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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |