| 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 |