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