blob: af9232f4395d2c8b1467a6b966b2aa35f1d63661 [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// 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.
4
5#include "config.h"
6
[email protected]4456eee22012-10-19 18:16:387#include "cc/single_thread_proxy.h"
[email protected]94f206c12012-08-25 00:09:148
9#include "CCDrawQuad.h"
10#include "CCGraphicsContext.h"
11#include "CCLayerTreeHost.h"
[email protected]6331a1172012-10-18 11:35:1312#include "base/debug/trace_event.h"
[email protected]4456eee22012-10-19 18:16:3813#include "cc/texture_update_controller.h"
[email protected]da2c9122012-10-20 23:13:0614#include "cc/timer.h"
[email protected]94f206c12012-08-25 00:09:1415#include <wtf/CurrentTime.h>
16
[email protected]9c88e562012-09-14 22:21:3017namespace cc {
[email protected]94f206c12012-08-25 00:09:1418
[email protected]c753e25a2012-10-19 21:22:4219scoped_ptr<CCProxy> CCSingleThreadProxy::create(CCLayerTreeHost* layerTreeHost)
[email protected]94f206c12012-08-25 00:09:1420{
[email protected]c753e25a2012-10-19 21:22:4221 return make_scoped_ptr(new CCSingleThreadProxy(layerTreeHost)).PassAs<CCProxy>();
[email protected]94f206c12012-08-25 00:09:1422}
23
[email protected]c753e25a2012-10-19 21:22:4224CCSingleThreadProxy::CCSingleThreadProxy(CCLayerTreeHost* layerTreeHost)
[email protected]94f206c12012-08-25 00:09:1425 : m_layerTreeHost(layerTreeHost)
26 , m_contextLost(false)
[email protected]94f206c12012-08-25 00:09:1427 , m_rendererInitialized(false)
28 , m_nextFrameIsNewlyCommittedFrame(false)
[email protected]8b9af6b2012-09-27 00:36:3629 , m_totalCommitCount(0)
[email protected]94f206c12012-08-25 00:09:1430{
[email protected]c753e25a2012-10-19 21:22:4231 TRACE_EVENT0("cc", "CCSingleThreadProxy::CCSingleThreadProxy");
32 DCHECK(CCProxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:1433}
34
[email protected]c753e25a2012-10-19 21:22:4235void CCSingleThreadProxy::start()
[email protected]94f206c12012-08-25 00:09:1436{
37 DebugScopedSetImplThread impl;
38 m_layerTreeHostImpl = m_layerTreeHost->createLayerTreeHostImpl(this);
39}
40
[email protected]c753e25a2012-10-19 21:22:4241CCSingleThreadProxy::~CCSingleThreadProxy()
[email protected]94f206c12012-08-25 00:09:1442{
[email protected]c753e25a2012-10-19 21:22:4243 TRACE_EVENT0("cc", "CCSingleThreadProxy::~CCSingleThreadProxy");
44 DCHECK(CCProxy::isMainThread());
[email protected]1d993172012-10-18 18:15:0445 DCHECK(!m_layerTreeHostImpl.get() && !m_layerTreeHost); // make sure stop() got called.
[email protected]94f206c12012-08-25 00:09:1446}
47
[email protected]c753e25a2012-10-19 21:22:4248bool CCSingleThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
[email protected]94f206c12012-08-25 00:09:1449{
[email protected]c753e25a2012-10-19 21:22:4250 TRACE_EVENT0("cc", "CCSingleThreadProxy::compositeAndReadback");
51 DCHECK(CCProxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:1452
53 if (!commitAndComposite())
54 return false;
55
56 m_layerTreeHostImpl->readback(pixels, rect);
57
58 if (m_layerTreeHostImpl->isContextLost())
59 return false;
60
61 m_layerTreeHostImpl->swapBuffers();
62 didSwapFrame();
63
64 return true;
65}
66
[email protected]c753e25a2012-10-19 21:22:4267void CCSingleThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double duration)
[email protected]94f206c12012-08-25 00:09:1468{
69 m_layerTreeHostImpl->startPageScaleAnimation(targetPosition, useAnchor, scale, monotonicallyIncreasingTime(), duration);
70}
71
[email protected]c753e25a2012-10-19 21:22:4272void CCSingleThreadProxy::finishAllRendering()
[email protected]94f206c12012-08-25 00:09:1473{
[email protected]c753e25a2012-10-19 21:22:4274 DCHECK(CCProxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:1475 {
76 DebugScopedSetImplThread impl;
77 m_layerTreeHostImpl->finishAllRendering();
78 }
79}
80
[email protected]c753e25a2012-10-19 21:22:4281bool CCSingleThreadProxy::isStarted() const
[email protected]94f206c12012-08-25 00:09:1482{
[email protected]c753e25a2012-10-19 21:22:4283 DCHECK(CCProxy::isMainThread());
[email protected]519281762012-10-06 20:06:3984 return m_layerTreeHostImpl.get();
[email protected]94f206c12012-08-25 00:09:1485}
86
[email protected]c753e25a2012-10-19 21:22:4287bool CCSingleThreadProxy::initializeContext()
[email protected]94f206c12012-08-25 00:09:1488{
[email protected]c753e25a2012-10-19 21:22:4289 DCHECK(CCProxy::isMainThread());
90 scoped_ptr<CCGraphicsContext> context = m_layerTreeHost->createContext();
[email protected]e28efacd2012-10-06 17:07:4991 if (!context.get())
[email protected]94f206c12012-08-25 00:09:1492 return false;
[email protected]e28efacd2012-10-06 17:07:4993 m_contextBeforeInitialization = context.Pass();
[email protected]94f206c12012-08-25 00:09:1494 return true;
95}
96
[email protected]c753e25a2012-10-19 21:22:4297void CCSingleThreadProxy::setSurfaceReady()
[email protected]94f206c12012-08-25 00:09:1498{
99 // Scheduling is controlled by the embedder in the single thread case, so nothing to do.
100}
101
[email protected]c753e25a2012-10-19 21:22:42102void CCSingleThreadProxy::setVisible(bool visible)
[email protected]94f206c12012-08-25 00:09:14103{
104 DebugScopedSetImplThread impl;
105 m_layerTreeHostImpl->setVisible(visible);
106}
107
[email protected]c753e25a2012-10-19 21:22:42108bool CCSingleThreadProxy::initializeRenderer()
[email protected]94f206c12012-08-25 00:09:14109{
[email protected]c753e25a2012-10-19 21:22:42110 DCHECK(CCProxy::isMainThread());
[email protected]1d993172012-10-18 18:15:04111 DCHECK(m_contextBeforeInitialization.get());
[email protected]94f206c12012-08-25 00:09:14112 {
113 DebugScopedSetImplThread impl;
[email protected]e28efacd2012-10-06 17:07:49114 bool ok = m_layerTreeHostImpl->initializeRenderer(m_contextBeforeInitialization.Pass());
[email protected]94f206c12012-08-25 00:09:14115 if (ok) {
116 m_rendererInitialized = true;
117 m_RendererCapabilitiesForMainThread = m_layerTreeHostImpl->rendererCapabilities();
118 }
119
120 return ok;
121 }
122}
123
[email protected]c753e25a2012-10-19 21:22:42124bool CCSingleThreadProxy::recreateContext()
[email protected]94f206c12012-08-25 00:09:14125{
[email protected]c753e25a2012-10-19 21:22:42126 TRACE_EVENT0("cc", "CCSingleThreadProxy::recreateContext");
127 DCHECK(CCProxy::isMainThread());
[email protected]1d993172012-10-18 18:15:04128 DCHECK(m_contextLost);
[email protected]94f206c12012-08-25 00:09:14129
[email protected]c753e25a2012-10-19 21:22:42130 scoped_ptr<CCGraphicsContext> context = m_layerTreeHost->createContext();
[email protected]e28efacd2012-10-06 17:07:49131 if (!context.get())
[email protected]94f206c12012-08-25 00:09:14132 return false;
133
134 bool initialized;
135 {
[email protected]d74ca3b2012-09-12 23:11:12136 DebugScopedSetMainThreadBlocked mainThreadBlocked;
[email protected]94f206c12012-08-25 00:09:14137 DebugScopedSetImplThread impl;
138 if (!m_layerTreeHostImpl->contentsTexturesPurged())
139 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->resourceProvider());
[email protected]e28efacd2012-10-06 17:07:49140 initialized = m_layerTreeHostImpl->initializeRenderer(context.Pass());
[email protected]94f206c12012-08-25 00:09:14141 if (initialized) {
142 m_RendererCapabilitiesForMainThread = m_layerTreeHostImpl->rendererCapabilities();
143 }
144 }
145
146 if (initialized)
147 m_contextLost = false;
148
149 return initialized;
150}
151
[email protected]c753e25a2012-10-19 21:22:42152void CCSingleThreadProxy::renderingStats(CCRenderingStats* stats)
[email protected]94f206c12012-08-25 00:09:14153{
[email protected]8b9af6b2012-09-27 00:36:36154 stats->totalCommitTimeInSeconds = m_totalCommitTime.InSecondsF();
155 stats->totalCommitCount = m_totalCommitCount;
[email protected]94f206c12012-08-25 00:09:14156 m_layerTreeHostImpl->renderingStats(stats);
157}
158
[email protected]c753e25a2012-10-19 21:22:42159const RendererCapabilities& CCSingleThreadProxy::rendererCapabilities() const
[email protected]94f206c12012-08-25 00:09:14160{
[email protected]1d993172012-10-18 18:15:04161 DCHECK(m_rendererInitialized);
[email protected]94f206c12012-08-25 00:09:14162 // Note: this gets called during the commit by the "impl" thread
163 return m_RendererCapabilitiesForMainThread;
164}
165
[email protected]c753e25a2012-10-19 21:22:42166void CCSingleThreadProxy::loseContext()
[email protected]94f206c12012-08-25 00:09:14167{
[email protected]c753e25a2012-10-19 21:22:42168 DCHECK(CCProxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:14169 m_layerTreeHost->didLoseContext();
170 m_contextLost = true;
171}
172
[email protected]c753e25a2012-10-19 21:22:42173void CCSingleThreadProxy::setNeedsAnimate()
[email protected]94f206c12012-08-25 00:09:14174{
[email protected]c753e25a2012-10-19 21:22:42175 // CCThread-only feature
[email protected]1d993172012-10-18 18:15:04176 NOTREACHED();
[email protected]94f206c12012-08-25 00:09:14177}
178
[email protected]c753e25a2012-10-19 21:22:42179void CCSingleThreadProxy::doCommit(scoped_ptr<CCTextureUpdateQueue> queue)
[email protected]94f206c12012-08-25 00:09:14180{
[email protected]c753e25a2012-10-19 21:22:42181 DCHECK(CCProxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:14182 // Commit immediately
183 {
184 DebugScopedSetMainThreadBlocked mainThreadBlocked;
185 DebugScopedSetImplThread impl;
186
[email protected]8b9af6b2012-09-27 00:36:36187 base::TimeTicks startTime = base::TimeTicks::HighResNow();
[email protected]94f206c12012-08-25 00:09:14188 m_layerTreeHostImpl->beginCommit();
189
[email protected]2c7d23f2012-10-15 20:43:25190 m_layerTreeHost->contentsTextureManager()->pushTexturePrioritiesToBackings();
[email protected]94f206c12012-08-25 00:09:14191 m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get());
192
[email protected]c753e25a2012-10-19 21:22:42193 scoped_ptr<CCTextureUpdateController> updateController =
194 CCTextureUpdateController::create(
[email protected]f961b792012-09-20 07:27:33195 NULL,
[email protected]c753e25a2012-10-19 21:22:42196 CCProxy::mainThread(),
[email protected]b1b800c2012-10-16 05:03:59197 queue.Pass(),
[email protected]e2249592012-10-19 06:59:09198 m_layerTreeHostImpl->resourceProvider());
[email protected]f961b792012-09-20 07:27:33199 updateController->finalize();
[email protected]94f206c12012-08-25 00:09:14200
201 m_layerTreeHost->finishCommitOnImplThread(m_layerTreeHostImpl.get());
202
203 m_layerTreeHostImpl->commitComplete();
204
[email protected]1d993172012-10-18 18:15:04205#ifndef NDEBUG
[email protected]94f206c12012-08-25 00:09:14206 // In the single-threaded case, the scroll deltas should never be
207 // touched on the impl layer tree.
[email protected]c753e25a2012-10-19 21:22:42208 scoped_ptr<CCScrollAndScaleSet> scrollInfo = m_layerTreeHostImpl->processScrollDeltas();
[email protected]1d993172012-10-18 18:15:04209 DCHECK(!scrollInfo->scrolls.size());
[email protected]94f206c12012-08-25 00:09:14210#endif
[email protected]8b9af6b2012-09-27 00:36:36211
212 base::TimeTicks endTime = base::TimeTicks::HighResNow();
213 m_totalCommitTime += endTime - startTime;
214 m_totalCommitCount++;
[email protected]94f206c12012-08-25 00:09:14215 }
216 m_layerTreeHost->commitComplete();
217 m_nextFrameIsNewlyCommittedFrame = true;
218}
219
[email protected]c753e25a2012-10-19 21:22:42220void CCSingleThreadProxy::setNeedsCommit()
[email protected]94f206c12012-08-25 00:09:14221{
[email protected]c753e25a2012-10-19 21:22:42222 DCHECK(CCProxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:14223 m_layerTreeHost->scheduleComposite();
224}
225
[email protected]c753e25a2012-10-19 21:22:42226void CCSingleThreadProxy::setNeedsRedraw()
[email protected]94f206c12012-08-25 00:09:14227{
228 // FIXME: Once we move render_widget scheduling into this class, we can
229 // treat redraw requests more efficiently than commitAndRedraw requests.
230 m_layerTreeHostImpl->setFullRootLayerDamage();
231 setNeedsCommit();
232}
233
[email protected]c753e25a2012-10-19 21:22:42234bool CCSingleThreadProxy::commitRequested() const
[email protected]94f206c12012-08-25 00:09:14235{
236 return false;
237}
238
[email protected]c753e25a2012-10-19 21:22:42239void CCSingleThreadProxy::didAddAnimation()
[email protected]94f206c12012-08-25 00:09:14240{
241}
242
[email protected]c753e25a2012-10-19 21:22:42243size_t CCSingleThreadProxy::maxPartialTextureUpdates() const
[email protected]493067512012-09-19 23:34:10244{
245 return std::numeric_limits<size_t>::max();
246}
247
[email protected]c753e25a2012-10-19 21:22:42248void CCSingleThreadProxy::stop()
[email protected]94f206c12012-08-25 00:09:14249{
[email protected]c753e25a2012-10-19 21:22:42250 TRACE_EVENT0("cc", "CCSingleThreadProxy::stop");
251 DCHECK(CCProxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:14252 {
253 DebugScopedSetMainThreadBlocked mainThreadBlocked;
254 DebugScopedSetImplThread impl;
255
256 if (!m_layerTreeHostImpl->contentsTexturesPurged())
257 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->resourceProvider());
[email protected]519281762012-10-06 20:06:39258 m_layerTreeHostImpl.reset();
[email protected]94f206c12012-08-25 00:09:14259 }
260 m_layerTreeHost = 0;
261}
262
[email protected]c753e25a2012-10-19 21:22:42263void CCSingleThreadProxy::setNeedsRedrawOnImplThread()
[email protected]493067512012-09-19 23:34:10264{
265 m_layerTreeHost->scheduleComposite();
266}
267
[email protected]c753e25a2012-10-19 21:22:42268void CCSingleThreadProxy::setNeedsCommitOnImplThread()
[email protected]493067512012-09-19 23:34:10269{
270 m_layerTreeHost->scheduleComposite();
271}
272
[email protected]c753e25a2012-10-19 21:22:42273void CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<CCAnimationEventsVector> events, double wallClockTime)
[email protected]94f206c12012-08-25 00:09:14274{
[email protected]c753e25a2012-10-19 21:22:42275 DCHECK(CCProxy::isImplThread());
[email protected]94f206c12012-08-25 00:09:14276 DebugScopedSetMainThread main;
[email protected]ec1d6d52012-10-10 01:28:57277 m_layerTreeHost->setAnimationEvents(events.Pass(), wallClockTime);
[email protected]94f206c12012-08-25 00:09:14278}
279
[email protected]c753e25a2012-10-19 21:22:42280bool CCSingleThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitBytes)
[email protected]e1fc8b32012-09-18 20:29:09281{
[email protected]1d993172012-10-18 18:15:04282 DCHECK(isImplThread());
[email protected]b1969fa2012-10-17 20:16:29283 if (!m_layerTreeHost->contentsTextureManager())
284 return false;
285
286 return m_layerTreeHost->contentsTextureManager()->reduceMemoryOnImplThread(limitBytes, m_layerTreeHostImpl->resourceProvider());
[email protected]e1fc8b32012-09-18 20:29:09287}
288
[email protected]94f206c12012-08-25 00:09:14289// Called by the legacy scheduling path (e.g. where render_widget does the scheduling)
[email protected]c753e25a2012-10-19 21:22:42290void CCSingleThreadProxy::compositeImmediately()
[email protected]94f206c12012-08-25 00:09:14291{
292 if (commitAndComposite()) {
293 m_layerTreeHostImpl->swapBuffers();
294 didSwapFrame();
295 }
296}
297
[email protected]c753e25a2012-10-19 21:22:42298void CCSingleThreadProxy::forceSerializeOnSwapBuffers()
[email protected]94f206c12012-08-25 00:09:14299{
300 {
301 DebugScopedSetImplThread impl;
302 if (m_rendererInitialized)
303 m_layerTreeHostImpl->renderer()->doNoOp();
304 }
305}
306
[email protected]c753e25a2012-10-19 21:22:42307void CCSingleThreadProxy::onSwapBuffersCompleteOnImplThread()
[email protected]493067512012-09-19 23:34:10308{
[email protected]1d993172012-10-18 18:15:04309 NOTREACHED();
[email protected]493067512012-09-19 23:34:10310}
311
[email protected]c753e25a2012-10-19 21:22:42312bool CCSingleThreadProxy::commitAndComposite()
[email protected]94f206c12012-08-25 00:09:14313{
[email protected]c753e25a2012-10-19 21:22:42314 DCHECK(CCProxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:14315
[email protected]94f206c12012-08-25 00:09:14316 if (!m_layerTreeHost->initializeRendererIfNeeded())
317 return false;
318
[email protected]e1fc8b32012-09-18 20:29:09319 // Unlink any texture backings that were deleted
[email protected]c753e25a2012-10-19 21:22:42320 CCPrioritizedTextureManager::BackingList evictedContentsTexturesBackings;
[email protected]e1fc8b32012-09-18 20:29:09321 {
322 DebugScopedSetImplThread implThread;
[email protected]2c7d23f2012-10-15 20:43:25323 m_layerTreeHost->contentsTextureManager()->getEvictedBackings(evictedContentsTexturesBackings);
[email protected]e1fc8b32012-09-18 20:29:09324 }
[email protected]2c7d23f2012-10-15 20:43:25325 m_layerTreeHost->contentsTextureManager()->unlinkEvictedBackings(evictedContentsTexturesBackings);
[email protected]94f206c12012-08-25 00:09:14326
[email protected]c753e25a2012-10-19 21:22:42327 scoped_ptr<CCTextureUpdateQueue> queue = make_scoped_ptr(new CCTextureUpdateQueue);
[email protected]f961b792012-09-20 07:27:33328 m_layerTreeHost->updateLayers(*(queue.get()), m_layerTreeHostImpl->memoryAllocationLimitBytes());
[email protected]e1fc8b32012-09-18 20:29:09329
330 if (m_layerTreeHostImpl->contentsTexturesPurged())
331 m_layerTreeHostImpl->resetContentsTexturesPurged();
[email protected]94f206c12012-08-25 00:09:14332
333 m_layerTreeHost->willCommit();
[email protected]b1b800c2012-10-16 05:03:59334 doCommit(queue.Pass());
[email protected]94f206c12012-08-25 00:09:14335 bool result = doComposite();
336 m_layerTreeHost->didBeginFrame();
337 return result;
338}
339
[email protected]c753e25a2012-10-19 21:22:42340bool CCSingleThreadProxy::doComposite()
[email protected]94f206c12012-08-25 00:09:14341{
[email protected]1d993172012-10-18 18:15:04342 DCHECK(!m_contextLost);
[email protected]94f206c12012-08-25 00:09:14343 {
344 DebugScopedSetImplThread impl;
345
346 if (!m_layerTreeHostImpl->visible())
347 return false;
348
349 double monotonicTime = monotonicallyIncreasingTime();
350 double wallClockTime = currentTime();
351 m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
352
353 // We guard prepareToDraw() with canDraw() because it always returns a valid frame, so can only
354 // be used when such a frame is possible. Since drawLayers() depends on the result of
355 // prepareToDraw(), it is guarded on canDraw() as well.
356 if (!m_layerTreeHostImpl->canDraw())
357 return false;
358
[email protected]c753e25a2012-10-19 21:22:42359 CCLayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:14360 m_layerTreeHostImpl->prepareToDraw(frame);
361 m_layerTreeHostImpl->drawLayers(frame);
362 m_layerTreeHostImpl->didDrawAllLayers(frame);
363 }
364
365 if (m_layerTreeHostImpl->isContextLost()) {
366 m_contextLost = true;
367 m_layerTreeHost->didLoseContext();
368 return false;
369 }
370
371 return true;
372}
373
[email protected]c753e25a2012-10-19 21:22:42374void CCSingleThreadProxy::didSwapFrame()
[email protected]94f206c12012-08-25 00:09:14375{
376 if (m_nextFrameIsNewlyCommittedFrame) {
377 m_nextFrameIsNewlyCommittedFrame = false;
378 m_layerTreeHost->didCommitAndDrawFrame();
379 }
380}
381
382}