/* * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "PageOverlay.h" #include "WebPageOverlay.h" #include "WebViewClient.h" #include "WebViewImpl.h" #include "core/page/Page.h" #include "core/frame/Settings.h" #include "platform/graphics/GraphicsLayer.h" #include "platform/graphics/GraphicsLayerClient.h" #include "public/platform/WebLayer.h" using namespace WebCore; namespace blink { namespace { WebCanvas* ToWebCanvas(GraphicsContext* gc) { return gc->canvas(); } } // namespace PassOwnPtr<PageOverlay> PageOverlay::create(WebViewImpl* viewImpl, WebPageOverlay* overlay) { return adoptPtr(new PageOverlay(viewImpl, overlay)); } PageOverlay::PageOverlay(WebViewImpl* viewImpl, WebPageOverlay* overlay) : m_viewImpl(viewImpl) , m_overlay(overlay) , m_zOrder(0) { } class OverlayGraphicsLayerClientImpl : public WebCore::GraphicsLayerClient { public: static PassOwnPtr<OverlayGraphicsLayerClientImpl> create(WebPageOverlay* overlay) { return adoptPtr(new OverlayGraphicsLayerClientImpl(overlay)); } virtual ~OverlayGraphicsLayerClientImpl() { } virtual void notifyAnimationStarted(const GraphicsLayer*, double wallClockTime, double monotonicTime) OVERRIDE { } virtual void paintContents(const GraphicsLayer*, GraphicsContext& gc, GraphicsLayerPaintingPhase, const IntRect& inClip) { gc.save(); m_overlay->paintPageOverlay(ToWebCanvas(&gc)); gc.restore(); } virtual String debugName(const GraphicsLayer* graphicsLayer) OVERRIDE { return String("WebViewImpl Page Overlay Content Layer"); } private: explicit OverlayGraphicsLayerClientImpl(WebPageOverlay* overlay) : m_overlay(overlay) { } WebPageOverlay* m_overlay; }; void PageOverlay::clear() { invalidateWebFrame(); if (m_layer) { m_layer->removeFromParent(); m_layer = nullptr; m_layerClient = nullptr; } } void PageOverlay::update() { invalidateWebFrame(); if (!m_layer) { m_layerClient = OverlayGraphicsLayerClientImpl::create(m_overlay); m_layer = GraphicsLayer::create(m_viewImpl->graphicsLayerFactory(), m_layerClient.get()); m_layer->setDrawsContent(true); // Compositor hit-testing does not know how to deal with layers that may be // transparent to events (see http://crbug.com/269598). So require // scrolling and touches on this layer to go to the main thread. WebLayer* platformLayer = m_layer->platformLayer(); platformLayer->setShouldScrollOnMainThread(true); WebVector<WebRect> webRects(static_cast<size_t>(1)); webRects[0] = WebRect(0, 0, INT_MAX, INT_MAX); platformLayer->setTouchEventHandlerRegion(webRects); } FloatSize size(m_viewImpl->size()); if (size != m_layer->size()) { // Triggers re-adding to root layer to ensure that we are on top of // scrollbars. m_layer->removeFromParent(); m_layer->setSize(size); } m_viewImpl->setOverlayLayer(m_layer.get()); m_layer->setNeedsDisplay(); } void PageOverlay::paintWebFrame(GraphicsContext& gc) { if (!m_viewImpl->isAcceleratedCompositingActive()) { gc.save(); m_overlay->paintPageOverlay(ToWebCanvas(&gc)); gc.restore(); } } void PageOverlay::invalidateWebFrame() { // WebPageOverlay does the actual painting of the overlay. // Here we just make sure to invalidate. if (!m_viewImpl->isAcceleratedCompositingActive()) { // FIXME: able to invalidate a smaller rect. // FIXME: Is it important to just invalidate a smaller rect given that // this is not on a critical codepath? In order to do so, we'd // have to take scrolling into account. const WebSize& size = m_viewImpl->size(); WebRect damagedRect(0, 0, size.width, size.height); if (m_viewImpl->client()) m_viewImpl->client()->didInvalidateRect(damagedRect); } } } // namespace blink