1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "CCLayerTreeHost.h"
9 #include "CCFontAtlas.h"
10 #include "CCGraphicsContext.h"
11 #include "CCHeadsUpDisplayLayerImpl.h"
12 #include "CCLayerAnimationController.h"
13 #include "CCLayerIterator.h"
14 #include "CCLayerTreeHostClient.h"
15 #include "CCLayerTreeHostCommon.h"
16 #include "CCLayerTreeHostImpl.h"
17 #include "CCOcclusionTracker.h"
18 #include "CCOverdrawMetrics.h"
19 #include "CCSettings.h"
20 #include "CCSingleThreadProxy.h"
21 #include "CCThreadProxy.h"
22 #include "HeadsUpDisplayLayerChromium.h"
23 #include "LayerChromium.h"
25 #include "TraceEvent.h"
26 #include "TreeSynchronizer.h"
29 using WebKit::WebTransformationMatrix
;
32 static int numLayerTreeInstances
;
37 bool CCLayerTreeHost::s_needsFilterContext
= false;
39 bool CCLayerTreeHost::anyLayerTreeHostInstanceExists()
41 return numLayerTreeInstances
> 0;
44 PassOwnPtr
<CCLayerTreeHost
> CCLayerTreeHost::create(CCLayerTreeHostClient
* client
, const CCLayerTreeSettings
& settings
)
46 OwnPtr
<CCLayerTreeHost
> layerTreeHost
= adoptPtr(new CCLayerTreeHost(client
, settings
));
47 if (!layerTreeHost
->initialize())
49 return layerTreeHost
.release();
52 CCLayerTreeHost::CCLayerTreeHost(CCLayerTreeHostClient
* client
, const CCLayerTreeSettings
& settings
)
54 , m_needsAnimateLayers(false)
58 , m_rendererInitialized(false)
59 , m_contextLost(false)
60 , m_numTimesRecreateShouldFail(0)
61 , m_numFailedRecreateAttempts(0)
62 , m_settings(settings
)
63 , m_deviceScaleFactor(1)
65 , m_pageScaleFactor(1)
66 , m_minPageScaleFactor(1)
67 , m_maxPageScaleFactor(1)
68 , m_triggerIdleUpdates(true)
69 , m_backgroundColor(SK_ColorWHITE
)
70 , m_hasTransparentBackground(false)
71 , m_partialTextureUpdateRequests(0)
73 ASSERT(CCProxy::isMainThread());
74 numLayerTreeInstances
++;
77 bool CCLayerTreeHost::initialize()
79 TRACE_EVENT0("cc", "CCLayerTreeHost::initialize");
81 if (CCProxy::hasImplThread())
82 m_proxy
= CCThreadProxy::create(this);
84 m_proxy
= CCSingleThreadProxy::create(this);
87 return m_proxy
->initializeContext();
90 CCLayerTreeHost::~CCLayerTreeHost()
93 m_rootLayer
->setLayerTreeHost(0);
94 ASSERT(CCProxy::isMainThread());
95 TRACE_EVENT0("cc", "CCLayerTreeHost::~CCLayerTreeHost");
99 numLayerTreeInstances
--;
100 RateLimiterMap::iterator it
= m_rateLimiters
.begin();
101 if (it
!= m_rateLimiters
.end())
105 void CCLayerTreeHost::setSurfaceReady()
107 m_proxy
->setSurfaceReady();
110 void CCLayerTreeHost::initializeRenderer()
112 TRACE_EVENT0("cc", "CCLayerTreeHost::initializeRenderer");
113 if (!m_proxy
->initializeRenderer()) {
114 // Uh oh, better tell the client that we can't do anything with this context.
115 m_client
->didRecreateOutputSurface(false);
119 // Update m_settings based on capabilities that we got back from the renderer.
120 m_settings
.acceleratePainting
= m_proxy
->rendererCapabilities().usingAcceleratedPainting
;
122 // Update m_settings based on partial update capability.
123 m_settings
.maxPartialTextureUpdates
= min(m_settings
.maxPartialTextureUpdates
, m_proxy
->maxPartialTextureUpdates());
125 m_contentsTextureManager
= CCPrioritizedTextureManager::create(0, m_proxy
->rendererCapabilities().maxTextureSize
, CCRenderer::ContentPool
);
126 m_surfaceMemoryPlaceholder
= m_contentsTextureManager
->createTexture(IntSize(), GraphicsContext3D::RGBA
);
128 m_rendererInitialized
= true;
130 m_settings
.defaultTileSize
= IntSize(min(m_settings
.defaultTileSize
.width(), m_proxy
->rendererCapabilities().maxTextureSize
),
131 min(m_settings
.defaultTileSize
.height(), m_proxy
->rendererCapabilities().maxTextureSize
));
132 m_settings
.maxUntiledLayerSize
= IntSize(min(m_settings
.maxUntiledLayerSize
.width(), m_proxy
->rendererCapabilities().maxTextureSize
),
133 min(m_settings
.maxUntiledLayerSize
.height(), m_proxy
->rendererCapabilities().maxTextureSize
));
136 CCLayerTreeHost::RecreateResult
CCLayerTreeHost::recreateContext()
138 TRACE_EVENT0("cc", "CCLayerTreeHost::recreateContext");
139 ASSERT(m_contextLost
);
141 bool recreated
= false;
142 if (!m_numTimesRecreateShouldFail
)
143 recreated
= m_proxy
->recreateContext();
145 m_numTimesRecreateShouldFail
--;
148 m_client
->didRecreateOutputSurface(true);
149 m_contextLost
= false;
150 return RecreateSucceeded
;
153 // Tolerate a certain number of recreation failures to work around races
154 // in the context-lost machinery.
155 m_numFailedRecreateAttempts
++;
156 if (m_numFailedRecreateAttempts
< 5) {
157 // FIXME: The single thread does not self-schedule context
158 // recreation. So force another recreation attempt to happen by requesting
160 if (!CCProxy::hasImplThread())
162 return RecreateFailedButTryAgain
;
165 // We have tried too many times to recreate the context. Tell the host to fall
166 // back to software rendering.
167 m_client
->didRecreateOutputSurface(false);
168 return RecreateFailedAndGaveUp
;
171 void CCLayerTreeHost::deleteContentsTexturesOnImplThread(CCResourceProvider
* resourceProvider
)
173 ASSERT(CCProxy::isImplThread());
174 if (m_rendererInitialized
)
175 m_contentsTextureManager
->clearAllMemory(resourceProvider
);
178 void CCLayerTreeHost::acquireLayerTextures()
180 ASSERT(CCProxy::isMainThread());
181 m_proxy
->acquireLayerTextures();
184 void CCLayerTreeHost::updateAnimations(double monotonicFrameBeginTime
)
187 m_client
->animate(monotonicFrameBeginTime
);
188 animateLayers(monotonicFrameBeginTime
);
191 m_renderingStats
.numAnimationFrames
++;
194 void CCLayerTreeHost::layout()
199 void CCLayerTreeHost::beginCommitOnImplThread(CCLayerTreeHostImpl
* hostImpl
)
201 ASSERT(CCProxy::isImplThread());
202 TRACE_EVENT0("cc", "CCLayerTreeHost::commitTo");
204 m_contentsTextureManager
->reduceMemory(hostImpl
->resourceProvider());
207 // This function commits the CCLayerTreeHost to an impl tree. When modifying
208 // this function, keep in mind that the function *runs* on the impl thread! Any
209 // code that is logically a main thread operation, e.g. deletion of a LayerChromium,
210 // should be delayed until the CCLayerTreeHost::commitComplete, which will run
211 // after the commit, but on the main thread.
212 void CCLayerTreeHost::finishCommitOnImplThread(CCLayerTreeHostImpl
* hostImpl
)
214 ASSERT(CCProxy::isImplThread());
216 hostImpl
->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl
->detachLayerTree(), hostImpl
));
218 if (m_rootLayer
&& m_hudLayer
)
219 hostImpl
->setHudLayer(static_cast<CCHeadsUpDisplayLayerImpl
*>(CCLayerTreeHostCommon::findLayerInSubtree(hostImpl
->rootLayer(), m_hudLayer
->id())));
221 hostImpl
->setHudLayer(0);
223 // We may have added an animation during the tree sync. This will cause both layer tree hosts
224 // to visit their controllers.
225 if (rootLayer() && m_needsAnimateLayers
)
226 hostImpl
->setNeedsAnimateLayers();
228 hostImpl
->setSourceFrameNumber(commitNumber());
229 hostImpl
->setViewportSize(layoutViewportSize(), deviceViewportSize());
230 hostImpl
->setDeviceScaleFactor(deviceScaleFactor());
231 hostImpl
->setPageScaleFactorAndLimits(m_pageScaleFactor
, m_minPageScaleFactor
, m_maxPageScaleFactor
);
232 hostImpl
->setBackgroundColor(m_backgroundColor
);
233 hostImpl
->setHasTransparentBackground(m_hasTransparentBackground
);
238 void CCLayerTreeHost::setFontAtlas(PassOwnPtr
<CCFontAtlas
> fontAtlas
)
240 m_fontAtlas
= fontAtlas
;
244 void CCLayerTreeHost::willCommit()
246 m_client
->willCommit();
247 if (m_rootLayer
&& m_settings
.showDebugInfo()) {
249 m_hudLayer
= HeadsUpDisplayLayerChromium::create();
252 m_hudLayer
->setFontAtlas(m_fontAtlas
.release());
254 if (!m_hudLayer
->parent())
255 m_rootLayer
->addChild(m_hudLayer
);
259 void CCLayerTreeHost::commitComplete()
261 m_deleteTextureAfterCommitList
.clear();
262 m_client
->didCommit();
265 PassOwnPtr
<CCGraphicsContext
> CCLayerTreeHost::createContext()
267 return m_client
->createOutputSurface();
270 PassOwnPtr
<CCInputHandler
> CCLayerTreeHost::createInputHandler()
272 return m_client
->createInputHandler();
275 PassOwnPtr
<CCLayerTreeHostImpl
> CCLayerTreeHost::createLayerTreeHostImpl(CCLayerTreeHostImplClient
* client
)
277 return CCLayerTreeHostImpl::create(m_settings
, client
);
280 void CCLayerTreeHost::didLoseContext()
282 TRACE_EVENT0("cc", "CCLayerTreeHost::didLoseContext");
283 ASSERT(CCProxy::isMainThread());
284 m_contextLost
= true;
285 m_numFailedRecreateAttempts
= 0;
289 bool CCLayerTreeHost::compositeAndReadback(void *pixels
, const IntRect
& rect
)
291 m_triggerIdleUpdates
= false;
292 bool ret
= m_proxy
->compositeAndReadback(pixels
, rect
);
293 m_triggerIdleUpdates
= true;
297 void CCLayerTreeHost::finishAllRendering()
299 if (!m_rendererInitialized
)
301 m_proxy
->finishAllRendering();
304 void CCLayerTreeHost::renderingStats(CCRenderingStats
& stats
) const
306 stats
= m_renderingStats
;
307 m_proxy
->implSideRenderingStats(stats
);
310 const RendererCapabilities
& CCLayerTreeHost::rendererCapabilities() const
312 return m_proxy
->rendererCapabilities();
315 void CCLayerTreeHost::setNeedsAnimate()
317 ASSERT(CCProxy::hasImplThread());
318 m_proxy
->setNeedsAnimate();
321 void CCLayerTreeHost::setNeedsCommit()
323 m_proxy
->setNeedsCommit();
326 void CCLayerTreeHost::setNeedsRedraw()
328 m_proxy
->setNeedsRedraw();
329 if (!CCThreadProxy::implThread())
330 m_client
->scheduleComposite();
333 bool CCLayerTreeHost::commitRequested() const
335 return m_proxy
->commitRequested();
338 void CCLayerTreeHost::setAnimationEvents(PassOwnPtr
<CCAnimationEventsVector
> events
, double wallClockTime
)
340 ASSERT(CCThreadProxy::isMainThread());
341 setAnimationEventsRecursive(*events
, m_rootLayer
.get(), wallClockTime
);
344 void CCLayerTreeHost::didAddAnimation()
346 m_needsAnimateLayers
= true;
347 m_proxy
->didAddAnimation();
350 void CCLayerTreeHost::setRootLayer(PassRefPtr
<LayerChromium
> rootLayer
)
352 if (m_rootLayer
== rootLayer
)
356 m_rootLayer
->setLayerTreeHost(0);
357 m_rootLayer
= rootLayer
;
359 m_rootLayer
->setLayerTreeHost(this);
362 m_hudLayer
->removeFromParent();
367 void CCLayerTreeHost::setViewportSize(const IntSize
& layoutViewportSize
, const IntSize
& deviceViewportSize
)
369 if (layoutViewportSize
== m_layoutViewportSize
&& deviceViewportSize
== m_deviceViewportSize
)
372 m_layoutViewportSize
= layoutViewportSize
;
373 m_deviceViewportSize
= deviceViewportSize
;
378 void CCLayerTreeHost::setPageScaleFactorAndLimits(float pageScaleFactor
, float minPageScaleFactor
, float maxPageScaleFactor
)
380 if (pageScaleFactor
== m_pageScaleFactor
&& minPageScaleFactor
== m_minPageScaleFactor
&& maxPageScaleFactor
== m_maxPageScaleFactor
)
383 m_pageScaleFactor
= pageScaleFactor
;
384 m_minPageScaleFactor
= minPageScaleFactor
;
385 m_maxPageScaleFactor
= maxPageScaleFactor
;
389 void CCLayerTreeHost::setVisible(bool visible
)
391 if (m_visible
== visible
)
394 m_proxy
->setVisible(visible
);
397 void CCLayerTreeHost::evictAllContentTextures()
399 ASSERT(CCProxy::isMainThread());
400 ASSERT(m_contentsTextureManager
.get());
401 m_contentsTextureManager
->allBackingTexturesWereDeleted();
404 void CCLayerTreeHost::startPageScaleAnimation(const IntSize
& targetPosition
, bool useAnchor
, float scale
, double durationSec
)
406 m_proxy
->startPageScaleAnimation(targetPosition
, useAnchor
, scale
, durationSec
);
409 void CCLayerTreeHost::loseContext(int numTimes
)
411 TRACE_EVENT1("cc", "CCLayerTreeHost::loseCompositorContext", "numTimes", numTimes
);
412 m_numTimesRecreateShouldFail
= numTimes
- 1;
413 m_proxy
->loseContext();
416 CCPrioritizedTextureManager
* CCLayerTreeHost::contentsTextureManager() const
418 return m_contentsTextureManager
.get();
421 void CCLayerTreeHost::composite()
423 ASSERT(!CCThreadProxy::implThread());
424 static_cast<CCSingleThreadProxy
*>(m_proxy
.get())->compositeImmediately();
427 void CCLayerTreeHost::scheduleComposite()
429 m_client
->scheduleComposite();
432 bool CCLayerTreeHost::initializeRendererIfNeeded()
434 if (!m_rendererInitialized
) {
435 initializeRenderer();
436 // If we couldn't initialize, then bail since we're returning to software mode.
437 if (!m_rendererInitialized
)
441 if (recreateContext() != RecreateSucceeded
)
447 void CCLayerTreeHost::updateLayers(CCTextureUpdateQueue
& queue
, size_t memoryAllocationLimitBytes
)
449 ASSERT(m_rendererInitialized
);
450 ASSERT(memoryAllocationLimitBytes
);
455 if (layoutViewportSize().isEmpty())
458 m_contentsTextureManager
->setMaxMemoryLimitBytes(memoryAllocationLimitBytes
);
460 updateLayers(rootLayer(), queue
);
463 static void setScale(LayerChromium
* layer
, float deviceScaleFactor
, float pageScaleFactor
)
465 if (layer
->boundsContainPageScale())
466 layer
->setContentsScale(deviceScaleFactor
);
468 layer
->setContentsScale(deviceScaleFactor
* pageScaleFactor
);
471 static void updateLayerScale(LayerChromium
* layer
, float deviceScaleFactor
, float pageScaleFactor
)
473 setScale(layer
, deviceScaleFactor
, pageScaleFactor
);
475 LayerChromium
* maskLayer
= layer
->maskLayer();
477 setScale(maskLayer
, deviceScaleFactor
, pageScaleFactor
);
479 LayerChromium
* replicaMaskLayer
= layer
->replicaLayer() ? layer
->replicaLayer()->maskLayer() : 0;
480 if (replicaMaskLayer
)
481 setScale(replicaMaskLayer
, deviceScaleFactor
, pageScaleFactor
);
483 const Vector
<RefPtr
<LayerChromium
> >& children
= layer
->children();
484 for (unsigned int i
= 0; i
< children
.size(); ++i
)
485 updateLayerScale(children
[i
].get(), deviceScaleFactor
, pageScaleFactor
);
488 void CCLayerTreeHost::updateLayers(LayerChromium
* rootLayer
, CCTextureUpdateQueue
& queue
)
490 TRACE_EVENT0("cc", "CCLayerTreeHost::updateLayers");
492 updateLayerScale(rootLayer
, m_deviceScaleFactor
, m_pageScaleFactor
);
494 LayerList updateList
;
497 TRACE_EVENT0("cc", "CCLayerTreeHost::updateLayers::calcDrawEtc");
498 CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer
, deviceViewportSize(), m_deviceScaleFactor
, rendererCapabilities().maxTextureSize
, updateList
);
499 CCLayerTreeHostCommon::calculateVisibleRects(updateList
);
502 // Reset partial texture update requests.
503 m_partialTextureUpdateRequests
= 0;
505 bool needMoreUpdates
= paintLayerContents(updateList
, queue
);
506 if (m_triggerIdleUpdates
&& needMoreUpdates
)
509 for (size_t i
= 0; i
< updateList
.size(); ++i
)
510 updateList
[i
]->clearRenderSurface();
513 void CCLayerTreeHost::setPrioritiesForSurfaces(size_t surfaceMemoryBytes
)
515 // Surfaces have a place holder for their memory since they are managed
516 // independantly but should still be tracked and reduce other memory usage.
517 m_surfaceMemoryPlaceholder
->setTextureManager(m_contentsTextureManager
.get());
518 m_surfaceMemoryPlaceholder
->setRequestPriority(CCPriorityCalculator::renderSurfacePriority());
519 m_surfaceMemoryPlaceholder
->setToSelfManagedMemoryPlaceholder(surfaceMemoryBytes
);
522 void CCLayerTreeHost::setPrioritiesForLayers(const LayerList
& updateList
)
524 // Use BackToFront since it's cheap and this isn't order-dependent.
525 typedef CCLayerIterator
<LayerChromium
, Vector
<RefPtr
<LayerChromium
> >, RenderSurfaceChromium
, CCLayerIteratorActions::BackToFront
> CCLayerIteratorType
;
527 CCPriorityCalculator calculator
;
528 CCLayerIteratorType end
= CCLayerIteratorType::end(&updateList
);
529 for (CCLayerIteratorType it
= CCLayerIteratorType::begin(&updateList
); it
!= end
; ++it
) {
530 if (it
.representsItself())
531 it
->setTexturePriorities(calculator
);
532 else if (it
.representsTargetRenderSurface()) {
534 it
->maskLayer()->setTexturePriorities(calculator
);
535 if (it
->replicaLayer() && it
->replicaLayer()->maskLayer())
536 it
->replicaLayer()->maskLayer()->setTexturePriorities(calculator
);
541 void CCLayerTreeHost::prioritizeTextures(const LayerList
& renderSurfaceLayerList
, CCOverdrawMetrics
& metrics
)
543 m_contentsTextureManager
->clearPriorities();
545 size_t memoryForRenderSurfacesMetric
= calculateMemoryForRenderSurfaces(renderSurfaceLayerList
);
547 setPrioritiesForLayers(renderSurfaceLayerList
);
548 setPrioritiesForSurfaces(memoryForRenderSurfacesMetric
);
550 metrics
.didUseContentsTextureMemoryBytes(m_contentsTextureManager
->memoryAboveCutoffBytes());
551 metrics
.didUseRenderSurfaceTextureMemoryBytes(memoryForRenderSurfacesMetric
);
553 m_contentsTextureManager
->prioritizeTextures();
556 size_t CCLayerTreeHost::calculateMemoryForRenderSurfaces(const LayerList
& updateList
)
558 size_t readbackBytes
= 0;
559 size_t maxBackgroundTextureBytes
= 0;
560 size_t contentsTextureBytes
= 0;
562 // Start iteration at 1 to skip the root surface as it does not have a texture cost.
563 for (size_t i
= 1; i
< updateList
.size(); ++i
) {
564 LayerChromium
* renderSurfaceLayer
= updateList
[i
].get();
565 RenderSurfaceChromium
* renderSurface
= renderSurfaceLayer
->renderSurface();
567 size_t bytes
= CCTexture::memorySizeBytes(renderSurface
->contentRect().size(), GraphicsContext3D::RGBA
);
568 contentsTextureBytes
+= bytes
;
570 if (renderSurfaceLayer
->backgroundFilters().isEmpty())
573 if (bytes
> maxBackgroundTextureBytes
)
574 maxBackgroundTextureBytes
= bytes
;
576 readbackBytes
= CCTexture::memorySizeBytes(m_deviceViewportSize
, GraphicsContext3D::RGBA
);
578 return readbackBytes
+ maxBackgroundTextureBytes
+ contentsTextureBytes
;
581 bool CCLayerTreeHost::paintMasksForRenderSurface(LayerChromium
* renderSurfaceLayer
, CCTextureUpdateQueue
& queue
)
583 // Note: Masks and replicas only exist for layers that own render surfaces. If we reach this point
584 // in code, we already know that at least something will be drawn into this render surface, so the
585 // mask and replica should be painted.
587 bool needMoreUpdates
= false;
588 LayerChromium
* maskLayer
= renderSurfaceLayer
->maskLayer();
590 maskLayer
->update(queue
, 0, m_renderingStats
);
591 needMoreUpdates
|= maskLayer
->needMoreUpdates();
594 LayerChromium
* replicaMaskLayer
= renderSurfaceLayer
->replicaLayer() ? renderSurfaceLayer
->replicaLayer()->maskLayer() : 0;
595 if (replicaMaskLayer
) {
596 replicaMaskLayer
->update(queue
, 0, m_renderingStats
);
597 needMoreUpdates
|= replicaMaskLayer
->needMoreUpdates();
599 return needMoreUpdates
;
602 bool CCLayerTreeHost::paintLayerContents(const LayerList
& renderSurfaceLayerList
, CCTextureUpdateQueue
& queue
)
604 // Use FrontToBack to allow for testing occlusion and performing culling during the tree walk.
605 typedef CCLayerIterator
<LayerChromium
, Vector
<RefPtr
<LayerChromium
> >, RenderSurfaceChromium
, CCLayerIteratorActions::FrontToBack
> CCLayerIteratorType
;
607 bool needMoreUpdates
= false;
608 bool recordMetricsForFrame
= true; // FIXME: In the future, disable this when about:tracing is off.
609 CCOcclusionTracker
occlusionTracker(m_rootLayer
->renderSurface()->contentRect(), recordMetricsForFrame
);
610 occlusionTracker
.setMinimumTrackingSize(m_settings
.minimumOcclusionTrackingSize
);
612 prioritizeTextures(renderSurfaceLayerList
, occlusionTracker
.overdrawMetrics());
614 CCLayerIteratorType end
= CCLayerIteratorType::end(&renderSurfaceLayerList
);
615 for (CCLayerIteratorType it
= CCLayerIteratorType::begin(&renderSurfaceLayerList
); it
!= end
; ++it
) {
616 occlusionTracker
.enterLayer(it
);
618 if (it
.representsTargetRenderSurface()) {
619 ASSERT(it
->renderSurface()->drawOpacity() || it
->renderSurface()->drawOpacityIsAnimating());
620 needMoreUpdates
|= paintMasksForRenderSurface(*it
, queue
);
621 } else if (it
.representsItself()) {
622 ASSERT(!it
->bounds().isEmpty());
623 it
->update(queue
, &occlusionTracker
, m_renderingStats
);
624 needMoreUpdates
|= it
->needMoreUpdates();
627 occlusionTracker
.leaveLayer(it
);
630 occlusionTracker
.overdrawMetrics().recordMetrics(this);
632 return needMoreUpdates
;
635 static LayerChromium
* findFirstScrollableLayer(LayerChromium
* layer
)
640 if (layer
->scrollable())
643 for (size_t i
= 0; i
< layer
->children().size(); ++i
) {
644 LayerChromium
* found
= findFirstScrollableLayer(layer
->children()[i
].get());
652 void CCLayerTreeHost::applyScrollAndScale(const CCScrollAndScaleSet
& info
)
657 LayerChromium
* rootScrollLayer
= findFirstScrollableLayer(m_rootLayer
.get());
658 IntSize rootScrollDelta
;
660 for (size_t i
= 0; i
< info
.scrolls
.size(); ++i
) {
661 LayerChromium
* layer
= CCLayerTreeHostCommon::findLayerInSubtree(m_rootLayer
.get(), info
.scrolls
[i
].layerId
);
664 if (layer
== rootScrollLayer
)
665 rootScrollDelta
+= info
.scrolls
[i
].scrollDelta
;
667 layer
->setScrollPosition(layer
->scrollPosition() + info
.scrolls
[i
].scrollDelta
);
669 if (!rootScrollDelta
.isZero() || info
.pageScaleDelta
!= 1)
670 m_client
->applyScrollAndScale(rootScrollDelta
, info
.pageScaleDelta
);
673 void CCLayerTreeHost::startRateLimiter(WebKit::WebGraphicsContext3D
* context
)
679 RateLimiterMap::iterator it
= m_rateLimiters
.find(context
);
680 if (it
!= m_rateLimiters
.end())
683 RefPtr
<RateLimiter
> rateLimiter
= RateLimiter::create(context
, this);
684 m_rateLimiters
.set(context
, rateLimiter
);
685 rateLimiter
->start();
689 void CCLayerTreeHost::stopRateLimiter(WebKit::WebGraphicsContext3D
* context
)
691 RateLimiterMap::iterator it
= m_rateLimiters
.find(context
);
692 if (it
!= m_rateLimiters
.end()) {
694 m_rateLimiters
.remove(it
);
698 void CCLayerTreeHost::rateLimit()
700 // Force a no-op command on the compositor context, so that any ratelimiting commands will wait for the compositing
701 // context, and therefore for the SwapBuffers.
702 m_proxy
->forceSerializeOnSwapBuffers();
705 bool CCLayerTreeHost::bufferedUpdates()
707 return m_settings
.maxPartialTextureUpdates
!= numeric_limits
<size_t>::max();
710 bool CCLayerTreeHost::requestPartialTextureUpdate()
712 if (m_partialTextureUpdateRequests
>= m_settings
.maxPartialTextureUpdates
)
715 m_partialTextureUpdateRequests
++;
719 void CCLayerTreeHost::deleteTextureAfterCommit(PassOwnPtr
<CCPrioritizedTexture
> texture
)
721 m_deleteTextureAfterCommitList
.append(texture
);
724 void CCLayerTreeHost::setDeviceScaleFactor(float deviceScaleFactor
)
726 if (deviceScaleFactor
== m_deviceScaleFactor
)
728 m_deviceScaleFactor
= deviceScaleFactor
;
733 void CCLayerTreeHost::animateLayers(double monotonicTime
)
735 if (!CCSettings::acceleratedAnimationEnabled() || !m_needsAnimateLayers
)
738 TRACE_EVENT0("cc", "CCLayerTreeHostImpl::animateLayers");
739 m_needsAnimateLayers
= animateLayersRecursive(m_rootLayer
.get(), monotonicTime
);
742 bool CCLayerTreeHost::animateLayersRecursive(LayerChromium
* current
, double monotonicTime
)
747 bool subtreeNeedsAnimateLayers
= false;
748 CCLayerAnimationController
* currentController
= current
->layerAnimationController();
749 currentController
->animate(monotonicTime
, 0);
751 // If the current controller still has an active animation, we must continue animating layers.
752 if (currentController
->hasActiveAnimation())
753 subtreeNeedsAnimateLayers
= true;
755 for (size_t i
= 0; i
< current
->children().size(); ++i
) {
756 if (animateLayersRecursive(current
->children()[i
].get(), monotonicTime
))
757 subtreeNeedsAnimateLayers
= true;
760 return subtreeNeedsAnimateLayers
;
763 void CCLayerTreeHost::setAnimationEventsRecursive(const CCAnimationEventsVector
& events
, LayerChromium
* layer
, double wallClockTime
)
768 for (size_t eventIndex
= 0; eventIndex
< events
.size(); ++eventIndex
) {
769 if (layer
->id() == events
[eventIndex
].layerId
) {
770 if (events
[eventIndex
].type
== CCAnimationEvent::Started
)
771 layer
->notifyAnimationStarted(events
[eventIndex
], wallClockTime
);
773 layer
->notifyAnimationFinished(wallClockTime
);
777 for (size_t childIndex
= 0; childIndex
< layer
->children().size(); ++childIndex
)
778 setAnimationEventsRecursive(events
, layer
->children()[childIndex
].get(), wallClockTime
);
781 } // namespace WebCore