| 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 30 matching lines...) Expand all Loading... |
| 354 { | 353 { |
| 355 DCHECK(isImplThread()); | 354 DCHECK(isImplThread()); |
| 356 TRACE_EVENT0("cc", "ThreadProxy::setNeedsForcedCommitOnImplThread"); | 355 TRACE_EVENT0("cc", "ThreadProxy::setNeedsForcedCommitOnImplThread"); |
| 357 m_schedulerOnImplThread->setNeedsForcedCommit(); | 356 m_schedulerOnImplThread->setNeedsForcedCommit(); |
| 358 } | 357 } |
| 359 | 358 |
| 360 void ThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<Animati
onEventsVector> events, base::Time wallClockTime) | 359 void ThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<Animati
onEventsVector> events, base::Time wallClockTime) |
| 361 { | 360 { |
| 362 DCHECK(isImplThread()); | 361 DCHECK(isImplThread()); |
| 363 TRACE_EVENT0("cc", "ThreadProxy::postAnimationEventsToMainThreadOnImplThread
"); | 362 TRACE_EVENT0("cc", "ThreadProxy::postAnimationEventsToMainThreadOnImplThread
"); |
| 364 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::setAnimation
Events, base::Unretained(this), base::Passed(events.Pass()), wallClockTime)); | 363 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::setAnimationEvents, m
_mainThreadWeakPtr, base::Passed(events.Pass()), wallClockTime)); |
| 365 } | 364 } |
| 366 | 365 |
| 367 bool ThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int
priorityCutoff) | 366 bool ThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int
priorityCutoff) |
| 368 { | 367 { |
| 369 DCHECK(isImplThread()); | 368 DCHECK(isImplThread()); |
| 370 | 369 |
| 371 if (!m_layerTreeHost->contentsTextureManager()) | 370 if (!m_layerTreeHost->contentsTextureManager()) |
| 372 return false; | 371 return false; |
| 373 | 372 |
| 374 bool reduceResult = m_layerTreeHost->contentsTextureManager()->reduceMemoryO
nImplThread(limitBytes, priorityCutoff, m_layerTreeHostImpl->resourceProvider())
; | 373 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... |
| 409 DCHECK(isMainThread()); | 408 DCHECK(isMainThread()); |
| 410 DCHECK_NE(m_deferCommits, deferCommits); | 409 DCHECK_NE(m_deferCommits, deferCommits); |
| 411 m_deferCommits = deferCommits; | 410 m_deferCommits = deferCommits; |
| 412 | 411 |
| 413 if (m_deferCommits) | 412 if (m_deferCommits) |
| 414 TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::setDeferCommits", this); | 413 TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::setDeferCommits", this); |
| 415 else | 414 else |
| 416 TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::setDeferCommits", this); | 415 TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::setDeferCommits", this); |
| 417 | 416 |
| 418 if (!m_deferCommits && m_pendingDeferredCommit) | 417 if (!m_deferCommits && m_pendingDeferredCommit) |
| 419 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::beginFra
me, base::Unretained(this), base::Passed(m_pendingDeferredCommit.Pass()))); | 418 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::beginFrame, m_mai
nThreadWeakPtr, base::Passed(m_pendingDeferredCommit.Pass()))); |
| 420 } | 419 } |
| 421 | 420 |
| 422 bool ThreadProxy::commitRequested() const | 421 bool ThreadProxy::commitRequested() const |
| 423 { | 422 { |
| 424 DCHECK(isMainThread()); | 423 DCHECK(isMainThread()); |
| 425 return m_commitRequested; | 424 return m_commitRequested; |
| 426 } | 425 } |
| 427 | 426 |
| 428 void ThreadProxy::setNeedsRedrawOnImplThread() | 427 void ThreadProxy::setNeedsRedrawOnImplThread() |
| 429 { | 428 { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 442 { | 441 { |
| 443 DCHECK(isMainThread()); | 442 DCHECK(isMainThread()); |
| 444 DCHECK(Proxy::implThread()); | 443 DCHECK(Proxy::implThread()); |
| 445 // Create LayerTreeHostImpl. | 444 // Create LayerTreeHostImpl. |
| 446 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); | 445 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); |
| 447 CompletionEvent completion; | 446 CompletionEvent completion; |
| 448 scoped_ptr<InputHandler> handler = m_layerTreeHost->createInputHandler(); | 447 scoped_ptr<InputHandler> handler = m_layerTreeHost->createInputHandler(); |
| 449 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::initializeImplOnImplT
hread, base::Unretained(this), &completion, handler.release())); | 448 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::initializeImplOnImplT
hread, base::Unretained(this), &completion, handler.release())); |
| 450 completion.wait(); | 449 completion.wait(); |
| 451 | 450 |
| 451 m_mainThreadWeakPtr = m_weakFactory.GetWeakPtr(); |
| 452 |
| 452 m_started = true; | 453 m_started = true; |
| 453 } | 454 } |
| 454 | 455 |
| 455 void ThreadProxy::stop() | 456 void ThreadProxy::stop() |
| 456 { | 457 { |
| 457 TRACE_EVENT0("cc", "ThreadProxy::stop"); | 458 TRACE_EVENT0("cc", "ThreadProxy::stop"); |
| 458 DCHECK(isMainThread()); | 459 DCHECK(isMainThread()); |
| 459 DCHECK(m_started); | 460 DCHECK(m_started); |
| 460 | 461 |
| 461 // Synchronously deletes the impl. | 462 // Synchronously deletes the impl. |
| 462 { | 463 { |
| 463 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); | 464 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); |
| 464 | 465 |
| 465 CompletionEvent completion; | 466 CompletionEvent completion; |
| 466 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::layerTreeHostClos
edOnImplThread, m_implThreadWeakPtr, &completion)); | 467 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::layerTreeHostClos
edOnImplThread, m_implThreadWeakPtr, &completion)); |
| 467 completion.wait(); | 468 completion.wait(); |
| 468 } | 469 } |
| 469 | 470 |
| 470 m_mainThreadProxy->shutdown(); // Stop running tasks posted to us. | 471 m_weakFactory.InvalidateWeakPtrs(); |
| 471 | 472 |
| 472 DCHECK(!m_layerTreeHostImpl.get()); // verify that the impl deleted. | 473 DCHECK(!m_layerTreeHostImpl.get()); // verify that the impl deleted. |
| 473 m_layerTreeHost = 0; | 474 m_layerTreeHost = 0; |
| 474 m_started = false; | 475 m_started = false; |
| 475 } | 476 } |
| 476 | 477 |
| 477 void ThreadProxy::forceSerializeOnSwapBuffers() | 478 void ThreadProxy::forceSerializeOnSwapBuffers() |
| 478 { | 479 { |
| 479 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); | 480 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); |
| 480 CompletionEvent completion; | 481 CompletionEvent completion; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 | 515 |
| 515 void ThreadProxy::scheduledActionBeginFrame() | 516 void ThreadProxy::scheduledActionBeginFrame() |
| 516 { | 517 { |
| 517 TRACE_EVENT0("cc", "ThreadProxy::scheduledActionBeginFrame"); | 518 TRACE_EVENT0("cc", "ThreadProxy::scheduledActionBeginFrame"); |
| 518 scoped_ptr<BeginFrameAndCommitState> beginFrameState(new BeginFrameAndCommit
State); | 519 scoped_ptr<BeginFrameAndCommitState> beginFrameState(new BeginFrameAndCommit
State); |
| 519 beginFrameState->monotonicFrameBeginTime = base::TimeTicks::Now(); | 520 beginFrameState->monotonicFrameBeginTime = base::TimeTicks::Now(); |
| 520 beginFrameState->scrollInfo = m_layerTreeHostImpl->processScrollDeltas(); | 521 beginFrameState->scrollInfo = m_layerTreeHostImpl->processScrollDeltas(); |
| 521 beginFrameState->implTransform = m_layerTreeHostImpl->implTransform(); | 522 beginFrameState->implTransform = m_layerTreeHostImpl->implTransform(); |
| 522 DCHECK_GT(m_layerTreeHostImpl->memoryAllocationLimitBytes(), 0u); | 523 DCHECK_GT(m_layerTreeHostImpl->memoryAllocationLimitBytes(), 0u); |
| 523 beginFrameState->memoryAllocationLimitBytes = m_layerTreeHostImpl->memoryAll
ocationLimitBytes(); | 524 beginFrameState->memoryAllocationLimitBytes = m_layerTreeHostImpl->memoryAll
ocationLimitBytes(); |
| 524 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::beginFrame,
base::Unretained(this), base::Passed(beginFrameState.Pass()))); | 525 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::beginFrame, m_mainThr
eadWeakPtr, base::Passed(beginFrameState.Pass()))); |
| 525 | 526 |
| 526 if (m_beginFrameCompletionEventOnImplThread) { | 527 if (m_beginFrameCompletionEventOnImplThread) { |
| 527 m_beginFrameCompletionEventOnImplThread->signal(); | 528 m_beginFrameCompletionEventOnImplThread->signal(); |
| 528 m_beginFrameCompletionEventOnImplThread = 0; | 529 m_beginFrameCompletionEventOnImplThread = 0; |
| 529 } | 530 } |
| 530 } | 531 } |
| 531 | 532 |
| 532 void ThreadProxy::beginFrame(scoped_ptr<BeginFrameAndCommitState> beginFrameStat
e) | 533 void ThreadProxy::beginFrame(scoped_ptr<BeginFrameAndCommitState> beginFrameStat
e) |
| 533 { | 534 { |
| 534 TRACE_EVENT0("cc", "ThreadProxy::beginFrame"); | 535 TRACE_EVENT0("cc", "ThreadProxy::beginFrame"); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 m_commitCompletionEventOnImplThread->signal(); | 714 m_commitCompletionEventOnImplThread->signal(); |
| 714 m_commitCompletionEventOnImplThread = 0; | 715 m_commitCompletionEventOnImplThread = 0; |
| 715 | 716 |
| 716 // SetVisible kicks off the next scheduler action, so this must be last. | 717 // SetVisible kicks off the next scheduler action, so this must be last. |
| 717 m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible()); | 718 m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible()); |
| 718 } | 719 } |
| 719 | 720 |
| 720 void ThreadProxy::scheduledActionBeginContextRecreation() | 721 void ThreadProxy::scheduledActionBeginContextRecreation() |
| 721 { | 722 { |
| 722 DCHECK(isImplThread()); | 723 DCHECK(isImplThread()); |
| 723 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::beginContext
Recreation, base::Unretained(this))); | 724 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::beginContextRecreatio
n, m_mainThreadWeakPtr)); |
| 724 } | 725 } |
| 725 | 726 |
| 726 ScheduledActionDrawAndSwapResult ThreadProxy::scheduledActionDrawAndSwapInternal
(bool forcedDraw) | 727 ScheduledActionDrawAndSwapResult ThreadProxy::scheduledActionDrawAndSwapInternal
(bool forcedDraw) |
| 727 { | 728 { |
| 728 TRACE_EVENT0("cc", "ThreadProxy::scheduledActionDrawAndSwap"); | 729 TRACE_EVENT0("cc", "ThreadProxy::scheduledActionDrawAndSwap"); |
| 729 ScheduledActionDrawAndSwapResult result; | 730 ScheduledActionDrawAndSwapResult result; |
| 730 result.didDraw = false; | 731 result.didDraw = false; |
| 731 result.didSwap = false; | 732 result.didSwap = false; |
| 732 DCHECK(isImplThread()); | 733 DCHECK(isImplThread()); |
| 733 DCHECK(m_layerTreeHostImpl.get()); | 734 DCHECK(m_layerTreeHostImpl.get()); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isCon
textLost(); | 772 m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isCon
textLost(); |
| 772 } | 773 } |
| 773 m_readbackRequestOnImplThread->completion.signal(); | 774 m_readbackRequestOnImplThread->completion.signal(); |
| 774 m_readbackRequestOnImplThread = 0; | 775 m_readbackRequestOnImplThread = 0; |
| 775 } else if (drawFrame) | 776 } else if (drawFrame) |
| 776 result.didSwap = m_layerTreeHostImpl->swapBuffers(); | 777 result.didSwap = m_layerTreeHostImpl->swapBuffers(); |
| 777 | 778 |
| 778 // Tell the main thread that the the newly-commited frame was drawn. | 779 // Tell the main thread that the the newly-commited frame was drawn. |
| 779 if (m_nextFrameIsNewlyCommittedFrameOnImplThread) { | 780 if (m_nextFrameIsNewlyCommittedFrameOnImplThread) { |
| 780 m_nextFrameIsNewlyCommittedFrameOnImplThread = false; | 781 m_nextFrameIsNewlyCommittedFrameOnImplThread = false; |
| 781 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::didCommi
tAndDrawFrame, base::Unretained(this))); | 782 Proxy::mainThread()->postTask(base::Bind(&ThreadProxy::didCommitAndDrawF
rame, m_mainThreadWeakPtr)); |
| 782 } | 783 } |
| 783 | 784 |
| 784 return result; | 785 return result; |
| 785 } | 786 } |
| 786 | 787 |
| 787 void ThreadProxy::acquireLayerTextures() | 788 void ThreadProxy::acquireLayerTextures() |
| 788 { | 789 { |
| 789 // Called when the main thread needs to modify a layer texture that is used | 790 // Called when the main thread needs to modify a layer texture that is used |
| 790 // directly by the compositor. | 791 // directly by the compositor. |
| 791 // This method will block until the next compositor draw if there is a | 792 // 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... |
| 999 } | 1000 } |
| 1000 | 1001 |
| 1001 void ThreadProxy::commitPendingOnImplThreadForTesting(CommitPendingRequest* requ
est) | 1002 void ThreadProxy::commitPendingOnImplThreadForTesting(CommitPendingRequest* requ
est) |
| 1002 { | 1003 { |
| 1003 DCHECK(isImplThread()); | 1004 DCHECK(isImplThread()); |
| 1004 request->commitPending = m_schedulerOnImplThread->commitPending(); | 1005 request->commitPending = m_schedulerOnImplThread->commitPending(); |
| 1005 request->completion.signal(); | 1006 request->completion.signal(); |
| 1006 } | 1007 } |
| 1007 | 1008 |
| 1008 } // namespace cc | 1009 } // namespace cc |
| OLD | NEW |