WebKit merge 128969:128981
[chromium-blink-merge.git] / cc / CCSingleThreadProxy.cpp
blob8ec53ed5f22680534012f2bf36a7bc70d97b8a63
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 "CCSingleThreadProxy.h"
9 #include "CCDrawQuad.h"
10 #include "CCGraphicsContext.h"
11 #include "CCLayerTreeHost.h"
12 #include "CCTextureUpdateController.h"
13 #include "CCTimer.h"
14 #include "TraceEvent.h"
15 #include <wtf/CurrentTime.h>
17 using namespace WTF;
19 namespace cc {
21 PassOwnPtr<CCProxy> CCSingleThreadProxy::create(CCLayerTreeHost* layerTreeHost)
23 return adoptPtr(new CCSingleThreadProxy(layerTreeHost));
26 CCSingleThreadProxy::CCSingleThreadProxy(CCLayerTreeHost* layerTreeHost)
27 : m_layerTreeHost(layerTreeHost)
28 , m_contextLost(false)
29 , m_rendererInitialized(false)
30 , m_nextFrameIsNewlyCommittedFrame(false)
32 TRACE_EVENT0("cc", "CCSingleThreadProxy::CCSingleThreadProxy");
33 ASSERT(CCProxy::isMainThread());
36 void CCSingleThreadProxy::start()
38 DebugScopedSetImplThread impl;
39 m_layerTreeHostImpl = m_layerTreeHost->createLayerTreeHostImpl(this);
42 CCSingleThreadProxy::~CCSingleThreadProxy()
44 TRACE_EVENT0("cc", "CCSingleThreadProxy::~CCSingleThreadProxy");
45 ASSERT(CCProxy::isMainThread());
46 ASSERT(!m_layerTreeHostImpl && !m_layerTreeHost); // make sure stop() got called.
49 bool CCSingleThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
51 TRACE_EVENT0("cc", "CCSingleThreadProxy::compositeAndReadback");
52 ASSERT(CCProxy::isMainThread());
54 if (!commitAndComposite())
55 return false;
57 m_layerTreeHostImpl->readback(pixels, rect);
59 if (m_layerTreeHostImpl->isContextLost())
60 return false;
62 m_layerTreeHostImpl->swapBuffers();
63 didSwapFrame();
65 return true;
68 void CCSingleThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double duration)
70 m_layerTreeHostImpl->startPageScaleAnimation(targetPosition, useAnchor, scale, monotonicallyIncreasingTime(), duration);
73 void CCSingleThreadProxy::finishAllRendering()
75 ASSERT(CCProxy::isMainThread());
77 DebugScopedSetImplThread impl;
78 m_layerTreeHostImpl->finishAllRendering();
82 bool CCSingleThreadProxy::isStarted() const
84 ASSERT(CCProxy::isMainThread());
85 return m_layerTreeHostImpl;
88 bool CCSingleThreadProxy::initializeContext()
90 ASSERT(CCProxy::isMainThread());
91 OwnPtr<CCGraphicsContext> context = m_layerTreeHost->createContext();
92 if (!context)
93 return false;
94 m_contextBeforeInitialization = context.release();
95 return true;
98 void CCSingleThreadProxy::setSurfaceReady()
100 // Scheduling is controlled by the embedder in the single thread case, so nothing to do.
103 void CCSingleThreadProxy::setVisible(bool visible)
105 DebugScopedSetImplThread impl;
106 m_layerTreeHostImpl->setVisible(visible);
109 bool CCSingleThreadProxy::initializeRenderer()
111 ASSERT(CCProxy::isMainThread());
112 ASSERT(m_contextBeforeInitialization);
114 DebugScopedSetImplThread impl;
115 bool ok = m_layerTreeHostImpl->initializeRenderer(m_contextBeforeInitialization.release(), UnthrottledUploader);
116 if (ok) {
117 m_rendererInitialized = true;
118 m_RendererCapabilitiesForMainThread = m_layerTreeHostImpl->rendererCapabilities();
121 return ok;
125 bool CCSingleThreadProxy::recreateContext()
127 TRACE_EVENT0("cc", "CCSingleThreadProxy::recreateContext");
128 ASSERT(CCProxy::isMainThread());
129 ASSERT(m_contextLost);
131 OwnPtr<CCGraphicsContext> context = m_layerTreeHost->createContext();
132 if (!context)
133 return false;
135 bool initialized;
137 DebugScopedSetMainThreadBlocked mainThreadBlocked;
138 DebugScopedSetImplThread impl;
139 if (!m_layerTreeHostImpl->contentsTexturesPurged())
140 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->resourceProvider());
141 initialized = m_layerTreeHostImpl->initializeRenderer(context.release(), UnthrottledUploader);
142 if (initialized) {
143 m_RendererCapabilitiesForMainThread = m_layerTreeHostImpl->rendererCapabilities();
147 if (initialized)
148 m_contextLost = false;
150 return initialized;
153 void CCSingleThreadProxy::implSideRenderingStats(CCRenderingStats& stats)
155 m_layerTreeHostImpl->renderingStats(stats);
158 const RendererCapabilities& CCSingleThreadProxy::rendererCapabilities() const
160 ASSERT(m_rendererInitialized);
161 // Note: this gets called during the commit by the "impl" thread
162 return m_RendererCapabilitiesForMainThread;
165 void CCSingleThreadProxy::loseContext()
167 ASSERT(CCProxy::isMainThread());
168 m_layerTreeHost->didLoseContext();
169 m_contextLost = true;
172 void CCSingleThreadProxy::setNeedsAnimate()
174 // CCThread-only feature
175 ASSERT_NOT_REACHED();
178 void CCSingleThreadProxy::doCommit(CCTextureUpdateQueue& queue)
180 ASSERT(CCProxy::isMainThread());
181 // Commit immediately
183 DebugScopedSetMainThreadBlocked mainThreadBlocked;
184 DebugScopedSetImplThread impl;
186 m_layerTreeHostImpl->beginCommit();
188 m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get());
190 CCTextureUpdateController::updateTextures(m_layerTreeHostImpl->resourceProvider(), m_layerTreeHostImpl->resourceProvider()->textureUploader(), &queue);
192 m_layerTreeHost->finishCommitOnImplThread(m_layerTreeHostImpl.get());
194 m_layerTreeHostImpl->commitComplete();
196 #if !ASSERT_DISABLED
197 // In the single-threaded case, the scroll deltas should never be
198 // touched on the impl layer tree.
199 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_layerTreeHostImpl->processScrollDeltas();
200 ASSERT(!scrollInfo->scrolls.size());
201 #endif
203 m_layerTreeHost->commitComplete();
204 m_nextFrameIsNewlyCommittedFrame = true;
207 void CCSingleThreadProxy::setNeedsCommit()
209 ASSERT(CCProxy::isMainThread());
210 m_layerTreeHost->scheduleComposite();
213 void CCSingleThreadProxy::setNeedsRedraw()
215 // FIXME: Once we move render_widget scheduling into this class, we can
216 // treat redraw requests more efficiently than commitAndRedraw requests.
217 m_layerTreeHostImpl->setFullRootLayerDamage();
218 setNeedsCommit();
221 bool CCSingleThreadProxy::commitRequested() const
223 return false;
226 void CCSingleThreadProxy::didAddAnimation()
230 void CCSingleThreadProxy::stop()
232 TRACE_EVENT0("cc", "CCSingleThreadProxy::stop");
233 ASSERT(CCProxy::isMainThread());
235 DebugScopedSetMainThreadBlocked mainThreadBlocked;
236 DebugScopedSetImplThread impl;
238 if (!m_layerTreeHostImpl->contentsTexturesPurged())
239 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->resourceProvider());
240 m_layerTreeHostImpl.clear();
242 m_layerTreeHost = 0;
245 void CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector> events, double wallClockTime)
247 ASSERT(CCProxy::isImplThread());
248 DebugScopedSetMainThread main;
249 m_layerTreeHost->setAnimationEvents(events, wallClockTime);
252 void CCSingleThreadProxy::releaseContentsTexturesOnImplThread()
254 ASSERT(isImplThread());
255 m_layerTreeHost->reduceContentsTexturesMemoryOnImplThread(0, m_layerTreeHostImpl->resourceProvider());
258 // Called by the legacy scheduling path (e.g. where render_widget does the scheduling)
259 void CCSingleThreadProxy::compositeImmediately()
261 if (commitAndComposite()) {
262 m_layerTreeHostImpl->swapBuffers();
263 didSwapFrame();
267 void CCSingleThreadProxy::forceSerializeOnSwapBuffers()
270 DebugScopedSetImplThread impl;
271 if (m_rendererInitialized)
272 m_layerTreeHostImpl->renderer()->doNoOp();
276 bool CCSingleThreadProxy::commitAndComposite()
278 ASSERT(CCProxy::isMainThread());
280 if (!m_layerTreeHost->initializeRendererIfNeeded())
281 return false;
283 // Unlink any texture backings that were deleted
284 CCPrioritizedTextureManager::BackingVector evictedContentsTexturesBackings;
286 DebugScopedSetImplThread implThread;
287 m_layerTreeHost->getEvictedContentTexturesBackings(evictedContentsTexturesBackings);
289 m_layerTreeHost->unlinkEvictedContentTexturesBackings(evictedContentsTexturesBackings);
291 DebugScopedSetImplThreadAndMainThreadBlocked implAndMainBlocked;
292 m_layerTreeHost->deleteEvictedContentTexturesBackings();
295 CCTextureUpdateQueue queue;
296 m_layerTreeHost->updateLayers(queue, m_layerTreeHostImpl->memoryAllocationLimitBytes());
298 if (m_layerTreeHostImpl->contentsTexturesPurged())
299 m_layerTreeHostImpl->resetContentsTexturesPurged();
301 m_layerTreeHost->willCommit();
302 doCommit(queue);
303 bool result = doComposite();
304 m_layerTreeHost->didBeginFrame();
305 return result;
308 bool CCSingleThreadProxy::doComposite()
310 ASSERT(!m_contextLost);
312 DebugScopedSetImplThread impl;
314 if (!m_layerTreeHostImpl->visible())
315 return false;
317 double monotonicTime = monotonicallyIncreasingTime();
318 double wallClockTime = currentTime();
319 m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
321 // We guard prepareToDraw() with canDraw() because it always returns a valid frame, so can only
322 // be used when such a frame is possible. Since drawLayers() depends on the result of
323 // prepareToDraw(), it is guarded on canDraw() as well.
324 if (!m_layerTreeHostImpl->canDraw())
325 return false;
327 CCLayerTreeHostImpl::FrameData frame;
328 m_layerTreeHostImpl->prepareToDraw(frame);
329 m_layerTreeHostImpl->drawLayers(frame);
330 m_layerTreeHostImpl->didDrawAllLayers(frame);
333 if (m_layerTreeHostImpl->isContextLost()) {
334 m_contextLost = true;
335 m_layerTreeHost->didLoseContext();
336 return false;
339 return true;
342 void CCSingleThreadProxy::didSwapFrame()
344 if (m_nextFrameIsNewlyCommittedFrame) {
345 m_nextFrameIsNewlyCommittedFrame = false;
346 m_layerTreeHost->didCommitAndDrawFrame();