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

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

Issue 23503003: cc: Add readback and forced draw states to the Scheduler (Closed) Base URL: http://git.chromium.org/chromium/src.git@schedReorg3
Patch Set: Fix all the tests Created 7 years, 3 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
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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 if (defer_commits_) { 116 if (defer_commits_) {
117 TRACE_EVENT0("cc", "CompositeAndReadback_DeferCommit"); 117 TRACE_EVENT0("cc", "CompositeAndReadback_DeferCommit");
118 return false; 118 return false;
119 } 119 }
120 120
121 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) { 121 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) {
122 TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized"); 122 TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized");
123 return false; 123 return false;
124 } 124 }
125 125
126 // Perform a synchronous commit. 126 // Perform a synchronous commit with an associated readback.
127 ReadbackRequest request;
128 request.rect = rect;
129 request.pixels = pixels;
127 { 130 {
128 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 131 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
129 CompletionEvent begin_frame_sent_to_main_thread_completion; 132 CompletionEvent begin_frame_sent_to_main_thread_completion;
130 Proxy::ImplThreadTaskRunner()->PostTask( 133 Proxy::ImplThreadTaskRunner()->PostTask(
131 FROM_HERE, 134 FROM_HERE,
132 base::Bind(&ThreadProxy::ForceCommitOnImplThread, 135 base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread,
133 impl_thread_weak_ptr_, 136 impl_thread_weak_ptr_,
134 &begin_frame_sent_to_main_thread_completion)); 137 &begin_frame_sent_to_main_thread_completion,
138 &request));
135 begin_frame_sent_to_main_thread_completion.Wait(); 139 begin_frame_sent_to_main_thread_completion.Wait();
136 } 140 }
137 141
138 in_composite_and_readback_ = true; 142 in_composite_and_readback_ = true;
143 // This is the forced commit.
144 // Note: The Impl thread also queues a separate BeginFrameOnMainThread on the
145 // main thread, which will be called after this CompositeAndReadback
danakj 2013/08/30 15:56:41 nit: double space
brianderson 2013/09/03 22:41:12 Done.
146 // completes, to replace the forced commit.
139 BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>()); 147 BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>());
140 in_composite_and_readback_ = false; 148 in_composite_and_readback_ = false;
141 149
142 // Composite and readback requires a second commit to undo any changes 150 // Composite and readback requires a second commit to undo any changes
143 // that it made. 151 // that it made.
144 can_cancel_commit_ = false; 152 can_cancel_commit_ = false;
145 153
146 // Perform a synchronous readback. 154 request.completion.Wait();
147 ReadbackRequest request;
148 request.rect = rect;
149 request.pixels = pixels;
150 {
151 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
152 Proxy::ImplThreadTaskRunner()->PostTask(
153 FROM_HERE,
154 base::Bind(&ThreadProxy::RequestReadbackOnImplThread,
155 impl_thread_weak_ptr_,
156 &request));
157 request.completion.Wait();
158 }
159 return request.success; 155 return request.success;
160 } 156 }
161 157
162 void ThreadProxy::ForceCommitOnImplThread(CompletionEvent* completion) { 158 void ThreadProxy::ForceCommitForReadbackOnImplThread(
163 TRACE_EVENT0("cc", "ThreadProxy::ForceCommitOnImplThread"); 159 CompletionEvent* begin_frame_sent_completion,
160 ReadbackRequest* request) {
161 TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread");
164 DCHECK(IsImplThread()); 162 DCHECK(IsImplThread());
165 DCHECK(!begin_frame_sent_to_main_thread_completion_event_on_impl_thread_); 163 DCHECK(!begin_frame_sent_to_main_thread_completion_event_on_impl_thread_);
164 DCHECK(!readback_request_on_impl_thread_);
166 165
167 scheduler_on_impl_thread_->SetNeedsForcedCommit();
168 if (scheduler_on_impl_thread_->CommitPending()) {
169 completion->Signal();
170 return;
171 }
172
173 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ = completion;
174 }
175
176 void ThreadProxy::RequestReadbackOnImplThread(ReadbackRequest* request) {
177 DCHECK(Proxy::IsImplThread());
178 DCHECK(!readback_request_on_impl_thread_);
179 if (!layer_tree_host_impl_) { 166 if (!layer_tree_host_impl_) {
167 begin_frame_sent_completion->Signal();
180 request->success = false; 168 request->success = false;
181 request->completion.Signal(); 169 request->completion.Signal();
182 return; 170 return;
183 } 171 }
184 172
185 readback_request_on_impl_thread_ = request; 173 readback_request_on_impl_thread_ = request;
186 scheduler_on_impl_thread_->SetNeedsRedraw(); 174
187 scheduler_on_impl_thread_->SetNeedsForcedRedraw(); 175 scheduler_on_impl_thread_->SetNeedsForcedCommitForReadback();
176 if (scheduler_on_impl_thread_->CommitPending()) {
177 begin_frame_sent_completion->Signal();
178 return;
179 }
180
181 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ =
182 begin_frame_sent_completion;
188 } 183 }
189 184
190 void ThreadProxy::FinishAllRendering() { 185 void ThreadProxy::FinishAllRendering() {
191 DCHECK(Proxy::IsMainThread()); 186 DCHECK(Proxy::IsMainThread());
192 DCHECK(!defer_commits_); 187 DCHECK(!defer_commits_);
193 188
194 // Make sure all GL drawing is finished on the impl thread. 189 // Make sure all GL drawing is finished on the impl thread.
195 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 190 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
196 CompletionEvent completion; 191 CompletionEvent completion;
197 Proxy::ImplThreadTaskRunner()->PostTask( 192 Proxy::ImplThreadTaskRunner()->PostTask(
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 967
973 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { 968 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
974 DCHECK(IsImplThread()); 969 DCHECK(IsImplThread());
975 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation"); 970 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation");
976 Proxy::MainThreadTaskRunner()->PostTask( 971 Proxy::MainThreadTaskRunner()->PostTask(
977 FROM_HERE, 972 FROM_HERE,
978 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, 973 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
979 main_thread_weak_ptr_)); 974 main_thread_weak_ptr_));
980 } 975 }
981 976
982 ScheduledActionDrawAndSwapResult 977 DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
983 ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) { 978 bool forced_draw,
984 TRACE_EVENT1( 979 bool swap_requested,
985 "cc", "ThreadProxy::ScheduledActionDrawAndSwap", "forced", forced_draw); 980 bool readback_requested) {
986 981 DrawSwapReadbackResult result;
987 ScheduledActionDrawAndSwapResult result;
988 result.did_draw = false; 982 result.did_draw = false;
989 result.did_swap = false; 983 result.did_swap = false;
danakj 2013/08/30 15:56:41 should we set did_readback false? or should we rem
brianderson 2013/09/03 22:41:12 I will set did_readback to false so it is explicit
990 DCHECK(IsImplThread()); 984 DCHECK(IsImplThread());
991 DCHECK(layer_tree_host_impl_.get()); 985 DCHECK(layer_tree_host_impl_.get());
992 if (!layer_tree_host_impl_) 986 if (!layer_tree_host_impl_)
993 return result; 987 return result;
994 988
995 DCHECK(layer_tree_host_impl_->renderer()); 989 DCHECK(layer_tree_host_impl_->renderer());
996 if (!layer_tree_host_impl_->renderer()) 990 if (!layer_tree_host_impl_->renderer())
997 return result; 991 return result;
998 992
999 base::TimeTicks monotonic_time = 993 base::TimeTicks monotonic_time =
(...skipping 14 matching lines...) Expand all
1014 // to produce a frame, as the calling site on main thread is blocked until its 1008 // to produce a frame, as the calling site on main thread is blocked until its
1015 // request completes, and we signal completion here. If CanDraw() is false, we 1009 // request completes, and we signal completion here. If CanDraw() is false, we
1016 // will indicate success=false to the caller, but we must still signal 1010 // will indicate success=false to the caller, but we must still signal
1017 // completion to avoid deadlock. 1011 // completion to avoid deadlock.
1018 1012
1019 // We guard PrepareToDraw() with CanDraw() because it always returns a valid 1013 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
1020 // frame, so can only be used when such a frame is possible. Since 1014 // frame, so can only be used when such a frame is possible. Since
1021 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on 1015 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
1022 // CanDraw() as well. 1016 // CanDraw() as well.
1023 1017
1024 bool drawing_for_readback = !!readback_request_on_impl_thread_; 1018 // readback_request_on_impl_thread_ may be for the pending tree, do
1019 // not perform the readback unless explicitly requested.
1020 bool drawing_for_readback =
1021 readback_requested && !!readback_request_on_impl_thread_;
1025 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels(); 1022 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
1026 1023
1027 LayerTreeHostImpl::FrameData frame; 1024 LayerTreeHostImpl::FrameData frame;
1028 bool draw_frame = false; 1025 bool draw_frame = false;
1029 bool start_ready_animations = true; 1026 bool start_ready_animations = true;
1030 1027
1031 if (layer_tree_host_impl_->CanDraw() && 1028 if (layer_tree_host_impl_->CanDraw() &&
1032 (!drawing_for_readback || can_do_readback)) { 1029 (!drawing_for_readback || can_do_readback)) {
1033 // If it is for a readback, make sure we draw the portion being read back. 1030 // If it is for a readback, make sure we draw the portion being read back.
1034 gfx::Rect readback_rect; 1031 gfx::Rect readback_rect;
(...skipping 13 matching lines...) Expand all
1048 layer_tree_host_impl_->DrawLayers( 1045 layer_tree_host_impl_->DrawLayers(
1049 &frame, 1046 &frame,
1050 scheduler_on_impl_thread_->LastBeginFrameOnImplThreadTime()); 1047 scheduler_on_impl_thread_->LastBeginFrameOnImplThreadTime());
1051 result.did_draw = true; 1048 result.did_draw = true;
1052 } 1049 }
1053 layer_tree_host_impl_->DidDrawAllLayers(frame); 1050 layer_tree_host_impl_->DidDrawAllLayers(frame);
1054 1051
1055 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); 1052 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
1056 1053
1057 // Check for a pending CompositeAndReadback. 1054 // Check for a pending CompositeAndReadback.
1058 if (readback_request_on_impl_thread_) { 1055 if (drawing_for_readback) {
1059 readback_request_on_impl_thread_->success = false; 1056 DCHECK(!swap_requested);
1057 result.did_readback = false;
1060 if (draw_frame) { 1058 if (draw_frame) {
1061 layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels, 1059 layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels,
1062 readback_request_on_impl_thread_->rect); 1060 readback_request_on_impl_thread_->rect);
1063 readback_request_on_impl_thread_->success = 1061 result.did_readback = !layer_tree_host_impl_->IsContextLost();
1064 !layer_tree_host_impl_->IsContextLost();
1065 } 1062 }
1063 readback_request_on_impl_thread_->success = result.did_readback;
1066 readback_request_on_impl_thread_->completion.Signal(); 1064 readback_request_on_impl_thread_->completion.Signal();
1067 readback_request_on_impl_thread_ = NULL; 1065 readback_request_on_impl_thread_ = NULL;
1068 } else if (draw_frame) { 1066 } else if (draw_frame && swap_requested) {
danakj 2013/08/30 15:56:41 Are you saying you expect this function to be call
brianderson 2013/09/03 22:41:12 My intention was to make sure that swap_requested
1069 result.did_swap = layer_tree_host_impl_->SwapBuffers(frame); 1067 result.did_swap = layer_tree_host_impl_->SwapBuffers(frame);
1070 1068
1071 if (frame.contains_incomplete_tile) 1069 if (frame.contains_incomplete_tile)
1072 DidSwapUseIncompleteTileOnImplThread(); 1070 DidSwapUseIncompleteTileOnImplThread();
1073 } 1071 }
1074 1072
1075 // Tell the main thread that the the newly-commited frame was drawn. 1073 // Tell the main thread that the the newly-commited frame was drawn.
1076 if (next_frame_is_newly_committed_frame_on_impl_thread_) { 1074 if (next_frame_is_newly_committed_frame_on_impl_thread_) {
1077 next_frame_is_newly_committed_frame_on_impl_thread_ = false; 1075 next_frame_is_newly_committed_frame_on_impl_thread_ = false;
1078 Proxy::MainThreadTaskRunner()->PostTask( 1076 Proxy::MainThreadTaskRunner()->PostTask(
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 texture_acquisition_completion_event_on_impl_thread_ = completion; 1149 texture_acquisition_completion_event_on_impl_thread_ = completion;
1152 scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures(); 1150 scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures();
1153 } 1151 }
1154 1152
1155 void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() { 1153 void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
1156 DCHECK(texture_acquisition_completion_event_on_impl_thread_); 1154 DCHECK(texture_acquisition_completion_event_on_impl_thread_);
1157 texture_acquisition_completion_event_on_impl_thread_->Signal(); 1155 texture_acquisition_completion_event_on_impl_thread_->Signal();
1158 texture_acquisition_completion_event_on_impl_thread_ = NULL; 1156 texture_acquisition_completion_event_on_impl_thread_ = NULL;
1159 } 1157 }
1160 1158
1161 ScheduledActionDrawAndSwapResult 1159 DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
1162 ThreadProxy::ScheduledActionDrawAndSwapIfPossible() { 1160 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap");
1163 return ScheduledActionDrawAndSwapInternal(false); 1161 bool forced_draw = false;
1162 bool swap_requested = true;
1163 bool readback_requested = false;
1164 return DrawSwapReadbackInternal(
1165 forced_draw, swap_requested, readback_requested);
1164 } 1166 }
1165 1167
1166 ScheduledActionDrawAndSwapResult 1168 DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapForced() {
1167 ThreadProxy::ScheduledActionDrawAndSwapForced() { 1169 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwapForced");
1168 return ScheduledActionDrawAndSwapInternal(true); 1170 bool forced_draw = true;
1171 bool swap_requested = true;
1172 bool readback_requested = false;
1173 return DrawSwapReadbackInternal(
1174 forced_draw, swap_requested, readback_requested);
1175 }
1176
1177 DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndReadback() {
1178 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndReadback");
1179 bool forced_draw = true;
1180 bool swap_requested = false;
1181 bool readback_requested = true;
1182 return DrawSwapReadbackInternal(
1183 forced_draw, swap_requested, readback_requested);
1169 } 1184 }
1170 1185
1171 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { 1186 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
1172 if (current_resource_update_controller_on_impl_thread_) 1187 if (current_resource_update_controller_on_impl_thread_)
1173 current_resource_update_controller_on_impl_thread_ 1188 current_resource_update_controller_on_impl_thread_
1174 ->PerformMoreUpdates(time); 1189 ->PerformMoreUpdates(time);
1175 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); 1190 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
1176 } 1191 }
1177 1192
1178 base::TimeDelta ThreadProxy::DrawDurationEstimate() { 1193 base::TimeDelta ThreadProxy::DrawDurationEstimate() {
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); 1527 DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1513 completion_event_for_commit_held_on_tree_activation_->Signal(); 1528 completion_event_for_commit_held_on_tree_activation_->Signal();
1514 completion_event_for_commit_held_on_tree_activation_ = NULL; 1529 completion_event_for_commit_held_on_tree_activation_ = NULL;
1515 } 1530 }
1516 1531
1517 commit_to_activate_duration_history_.InsertSample( 1532 commit_to_activate_duration_history_.InsertSample(
1518 base::TimeTicks::HighResNow() - commit_complete_time_); 1533 base::TimeTicks::HighResNow() - commit_complete_time_);
1519 } 1534 }
1520 1535
1521 } // namespace cc 1536 } // 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