Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: cc/trees/thread_proxy.cc

Issue 19106007: cc: Allow the main thread to cancel commits (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix scheduler tests Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« cc/trees/single_thread_proxy.cc ('K') | « cc/trees/thread_proxy.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 completion_event_for_commit_held_on_tree_activation_(NULL), 83 completion_event_for_commit_held_on_tree_activation_(NULL),
84 texture_acquisition_completion_event_on_impl_thread_(NULL), 84 texture_acquisition_completion_event_on_impl_thread_(NULL),
85 next_frame_is_newly_committed_frame_on_impl_thread_(false), 85 next_frame_is_newly_committed_frame_on_impl_thread_(false),
86 throttle_frame_production_( 86 throttle_frame_production_(
87 layer_tree_host->settings().throttle_frame_production), 87 layer_tree_host->settings().throttle_frame_production),
88 begin_frame_scheduling_enabled_( 88 begin_frame_scheduling_enabled_(
89 layer_tree_host->settings().begin_frame_scheduling_enabled), 89 layer_tree_host->settings().begin_frame_scheduling_enabled),
90 using_synchronous_renderer_compositor_( 90 using_synchronous_renderer_compositor_(
91 layer_tree_host->settings().using_synchronous_renderer_compositor), 91 layer_tree_host->settings().using_synchronous_renderer_compositor),
92 inside_draw_(false), 92 inside_draw_(false),
93 can_cancel_commit_(false),
danakj 2013/07/17 20:53:24 true
enne (OOO) 2013/07/18 17:36:37 Done.
93 defer_commits_(false), 94 defer_commits_(false),
94 renew_tree_priority_on_impl_thread_pending_(false), 95 renew_tree_priority_on_impl_thread_pending_(false),
95 draw_duration_history_(kDurationHistorySize), 96 draw_duration_history_(kDurationHistorySize),
96 begin_frame_to_commit_duration_history_(kDurationHistorySize), 97 begin_frame_to_commit_duration_history_(kDurationHistorySize),
97 commit_to_activate_duration_history_(kDurationHistorySize) { 98 commit_to_activate_duration_history_(kDurationHistorySize) {
98 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy"); 99 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
99 DCHECK(IsMainThread()); 100 DCHECK(IsMainThread());
100 DCHECK(layer_tree_host_); 101 DCHECK(layer_tree_host_);
101 } 102 }
102 103
(...skipping 18 matching lines...) Expand all
121 { 122 {
122 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 123 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
123 CompletionEvent begin_frame_sent_to_main_thread_completion; 124 CompletionEvent begin_frame_sent_to_main_thread_completion;
124 Proxy::ImplThreadTaskRunner()->PostTask( 125 Proxy::ImplThreadTaskRunner()->PostTask(
125 FROM_HERE, 126 FROM_HERE,
126 base::Bind(&ThreadProxy::ForceCommitOnImplThread, 127 base::Bind(&ThreadProxy::ForceCommitOnImplThread,
127 impl_thread_weak_ptr_, 128 impl_thread_weak_ptr_,
128 &begin_frame_sent_to_main_thread_completion)); 129 &begin_frame_sent_to_main_thread_completion));
129 begin_frame_sent_to_main_thread_completion.Wait(); 130 begin_frame_sent_to_main_thread_completion.Wait();
130 } 131 }
132
131 in_composite_and_readback_ = true; 133 in_composite_and_readback_ = true;
132 BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>()); 134 BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>());
133 in_composite_and_readback_ = false; 135 in_composite_and_readback_ = false;
134 136
137 // Composite and readback requires a second commit to undo any changes
138 // that it made.
139 can_cancel_commit_ = false;
140
135 // Perform a synchronous readback. 141 // Perform a synchronous readback.
136 ReadbackRequest request; 142 ReadbackRequest request;
137 request.rect = rect; 143 request.rect = rect;
138 request.pixels = pixels; 144 request.pixels = pixels;
139 { 145 {
140 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 146 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
141 Proxy::ImplThreadTaskRunner()->PostTask( 147 Proxy::ImplThreadTaskRunner()->PostTask(
142 FROM_HERE, 148 FROM_HERE,
143 base::Bind(&ThreadProxy::RequestReadbackOnImplThread, 149 base::Bind(&ThreadProxy::RequestReadbackOnImplThread,
144 impl_thread_weak_ptr_, 150 impl_thread_weak_ptr_,
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 if (result == LayerTreeHost::CreateFailedButTryAgain) { 300 if (result == LayerTreeHost::CreateFailedButTryAgain) {
295 if (!output_surface_creation_callback_.callback().is_null()) { 301 if (!output_surface_creation_callback_.callback().is_null()) {
296 Proxy::MainThreadTaskRunner()->PostTask( 302 Proxy::MainThreadTaskRunner()->PostTask(
297 FROM_HERE, output_surface_creation_callback_.callback()); 303 FROM_HERE, output_surface_creation_callback_.callback());
298 } 304 }
299 } else { 305 } else {
300 output_surface_creation_callback_.Cancel(); 306 output_surface_creation_callback_.Cancel();
301 } 307 }
302 } 308 }
303 309
310 void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
311 DCHECK(IsMainThread());
312 if (commit_request_sent_to_impl_thread_)
313 return;
314 commit_request_sent_to_impl_thread_ = true;
315 Proxy::ImplThreadTaskRunner()->PostTask(
316 FROM_HERE,
317 base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
318 impl_thread_weak_ptr_));
319 }
320
304 const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const { 321 const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const {
305 DCHECK(IsMainThread()); 322 DCHECK(IsMainThread());
306 DCHECK(!layer_tree_host_->output_surface_lost()); 323 DCHECK(!layer_tree_host_->output_surface_lost());
307 return renderer_capabilities_main_thread_copy_; 324 return renderer_capabilities_main_thread_copy_;
308 } 325 }
309 326
310 void ThreadProxy::SetNeedsAnimate() { 327 void ThreadProxy::SetNeedsAnimate() {
311 DCHECK(IsMainThread()); 328 DCHECK(IsMainThread());
312 if (animate_requested_) 329 if (animate_requested_)
313 return; 330 return;
314 331
315 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate"); 332 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate");
316 animate_requested_ = true; 333 animate_requested_ = true;
334 can_cancel_commit_ = false;
335 SendCommitRequestToImplThreadIfNeeded();
336 }
317 337
318 if (commit_request_sent_to_impl_thread_) 338 void ThreadProxy::SetNeedsUpdateLayers() {
319 return; 339 DCHECK(IsMainThread());
320 commit_request_sent_to_impl_thread_ = true; 340 SendCommitRequestToImplThreadIfNeeded();
321 Proxy::ImplThreadTaskRunner()->PostTask(
322 FROM_HERE,
323 base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
324 impl_thread_weak_ptr_));
325 } 341 }
326 342
327 void ThreadProxy::SetNeedsCommit() { 343 void ThreadProxy::SetNeedsCommit() {
328 DCHECK(IsMainThread()); 344 DCHECK(IsMainThread());
345 // Unconditionally set here to handle SetNeedsCommit calls during a commit.
346 can_cancel_commit_ = false;
347
329 if (commit_requested_) 348 if (commit_requested_)
330 return; 349 return;
331 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit"); 350 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit");
332 commit_requested_ = true; 351 commit_requested_ = true;
333 352
334 if (commit_request_sent_to_impl_thread_) 353 SendCommitRequestToImplThreadIfNeeded();
335 return;
336 commit_request_sent_to_impl_thread_ = true;
337 Proxy::ImplThreadTaskRunner()->PostTask(
338 FROM_HERE,
339 base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
340 impl_thread_weak_ptr_));
341 } 354 }
342 355
343 void ThreadProxy::DidLoseOutputSurfaceOnImplThread() { 356 void ThreadProxy::DidLoseOutputSurfaceOnImplThread() {
344 DCHECK(IsImplThread()); 357 DCHECK(IsImplThread());
345 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread"); 358 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
346 Proxy::ImplThreadTaskRunner()->PostTask( 359 Proxy::ImplThreadTaskRunner()->PostTask(
347 FROM_HERE, 360 FROM_HERE,
348 base::Bind(&ThreadProxy::CheckOutputSurfaceStatusOnImplThread, 361 base::Bind(&ThreadProxy::CheckOutputSurfaceStatusOnImplThread,
349 impl_thread_weak_ptr_)); 362 impl_thread_weak_ptr_));
350 } 363 }
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 // the paint, commit_requested_ will be set to false to allow new commit 686 // the paint, commit_requested_ will be set to false to allow new commit
674 // requests to be scheduled. 687 // requests to be scheduled.
675 commit_requested_ = true; 688 commit_requested_ = true;
676 commit_request_sent_to_impl_thread_ = true; 689 commit_request_sent_to_impl_thread_ = true;
677 690
678 // On the other hand, the AnimationRequested flag needs to be cleared 691 // On the other hand, the AnimationRequested flag needs to be cleared
679 // here so that any animation requests generated by the apply or animate 692 // here so that any animation requests generated by the apply or animate
680 // callbacks will trigger another frame. 693 // callbacks will trigger another frame.
681 animate_requested_ = false; 694 animate_requested_ = false;
682 695
683 if (begin_frame_state)
684 layer_tree_host_->ApplyScrollAndScale(*begin_frame_state->scroll_info);
685
686 if (!in_composite_and_readback_ && !layer_tree_host_->visible()) { 696 if (!in_composite_and_readback_ && !layer_tree_host_->visible()) {
687 commit_requested_ = false; 697 commit_requested_ = false;
688 commit_request_sent_to_impl_thread_ = false; 698 commit_request_sent_to_impl_thread_ = false;
689 699
690 TRACE_EVENT0("cc", "EarlyOut_NotVisible"); 700 TRACE_EVENT0("cc", "EarlyOut_NotVisible");
701 bool did_handle = false;
691 Proxy::ImplThreadTaskRunner()->PostTask( 702 Proxy::ImplThreadTaskRunner()->PostTask(
692 FROM_HERE, 703 FROM_HERE,
693 base::Bind(&ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread, 704 base::Bind(&ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread,
694 impl_thread_weak_ptr_)); 705 impl_thread_weak_ptr_,
706 did_handle));
695 return; 707 return;
696 } 708 }
697 709
710 if (begin_frame_state)
711 layer_tree_host_->ApplyScrollAndScale(*begin_frame_state->scroll_info);
712
698 layer_tree_host_->WillBeginFrame(); 713 layer_tree_host_->WillBeginFrame();
699 714
700 if (begin_frame_state) { 715 if (begin_frame_state) {
701 layer_tree_host_->UpdateClientAnimations( 716 layer_tree_host_->UpdateClientAnimations(
702 begin_frame_state->monotonic_frame_begin_time); 717 begin_frame_state->monotonic_frame_begin_time);
703 layer_tree_host_->AnimateLayers( 718 layer_tree_host_->AnimateLayers(
704 begin_frame_state->monotonic_frame_begin_time); 719 begin_frame_state->monotonic_frame_begin_time);
705 } 720 }
706 721
707 // Unlink any backings that the impl thread has evicted, so that we know to 722 // Unlink any backings that the impl thread has evicted, so that we know to
708 // re-paint them in UpdateLayers. 723 // re-paint them in UpdateLayers.
709 if (layer_tree_host_->contents_texture_manager()) { 724 if (layer_tree_host_->contents_texture_manager()) {
710 layer_tree_host_->contents_texture_manager()-> 725 layer_tree_host_->contents_texture_manager()->
711 UnlinkAndClearEvictedBackings(); 726 UnlinkAndClearEvictedBackings();
712 } 727 }
713 728
714 layer_tree_host_->Layout(); 729 layer_tree_host_->Layout();
715 730
716 // Clear the commit flag after updating animations and layout here --- objects 731 // Clear the commit flag after updating animations and layout here --- objects
717 // that only layout when painted will trigger another SetNeedsCommit inside 732 // that only layout when painted will trigger another SetNeedsCommit inside
718 // UpdateLayers. 733 // UpdateLayers.
719 commit_requested_ = false; 734 commit_requested_ = false;
720 commit_request_sent_to_impl_thread_ = false; 735 commit_request_sent_to_impl_thread_ = false;
736 bool can_cancel_this_commit =
737 can_cancel_commit_ && !in_composite_and_readback_;
738 can_cancel_commit_ = true;
721 739
722 scoped_ptr<ResourceUpdateQueue> queue = 740 scoped_ptr<ResourceUpdateQueue> queue =
723 make_scoped_ptr(new ResourceUpdateQueue); 741 make_scoped_ptr(new ResourceUpdateQueue);
724 layer_tree_host_->UpdateLayers( 742 bool updated = layer_tree_host_->UpdateLayers(
725 queue.get(), 743 queue.get(),
726 begin_frame_state ? 744 begin_frame_state ? begin_frame_state->memory_allocation_limit_bytes
727 begin_frame_state->memory_allocation_limit_bytes : 0u); 745 : 0u);
728 746
729 // Once single buffered layers are committed, they cannot be modified until 747 // Once single buffered layers are committed, they cannot be modified until
730 // they are drawn by the impl thread. 748 // they are drawn by the impl thread.
731 textures_acquired_ = false; 749 textures_acquired_ = false;
732 750
733 layer_tree_host_->WillCommit(); 751 layer_tree_host_->WillCommit();
734 // Before applying scrolls and calling animate, we set animate_requested_ to 752
735 // false. If it is true now, it means SetNeedAnimate was called again, but 753 if (!updated && can_cancel_this_commit) {
736 // during a state when commit_request_sent_to_impl_thread_ = true. We need to 754 TRACE_EVENT0("cc", "EarlyOut_NoUpdates");
737 // force that call to happen again now so that the commit request is sent to 755 bool did_handle = true;
738 // the impl thread. 756 Proxy::ImplThreadTaskRunner()->PostTask(
757 FROM_HERE,
758 base::Bind(&ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread,
759 impl_thread_weak_ptr_,
760 did_handle));
761
762 // Although the commit is internally aborted, this is because it has been
763 // detected to be a no-op. From the perspective of an embedder, this commit
764 // went through, and input should no longer be throttled, etc.
765 layer_tree_host_->CommitComplete();
766 layer_tree_host_->DidBeginFrame();
767 return;
768 }
769
770 // Before calling animate, we set animate_requested_ to false. If it is true
771 // now, it means SetNeedAnimate was called again, but during a state when
772 // commit_request_sent_to_impl_thread_ = true. We need to force that call to
773 // happen again now so that the commit request is sent to the impl thread.
739 if (animate_requested_) { 774 if (animate_requested_) {
740 // Forces SetNeedsAnimate to consider posting a commit task. 775 // Forces SetNeedsAnimate to consider posting a commit task.
741 animate_requested_ = false; 776 animate_requested_ = false;
742 SetNeedsAnimate(); 777 SetNeedsAnimate();
743 } 778 }
744 779
745 scoped_refptr<cc::ContextProvider> offscreen_context_provider; 780 scoped_refptr<cc::ContextProvider> offscreen_context_provider;
746 if (renderer_capabilities_main_thread_copy_.using_offscreen_context3d && 781 if (renderer_capabilities_main_thread_copy_.using_offscreen_context3d &&
747 layer_tree_host_->needs_offscreen_context()) { 782 layer_tree_host_->needs_offscreen_context()) {
748 offscreen_context_provider = layer_tree_host_->client()-> 783 offscreen_context_provider = layer_tree_host_->client()->
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 current_resource_update_controller_on_impl_thread_ = 859 current_resource_update_controller_on_impl_thread_ =
825 ResourceUpdateController::Create( 860 ResourceUpdateController::Create(
826 this, 861 this,
827 Proxy::ImplThreadTaskRunner(), 862 Proxy::ImplThreadTaskRunner(),
828 queue.Pass(), 863 queue.Pass(),
829 layer_tree_host_impl_->resource_provider()); 864 layer_tree_host_impl_->resource_provider());
830 current_resource_update_controller_on_impl_thread_->PerformMoreUpdates( 865 current_resource_update_controller_on_impl_thread_->PerformMoreUpdates(
831 scheduler_on_impl_thread_->AnticipatedDrawTime()); 866 scheduler_on_impl_thread_->AnticipatedDrawTime());
832 } 867 }
833 868
834 void ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread() { 869 void ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread(
870 bool did_handle) {
835 TRACE_EVENT0("cc", "ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread"); 871 TRACE_EVENT0("cc", "ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread");
836 DCHECK(IsImplThread()); 872 DCHECK(IsImplThread());
837 DCHECK(scheduler_on_impl_thread_); 873 DCHECK(scheduler_on_impl_thread_);
838 DCHECK(scheduler_on_impl_thread_->CommitPending()); 874 DCHECK(scheduler_on_impl_thread_->CommitPending());
839 875
840 scheduler_on_impl_thread_->BeginFrameAbortedByMainThread(); 876 // If the begin frame data was handled, then scroll and scale set was applied
877 // by the main thread, so the active tree needs to be updated as if these sent
878 // values were applied and committed.
879 if (did_handle)
880 layer_tree_host_impl_->active_tree()->ApplySentScrollAndScaleDeltas();
881 scheduler_on_impl_thread_->BeginFrameAbortedByMainThread(did_handle);
841 } 882 }
842 883
843 void ThreadProxy::ScheduledActionCommit() { 884 void ThreadProxy::ScheduledActionCommit() {
844 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit"); 885 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit");
845 DCHECK(IsImplThread()); 886 DCHECK(IsImplThread());
846 DCHECK(commit_completion_event_on_impl_thread_); 887 DCHECK(commit_completion_event_on_impl_thread_);
847 DCHECK(current_resource_update_controller_on_impl_thread_); 888 DCHECK(current_resource_update_controller_on_impl_thread_);
848 889
849 // Complete all remaining texture updates. 890 // Complete all remaining texture updates.
850 current_resource_update_controller_on_impl_thread_->Finalize(); 891 current_resource_update_controller_on_impl_thread_->Finalize();
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 CompletionEvent completion; 1101 CompletionEvent completion;
1061 Proxy::ImplThreadTaskRunner()->PostTask( 1102 Proxy::ImplThreadTaskRunner()->PostTask(
1062 FROM_HERE, 1103 FROM_HERE,
1063 base::Bind(&ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread, 1104 base::Bind(&ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread,
1064 impl_thread_weak_ptr_, 1105 impl_thread_weak_ptr_,
1065 &completion)); 1106 &completion));
1066 // Block until it is safe to write to layer textures from the main thread. 1107 // Block until it is safe to write to layer textures from the main thread.
1067 completion.Wait(); 1108 completion.Wait();
1068 1109
1069 textures_acquired_ = true; 1110 textures_acquired_ = true;
1111 can_cancel_commit_ = false;
1070 } 1112 }
1071 1113
1072 void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread( 1114 void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread(
1073 CompletionEvent* completion) { 1115 CompletionEvent* completion) {
1074 DCHECK(IsImplThread()); 1116 DCHECK(IsImplThread());
1075 DCHECK(!texture_acquisition_completion_event_on_impl_thread_); 1117 DCHECK(!texture_acquisition_completion_event_on_impl_thread_);
1076 1118
1077 texture_acquisition_completion_event_on_impl_thread_ = completion; 1119 texture_acquisition_completion_event_on_impl_thread_ = completion;
1078 scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures(); 1120 scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures();
1079 } 1121 }
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); 1502 DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1461 completion_event_for_commit_held_on_tree_activation_->Signal(); 1503 completion_event_for_commit_held_on_tree_activation_->Signal();
1462 completion_event_for_commit_held_on_tree_activation_ = NULL; 1504 completion_event_for_commit_held_on_tree_activation_ = NULL;
1463 } 1505 }
1464 1506
1465 commit_to_activate_duration_history_.InsertSample( 1507 commit_to_activate_duration_history_.InsertSample(
1466 base::TimeTicks::HighResNow() - commit_complete_time_); 1508 base::TimeTicks::HighResNow() - commit_complete_time_);
1467 } 1509 }
1468 1510
1469 } // namespace cc 1511 } // namespace cc
OLDNEW
« cc/trees/single_thread_proxy.cc ('K') | « cc/trees/thread_proxy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698