Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2078)

Side by Side Diff: cc/CCThreadProxy.cpp

Issue 11122003: [cc] Rename all cc/ filenames to Chromium style (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/CCThreadProxy.h ('k') | cc/CCThreadTask.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "config.h"
6
7 #include "CCThreadProxy.h"
8
9 #include "CCDelayBasedTimeSource.h"
10 #include "CCDrawQuad.h"
11 #include "CCFrameRateController.h"
12 #include "CCGraphicsContext.h"
13 #include "CCInputHandler.h"
14 #include "CCLayerTreeHost.h"
15 #include "CCScheduler.h"
16 #include "CCScopedThreadProxy.h"
17 #include "CCThreadTask.h"
18 #include "TraceEvent.h"
19 #include <public/WebSharedGraphicsContext3D.h>
20 #include <wtf/CurrentTime.h>
21
22 using namespace WTF;
23 using WebKit::WebSharedGraphicsContext3D;
24
25 namespace {
26
27 // Measured in seconds.
28 const double contextRecreationTickRate = 0.03;
29
30 } // namespace
31
32 namespace cc {
33
34 scoped_ptr<CCProxy> CCThreadProxy::create(CCLayerTreeHost* layerTreeHost)
35 {
36 return make_scoped_ptr(new CCThreadProxy(layerTreeHost)).PassAs<CCProxy>();
37 }
38
39 CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost)
40 : m_animateRequested(false)
41 , m_commitRequested(false)
42 , m_commitRequestSentToImplThread(false)
43 , m_forcedCommitRequested(false)
44 , m_layerTreeHost(layerTreeHost)
45 , m_rendererInitialized(false)
46 , m_started(false)
47 , m_texturesAcquired(true)
48 , m_inCompositeAndReadback(false)
49 , m_mainThreadProxy(CCScopedThreadProxy::create(CCProxy::mainThread()))
50 , m_beginFrameCompletionEventOnImplThread(0)
51 , m_readbackRequestOnImplThread(0)
52 , m_commitCompletionEventOnImplThread(0)
53 , m_textureAcquisitionCompletionEventOnImplThread(0)
54 , m_resetContentsTexturesPurgedAfterCommitOnImplThread(false)
55 , m_nextFrameIsNewlyCommittedFrameOnImplThread(false)
56 , m_renderVSyncEnabled(layerTreeHost->settings().renderVSyncEnabled)
57 , m_totalCommitCount(0)
58 {
59 TRACE_EVENT0("cc", "CCThreadProxy::CCThreadProxy");
60 ASSERT(isMainThread());
61 }
62
63 CCThreadProxy::~CCThreadProxy()
64 {
65 TRACE_EVENT0("cc", "CCThreadProxy::~CCThreadProxy");
66 ASSERT(isMainThread());
67 ASSERT(!m_started);
68 }
69
70 bool CCThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
71 {
72 TRACE_EVENT0("cc", "CCThreadPRoxy::compositeAndReadback");
73 ASSERT(isMainThread());
74 ASSERT(m_layerTreeHost);
75
76 if (!m_layerTreeHost->initializeRendererIfNeeded()) {
77 TRACE_EVENT0("cc", "compositeAndReadback_EarlyOut_LR_Uninitialized");
78 return false;
79 }
80
81
82 // Perform a synchronous commit.
83 {
84 DebugScopedSetMainThreadBlocked mainThreadBlocked;
85 CCCompletionEvent beginFrameCompletion;
86 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy: :forceBeginFrameOnImplThread, &beginFrameCompletion));
87 beginFrameCompletion.wait();
88 }
89 m_inCompositeAndReadback = true;
90 beginFrame();
91 m_inCompositeAndReadback = false;
92
93 // Perform a synchronous readback.
94 ReadbackRequest request;
95 request.rect = rect;
96 request.pixels = pixels;
97 {
98 DebugScopedSetMainThreadBlocked mainThreadBlocked;
99 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy: :requestReadbackOnImplThread, &request));
100 request.completion.wait();
101 }
102 return request.success;
103 }
104
105 void CCThreadProxy::requestReadbackOnImplThread(ReadbackRequest* request)
106 {
107 ASSERT(CCProxy::isImplThread());
108 ASSERT(!m_readbackRequestOnImplThread);
109 if (!m_layerTreeHostImpl.get()) {
110 request->success = false;
111 request->completion.signal();
112 return;
113 }
114
115 m_readbackRequestOnImplThread = request;
116 m_schedulerOnImplThread->setNeedsRedraw();
117 m_schedulerOnImplThread->setNeedsForcedRedraw();
118 }
119
120 void CCThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double duration)
121 {
122 ASSERT(CCProxy::isMainThread());
123 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::req uestStartPageScaleAnimationOnImplThread, targetPosition, useAnchor, scale, durat ion));
124 }
125
126 void CCThreadProxy::requestStartPageScaleAnimationOnImplThread(IntSize targetPos ition, bool useAnchor, float scale, double duration)
127 {
128 ASSERT(CCProxy::isImplThread());
129 if (m_layerTreeHostImpl.get())
130 m_layerTreeHostImpl->startPageScaleAnimation(targetPosition, useAnchor, scale, monotonicallyIncreasingTime(), duration);
131 }
132
133 void CCThreadProxy::finishAllRendering()
134 {
135 ASSERT(CCProxy::isMainThread());
136
137 // Make sure all GL drawing is finished on the impl thread.
138 DebugScopedSetMainThreadBlocked mainThreadBlocked;
139 CCCompletionEvent completion;
140 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::fin ishAllRenderingOnImplThread, &completion));
141 completion.wait();
142 }
143
144 bool CCThreadProxy::isStarted() const
145 {
146 ASSERT(CCProxy::isMainThread());
147 return m_started;
148 }
149
150 bool CCThreadProxy::initializeContext()
151 {
152 TRACE_EVENT0("cc", "CCThreadProxy::initializeContext");
153 scoped_ptr<CCGraphicsContext> context = m_layerTreeHost->createContext();
154 if (!context.get())
155 return false;
156
157 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::ini tializeContextOnImplThread,
158 context.release()));
159 return true;
160 }
161
162 void CCThreadProxy::setSurfaceReady()
163 {
164 TRACE_EVENT0("cc", "CCThreadProxy::setSurfaceReady");
165 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set SurfaceReadyOnImplThread));
166 }
167
168 void CCThreadProxy::setSurfaceReadyOnImplThread()
169 {
170 TRACE_EVENT0("cc", "CCThreadProxy::setSurfaceReadyOnImplThread");
171 m_schedulerOnImplThread->setCanBeginFrame(true);
172 }
173
174 void CCThreadProxy::setVisible(bool visible)
175 {
176 TRACE_EVENT0("cc", "CCThreadProxy::setVisible");
177 DebugScopedSetMainThreadBlocked mainThreadBlocked;
178 CCCompletionEvent completion;
179 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set VisibleOnImplThread, &completion, visible));
180 completion.wait();
181 }
182
183 void CCThreadProxy::setVisibleOnImplThread(CCCompletionEvent* completion, bool v isible)
184 {
185 TRACE_EVENT0("cc", "CCThreadProxy::setVisibleOnImplThread");
186 m_layerTreeHostImpl->setVisible(visible);
187 m_schedulerOnImplThread->setVisible(visible);
188 completion->signal();
189 }
190
191 bool CCThreadProxy::initializeRenderer()
192 {
193 TRACE_EVENT0("cc", "CCThreadProxy::initializeRenderer");
194 // Make a blocking call to initializeRendererOnImplThread. The results of th at call
195 // are pushed into the initializeSucceeded and capabilities local variables.
196 CCCompletionEvent completion;
197 bool initializeSucceeded = false;
198 RendererCapabilities capabilities;
199 DebugScopedSetMainThreadBlocked mainThreadBlocked;
200 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::ini tializeRendererOnImplThread,
201 &completion,
202 &initializeSucceeded,
203 &capabilities));
204 completion.wait();
205
206 if (initializeSucceeded) {
207 m_rendererInitialized = true;
208 m_RendererCapabilitiesMainThreadCopy = capabilities;
209 }
210 return initializeSucceeded;
211 }
212
213 bool CCThreadProxy::recreateContext()
214 {
215 TRACE_EVENT0("cc", "CCThreadProxy::recreateContext");
216 ASSERT(isMainThread());
217
218 // Try to create the context.
219 scoped_ptr<CCGraphicsContext> context = m_layerTreeHost->createContext();
220 if (!context.get())
221 return false;
222 if (m_layerTreeHost->needsSharedContext())
223 if (!WebSharedGraphicsContext3D::createCompositorThreadContext())
224 return false;
225
226 // Make a blocking call to recreateContextOnImplThread. The results of that
227 // call are pushed into the recreateSucceeded and capabilities local
228 // variables.
229 CCCompletionEvent completion;
230 bool recreateSucceeded = false;
231 RendererCapabilities capabilities;
232 DebugScopedSetMainThreadBlocked mainThreadBlocked;
233 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::rec reateContextOnImplThread,
234 &completion,
235 context.release(),
236 &recreateSucceeded,
237 &capabilities));
238 completion.wait();
239
240 if (recreateSucceeded)
241 m_RendererCapabilitiesMainThreadCopy = capabilities;
242 return recreateSucceeded;
243 }
244
245 void CCThreadProxy::renderingStats(CCRenderingStats* stats)
246 {
247 ASSERT(isMainThread());
248
249 DebugScopedSetMainThreadBlocked mainThreadBlocked;
250 CCCompletionEvent completion;
251 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::ren deringStatsOnImplThread,
252 &completion,
253 stats));
254 stats->totalCommitTimeInSeconds = m_totalCommitTime.InSecondsF();
255 stats->totalCommitCount = m_totalCommitCount;
256
257 completion.wait();
258 }
259
260 const RendererCapabilities& CCThreadProxy::rendererCapabilities() const
261 {
262 ASSERT(m_rendererInitialized);
263 return m_RendererCapabilitiesMainThreadCopy;
264 }
265
266 void CCThreadProxy::loseContext()
267 {
268 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::did LoseContextOnImplThread));
269 }
270
271 void CCThreadProxy::setNeedsAnimate()
272 {
273 ASSERT(isMainThread());
274 if (m_animateRequested)
275 return;
276
277 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsAnimate");
278 m_animateRequested = true;
279
280 if (m_commitRequestSentToImplThread)
281 return;
282 m_commitRequestSentToImplThread = true;
283 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set NeedsCommitOnImplThread));
284 }
285
286 void CCThreadProxy::setNeedsCommit()
287 {
288 ASSERT(isMainThread());
289 if (m_commitRequested)
290 return;
291 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsCommit");
292 m_commitRequested = true;
293
294 if (m_commitRequestSentToImplThread)
295 return;
296 m_commitRequestSentToImplThread = true;
297 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set NeedsCommitOnImplThread));
298 }
299
300 void CCThreadProxy::didLoseContextOnImplThread()
301 {
302 ASSERT(isImplThread());
303 TRACE_EVENT0("cc", "CCThreadProxy::didLoseContextOnImplThread");
304 m_schedulerOnImplThread->didLoseContext();
305 }
306
307 void CCThreadProxy::onSwapBuffersCompleteOnImplThread()
308 {
309 ASSERT(isImplThread());
310 TRACE_EVENT0("cc", "CCThreadProxy::onSwapBuffersCompleteOnImplThread");
311 m_schedulerOnImplThread->didSwapBuffersComplete();
312 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::didComp leteSwapBuffers));
313 }
314
315 void CCThreadProxy::onVSyncParametersChanged(double monotonicTimebase, double in tervalInSeconds)
316 {
317 ASSERT(isImplThread());
318 TRACE_EVENT2("cc", "CCThreadProxy::onVSyncParametersChanged", "monotonicTime base", monotonicTimebase, "intervalInSeconds", intervalInSeconds);
319 base::TimeTicks timebase = base::TimeTicks::FromInternalValue(monotonicTimeb ase * base::Time::kMicrosecondsPerSecond);
320 base::TimeDelta interval = base::TimeDelta::FromMicroseconds(intervalInSecon ds * base::Time::kMicrosecondsPerSecond);
321 m_schedulerOnImplThread->setTimebaseAndInterval(timebase, interval);
322 }
323
324 void CCThreadProxy::onCanDrawStateChanged(bool canDraw)
325 {
326 ASSERT(isImplThread());
327 TRACE_EVENT1("cc", "CCThreadProxy::onCanDrawStateChanged", "canDraw", canDra w);
328 m_schedulerOnImplThread->setCanDraw(canDraw);
329 }
330
331 void CCThreadProxy::setNeedsCommitOnImplThread()
332 {
333 ASSERT(isImplThread());
334 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsCommitOnImplThread");
335 m_schedulerOnImplThread->setNeedsCommit();
336 }
337
338 void CCThreadProxy::setNeedsForcedCommitOnImplThread()
339 {
340 ASSERT(isImplThread());
341 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsForcedCommitOnImplThread");
342 m_schedulerOnImplThread->setNeedsCommit();
343 m_schedulerOnImplThread->setNeedsForcedCommit();
344 }
345
346 void CCThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<CCAni mationEventsVector> events, double wallClockTime)
347 {
348 ASSERT(isImplThread());
349 TRACE_EVENT0("cc", "CCThreadProxy::postAnimationEventsToMainThreadOnImplThre ad");
350 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::setAnim ationEvents, events.release(), wallClockTime));
351 }
352
353 void CCThreadProxy::releaseContentsTexturesOnImplThread()
354 {
355 ASSERT(isImplThread());
356
357 m_layerTreeHost->reduceContentsTexturesMemoryOnImplThread(0, m_layerTreeHost Impl->resourceProvider());
358
359 // Make sure that we get a new commit before drawing again.
360 m_resetContentsTexturesPurgedAfterCommitOnImplThread = false;
361 // The texture upload queue may reference textures that were just purged, cl ear
362 // them from the queue.
363 if (m_currentTextureUpdateControllerOnImplThread.get() && m_layerTreeHost->e victedContentsTexturesBackingsExist())
364 m_currentTextureUpdateControllerOnImplThread->discardUploadsToEvictedRes ources();
365 }
366
367 void CCThreadProxy::setNeedsRedraw()
368 {
369 ASSERT(isMainThread());
370 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsRedraw");
371 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set FullRootLayerDamageOnImplThread));
372 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set NeedsRedrawOnImplThread));
373 }
374
375 bool CCThreadProxy::commitRequested() const
376 {
377 ASSERT(isMainThread());
378 return m_commitRequested;
379 }
380
381 void CCThreadProxy::setNeedsRedrawOnImplThread()
382 {
383 ASSERT(isImplThread());
384 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsRedrawOnImplThread");
385 m_schedulerOnImplThread->setNeedsRedraw();
386 }
387
388 void CCThreadProxy::start()
389 {
390 ASSERT(isMainThread());
391 ASSERT(CCProxy::implThread());
392 // Create LayerTreeHostImpl.
393 DebugScopedSetMainThreadBlocked mainThreadBlocked;
394 CCCompletionEvent completion;
395 scoped_ptr<CCInputHandler> handler = m_layerTreeHost->createInputHandler();
396 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::ini tializeImplOnImplThread, &completion, handler.release()));
397 completion.wait();
398
399 m_started = true;
400 }
401
402 void CCThreadProxy::stop()
403 {
404 TRACE_EVENT0("cc", "CCThreadProxy::stop");
405 ASSERT(isMainThread());
406 ASSERT(m_started);
407
408 // Synchronously deletes the impl.
409 {
410 DebugScopedSetMainThreadBlocked mainThreadBlocked;
411
412 CCCompletionEvent completion;
413 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy: :layerTreeHostClosedOnImplThread, &completion));
414 completion.wait();
415 }
416
417 m_mainThreadProxy->shutdown(); // Stop running tasks posted to us.
418
419 ASSERT(!m_layerTreeHostImpl.get()); // verify that the impl deleted.
420 m_layerTreeHost = 0;
421 m_started = false;
422 }
423
424 void CCThreadProxy::forceSerializeOnSwapBuffers()
425 {
426 DebugScopedSetMainThreadBlocked mainThreadBlocked;
427 CCCompletionEvent completion;
428 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::for ceSerializeOnSwapBuffersOnImplThread, &completion));
429 completion.wait();
430 }
431
432 void CCThreadProxy::forceSerializeOnSwapBuffersOnImplThread(CCCompletionEvent* c ompletion)
433 {
434 if (m_rendererInitialized)
435 m_layerTreeHostImpl->renderer()->doNoOp();
436 completion->signal();
437 }
438
439
440 void CCThreadProxy::finishAllRenderingOnImplThread(CCCompletionEvent* completion )
441 {
442 TRACE_EVENT0("cc", "CCThreadProxy::finishAllRenderingOnImplThread");
443 ASSERT(isImplThread());
444 m_layerTreeHostImpl->finishAllRendering();
445 completion->signal();
446 }
447
448 void CCThreadProxy::forceBeginFrameOnImplThread(CCCompletionEvent* completion)
449 {
450 TRACE_EVENT0("cc", "CCThreadProxy::forceBeginFrameOnImplThread");
451 ASSERT(!m_beginFrameCompletionEventOnImplThread);
452
453 if (m_schedulerOnImplThread->commitPending()) {
454 completion->signal();
455 return;
456 }
457
458 m_beginFrameCompletionEventOnImplThread = completion;
459 setNeedsForcedCommitOnImplThread();
460 }
461
462 void CCThreadProxy::scheduledActionBeginFrame()
463 {
464 TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionBeginFrame");
465 ASSERT(!m_pendingBeginFrameRequest);
466 m_pendingBeginFrameRequest = adoptPtr(new BeginFrameAndCommitState());
467 m_pendingBeginFrameRequest->monotonicFrameBeginTime = monotonicallyIncreasin gTime();
468 m_pendingBeginFrameRequest->scrollInfo = m_layerTreeHostImpl->processScrollD eltas();
469 m_pendingBeginFrameRequest->implTransform = m_layerTreeHostImpl->implTransfo rm();
470 m_pendingBeginFrameRequest->memoryAllocationLimitBytes = m_layerTreeHostImpl ->memoryAllocationLimitBytes();
471 m_layerTreeHost->getEvictedContentTexturesBackings(m_pendingBeginFrameReques t->evictedContentsTexturesBackings);
472
473 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginFr ame));
474
475 if (m_beginFrameCompletionEventOnImplThread) {
476 m_beginFrameCompletionEventOnImplThread->signal();
477 m_beginFrameCompletionEventOnImplThread = 0;
478 }
479 }
480
481 void CCThreadProxy::beginFrame()
482 {
483 TRACE_EVENT0("cc", "CCThreadProxy::beginFrame");
484 ASSERT(isMainThread());
485 if (!m_layerTreeHost)
486 return;
487
488 if (!m_pendingBeginFrameRequest) {
489 TRACE_EVENT0("cc", "EarlyOut_StaleBeginFrameMessage");
490 return;
491 }
492
493 if (m_layerTreeHost->needsSharedContext() && !WebSharedGraphicsContext3D::ha veCompositorThreadContext())
494 WebSharedGraphicsContext3D::createCompositorThreadContext();
495
496 OwnPtr<BeginFrameAndCommitState> request(m_pendingBeginFrameRequest.release( ));
497
498 // Do not notify the impl thread of commit requests that occur during
499 // the apply/animate/layout part of the beginFrameAndCommit process since
500 // those commit requests will get painted immediately. Once we have done
501 // the paint, m_commitRequested will be set to false to allow new commit
502 // requests to be scheduled.
503 m_commitRequested = true;
504 m_commitRequestSentToImplThread = true;
505
506 // On the other hand, the animationRequested flag needs to be cleared
507 // here so that any animation requests generated by the apply or animate
508 // callbacks will trigger another frame.
509 m_animateRequested = false;
510
511 // FIXME: technically, scroll deltas need to be applied for dropped commits as well.
512 // Re-do the commit flow so that we don't send the scrollInfo on the BFAC me ssage.
513 m_layerTreeHost->applyScrollAndScale(*request->scrollInfo);
514 m_layerTreeHost->setImplTransform(request->implTransform);
515
516 if (!m_inCompositeAndReadback && !m_layerTreeHost->visible()) {
517 m_commitRequested = false;
518 m_commitRequestSentToImplThread = false;
519 m_forcedCommitRequested = false;
520
521 TRACE_EVENT0("cc", "EarlyOut_NotVisible");
522 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy: :beginFrameAbortedOnImplThread));
523 return;
524 }
525
526 m_layerTreeHost->willBeginFrame();
527
528 m_layerTreeHost->updateAnimations(request->monotonicFrameBeginTime);
529 m_layerTreeHost->layout();
530
531 // Clear the commit flag after updating animations and layout here --- objec ts that only
532 // layout when painted will trigger another setNeedsCommit inside
533 // updateLayers.
534 m_commitRequested = false;
535 m_commitRequestSentToImplThread = false;
536 m_forcedCommitRequested = false;
537
538 if (!m_layerTreeHost->initializeRendererIfNeeded()) {
539 TRACE_EVENT0("cc", "EarlyOut_InitializeFailed");
540 return;
541 }
542
543 m_layerTreeHost->unlinkEvictedContentTexturesBackings(request->evictedConten tsTexturesBackings);
544
545 OwnPtr<CCTextureUpdateQueue> queue = adoptPtr(new CCTextureUpdateQueue);
546 m_layerTreeHost->updateLayers(*(queue.get()), request->memoryAllocationLimit Bytes);
547
548 // Once single buffered layers are committed, they cannot be modified until
549 // they are drawn by the impl thread.
550 m_texturesAcquired = false;
551
552 m_layerTreeHost->willCommit();
553 // Before applying scrolls and calling animate, we set m_animateRequested to
554 // false. If it is true now, it means setNeedAnimate was called again, but
555 // during a state when m_commitRequestSentToImplThread = true. We need to
556 // force that call to happen again now so that the commit request is sent to
557 // the impl thread.
558 if (m_animateRequested) {
559 // Forces setNeedsAnimate to consider posting a commit task.
560 m_animateRequested = false;
561 setNeedsAnimate();
562 }
563
564 // Notify the impl thread that the beginFrame has completed. This will
565 // begin the commit process, which is blocking from the main thread's
566 // point of view, but asynchronously performed on the impl thread,
567 // coordinated by the CCScheduler.
568 {
569 TRACE_EVENT0("cc", "commit");
570
571 DebugScopedSetMainThreadBlocked mainThreadBlocked;
572
573 base::TimeTicks startTime = base::TimeTicks::HighResNow();
574 CCCompletionEvent completion;
575 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy: :beginFrameCompleteOnImplThread, &completion, queue.release()));
576 completion.wait();
577 base::TimeTicks endTime = base::TimeTicks::HighResNow();
578
579 m_totalCommitTime += endTime - startTime;
580 m_totalCommitCount++;
581 }
582
583 m_layerTreeHost->commitComplete();
584 m_layerTreeHost->didBeginFrame();
585 }
586
587 void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion , PassOwnPtr<CCTextureUpdateQueue> queue)
588 {
589 TRACE_EVENT0("cc", "CCThreadProxy::beginFrameCompleteOnImplThread");
590 ASSERT(!m_commitCompletionEventOnImplThread);
591 ASSERT(isImplThread() && isMainThreadBlocked());
592 ASSERT(m_schedulerOnImplThread);
593 ASSERT(m_schedulerOnImplThread->commitPending());
594
595 if (!m_layerTreeHostImpl.get()) {
596 TRACE_EVENT0("cc", "EarlyOut_NoLayerTree");
597 completion->signal();
598 return;
599 }
600
601 // Clear any uploads we were making to textures linked to evicted
602 // resources
603 if (m_layerTreeHost->evictedContentsTexturesBackingsExist())
604 queue->clearUploadsToEvictedResources();
605
606 // If we unlinked evicted textures on the main thread, delete them now.
607 if (m_layerTreeHost->deleteEvictedContentTexturesBackings()) {
608 // Deleting the evicted textures' backings resulted in some textures in the
609 // layer tree being invalidated (unliked from their backings). Kick off
610 // another commit to fill them again.
611 setNeedsCommitOnImplThread();
612 } else {
613 // The layer tree does not reference evicted textures, so mark that we
614 // can draw this tree once this commit is complete.
615 if (m_layerTreeHostImpl->contentsTexturesPurged())
616 m_resetContentsTexturesPurgedAfterCommitOnImplThread = true;
617 }
618
619 m_currentTextureUpdateControllerOnImplThread = CCTextureUpdateController::cr eate(this, CCProxy::implThread(), queue, m_layerTreeHostImpl->resourceProvider() , m_layerTreeHostImpl->resourceProvider()->textureUploader());
620 m_currentTextureUpdateControllerOnImplThread->performMoreUpdates(
621 m_schedulerOnImplThread->anticipatedDrawTime());
622
623 m_commitCompletionEventOnImplThread = completion;
624 }
625
626 void CCThreadProxy::beginFrameAbortedOnImplThread()
627 {
628 TRACE_EVENT0("cc", "CCThreadProxy::beginFrameAbortedOnImplThread");
629 ASSERT(isImplThread());
630 ASSERT(m_schedulerOnImplThread);
631 ASSERT(m_schedulerOnImplThread->commitPending());
632
633 m_schedulerOnImplThread->beginFrameAborted();
634 }
635
636 void CCThreadProxy::scheduledActionCommit()
637 {
638 TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionCommit");
639 ASSERT(isImplThread());
640 ASSERT(m_commitCompletionEventOnImplThread);
641 ASSERT(m_currentTextureUpdateControllerOnImplThread);
642
643 // Complete all remaining texture updates.
644 m_currentTextureUpdateControllerOnImplThread->finalize();
645 m_currentTextureUpdateControllerOnImplThread.clear();
646
647 m_layerTreeHostImpl->beginCommit();
648
649 m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get());
650 m_layerTreeHost->finishCommitOnImplThread(m_layerTreeHostImpl.get());
651
652 if (m_resetContentsTexturesPurgedAfterCommitOnImplThread) {
653 m_resetContentsTexturesPurgedAfterCommitOnImplThread = false;
654 m_layerTreeHostImpl->resetContentsTexturesPurged();
655 }
656
657 m_layerTreeHostImpl->commitComplete();
658
659 m_nextFrameIsNewlyCommittedFrameOnImplThread = true;
660
661 m_commitCompletionEventOnImplThread->signal();
662 m_commitCompletionEventOnImplThread = 0;
663
664 // SetVisible kicks off the next scheduler action, so this must be last.
665 m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible());
666 }
667
668 void CCThreadProxy::scheduledActionBeginContextRecreation()
669 {
670 ASSERT(isImplThread());
671 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginCo ntextRecreation));
672 }
673
674 CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapInte rnal(bool forcedDraw)
675 {
676 TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionDrawAndSwap");
677 CCScheduledActionDrawAndSwapResult result;
678 result.didDraw = false;
679 result.didSwap = false;
680 ASSERT(isImplThread());
681 ASSERT(m_layerTreeHostImpl.get());
682 if (!m_layerTreeHostImpl.get())
683 return result;
684
685 ASSERT(m_layerTreeHostImpl->renderer());
686 if (!m_layerTreeHostImpl->renderer())
687 return result;
688
689 // FIXME: compute the frame display time more intelligently
690 double monotonicTime = monotonicallyIncreasingTime();
691 double wallClockTime = currentTime();
692
693 if (m_inputHandlerOnImplThread.get())
694 m_inputHandlerOnImplThread->animate(monotonicTime);
695 m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
696
697 // This method is called on a forced draw, regardless of whether we are able to produce a frame,
698 // as the calling site on main thread is blocked until its request completes , and we signal
699 // completion here. If canDraw() is false, we will indicate success=false to the caller, but we
700 // must still signal completion to avoid deadlock.
701
702 // We guard prepareToDraw() with canDraw() because it always returns a valid frame, so can only
703 // be used when such a frame is possible. Since drawLayers() depends on the result of
704 // prepareToDraw(), it is guarded on canDraw() as well.
705
706 CCLayerTreeHostImpl::FrameData frame;
707 bool drawFrame = m_layerTreeHostImpl->canDraw() && (m_layerTreeHostImpl->pre pareToDraw(frame) || forcedDraw);
708 if (drawFrame) {
709 m_layerTreeHostImpl->drawLayers(frame);
710 result.didDraw = true;
711 }
712 m_layerTreeHostImpl->didDrawAllLayers(frame);
713
714 // Check for a pending compositeAndReadback.
715 if (m_readbackRequestOnImplThread) {
716 m_readbackRequestOnImplThread->success = false;
717 if (drawFrame) {
718 m_layerTreeHostImpl->readback(m_readbackRequestOnImplThread->pixels, m_readbackRequestOnImplThread->rect);
719 m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isCon textLost();
720 }
721 m_readbackRequestOnImplThread->completion.signal();
722 m_readbackRequestOnImplThread = 0;
723 } else if (drawFrame)
724 result.didSwap = m_layerTreeHostImpl->swapBuffers();
725
726 // Tell the main thread that the the newly-commited frame was drawn.
727 if (m_nextFrameIsNewlyCommittedFrameOnImplThread) {
728 m_nextFrameIsNewlyCommittedFrameOnImplThread = false;
729 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::did CommitAndDrawFrame));
730 }
731
732 return result;
733 }
734
735 void CCThreadProxy::acquireLayerTextures()
736 {
737 // Called when the main thread needs to modify a layer texture that is used
738 // directly by the compositor.
739 // This method will block until the next compositor draw if there is a
740 // previously committed frame that is still undrawn. This is necessary to
741 // ensure that the main thread does not monopolize access to the textures.
742 ASSERT(isMainThread());
743
744 if (m_texturesAcquired)
745 return;
746
747 TRACE_EVENT0("cc", "CCThreadProxy::acquireLayerTextures");
748 DebugScopedSetMainThreadBlocked mainThreadBlocked;
749 CCCompletionEvent completion;
750 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::acq uireLayerTexturesForMainThreadOnImplThread, &completion));
751 completion.wait(); // Block until it is safe to write to layer textures from the main thread.
752
753 m_texturesAcquired = true;
754 }
755
756 void CCThreadProxy::acquireLayerTexturesForMainThreadOnImplThread(CCCompletionEv ent* completion)
757 {
758 ASSERT(isImplThread());
759 ASSERT(!m_textureAcquisitionCompletionEventOnImplThread);
760
761 m_textureAcquisitionCompletionEventOnImplThread = completion;
762 m_schedulerOnImplThread->setMainThreadNeedsLayerTextures();
763 }
764
765 void CCThreadProxy::scheduledActionAcquireLayerTexturesForMainThread()
766 {
767 ASSERT(m_textureAcquisitionCompletionEventOnImplThread);
768 m_textureAcquisitionCompletionEventOnImplThread->signal();
769 m_textureAcquisitionCompletionEventOnImplThread = 0;
770 }
771
772 CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapIfPo ssible()
773 {
774 return scheduledActionDrawAndSwapInternal(false);
775 }
776
777 CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapForc ed()
778 {
779 return scheduledActionDrawAndSwapInternal(true);
780 }
781
782 void CCThreadProxy::didAnticipatedDrawTimeChange(base::TimeTicks time)
783 {
784 if (!m_currentTextureUpdateControllerOnImplThread)
785 return;
786
787 m_currentTextureUpdateControllerOnImplThread->performMoreUpdates(time);
788 }
789
790 void CCThreadProxy::readyToFinalizeTextureUpdates()
791 {
792 ASSERT(isImplThread());
793 m_schedulerOnImplThread->beginFrameComplete();
794 }
795
796 void CCThreadProxy::didCommitAndDrawFrame()
797 {
798 ASSERT(isMainThread());
799 if (!m_layerTreeHost)
800 return;
801 m_layerTreeHost->didCommitAndDrawFrame();
802 }
803
804 void CCThreadProxy::didCompleteSwapBuffers()
805 {
806 ASSERT(isMainThread());
807 if (!m_layerTreeHost)
808 return;
809 m_layerTreeHost->didCompleteSwapBuffers();
810 }
811
812 void CCThreadProxy::setAnimationEvents(CCAnimationEventsVector* passed_events, d ouble wallClockTime)
813 {
814 scoped_ptr<CCAnimationEventsVector> events(make_scoped_ptr(passed_events));
815
816 TRACE_EVENT0("cc", "CCThreadProxy::setAnimationEvents");
817 ASSERT(isMainThread());
818 if (!m_layerTreeHost)
819 return;
820 m_layerTreeHost->setAnimationEvents(events.Pass(), wallClockTime);
821 }
822
823 class CCThreadProxyContextRecreationTimer : public CCTimer, CCTimerClient {
824 public:
825 static PassOwnPtr<CCThreadProxyContextRecreationTimer> create(CCThreadProxy* proxy) { return adoptPtr(new CCThreadProxyContextRecreationTimer(proxy)); }
826
827 virtual void onTimerFired() OVERRIDE
828 {
829 m_proxy->tryToRecreateContext();
830 }
831
832 private:
833 explicit CCThreadProxyContextRecreationTimer(CCThreadProxy* proxy)
834 : CCTimer(CCProxy::mainThread(), this)
835 , m_proxy(proxy)
836 {
837 }
838
839 CCThreadProxy* m_proxy;
840 };
841
842 void CCThreadProxy::beginContextRecreation()
843 {
844 TRACE_EVENT0("cc", "CCThreadProxy::beginContextRecreation");
845 ASSERT(isMainThread());
846 ASSERT(!m_contextRecreationTimer);
847 m_contextRecreationTimer = CCThreadProxyContextRecreationTimer::create(this) ;
848 m_layerTreeHost->didLoseContext();
849 m_contextRecreationTimer->startOneShot(contextRecreationTickRate);
850 }
851
852 void CCThreadProxy::tryToRecreateContext()
853 {
854 ASSERT(isMainThread());
855 ASSERT(m_layerTreeHost);
856 CCLayerTreeHost::RecreateResult result = m_layerTreeHost->recreateContext();
857 if (result == CCLayerTreeHost::RecreateFailedButTryAgain)
858 m_contextRecreationTimer->startOneShot(contextRecreationTickRate);
859 else if (result == CCLayerTreeHost::RecreateSucceeded)
860 m_contextRecreationTimer.clear();
861 }
862
863 void CCThreadProxy::initializeImplOnImplThread(CCCompletionEvent* completion, CC InputHandler* handler)
864 {
865 TRACE_EVENT0("cc", "CCThreadProxy::initializeImplOnImplThread");
866 ASSERT(isImplThread());
867 m_layerTreeHostImpl = m_layerTreeHost->createLayerTreeHostImpl(this);
868 const base::TimeDelta displayRefreshInterval = base::TimeDelta::FromMicrosec onds(base::Time::kMicrosecondsPerSecond / 60);
869 scoped_ptr<CCFrameRateController> frameRateController;
870 if (m_renderVSyncEnabled)
871 frameRateController.reset(new CCFrameRateController(CCDelayBasedTimeSour ce::create(displayRefreshInterval, CCProxy::implThread())));
872 else
873 frameRateController.reset(new CCFrameRateController(CCProxy::implThread( )));
874 m_schedulerOnImplThread = CCScheduler::create(this, frameRateController.Pass ());
875 m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible());
876
877 m_inputHandlerOnImplThread = scoped_ptr<CCInputHandler>(handler);
878 if (m_inputHandlerOnImplThread.get())
879 m_inputHandlerOnImplThread->bindToClient(m_layerTreeHostImpl.get());
880
881 completion->signal();
882 }
883
884 void CCThreadProxy::initializeContextOnImplThread(CCGraphicsContext* context)
885 {
886 TRACE_EVENT0("cc", "CCThreadProxy::initializeContextOnImplThread");
887 ASSERT(isImplThread());
888 m_contextBeforeInitializationOnImplThread = scoped_ptr<CCGraphicsContext>(co ntext).Pass();
889 }
890
891 void CCThreadProxy::initializeRendererOnImplThread(CCCompletionEvent* completion , bool* initializeSucceeded, RendererCapabilities* capabilities)
892 {
893 TRACE_EVENT0("cc", "CCThreadProxy::initializeRendererOnImplThread");
894 ASSERT(isImplThread());
895 ASSERT(m_contextBeforeInitializationOnImplThread.get());
896 *initializeSucceeded = m_layerTreeHostImpl->initializeRenderer(m_contextBefo reInitializationOnImplThread.Pass());
897 if (*initializeSucceeded) {
898 *capabilities = m_layerTreeHostImpl->rendererCapabilities();
899 m_schedulerOnImplThread->setSwapBuffersCompleteSupported(
900 capabilities->usingSwapCompleteCallback);
901 }
902
903 completion->signal();
904 }
905
906 void CCThreadProxy::layerTreeHostClosedOnImplThread(CCCompletionEvent* completio n)
907 {
908 TRACE_EVENT0("cc", "CCThreadProxy::layerTreeHostClosedOnImplThread");
909 ASSERT(isImplThread());
910 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->res ourceProvider());
911 m_inputHandlerOnImplThread.reset();
912 m_layerTreeHostImpl.reset();
913 m_schedulerOnImplThread.clear();
914 completion->signal();
915 }
916
917 void CCThreadProxy::setFullRootLayerDamageOnImplThread()
918 {
919 ASSERT(isImplThread());
920 m_layerTreeHostImpl->setFullRootLayerDamage();
921 }
922
923 size_t CCThreadProxy::maxPartialTextureUpdates() const
924 {
925 return CCTextureUpdateController::maxPartialTextureUpdates();
926 }
927
928 void CCThreadProxy::recreateContextOnImplThread(CCCompletionEvent* completion, C CGraphicsContext* contextPtr, bool* recreateSucceeded, RendererCapabilities* cap abilities)
929 {
930 TRACE_EVENT0("cc", "CCThreadProxy::recreateContextOnImplThread");
931 ASSERT(isImplThread());
932 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->res ourceProvider());
933 *recreateSucceeded = m_layerTreeHostImpl->initializeRenderer(scoped_ptr<CCGr aphicsContext>(contextPtr).Pass());
934 if (*recreateSucceeded) {
935 *capabilities = m_layerTreeHostImpl->rendererCapabilities();
936 m_schedulerOnImplThread->didRecreateContext();
937 }
938 completion->signal();
939 }
940
941 void CCThreadProxy::renderingStatsOnImplThread(CCCompletionEvent* completion, CC RenderingStats* stats)
942 {
943 ASSERT(isImplThread());
944 m_layerTreeHostImpl->renderingStats(stats);
945 completion->signal();
946 }
947
948 CCThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState()
949 : monotonicFrameBeginTime(0)
950 {
951 }
952
953 CCThreadProxy::BeginFrameAndCommitState::~BeginFrameAndCommitState()
954 {
955 }
956
957 } // namespace cc
OLDNEW
« no previous file with comments | « cc/CCThreadProxy.h ('k') | cc/CCThreadTask.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698