| 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/trees/thread_proxy.h" | 5 #include "cc/trees/thread_proxy.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 DCHECK(IsMainThread()); | 85 DCHECK(IsMainThread()); |
| 86 DCHECK(this->layer_tree_host()); | 86 DCHECK(this->layer_tree_host()); |
| 87 } | 87 } |
| 88 | 88 |
| 89 ThreadProxy::MainThreadOnly::MainThreadOnly(ThreadProxy* proxy, | 89 ThreadProxy::MainThreadOnly::MainThreadOnly(ThreadProxy* proxy, |
| 90 int layer_tree_host_id) | 90 int layer_tree_host_id) |
| 91 : layer_tree_host_id(layer_tree_host_id), | 91 : layer_tree_host_id(layer_tree_host_id), |
| 92 animate_requested(false), | 92 animate_requested(false), |
| 93 commit_requested(false), | 93 commit_requested(false), |
| 94 commit_request_sent_to_impl_thread(false), | 94 commit_request_sent_to_impl_thread(false), |
| 95 created_offscreen_context_provider(false), | |
| 96 started(false), | 95 started(false), |
| 97 in_composite_and_readback(false), | 96 in_composite_and_readback(false), |
| 98 manage_tiles_pending(false), | 97 manage_tiles_pending(false), |
| 99 can_cancel_commit(true), | 98 can_cancel_commit(true), |
| 100 defer_commits(false), | 99 defer_commits(false), |
| 101 weak_factory(proxy) {} | 100 weak_factory(proxy) {} |
| 102 | 101 |
| 103 ThreadProxy::MainThreadOnly::~MainThreadOnly() {} | 102 ThreadProxy::MainThreadOnly::~MainThreadOnly() {} |
| 104 | 103 |
| 105 ThreadProxy::MainThreadOrBlockedMainThread::MainThreadOrBlockedMainThread( | 104 ThreadProxy::MainThreadOrBlockedMainThread::MainThreadOrBlockedMainThread( |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 scoped_ptr<OutputSurface> output_surface = | 286 scoped_ptr<OutputSurface> output_surface = |
| 288 layer_tree_host()->CreateOutputSurface(); | 287 layer_tree_host()->CreateOutputSurface(); |
| 289 | 288 |
| 290 RendererCapabilities capabilities; | 289 RendererCapabilities capabilities; |
| 291 bool success = !!output_surface; | 290 bool success = !!output_surface; |
| 292 if (!success) { | 291 if (!success) { |
| 293 OnOutputSurfaceInitializeAttempted(false, capabilities); | 292 OnOutputSurfaceInitializeAttempted(false, capabilities); |
| 294 return; | 293 return; |
| 295 } | 294 } |
| 296 | 295 |
| 297 scoped_refptr<ContextProvider> offscreen_context_provider; | |
| 298 if (main().created_offscreen_context_provider) { | |
| 299 offscreen_context_provider = | |
| 300 layer_tree_host()->client()->OffscreenContextProvider(); | |
| 301 success = !!offscreen_context_provider.get(); | |
| 302 if (!success) { | |
| 303 OnOutputSurfaceInitializeAttempted(false, capabilities); | |
| 304 return; | |
| 305 } | |
| 306 } | |
| 307 | |
| 308 success = false; | 296 success = false; |
| 309 { | 297 { |
| 310 // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results | 298 // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results |
| 311 // of that call are pushed into the success and capabilities local | 299 // of that call are pushed into the success and capabilities local |
| 312 // variables. | 300 // variables. |
| 313 CompletionEvent completion; | 301 CompletionEvent completion; |
| 314 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 302 DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
| 315 | 303 |
| 316 Proxy::ImplThreadTaskRunner()->PostTask( | 304 Proxy::ImplThreadTaskRunner()->PostTask( |
| 317 FROM_HERE, | 305 FROM_HERE, |
| 318 base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread, | 306 base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread, |
| 319 impl_thread_weak_ptr_, | 307 impl_thread_weak_ptr_, |
| 320 &completion, | 308 &completion, |
| 321 base::Passed(&output_surface), | 309 base::Passed(&output_surface), |
| 322 offscreen_context_provider, | |
| 323 &success, | 310 &success, |
| 324 &capabilities)); | 311 &capabilities)); |
| 325 completion.Wait(); | 312 completion.Wait(); |
| 326 } | 313 } |
| 327 | 314 |
| 328 OnOutputSurfaceInitializeAttempted(success, capabilities); | 315 OnOutputSurfaceInitializeAttempted(success, capabilities); |
| 329 } | 316 } |
| 330 | 317 |
| 331 void ThreadProxy::SetRendererCapabilitiesMainThreadCopy( | 318 void ThreadProxy::SetRendererCapabilitiesMainThreadCopy( |
| 332 const RendererCapabilities& capabilities) { | 319 const RendererCapabilities& capabilities) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread"); | 407 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread"); |
| 421 DCHECK(IsImplThread()); | 408 DCHECK(IsImplThread()); |
| 422 CheckOutputSurfaceStatusOnImplThread(); | 409 CheckOutputSurfaceStatusOnImplThread(); |
| 423 } | 410 } |
| 424 | 411 |
| 425 void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() { | 412 void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() { |
| 426 TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread"); | 413 TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread"); |
| 427 DCHECK(IsImplThread()); | 414 DCHECK(IsImplThread()); |
| 428 if (!impl().layer_tree_host_impl->IsContextLost()) | 415 if (!impl().layer_tree_host_impl->IsContextLost()) |
| 429 return; | 416 return; |
| 430 if (ContextProvider* offscreen_contexts = | |
| 431 impl().layer_tree_host_impl->offscreen_context_provider()) | |
| 432 offscreen_contexts->VerifyContexts(); | |
| 433 impl().scheduler->DidLoseOutputSurface(); | 417 impl().scheduler->DidLoseOutputSurface(); |
| 434 } | 418 } |
| 435 | 419 |
| 436 void ThreadProxy::SetMaxSwapsPendingOnImplThread(int max) { | 420 void ThreadProxy::SetMaxSwapsPendingOnImplThread(int max) { |
| 437 impl().scheduler->SetMaxSwapsPending(max); | 421 impl().scheduler->SetMaxSwapsPending(max); |
| 438 } | 422 } |
| 439 | 423 |
| 440 void ThreadProxy::DidSwapBuffersOnImplThread() { | 424 void ThreadProxy::DidSwapBuffersOnImplThread() { |
| 441 impl().scheduler->DidSwapBuffers(); | 425 impl().scheduler->DidSwapBuffers(); |
| 442 } | 426 } |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 did_handle)); | 926 did_handle)); |
| 943 | 927 |
| 944 // Although the commit is internally aborted, this is because it has been | 928 // Although the commit is internally aborted, this is because it has been |
| 945 // detected to be a no-op. From the perspective of an embedder, this commit | 929 // detected to be a no-op. From the perspective of an embedder, this commit |
| 946 // went through, and input should no longer be throttled, etc. | 930 // went through, and input should no longer be throttled, etc. |
| 947 layer_tree_host()->CommitComplete(); | 931 layer_tree_host()->CommitComplete(); |
| 948 layer_tree_host()->DidBeginMainFrame(); | 932 layer_tree_host()->DidBeginMainFrame(); |
| 949 return; | 933 return; |
| 950 } | 934 } |
| 951 | 935 |
| 952 scoped_refptr<ContextProvider> offscreen_context_provider; | |
| 953 if (main().renderer_capabilities_main_thread_copy.using_offscreen_context3d && | |
| 954 layer_tree_host()->needs_offscreen_context()) { | |
| 955 offscreen_context_provider = | |
| 956 layer_tree_host()->client()->OffscreenContextProvider(); | |
| 957 if (offscreen_context_provider.get()) | |
| 958 main().created_offscreen_context_provider = true; | |
| 959 } | |
| 960 | |
| 961 // Notify the impl thread that the main thread is ready to commit. This will | 936 // Notify the impl thread that the main thread is ready to commit. This will |
| 962 // begin the commit process, which is blocking from the main thread's | 937 // begin the commit process, which is blocking from the main thread's |
| 963 // point of view, but asynchronously performed on the impl thread, | 938 // point of view, but asynchronously performed on the impl thread, |
| 964 // coordinated by the Scheduler. | 939 // coordinated by the Scheduler. |
| 965 { | 940 { |
| 966 TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame::commit"); | 941 TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame::commit"); |
| 967 | 942 |
| 968 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 943 DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
| 969 | 944 |
| 970 // This CapturePostTasks should be destroyed before CommitComplete() is | 945 // This CapturePostTasks should be destroyed before CommitComplete() is |
| 971 // called since that goes out to the embedder, and we want the embedder | 946 // called since that goes out to the embedder, and we want the embedder |
| 972 // to receive its callbacks before that. | 947 // to receive its callbacks before that. |
| 973 BlockingTaskRunner::CapturePostTasks blocked; | 948 BlockingTaskRunner::CapturePostTasks blocked; |
| 974 | 949 |
| 975 CompletionEvent completion; | 950 CompletionEvent completion; |
| 976 Proxy::ImplThreadTaskRunner()->PostTask( | 951 Proxy::ImplThreadTaskRunner()->PostTask( |
| 977 FROM_HERE, | 952 FROM_HERE, |
| 978 base::Bind(&ThreadProxy::StartCommitOnImplThread, | 953 base::Bind(&ThreadProxy::StartCommitOnImplThread, |
| 979 impl_thread_weak_ptr_, | 954 impl_thread_weak_ptr_, |
| 980 &completion, | 955 &completion, |
| 981 queue.release(), | 956 queue.release())); |
| 982 offscreen_context_provider)); | |
| 983 completion.Wait(); | 957 completion.Wait(); |
| 984 | 958 |
| 985 RenderingStatsInstrumentation* stats_instrumentation = | 959 RenderingStatsInstrumentation* stats_instrumentation = |
| 986 layer_tree_host()->rendering_stats_instrumentation(); | 960 layer_tree_host()->rendering_stats_instrumentation(); |
| 987 BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent( | 961 BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent( |
| 988 stats_instrumentation->main_thread_rendering_stats()); | 962 stats_instrumentation->main_thread_rendering_stats()); |
| 989 stats_instrumentation->AccumulateAndClearMainThreadStats(); | 963 stats_instrumentation->AccumulateAndClearMainThreadStats(); |
| 990 } | 964 } |
| 991 | 965 |
| 992 layer_tree_host()->CommitComplete(); | 966 layer_tree_host()->CommitComplete(); |
| 993 layer_tree_host()->DidBeginMainFrame(); | 967 layer_tree_host()->DidBeginMainFrame(); |
| 994 } | 968 } |
| 995 | 969 |
| 996 void ThreadProxy::StartCommitOnImplThread( | 970 void ThreadProxy::StartCommitOnImplThread(CompletionEvent* completion, |
| 997 CompletionEvent* completion, | 971 ResourceUpdateQueue* raw_queue) { |
| 998 ResourceUpdateQueue* raw_queue, | |
| 999 scoped_refptr<ContextProvider> offscreen_context_provider) { | |
| 1000 TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread"); | 972 TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread"); |
| 1001 DCHECK(!impl().commit_completion_event); | 973 DCHECK(!impl().commit_completion_event); |
| 1002 DCHECK(IsImplThread() && IsMainThreadBlocked()); | 974 DCHECK(IsImplThread() && IsMainThreadBlocked()); |
| 1003 DCHECK(impl().scheduler); | 975 DCHECK(impl().scheduler); |
| 1004 DCHECK(impl().scheduler->CommitPending()); | 976 DCHECK(impl().scheduler->CommitPending()); |
| 1005 | 977 |
| 1006 if (!impl().layer_tree_host_impl) { | 978 if (!impl().layer_tree_host_impl) { |
| 1007 TRACE_EVENT_INSTANT0( | 979 TRACE_EVENT_INSTANT0( |
| 1008 "cc", "EarlyOut_NoLayerTree", TRACE_EVENT_SCOPE_THREAD); | 980 "cc", "EarlyOut_NoLayerTree", TRACE_EVENT_SCOPE_THREAD); |
| 1009 completion->Signal(); | 981 completion->Signal(); |
| 1010 return; | 982 return; |
| 1011 } | 983 } |
| 1012 | 984 |
| 1013 // Ideally, we should inform to impl thread when BeginMainFrame is started. | 985 // Ideally, we should inform to impl thread when BeginMainFrame is started. |
| 1014 // But, we can avoid a PostTask in here. | 986 // But, we can avoid a PostTask in here. |
| 1015 impl().scheduler->NotifyBeginMainFrameStarted(); | 987 impl().scheduler->NotifyBeginMainFrameStarted(); |
| 1016 | 988 |
| 1017 scoped_ptr<ResourceUpdateQueue> queue(raw_queue); | 989 scoped_ptr<ResourceUpdateQueue> queue(raw_queue); |
| 1018 | 990 |
| 1019 if (offscreen_context_provider.get()) | |
| 1020 offscreen_context_provider->BindToCurrentThread(); | |
| 1021 impl().layer_tree_host_impl->SetOffscreenContextProvider( | |
| 1022 offscreen_context_provider); | |
| 1023 | |
| 1024 if (impl().contents_texture_manager) { | 991 if (impl().contents_texture_manager) { |
| 1025 DCHECK_EQ(impl().contents_texture_manager, | 992 DCHECK_EQ(impl().contents_texture_manager, |
| 1026 blocked_main().contents_texture_manager()); | 993 blocked_main().contents_texture_manager()); |
| 1027 } else { | 994 } else { |
| 1028 // Cache this pointer that was created on the main thread side to avoid a | 995 // Cache this pointer that was created on the main thread side to avoid a |
| 1029 // data race between creating it and using it on the compositor thread. | 996 // data race between creating it and using it on the compositor thread. |
| 1030 impl().contents_texture_manager = blocked_main().contents_texture_manager(); | 997 impl().contents_texture_manager = blocked_main().contents_texture_manager(); |
| 1031 } | 998 } |
| 1032 | 999 |
| 1033 if (impl().contents_texture_manager) { | 1000 if (impl().contents_texture_manager) { |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1445 ImplThreadTaskRunner()); | 1412 ImplThreadTaskRunner()); |
| 1446 impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible()); | 1413 impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible()); |
| 1447 | 1414 |
| 1448 impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr(); | 1415 impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr(); |
| 1449 completion->Signal(); | 1416 completion->Signal(); |
| 1450 } | 1417 } |
| 1451 | 1418 |
| 1452 void ThreadProxy::InitializeOutputSurfaceOnImplThread( | 1419 void ThreadProxy::InitializeOutputSurfaceOnImplThread( |
| 1453 CompletionEvent* completion, | 1420 CompletionEvent* completion, |
| 1454 scoped_ptr<OutputSurface> output_surface, | 1421 scoped_ptr<OutputSurface> output_surface, |
| 1455 scoped_refptr<ContextProvider> offscreen_context_provider, | |
| 1456 bool* success, | 1422 bool* success, |
| 1457 RendererCapabilities* capabilities) { | 1423 RendererCapabilities* capabilities) { |
| 1458 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread"); | 1424 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread"); |
| 1459 DCHECK(IsImplThread()); | 1425 DCHECK(IsImplThread()); |
| 1460 DCHECK(IsMainThreadBlocked()); | 1426 DCHECK(IsMainThreadBlocked()); |
| 1461 DCHECK(success); | 1427 DCHECK(success); |
| 1462 DCHECK(capabilities); | 1428 DCHECK(capabilities); |
| 1463 | 1429 |
| 1464 layer_tree_host()->DeleteContentsTexturesOnImplThread( | 1430 layer_tree_host()->DeleteContentsTexturesOnImplThread( |
| 1465 impl().layer_tree_host_impl->resource_provider()); | 1431 impl().layer_tree_host_impl->resource_provider()); |
| 1466 | 1432 |
| 1467 *success = | 1433 *success = |
| 1468 impl().layer_tree_host_impl->InitializeRenderer(output_surface.Pass()); | 1434 impl().layer_tree_host_impl->InitializeRenderer(output_surface.Pass()); |
| 1469 | 1435 |
| 1470 if (*success) { | 1436 if (*success) { |
| 1471 *capabilities = impl() | 1437 *capabilities = impl() |
| 1472 .layer_tree_host_impl->GetRendererCapabilities() | 1438 .layer_tree_host_impl->GetRendererCapabilities() |
| 1473 .MainThreadCapabilities(); | 1439 .MainThreadCapabilities(); |
| 1474 impl().scheduler->DidCreateAndInitializeOutputSurface(); | 1440 impl().scheduler->DidCreateAndInitializeOutputSurface(); |
| 1475 } else if (offscreen_context_provider.get()) { | |
| 1476 if (offscreen_context_provider->BindToCurrentThread()) | |
| 1477 offscreen_context_provider->VerifyContexts(); | |
| 1478 offscreen_context_provider = NULL; | |
| 1479 } | 1441 } |
| 1480 | 1442 |
| 1481 impl().layer_tree_host_impl->SetOffscreenContextProvider( | |
| 1482 offscreen_context_provider); | |
| 1483 | |
| 1484 completion->Signal(); | 1443 completion->Signal(); |
| 1485 } | 1444 } |
| 1486 | 1445 |
| 1487 void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) { | 1446 void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) { |
| 1488 TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread"); | 1447 TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread"); |
| 1489 DCHECK(IsImplThread()); | 1448 DCHECK(IsImplThread()); |
| 1490 if (impl().layer_tree_host_impl->resource_provider()) | 1449 if (impl().layer_tree_host_impl->resource_provider()) |
| 1491 impl().layer_tree_host_impl->resource_provider()->Finish(); | 1450 impl().layer_tree_host_impl->resource_provider()->Finish(); |
| 1492 completion->Signal(); | 1451 completion->Signal(); |
| 1493 } | 1452 } |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1696 | 1655 |
| 1697 impl().timing_history.DidActivatePendingTree(); | 1656 impl().timing_history.DidActivatePendingTree(); |
| 1698 } | 1657 } |
| 1699 | 1658 |
| 1700 void ThreadProxy::DidManageTiles() { | 1659 void ThreadProxy::DidManageTiles() { |
| 1701 DCHECK(IsImplThread()); | 1660 DCHECK(IsImplThread()); |
| 1702 impl().scheduler->DidManageTiles(); | 1661 impl().scheduler->DidManageTiles(); |
| 1703 } | 1662 } |
| 1704 | 1663 |
| 1705 } // namespace cc | 1664 } // namespace cc |
| OLD | NEW |