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 |