1 /* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 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. 12 * 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. 24 */ 25 26 #include "config.h" 27 #include "LayerTreeHostCA.h" 28 29 #include "DrawingAreaImpl.h" 30 #include "WebPage.h" 31 #include "WebProcess.h" 32 #include <WebCore/Frame.h> 33 #include <WebCore/FrameView.h> 34 #include <WebCore/GraphicsLayerCA.h> 35 #include <WebCore/Page.h> 36 #include <WebCore/PlatformCALayer.h> 37 #include <WebCore/Settings.h> 38 39 using namespace WebCore; 40 41 namespace WebKit { 42 43 LayerTreeHostCA::LayerTreeHostCA(WebPage* webPage) 44 : LayerTreeHost(webPage) 45 , m_isValid(true) 46 , m_notifyAfterScheduledLayerFlush(false) 47 { 48 } 49 50 void LayerTreeHostCA::initialize() 51 { 52 // Create a root layer. 53 m_rootLayer = GraphicsLayer::create(this); 54 #ifndef NDEBUG 55 m_rootLayer->setName("LayerTreeHost root layer"); 56 #endif 57 m_rootLayer->setDrawsContent(false); 58 m_rootLayer->setSize(m_webPage->size()); 59 static_cast<GraphicsLayerCA*>(m_rootLayer.get())->platformCALayer()->setGeometryFlipped(true); 60 61 m_nonCompositedContentLayer = GraphicsLayer::create(this); 62 static_cast<GraphicsLayerCA*>(m_nonCompositedContentLayer.get())->setAllowTiledLayer(false); 63 #ifndef NDEBUG 64 m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content"); 65 #endif 66 m_nonCompositedContentLayer->setDrawsContent(true); 67 m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground()); 68 m_nonCompositedContentLayer->setSize(m_webPage->size()); 69 if (m_webPage->corePage()->settings()->acceleratedDrawingEnabled()) 70 m_nonCompositedContentLayer->setAcceleratesDrawing(true); 71 72 m_rootLayer->addChild(m_nonCompositedContentLayer.get()); 73 74 if (m_webPage->hasPageOverlay()) 75 createPageOverlayLayer(); 76 77 platformInitialize(m_layerTreeContext); 78 79 scheduleLayerFlush(); 80 } 81 82 LayerTreeHostCA::~LayerTreeHostCA() 83 { 84 ASSERT(!m_isValid); 85 ASSERT(!m_rootLayer); 86 } 87 88 const LayerTreeContext& LayerTreeHostCA::layerTreeContext() 89 { 90 return m_layerTreeContext; 91 } 92 93 void LayerTreeHostCA::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush) 94 { 95 m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush; 96 } 97 98 void LayerTreeHostCA::setRootCompositingLayer(GraphicsLayer* graphicsLayer) 99 { 100 m_nonCompositedContentLayer->removeAllChildren(); 101 102 // Add the accelerated layer tree hierarchy. 103 if (graphicsLayer) 104 m_nonCompositedContentLayer->addChild(graphicsLayer); 105 } 106 107 void LayerTreeHostCA::invalidate() 108 { 109 ASSERT(m_isValid); 110 m_rootLayer = nullptr; 111 m_isValid = false; 112 } 113 114 void LayerTreeHostCA::setNonCompositedContentsNeedDisplay(const IntRect& rect) 115 { 116 m_nonCompositedContentLayer->setNeedsDisplayInRect(rect); 117 if (m_pageOverlayLayer) 118 m_pageOverlayLayer->setNeedsDisplayInRect(rect); 119 120 scheduleLayerFlush(); 121 } 122 123 void LayerTreeHostCA::scrollNonCompositedContents(const IntRect& scrollRect, const IntSize& scrollOffset) 124 { 125 setNonCompositedContentsNeedDisplay(scrollRect); 126 } 127 128 void LayerTreeHostCA::sizeDidChange(const IntSize& newSize) 129 { 130 m_rootLayer->setSize(newSize); 131 m_nonCompositedContentLayer->setSize(newSize); 132 133 if (m_pageOverlayLayer) 134 m_pageOverlayLayer->setSize(newSize); 135 136 scheduleLayerFlush(); 137 flushPendingLayerChanges(); 138 } 139 140 void LayerTreeHostCA::forceRepaint() 141 { 142 scheduleLayerFlush(); 143 flushPendingLayerChanges(); 144 } 145 146 void LayerTreeHostCA::didInstallPageOverlay() 147 { 148 createPageOverlayLayer(); 149 scheduleLayerFlush(); 150 } 151 152 void LayerTreeHostCA::didUninstallPageOverlay() 153 { 154 destroyPageOverlayLayer(); 155 scheduleLayerFlush(); 156 } 157 158 void LayerTreeHostCA::setPageOverlayNeedsDisplay(const IntRect& rect) 159 { 160 ASSERT(m_pageOverlayLayer); 161 m_pageOverlayLayer->setNeedsDisplayInRect(rect); 162 scheduleLayerFlush(); 163 } 164 165 void LayerTreeHostCA::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time) 166 { 167 } 168 169 void LayerTreeHostCA::notifySyncRequired(const WebCore::GraphicsLayer*) 170 { 171 } 172 173 void LayerTreeHostCA::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& clipRect) 174 { 175 if (graphicsLayer == m_nonCompositedContentLayer) { 176 m_webPage->drawRect(graphicsContext, clipRect); 177 return; 178 } 179 180 if (graphicsLayer == m_pageOverlayLayer) { 181 m_webPage->drawPageOverlay(graphicsContext, clipRect); 182 return; 183 } 184 } 185 186 bool LayerTreeHostCA::showDebugBorders() const 187 { 188 return m_webPage->corePage()->settings()->showDebugBorders(); 189 } 190 191 bool LayerTreeHostCA::showRepaintCounter() const 192 { 193 return m_webPage->corePage()->settings()->showRepaintCounter(); 194 } 195 196 void LayerTreeHostCA::performScheduledLayerFlush() 197 { 198 { 199 RefPtr<LayerTreeHostCA> protect(this); 200 m_webPage->layoutIfNeeded(); 201 202 if (!m_isValid) 203 return; 204 } 205 206 if (!flushPendingLayerChanges()) 207 return; 208 209 didPerformScheduledLayerFlush(); 210 } 211 212 void LayerTreeHostCA::didPerformScheduledLayerFlush() 213 { 214 if (m_notifyAfterScheduledLayerFlush) { 215 // Let the drawing area know that we've done a flush of the layer changes. 216 static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers(); 217 m_notifyAfterScheduledLayerFlush = false; 218 } 219 } 220 221 bool LayerTreeHostCA::flushPendingLayerChanges() 222 { 223 m_rootLayer->syncCompositingStateForThisLayerOnly(); 224 m_nonCompositedContentLayer->syncCompositingStateForThisLayerOnly(); 225 if (m_pageOverlayLayer) 226 m_pageOverlayLayer->syncCompositingStateForThisLayerOnly(); 227 228 return m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes(); 229 } 230 231 void LayerTreeHostCA::createPageOverlayLayer() 232 { 233 ASSERT(!m_pageOverlayLayer); 234 235 m_pageOverlayLayer = GraphicsLayer::create(this); 236 #ifndef NDEBUG 237 m_pageOverlayLayer->setName("LayerTreeHost page overlay content"); 238 #endif 239 240 m_pageOverlayLayer->setDrawsContent(true); 241 m_pageOverlayLayer->setSize(m_webPage->size()); 242 243 m_rootLayer->addChild(m_pageOverlayLayer.get()); 244 } 245 246 void LayerTreeHostCA::destroyPageOverlayLayer() 247 { 248 ASSERT(m_pageOverlayLayer); 249 m_pageOverlayLayer->removeFromParent(); 250 m_pageOverlayLayer = nullptr; 251 } 252 253 } // namespace WebKit 254