OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/thread_proxy.h" | 5 #include "cc/thread_proxy.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "cc/delay_based_time_source.h" | 9 #include "cc/delay_based_time_source.h" |
10 #include "cc/draw_quad.h" | 10 #include "cc/draw_quad.h" |
11 #include "cc/frame_rate_controller.h" | 11 #include "cc/frame_rate_controller.h" |
12 #include "cc/input_handler.h" | 12 #include "cc/input_handler.h" |
13 #include "cc/layer_tree_host.h" | 13 #include "cc/layer_tree_host.h" |
14 #include "cc/output_surface.h" | 14 #include "cc/output_surface.h" |
15 #include "cc/scheduler.h" | 15 #include "cc/scheduler.h" |
16 #include "cc/scoped_thread_proxy.h" | |
17 #include "cc/thread.h" | 16 #include "cc/thread.h" |
18 #include "third_party/WebKit/Source/Platform/chromium/public/WebSharedGraphicsCo
ntext3D.h" | 17 #include "third_party/WebKit/Source/Platform/chromium/public/WebSharedGraphicsCo
ntext3D.h" |
19 | 18 |
20 using WebKit::WebSharedGraphicsContext3D; | 19 using WebKit::WebSharedGraphicsContext3D; |
21 | 20 |
22 namespace { | 21 namespace { |
23 | 22 |
24 // Measured in seconds. | 23 // Measured in seconds. |
25 const double contextRecreationTickRate = 0.03; | 24 const double contextRecreationTickRate = 0.03; |
26 | 25 |
(...skipping 11 matching lines...) Expand all Loading... |
38 , m_animateRequested(false) | 37 , m_animateRequested(false) |
39 , m_commitRequested(false) | 38 , m_commitRequested(false) |
40 , m_commitRequestSentToImplThread(false) | 39 , m_commitRequestSentToImplThread(false) |
41 , m_layerTreeHost(layerTreeHost) | 40 , m_layerTreeHost(layerTreeHost) |
42 , m_rendererInitialized(false) | 41 , m_rendererInitialized(false) |
43 , m_started(false) | 42 , m_started(false) |
44 , m_texturesAcquired(true) | 43 , m_texturesAcquired(true) |
45 , m_inCompositeAndReadback(false) | 44 , m_inCompositeAndReadback(false) |
46 , m_manageTilesPending(false) | 45 , m_manageTilesPending(false) |
47 , m_weakFactoryOnImplThread(ALLOW_THIS_IN_INITIALIZER_LIST(this)) | 46 , m_weakFactoryOnImplThread(ALLOW_THIS_IN_INITIALIZER_LIST(this)) |
48 , m_mainThreadProxy(ScopedThreadProxy::create(Proxy::mainThread())) | 47 , m_weakFactory(ALLOW_THIS_IN_INITIALIZER_LIST(this)) |
49 , m_beginFrameCompletionEventOnImplThread(0) | 48 , m_beginFrameCompletionEventOnImplThread(0) |
50 , m_readbackRequestOnImplThread(0) | 49 , m_readbackRequestOnImplThread(0) |
51 , m_commitCompletionEventOnImplThread(0) | 50 , m_commitCompletionEventOnImplThread(0) |
52 , m_textureAcquisitionCompletionEventOnImplThread(0) | 51 , m_textureAcquisitionCompletionEventOnImplThread(0) |
53 , m_nextFrameIsNewlyCommittedFrameOnImplThread(false) | 52 , m_nextFrameIsNewlyCommittedFrameOnImplThread(false) |
54 , m_renderVSyncEnabled(layerTreeHost->settings().renderVSyncEnabled) | 53 , m_renderVSyncEnabled(layerTreeHost->settings().renderVSyncEnabled) |
55 , m_totalCommitCount(0) | 54 , m_totalCommitCount(0) |
56 , m_deferCommits(false) | 55 , m_deferCommits(false) |
57 { | 56 { |
58 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy"); | 57 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy"); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 DCHECK(isImplThread()); | 302 DCHECK(isImplThread()); |
304 TRACE_EVENT0("cc", "ThreadProxy::didLoseOutputSurfaceOnImplThread"); | 303 TRACE_EVENT0("cc", "ThreadProxy::didLoseOutputSurfaceOnImplThread"); |
305 m_schedulerOnImplThread->didLoseOutputSurface(); | 304 m_schedulerOnImplThread->didLoseOutputSurface(); |
306 } | 305 } |
307 | 306 |
308 void ThreadProxy::onSwapBuffersCompleteOnImplThread() | 307 void ThreadProxy::onSwapBuffersCompleteOnImplThread() |
309 { | 308 { |
310 DCHECK(isImplThread()); | 309 DCHECK(isImplThread()); |
311 TRACE_EVENT0("cc", "ThreadProxy::onSwapBuffersCompleteOnImplThread"); | 310 TRACE_EVENT0("cc", "ThreadProxy::onSwapBuffersCompleteOnImplThread"); |
312 m_schedulerOnImplThread->didSwapBuffersComplete(); | 311 m_schedulerOnImplThread->didSwapBuffersComplete(); |
313 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::didCompleteS
wapBuffers, base::Unretained(this))); | 312 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::didCompleteSwapBuffer
s, m_mainThreadWeakPtr)); |
314 } | 313 } |
315 | 314 |
316 void ThreadProxy::onVSyncParametersChanged(base::TimeTicks timebase, base::TimeD
elta interval) | 315 void ThreadProxy::onVSyncParametersChanged(base::TimeTicks timebase, base::TimeD
elta interval) |
317 { | 316 { |
318 DCHECK(isImplThread()); | 317 DCHECK(isImplThread()); |
319 TRACE_EVENT2("cc", "ThreadProxy::onVSyncParametersChanged", "timebase", (tim
ebase - base::TimeTicks()).InMilliseconds(), "interval", interval.InMilliseconds
()); | 318 TRACE_EVENT2("cc", "ThreadProxy::onVSyncParametersChanged", "timebase", (tim
ebase - base::TimeTicks()).InMilliseconds(), "interval", interval.InMilliseconds
()); |
320 m_schedulerOnImplThread->setTimebaseAndInterval(timebase, interval); | 319 m_schedulerOnImplThread->setTimebaseAndInterval(timebase, interval); |
321 } | 320 } |
322 | 321 |
323 void ThreadProxy::onCanDrawStateChanged(bool canDraw) | 322 void ThreadProxy::onCanDrawStateChanged(bool canDraw) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 { | 360 { |
362 DCHECK(isImplThread()); | 361 DCHECK(isImplThread()); |
363 TRACE_EVENT0("cc", "ThreadProxy::setNeedsForcedCommitOnImplThread"); | 362 TRACE_EVENT0("cc", "ThreadProxy::setNeedsForcedCommitOnImplThread"); |
364 m_schedulerOnImplThread->setNeedsForcedCommit(); | 363 m_schedulerOnImplThread->setNeedsForcedCommit(); |
365 } | 364 } |
366 | 365 |
367 void ThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<Animati
onEventsVector> events, base::Time wallClockTime) | 366 void ThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<Animati
onEventsVector> events, base::Time wallClockTime) |
368 { | 367 { |
369 DCHECK(isImplThread()); | 368 DCHECK(isImplThread()); |
370 TRACE_EVENT0("cc", "ThreadProxy::postAnimationEventsToMainThreadOnImplThread
"); | 369 TRACE_EVENT0("cc", "ThreadProxy::postAnimationEventsToMainThreadOnImplThread
"); |
371 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::setAnimation
Events, base::Unretained(this), base::Passed(&events), wallClockTime)); | 370 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::setAnimationEvents, m
_mainThreadWeakPtr, base::Passed(&events), wallClockTime)); |
372 } | 371 } |
373 | 372 |
374 bool ThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int
priorityCutoff) | 373 bool ThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int
priorityCutoff) |
375 { | 374 { |
376 DCHECK(isImplThread()); | 375 DCHECK(isImplThread()); |
377 | 376 |
378 if (!m_layerTreeHost->contentsTextureManager()) | 377 if (!m_layerTreeHost->contentsTextureManager()) |
379 return false; | 378 return false; |
380 | 379 |
381 bool reduceResult = m_layerTreeHost->contentsTextureManager()->reduceMemoryO
nImplThread(limitBytes, priorityCutoff, m_layerTreeHostImpl->resourceProvider())
; | 380 bool reduceResult = m_layerTreeHost->contentsTextureManager()->reduceMemoryO
nImplThread(limitBytes, priorityCutoff, m_layerTreeHostImpl->resourceProvider())
; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 DCHECK(isMainThread()); | 415 DCHECK(isMainThread()); |
417 DCHECK_NE(m_deferCommits, deferCommits); | 416 DCHECK_NE(m_deferCommits, deferCommits); |
418 m_deferCommits = deferCommits; | 417 m_deferCommits = deferCommits; |
419 | 418 |
420 if (m_deferCommits) | 419 if (m_deferCommits) |
421 TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::setDeferCommits", this); | 420 TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::setDeferCommits", this); |
422 else | 421 else |
423 TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::setDeferCommits", this); | 422 TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::setDeferCommits", this); |
424 | 423 |
425 if (!m_deferCommits && m_pendingDeferredCommit) | 424 if (!m_deferCommits && m_pendingDeferredCommit) |
426 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::beginFra
me, base::Unretained(this), base::Passed(&m_pendingDeferredCommit))); | 425 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::beginFrame, m_mai
nThreadWeakPtr, base::Passed(&m_pendingDeferredCommit))); |
427 } | 426 } |
428 | 427 |
429 bool ThreadProxy::commitRequested() const | 428 bool ThreadProxy::commitRequested() const |
430 { | 429 { |
431 DCHECK(isMainThread()); | 430 DCHECK(isMainThread()); |
432 return m_commitRequested; | 431 return m_commitRequested; |
433 } | 432 } |
434 | 433 |
435 void ThreadProxy::setNeedsRedrawOnImplThread() | 434 void ThreadProxy::setNeedsRedrawOnImplThread() |
436 { | 435 { |
(...skipping 12 matching lines...) Expand all Loading... |
449 { | 448 { |
450 DCHECK(isMainThread()); | 449 DCHECK(isMainThread()); |
451 DCHECK(Proxy::implThread()); | 450 DCHECK(Proxy::implThread()); |
452 // Create LayerTreeHostImpl. | 451 // Create LayerTreeHostImpl. |
453 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); | 452 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); |
454 CompletionEvent completion; | 453 CompletionEvent completion; |
455 scoped_ptr<InputHandler> handler = m_layerTreeHost->createInputHandler(); | 454 scoped_ptr<InputHandler> handler = m_layerTreeHost->createInputHandler(); |
456 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::initializeImplOnImplT
hread, base::Unretained(this), &completion, handler.release())); | 455 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::initializeImplOnImplT
hread, base::Unretained(this), &completion, handler.release())); |
457 completion.wait(); | 456 completion.wait(); |
458 | 457 |
| 458 m_mainThreadWeakPtr = m_weakFactory.GetWeakPtr(); |
| 459 |
459 m_started = true; | 460 m_started = true; |
460 } | 461 } |
461 | 462 |
462 void ThreadProxy::stop() | 463 void ThreadProxy::stop() |
463 { | 464 { |
464 TRACE_EVENT0("cc", "ThreadProxy::stop"); | 465 TRACE_EVENT0("cc", "ThreadProxy::stop"); |
465 DCHECK(isMainThread()); | 466 DCHECK(isMainThread()); |
466 DCHECK(m_started); | 467 DCHECK(m_started); |
467 | 468 |
468 // Synchronously deletes the impl. | 469 // Synchronously deletes the impl. |
469 { | 470 { |
470 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); | 471 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); |
471 | 472 |
472 CompletionEvent completion; | 473 CompletionEvent completion; |
473 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::layerTreeHostClos
edOnImplThread, m_implThreadWeakPtr, &completion)); | 474 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::layerTreeHostClos
edOnImplThread, m_implThreadWeakPtr, &completion)); |
474 completion.wait(); | 475 completion.wait(); |
475 } | 476 } |
476 | 477 |
477 m_mainThreadProxy->shutdown(); // Stop running tasks posted to us. | 478 m_weakFactory.InvalidateWeakPtrs(); |
478 | 479 |
479 DCHECK(!m_layerTreeHostImpl.get()); // verify that the impl deleted. | 480 DCHECK(!m_layerTreeHostImpl.get()); // verify that the impl deleted. |
480 m_layerTreeHost = 0; | 481 m_layerTreeHost = 0; |
481 m_started = false; | 482 m_started = false; |
482 } | 483 } |
483 | 484 |
484 void ThreadProxy::forceSerializeOnSwapBuffers() | 485 void ThreadProxy::forceSerializeOnSwapBuffers() |
485 { | 486 { |
486 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); | 487 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); |
487 CompletionEvent completion; | 488 CompletionEvent completion; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 | 522 |
522 void ThreadProxy::scheduledActionBeginFrame() | 523 void ThreadProxy::scheduledActionBeginFrame() |
523 { | 524 { |
524 TRACE_EVENT0("cc", "ThreadProxy::scheduledActionBeginFrame"); | 525 TRACE_EVENT0("cc", "ThreadProxy::scheduledActionBeginFrame"); |
525 scoped_ptr<BeginFrameAndCommitState> beginFrameState(new BeginFrameAndCommit
State); | 526 scoped_ptr<BeginFrameAndCommitState> beginFrameState(new BeginFrameAndCommit
State); |
526 beginFrameState->monotonicFrameBeginTime = base::TimeTicks::Now(); | 527 beginFrameState->monotonicFrameBeginTime = base::TimeTicks::Now(); |
527 beginFrameState->scrollInfo = m_layerTreeHostImpl->processScrollDeltas(); | 528 beginFrameState->scrollInfo = m_layerTreeHostImpl->processScrollDeltas(); |
528 beginFrameState->implTransform = m_layerTreeHostImpl->implTransform(); | 529 beginFrameState->implTransform = m_layerTreeHostImpl->implTransform(); |
529 DCHECK_GT(m_layerTreeHostImpl->memoryAllocationLimitBytes(), 0u); | 530 DCHECK_GT(m_layerTreeHostImpl->memoryAllocationLimitBytes(), 0u); |
530 beginFrameState->memoryAllocationLimitBytes = m_layerTreeHostImpl->memoryAll
ocationLimitBytes(); | 531 beginFrameState->memoryAllocationLimitBytes = m_layerTreeHostImpl->memoryAll
ocationLimitBytes(); |
531 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::beginFrame,
base::Unretained(this), base::Passed(&beginFrameState))); | 532 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::beginFrame, m_mainThr
eadWeakPtr, base::Passed(&beginFrameState))); |
532 | 533 |
533 if (m_beginFrameCompletionEventOnImplThread) { | 534 if (m_beginFrameCompletionEventOnImplThread) { |
534 m_beginFrameCompletionEventOnImplThread->signal(); | 535 m_beginFrameCompletionEventOnImplThread->signal(); |
535 m_beginFrameCompletionEventOnImplThread = 0; | 536 m_beginFrameCompletionEventOnImplThread = 0; |
536 } | 537 } |
537 } | 538 } |
538 | 539 |
539 void ThreadProxy::beginFrame(scoped_ptr<BeginFrameAndCommitState> beginFrameStat
e) | 540 void ThreadProxy::beginFrame(scoped_ptr<BeginFrameAndCommitState> beginFrameStat
e) |
540 { | 541 { |
541 TRACE_EVENT0("cc", "ThreadProxy::beginFrame"); | 542 TRACE_EVENT0("cc", "ThreadProxy::beginFrame"); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 m_commitCompletionEventOnImplThread->signal(); | 721 m_commitCompletionEventOnImplThread->signal(); |
721 m_commitCompletionEventOnImplThread = 0; | 722 m_commitCompletionEventOnImplThread = 0; |
722 | 723 |
723 // SetVisible kicks off the next scheduler action, so this must be last. | 724 // SetVisible kicks off the next scheduler action, so this must be last. |
724 m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible()); | 725 m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible()); |
725 } | 726 } |
726 | 727 |
727 void ThreadProxy::scheduledActionBeginContextRecreation() | 728 void ThreadProxy::scheduledActionBeginContextRecreation() |
728 { | 729 { |
729 DCHECK(isImplThread()); | 730 DCHECK(isImplThread()); |
730 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::beginContext
Recreation, base::Unretained(this))); | 731 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::beginContextRecreatio
n, m_mainThreadWeakPtr)); |
731 } | 732 } |
732 | 733 |
733 ScheduledActionDrawAndSwapResult ThreadProxy::scheduledActionDrawAndSwapInternal
(bool forcedDraw) | 734 ScheduledActionDrawAndSwapResult ThreadProxy::scheduledActionDrawAndSwapInternal
(bool forcedDraw) |
734 { | 735 { |
735 TRACE_EVENT0("cc", "ThreadProxy::scheduledActionDrawAndSwap"); | 736 TRACE_EVENT0("cc", "ThreadProxy::scheduledActionDrawAndSwap"); |
736 ScheduledActionDrawAndSwapResult result; | 737 ScheduledActionDrawAndSwapResult result; |
737 result.didDraw = false; | 738 result.didDraw = false; |
738 result.didSwap = false; | 739 result.didSwap = false; |
739 DCHECK(isImplThread()); | 740 DCHECK(isImplThread()); |
740 DCHECK(m_layerTreeHostImpl.get()); | 741 DCHECK(m_layerTreeHostImpl.get()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isCon
textLost(); | 779 m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isCon
textLost(); |
779 } | 780 } |
780 m_readbackRequestOnImplThread->completion.signal(); | 781 m_readbackRequestOnImplThread->completion.signal(); |
781 m_readbackRequestOnImplThread = 0; | 782 m_readbackRequestOnImplThread = 0; |
782 } else if (drawFrame) | 783 } else if (drawFrame) |
783 result.didSwap = m_layerTreeHostImpl->swapBuffers(); | 784 result.didSwap = m_layerTreeHostImpl->swapBuffers(); |
784 | 785 |
785 // Tell the main thread that the the newly-commited frame was drawn. | 786 // Tell the main thread that the the newly-commited frame was drawn. |
786 if (m_nextFrameIsNewlyCommittedFrameOnImplThread) { | 787 if (m_nextFrameIsNewlyCommittedFrameOnImplThread) { |
787 m_nextFrameIsNewlyCommittedFrameOnImplThread = false; | 788 m_nextFrameIsNewlyCommittedFrameOnImplThread = false; |
788 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::didCommi
tAndDrawFrame, base::Unretained(this))); | 789 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::didCommitAndDrawF
rame, m_mainThreadWeakPtr)); |
789 } | 790 } |
790 | 791 |
791 return result; | 792 return result; |
792 } | 793 } |
793 | 794 |
794 void ThreadProxy::acquireLayerTextures() | 795 void ThreadProxy::acquireLayerTextures() |
795 { | 796 { |
796 // Called when the main thread needs to modify a layer texture that is used | 797 // Called when the main thread needs to modify a layer texture that is used |
797 // directly by the compositor. | 798 // directly by the compositor. |
798 // This method will block until the next compositor draw if there is a | 799 // This method will block until the next compositor draw if there is a |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1006 } | 1007 } |
1007 | 1008 |
1008 void ThreadProxy::commitPendingOnImplThreadForTesting(CommitPendingRequest* requ
est) | 1009 void ThreadProxy::commitPendingOnImplThreadForTesting(CommitPendingRequest* requ
est) |
1009 { | 1010 { |
1010 DCHECK(isImplThread()); | 1011 DCHECK(isImplThread()); |
1011 request->commitPending = m_schedulerOnImplThread->commitPending(); | 1012 request->commitPending = m_schedulerOnImplThread->commitPending(); |
1012 request->completion.signal(); | 1013 request->completion.signal(); |
1013 } | 1014 } |
1014 | 1015 |
1015 } // namespace cc | 1016 } // namespace cc |
OLD | NEW |