Remove extra line from unit_tests.isolate
[chromium-blink-merge.git] / cc / CCLayerTreeHost.cpp
blobd75a3d36b784a3d7ed2036180797409ff2073b01
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.
5 #include "config.h"
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"
24 #include "Region.h"
25 #include "TraceEvent.h"
26 #include "TreeSynchronizer.h"
28 using namespace std;
29 using WebKit::WebTransformationMatrix;
31 namespace {
32 static int numLayerTreeInstances;
35 namespace cc {
37 bool CCLayerTreeHost::s_needsFilterContext = false;
39 CCLayerTreeSettings::CCLayerTreeSettings()
40 : acceleratePainting(false)
41 , showFPSCounter(false)
42 , showPlatformLayerTree(false)
43 , showPaintRects(false)
44 , showPropertyChangedRects(false)
45 , showSurfaceDamageRects(false)
46 , showScreenSpaceRects(false)
47 , showReplicaScreenSpaceRects(false)
48 , showOccludingRects(false)
49 , renderVSyncEnabled(true)
50 , refreshRate(0)
51 , maxPartialTextureUpdates(std::numeric_limits<size_t>::max())
52 , defaultTileSize(IntSize(256, 256))
53 , maxUntiledLayerSize(IntSize(512, 512))
54 , minimumOcclusionTrackingSize(IntSize(160, 160))
58 CCLayerTreeSettings::~CCLayerTreeSettings()
62 RendererCapabilities::RendererCapabilities()
63 : bestTextureFormat(0)
64 , contextHasCachedFrontBuffer(false)
65 , usingPartialSwap(false)
66 , usingAcceleratedPainting(false)
67 , usingSetVisibility(false)
68 , usingSwapCompleteCallback(false)
69 , usingGpuMemoryManager(false)
70 , usingDiscardFramebuffer(false)
71 , usingEglImage(false)
72 , maxTextureSize(0)
76 RendererCapabilities::~RendererCapabilities()
80 bool CCLayerTreeHost::anyLayerTreeHostInstanceExists()
82 return numLayerTreeInstances > 0;
85 scoped_ptr<CCLayerTreeHost> CCLayerTreeHost::create(CCLayerTreeHostClient* client, const CCLayerTreeSettings& settings)
87 scoped_ptr<CCLayerTreeHost> layerTreeHost(new CCLayerTreeHost(client, settings));
88 if (!layerTreeHost->initialize())
89 return scoped_ptr<CCLayerTreeHost>();
90 return layerTreeHost.Pass();
93 CCLayerTreeHost::CCLayerTreeHost(CCLayerTreeHostClient* client, const CCLayerTreeSettings& settings)
94 : m_animating(false)
95 , m_needsAnimateLayers(false)
96 , m_client(client)
97 , m_commitNumber(0)
98 , m_renderingStats()
99 , m_rendererInitialized(false)
100 , m_contextLost(false)
101 , m_numTimesRecreateShouldFail(0)
102 , m_numFailedRecreateAttempts(0)
103 , m_settings(settings)
104 , m_deviceScaleFactor(1)
105 , m_visible(true)
106 , m_pageScaleFactor(1)
107 , m_minPageScaleFactor(1)
108 , m_maxPageScaleFactor(1)
109 , m_triggerIdleUpdates(true)
110 , m_backgroundColor(SK_ColorWHITE)
111 , m_hasTransparentBackground(false)
112 , m_partialTextureUpdateRequests(0)
114 ASSERT(CCProxy::isMainThread());
115 numLayerTreeInstances++;
118 bool CCLayerTreeHost::initialize()
120 TRACE_EVENT0("cc", "CCLayerTreeHost::initialize");
122 if (CCProxy::hasImplThread())
123 m_proxy = CCThreadProxy::create(this);
124 else
125 m_proxy = CCSingleThreadProxy::create(this);
126 m_proxy->start();
128 return m_proxy->initializeContext();
131 CCLayerTreeHost::~CCLayerTreeHost()
133 if (m_rootLayer)
134 m_rootLayer->setLayerTreeHost(0);
135 ASSERT(CCProxy::isMainThread());
136 TRACE_EVENT0("cc", "CCLayerTreeHost::~CCLayerTreeHost");
137 ASSERT(m_proxy.get());
138 m_proxy->stop();
139 m_proxy.reset();
140 numLayerTreeInstances--;
141 RateLimiterMap::iterator it = m_rateLimiters.begin();
142 if (it != m_rateLimiters.end())
143 it->second->stop();
146 void CCLayerTreeHost::setSurfaceReady()
148 m_proxy->setSurfaceReady();
151 void CCLayerTreeHost::initializeRenderer()
153 TRACE_EVENT0("cc", "CCLayerTreeHost::initializeRenderer");
154 if (!m_proxy->initializeRenderer()) {
155 // Uh oh, better tell the client that we can't do anything with this context.
156 m_client->didRecreateOutputSurface(false);
157 return;
160 // Update m_settings based on capabilities that we got back from the renderer.
161 m_settings.acceleratePainting = m_proxy->rendererCapabilities().usingAcceleratedPainting;
163 // Update m_settings based on partial update capability.
164 m_settings.maxPartialTextureUpdates = min(m_settings.maxPartialTextureUpdates, m_proxy->maxPartialTextureUpdates());
166 m_contentsTextureManager = CCPrioritizedTextureManager::create(0, m_proxy->rendererCapabilities().maxTextureSize, CCRenderer::ContentPool);
167 m_surfaceMemoryPlaceholder = m_contentsTextureManager->createTexture(IntSize(), GraphicsContext3D::RGBA);
169 m_rendererInitialized = true;
171 m_settings.defaultTileSize = IntSize(min(m_settings.defaultTileSize.width(), m_proxy->rendererCapabilities().maxTextureSize),
172 min(m_settings.defaultTileSize.height(), m_proxy->rendererCapabilities().maxTextureSize));
173 m_settings.maxUntiledLayerSize = IntSize(min(m_settings.maxUntiledLayerSize.width(), m_proxy->rendererCapabilities().maxTextureSize),
174 min(m_settings.maxUntiledLayerSize.height(), m_proxy->rendererCapabilities().maxTextureSize));
177 CCLayerTreeHost::RecreateResult CCLayerTreeHost::recreateContext()
179 TRACE_EVENT0("cc", "CCLayerTreeHost::recreateContext");
180 ASSERT(m_contextLost);
182 bool recreated = false;
183 if (!m_numTimesRecreateShouldFail)
184 recreated = m_proxy->recreateContext();
185 else
186 m_numTimesRecreateShouldFail--;
188 if (recreated) {
189 m_client->didRecreateOutputSurface(true);
190 m_contextLost = false;
191 return RecreateSucceeded;
194 // Tolerate a certain number of recreation failures to work around races
195 // in the context-lost machinery.
196 m_numFailedRecreateAttempts++;
197 if (m_numFailedRecreateAttempts < 5) {
198 // FIXME: The single thread does not self-schedule context
199 // recreation. So force another recreation attempt to happen by requesting
200 // another commit.
201 if (!CCProxy::hasImplThread())
202 setNeedsCommit();
203 return RecreateFailedButTryAgain;
206 // We have tried too many times to recreate the context. Tell the host to fall
207 // back to software rendering.
208 m_client->didRecreateOutputSurface(false);
209 return RecreateFailedAndGaveUp;
212 void CCLayerTreeHost::deleteContentsTexturesOnImplThread(CCResourceProvider* resourceProvider)
214 ASSERT(CCProxy::isImplThread());
215 if (m_rendererInitialized)
216 m_contentsTextureManager->clearAllMemory(resourceProvider);
219 void CCLayerTreeHost::acquireLayerTextures()
221 ASSERT(CCProxy::isMainThread());
222 m_proxy->acquireLayerTextures();
225 void CCLayerTreeHost::updateAnimations(double monotonicFrameBeginTime)
227 m_animating = true;
228 m_client->animate(monotonicFrameBeginTime);
229 animateLayers(monotonicFrameBeginTime);
230 m_animating = false;
232 m_renderingStats.numAnimationFrames++;
235 void CCLayerTreeHost::layout()
237 m_client->layout();
240 void CCLayerTreeHost::beginCommitOnImplThread(CCLayerTreeHostImpl* hostImpl)
242 ASSERT(CCProxy::isImplThread());
243 TRACE_EVENT0("cc", "CCLayerTreeHost::commitTo");
245 m_contentsTextureManager->reduceMemory(hostImpl->resourceProvider());
248 // This function commits the CCLayerTreeHost to an impl tree. When modifying
249 // this function, keep in mind that the function *runs* on the impl thread! Any
250 // code that is logically a main thread operation, e.g. deletion of a LayerChromium,
251 // should be delayed until the CCLayerTreeHost::commitComplete, which will run
252 // after the commit, but on the main thread.
253 void CCLayerTreeHost::finishCommitOnImplThread(CCLayerTreeHostImpl* hostImpl)
255 ASSERT(CCProxy::isImplThread());
257 hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->detachLayerTree(), hostImpl));
259 if (m_rootLayer && m_hudLayer)
260 hostImpl->setHudLayer(static_cast<CCHeadsUpDisplayLayerImpl*>(CCLayerTreeHostCommon::findLayerInSubtree(hostImpl->rootLayer(), m_hudLayer->id())));
261 else
262 hostImpl->setHudLayer(0);
264 // We may have added an animation during the tree sync. This will cause both layer tree hosts
265 // to visit their controllers.
266 if (rootLayer() && m_needsAnimateLayers)
267 hostImpl->setNeedsAnimateLayers();
269 hostImpl->setSourceFrameNumber(commitNumber());
270 hostImpl->setViewportSize(layoutViewportSize(), deviceViewportSize());
271 hostImpl->setDeviceScaleFactor(deviceScaleFactor());
272 hostImpl->setPageScaleFactorAndLimits(m_pageScaleFactor, m_minPageScaleFactor, m_maxPageScaleFactor);
273 hostImpl->setBackgroundColor(m_backgroundColor);
274 hostImpl->setHasTransparentBackground(m_hasTransparentBackground);
276 m_commitNumber++;
279 void CCLayerTreeHost::setFontAtlas(scoped_ptr<CCFontAtlas> fontAtlas)
281 m_fontAtlas = fontAtlas.Pass();
282 setNeedsCommit();
285 void CCLayerTreeHost::willCommit()
287 m_client->willCommit();
288 if (m_rootLayer && m_settings.showDebugInfo()) {
289 if (!m_hudLayer)
290 m_hudLayer = HeadsUpDisplayLayerChromium::create();
292 if (m_fontAtlas.get())
293 m_hudLayer->setFontAtlas(m_fontAtlas.Pass());
295 if (!m_hudLayer->parent())
296 m_rootLayer->addChild(m_hudLayer);
300 void CCLayerTreeHost::commitComplete()
302 m_deleteTextureAfterCommitList.clear();
303 m_client->didCommit();
306 scoped_ptr<CCGraphicsContext> CCLayerTreeHost::createContext()
308 return m_client->createOutputSurface();
311 scoped_ptr<CCInputHandler> CCLayerTreeHost::createInputHandler()
313 return m_client->createInputHandler();
316 scoped_ptr<CCLayerTreeHostImpl> CCLayerTreeHost::createLayerTreeHostImpl(CCLayerTreeHostImplClient* client)
318 return CCLayerTreeHostImpl::create(m_settings, client);
321 void CCLayerTreeHost::didLoseContext()
323 TRACE_EVENT0("cc", "CCLayerTreeHost::didLoseContext");
324 ASSERT(CCProxy::isMainThread());
325 m_contextLost = true;
326 m_numFailedRecreateAttempts = 0;
327 setNeedsCommit();
330 bool CCLayerTreeHost::compositeAndReadback(void *pixels, const IntRect& rect)
332 m_triggerIdleUpdates = false;
333 bool ret = m_proxy->compositeAndReadback(pixels, rect);
334 m_triggerIdleUpdates = true;
335 return ret;
338 void CCLayerTreeHost::finishAllRendering()
340 if (!m_rendererInitialized)
341 return;
342 m_proxy->finishAllRendering();
345 void CCLayerTreeHost::renderingStats(CCRenderingStats* stats) const
347 *stats = m_renderingStats;
348 m_proxy->renderingStats(stats);
351 const RendererCapabilities& CCLayerTreeHost::rendererCapabilities() const
353 return m_proxy->rendererCapabilities();
356 void CCLayerTreeHost::setNeedsAnimate()
358 ASSERT(CCProxy::hasImplThread());
359 m_proxy->setNeedsAnimate();
362 void CCLayerTreeHost::setNeedsCommit()
364 m_proxy->setNeedsCommit();
367 void CCLayerTreeHost::setNeedsRedraw()
369 m_proxy->setNeedsRedraw();
370 if (!CCThreadProxy::implThread())
371 m_client->scheduleComposite();
374 bool CCLayerTreeHost::commitRequested() const
376 return m_proxy->commitRequested();
379 void CCLayerTreeHost::setAnimationEvents(scoped_ptr<CCAnimationEventsVector> events, double wallClockTime)
381 ASSERT(CCThreadProxy::isMainThread());
382 setAnimationEventsRecursive(*events.get(), m_rootLayer.get(), wallClockTime);
385 void CCLayerTreeHost::didAddAnimation()
387 m_needsAnimateLayers = true;
388 m_proxy->didAddAnimation();
391 void CCLayerTreeHost::setRootLayer(scoped_refptr<LayerChromium> rootLayer)
393 if (m_rootLayer == rootLayer)
394 return;
396 if (m_rootLayer)
397 m_rootLayer->setLayerTreeHost(0);
398 m_rootLayer = rootLayer;
399 if (m_rootLayer)
400 m_rootLayer->setLayerTreeHost(this);
402 if (m_hudLayer)
403 m_hudLayer->removeFromParent();
405 setNeedsCommit();
408 void CCLayerTreeHost::setViewportSize(const IntSize& layoutViewportSize, const IntSize& deviceViewportSize)
410 if (layoutViewportSize == m_layoutViewportSize && deviceViewportSize == m_deviceViewportSize)
411 return;
413 m_layoutViewportSize = layoutViewportSize;
414 m_deviceViewportSize = deviceViewportSize;
416 setNeedsCommit();
419 void CCLayerTreeHost::setPageScaleFactorAndLimits(float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor)
421 if (pageScaleFactor == m_pageScaleFactor && minPageScaleFactor == m_minPageScaleFactor && maxPageScaleFactor == m_maxPageScaleFactor)
422 return;
424 m_pageScaleFactor = pageScaleFactor;
425 m_minPageScaleFactor = minPageScaleFactor;
426 m_maxPageScaleFactor = maxPageScaleFactor;
427 setNeedsCommit();
430 void CCLayerTreeHost::setVisible(bool visible)
432 if (m_visible == visible)
433 return;
434 m_visible = visible;
435 m_proxy->setVisible(visible);
438 void CCLayerTreeHost::reduceContentsTexturesMemoryOnImplThread(size_t limitBytes, CCResourceProvider* resourceProvider)
440 ASSERT(CCProxy::isImplThread());
441 ASSERT(m_contentsTextureManager.get());
442 m_contentsTextureManager->reduceMemoryOnImplThread(limitBytes, resourceProvider);
445 bool CCLayerTreeHost::evictedContentsTexturesBackingsExist() const
447 ASSERT(CCProxy::isImplThread());
448 ASSERT(m_contentsTextureManager.get());
449 return m_contentsTextureManager->evictedBackingsExist();
452 void CCLayerTreeHost::getEvictedContentTexturesBackings(CCPrioritizedTextureManager::BackingVector& evictedBackings)
454 ASSERT(CCProxy::isImplThread());
455 evictedBackings.clear();
456 if (m_rendererInitialized)
457 m_contentsTextureManager->getEvictedBackings(evictedBackings);
460 void CCLayerTreeHost::unlinkEvictedContentTexturesBackings(const CCPrioritizedTextureManager::BackingVector& evictedBackings)
462 ASSERT(CCProxy::isMainThread());
463 ASSERT(m_contentsTextureManager.get());
464 m_contentsTextureManager->unlinkEvictedBackings(evictedBackings);
467 bool CCLayerTreeHost::deleteEvictedContentTexturesBackings()
469 ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
470 ASSERT(m_contentsTextureManager.get());
471 return m_contentsTextureManager->deleteEvictedBackings();
474 void CCLayerTreeHost::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double durationSec)
476 m_proxy->startPageScaleAnimation(targetPosition, useAnchor, scale, durationSec);
479 void CCLayerTreeHost::loseContext(int numTimes)
481 TRACE_EVENT1("cc", "CCLayerTreeHost::loseCompositorContext", "numTimes", numTimes);
482 m_numTimesRecreateShouldFail = numTimes - 1;
483 m_proxy->loseContext();
486 CCPrioritizedTextureManager* CCLayerTreeHost::contentsTextureManager() const
488 return m_contentsTextureManager.get();
491 void CCLayerTreeHost::composite()
493 ASSERT(!CCThreadProxy::implThread());
494 static_cast<CCSingleThreadProxy*>(m_proxy.get())->compositeImmediately();
497 void CCLayerTreeHost::scheduleComposite()
499 m_client->scheduleComposite();
502 bool CCLayerTreeHost::initializeRendererIfNeeded()
504 if (!m_rendererInitialized) {
505 initializeRenderer();
506 // If we couldn't initialize, then bail since we're returning to software mode.
507 if (!m_rendererInitialized)
508 return false;
510 if (m_contextLost) {
511 if (recreateContext() != RecreateSucceeded)
512 return false;
514 return true;
517 void CCLayerTreeHost::updateLayers(CCTextureUpdateQueue& queue, size_t memoryAllocationLimitBytes)
519 ASSERT(m_rendererInitialized);
520 ASSERT(memoryAllocationLimitBytes);
522 if (!rootLayer())
523 return;
525 if (layoutViewportSize().isEmpty())
526 return;
528 m_contentsTextureManager->setMaxMemoryLimitBytes(memoryAllocationLimitBytes);
530 updateLayers(rootLayer(), queue);
533 static void setScale(LayerChromium* layer, float deviceScaleFactor, float pageScaleFactor)
535 if (layer->boundsContainPageScale())
536 layer->setContentsScale(deviceScaleFactor);
537 else
538 layer->setContentsScale(deviceScaleFactor * pageScaleFactor);
541 static LayerChromium* findFirstScrollableLayer(LayerChromium* layer)
543 if (!layer)
544 return 0;
546 if (layer->scrollable())
547 return layer;
549 for (size_t i = 0; i < layer->children().size(); ++i) {
550 LayerChromium* found = findFirstScrollableLayer(layer->children()[i].get());
551 if (found)
552 return found;
555 return 0;
558 static void updateLayerScale(LayerChromium* layer, float deviceScaleFactor, float pageScaleFactor)
560 setScale(layer, deviceScaleFactor, pageScaleFactor);
562 LayerChromium* maskLayer = layer->maskLayer();
563 if (maskLayer)
564 setScale(maskLayer, deviceScaleFactor, pageScaleFactor);
566 LayerChromium* replicaMaskLayer = layer->replicaLayer() ? layer->replicaLayer()->maskLayer() : 0;
567 if (replicaMaskLayer)
568 setScale(replicaMaskLayer, deviceScaleFactor, pageScaleFactor);
570 const std::vector<scoped_refptr<LayerChromium> >& children = layer->children();
571 for (unsigned int i = 0; i < children.size(); ++i)
572 updateLayerScale(children[i].get(), deviceScaleFactor, pageScaleFactor);
575 void CCLayerTreeHost::updateLayers(LayerChromium* rootLayer, CCTextureUpdateQueue& queue)
577 TRACE_EVENT0("cc", "CCLayerTreeHost::updateLayers");
579 updateLayerScale(rootLayer, m_deviceScaleFactor, m_pageScaleFactor);
581 LayerList updateList;
584 if (CCSettings::pageScalePinchZoomEnabled()) {
585 LayerChromium* rootScroll = findFirstScrollableLayer(rootLayer);
586 if (rootScroll)
587 rootScroll->setImplTransform(m_implTransform);
590 TRACE_EVENT0("cc", "CCLayerTreeHost::updateLayers::calcDrawEtc");
591 CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, deviceViewportSize(), m_deviceScaleFactor, rendererCapabilities().maxTextureSize, updateList);
594 // Reset partial texture update requests.
595 m_partialTextureUpdateRequests = 0;
597 bool needMoreUpdates = paintLayerContents(updateList, queue);
598 if (m_triggerIdleUpdates && needMoreUpdates)
599 setNeedsCommit();
601 for (size_t i = 0; i < updateList.size(); ++i)
602 updateList[i]->clearRenderSurface();
605 void CCLayerTreeHost::setPrioritiesForSurfaces(size_t surfaceMemoryBytes)
607 // Surfaces have a place holder for their memory since they are managed
608 // independantly but should still be tracked and reduce other memory usage.
609 m_surfaceMemoryPlaceholder->setTextureManager(m_contentsTextureManager.get());
610 m_surfaceMemoryPlaceholder->setRequestPriority(CCPriorityCalculator::renderSurfacePriority());
611 m_surfaceMemoryPlaceholder->setToSelfManagedMemoryPlaceholder(surfaceMemoryBytes);
614 void CCLayerTreeHost::setPrioritiesForLayers(const LayerList& updateList)
616 // Use BackToFront since it's cheap and this isn't order-dependent.
617 typedef CCLayerIterator<LayerChromium, LayerList, RenderSurfaceChromium, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
619 CCPriorityCalculator calculator;
620 CCLayerIteratorType end = CCLayerIteratorType::end(&updateList);
621 for (CCLayerIteratorType it = CCLayerIteratorType::begin(&updateList); it != end; ++it) {
622 if (it.representsItself())
623 it->setTexturePriorities(calculator);
624 else if (it.representsTargetRenderSurface()) {
625 if (it->maskLayer())
626 it->maskLayer()->setTexturePriorities(calculator);
627 if (it->replicaLayer() && it->replicaLayer()->maskLayer())
628 it->replicaLayer()->maskLayer()->setTexturePriorities(calculator);
633 void CCLayerTreeHost::prioritizeTextures(const LayerList& renderSurfaceLayerList, CCOverdrawMetrics& metrics)
635 m_contentsTextureManager->clearPriorities();
637 size_t memoryForRenderSurfacesMetric = calculateMemoryForRenderSurfaces(renderSurfaceLayerList);
639 setPrioritiesForLayers(renderSurfaceLayerList);
640 setPrioritiesForSurfaces(memoryForRenderSurfacesMetric);
642 metrics.didUseContentsTextureMemoryBytes(m_contentsTextureManager->memoryAboveCutoffBytes());
643 metrics.didUseRenderSurfaceTextureMemoryBytes(memoryForRenderSurfacesMetric);
645 m_contentsTextureManager->prioritizeTextures();
648 size_t CCLayerTreeHost::calculateMemoryForRenderSurfaces(const LayerList& updateList)
650 size_t readbackBytes = 0;
651 size_t maxBackgroundTextureBytes = 0;
652 size_t contentsTextureBytes = 0;
654 // Start iteration at 1 to skip the root surface as it does not have a texture cost.
655 for (size_t i = 1; i < updateList.size(); ++i) {
656 LayerChromium* renderSurfaceLayer = updateList[i].get();
657 RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
659 size_t bytes = CCTexture::memorySizeBytes(renderSurface->contentRect().size(), GraphicsContext3D::RGBA);
660 contentsTextureBytes += bytes;
662 if (renderSurfaceLayer->backgroundFilters().isEmpty())
663 continue;
665 if (bytes > maxBackgroundTextureBytes)
666 maxBackgroundTextureBytes = bytes;
667 if (!readbackBytes)
668 readbackBytes = CCTexture::memorySizeBytes(m_deviceViewportSize, GraphicsContext3D::RGBA);
670 return readbackBytes + maxBackgroundTextureBytes + contentsTextureBytes;
673 bool CCLayerTreeHost::paintMasksForRenderSurface(LayerChromium* renderSurfaceLayer, CCTextureUpdateQueue& queue)
675 // Note: Masks and replicas only exist for layers that own render surfaces. If we reach this point
676 // in code, we already know that at least something will be drawn into this render surface, so the
677 // mask and replica should be painted.
679 bool needMoreUpdates = false;
680 LayerChromium* maskLayer = renderSurfaceLayer->maskLayer();
681 if (maskLayer) {
682 maskLayer->update(queue, 0, m_renderingStats);
683 needMoreUpdates |= maskLayer->needMoreUpdates();
686 LayerChromium* replicaMaskLayer = renderSurfaceLayer->replicaLayer() ? renderSurfaceLayer->replicaLayer()->maskLayer() : 0;
687 if (replicaMaskLayer) {
688 replicaMaskLayer->update(queue, 0, m_renderingStats);
689 needMoreUpdates |= replicaMaskLayer->needMoreUpdates();
691 return needMoreUpdates;
694 bool CCLayerTreeHost::paintLayerContents(const LayerList& renderSurfaceLayerList, CCTextureUpdateQueue& queue)
696 // Use FrontToBack to allow for testing occlusion and performing culling during the tree walk.
697 typedef CCLayerIterator<LayerChromium, LayerList, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType;
699 bool needMoreUpdates = false;
700 bool recordMetricsForFrame = true; // FIXME: In the future, disable this when about:tracing is off.
701 CCOcclusionTracker occlusionTracker(m_rootLayer->renderSurface()->contentRect(), recordMetricsForFrame);
702 occlusionTracker.setMinimumTrackingSize(m_settings.minimumOcclusionTrackingSize);
704 prioritizeTextures(renderSurfaceLayerList, occlusionTracker.overdrawMetrics());
706 CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
707 for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
708 occlusionTracker.enterLayer(it);
710 if (it.representsTargetRenderSurface()) {
711 ASSERT(it->renderSurface()->drawOpacity() || it->renderSurface()->drawOpacityIsAnimating());
712 needMoreUpdates |= paintMasksForRenderSurface(*it, queue);
713 } else if (it.representsItself()) {
714 ASSERT(!it->bounds().isEmpty());
715 it->update(queue, &occlusionTracker, m_renderingStats);
716 needMoreUpdates |= it->needMoreUpdates();
719 occlusionTracker.leaveLayer(it);
722 occlusionTracker.overdrawMetrics().recordMetrics(this);
724 return needMoreUpdates;
727 void CCLayerTreeHost::applyScrollAndScale(const CCScrollAndScaleSet& info)
729 if (!m_rootLayer)
730 return;
732 LayerChromium* rootScrollLayer = findFirstScrollableLayer(m_rootLayer.get());
733 IntSize rootScrollDelta;
735 for (size_t i = 0; i < info.scrolls.size(); ++i) {
736 LayerChromium* layer = CCLayerTreeHostCommon::findLayerInSubtree(m_rootLayer.get(), info.scrolls[i].layerId);
737 if (!layer)
738 continue;
739 if (layer == rootScrollLayer)
740 rootScrollDelta += info.scrolls[i].scrollDelta;
741 else
742 layer->setScrollPosition(layer->scrollPosition() + info.scrolls[i].scrollDelta);
744 if (!rootScrollDelta.isZero() || info.pageScaleDelta != 1)
745 m_client->applyScrollAndScale(rootScrollDelta, info.pageScaleDelta);
748 void CCLayerTreeHost::setImplTransform(const WebKit::WebTransformationMatrix& transform)
750 m_implTransform = transform;
753 void CCLayerTreeHost::startRateLimiter(WebKit::WebGraphicsContext3D* context)
755 if (m_animating)
756 return;
758 ASSERT(context);
759 RateLimiterMap::iterator it = m_rateLimiters.find(context);
760 if (it != m_rateLimiters.end())
761 it->second->start();
762 else {
763 scoped_refptr<RateLimiter> rateLimiter = RateLimiter::create(context, this);
764 m_rateLimiters[context] = rateLimiter;
765 rateLimiter->start();
769 void CCLayerTreeHost::stopRateLimiter(WebKit::WebGraphicsContext3D* context)
771 RateLimiterMap::iterator it = m_rateLimiters.find(context);
772 if (it != m_rateLimiters.end()) {
773 it->second->stop();
774 m_rateLimiters.erase(it);
778 void CCLayerTreeHost::rateLimit()
780 // Force a no-op command on the compositor context, so that any ratelimiting commands will wait for the compositing
781 // context, and therefore for the SwapBuffers.
782 m_proxy->forceSerializeOnSwapBuffers();
785 bool CCLayerTreeHost::bufferedUpdates()
787 return m_settings.maxPartialTextureUpdates != numeric_limits<size_t>::max();
790 bool CCLayerTreeHost::requestPartialTextureUpdate()
792 if (m_partialTextureUpdateRequests >= m_settings.maxPartialTextureUpdates)
793 return false;
795 m_partialTextureUpdateRequests++;
796 return true;
799 void CCLayerTreeHost::deleteTextureAfterCommit(scoped_ptr<CCPrioritizedTexture> texture)
801 m_deleteTextureAfterCommitList.append(texture.Pass());
804 void CCLayerTreeHost::setDeviceScaleFactor(float deviceScaleFactor)
806 if (deviceScaleFactor == m_deviceScaleFactor)
807 return;
808 m_deviceScaleFactor = deviceScaleFactor;
810 setNeedsCommit();
813 void CCLayerTreeHost::animateLayers(double monotonicTime)
815 if (!CCSettings::acceleratedAnimationEnabled() || !m_needsAnimateLayers)
816 return;
818 TRACE_EVENT0("cc", "CCLayerTreeHostImpl::animateLayers");
819 m_needsAnimateLayers = animateLayersRecursive(m_rootLayer.get(), monotonicTime);
822 bool CCLayerTreeHost::animateLayersRecursive(LayerChromium* current, double monotonicTime)
824 if (!current)
825 return false;
827 bool subtreeNeedsAnimateLayers = false;
828 CCLayerAnimationController* currentController = current->layerAnimationController();
829 currentController->animate(monotonicTime, 0);
831 // If the current controller still has an active animation, we must continue animating layers.
832 if (currentController->hasActiveAnimation())
833 subtreeNeedsAnimateLayers = true;
835 for (size_t i = 0; i < current->children().size(); ++i) {
836 if (animateLayersRecursive(current->children()[i].get(), monotonicTime))
837 subtreeNeedsAnimateLayers = true;
840 return subtreeNeedsAnimateLayers;
843 void CCLayerTreeHost::setAnimationEventsRecursive(const CCAnimationEventsVector& events, LayerChromium* layer, double wallClockTime)
845 if (!layer)
846 return;
848 for (size_t eventIndex = 0; eventIndex < events.size(); ++eventIndex) {
849 if (layer->id() == events[eventIndex].layerId) {
850 if (events[eventIndex].type == CCAnimationEvent::Started)
851 layer->notifyAnimationStarted(events[eventIndex], wallClockTime);
852 else
853 layer->notifyAnimationFinished(wallClockTime);
857 for (size_t childIndex = 0; childIndex < layer->children().size(); ++childIndex)
858 setAnimationEventsRecursive(events, layer->children()[childIndex].get(), wallClockTime);
861 } // namespace cc