2 * Copyright (C) 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
27 #include "PageOverlayController.h"
29 #include "DrawingArea.h"
30 #include "PageOverlay.h"
32 #include <WebCore/Frame.h>
33 #include <WebCore/FrameView.h>
34 #include <WebCore/GraphicsContext.h>
35 #include <WebCore/GraphicsLayer.h>
36 #include <WebCore/MainFrame.h>
37 #include <WebCore/ScrollingCoordinator.h>
38 #include <WebCore/Settings.h>
39 #include <WebCore/TiledBacking.h>
41 using namespace WebCore;
45 PageOverlayController::PageOverlayController(WebPage& webPage)
50 void PageOverlayController::initialize()
52 ASSERT(!m_documentOverlayRootLayer);
53 ASSERT(!m_viewOverlayRootLayer);
55 m_documentOverlayRootLayer = GraphicsLayer::create(m_webPage.drawingArea()->graphicsLayerFactory(), *this);
56 m_viewOverlayRootLayer = GraphicsLayer::create(m_webPage.drawingArea()->graphicsLayerFactory(), *this);
58 m_documentOverlayRootLayer->setName("Page Overlay container (document-relative)");
59 m_viewOverlayRootLayer->setName("Page Overlay container (view-relative)");
63 static void updateOverlayGeometry(PageOverlay& overlay, GraphicsLayer& graphicsLayer)
65 IntRect overlayFrame = overlay.frame();
67 if (overlayFrame.location() == graphicsLayer.position() && overlayFrame.size() == graphicsLayer.size())
70 graphicsLayer.setPosition(overlayFrame.location());
71 graphicsLayer.setSize(overlayFrame.size());
74 void PageOverlayController::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay, PageOverlay::FadeMode fadeMode)
76 ASSERT(m_documentOverlayRootLayer);
77 ASSERT(m_viewOverlayRootLayer);
79 RefPtr<PageOverlay> overlay = pageOverlay;
81 if (m_pageOverlays.contains(overlay))
84 m_pageOverlays.append(overlay);
85 overlay->setPage(&m_webPage);
87 if (fadeMode == PageOverlay::FadeMode::Fade)
88 overlay->startFadeInAnimation();
90 std::unique_ptr<GraphicsLayer> layer = GraphicsLayer::create(m_webPage.drawingArea()->graphicsLayerFactory(), *this);
91 layer->setAnchorPoint(FloatPoint3D());
92 layer->setBackgroundColor(overlay->backgroundColor());
93 updateOverlayGeometry(*overlay, *layer);
95 layer->setName("Page Overlay content");
98 updateSettingsForLayer(*layer);
100 switch (overlay->overlayType()) {
101 case PageOverlay::OverlayType::View:
102 m_viewOverlayRootLayer->addChild(layer.get());
104 case PageOverlay::OverlayType::Document:
105 m_documentOverlayRootLayer->addChild(layer.get());
109 m_overlayGraphicsLayers.set(overlay.get(), WTF::move(layer));
111 updateForceSynchronousScrollLayerPositionUpdates();
114 void PageOverlayController::uninstallPageOverlay(PageOverlay* overlay, PageOverlay::FadeMode fadeMode)
116 if (fadeMode == PageOverlay::FadeMode::Fade) {
117 overlay->startFadeOutAnimation();
121 overlay->setPage(nullptr);
123 m_overlayGraphicsLayers.take(overlay)->removeFromParent();
125 size_t overlayIndex = m_pageOverlays.find(overlay);
126 ASSERT(overlayIndex != notFound);
127 m_pageOverlays.remove(overlayIndex);
129 updateForceSynchronousScrollLayerPositionUpdates();
132 void PageOverlayController::updateForceSynchronousScrollLayerPositionUpdates()
134 #if ENABLE(ASYNC_SCROLLING)
135 bool forceSynchronousScrollLayerPositionUpdates = false;
137 for (auto& overlay : m_pageOverlays) {
138 if (overlay->overlayType() == PageOverlay::OverlayType::View)
139 forceSynchronousScrollLayerPositionUpdates = true;
142 if (Page* page = m_webPage.corePage()) {
143 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
144 scrollingCoordinator->setForceSynchronousScrollLayerPositionUpdates(forceSynchronousScrollLayerPositionUpdates);
149 void PageOverlayController::setPageOverlayNeedsDisplay(PageOverlay& overlay, const WebCore::IntRect& dirtyRect)
151 ASSERT(m_pageOverlays.contains(&overlay));
152 GraphicsLayer& graphicsLayer = *m_overlayGraphicsLayers.get(&overlay);
154 if (!graphicsLayer.drawsContent()) {
155 graphicsLayer.setDrawsContent(true);
156 updateOverlayGeometry(overlay, graphicsLayer);
159 graphicsLayer.setNeedsDisplayInRect(dirtyRect);
162 void PageOverlayController::setPageOverlayOpacity(PageOverlay& overlay, float opacity)
164 ASSERT(m_pageOverlays.contains(&overlay));
165 m_overlayGraphicsLayers.get(&overlay)->setOpacity(opacity);
168 void PageOverlayController::clearPageOverlay(PageOverlay& overlay)
170 ASSERT(m_pageOverlays.contains(&overlay));
171 m_overlayGraphicsLayers.get(&overlay)->setDrawsContent(false);
174 GraphicsLayer* PageOverlayController::layerForOverlay(PageOverlay& overlay) const
176 ASSERT(m_pageOverlays.contains(&overlay));
177 return m_overlayGraphicsLayers.get(&overlay);
180 void PageOverlayController::didChangeViewSize()
182 for (auto& overlayAndLayer : m_overlayGraphicsLayers) {
183 if (overlayAndLayer.key->overlayType() == PageOverlay::OverlayType::View)
184 updateOverlayGeometry(*overlayAndLayer.key, *overlayAndLayer.value);
188 void PageOverlayController::didChangeDocumentSize()
190 for (auto& overlayAndLayer : m_overlayGraphicsLayers) {
191 if (overlayAndLayer.key->overlayType() == PageOverlay::OverlayType::Document)
192 updateOverlayGeometry(*overlayAndLayer.key, *overlayAndLayer.value);
196 void PageOverlayController::didChangePreferences()
198 for (auto& graphicsLayer : m_overlayGraphicsLayers.values())
199 updateSettingsForLayer(*graphicsLayer);
202 void PageOverlayController::didChangeDeviceScaleFactor()
204 m_documentOverlayRootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
205 m_viewOverlayRootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
207 for (auto& graphicsLayer : m_overlayGraphicsLayers.values())
208 graphicsLayer->setNeedsDisplay();
211 void PageOverlayController::didChangeExposedRect()
213 m_webPage.drawingArea()->scheduleCompositingLayerFlush();
216 void PageOverlayController::didScrollFrame(Frame* frame)
218 for (auto& overlayAndLayer : m_overlayGraphicsLayers) {
219 if (overlayAndLayer.key->overlayType() == PageOverlay::OverlayType::View || !frame->isMainFrame())
220 overlayAndLayer.value->setNeedsDisplay();
224 void PageOverlayController::flushPageOverlayLayers(FloatRect visibleRect)
226 m_viewOverlayRootLayer->flushCompositingState(visibleRect);
229 void PageOverlayController::updateSettingsForLayer(GraphicsLayer& layer)
231 Settings& settings = m_webPage.corePage()->settings();
232 layer.setAcceleratesDrawing(settings.acceleratedDrawingEnabled());
233 layer.setShowDebugBorder(settings.showDebugBorders());
234 layer.setShowRepaintCounter(settings.showRepaintCounter());
237 bool PageOverlayController::handleMouseEvent(const WebMouseEvent& mouseEvent)
239 if (!m_pageOverlays.size())
242 for (auto it = m_pageOverlays.rbegin(), end = m_pageOverlays.rend(); it != end; ++it) {
243 if ((*it)->mouseEvent(mouseEvent))
250 WKTypeRef PageOverlayController::copyAccessibilityAttributeValue(WKStringRef attribute, WKTypeRef parameter)
252 if (!m_pageOverlays.size())
255 for (auto it = m_pageOverlays.rbegin(), end = m_pageOverlays.rend(); it != end; ++it) {
256 if (WKTypeRef value = (*it)->copyAccessibilityAttributeValue(attribute, parameter))
263 WKArrayRef PageOverlayController::copyAccessibilityAttributesNames(bool parameterizedNames)
265 if (!m_pageOverlays.size())
268 for (auto it = m_pageOverlays.rbegin(), end = m_pageOverlays.rend(); it != end; ++it) {
269 if (WKArrayRef value = (*it)->copyAccessibilityAttributeNames(parameterizedNames))
276 void PageOverlayController::paintContents(const WebCore::GraphicsLayer* graphicsLayer, WebCore::GraphicsContext& graphicsContext, WebCore::GraphicsLayerPaintingPhase, const WebCore::FloatRect& clipRect)
278 for (auto it = m_overlayGraphicsLayers.begin(), end = m_overlayGraphicsLayers.end(); it != end; ++it) {
279 if (it->value.get() != graphicsLayer)
282 GraphicsContextStateSaver stateSaver(graphicsContext);
283 graphicsContext.clip(clipRect);
284 it->key->drawRect(graphicsContext, enclosingIntRect(clipRect));
290 float PageOverlayController::deviceScaleFactor() const
292 return m_webPage.corePage()->deviceScaleFactor();
295 void PageOverlayController::notifyFlushRequired(const WebCore::GraphicsLayer*)
297 if (m_webPage.drawingArea())
298 m_webPage.drawingArea()->scheduleCompositingLayerFlush();
301 void PageOverlayController::didChangeOverlayFrame(PageOverlay& overlay)
303 ASSERT(m_pageOverlays.contains(&overlay));
304 updateOverlayGeometry(overlay, *m_overlayGraphicsLayers.get(&overlay));
307 void PageOverlayController::didChangeOverlayBackgroundColor(PageOverlay& overlay)
309 ASSERT(m_pageOverlays.contains(&overlay));
310 m_overlayGraphicsLayers.get(&overlay)->setBackgroundColor(overlay.backgroundColor());
313 } // namespace WebKit