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

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: 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
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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 completion_event_for_commit_held_on_tree_activation_(NULL), 82 completion_event_for_commit_held_on_tree_activation_(NULL),
83 texture_acquisition_completion_event_on_impl_thread_(NULL), 83 texture_acquisition_completion_event_on_impl_thread_(NULL),
84 next_frame_is_newly_committed_frame_on_impl_thread_(false), 84 next_frame_is_newly_committed_frame_on_impl_thread_(false),
85 throttle_frame_production_( 85 throttle_frame_production_(
86 layer_tree_host->settings().throttle_frame_production), 86 layer_tree_host->settings().throttle_frame_production),
87 begin_frame_scheduling_enabled_( 87 begin_frame_scheduling_enabled_(
88 layer_tree_host->settings().begin_frame_scheduling_enabled), 88 layer_tree_host->settings().begin_frame_scheduling_enabled),
89 using_synchronous_renderer_compositor_( 89 using_synchronous_renderer_compositor_(
90 layer_tree_host->settings().using_synchronous_renderer_compositor), 90 layer_tree_host->settings().using_synchronous_renderer_compositor),
91 inside_draw_(false), 91 inside_draw_(false),
92 can_cancel_commit_(false),
92 defer_commits_(false), 93 defer_commits_(false),
93 renew_tree_priority_on_impl_thread_pending_(false), 94 renew_tree_priority_on_impl_thread_pending_(false),
94 draw_duration_history_(kDrawDurationHistorySize) { 95 draw_duration_history_(kDrawDurationHistorySize) {
95 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy"); 96 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
96 DCHECK(IsMainThread()); 97 DCHECK(IsMainThread());
97 DCHECK(layer_tree_host_); 98 DCHECK(layer_tree_host_);
98 } 99 }
99 100
100 ThreadProxy::~ThreadProxy() { 101 ThreadProxy::~ThreadProxy() {
101 TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy"); 102 TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy");
(...skipping 16 matching lines...) Expand all
118 { 119 {
119 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 120 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
120 CompletionEvent begin_frame_sent_to_main_thread_completion; 121 CompletionEvent begin_frame_sent_to_main_thread_completion;
121 Proxy::ImplThreadTaskRunner()->PostTask( 122 Proxy::ImplThreadTaskRunner()->PostTask(
122 FROM_HERE, 123 FROM_HERE,
123 base::Bind(&ThreadProxy::ForceCommitOnImplThread, 124 base::Bind(&ThreadProxy::ForceCommitOnImplThread,
124 impl_thread_weak_ptr_, 125 impl_thread_weak_ptr_,
125 &begin_frame_sent_to_main_thread_completion)); 126 &begin_frame_sent_to_main_thread_completion));
126 begin_frame_sent_to_main_thread_completion.Wait(); 127 begin_frame_sent_to_main_thread_completion.Wait();
127 } 128 }
129
128 in_composite_and_readback_ = true; 130 in_composite_and_readback_ = true;
129 BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>()); 131 BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>());
130 in_composite_and_readback_ = false; 132 in_composite_and_readback_ = false;
131 133
134 // Composite and readback requires a second commit to undo any changes
135 // that it made.
136 can_cancel_commit_ = false;
137
132 // Perform a synchronous readback. 138 // Perform a synchronous readback.
133 ReadbackRequest request; 139 ReadbackRequest request;
134 request.rect = rect; 140 request.rect = rect;
135 request.pixels = pixels; 141 request.pixels = pixels;
136 { 142 {
137 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 143 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
138 Proxy::ImplThreadTaskRunner()->PostTask( 144 Proxy::ImplThreadTaskRunner()->PostTask(
139 FROM_HERE, 145 FROM_HERE,
140 base::Bind(&ThreadProxy::RequestReadbackOnImplThread, 146 base::Bind(&ThreadProxy::RequestReadbackOnImplThread,
141 impl_thread_weak_ptr_, 147 impl_thread_weak_ptr_,
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 if (result == LayerTreeHost::CreateFailedButTryAgain) { 297 if (result == LayerTreeHost::CreateFailedButTryAgain) {
292 if (!output_surface_creation_callback_.callback().is_null()) { 298 if (!output_surface_creation_callback_.callback().is_null()) {
293 Proxy::MainThreadTaskRunner()->PostTask( 299 Proxy::MainThreadTaskRunner()->PostTask(
294 FROM_HERE, output_surface_creation_callback_.callback()); 300 FROM_HERE, output_surface_creation_callback_.callback());
295 } 301 }
296 } else { 302 } else {
297 output_surface_creation_callback_.Cancel(); 303 output_surface_creation_callback_.Cancel();
298 } 304 }
299 } 305 }
300 306
307 void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
brianderson 2013/07/13 01:26:42 While you are adding this method, it looks like co
enne (OOO) 2013/07/15 22:23:28 It doesn't look like one can be removed. commit_r
308 DCHECK(IsMainThread());
309 if (commit_request_sent_to_impl_thread_)
310 return;
311 commit_request_sent_to_impl_thread_ = true;
312 Proxy::ImplThreadTaskRunner()->PostTask(
313 FROM_HERE,
314 base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
315 impl_thread_weak_ptr_));
316 }
317
301 const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const { 318 const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const {
302 DCHECK(IsMainThread()); 319 DCHECK(IsMainThread());
303 DCHECK(!layer_tree_host_->output_surface_lost()); 320 DCHECK(!layer_tree_host_->output_surface_lost());
304 return renderer_capabilities_main_thread_copy_; 321 return renderer_capabilities_main_thread_copy_;
305 } 322 }
306 323
307 void ThreadProxy::SetNeedsAnimate() { 324 void ThreadProxy::SetNeedsAnimate() {
308 DCHECK(IsMainThread()); 325 DCHECK(IsMainThread());
309 if (animate_requested_) 326 if (animate_requested_)
310 return; 327 return;
311 328
312 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate"); 329 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate");
313 animate_requested_ = true; 330 animate_requested_ = true;
331 can_cancel_commit_ = false;
332 SendCommitRequestToImplThreadIfNeeded();
333 }
314 334
315 if (commit_request_sent_to_impl_thread_) 335 void ThreadProxy::SetNeedsUpdateLayers() {
316 return; 336 DCHECK(IsMainThread());
317 commit_request_sent_to_impl_thread_ = true; 337 SendCommitRequestToImplThreadIfNeeded();
318 Proxy::ImplThreadTaskRunner()->PostTask(
319 FROM_HERE,
320 base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
321 impl_thread_weak_ptr_));
322 } 338 }
323 339
324 void ThreadProxy::SetNeedsCommit() { 340 void ThreadProxy::SetNeedsCommit() {
325 DCHECK(IsMainThread()); 341 DCHECK(IsMainThread());
342 // This needs to unconditionally be set here, because the during
brianderson 2013/07/13 01:26:42 Nit: -the
enne (OOO) 2013/07/15 22:23:28 Done.
343 // begin frame commit_requested_ is set unconditionally to true
344 // to suppress extra commits, however we don't want to suppress cancels.
brianderson 2013/07/13 01:26:42 Triple negative made that last part of the comment
enne (OOO) 2013/07/15 22:23:28 Cleaned up this comment in general.
345 can_cancel_commit_ = false;
346
326 if (commit_requested_) 347 if (commit_requested_)
327 return; 348 return;
328 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit"); 349 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit");
329 commit_requested_ = true; 350 commit_requested_ = true;
330 351
331 if (commit_request_sent_to_impl_thread_) 352 SendCommitRequestToImplThreadIfNeeded();
332 return;
333 commit_request_sent_to_impl_thread_ = true;
334 Proxy::ImplThreadTaskRunner()->PostTask(
335 FROM_HERE,
336 base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
337 impl_thread_weak_ptr_));
338 } 353 }
339 354
340 void ThreadProxy::DidLoseOutputSurfaceOnImplThread() { 355 void ThreadProxy::DidLoseOutputSurfaceOnImplThread() {
341 DCHECK(IsImplThread()); 356 DCHECK(IsImplThread());
342 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread"); 357 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
343 Proxy::ImplThreadTaskRunner()->PostTask( 358 Proxy::ImplThreadTaskRunner()->PostTask(
344 FROM_HERE, 359 FROM_HERE,
345 base::Bind(&ThreadProxy::CheckOutputSurfaceStatusOnImplThread, 360 base::Bind(&ThreadProxy::CheckOutputSurfaceStatusOnImplThread,
346 impl_thread_weak_ptr_)); 361 impl_thread_weak_ptr_));
347 } 362 }
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 animate_requested_ = false; 692 animate_requested_ = false;
678 693
679 if (begin_frame_state) 694 if (begin_frame_state)
680 layer_tree_host_->ApplyScrollAndScale(*begin_frame_state->scroll_info); 695 layer_tree_host_->ApplyScrollAndScale(*begin_frame_state->scroll_info);
681 696
682 if (!in_composite_and_readback_ && !layer_tree_host_->visible()) { 697 if (!in_composite_and_readback_ && !layer_tree_host_->visible()) {
683 commit_requested_ = false; 698 commit_requested_ = false;
684 commit_request_sent_to_impl_thread_ = false; 699 commit_request_sent_to_impl_thread_ = false;
685 700
686 TRACE_EVENT0("cc", "EarlyOut_NotVisible"); 701 TRACE_EVENT0("cc", "EarlyOut_NotVisible");
702 bool cancel_commit = false;
687 Proxy::ImplThreadTaskRunner()->PostTask( 703 Proxy::ImplThreadTaskRunner()->PostTask(
688 FROM_HERE, 704 FROM_HERE,
689 base::Bind(&ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread, 705 base::Bind(&ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread,
690 impl_thread_weak_ptr_)); 706 impl_thread_weak_ptr_,
707 cancel_commit));
691 return; 708 return;
692 } 709 }
693 710
694 layer_tree_host_->WillBeginFrame(); 711 layer_tree_host_->WillBeginFrame();
695 712
696 if (begin_frame_state) { 713 if (begin_frame_state) {
697 layer_tree_host_->UpdateClientAnimations( 714 layer_tree_host_->UpdateClientAnimations(
698 begin_frame_state->monotonic_frame_begin_time); 715 begin_frame_state->monotonic_frame_begin_time);
699 layer_tree_host_->AnimateLayers( 716 layer_tree_host_->AnimateLayers(
700 begin_frame_state->monotonic_frame_begin_time); 717 begin_frame_state->monotonic_frame_begin_time);
701 } 718 }
702 719
703 // Unlink any backings that the impl thread has evicted, so that we know to 720 // Unlink any backings that the impl thread has evicted, so that we know to
704 // re-paint them in UpdateLayers. 721 // re-paint them in UpdateLayers.
705 if (layer_tree_host_->contents_texture_manager()) { 722 if (layer_tree_host_->contents_texture_manager()) {
706 layer_tree_host_->contents_texture_manager()-> 723 layer_tree_host_->contents_texture_manager()->
707 UnlinkAndClearEvictedBackings(); 724 UnlinkAndClearEvictedBackings();
708 } 725 }
709 726
710 layer_tree_host_->Layout(); 727 layer_tree_host_->Layout();
711 728
712 // Clear the commit flag after updating animations and layout here --- objects 729 // Clear the commit flag after updating animations and layout here --- objects
713 // that only layout when painted will trigger another SetNeedsCommit inside 730 // that only layout when painted will trigger another SetNeedsCommit inside
714 // UpdateLayers. 731 // UpdateLayers.
715 commit_requested_ = false; 732 commit_requested_ = false;
716 commit_request_sent_to_impl_thread_ = false; 733 commit_request_sent_to_impl_thread_ = false;
734 bool can_cancel_this_commit =
735 can_cancel_commit_ && !in_composite_and_readback_;
736 can_cancel_commit_ = true;
717 737
718 scoped_ptr<ResourceUpdateQueue> queue = 738 scoped_ptr<ResourceUpdateQueue> queue =
719 make_scoped_ptr(new ResourceUpdateQueue); 739 make_scoped_ptr(new ResourceUpdateQueue);
720 layer_tree_host_->UpdateLayers( 740 bool updated = layer_tree_host_->UpdateLayers(
721 queue.get(), 741 queue.get(),
722 begin_frame_state ? 742 begin_frame_state ? begin_frame_state->memory_allocation_limit_bytes
723 begin_frame_state->memory_allocation_limit_bytes : 0u); 743 : 0u);
744
745 if (!updated && can_cancel_this_commit) {
brianderson 2013/07/13 01:26:42 If "updated" is false, what else is there to commi
enne (OOO) 2013/07/15 22:23:28 The low-hanging fruit here are the cases I've adde
746 TRACE_EVENT0("cc", "EarlyOut_NoUpdates");
747 bool cancel_commit = true;
748 Proxy::ImplThreadTaskRunner()->PostTask(
749 FROM_HERE,
750 base::Bind(&ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread,
751 impl_thread_weak_ptr_,
752 cancel_commit));
753 return;
754 }
724 755
725 // Once single buffered layers are committed, they cannot be modified until 756 // Once single buffered layers are committed, they cannot be modified until
726 // they are drawn by the impl thread. 757 // they are drawn by the impl thread.
727 textures_acquired_ = false; 758 textures_acquired_ = false;
728 759
729 layer_tree_host_->WillCommit(); 760 layer_tree_host_->WillCommit();
730 // Before applying scrolls and calling animate, we set animate_requested_ to 761 // Before applying scrolls and calling animate, we set animate_requested_ to
731 // false. If it is true now, it means SetNeedAnimate was called again, but 762 // false. If it is true now, it means SetNeedAnimate was called again, but
732 // during a state when commit_request_sent_to_impl_thread_ = true. We need to 763 // during a state when commit_request_sent_to_impl_thread_ = true. We need to
733 // force that call to happen again now so that the commit request is sent to 764 // force that call to happen again now so that the commit request is sent to
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 current_resource_update_controller_on_impl_thread_ = 851 current_resource_update_controller_on_impl_thread_ =
821 ResourceUpdateController::Create( 852 ResourceUpdateController::Create(
822 this, 853 this,
823 Proxy::ImplThreadTaskRunner(), 854 Proxy::ImplThreadTaskRunner(),
824 queue.Pass(), 855 queue.Pass(),
825 layer_tree_host_impl_->resource_provider()); 856 layer_tree_host_impl_->resource_provider());
826 current_resource_update_controller_on_impl_thread_->PerformMoreUpdates( 857 current_resource_update_controller_on_impl_thread_->PerformMoreUpdates(
827 scheduler_on_impl_thread_->AnticipatedDrawTime()); 858 scheduler_on_impl_thread_->AnticipatedDrawTime());
828 } 859 }
829 860
830 void ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread() { 861 void ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread(
862 bool cancel_commit) {
831 TRACE_EVENT0("cc", "ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread"); 863 TRACE_EVENT0("cc", "ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread");
832 DCHECK(IsImplThread()); 864 DCHECK(IsImplThread());
833 DCHECK(scheduler_on_impl_thread_); 865 DCHECK(scheduler_on_impl_thread_);
834 DCHECK(scheduler_on_impl_thread_->CommitPending()); 866 DCHECK(scheduler_on_impl_thread_->CommitPending());
835 867
836 scheduler_on_impl_thread_->BeginFrameAbortedByMainThread(); 868 // The scroll and scale set was applied by the main thread, so the active tree
869 // needs to be updated as if these sent values were applied and committed.
870 layer_tree_host_impl_->active_tree()->ApplySentScrollAndScaleDeltas();
871 scheduler_on_impl_thread_->BeginFrameAbortedByMainThread(cancel_commit);
837 } 872 }
838 873
839 void ThreadProxy::ScheduledActionCommit() { 874 void ThreadProxy::ScheduledActionCommit() {
840 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit"); 875 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit");
841 DCHECK(IsImplThread()); 876 DCHECK(IsImplThread());
842 DCHECK(commit_completion_event_on_impl_thread_); 877 DCHECK(commit_completion_event_on_impl_thread_);
843 DCHECK(current_resource_update_controller_on_impl_thread_); 878 DCHECK(current_resource_update_controller_on_impl_thread_);
844 879
845 // Complete all remaining texture updates. 880 // Complete all remaining texture updates.
846 current_resource_update_controller_on_impl_thread_->Finalize(); 881 current_resource_update_controller_on_impl_thread_->Finalize();
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 !layer_tree_host_impl_->pending_tree()) { 1474 !layer_tree_host_impl_->pending_tree()) {
1440 TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation", 1475 TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation",
1441 TRACE_EVENT_SCOPE_THREAD); 1476 TRACE_EVENT_SCOPE_THREAD);
1442 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); 1477 DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1443 completion_event_for_commit_held_on_tree_activation_->Signal(); 1478 completion_event_for_commit_held_on_tree_activation_->Signal();
1444 completion_event_for_commit_held_on_tree_activation_ = NULL; 1479 completion_event_for_commit_held_on_tree_activation_ = NULL;
1445 } 1480 }
1446 } 1481 }
1447 1482
1448 } // namespace cc 1483 } // namespace cc
OLDNEW
« cc/scheduler/scheduler_state_machine_unittest.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