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 39using namespace WebCore; 40 41namespace WebKit { 42 43LayerTreeHostCA::LayerTreeHostCA(WebPage* webPage) 44 : LayerTreeHost(webPage) 45 , m_isValid(true) 46 , m_notifyAfterScheduledLayerFlush(false) 47{ 48} 49 50void 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 82LayerTreeHostCA::~LayerTreeHostCA() 83{ 84 ASSERT(!m_isValid); 85 ASSERT(!m_rootLayer); 86} 87 88const LayerTreeContext& LayerTreeHostCA::layerTreeContext() 89{ 90 return m_layerTreeContext; 91} 92 93void LayerTreeHostCA::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush) 94{ 95 m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush; 96} 97 98void 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 107void LayerTreeHostCA::invalidate() 108{ 109 ASSERT(m_isValid); 110 m_rootLayer = nullptr; 111 m_isValid = false; 112} 113 114void 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 123void LayerTreeHostCA::scrollNonCompositedContents(const IntRect& scrollRect, const IntSize& scrollOffset) 124{ 125 setNonCompositedContentsNeedDisplay(scrollRect); 126} 127 128void 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 140void LayerTreeHostCA::forceRepaint() 141{ 142 scheduleLayerFlush(); 143 flushPendingLayerChanges(); 144} 145 146void LayerTreeHostCA::didInstallPageOverlay() 147{ 148 createPageOverlayLayer(); 149 scheduleLayerFlush(); 150} 151 152void LayerTreeHostCA::didUninstallPageOverlay() 153{ 154 destroyPageOverlayLayer(); 155 scheduleLayerFlush(); 156} 157 158void LayerTreeHostCA::setPageOverlayNeedsDisplay(const IntRect& rect) 159{ 160 ASSERT(m_pageOverlayLayer); 161 m_pageOverlayLayer->setNeedsDisplayInRect(rect); 162 scheduleLayerFlush(); 163} 164 165void LayerTreeHostCA::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time) 166{ 167} 168 169void LayerTreeHostCA::notifySyncRequired(const WebCore::GraphicsLayer*) 170{ 171} 172 173void 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 186bool LayerTreeHostCA::showDebugBorders() const 187{ 188 return m_webPage->corePage()->settings()->showDebugBorders(); 189} 190 191bool LayerTreeHostCA::showRepaintCounter() const 192{ 193 return m_webPage->corePage()->settings()->showRepaintCounter(); 194} 195 196void 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 212void 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 221bool 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 231void 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 246void LayerTreeHostCA::destroyPageOverlayLayer() 247{ 248 ASSERT(m_pageOverlayLayer); 249 m_pageOverlayLayer->removeFromParent(); 250 m_pageOverlayLayer = nullptr; 251} 252 253} // namespace WebKit 254