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

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: Don't abuse CanReadback 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
« no previous file with comments | « 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 if (defer_commits_) { 119 if (defer_commits_) {
120 TRACE_EVENT0("cc", "CompositeAndReadback_DeferCommit"); 120 TRACE_EVENT0("cc", "CompositeAndReadback_DeferCommit");
121 return false; 121 return false;
122 } 122 }
123 123
124 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) { 124 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) {
125 TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized"); 125 TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized");
126 return false; 126 return false;
127 } 127 }
128 128
129 // Perform a synchronous commit. 129 // Perform a synchronous commit with an associated readback.
130 ReadbackRequest request;
131 request.rect = rect;
132 request.pixels = pixels;
130 { 133 {
131 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 134 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
132 CompletionEvent begin_frame_sent_to_main_thread_completion; 135 CompletionEvent begin_frame_sent_to_main_thread_completion;
133 Proxy::ImplThreadTaskRunner()->PostTask( 136 Proxy::ImplThreadTaskRunner()
134 FROM_HERE, 137 ->PostTask(FROM_HERE,
135 base::Bind(&ThreadProxy::ForceCommitOnImplThread, 138 base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread,
136 impl_thread_weak_ptr_, 139 impl_thread_weak_ptr_,
137 &begin_frame_sent_to_main_thread_completion)); 140 &begin_frame_sent_to_main_thread_completion,
141 &request));
138 begin_frame_sent_to_main_thread_completion.Wait(); 142 begin_frame_sent_to_main_thread_completion.Wait();
139 } 143 }
140 144
141 in_composite_and_readback_ = true; 145 in_composite_and_readback_ = true;
146 // This is the forced commit.
147 // Note: The Impl thread also queues a separate BeginFrameOnMainThread on the
148 // main thread, which will be called after this CompositeAndReadback
149 // completes, to replace the forced commit.
142 BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>()); 150 BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>());
143 in_composite_and_readback_ = false; 151 in_composite_and_readback_ = false;
144 152
145 // Composite and readback requires a second commit to undo any changes 153 // Composite and readback requires a second commit to undo any changes
146 // that it made. 154 // that it made.
147 can_cancel_commit_ = false; 155 can_cancel_commit_ = false;
148 156
149 // Perform a synchronous readback. 157 request.completion.Wait();
150 ReadbackRequest request;
151 request.rect = rect;
152 request.pixels = pixels;
153 {
154 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
155 Proxy::ImplThreadTaskRunner()->PostTask(
156 FROM_HERE,
157 base::Bind(&ThreadProxy::RequestReadbackOnImplThread,
158 impl_thread_weak_ptr_,
159 &request));
160 request.completion.Wait();
161 }
162 return request.success; 158 return request.success;
163 } 159 }
164 160
165 void ThreadProxy::ForceCommitOnImplThread(CompletionEvent* completion) { 161 void ThreadProxy::ForceCommitForReadbackOnImplThread(
166 TRACE_EVENT0("cc", "ThreadProxy::ForceCommitOnImplThread"); 162 CompletionEvent* begin_frame_sent_completion,
163 ReadbackRequest* request) {
164 TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread");
167 DCHECK(IsImplThread()); 165 DCHECK(IsImplThread());
168 DCHECK(!begin_frame_sent_to_main_thread_completion_event_on_impl_thread_); 166 DCHECK(!begin_frame_sent_to_main_thread_completion_event_on_impl_thread_);
167 DCHECK(!readback_request_on_impl_thread_);
169 168
170 scheduler_on_impl_thread_->SetNeedsForcedCommit();
171 if (scheduler_on_impl_thread_->CommitPending()) {
172 completion->Signal();
173 return;
174 }
175
176 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ = completion;
177 }
178
179 void ThreadProxy::RequestReadbackOnImplThread(ReadbackRequest* request) {
180 DCHECK(Proxy::IsImplThread());
181 DCHECK(!readback_request_on_impl_thread_);
182 if (!layer_tree_host_impl_) { 169 if (!layer_tree_host_impl_) {
170 begin_frame_sent_completion->Signal();
183 request->success = false; 171 request->success = false;
184 request->completion.Signal(); 172 request->completion.Signal();
185 return; 173 return;
186 } 174 }
187 175
188 readback_request_on_impl_thread_ = request; 176 readback_request_on_impl_thread_ = request;
189 scheduler_on_impl_thread_->SetNeedsRedraw(); 177
190 scheduler_on_impl_thread_->SetNeedsForcedRedraw(); 178 scheduler_on_impl_thread_->SetNeedsForcedCommitForReadback();
179 if (scheduler_on_impl_thread_->CommitPending()) {
180 begin_frame_sent_completion->Signal();
181 return;
182 }
183
184 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ =
185 begin_frame_sent_completion;
191 } 186 }
192 187
193 void ThreadProxy::FinishAllRendering() { 188 void ThreadProxy::FinishAllRendering() {
194 DCHECK(Proxy::IsMainThread()); 189 DCHECK(Proxy::IsMainThread());
195 DCHECK(!defer_commits_); 190 DCHECK(!defer_commits_);
196 191
197 // Make sure all GL drawing is finished on the impl thread. 192 // Make sure all GL drawing is finished on the impl thread.
198 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 193 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
199 CompletionEvent completion; 194 CompletionEvent completion;
200 Proxy::ImplThreadTaskRunner()->PostTask( 195 Proxy::ImplThreadTaskRunner()->PostTask(
(...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 987
993 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { 988 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
994 DCHECK(IsImplThread()); 989 DCHECK(IsImplThread());
995 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation"); 990 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation");
996 Proxy::MainThreadTaskRunner()->PostTask( 991 Proxy::MainThreadTaskRunner()->PostTask(
997 FROM_HERE, 992 FROM_HERE,
998 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, 993 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
999 main_thread_weak_ptr_)); 994 main_thread_weak_ptr_));
1000 } 995 }
1001 996
1002 ScheduledActionDrawAndSwapResult 997 DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
1003 ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) { 998 bool forced_draw,
1004 TRACE_EVENT1( 999 bool swap_requested,
1005 "cc", "ThreadProxy::ScheduledActionDrawAndSwap", "forced", forced_draw); 1000 bool readback_requested) {
1006 1001 DrawSwapReadbackResult result;
1007 ScheduledActionDrawAndSwapResult result;
1008 result.did_draw = false; 1002 result.did_draw = false;
1009 result.did_swap = false; 1003 result.did_swap = false;
1004 result.did_readback = false;
1010 DCHECK(IsImplThread()); 1005 DCHECK(IsImplThread());
1011 DCHECK(layer_tree_host_impl_.get()); 1006 DCHECK(layer_tree_host_impl_.get());
1012 if (!layer_tree_host_impl_) 1007 if (!layer_tree_host_impl_)
1013 return result; 1008 return result;
1014 1009
1015 DCHECK(layer_tree_host_impl_->renderer()); 1010 DCHECK(layer_tree_host_impl_->renderer());
1016 if (!layer_tree_host_impl_->renderer()) 1011 if (!layer_tree_host_impl_->renderer())
1017 return result; 1012 return result;
1018 1013
1019 base::TimeTicks monotonic_time = 1014 base::TimeTicks monotonic_time =
(...skipping 14 matching lines...) Expand all
1034 // to produce a frame, as the calling site on main thread is blocked until its 1029 // to produce a frame, as the calling site on main thread is blocked until its
1035 // request completes, and we signal completion here. If CanDraw() is false, we 1030 // request completes, and we signal completion here. If CanDraw() is false, we
1036 // will indicate success=false to the caller, but we must still signal 1031 // will indicate success=false to the caller, but we must still signal
1037 // completion to avoid deadlock. 1032 // completion to avoid deadlock.
1038 1033
1039 // We guard PrepareToDraw() with CanDraw() because it always returns a valid 1034 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
1040 // frame, so can only be used when such a frame is possible. Since 1035 // frame, so can only be used when such a frame is possible. Since
1041 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on 1036 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
1042 // CanDraw() as well. 1037 // CanDraw() as well.
1043 1038
1044 bool drawing_for_readback = !!readback_request_on_impl_thread_; 1039 // readback_request_on_impl_thread_ may be for the pending tree, do
1040 // not perform the readback unless explicitly requested.
1041 bool drawing_for_readback =
1042 readback_requested && !!readback_request_on_impl_thread_;
1045 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels(); 1043 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
1046 1044
1047 LayerTreeHostImpl::FrameData frame; 1045 LayerTreeHostImpl::FrameData frame;
1048 bool draw_frame = false; 1046 bool draw_frame = false;
1049 bool start_ready_animations = true; 1047 bool start_ready_animations = true;
1050 1048
1051 if (layer_tree_host_impl_->CanDraw() && 1049 if (layer_tree_host_impl_->CanDraw() &&
1052 (!drawing_for_readback || can_do_readback)) { 1050 (!drawing_for_readback || can_do_readback)) {
1053 // If it is for a readback, make sure we draw the portion being read back. 1051 // If it is for a readback, make sure we draw the portion being read back.
1054 gfx::Rect readback_rect; 1052 gfx::Rect readback_rect;
(...skipping 12 matching lines...) Expand all
1067 if (draw_frame) { 1065 if (draw_frame) {
1068 layer_tree_host_impl_->DrawLayers( 1066 layer_tree_host_impl_->DrawLayers(
1069 &frame, 1067 &frame,
1070 scheduler_on_impl_thread_->LastBeginFrameOnImplThreadTime()); 1068 scheduler_on_impl_thread_->LastBeginFrameOnImplThreadTime());
1071 result.did_draw = true; 1069 result.did_draw = true;
1072 } 1070 }
1073 layer_tree_host_impl_->DidDrawAllLayers(frame); 1071 layer_tree_host_impl_->DidDrawAllLayers(frame);
1074 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); 1072 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
1075 1073
1076 // Check for a pending CompositeAndReadback. 1074 // Check for a pending CompositeAndReadback.
1077 if (readback_request_on_impl_thread_) { 1075 if (drawing_for_readback) {
1078 readback_request_on_impl_thread_->success = false; 1076 DCHECK(!swap_requested);
1079 if (draw_frame) { 1077 result.did_readback = false;
1078 if (draw_frame && !layer_tree_host_impl_->IsContextLost()) {
brianderson 2013/09/06 22:04:29 It was easier to check for context lost here than
1080 layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels, 1079 layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels,
1081 readback_request_on_impl_thread_->rect); 1080 readback_request_on_impl_thread_->rect);
1082 readback_request_on_impl_thread_->success = 1081 result.did_readback = true;
1083 !layer_tree_host_impl_->IsContextLost();
1084 } 1082 }
1083 readback_request_on_impl_thread_->success = result.did_readback;
1085 readback_request_on_impl_thread_->completion.Signal(); 1084 readback_request_on_impl_thread_->completion.Signal();
1086 readback_request_on_impl_thread_ = NULL; 1085 readback_request_on_impl_thread_ = NULL;
1087 } else if (draw_frame) { 1086 } else if (draw_frame) {
1087 DCHECK(swap_requested);
1088 result.did_swap = layer_tree_host_impl_->SwapBuffers(frame); 1088 result.did_swap = layer_tree_host_impl_->SwapBuffers(frame);
1089 1089
1090 if (frame.contains_incomplete_tile) 1090 if (frame.contains_incomplete_tile)
1091 DidSwapUseIncompleteTileOnImplThread(); 1091 DidSwapUseIncompleteTileOnImplThread();
1092 } 1092 }
1093 1093
1094 // Tell the main thread that the the newly-commited frame was drawn. 1094 // Tell the main thread that the the newly-commited frame was drawn.
1095 if (next_frame_is_newly_committed_frame_on_impl_thread_) { 1095 if (next_frame_is_newly_committed_frame_on_impl_thread_) {
1096 next_frame_is_newly_committed_frame_on_impl_thread_ = false; 1096 next_frame_is_newly_committed_frame_on_impl_thread_ = false;
1097 Proxy::MainThreadTaskRunner()->PostTask( 1097 Proxy::MainThreadTaskRunner()->PostTask(
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 texture_acquisition_completion_event_on_impl_thread_ = completion; 1170 texture_acquisition_completion_event_on_impl_thread_ = completion;
1171 scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures(); 1171 scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures();
1172 } 1172 }
1173 1173
1174 void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() { 1174 void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
1175 DCHECK(texture_acquisition_completion_event_on_impl_thread_); 1175 DCHECK(texture_acquisition_completion_event_on_impl_thread_);
1176 texture_acquisition_completion_event_on_impl_thread_->Signal(); 1176 texture_acquisition_completion_event_on_impl_thread_->Signal();
1177 texture_acquisition_completion_event_on_impl_thread_ = NULL; 1177 texture_acquisition_completion_event_on_impl_thread_ = NULL;
1178 } 1178 }
1179 1179
1180 ScheduledActionDrawAndSwapResult 1180 DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
1181 ThreadProxy::ScheduledActionDrawAndSwapIfPossible() { 1181 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap");
1182 return ScheduledActionDrawAndSwapInternal(false); 1182 bool forced_draw = false;
1183 bool swap_requested = true;
1184 bool readback_requested = false;
1185 return DrawSwapReadbackInternal(
1186 forced_draw, swap_requested, readback_requested);
1183 } 1187 }
1184 1188
1185 ScheduledActionDrawAndSwapResult 1189 DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapForced() {
1186 ThreadProxy::ScheduledActionDrawAndSwapForced() { 1190 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwapForced");
1187 return ScheduledActionDrawAndSwapInternal(true); 1191 bool forced_draw = true;
1192 bool swap_requested = true;
1193 bool readback_requested = false;
1194 return DrawSwapReadbackInternal(
1195 forced_draw, swap_requested, readback_requested);
1196 }
1197
1198 DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndReadback() {
1199 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndReadback");
1200 bool forced_draw = true;
1201 bool swap_requested = false;
1202 bool readback_requested = true;
1203 return DrawSwapReadbackInternal(
1204 forced_draw, swap_requested, readback_requested);
1188 } 1205 }
1189 1206
1190 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { 1207 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
1191 if (current_resource_update_controller_on_impl_thread_) 1208 if (current_resource_update_controller_on_impl_thread_)
1192 current_resource_update_controller_on_impl_thread_ 1209 current_resource_update_controller_on_impl_thread_
1193 ->PerformMoreUpdates(time); 1210 ->PerformMoreUpdates(time);
1194 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); 1211 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
1195 } 1212 }
1196 1213
1197 base::TimeDelta ThreadProxy::DrawDurationEstimate() { 1214 base::TimeDelta ThreadProxy::DrawDurationEstimate() {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 1295
1279 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { 1296 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
1280 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread"); 1297 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
1281 DCHECK(IsImplThread()); 1298 DCHECK(IsImplThread());
1282 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); 1299 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
1283 const LayerTreeSettings& settings = layer_tree_host_->settings(); 1300 const LayerTreeSettings& settings = layer_tree_host_->settings();
1284 SchedulerSettings scheduler_settings; 1301 SchedulerSettings scheduler_settings;
1285 scheduler_settings.impl_side_painting = settings.impl_side_painting; 1302 scheduler_settings.impl_side_painting = settings.impl_side_painting;
1286 scheduler_settings.timeout_and_draw_when_animation_checkerboards = 1303 scheduler_settings.timeout_and_draw_when_animation_checkerboards =
1287 settings.timeout_and_draw_when_animation_checkerboards; 1304 settings.timeout_and_draw_when_animation_checkerboards;
1305 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
1306 settings.maximum_number_of_failed_draws_before_draw_is_forced_;
1288 scheduler_settings.using_synchronous_renderer_compositor = 1307 scheduler_settings.using_synchronous_renderer_compositor =
1289 settings.using_synchronous_renderer_compositor; 1308 settings.using_synchronous_renderer_compositor;
1290 scheduler_settings.throttle_frame_production = 1309 scheduler_settings.throttle_frame_production =
1291 settings.throttle_frame_production; 1310 settings.throttle_frame_production;
1292 scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings); 1311 scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings);
1293 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); 1312 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
1294 1313
1295 impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr(); 1314 impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr();
1296 completion->Signal(); 1315 completion->Signal();
1297 } 1316 }
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 completion_event_for_commit_held_on_tree_activation_ = NULL; 1540 completion_event_for_commit_held_on_tree_activation_ = NULL;
1522 } 1541 }
1523 1542
1524 UpdateBackgroundAnimateTicking(); 1543 UpdateBackgroundAnimateTicking();
1525 1544
1526 commit_to_activate_duration_history_.InsertSample( 1545 commit_to_activate_duration_history_.InsertSample(
1527 base::TimeTicks::HighResNow() - commit_complete_time_); 1546 base::TimeTicks::HighResNow() - commit_complete_time_);
1528 } 1547 }
1529 1548
1530 } // namespace cc 1549 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/thread_proxy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698