Add Sad Tab resources to the iOS build.
[chromium-blink-merge.git] / cc / single_thread_proxy.cc
blob4d4e836bc1e1feba1be724e0f075b416836d2ccc
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 "cc/single_thread_proxy.h"
9 #include "base/debug/trace_event.h"
10 #include "cc/draw_quad.h"
11 #include "cc/graphics_context.h"
12 #include "cc/layer_tree_host.h"
13 #include "cc/resource_update_controller.h"
14 #include "cc/thread.h"
16 namespace cc {
18 scoped_ptr<Proxy> SingleThreadProxy::create(LayerTreeHost* layerTreeHost)
20 return make_scoped_ptr(new SingleThreadProxy(layerTreeHost)).PassAs<Proxy>();
23 SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layerTreeHost)
24 : Proxy(scoped_ptr<Thread>(NULL))
25 , m_layerTreeHost(layerTreeHost)
26 , m_contextLost(false)
27 , m_rendererInitialized(false)
28 , m_nextFrameIsNewlyCommittedFrame(false)
29 , m_totalCommitCount(0)
31 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
32 DCHECK(Proxy::isMainThread());
35 void SingleThreadProxy::start()
37 DebugScopedSetImplThread impl(this);
38 m_layerTreeHostImpl = m_layerTreeHost->createLayerTreeHostImpl(this);
41 SingleThreadProxy::~SingleThreadProxy()
43 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
44 DCHECK(Proxy::isMainThread());
45 DCHECK(!m_layerTreeHostImpl.get() && !m_layerTreeHost); // make sure stop() got called.
48 bool SingleThreadProxy::compositeAndReadback(void *pixels, const gfx::Rect& rect)
50 TRACE_EVENT0("cc", "SingleThreadProxy::compositeAndReadback");
51 DCHECK(Proxy::isMainThread());
53 if (!commitAndComposite())
54 return false;
56 m_layerTreeHostImpl->readback(pixels, rect);
58 if (m_layerTreeHostImpl->isContextLost())
59 return false;
61 m_layerTreeHostImpl->swapBuffers();
62 didSwapFrame();
64 return true;
67 void SingleThreadProxy::startPageScaleAnimation(gfx::Vector2d targetOffset, bool useAnchor, float scale, base::TimeDelta duration)
69 m_layerTreeHostImpl->startPageScaleAnimation(targetOffset, useAnchor, scale, base::TimeTicks::Now(), duration);
72 void SingleThreadProxy::finishAllRendering()
74 DCHECK(Proxy::isMainThread());
76 DebugScopedSetImplThread impl(this);
77 m_layerTreeHostImpl->finishAllRendering();
81 bool SingleThreadProxy::isStarted() const
83 DCHECK(Proxy::isMainThread());
84 return m_layerTreeHostImpl.get();
87 bool SingleThreadProxy::initializeContext()
89 DCHECK(Proxy::isMainThread());
90 scoped_ptr<GraphicsContext> context = m_layerTreeHost->createContext();
91 if (!context.get())
92 return false;
93 m_contextBeforeInitialization = context.Pass();
94 return true;
97 void SingleThreadProxy::setSurfaceReady()
99 // Scheduling is controlled by the embedder in the single thread case, so nothing to do.
102 void SingleThreadProxy::setVisible(bool visible)
104 DebugScopedSetImplThread impl(this);
105 m_layerTreeHostImpl->setVisible(visible);
108 bool SingleThreadProxy::initializeRenderer()
110 DCHECK(Proxy::isMainThread());
111 DCHECK(m_contextBeforeInitialization.get());
113 DebugScopedSetImplThread impl(this);
114 bool ok = m_layerTreeHostImpl->initializeRenderer(m_contextBeforeInitialization.Pass());
115 if (ok) {
116 m_rendererInitialized = true;
117 m_RendererCapabilitiesForMainThread = m_layerTreeHostImpl->rendererCapabilities();
120 return ok;
124 bool SingleThreadProxy::recreateContext()
126 TRACE_EVENT0("cc", "SingleThreadProxy::recreateContext");
127 DCHECK(Proxy::isMainThread());
128 DCHECK(m_contextLost);
130 scoped_ptr<GraphicsContext> context = m_layerTreeHost->createContext();
131 if (!context.get())
132 return false;
134 bool initialized;
136 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
137 DebugScopedSetImplThread impl(this);
138 if (!m_layerTreeHostImpl->contentsTexturesPurged())
139 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->resourceProvider());
140 initialized = m_layerTreeHostImpl->initializeRenderer(context.Pass());
141 if (initialized) {
142 m_RendererCapabilitiesForMainThread = m_layerTreeHostImpl->rendererCapabilities();
146 if (initialized)
147 m_contextLost = false;
149 return initialized;
152 void SingleThreadProxy::renderingStats(RenderingStats* stats)
154 stats->totalCommitTimeInSeconds = m_totalCommitTime.InSecondsF();
155 stats->totalCommitCount = m_totalCommitCount;
156 m_layerTreeHostImpl->renderingStats(stats);
159 const RendererCapabilities& SingleThreadProxy::rendererCapabilities() const
161 DCHECK(m_rendererInitialized);
162 // Note: this gets called during the commit by the "impl" thread
163 return m_RendererCapabilitiesForMainThread;
166 void SingleThreadProxy::loseContext()
168 DCHECK(Proxy::isMainThread());
169 m_layerTreeHost->didLoseContext();
170 m_contextLost = true;
173 void SingleThreadProxy::setNeedsAnimate()
175 // Thread-only feature
176 NOTREACHED();
179 void SingleThreadProxy::doCommit(scoped_ptr<ResourceUpdateQueue> queue)
181 DCHECK(Proxy::isMainThread());
182 // Commit immediately
184 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
185 DebugScopedSetImplThread impl(this);
187 base::TimeTicks startTime = base::TimeTicks::HighResNow();
188 m_layerTreeHostImpl->beginCommit();
190 m_layerTreeHost->contentsTextureManager()->pushTexturePrioritiesToBackings();
191 m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get());
193 scoped_ptr<ResourceUpdateController> updateController =
194 ResourceUpdateController::create(
195 NULL,
196 Proxy::mainThread(),
197 queue.Pass(),
198 m_layerTreeHostImpl->resourceProvider(),
199 hasImplThread());
200 updateController->finalize();
202 m_layerTreeHost->finishCommitOnImplThread(m_layerTreeHostImpl.get());
204 m_layerTreeHostImpl->commitComplete();
206 #ifndef NDEBUG
207 // In the single-threaded case, the scroll deltas should never be
208 // touched on the impl layer tree.
209 scoped_ptr<ScrollAndScaleSet> scrollInfo = m_layerTreeHostImpl->processScrollDeltas();
210 DCHECK(!scrollInfo->scrolls.size());
211 #endif
213 base::TimeTicks endTime = base::TimeTicks::HighResNow();
214 m_totalCommitTime += endTime - startTime;
215 m_totalCommitCount++;
217 m_layerTreeHost->commitComplete();
218 m_nextFrameIsNewlyCommittedFrame = true;
221 void SingleThreadProxy::setNeedsCommit()
223 DCHECK(Proxy::isMainThread());
224 m_layerTreeHost->scheduleComposite();
227 void SingleThreadProxy::setNeedsRedraw()
229 // FIXME: Once we move render_widget scheduling into this class, we can
230 // treat redraw requests more efficiently than commitAndRedraw requests.
231 m_layerTreeHostImpl->setFullRootLayerDamage();
232 setNeedsCommit();
235 void SingleThreadProxy::setDeferCommits(bool deferCommits)
237 // Thread-only feature.
238 NOTREACHED();
241 bool SingleThreadProxy::commitRequested() const
243 return false;
246 void SingleThreadProxy::didAddAnimation()
250 size_t SingleThreadProxy::maxPartialTextureUpdates() const
252 return std::numeric_limits<size_t>::max();
255 void SingleThreadProxy::stop()
257 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
258 DCHECK(Proxy::isMainThread());
260 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
261 DebugScopedSetImplThread impl(this);
263 if (!m_layerTreeHostImpl->contentsTexturesPurged())
264 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->resourceProvider());
265 m_layerTreeHostImpl.reset();
267 m_layerTreeHost = 0;
270 void SingleThreadProxy::setNeedsRedrawOnImplThread()
272 m_layerTreeHost->scheduleComposite();
275 void SingleThreadProxy::setNeedsCommitOnImplThread()
277 m_layerTreeHost->scheduleComposite();
280 void SingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<AnimationEventsVector> events, base::Time wallClockTime)
282 DCHECK(Proxy::isImplThread());
283 DebugScopedSetMainThread main(this);
284 m_layerTreeHost->setAnimationEvents(events.Pass(), wallClockTime);
287 bool SingleThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int priorityCutoff)
289 DCHECK(isImplThread());
290 if (!m_layerTreeHost->contentsTextureManager())
291 return false;
293 return m_layerTreeHost->contentsTextureManager()->reduceMemoryOnImplThread(limitBytes, priorityCutoff, m_layerTreeHostImpl->resourceProvider());
296 void SingleThreadProxy::sendManagedMemoryStats()
298 DCHECK(Proxy::isImplThread());
299 if (!m_layerTreeHostImpl.get())
300 return;
301 if (!m_layerTreeHostImpl->renderer())
302 return;
303 if (!m_layerTreeHost->contentsTextureManager())
304 return;
306 m_layerTreeHostImpl->renderer()->sendManagedMemoryStats(
307 m_layerTreeHost->contentsTextureManager()->memoryVisibleBytes(),
308 m_layerTreeHost->contentsTextureManager()->memoryVisibleAndNearbyBytes(),
309 m_layerTreeHost->contentsTextureManager()->memoryUseBytes());
312 // Called by the legacy scheduling path (e.g. where render_widget does the scheduling)
313 void SingleThreadProxy::compositeImmediately()
315 if (commitAndComposite()) {
316 m_layerTreeHostImpl->swapBuffers();
317 didSwapFrame();
321 void SingleThreadProxy::forceSerializeOnSwapBuffers()
324 DebugScopedSetImplThread impl(this);
325 if (m_rendererInitialized)
326 m_layerTreeHostImpl->renderer()->doNoOp();
330 void SingleThreadProxy::onSwapBuffersCompleteOnImplThread()
332 NOTREACHED();
335 bool SingleThreadProxy::commitAndComposite()
337 DCHECK(Proxy::isMainThread());
339 if (!m_layerTreeHost->initializeRendererIfNeeded())
340 return false;
342 // Unlink any texture backings that were deleted
343 PrioritizedResourceManager::BackingList evictedContentsTexturesBackings;
345 DebugScopedSetImplThread impl(this);
346 m_layerTreeHost->contentsTextureManager()->getEvictedBackings(evictedContentsTexturesBackings);
348 m_layerTreeHost->contentsTextureManager()->unlinkEvictedBackings(evictedContentsTexturesBackings);
350 scoped_ptr<ResourceUpdateQueue> queue = make_scoped_ptr(new ResourceUpdateQueue);
351 m_layerTreeHost->updateLayers(*(queue.get()), m_layerTreeHostImpl->memoryAllocationLimitBytes());
353 if (m_layerTreeHostImpl->contentsTexturesPurged())
354 m_layerTreeHostImpl->resetContentsTexturesPurged();
356 m_layerTreeHost->willCommit();
357 doCommit(queue.Pass());
358 bool result = doComposite();
359 m_layerTreeHost->didBeginFrame();
360 return result;
363 bool SingleThreadProxy::doComposite()
365 DCHECK(!m_contextLost);
367 DebugScopedSetImplThread impl(this);
369 if (!m_layerTreeHostImpl->visible())
370 return false;
372 m_layerTreeHostImpl->animate(base::TimeTicks::Now(), base::Time::Now());
374 // We guard prepareToDraw() with canDraw() because it always returns a valid frame, so can only
375 // be used when such a frame is possible. Since drawLayers() depends on the result of
376 // prepareToDraw(), it is guarded on canDraw() as well.
377 if (!m_layerTreeHostImpl->canDraw())
378 return false;
380 LayerTreeHostImpl::FrameData frame;
381 m_layerTreeHostImpl->prepareToDraw(frame);
382 m_layerTreeHostImpl->drawLayers(frame);
383 m_layerTreeHostImpl->didDrawAllLayers(frame);
386 if (m_layerTreeHostImpl->isContextLost()) {
387 m_contextLost = true;
388 m_layerTreeHost->didLoseContext();
389 return false;
392 return true;
395 void SingleThreadProxy::didSwapFrame()
397 if (m_nextFrameIsNewlyCommittedFrame) {
398 m_nextFrameIsNewlyCommittedFrame = false;
399 m_layerTreeHost->didCommitAndDrawFrame();
403 } // namespace cc