[Chromium] Compositor doesn't support translucent root layers.
[WebKit-https.git] / Source / WebCore / platform / graphics / chromium / cc / CCLayerTreeHost.cpp
1 /*
2  * Copyright (C) 2011 Google 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'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "cc/CCLayerTreeHost.h"
28
29 #include "LayerChromium.h"
30 #include "LayerPainterChromium.h"
31 #include "LayerRendererChromium.h"
32 #include "Region.h"
33 #include "TraceEvent.h"
34 #include "TreeSynchronizer.h"
35 #include "cc/CCFontAtlas.h"
36 #include "cc/CCLayerAnimationController.h"
37 #include "cc/CCLayerIterator.h"
38 #include "cc/CCLayerTreeHostCommon.h"
39 #include "cc/CCLayerTreeHostImpl.h"
40 #include "cc/CCOcclusionTracker.h"
41 #include "cc/CCSingleThreadProxy.h"
42 #include "cc/CCThread.h"
43 #include "cc/CCThreadProxy.h"
44
45 using namespace std;
46 using WebKit::WebTransformationMatrix;
47
48 namespace {
49 static int numLayerTreeInstances;
50 }
51
52 namespace WebCore {
53
54 bool CCLayerTreeHost::s_needsFilterContext = false;
55
56 bool CCLayerTreeHost::anyLayerTreeHostInstanceExists()
57 {
58     return numLayerTreeInstances > 0;
59 }
60
61 PassOwnPtr<CCLayerTreeHost> CCLayerTreeHost::create(CCLayerTreeHostClient* client, const CCSettings& settings)
62 {
63     OwnPtr<CCLayerTreeHost> layerTreeHost = adoptPtr(new CCLayerTreeHost(client, settings));
64     if (!layerTreeHost->initialize())
65         return nullptr;
66     return layerTreeHost.release();
67 }
68
69 CCLayerTreeHost::CCLayerTreeHost(CCLayerTreeHostClient* client, const CCSettings& settings)
70     : m_compositorIdentifier(-1)
71     , m_animating(false)
72     , m_needsAnimateLayers(false)
73     , m_client(client)
74     , m_frameNumber(0)
75     , m_frameIsForDisplay(false)
76     , m_layerRendererInitialized(false)
77     , m_contextLost(false)
78     , m_numTimesRecreateShouldFail(0)
79     , m_numFailedRecreateAttempts(0)
80     , m_settings(settings)
81     , m_visible(true)
82     , m_memoryAllocationBytes(0)
83     , m_memoryAllocationIsForDisplay(false)
84     , m_pageScaleFactor(1)
85     , m_minPageScaleFactor(1)
86     , m_maxPageScaleFactor(1)
87     , m_triggerIdlePaints(true)
88     , m_backgroundColor(Color::white)
89     , m_hasTransparentBackground(false)
90     , m_partialTextureUpdateRequests(0)
91 {
92     ASSERT(CCProxy::isMainThread());
93     numLayerTreeInstances++;
94 }
95
96 bool CCLayerTreeHost::initialize()
97 {
98     TRACE_EVENT("CCLayerTreeHost::initialize", this, 0);
99
100     if (CCProxy::hasImplThread())
101         m_proxy = CCThreadProxy::create(this);
102     else
103         m_proxy = CCSingleThreadProxy::create(this);
104     m_proxy->start();
105
106     if (!m_proxy->initializeContext())
107         return false;
108
109     // Only allocate the font atlas if we have reason to use the heads-up display.
110     if (m_settings.showFPSCounter || m_settings.showPlatformLayerTree) {
111         TRACE_EVENT0("cc", "CCLayerTreeHost::initialize::initializeFontAtlas");
112         OwnPtr<CCFontAtlas> fontAtlas(CCFontAtlas::create());
113         fontAtlas->initialize();
114         m_proxy->setFontAtlas(fontAtlas.release());
115     }
116
117     m_compositorIdentifier = m_proxy->compositorIdentifier();
118     return true;
119 }
120
121 CCLayerTreeHost::~CCLayerTreeHost()
122 {
123     ASSERT(CCProxy::isMainThread());
124     TRACE_EVENT("CCLayerTreeHost::~CCLayerTreeHost", this, 0);
125     ASSERT(m_proxy);
126     m_proxy->stop();
127     m_proxy.clear();
128     numLayerTreeInstances--;
129 }
130
131 void CCLayerTreeHost::setSurfaceReady()
132 {
133     m_proxy->setSurfaceReady();
134 }
135
136 void CCLayerTreeHost::initializeLayerRenderer()
137 {
138     TRACE_EVENT("CCLayerTreeHost::initializeLayerRenderer", this, 0);
139     if (!m_proxy->initializeLayerRenderer()) {
140         // Uh oh, better tell the client that we can't do anything with this context.
141         m_client->didRecreateContext(false);
142         return;
143     }
144
145     // Update m_settings based on capabilities that we got back from the renderer.
146     m_settings.acceleratePainting = m_proxy->layerRendererCapabilities().usingAcceleratedPainting;
147
148     // Update m_settings based on partial update capability.
149     m_settings.maxPartialTextureUpdates = min(m_settings.maxPartialTextureUpdates, m_proxy->maxPartialTextureUpdates());
150
151     m_contentsTextureManager = TextureManager::create(0, 0, m_proxy->layerRendererCapabilities().maxTextureSize);
152
153     // FIXME: This is the same as setContentsMemoryAllocationLimitBytes, but
154     // we're in the middle of a commit here and don't want to force another.
155     m_memoryAllocationBytes = TextureManager::highLimitBytes(deviceViewportSize());
156     m_memoryAllocationIsForDisplay = true;
157
158     m_layerRendererInitialized = true;
159
160     m_settings.defaultTileSize = IntSize(min(m_settings.defaultTileSize.width(), m_proxy->layerRendererCapabilities().maxTextureSize),
161                                          min(m_settings.defaultTileSize.height(), m_proxy->layerRendererCapabilities().maxTextureSize));
162     m_settings.maxUntiledLayerSize = IntSize(min(m_settings.maxUntiledLayerSize.width(), m_proxy->layerRendererCapabilities().maxTextureSize),
163                                              min(m_settings.maxUntiledLayerSize.height(), m_proxy->layerRendererCapabilities().maxTextureSize));
164 }
165
166 CCLayerTreeHost::RecreateResult CCLayerTreeHost::recreateContext()
167 {
168     TRACE_EVENT0("cc", "CCLayerTreeHost::recreateContext");
169     ASSERT(m_contextLost);
170
171     bool recreated = false;
172     if (!m_numTimesRecreateShouldFail)
173         recreated = m_proxy->recreateContext();
174     else
175         m_numTimesRecreateShouldFail--;
176
177     if (recreated) {
178         m_client->didRecreateContext(true);
179         m_contextLost = false;
180         return RecreateSucceeded;
181     }
182
183     // Tolerate a certain number of recreation failures to work around races
184     // in the context-lost machinery.
185     m_numFailedRecreateAttempts++;
186     if (m_numFailedRecreateAttempts < 5) {
187         // FIXME: The single thread does not self-schedule context
188         // recreation. So force another recreation attempt to happen by requesting
189         // another commit.
190         if (!CCProxy::hasImplThread())
191             setNeedsCommit();
192         return RecreateFailedButTryAgain;
193     }
194
195     // We have tried too many times to recreate the context. Tell the host to fall
196     // back to software rendering.
197     m_client->didRecreateContext(false);
198     return RecreateFailedAndGaveUp;
199 }
200
201 void CCLayerTreeHost::deleteContentsTexturesOnImplThread(TextureAllocator* allocator)
202 {
203     ASSERT(CCProxy::isImplThread());
204     if (m_layerRendererInitialized)
205         m_contentsTextureManager->evictAndDeleteAllTextures(allocator);
206 }
207
208 void CCLayerTreeHost::acquireLayerTextures()
209 {
210     ASSERT(CCProxy::isMainThread());
211     m_proxy->acquireLayerTextures();
212 }
213
214 void CCLayerTreeHost::updateAnimations(double monotonicFrameBeginTime)
215 {
216     m_animating = true;
217     m_client->updateAnimations(monotonicFrameBeginTime);
218     animateLayers(monotonicFrameBeginTime);
219     m_animating = false;
220 }
221
222 void CCLayerTreeHost::layout()
223 {
224     m_client->layout();
225 }
226
227 void CCLayerTreeHost::beginCommitOnImplThread(CCLayerTreeHostImpl* hostImpl)
228 {
229     ASSERT(CCProxy::isImplThread());
230     TRACE_EVENT("CCLayerTreeHost::commitTo", this, 0);
231
232     m_contentsTextureManager->reduceMemoryToLimit(m_contentsTextureManager->preferredMemoryLimitBytes());
233     m_contentsTextureManager->deleteEvictedTextures(hostImpl->contentsTextureAllocator());
234 }
235
236 // This function commits the CCLayerTreeHost to an impl tree. When modifying
237 // this function, keep in mind that the function *runs* on the impl thread! Any
238 // code that is logically a main thread operation, e.g. deletion of a LayerChromium,
239 // should be delayed until the CCLayerTreeHost::commitComplete, which will run
240 // after the commit, but on the main thread.
241 void CCLayerTreeHost::finishCommitOnImplThread(CCLayerTreeHostImpl* hostImpl)
242 {
243     ASSERT(CCProxy::isImplThread());
244
245     hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->releaseRootLayer(), hostImpl));
246
247     // We may have added an animation during the tree sync. This will cause both layer tree hosts
248     // to visit their controllers.
249     if (rootLayer() && m_needsAnimateLayers)
250         hostImpl->setNeedsAnimateLayers();
251
252     hostImpl->setSourceFrameNumber(frameNumber());
253     hostImpl->setViewportSize(viewportSize());
254     hostImpl->setPageScaleFactorAndLimits(m_pageScaleFactor, m_minPageScaleFactor, m_maxPageScaleFactor);
255     hostImpl->setBackgroundColor(m_backgroundColor);
256     hostImpl->setHasTransparentBackground(m_hasTransparentBackground);
257     hostImpl->setVisible(m_visible);
258     hostImpl->setSourceFrameCanBeDrawn(m_frameIsForDisplay);
259
260     m_frameNumber++;
261 }
262
263 void CCLayerTreeHost::commitComplete()
264 {
265     m_deleteTextureAfterCommitList.clear();
266     m_contentsTextureManager->unprotectAllTextures();
267     m_client->didCommit();
268 }
269
270 PassRefPtr<CCGraphicsContext> CCLayerTreeHost::createContext()
271 {
272     RefPtr<CCGraphicsContext> context;
273     if (settings().forceSoftwareCompositing)
274         return CCGraphicsContext::create2D();
275     return CCGraphicsContext::create3D(m_client->createContext3D());
276 }
277
278 PassOwnPtr<CCLayerTreeHostImpl> CCLayerTreeHost::createLayerTreeHostImpl(CCLayerTreeHostImplClient* client)
279 {
280     return CCLayerTreeHostImpl::create(m_settings, client);
281 }
282
283 void CCLayerTreeHost::didLoseContext()
284 {
285     TRACE_EVENT("CCLayerTreeHost::didLoseContext", 0, this);
286     ASSERT(CCProxy::isMainThread());
287     m_contextLost = true;
288     m_numFailedRecreateAttempts = 0;
289     setNeedsCommit();
290 }
291
292 // Temporary hack until WebViewImpl context creation gets simplified
293 CCGraphicsContext* CCLayerTreeHost::context()
294 {
295     return m_proxy->context();
296 }
297
298 bool CCLayerTreeHost::compositeAndReadback(void *pixels, const IntRect& rect)
299 {
300     if (!m_layerRendererInitialized) {
301         initializeLayerRenderer();
302         if (!m_layerRendererInitialized)
303             return false;
304     }
305     if (m_contextLost) {
306         if (recreateContext() != RecreateSucceeded)
307             return false;
308     }
309     m_triggerIdlePaints = false;
310     bool ret = m_proxy->compositeAndReadback(pixels, rect);
311     m_triggerIdlePaints = true;
312     return ret;
313 }
314
315 void CCLayerTreeHost::finishAllRendering()
316 {
317     if (!m_layerRendererInitialized)
318         return;
319     m_proxy->finishAllRendering();
320 }
321
322 const LayerRendererCapabilities& CCLayerTreeHost::layerRendererCapabilities() const
323 {
324     return m_proxy->layerRendererCapabilities();
325 }
326
327 void CCLayerTreeHost::setNeedsAnimate()
328 {
329     ASSERT(CCProxy::hasImplThread());
330     m_proxy->setNeedsAnimate();
331 }
332
333 void CCLayerTreeHost::setNeedsCommit()
334 {
335     m_proxy->setNeedsCommit();
336 }
337
338 void CCLayerTreeHost::setNeedsForcedCommit()
339 {
340     m_proxy->setNeedsForcedCommit();
341 }
342
343 void CCLayerTreeHost::setNeedsRedraw()
344 {
345     m_proxy->setNeedsRedraw();
346     if (!CCThreadProxy::implThread())
347         m_client->scheduleComposite();
348 }
349
350 bool CCLayerTreeHost::commitRequested() const
351 {
352     return m_proxy->commitRequested();
353 }
354
355 void CCLayerTreeHost::setAnimationEvents(PassOwnPtr<CCAnimationEventsVector> events, double wallClockTime)
356 {
357     ASSERT(CCThreadProxy::isMainThread());
358     setAnimationEventsRecursive(*events, m_rootLayer.get(), wallClockTime);
359 }
360
361 void CCLayerTreeHost::didAddAnimation()
362 {
363     m_needsAnimateLayers = true;
364     m_proxy->didAddAnimation();
365 }
366
367 void CCLayerTreeHost::setRootLayer(PassRefPtr<LayerChromium> rootLayer)
368 {
369     if (m_rootLayer == rootLayer)
370         return;
371
372     if (m_rootLayer)
373         m_rootLayer->setLayerTreeHost(0);
374     m_rootLayer = rootLayer;
375     if (m_rootLayer)
376         m_rootLayer->setLayerTreeHost(this);
377     setNeedsCommit();
378 }
379
380 void CCLayerTreeHost::setViewportSize(const IntSize& viewportSize)
381 {
382     if (viewportSize == m_viewportSize)
383         return;
384
385     m_viewportSize = viewportSize;
386
387     m_deviceViewportSize = viewportSize;
388     m_deviceViewportSize.scale(m_settings.deviceScaleFactor);
389
390     setNeedsCommit();
391 }
392
393 void CCLayerTreeHost::setPageScaleFactorAndLimits(float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor)
394 {
395     if (pageScaleFactor == m_pageScaleFactor && minPageScaleFactor == m_minPageScaleFactor && maxPageScaleFactor == m_maxPageScaleFactor)
396         return;
397
398     m_pageScaleFactor = pageScaleFactor;
399     m_minPageScaleFactor = minPageScaleFactor;
400     m_maxPageScaleFactor = maxPageScaleFactor;
401     setNeedsCommit();
402 }
403
404 void CCLayerTreeHost::setVisible(bool visible)
405 {
406     if (m_visible == visible)
407         return;
408
409     m_visible = visible;
410
411     // FIXME: Remove this stuff, it is here just for the m20 merge.
412     if (!m_visible && m_layerRendererInitialized) {
413         if (m_proxy->layerRendererCapabilities().contextHasCachedFrontBuffer)
414             setContentsMemoryAllocationLimitBytes(0);
415         else
416             setContentsMemoryAllocationLimitBytes(m_contentsTextureManager->preferredMemoryLimitBytes());
417     }
418
419     setNeedsForcedCommit();
420 }
421
422 void CCLayerTreeHost::setContentsMemoryAllocationLimitBytes(size_t bytes)
423 {
424     ASSERT(CCProxy::isMainThread());
425     if (m_memoryAllocationBytes == bytes)
426         return;
427
428     m_memoryAllocationBytes = bytes;
429     m_memoryAllocationIsForDisplay = bytes;
430
431     // When not visible, force a commit so that we change our memory allocation
432     // and evict/delete any textures if we are being requested to.
433     if (!m_visible)
434         setNeedsForcedCommit();
435     else
436         setNeedsCommit();
437 }
438
439 void CCLayerTreeHost::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double durationSec)
440 {
441     m_proxy->startPageScaleAnimation(targetPosition, useAnchor, scale, durationSec);
442 }
443
444 void CCLayerTreeHost::loseContext(int numTimes)
445 {
446     TRACE_EVENT1("cc", "CCLayerTreeHost::loseCompositorContext", "numTimes", numTimes);
447     m_numTimesRecreateShouldFail = numTimes - 1;
448     m_proxy->loseContext();
449 }
450
451 TextureManager* CCLayerTreeHost::contentsTextureManager() const
452 {
453     return m_contentsTextureManager.get();
454 }
455
456 void CCLayerTreeHost::composite()
457 {
458     ASSERT(!CCThreadProxy::implThread());
459     static_cast<CCSingleThreadProxy*>(m_proxy.get())->compositeImmediately();
460 }
461
462 void CCLayerTreeHost::scheduleComposite()
463 {
464     m_client->scheduleComposite();
465 }
466
467 bool CCLayerTreeHost::updateLayers(CCTextureUpdater& updater)
468 {
469     if (!m_layerRendererInitialized) {
470         initializeLayerRenderer();
471         // If we couldn't initialize, then bail since we're returning to software mode.
472         if (!m_layerRendererInitialized)
473             return false;
474     }
475     if (m_contextLost) {
476         if (recreateContext() != RecreateSucceeded)
477             return false;
478     }
479
480     // The visible state and memory allocation are set independently and in
481     // arbitrary order, so do not change the memory allocation used for the
482     // current commit until both values match intentions.
483     // FIXME: These two states should be combined into a single action so we
484     // need a single commit to change visible state, and this can be removed.
485     bool memoryAllocationStateMatchesVisibility = m_visible == m_memoryAllocationIsForDisplay;
486     if (memoryAllocationStateMatchesVisibility) {
487         m_contentsTextureManager->setMemoryAllocationLimitBytes(m_memoryAllocationBytes);
488         m_frameIsForDisplay = m_memoryAllocationIsForDisplay;
489     }
490
491     if (!rootLayer())
492         return true;
493
494     if (viewportSize().isEmpty())
495         return true;
496
497     updateLayers(rootLayer(), updater);
498     return true;
499 }
500
501 void CCLayerTreeHost::updateLayers(LayerChromium* rootLayer, CCTextureUpdater& updater)
502 {
503     TRACE_EVENT("CCLayerTreeHost::updateLayers", this, 0);
504
505     if (!rootLayer->renderSurface())
506         rootLayer->createRenderSurface();
507     rootLayer->renderSurface()->setContentRect(IntRect(IntPoint(0, 0), deviceViewportSize()));
508
509     IntRect rootClipRect(IntPoint(), deviceViewportSize());
510     rootLayer->setClipRect(rootClipRect);
511
512     LayerList updateList;
513     updateList.append(rootLayer);
514
515     RenderSurfaceChromium* rootRenderSurface = rootLayer->renderSurface();
516     rootRenderSurface->clearLayerList();
517
518     {
519         TRACE_EVENT("CCLayerTreeHost::updateLayers::calcDrawEtc", this, 0);
520         WebTransformationMatrix identityMatrix;
521         WebTransformationMatrix deviceScaleTransform;
522         deviceScaleTransform.scale(m_settings.deviceScaleFactor);
523         CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, rootLayer, deviceScaleTransform, identityMatrix, updateList, rootRenderSurface->layerList(), layerRendererCapabilities().maxTextureSize);
524
525         FloatRect rootScissorRect(FloatPoint(0, 0), viewportSize());
526         CCLayerTreeHostCommon::calculateVisibleAndScissorRects(updateList, rootScissorRect);
527     }
528
529     // Reset partial texture update requests.
530     m_partialTextureUpdateRequests = 0;
531
532     reserveTextures(updateList);
533
534     paintLayerContents(updateList, PaintVisible, updater);
535     if (!m_triggerIdlePaints)
536         return;
537
538     size_t preferredLimitBytes = m_contentsTextureManager->preferredMemoryLimitBytes();
539     size_t maxLimitBytes = m_contentsTextureManager->maxMemoryLimitBytes();
540     m_contentsTextureManager->reduceMemoryToLimit(preferredLimitBytes);
541     if (m_contentsTextureManager->currentMemoryUseBytes() >= preferredLimitBytes)
542         return;
543
544     // Idle painting should fail when we hit the preferred memory limit,
545     // otherwise it will always push us towards the maximum limit.
546     m_contentsTextureManager->setMaxMemoryLimitBytes(preferredLimitBytes);
547     // The second (idle) paint will be a no-op in layers where painting already occured above.
548     paintLayerContents(updateList, PaintIdle, updater);
549     m_contentsTextureManager->setMaxMemoryLimitBytes(maxLimitBytes);
550
551     for (size_t i = 0; i < updateList.size(); ++i)
552         updateList[i]->clearRenderSurface();
553 }
554
555 void CCLayerTreeHost::reserveTextures(const LayerList& updateList)
556 {
557     // Use BackToFront since it's cheap and this isn't order-dependent.
558     typedef CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
559
560     CCLayerIteratorType end = CCLayerIteratorType::end(&updateList);
561     for (CCLayerIteratorType it = CCLayerIteratorType::begin(&updateList); it != end; ++it) {
562         if (!it.representsItself() || !it->alwaysReserveTextures())
563             continue;
564         it->reserveTextures();
565     }
566 }
567
568 // static
569 void CCLayerTreeHost::update(LayerChromium* layer, PaintType paintType, CCTextureUpdater& updater, const CCOcclusionTracker* occlusion)
570 {
571     ASSERT(layer);
572     ASSERT(PaintVisible == paintType || PaintIdle == paintType);
573     if (PaintVisible == paintType)
574         layer->update(updater, occlusion);
575     else
576         layer->idleUpdate(updater, occlusion);
577 }
578
579 void CCLayerTreeHost::paintMasksForRenderSurface(LayerChromium* renderSurfaceLayer, PaintType paintType, CCTextureUpdater& updater)
580 {
581     // Note: Masks and replicas only exist for layers that own render surfaces. If we reach this point
582     // in code, we already know that at least something will be drawn into this render surface, so the
583     // mask and replica should be painted.
584
585     LayerChromium* maskLayer = renderSurfaceLayer->maskLayer();
586     if (maskLayer) {
587         maskLayer->setVisibleLayerRect(IntRect(IntPoint(), renderSurfaceLayer->contentBounds()));
588         update(maskLayer, paintType, updater, 0);
589     }
590
591     LayerChromium* replicaMaskLayer = renderSurfaceLayer->replicaLayer() ? renderSurfaceLayer->replicaLayer()->maskLayer() : 0;
592     if (replicaMaskLayer) {
593         replicaMaskLayer->setVisibleLayerRect(IntRect(IntPoint(), renderSurfaceLayer->contentBounds()));
594         update(replicaMaskLayer, paintType, updater, 0);
595     }
596 }
597
598 void CCLayerTreeHost::paintLayerContents(const LayerList& renderSurfaceLayerList, PaintType paintType, CCTextureUpdater& updater)
599 {
600     // Use FrontToBack to allow for testing occlusion and performing culling during the tree walk.
601     typedef CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType;
602
603     bool recordMetricsForFrame = true; // FIXME: In the future, disable this when about:tracing is off.
604     CCOcclusionTracker occlusionTracker(IntRect(IntPoint(), deviceViewportSize()), recordMetricsForFrame);
605     occlusionTracker.setMinimumTrackingSize(CCOcclusionTracker::preferredMinimumTrackingSize());
606
607     CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
608     for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
609         occlusionTracker.enterLayer(it);
610
611         if (it.representsTargetRenderSurface()) {
612             ASSERT(it->renderSurface()->drawOpacity() || it->renderSurface()->drawOpacityIsAnimating());
613             paintMasksForRenderSurface(*it, paintType, updater);
614         } else if (it.representsItself()) {
615             ASSERT(!it->bounds().isEmpty());
616             update(*it, paintType, updater, &occlusionTracker);
617         }
618
619         occlusionTracker.leaveLayer(it);
620     }
621
622     occlusionTracker.overdrawMetrics().recordMetrics(this);
623 }
624
625 void CCLayerTreeHost::applyScrollAndScale(const CCScrollAndScaleSet& info)
626 {
627     // FIXME: pushing scroll offsets to non-root layers not implemented
628     if (!info.scrolls.size())
629         return;
630
631     ASSERT(info.scrolls.size() == 1);
632     IntSize scrollDelta = info.scrolls[0].scrollDelta;
633     m_client->applyScrollAndScale(scrollDelta, info.pageScaleDelta);
634 }
635
636 void CCLayerTreeHost::startRateLimiter(GraphicsContext3D* context)
637 {
638     if (m_animating)
639         return;
640     ASSERT(context);
641     RateLimiterMap::iterator it = m_rateLimiters.find(context);
642     if (it != m_rateLimiters.end())
643         it->second->start();
644     else {
645         RefPtr<RateLimiter> rateLimiter = RateLimiter::create(context, this);
646         m_rateLimiters.set(context, rateLimiter);
647         rateLimiter->start();
648     }
649 }
650
651 void CCLayerTreeHost::rateLimit()
652 {
653     // Force a no-op command on the compositor context, so that any ratelimiting commands will wait for the compositing
654     // context, and therefore for the SwapBuffers.
655     m_proxy->forceSerializeOnSwapBuffers();
656 }
657
658 void CCLayerTreeHost::stopRateLimiter(GraphicsContext3D* context)
659 {
660     RateLimiterMap::iterator it = m_rateLimiters.find(context);
661     if (it != m_rateLimiters.end()) {
662         it->second->stop();
663         m_rateLimiters.remove(it);
664     }
665 }
666
667 bool CCLayerTreeHost::bufferedUpdates()
668 {
669     return m_settings.maxPartialTextureUpdates != numeric_limits<size_t>::max();
670 }
671
672 bool CCLayerTreeHost::requestPartialTextureUpdate()
673 {
674     if (m_partialTextureUpdateRequests >= m_settings.maxPartialTextureUpdates)
675         return false;
676
677     m_partialTextureUpdateRequests++;
678     return true;
679 }
680
681 void CCLayerTreeHost::deleteTextureAfterCommit(PassOwnPtr<ManagedTexture> texture)
682 {
683     m_deleteTextureAfterCommitList.append(texture);
684 }
685
686 void CCLayerTreeHost::animateLayers(double monotonicTime)
687 {
688     if (!m_settings.threadedAnimationEnabled || !m_needsAnimateLayers)
689         return;
690
691     TRACE_EVENT("CCLayerTreeHostImpl::animateLayers", this, 0);
692     m_needsAnimateLayers = animateLayersRecursive(m_rootLayer.get(), monotonicTime);
693 }
694
695 bool CCLayerTreeHost::animateLayersRecursive(LayerChromium* current, double monotonicTime)
696 {
697     if (!current)
698         return false;
699
700     bool subtreeNeedsAnimateLayers = false;
701     CCLayerAnimationController* currentController = current->layerAnimationController();
702     currentController->animate(monotonicTime, 0);
703
704     // If the current controller still has an active animation, we must continue animating layers.
705     if (currentController->hasActiveAnimation())
706          subtreeNeedsAnimateLayers = true;
707
708     for (size_t i = 0; i < current->children().size(); ++i) {
709         if (animateLayersRecursive(current->children()[i].get(), monotonicTime))
710             subtreeNeedsAnimateLayers = true;
711     }
712
713     return subtreeNeedsAnimateLayers;
714 }
715
716 void CCLayerTreeHost::setAnimationEventsRecursive(const CCAnimationEventsVector& events, LayerChromium* layer, double wallClockTime)
717 {
718     if (!layer)
719         return;
720
721     for (size_t eventIndex = 0; eventIndex < events.size(); ++eventIndex) {
722         if (layer->id() == events[eventIndex].layerId) {
723             if (events[eventIndex].type == CCAnimationEvent::Started)
724                 layer->notifyAnimationStarted(events[eventIndex], wallClockTime);
725             else
726                 layer->notifyAnimationFinished(wallClockTime);
727         }
728     }
729
730     for (size_t childIndex = 0; childIndex < layer->children().size(); ++childIndex)
731         setAnimationEventsRecursive(events, layer->children()[childIndex].get(), wallClockTime);
732 }
733
734 } // namespace WebCore