blob: 30d88ba74dba5c95835ee18681828fe73b9ec44d [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"
[email protected]6331a1172012-10-18 11:35:1311#include "base/debug/trace_event.h"
[email protected]d50c6862012-10-23 02:08:3112#include "cc/layer_tree_host.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]96baf3e2012-10-22 23:09:5519scoped_ptr<Proxy> SingleThreadProxy::create(LayerTreeHost* layerTreeHost)
[email protected]94f206c12012-08-25 00:09:1420{
[email protected]96baf3e2012-10-22 23:09:5521 return make_scoped_ptr(new SingleThreadProxy(layerTreeHost)).PassAs<Proxy>();
[email protected]94f206c12012-08-25 00:09:1422}
23
[email protected]96baf3e2012-10-22 23:09:5524SingleThreadProxy::SingleThreadProxy(LayerTreeHost* 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]96baf3e2012-10-22 23:09:5531 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
32 DCHECK(Proxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:1433}
34
[email protected]96baf3e2012-10-22 23:09:5535void SingleThreadProxy::start()
[email protected]94f206c12012-08-25 00:09:1436{
37 DebugScopedSetImplThread impl;
38 m_layerTreeHostImpl = m_layerTreeHost->createLayerTreeHostImpl(this);
39}
40
[email protected]96baf3e2012-10-22 23:09:5541SingleThreadProxy::~SingleThreadProxy()
[email protected]94f206c12012-08-25 00:09:1442{
[email protected]96baf3e2012-10-22 23:09:5543 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
44 DCHECK(Proxy::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]96baf3e2012-10-22 23:09:5548bool SingleThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
[email protected]94f206c12012-08-25 00:09:1449{
[email protected]96baf3e2012-10-22 23:09:5550 TRACE_EVENT0("cc", "SingleThreadProxy::compositeAndReadback");
51 DCHECK(Proxy::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]96baf3e2012-10-22 23:09:5567void SingleThreadProxy::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]96baf3e2012-10-22 23:09:5572void SingleThreadProxy::finishAllRendering()
[email protected]94f206c12012-08-25 00:09:1473{
[email protected]96baf3e2012-10-22 23:09:5574 DCHECK(Proxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:1475 {
76 DebugScopedSetImplThread impl;
77 m_layerTreeHostImpl->finishAllRendering();
78 }
79}
80
[email protected]96baf3e2012-10-22 23:09:5581bool SingleThreadProxy::isStarted() const
[email protected]94f206c12012-08-25 00:09:1482{
[email protected]96baf3e2012-10-22 23:09:5583 DCHECK(Proxy::isMainThread());
[email protected]519281762012-10-06 20:06:3984 return m_layerTreeHostImpl.get();
[email protected]94f206c12012-08-25 00:09:1485}
86
[email protected]96baf3e2012-10-22 23:09:5587bool SingleThreadProxy::initializeContext()
[email protected]94f206c12012-08-25 00:09:1488{
[email protected]96baf3e2012-10-22 23:09:5589 DCHECK(Proxy::isMainThread());
90 scoped_ptr<GraphicsContext> 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]96baf3e2012-10-22 23:09:5597void SingleThreadProxy::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]96baf3e2012-10-22 23:09:55102void SingleThreadProxy::setVisible(bool visible)
[email protected]94f206c12012-08-25 00:09:14103{
104 DebugScopedSetImplThread impl;
105 m_layerTreeHostImpl->setVisible(visible);
106}
107
[email protected]96baf3e2012-10-22 23:09:55108bool SingleThreadProxy::initializeRenderer()
[email protected]94f206c12012-08-25 00:09:14109{
[email protected]96baf3e2012-10-22 23:09:55110 DCHECK(Proxy::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]96baf3e2012-10-22 23:09:55124bool SingleThreadProxy::recreateContext()
[email protected]94f206c12012-08-25 00:09:14125{
[email protected]96baf3e2012-10-22 23:09:55126 TRACE_EVENT0("cc", "SingleThreadProxy::recreateContext");
127 DCHECK(Proxy::isMainThread());
[email protected]1d993172012-10-18 18:15:04128 DCHECK(m_contextLost);
[email protected]94f206c12012-08-25 00:09:14129
[email protected]96baf3e2012-10-22 23:09:55130 scoped_ptr<GraphicsContext> 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]96baf3e2012-10-22 23:09:55152void SingleThreadProxy::renderingStats(RenderingStats* 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]96baf3e2012-10-22 23:09:55159const RendererCapabilities& SingleThreadProxy::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]96baf3e2012-10-22 23:09:55166void SingleThreadProxy::loseContext()
[email protected]94f206c12012-08-25 00:09:14167{
[email protected]96baf3e2012-10-22 23:09:55168 DCHECK(Proxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:14169 m_layerTreeHost->didLoseContext();
170 m_contextLost = true;
171}
172
[email protected]96baf3e2012-10-22 23:09:55173void SingleThreadProxy::setNeedsAnimate()
[email protected]94f206c12012-08-25 00:09:14174{
[email protected]96baf3e2012-10-22 23:09:55175 // Thread-only feature
[email protected]1d993172012-10-18 18:15:04176 NOTREACHED();
[email protected]94f206c12012-08-25 00:09:14177}
178
[email protected]96baf3e2012-10-22 23:09:55179void SingleThreadProxy::doCommit(scoped_ptr<TextureUpdateQueue> queue)
[email protected]94f206c12012-08-25 00:09:14180{
[email protected]96baf3e2012-10-22 23:09:55181 DCHECK(Proxy::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]96baf3e2012-10-22 23:09:55193 scoped_ptr<TextureUpdateController> updateController =
194 TextureUpdateController::create(
[email protected]f961b792012-09-20 07:27:33195 NULL,
[email protected]96baf3e2012-10-22 23:09:55196 Proxy::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]96baf3e2012-10-22 23:09:55208 scoped_ptr<ScrollAndScaleSet> 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]96baf3e2012-10-22 23:09:55220void SingleThreadProxy::setNeedsCommit()
[email protected]94f206c12012-08-25 00:09:14221{
[email protected]96baf3e2012-10-22 23:09:55222 DCHECK(Proxy::isMainThread());
[email protected]94f206c12012-08-25 00:09:14223 m_layerTreeHost->scheduleComposite();
224}
225
[email protected]96baf3e2012-10-22 23:09:55226void SingleThreadProxy::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]96baf3e2012-10-22 23:09:55234bool SingleThreadProxy::commitRequested() const
[email protected]94f206c12012-08-25 00:09:14235{
236 return false;
237}
238
[email protected]96baf3e2012-10-22 23:09:55239void SingleThreadProxy::didAddAnimation()
[email protected]94f206c12012-08-25 00:09:14240{
241}
242
[email protected]96baf3e2012-10-22 23:09:55243size_t SingleThreadProxy::maxPartialTextureUpdates() const
[email protected]493067512012-09-19 23:34:10244{
245 return std::numeric_limits<size_t>::max();
246}
247
[email protected]96baf3e2012-10-22 23:09:55248void SingleThreadProxy::stop()
[email protected]94f206c12012-08-25 00:09:14249{
[email protected]96baf3e2012-10-22 23:09:55250 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
251 DCHECK(Proxy::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]96baf3e2012-10-22 23:09:55263void SingleThreadProxy::setNeedsRedrawOnImplThread()
[email protected]493067512012-09-19 23:34:10264{
265 m_layerTreeHost->scheduleComposite();
266}
267
[email protected]96baf3e2012-10-22 23:09:55268void SingleThreadProxy::setNeedsCommitOnImplThread()
[email protected]493067512012-09-19 23:34:10269{
270 m_layerTreeHost->scheduleComposite();
271}
272
[email protected]96baf3e2012-10-22 23:09:55273void SingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<AnimationEventsVector> events, double wallClockTime)
[email protected]94f206c12012-08-25 00:09:14274{
[email protected]96baf3e2012-10-22 23:09:55275 DCHECK(Proxy::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]96baf3e2012-10-22 23:09:55280bool SingleThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int priorityCutoff)
[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
[email protected]a0a00842012-10-22 22:50:28286 return m_layerTreeHost->contentsTextureManager()->reduceMemoryOnImplThread(limitBytes, priorityCutoff, 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]96baf3e2012-10-22 23:09:55290void SingleThreadProxy::compositeImmediately()
[email protected]94f206c12012-08-25 00:09:14291{
292 if (commitAndComposite()) {
293 m_layerTreeHostImpl->swapBuffers();
294 didSwapFrame();
295 }
296}
297
[email protected]96baf3e2012-10-22 23:09:55298void SingleThreadProxy::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]96baf3e2012-10-22 23:09:55307void SingleThreadProxy::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]96baf3e2012-10-22 23:09:55312bool SingleThreadProxy::commitAndComposite()
[email protected]94f206c12012-08-25 00:09:14313{
[email protected]96baf3e2012-10-22 23:09:55314 DCHECK(Proxy::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]96baf3e2012-10-22 23:09:55320 PrioritizedTextureManager::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]96baf3e2012-10-22 23:09:55327 scoped_ptr<TextureUpdateQueue> queue = make_scoped_ptr(new TextureUpdateQueue);
[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]96baf3e2012-10-22 23:09:55340bool SingleThreadProxy::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]96baf3e2012-10-22 23:09:55359 LayerTreeHostImpl::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]96baf3e2012-10-22 23:09:55374void SingleThreadProxy::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}