1/* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 * Copyright (C) 2012 Company 100, Inc. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 25 * THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include "config.h" 29 30#if USE(COORDINATED_GRAPHICS) 31#include "CoordinatedLayerTreeHost.h" 32 33#include "CoordinatedDrawingArea.h" 34#include "CoordinatedGraphicsArgumentCoders.h" 35#include "CoordinatedLayerTreeHostProxyMessages.h" 36#include "GraphicsContext.h" 37#include "WebCoordinatedSurface.h" 38#include "WebCoreArgumentCoders.h" 39#include "WebPage.h" 40#include "WebPageProxyMessages.h" 41#include <WebCore/Frame.h> 42#include <WebCore/FrameView.h> 43#include <WebCore/Settings.h> 44#include <wtf/CurrentTime.h> 45 46using namespace WebCore; 47 48namespace WebKit { 49 50PassRefPtr<CoordinatedLayerTreeHost> CoordinatedLayerTreeHost::create(WebPage* webPage) 51{ 52 return adoptRef(new CoordinatedLayerTreeHost(webPage)); 53} 54 55CoordinatedLayerTreeHost::~CoordinatedLayerTreeHost() 56{ 57} 58 59CoordinatedLayerTreeHost::CoordinatedLayerTreeHost(WebPage* webPage) 60 : LayerTreeHost(webPage) 61 , m_notifyAfterScheduledLayerFlush(false) 62 , m_isValid(true) 63 , m_isSuspended(false) 64 , m_isWaitingForRenderer(true) 65 , m_layerFlushTimer(this, &CoordinatedLayerTreeHost::layerFlushTimerFired) 66 , m_layerFlushSchedulingEnabled(true) 67 , m_forceRepaintAsyncCallbackID(0) 68{ 69 m_coordinator = std::make_unique<CompositingCoordinator>(webPage->corePage(), this); 70 71 m_coordinator->createRootLayer(webPage->size()); 72 m_layerTreeContext.contextID = toCoordinatedGraphicsLayer(m_coordinator->rootLayer())->id(); 73 74 CoordinatedSurface::setFactory(createCoordinatedSurface); 75 76 scheduleLayerFlush(); 77} 78 79void CoordinatedLayerTreeHost::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled) 80{ 81 if (m_layerFlushSchedulingEnabled == layerFlushingEnabled) 82 return; 83 84 m_layerFlushSchedulingEnabled = layerFlushingEnabled; 85 86 if (m_layerFlushSchedulingEnabled) { 87 scheduleLayerFlush(); 88 return; 89 } 90 91 cancelPendingLayerFlush(); 92} 93 94void CoordinatedLayerTreeHost::scheduleLayerFlush() 95{ 96 if (!m_layerFlushSchedulingEnabled) 97 return; 98 99 if (!m_layerFlushTimer.isActive() || m_layerFlushTimer.nextFireInterval() > 0) 100 m_layerFlushTimer.startOneShot(0); 101} 102 103void CoordinatedLayerTreeHost::cancelPendingLayerFlush() 104{ 105 m_layerFlushTimer.stop(); 106} 107 108void CoordinatedLayerTreeHost::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush) 109{ 110 m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush; 111} 112 113void CoordinatedLayerTreeHost::setRootCompositingLayer(WebCore::GraphicsLayer* graphicsLayer) 114{ 115 m_coordinator->setRootCompositingLayer(graphicsLayer, m_webPage->pageOverlayController().viewOverlayRootLayer()); 116} 117 118void CoordinatedLayerTreeHost::invalidate() 119{ 120 cancelPendingLayerFlush(); 121 122 ASSERT(m_isValid); 123 m_coordinator->clearRootLayer(); 124 m_isValid = false; 125} 126 127void CoordinatedLayerTreeHost::forceRepaint() 128{ 129 // This is necessary for running layout tests. Since in this case we are not waiting for a UIProcess to reply nicely. 130 // Instead we are just triggering forceRepaint. But we still want to have the scripted animation callbacks being executed. 131 m_coordinator->syncDisplayState(); 132 133 // We need to schedule another flush, otherwise the forced paint might cancel a later expected flush. 134 // This is aligned with LayerTreeHostCA. 135 scheduleLayerFlush(); 136 137 if (m_isWaitingForRenderer) 138 return; 139 140 m_coordinator->flushPendingLayerChanges(); 141} 142 143bool CoordinatedLayerTreeHost::forceRepaintAsync(uint64_t callbackID) 144{ 145 // We expect the UI process to not require a new repaint until the previous one has finished. 146 ASSERT(!m_forceRepaintAsyncCallbackID); 147 m_forceRepaintAsyncCallbackID = callbackID; 148 scheduleLayerFlush(); 149 return true; 150} 151 152void CoordinatedLayerTreeHost::sizeDidChange(const WebCore::IntSize& newSize) 153{ 154 m_coordinator->sizeDidChange(newSize); 155 scheduleLayerFlush(); 156} 157 158void CoordinatedLayerTreeHost::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector) 159{ 160 m_coordinator->setVisibleContentsRect(rect, trajectoryVector); 161 scheduleLayerFlush(); 162} 163 164void CoordinatedLayerTreeHost::renderNextFrame() 165{ 166 m_isWaitingForRenderer = false; 167 scheduleLayerFlush(); 168 m_coordinator->renderNextFrame(); 169} 170 171void CoordinatedLayerTreeHost::purgeBackingStores() 172{ 173 m_coordinator->purgeBackingStores(); 174} 175 176void CoordinatedLayerTreeHost::didFlushRootLayer(const FloatRect& visibleContentRect) 177{ 178 m_webPage->pageOverlayController().flushPageOverlayLayers(visibleContentRect); 179} 180 181void CoordinatedLayerTreeHost::performScheduledLayerFlush() 182{ 183 if (m_isSuspended || m_isWaitingForRenderer) 184 return; 185 186 m_coordinator->syncDisplayState(); 187 188 if (!m_isValid) 189 return; 190 191 bool didSync = m_coordinator->flushPendingLayerChanges(); 192 193 if (m_forceRepaintAsyncCallbackID) { 194 m_webPage->send(Messages::WebPageProxy::VoidCallback(m_forceRepaintAsyncCallbackID)); 195 m_forceRepaintAsyncCallbackID = 0; 196 } 197 198 if (m_notifyAfterScheduledLayerFlush && didSync) { 199 static_cast<CoordinatedDrawingArea*>(m_webPage->drawingArea())->layerHostDidFlushLayers(); 200 m_notifyAfterScheduledLayerFlush = false; 201 } 202} 203 204void CoordinatedLayerTreeHost::layerFlushTimerFired(Timer<CoordinatedLayerTreeHost>*) 205{ 206 performScheduledLayerFlush(); 207} 208 209void CoordinatedLayerTreeHost::paintLayerContents(const GraphicsLayer*, GraphicsContext&, const IntRect&) 210{ 211} 212 213void CoordinatedLayerTreeHost::commitSceneState(const WebCore::CoordinatedGraphicsState& state) 214{ 215 m_webPage->send(Messages::CoordinatedLayerTreeHostProxy::CommitCoordinatedGraphicsState(state)); 216 m_isWaitingForRenderer = true; 217} 218 219PassRefPtr<CoordinatedSurface> CoordinatedLayerTreeHost::createCoordinatedSurface(const IntSize& size, CoordinatedSurface::Flags flags) 220{ 221 return WebCoordinatedSurface::create(size, flags); 222} 223 224void CoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged() 225{ 226 m_coordinator->deviceOrPageScaleFactorChanged(); 227 m_webPage->pageOverlayController().didChangeDeviceScaleFactor(); 228} 229 230void CoordinatedLayerTreeHost::pageBackgroundTransparencyChanged() 231{ 232} 233 234GraphicsLayerFactory* CoordinatedLayerTreeHost::graphicsLayerFactory() 235{ 236 return m_coordinator.get(); 237} 238 239#if ENABLE(REQUEST_ANIMATION_FRAME) 240void CoordinatedLayerTreeHost::scheduleAnimation() 241{ 242 if (m_isWaitingForRenderer) 243 return; 244 245 if (m_layerFlushTimer.isActive()) 246 return; 247 248 scheduleLayerFlush(); 249 m_layerFlushTimer.startOneShot(m_coordinator->nextAnimationServiceTime()); 250} 251#endif 252 253void CoordinatedLayerTreeHost::setBackgroundColor(const WebCore::Color& color) 254{ 255 m_webPage->send(Messages::CoordinatedLayerTreeHostProxy::SetBackgroundColor(color)); 256} 257 258void CoordinatedLayerTreeHost::commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset) 259{ 260 m_coordinator->commitScrollOffset(layerID, offset); 261} 262 263} // namespace WebKit 264#endif // USE(COORDINATED_GRAPHICS) 265