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 <string> | 7 #include <string> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 commit_requested_(false), | 70 commit_requested_(false), |
71 commit_request_sent_to_impl_thread_(false), | 71 commit_request_sent_to_impl_thread_(false), |
72 created_offscreen_context_provider_(false), | 72 created_offscreen_context_provider_(false), |
73 layer_tree_host_(layer_tree_host), | 73 layer_tree_host_(layer_tree_host), |
74 started_(false), | 74 started_(false), |
75 textures_acquired_(true), | 75 textures_acquired_(true), |
76 in_composite_and_readback_(false), | 76 in_composite_and_readback_(false), |
77 manage_tiles_pending_(false), | 77 manage_tiles_pending_(false), |
78 weak_factory_on_impl_thread_(this), | 78 weak_factory_on_impl_thread_(this), |
79 weak_factory_(this), | 79 weak_factory_(this), |
| 80 frame_did_draw_(false), |
80 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_(NULL), | 81 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_(NULL), |
81 readback_request_on_impl_thread_(NULL), | 82 readback_request_on_impl_thread_(NULL), |
82 commit_completion_event_on_impl_thread_(NULL), | 83 commit_completion_event_on_impl_thread_(NULL), |
83 completion_event_for_commit_held_on_tree_activation_(NULL), | 84 completion_event_for_commit_held_on_tree_activation_(NULL), |
84 texture_acquisition_completion_event_on_impl_thread_(NULL), | 85 texture_acquisition_completion_event_on_impl_thread_(NULL), |
85 next_frame_is_newly_committed_frame_on_impl_thread_(false), | 86 next_frame_is_newly_committed_frame_on_impl_thread_(false), |
86 throttle_frame_production_( | 87 throttle_frame_production_( |
87 layer_tree_host->settings().throttle_frame_production), | 88 layer_tree_host->settings().throttle_frame_production), |
88 begin_frame_scheduling_enabled_( | 89 begin_frame_scheduling_enabled_( |
89 layer_tree_host->settings().begin_frame_scheduling_enabled), | 90 layer_tree_host->settings().begin_frame_scheduling_enabled), |
(...skipping 22 matching lines...) Expand all Loading... |
112 TRACE_EVENT0("cc", "ThreadProxy::CompositeAndReadback"); | 113 TRACE_EVENT0("cc", "ThreadProxy::CompositeAndReadback"); |
113 DCHECK(IsMainThread()); | 114 DCHECK(IsMainThread()); |
114 DCHECK(layer_tree_host_); | 115 DCHECK(layer_tree_host_); |
115 DCHECK(!defer_commits_); | 116 DCHECK(!defer_commits_); |
116 | 117 |
117 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) { | 118 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) { |
118 TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized"); | 119 TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized"); |
119 return false; | 120 return false; |
120 } | 121 } |
121 | 122 |
122 // Perform a synchronous commit. | 123 // Perform a synchronous commit with an associated readback. |
| 124 ReadbackRequest request; |
| 125 request.rect = rect; |
| 126 request.pixels = pixels; |
123 { | 127 { |
124 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 128 DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
125 CompletionEvent begin_frame_sent_to_main_thread_completion; | 129 CompletionEvent begin_frame_sent_to_main_thread_completion; |
126 Proxy::ImplThreadTaskRunner()->PostTask( | 130 Proxy::ImplThreadTaskRunner()->PostTask( |
127 FROM_HERE, | 131 FROM_HERE, |
128 base::Bind(&ThreadProxy::ForceCommitOnImplThread, | 132 base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread, |
129 impl_thread_weak_ptr_, | 133 impl_thread_weak_ptr_, |
130 &begin_frame_sent_to_main_thread_completion)); | 134 &begin_frame_sent_to_main_thread_completion, |
| 135 &request)); |
131 begin_frame_sent_to_main_thread_completion.Wait(); | 136 begin_frame_sent_to_main_thread_completion.Wait(); |
132 } | 137 } |
133 | 138 |
134 in_composite_and_readback_ = true; | 139 in_composite_and_readback_ = true; |
| 140 // This is the forced commit. |
| 141 // Note: The Impl thread also queues a separate BeginFrameOnMainThread on the |
| 142 // main thread, which will be called after this CompositeAndReadback |
| 143 // completes, to replace the forced commit. |
135 BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>()); | 144 BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>()); |
136 in_composite_and_readback_ = false; | 145 in_composite_and_readback_ = false; |
137 | 146 |
138 // Composite and readback requires a second commit to undo any changes | 147 // Composite and readback requires a second commit to undo any changes |
139 // that it made. | 148 // that it made. |
140 can_cancel_commit_ = false; | 149 can_cancel_commit_ = false; |
141 | 150 |
142 // Perform a synchronous readback. | 151 request.completion.Wait(); |
143 ReadbackRequest request; | |
144 request.rect = rect; | |
145 request.pixels = pixels; | |
146 { | |
147 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | |
148 Proxy::ImplThreadTaskRunner()->PostTask( | |
149 FROM_HERE, | |
150 base::Bind(&ThreadProxy::RequestReadbackOnImplThread, | |
151 impl_thread_weak_ptr_, | |
152 &request)); | |
153 request.completion.Wait(); | |
154 } | |
155 return request.success; | 152 return request.success; |
156 } | 153 } |
157 | 154 |
158 void ThreadProxy::ForceCommitOnImplThread(CompletionEvent* completion) { | 155 void ThreadProxy::ForceCommitForReadbackOnImplThread( |
159 TRACE_EVENT0("cc", "ThreadProxy::ForceCommitOnImplThread"); | 156 CompletionEvent* begin_frame_sent_completion, |
| 157 ReadbackRequest* request) { |
| 158 TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread"); |
160 DCHECK(IsImplThread()); | 159 DCHECK(IsImplThread()); |
161 DCHECK(!begin_frame_sent_to_main_thread_completion_event_on_impl_thread_); | 160 DCHECK(!begin_frame_sent_to_main_thread_completion_event_on_impl_thread_); |
| 161 DCHECK(!readback_request_on_impl_thread_); |
162 | 162 |
163 scheduler_on_impl_thread_->SetNeedsForcedCommit(); | |
164 if (scheduler_on_impl_thread_->CommitPending()) { | |
165 completion->Signal(); | |
166 return; | |
167 } | |
168 | |
169 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ = completion; | |
170 } | |
171 | |
172 void ThreadProxy::RequestReadbackOnImplThread(ReadbackRequest* request) { | |
173 DCHECK(Proxy::IsImplThread()); | |
174 DCHECK(!readback_request_on_impl_thread_); | |
175 if (!layer_tree_host_impl_) { | 163 if (!layer_tree_host_impl_) { |
| 164 begin_frame_sent_completion->Signal(); |
176 request->success = false; | 165 request->success = false; |
177 request->completion.Signal(); | 166 request->completion.Signal(); |
178 return; | 167 return; |
179 } | 168 } |
180 | 169 |
181 readback_request_on_impl_thread_ = request; | 170 readback_request_on_impl_thread_ = request; |
182 scheduler_on_impl_thread_->SetNeedsRedraw(); | 171 |
183 scheduler_on_impl_thread_->SetNeedsForcedRedraw(); | 172 scheduler_on_impl_thread_->SetNeedsForcedCommitForReadback(); |
| 173 if (scheduler_on_impl_thread_->CommitPending()) { |
| 174 begin_frame_sent_completion->Signal(); |
| 175 return; |
| 176 } |
| 177 |
| 178 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ = |
| 179 begin_frame_sent_completion; |
184 } | 180 } |
185 | 181 |
186 void ThreadProxy::FinishAllRendering() { | 182 void ThreadProxy::FinishAllRendering() { |
187 DCHECK(Proxy::IsMainThread()); | 183 DCHECK(Proxy::IsMainThread()); |
188 DCHECK(!defer_commits_); | 184 DCHECK(!defer_commits_); |
189 | 185 |
190 // Make sure all GL drawing is finished on the impl thread. | 186 // Make sure all GL drawing is finished on the impl thread. |
191 DebugScopedSetMainThreadBlocked main_thread_blocked(this); | 187 DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
192 CompletionEvent completion; | 188 CompletionEvent completion; |
193 Proxy::ImplThreadTaskRunner()->PostTask( | 189 Proxy::ImplThreadTaskRunner()->PostTask( |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 Proxy::MainThreadTaskRunner()->PostTask( | 378 Proxy::MainThreadTaskRunner()->PostTask( |
383 FROM_HERE, | 379 FROM_HERE, |
384 base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_)); | 380 base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_)); |
385 } | 381 } |
386 | 382 |
387 void ThreadProxy::SetNeedsBeginFrameOnImplThread(bool enable) { | 383 void ThreadProxy::SetNeedsBeginFrameOnImplThread(bool enable) { |
388 DCHECK(IsImplThread()); | 384 DCHECK(IsImplThread()); |
389 TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginFrameOnImplThread", | 385 TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginFrameOnImplThread", |
390 "enable", enable); | 386 "enable", enable); |
391 layer_tree_host_impl_->SetNeedsBeginFrame(enable); | 387 layer_tree_host_impl_->SetNeedsBeginFrame(enable); |
| 388 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(!enable); |
392 } | 389 } |
393 | 390 |
394 void ThreadProxy::BeginFrameOnImplThread(const BeginFrameArgs& args) { | 391 void ThreadProxy::BeginFrameOnImplThread(const BeginFrameArgs& args) { |
395 DCHECK(IsImplThread()); | 392 DCHECK(IsImplThread()); |
396 TRACE_EVENT0("cc", "ThreadProxy::BeginFrameOnImplThread"); | 393 TRACE_EVENT0("cc", "ThreadProxy::BeginFrameOnImplThread"); |
| 394 |
| 395 base::TimeTicks monotonic_time = |
| 396 layer_tree_host_impl_->CurrentFrameTimeTicks(); |
| 397 base::Time wall_clock_time = layer_tree_host_impl_->CurrentFrameTime(); |
| 398 layer_tree_host_impl_->Animate(monotonic_time, wall_clock_time); |
| 399 |
| 400 // Reinitialize for the current frame. |
| 401 frame_did_draw_ = false; |
| 402 |
397 scheduler_on_impl_thread_->BeginFrame(args); | 403 scheduler_on_impl_thread_->BeginFrame(args); |
398 } | 404 } |
399 | 405 |
| 406 void ThreadProxy::DidBeginFrameDeadlineOnImplThread() { |
| 407 // Do not start animations if we skip drawing the frame to avoid |
| 408 // checkerboarding. |
| 409 layer_tree_host_impl_->UpdateAnimationState( |
| 410 frame_did_draw_ || !layer_tree_host_impl_->CanDraw()); |
| 411 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); |
| 412 } |
| 413 |
400 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) { | 414 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) { |
401 DCHECK(IsImplThread()); | 415 DCHECK(IsImplThread()); |
402 TRACE_EVENT1( | 416 TRACE_EVENT1( |
403 "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); | 417 "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); |
404 scheduler_on_impl_thread_->SetCanDraw(can_draw); | 418 scheduler_on_impl_thread_->SetCanDraw(can_draw); |
405 layer_tree_host_impl_->UpdateBackgroundAnimateTicking( | 419 layer_tree_host_impl_->UpdateBackgroundAnimateTicking( |
406 !scheduler_on_impl_thread_->WillDrawIfNeeded()); | 420 !scheduler_on_impl_thread_->WillDrawIfNeeded()); |
407 } | 421 } |
408 | 422 |
| 423 void ThreadProxy::NotifyReadyToActivate() { |
| 424 TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate"); |
| 425 scheduler_on_impl_thread_->NotifyReadyToActivate(); |
| 426 } |
| 427 |
409 void ThreadProxy::OnHasPendingTreeStateChanged(bool has_pending_tree) { | 428 void ThreadProxy::OnHasPendingTreeStateChanged(bool has_pending_tree) { |
410 DCHECK(IsImplThread()); | 429 DCHECK(IsImplThread()); |
411 TRACE_EVENT1("cc", "ThreadProxy::OnHasPendingTreeStateChanged", | 430 TRACE_EVENT1("cc", "ThreadProxy::OnHasPendingTreeStateChanged", |
412 "has_pending_tree", has_pending_tree); | 431 "has_pending_tree", has_pending_tree); |
413 scheduler_on_impl_thread_->SetHasPendingTree(has_pending_tree); | 432 scheduler_on_impl_thread_->SetHasTrees( |
| 433 has_pending_tree, |
| 434 layer_tree_host_impl_->active_tree() ? |
| 435 !layer_tree_host_impl_->active_tree()->root_layer() : true); |
414 } | 436 } |
415 | 437 |
416 void ThreadProxy::SetNeedsCommitOnImplThread() { | 438 void ThreadProxy::SetNeedsCommitOnImplThread() { |
417 DCHECK(IsImplThread()); | 439 DCHECK(IsImplThread()); |
418 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommitOnImplThread"); | 440 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommitOnImplThread"); |
419 scheduler_on_impl_thread_->SetNeedsCommit(); | 441 scheduler_on_impl_thread_->SetNeedsCommit(); |
420 } | 442 } |
421 | 443 |
422 void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread( | 444 void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread( |
423 scoped_ptr<AnimationEventsVector> events, | 445 scoped_ptr<AnimationEventsVector> events, |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 TRACE_EVENT0("cc", "ThreadProxy::FinishAllRenderingOnImplThread"); | 679 TRACE_EVENT0("cc", "ThreadProxy::FinishAllRenderingOnImplThread"); |
658 DCHECK(IsImplThread()); | 680 DCHECK(IsImplThread()); |
659 layer_tree_host_impl_->FinishAllRendering(); | 681 layer_tree_host_impl_->FinishAllRendering(); |
660 completion->Signal(); | 682 completion->Signal(); |
661 } | 683 } |
662 | 684 |
663 void ThreadProxy::ScheduledActionSendBeginFrameToMainThread() { | 685 void ThreadProxy::ScheduledActionSendBeginFrameToMainThread() { |
664 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionSendBeginFrameToMainThread"); | 686 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionSendBeginFrameToMainThread"); |
665 scoped_ptr<BeginFrameAndCommitState> begin_frame_state( | 687 scoped_ptr<BeginFrameAndCommitState> begin_frame_state( |
666 new BeginFrameAndCommitState); | 688 new BeginFrameAndCommitState); |
| 689 |
667 begin_frame_state->monotonic_frame_begin_time = | 690 begin_frame_state->monotonic_frame_begin_time = |
668 layer_tree_host_impl_->CurrentPhysicalTimeTicks(); | 691 layer_tree_host_impl_->CurrentPhysicalTimeTicks(); |
669 begin_frame_state->scroll_info = | 692 begin_frame_state->scroll_info = |
670 layer_tree_host_impl_->ProcessScrollDeltas(); | 693 layer_tree_host_impl_->ProcessScrollDeltas(); |
671 | 694 |
672 if (!layer_tree_host_impl_->settings().impl_side_painting) { | 695 if (!layer_tree_host_impl_->settings().impl_side_painting) { |
673 DCHECK_GT(layer_tree_host_impl_->memory_allocation_limit_bytes(), 0u); | 696 DCHECK_GT(layer_tree_host_impl_->memory_allocation_limit_bytes(), 0u); |
674 } | 697 } |
| 698 |
| 699 |
675 begin_frame_state->memory_allocation_limit_bytes = | 700 begin_frame_state->memory_allocation_limit_bytes = |
676 layer_tree_host_impl_->memory_allocation_limit_bytes(); | 701 layer_tree_host_impl_->memory_allocation_limit_bytes(); |
677 Proxy::MainThreadTaskRunner()->PostTask( | 702 Proxy::MainThreadTaskRunner()->PostTask( |
678 FROM_HERE, | 703 FROM_HERE, |
679 base::Bind(&ThreadProxy::BeginFrameOnMainThread, | 704 base::Bind(&ThreadProxy::BeginFrameOnMainThread, |
680 main_thread_weak_ptr_, | 705 main_thread_weak_ptr_, |
681 base::Passed(&begin_frame_state))); | 706 base::Passed(&begin_frame_state))); |
682 | 707 |
683 if (begin_frame_sent_to_main_thread_completion_event_on_impl_thread_) { | 708 if (begin_frame_sent_to_main_thread_completion_event_on_impl_thread_) { |
684 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_->Signal(); | 709 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_->Signal(); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 } | 860 } |
836 | 861 |
837 layer_tree_host_->CommitComplete(); | 862 layer_tree_host_->CommitComplete(); |
838 layer_tree_host_->DidBeginFrame(); | 863 layer_tree_host_->DidBeginFrame(); |
839 } | 864 } |
840 | 865 |
841 void ThreadProxy::StartCommitOnImplThread( | 866 void ThreadProxy::StartCommitOnImplThread( |
842 CompletionEvent* completion, | 867 CompletionEvent* completion, |
843 ResourceUpdateQueue* raw_queue, | 868 ResourceUpdateQueue* raw_queue, |
844 scoped_refptr<cc::ContextProvider> offscreen_context_provider) { | 869 scoped_refptr<cc::ContextProvider> offscreen_context_provider) { |
845 scoped_ptr<ResourceUpdateQueue> queue(raw_queue); | |
846 | |
847 TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread"); | 870 TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread"); |
848 DCHECK(!commit_completion_event_on_impl_thread_); | 871 DCHECK(!commit_completion_event_on_impl_thread_); |
849 DCHECK(IsImplThread() && IsMainThreadBlocked()); | 872 DCHECK(IsImplThread() && IsMainThreadBlocked()); |
850 DCHECK(scheduler_on_impl_thread_); | 873 DCHECK(scheduler_on_impl_thread_); |
851 DCHECK(scheduler_on_impl_thread_->CommitPending()); | 874 DCHECK(scheduler_on_impl_thread_->CommitPending()); |
852 | 875 |
853 if (!layer_tree_host_impl_) { | 876 if (!layer_tree_host_impl_) { |
854 TRACE_EVENT0("cc", "EarlyOut_NoLayerTree"); | 877 TRACE_EVENT0("cc", "EarlyOut_NoLayerTree"); |
855 completion->Signal(); | 878 completion->Signal(); |
| 879 |
856 return; | 880 return; |
857 } | 881 } |
858 | 882 |
| 883 scoped_ptr<ResourceUpdateQueue> queue(raw_queue); |
| 884 |
859 if (offscreen_context_provider.get()) | 885 if (offscreen_context_provider.get()) |
860 offscreen_context_provider->BindToCurrentThread(); | 886 offscreen_context_provider->BindToCurrentThread(); |
861 layer_tree_host_impl_->resource_provider()-> | 887 layer_tree_host_impl_->resource_provider()-> |
862 set_offscreen_context_provider(offscreen_context_provider); | 888 set_offscreen_context_provider(offscreen_context_provider); |
863 | 889 |
864 if (layer_tree_host_->contents_texture_manager()) { | 890 if (layer_tree_host_->contents_texture_manager()) { |
865 if (layer_tree_host_->contents_texture_manager()-> | 891 if (layer_tree_host_->contents_texture_manager()-> |
866 LinkedEvictedBackingsExist()) { | 892 LinkedEvictedBackingsExist()) { |
867 // Clear any uploads we were making to textures linked to evicted | 893 // Clear any uploads we were making to textures linked to evicted |
868 // resources | 894 // resources |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 current_resource_update_controller_on_impl_thread_->Finalize(); | 941 current_resource_update_controller_on_impl_thread_->Finalize(); |
916 current_resource_update_controller_on_impl_thread_.reset(); | 942 current_resource_update_controller_on_impl_thread_.reset(); |
917 | 943 |
918 layer_tree_host_impl_->BeginCommit(); | 944 layer_tree_host_impl_->BeginCommit(); |
919 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get()); | 945 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get()); |
920 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get()); | 946 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get()); |
921 layer_tree_host_impl_->CommitComplete(); | 947 layer_tree_host_impl_->CommitComplete(); |
922 | 948 |
923 SetInputThrottledUntilCommitOnImplThread(false); | 949 SetInputThrottledUntilCommitOnImplThread(false); |
924 | 950 |
925 layer_tree_host_impl_->UpdateBackgroundAnimateTicking( | |
926 !scheduler_on_impl_thread_->WillDrawIfNeeded()); | |
927 | |
928 next_frame_is_newly_committed_frame_on_impl_thread_ = true; | 951 next_frame_is_newly_committed_frame_on_impl_thread_ = true; |
929 | 952 |
930 if (layer_tree_host_->settings().impl_side_painting && | 953 if (layer_tree_host_->settings().impl_side_painting && |
931 layer_tree_host_->BlocksPendingCommit() && | 954 layer_tree_host_->BlocksPendingCommit() && |
932 layer_tree_host_impl_->pending_tree()) { | 955 layer_tree_host_impl_->pending_tree()) { |
933 // For some layer types in impl-side painting, the commit is held until | 956 // For some layer types in impl-side painting, the commit is held until |
934 // the pending tree is activated. It's also possible that the | 957 // the pending tree is activated. It's also possible that the |
935 // pending tree has already activated if there was no work to be done. | 958 // pending tree has already activated if there was no work to be done. |
936 TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD); | 959 TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD); |
937 completion_event_for_commit_held_on_tree_activation_ = | 960 completion_event_for_commit_held_on_tree_activation_ = |
938 commit_completion_event_on_impl_thread_; | 961 commit_completion_event_on_impl_thread_; |
939 commit_completion_event_on_impl_thread_ = NULL; | 962 commit_completion_event_on_impl_thread_ = NULL; |
940 } else { | 963 } else { |
941 commit_completion_event_on_impl_thread_->Signal(); | 964 commit_completion_event_on_impl_thread_->Signal(); |
942 commit_completion_event_on_impl_thread_ = NULL; | 965 commit_completion_event_on_impl_thread_ = NULL; |
943 } | 966 } |
944 | 967 |
945 commit_complete_time_ = base::TimeTicks::HighResNow(); | 968 commit_complete_time_ = base::TimeTicks::HighResNow(); |
946 begin_frame_to_commit_duration_history_.InsertSample( | 969 begin_frame_to_commit_duration_history_.InsertSample( |
947 commit_complete_time_ - begin_frame_sent_to_main_thread_time_); | 970 commit_complete_time_ - begin_frame_sent_to_main_thread_time_); |
948 | 971 |
| 972 // The commit may have added animations, requiring us to start |
| 973 // background ticking. |
| 974 layer_tree_host_impl_->UpdateBackgroundAnimateTicking( |
| 975 !scheduler_on_impl_thread_->WillDrawIfNeeded()); |
949 // SetVisible kicks off the next scheduler action, so this must be last. | 976 // SetVisible kicks off the next scheduler action, so this must be last. |
950 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); | 977 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); |
951 } | 978 } |
952 | 979 |
953 void ThreadProxy::ScheduledActionUpdateVisibleTiles() { | 980 void ThreadProxy::ScheduledActionUpdateVisibleTiles() { |
954 DCHECK(IsImplThread()); | 981 DCHECK(IsImplThread()); |
955 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles"); | 982 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles"); |
956 layer_tree_host_impl_->UpdateVisibleTiles(); | 983 layer_tree_host_impl_->UpdateVisibleTiles(); |
957 } | 984 } |
958 | 985 |
959 void ThreadProxy::ScheduledActionActivatePendingTreeIfNeeded() { | 986 void ThreadProxy::ScheduledActionActivatePendingTree() { |
960 DCHECK(IsImplThread()); | 987 DCHECK(IsImplThread()); |
961 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTreeIfNeeded"); | 988 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTree"); |
962 layer_tree_host_impl_->ActivatePendingTreeIfNeeded(); | 989 layer_tree_host_impl_->ActivatePendingTree(); |
963 } | 990 } |
964 | 991 |
965 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { | 992 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { |
966 DCHECK(IsImplThread()); | 993 DCHECK(IsImplThread()); |
967 Proxy::MainThreadTaskRunner()->PostTask( | 994 Proxy::MainThreadTaskRunner()->PostTask( |
968 FROM_HERE, | 995 FROM_HERE, |
969 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, | 996 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, |
970 main_thread_weak_ptr_)); | 997 main_thread_weak_ptr_)); |
971 } | 998 } |
972 | 999 |
973 ScheduledActionDrawAndSwapResult | 1000 DrawSwapReadbackResult |
974 ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) { | 1001 ThreadProxy::ScheduledActionDrawSwapReadbackInternal( |
975 TRACE_EVENT1( | 1002 bool forced_draw, bool swap_requested, bool readback_requested) { |
976 "cc", "ThreadProxy::ScheduledActionDrawAndSwap", "forced", forced_draw); | 1003 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawSwapReadback"); |
977 | 1004 |
978 ScheduledActionDrawAndSwapResult result; | 1005 DrawSwapReadbackResult result; |
979 result.did_draw = false; | 1006 result.did_draw = false; |
980 result.did_swap = false; | 1007 result.did_swap = false; |
981 DCHECK(IsImplThread()); | 1008 DCHECK(IsImplThread()); |
982 DCHECK(layer_tree_host_impl_.get()); | 1009 DCHECK(layer_tree_host_impl_.get()); |
983 if (!layer_tree_host_impl_) | 1010 if (!layer_tree_host_impl_) |
984 return result; | 1011 return result; |
985 | 1012 |
986 DCHECK(layer_tree_host_impl_->renderer()); | 1013 DCHECK(layer_tree_host_impl_->renderer()); |
987 if (!layer_tree_host_impl_->renderer()) | 1014 if (!layer_tree_host_impl_->renderer()) |
988 return result; | 1015 return result; |
989 | 1016 |
990 base::TimeTicks monotonic_time = | |
991 layer_tree_host_impl_->CurrentFrameTimeTicks(); | |
992 base::Time wall_clock_time = layer_tree_host_impl_->CurrentFrameTime(); | |
993 | |
994 // TODO(enne): This should probably happen post-animate. | |
995 if (layer_tree_host_impl_->pending_tree()) { | |
996 layer_tree_host_impl_->ActivatePendingTreeIfNeeded(); | |
997 if (layer_tree_host_impl_->pending_tree()) | |
998 layer_tree_host_impl_->pending_tree()->UpdateDrawProperties(); | |
999 } | |
1000 layer_tree_host_impl_->Animate(monotonic_time, wall_clock_time); | |
1001 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(false); | |
1002 | |
1003 base::TimeTicks start_time = base::TimeTicks::HighResNow(); | 1017 base::TimeTicks start_time = base::TimeTicks::HighResNow(); |
1004 base::TimeDelta draw_duration_estimate = DrawDurationEstimate(); | 1018 base::TimeDelta draw_duration_estimate = DrawDurationEstimate(); |
1005 base::AutoReset<bool> mark_inside(&inside_draw_, true); | 1019 base::AutoReset<bool> mark_inside(&inside_draw_, true); |
1006 | 1020 |
1007 // This method is called on a forced draw, regardless of whether we are able | 1021 // This method is called on a forced draw, regardless of whether we are able |
1008 // to produce a frame, as the calling site on main thread is blocked until its | 1022 // to produce a frame, as the calling site on main thread is blocked until its |
1009 // request completes, and we signal completion here. If CanDraw() is false, we | 1023 // request completes, and we signal completion here. If CanDraw() is false, we |
1010 // will indicate success=false to the caller, but we must still signal | 1024 // will indicate success=false to the caller, but we must still signal |
1011 // completion to avoid deadlock. | 1025 // completion to avoid deadlock. |
1012 | 1026 |
1013 // We guard PrepareToDraw() with CanDraw() because it always returns a valid | 1027 // We guard PrepareToDraw() with CanDraw() because it always returns a valid |
1014 // frame, so can only be used when such a frame is possible. Since | 1028 // frame, so can only be used when such a frame is possible. Since |
1015 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on | 1029 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on |
1016 // CanDraw() as well. | 1030 // CanDraw() as well. |
1017 | 1031 |
1018 bool drawing_for_readback = !!readback_request_on_impl_thread_; | 1032 bool drawing_for_readback = |
| 1033 readback_requested && !!readback_request_on_impl_thread_; |
1019 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels(); | 1034 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels(); |
1020 | 1035 |
1021 LayerTreeHostImpl::FrameData frame; | 1036 LayerTreeHostImpl::FrameData frame; |
1022 bool draw_frame = false; | 1037 bool draw_frame = false; |
1023 bool start_ready_animations = true; | |
1024 | 1038 |
1025 if (layer_tree_host_impl_->CanDraw() && | 1039 if (layer_tree_host_impl_->CanDraw() && |
1026 (!drawing_for_readback || can_do_readback)) { | 1040 (!drawing_for_readback || can_do_readback)) { |
1027 // If it is for a readback, make sure we draw the portion being read back. | 1041 // If it is for a readback, make sure we draw the portion being read back. |
1028 gfx::Rect readback_rect; | 1042 gfx::Rect readback_rect; |
1029 if (drawing_for_readback) | 1043 if (drawing_for_readback) |
1030 readback_rect = readback_request_on_impl_thread_->rect; | 1044 readback_rect = readback_request_on_impl_thread_->rect; |
1031 | 1045 |
1032 // Do not start animations if we skip drawing the frame to avoid | |
1033 // checkerboarding. | |
1034 if (layer_tree_host_impl_->PrepareToDraw(&frame, readback_rect) || | 1046 if (layer_tree_host_impl_->PrepareToDraw(&frame, readback_rect) || |
1035 forced_draw) | 1047 forced_draw) |
1036 draw_frame = true; | 1048 draw_frame = true; |
1037 else | |
1038 start_ready_animations = false; | |
1039 } | 1049 } |
1040 | 1050 |
| 1051 frame_did_draw_ = draw_frame; |
| 1052 |
1041 if (draw_frame) { | 1053 if (draw_frame) { |
1042 layer_tree_host_impl_->DrawLayers( | 1054 layer_tree_host_impl_->DrawLayers( |
1043 &frame, | 1055 &frame, |
1044 scheduler_on_impl_thread_->LastBeginFrameOnImplThreadTime()); | 1056 scheduler_on_impl_thread_->LastBeginFrameOnImplThreadTime()); |
1045 result.did_draw = true; | 1057 result.did_draw = true; |
1046 } | 1058 } |
1047 layer_tree_host_impl_->DidDrawAllLayers(frame); | 1059 layer_tree_host_impl_->DidDrawAllLayers(frame); |
1048 | 1060 |
1049 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); | |
1050 | |
1051 // Check for a pending CompositeAndReadback. | 1061 // Check for a pending CompositeAndReadback. |
1052 if (readback_request_on_impl_thread_) { | 1062 if (drawing_for_readback) { |
1053 readback_request_on_impl_thread_->success = false; | 1063 result.did_readback = false; |
1054 if (draw_frame) { | 1064 if (draw_frame) { |
1055 layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels, | 1065 layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels, |
1056 readback_request_on_impl_thread_->rect); | 1066 readback_request_on_impl_thread_->rect); |
1057 readback_request_on_impl_thread_->success = | 1067 result.did_readback = |
1058 !layer_tree_host_impl_->IsContextLost(); | 1068 !layer_tree_host_impl_->IsContextLost(); |
1059 } | 1069 } |
| 1070 readback_request_on_impl_thread_->success = result.did_readback; |
1060 readback_request_on_impl_thread_->completion.Signal(); | 1071 readback_request_on_impl_thread_->completion.Signal(); |
1061 readback_request_on_impl_thread_ = NULL; | 1072 readback_request_on_impl_thread_ = NULL; |
1062 } else if (draw_frame) { | 1073 } else if (draw_frame && swap_requested) { |
1063 result.did_swap = layer_tree_host_impl_->SwapBuffers(frame); | 1074 result.did_swap = layer_tree_host_impl_->SwapBuffers(frame); |
1064 | 1075 |
1065 if (frame.contains_incomplete_tile) | 1076 if (frame.contains_incomplete_tile) |
1066 DidSwapUseIncompleteTileOnImplThread(); | 1077 DidSwapUseIncompleteTileOnImplThread(); |
1067 } | 1078 } |
1068 | 1079 |
1069 // Tell the main thread that the the newly-commited frame was drawn. | 1080 // Tell the main thread that the the newly-commited frame was drawn. |
1070 if (next_frame_is_newly_committed_frame_on_impl_thread_) { | 1081 if (next_frame_is_newly_committed_frame_on_impl_thread_) { |
1071 next_frame_is_newly_committed_frame_on_impl_thread_ = false; | 1082 next_frame_is_newly_committed_frame_on_impl_thread_ = false; |
1072 Proxy::MainThreadTaskRunner()->PostTask( | 1083 Proxy::MainThreadTaskRunner()->PostTask( |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1145 texture_acquisition_completion_event_on_impl_thread_ = completion; | 1156 texture_acquisition_completion_event_on_impl_thread_ = completion; |
1146 scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures(); | 1157 scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures(); |
1147 } | 1158 } |
1148 | 1159 |
1149 void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() { | 1160 void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() { |
1150 DCHECK(texture_acquisition_completion_event_on_impl_thread_); | 1161 DCHECK(texture_acquisition_completion_event_on_impl_thread_); |
1151 texture_acquisition_completion_event_on_impl_thread_->Signal(); | 1162 texture_acquisition_completion_event_on_impl_thread_->Signal(); |
1152 texture_acquisition_completion_event_on_impl_thread_ = NULL; | 1163 texture_acquisition_completion_event_on_impl_thread_ = NULL; |
1153 } | 1164 } |
1154 | 1165 |
1155 ScheduledActionDrawAndSwapResult | 1166 DrawSwapReadbackResult |
1156 ThreadProxy::ScheduledActionDrawAndSwapIfPossible() { | 1167 ThreadProxy::ScheduledActionDrawAndSwapIfPossible() { |
1157 return ScheduledActionDrawAndSwapInternal(false); | 1168 bool forced_draw = false; |
| 1169 bool swap_requested = true; |
| 1170 bool readback_requested = false; |
| 1171 return ScheduledActionDrawSwapReadbackInternal( |
| 1172 forced_draw, swap_requested, readback_requested); |
1158 } | 1173 } |
1159 | 1174 |
1160 ScheduledActionDrawAndSwapResult | 1175 DrawSwapReadbackResult |
1161 ThreadProxy::ScheduledActionDrawAndSwapForced() { | 1176 ThreadProxy::ScheduledActionDrawAndSwapForced() { |
1162 return ScheduledActionDrawAndSwapInternal(true); | 1177 bool forced_draw = true; |
| 1178 bool swap_requested = true; |
| 1179 bool readback_requested = false; |
| 1180 return ScheduledActionDrawSwapReadbackInternal( |
| 1181 forced_draw, swap_requested, readback_requested); |
1163 } | 1182 } |
1164 | 1183 |
| 1184 DrawSwapReadbackResult |
| 1185 ThreadProxy::ScheduledActionDrawAndReadback() { |
| 1186 bool forced_draw = true; |
| 1187 bool swap_requested = false; |
| 1188 bool readback_requested = true; |
| 1189 return ScheduledActionDrawSwapReadbackInternal( |
| 1190 forced_draw, swap_requested, readback_requested); |
| 1191 } |
| 1192 |
| 1193 |
1165 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { | 1194 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { |
1166 if (current_resource_update_controller_on_impl_thread_) | 1195 if (current_resource_update_controller_on_impl_thread_) |
1167 current_resource_update_controller_on_impl_thread_ | 1196 current_resource_update_controller_on_impl_thread_ |
1168 ->PerformMoreUpdates(time); | 1197 ->PerformMoreUpdates(time); |
1169 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); | |
1170 } | 1198 } |
1171 | 1199 |
1172 base::TimeDelta ThreadProxy::DrawDurationEstimate() { | 1200 base::TimeDelta ThreadProxy::DrawDurationEstimate() { |
1173 base::TimeDelta historical_estimate = | 1201 base::TimeDelta historical_estimate = |
1174 draw_duration_history_.Percentile(kDrawDurationEstimationPercentile); | 1202 draw_duration_history_.Percentile(kDrawDurationEstimationPercentile); |
1175 base::TimeDelta padding = base::TimeDelta::FromMicroseconds( | 1203 base::TimeDelta padding = base::TimeDelta::FromMicroseconds( |
1176 kDrawDurationEstimatePaddingInMicroseconds); | 1204 kDrawDurationEstimatePaddingInMicroseconds); |
1177 return historical_estimate + padding; | 1205 return historical_estimate + padding; |
1178 } | 1206 } |
1179 | 1207 |
1180 base::TimeDelta ThreadProxy::BeginFrameToCommitDurationEstimate() { | 1208 base::TimeDelta ThreadProxy::BeginFrameToCommitDurationEstimate() { |
1181 return begin_frame_to_commit_duration_history_.Percentile( | 1209 return begin_frame_to_commit_duration_history_.Percentile( |
1182 kCommitAndActivationDurationEstimationPercentile); | 1210 kCommitAndActivationDurationEstimationPercentile); |
1183 } | 1211 } |
1184 | 1212 |
1185 base::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() { | 1213 base::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() { |
1186 return commit_to_activate_duration_history_.Percentile( | 1214 return commit_to_activate_duration_history_.Percentile( |
1187 kCommitAndActivationDurationEstimationPercentile); | 1215 kCommitAndActivationDurationEstimationPercentile); |
1188 } | 1216 } |
1189 | 1217 |
| 1218 void ThreadProxy::PostBeginFrameDeadline(const base::Closure &closure, |
| 1219 base::TimeTicks deadline) { |
| 1220 base::TimeDelta delta = deadline - base::TimeTicks::Now(); |
| 1221 if (delta <= base::TimeDelta()) |
| 1222 delta = base::TimeDelta(); |
| 1223 Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta); |
| 1224 } |
| 1225 |
1190 void ThreadProxy::ReadyToFinalizeTextureUpdates() { | 1226 void ThreadProxy::ReadyToFinalizeTextureUpdates() { |
1191 DCHECK(IsImplThread()); | 1227 DCHECK(IsImplThread()); |
1192 scheduler_on_impl_thread_->FinishCommit(); | 1228 scheduler_on_impl_thread_->FinishCommit(); |
1193 } | 1229 } |
1194 | 1230 |
1195 void ThreadProxy::DidCommitAndDrawFrame() { | 1231 void ThreadProxy::DidCommitAndDrawFrame() { |
1196 DCHECK(IsMainThread()); | 1232 DCHECK(IsMainThread()); |
1197 if (!layer_tree_host_) | 1233 if (!layer_tree_host_) |
1198 return; | 1234 return; |
1199 layer_tree_host_->DidCommitAndDrawFrame(); | 1235 layer_tree_host_->DidCommitAndDrawFrame(); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); | 1293 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); |
1258 const LayerTreeSettings& settings = layer_tree_host_->settings(); | 1294 const LayerTreeSettings& settings = layer_tree_host_->settings(); |
1259 SchedulerSettings scheduler_settings; | 1295 SchedulerSettings scheduler_settings; |
1260 scheduler_settings.impl_side_painting = settings.impl_side_painting; | 1296 scheduler_settings.impl_side_painting = settings.impl_side_painting; |
1261 scheduler_settings.timeout_and_draw_when_animation_checkerboards = | 1297 scheduler_settings.timeout_and_draw_when_animation_checkerboards = |
1262 settings.timeout_and_draw_when_animation_checkerboards; | 1298 settings.timeout_and_draw_when_animation_checkerboards; |
1263 scheduler_settings.using_synchronous_renderer_compositor = | 1299 scheduler_settings.using_synchronous_renderer_compositor = |
1264 settings.using_synchronous_renderer_compositor; | 1300 settings.using_synchronous_renderer_compositor; |
1265 scheduler_settings.throttle_frame_production = | 1301 scheduler_settings.throttle_frame_production = |
1266 settings.throttle_frame_production; | 1302 settings.throttle_frame_production; |
| 1303 scheduler_settings.use_begin_frame_workaround_for_crbug_249806 = true; |
1267 scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings); | 1304 scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings); |
1268 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); | 1305 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); |
1269 | 1306 |
1270 impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr(); | 1307 impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr(); |
1271 completion->Signal(); | 1308 completion->Signal(); |
1272 } | 1309 } |
1273 | 1310 |
1274 void ThreadProxy::InitializeOutputSurfaceOnImplThread( | 1311 void ThreadProxy::InitializeOutputSurfaceOnImplThread( |
1275 CompletionEvent* completion, | 1312 CompletionEvent* completion, |
1276 scoped_ptr<OutputSurface> output_surface, | 1313 scoped_ptr<OutputSurface> output_surface, |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1506 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); | 1543 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); |
1507 completion_event_for_commit_held_on_tree_activation_->Signal(); | 1544 completion_event_for_commit_held_on_tree_activation_->Signal(); |
1508 completion_event_for_commit_held_on_tree_activation_ = NULL; | 1545 completion_event_for_commit_held_on_tree_activation_ = NULL; |
1509 } | 1546 } |
1510 | 1547 |
1511 commit_to_activate_duration_history_.InsertSample( | 1548 commit_to_activate_duration_history_.InsertSample( |
1512 base::TimeTicks::HighResNow() - commit_complete_time_); | 1549 base::TimeTicks::HighResNow() - commit_complete_time_); |
1513 } | 1550 } |
1514 | 1551 |
1515 } // namespace cc | 1552 } // namespace cc |
OLD | NEW |