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

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

Issue 287193003: cc: Stop blocking the main thread in CreateAndInitializeOutputSurface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: threadproxy-nonblock-create: defer Created 6 years, 6 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
« 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 <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 void ThreadProxy::UpdateBackgroundAnimateTicking() { 191 void ThreadProxy::UpdateBackgroundAnimateTicking() {
192 bool should_background_tick = 192 bool should_background_tick =
193 !impl().scheduler->WillDrawIfNeeded() && 193 !impl().scheduler->WillDrawIfNeeded() &&
194 impl().layer_tree_host_impl->active_tree()->root_layer(); 194 impl().layer_tree_host_impl->active_tree()->root_layer();
195 impl().layer_tree_host_impl->UpdateBackgroundAnimateTicking( 195 impl().layer_tree_host_impl->UpdateBackgroundAnimateTicking(
196 should_background_tick); 196 should_background_tick);
197 if (should_background_tick) 197 if (should_background_tick)
198 impl().animations_frozen_until_next_draw = false; 198 impl().animations_frozen_until_next_draw = false;
199 } 199 }
200 200
201 void ThreadProxy::DoCreateAndInitializeOutputSurface() { 201 void ThreadProxy::DidLoseOutputSurface() {
202 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurface");
203 DCHECK(IsMainThread());
204 layer_tree_host()->DidLoseOutputSurface();
205
206 {
207 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
208
209 // Return lost resources to their owners immediately.
210 BlockingTaskRunner::CapturePostTasks blocked;
211
212 CompletionEvent completion;
213 Proxy::ImplThreadTaskRunner()->PostTask(
214 FROM_HERE,
215 base::Bind(&ThreadProxy::DeleteContentsTexturesOnImplThread,
216 impl_thread_weak_ptr_,
217 &completion));
218 completion.Wait();
219 }
220 }
221
222 void ThreadProxy::CreateAndInitializeOutputSurface() {
202 TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface"); 223 TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface");
203 DCHECK(IsMainThread()); 224 DCHECK(IsMainThread());
204 225
205 scoped_ptr<OutputSurface> output_surface = 226 scoped_ptr<OutputSurface> output_surface =
206 layer_tree_host()->CreateOutputSurface(); 227 layer_tree_host()->CreateOutputSurface();
207 228
208 RendererCapabilities capabilities; 229 if (output_surface) {
209 bool success = !!output_surface;
210 if (success) {
211 // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results
212 // of that call are pushed into the success and capabilities local
213 // variables.
214 CompletionEvent completion;
215 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
216
217 Proxy::ImplThreadTaskRunner()->PostTask( 230 Proxy::ImplThreadTaskRunner()->PostTask(
218 FROM_HERE, 231 FROM_HERE,
219 base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread, 232 base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
220 impl_thread_weak_ptr_, 233 impl_thread_weak_ptr_,
221 &completion, 234 base::Passed(&output_surface)));
222 base::Passed(&output_surface), 235 return;
223 &success,
224 &capabilities));
225 completion.Wait();
226 } 236 }
237
238 DidInitializeOutputSurface(false, RendererCapabilities());
239 }
240
241 void ThreadProxy::DidInitializeOutputSurface(
242 bool success,
243 const RendererCapabilities& capabilities) {
244 TRACE_EVENT0("cc", "ThreadProxy::DidInitializeOutputSurface");
245 DCHECK(IsMainThread());
227 main().renderer_capabilities_main_thread_copy = capabilities; 246 main().renderer_capabilities_main_thread_copy = capabilities;
228 layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success); 247 layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
229 248
230 if (success) { 249 if (!success) {
231 main().output_surface_creation_callback.Cancel();
232 } else if (!main().output_surface_creation_callback.IsCancelled()) {
233 Proxy::MainThreadTaskRunner()->PostTask( 250 Proxy::MainThreadTaskRunner()->PostTask(
234 FROM_HERE, main().output_surface_creation_callback.callback()); 251 FROM_HERE,
252 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
253 main_thread_weak_ptr_));
235 } 254 }
236 } 255 }
237 256
238 void ThreadProxy::SetRendererCapabilitiesMainThreadCopy( 257 void ThreadProxy::SetRendererCapabilitiesMainThreadCopy(
239 const RendererCapabilities& capabilities) { 258 const RendererCapabilities& capabilities) {
240 main().renderer_capabilities_main_thread_copy = capabilities; 259 main().renderer_capabilities_main_thread_copy = capabilities;
241 } 260 }
242 261
243 void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() { 262 void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
244 DCHECK(IsMainThread()); 263 DCHECK(IsMainThread());
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread"); 324 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
306 DCHECK(IsImplThread()); 325 DCHECK(IsImplThread());
307 CheckOutputSurfaceStatusOnImplThread(); 326 CheckOutputSurfaceStatusOnImplThread();
308 } 327 }
309 328
310 void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() { 329 void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() {
311 TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread"); 330 TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread");
312 DCHECK(IsImplThread()); 331 DCHECK(IsImplThread());
313 if (!impl().layer_tree_host_impl->IsContextLost()) 332 if (!impl().layer_tree_host_impl->IsContextLost())
314 return; 333 return;
334 Proxy::MainThreadTaskRunner()->PostTask(
335 FROM_HERE,
336 base::Bind(&ThreadProxy::DidLoseOutputSurface, main_thread_weak_ptr_));
315 impl().scheduler->DidLoseOutputSurface(); 337 impl().scheduler->DidLoseOutputSurface();
316 } 338 }
317 339
318 void ThreadProxy::CommitVSyncParameters(base::TimeTicks timebase, 340 void ThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
319 base::TimeDelta interval) { 341 base::TimeDelta interval) {
320 impl().scheduler->CommitVSyncParameters(timebase, interval); 342 impl().scheduler->CommitVSyncParameters(timebase, interval);
321 } 343 }
322 344
323 void ThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { 345 void ThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
324 impl().scheduler->SetEstimatedParentDrawTime(draw_time); 346 impl().scheduler->SetEstimatedParentDrawTime(draw_time);
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 TRACE_EVENT_INSTANT0( 742 TRACE_EVENT_INSTANT0(
721 "cc", "EarlyOut_DeferCommits", TRACE_EVENT_SCOPE_THREAD); 743 "cc", "EarlyOut_DeferCommits", TRACE_EVENT_SCOPE_THREAD);
722 return; 744 return;
723 } 745 }
724 746
725 // If the commit finishes, LayerTreeHost will transfer its swap promises to 747 // If the commit finishes, LayerTreeHost will transfer its swap promises to
726 // LayerTreeImpl. The destructor of SwapPromiseChecker checks LayerTressHost's 748 // LayerTreeImpl. The destructor of SwapPromiseChecker checks LayerTressHost's
727 // swap promises. 749 // swap promises.
728 SwapPromiseChecker swap_promise_checker(layer_tree_host()); 750 SwapPromiseChecker swap_promise_checker(layer_tree_host());
729 751
730 // Do not notify the impl thread of commit requests that occur during 752 main().commit_requested = false;
731 // the apply/animate/layout part of the BeginMainFrameAndCommit process since 753 main().commit_request_sent_to_impl_thread = false;
732 // those commit requests will get painted immediately. Once we have done
733 // the paint, main().commit_requested will be set to false to allow new commit
734 // requests to be scheduled.
735 main().commit_requested = true;
736 main().commit_request_sent_to_impl_thread = true;
737
738 // On the other hand, the AnimationRequested flag needs to be cleared
739 // here so that any animation requests generated by the apply or animate
740 // callbacks will trigger another frame.
741 main().animate_requested = false; 754 main().animate_requested = false;
742 755
743 if (!layer_tree_host()->visible()) { 756 if (!layer_tree_host()->visible()) {
744 main().commit_requested = false;
745 main().commit_request_sent_to_impl_thread = false;
746
747 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD); 757 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
748 bool did_handle = false; 758 bool did_handle = false;
749 Proxy::ImplThreadTaskRunner()->PostTask( 759 Proxy::ImplThreadTaskRunner()->PostTask(
750 FROM_HERE, 760 FROM_HERE,
751 base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread, 761 base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
752 impl_thread_weak_ptr_, 762 impl_thread_weak_ptr_,
753 did_handle)); 763 did_handle));
754 return; 764 return;
755 } 765 }
756 766
767 if (layer_tree_host()->output_surface_lost()) {
768 TRACE_EVENT_INSTANT0(
769 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
770 bool did_handle = false;
771 Proxy::ImplThreadTaskRunner()->PostTask(
772 FROM_HERE,
773 base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
774 impl_thread_weak_ptr_,
775 did_handle));
776 return;
777 }
778
779 // Do not notify the impl thread of commit requests that occur during
780 // the apply/animate/layout part of the BeginMainFrameAndCommit process since
781 // those commit requests will get painted immediately. Once we have done
782 // the paint, main().commit_requested will be set to false to allow new commit
783 // requests to be scheduled.
784 // On the other hand, the animate_requested flag should remain cleared
785 // here so that any animation requests generated by the apply or animate
786 // callbacks will trigger another frame.
787 main().commit_requested = true;
788 main().commit_request_sent_to_impl_thread = true;
789
757 layer_tree_host()->ApplyScrollAndScale(*begin_main_frame_state->scroll_info); 790 layer_tree_host()->ApplyScrollAndScale(*begin_main_frame_state->scroll_info);
758 791
759 layer_tree_host()->WillBeginMainFrame(); 792 layer_tree_host()->WillBeginMainFrame();
760 793
761 layer_tree_host()->UpdateClientAnimations( 794 layer_tree_host()->UpdateClientAnimations(
762 begin_main_frame_state->monotonic_frame_begin_time); 795 begin_main_frame_state->monotonic_frame_begin_time);
763 layer_tree_host()->AnimateLayers( 796 layer_tree_host()->AnimateLayers(
764 begin_main_frame_state->monotonic_frame_begin_time); 797 begin_main_frame_state->monotonic_frame_begin_time);
765 blocked_main().last_monotonic_frame_begin_time = 798 blocked_main().last_monotonic_frame_begin_time =
766 begin_main_frame_state->monotonic_frame_begin_time; 799 begin_main_frame_state->monotonic_frame_begin_time;
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 DCHECK(IsMainThread()); 1221 DCHECK(IsMainThread());
1189 layer_tree_host()->DidCompleteSwapBuffers(); 1222 layer_tree_host()->DidCompleteSwapBuffers();
1190 } 1223 }
1191 1224
1192 void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) { 1225 void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) {
1193 TRACE_EVENT0("cc", "ThreadProxy::SetAnimationEvents"); 1226 TRACE_EVENT0("cc", "ThreadProxy::SetAnimationEvents");
1194 DCHECK(IsMainThread()); 1227 DCHECK(IsMainThread());
1195 layer_tree_host()->SetAnimationEvents(events.Pass()); 1228 layer_tree_host()->SetAnimationEvents(events.Pass());
1196 } 1229 }
1197 1230
1198 void ThreadProxy::CreateAndInitializeOutputSurface() {
1199 TRACE_EVENT0("cc", "ThreadProxy::CreateAndInitializeOutputSurface");
1200 DCHECK(IsMainThread());
1201
1202 // Check that output surface has not been recreated by CompositeAndReadback
1203 // after this task is posted but before it is run.
1204 bool has_initialized_output_surface = true;
1205 {
1206 CompletionEvent completion;
1207 Proxy::ImplThreadTaskRunner()->PostTask(
1208 FROM_HERE,
1209 base::Bind(&ThreadProxy::HasInitializedOutputSurfaceOnImplThread,
1210 impl_thread_weak_ptr_,
1211 &completion,
1212 &has_initialized_output_surface));
1213 completion.Wait();
1214 }
1215 if (has_initialized_output_surface)
1216 return;
1217
1218 layer_tree_host()->DidLoseOutputSurface();
1219 main().output_surface_creation_callback.Reset(
1220 base::Bind(&ThreadProxy::DoCreateAndInitializeOutputSurface,
1221 base::Unretained(this)));
1222 main().output_surface_creation_callback.callback().Run();
1223 }
1224
1225 void ThreadProxy::HasInitializedOutputSurfaceOnImplThread(
1226 CompletionEvent* completion,
1227 bool* has_initialized_output_surface) {
1228 DCHECK(IsImplThread());
1229 *has_initialized_output_surface =
1230 impl().scheduler->HasInitializedOutputSurface();
1231 completion->Signal();
1232 }
1233
1234 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { 1231 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
1235 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread"); 1232 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
1236 DCHECK(IsImplThread()); 1233 DCHECK(IsImplThread());
1237 impl().layer_tree_host_impl = 1234 impl().layer_tree_host_impl =
1238 layer_tree_host()->CreateLayerTreeHostImpl(this); 1235 layer_tree_host()->CreateLayerTreeHostImpl(this);
1239 const LayerTreeSettings& settings = layer_tree_host()->settings(); 1236 const LayerTreeSettings& settings = layer_tree_host()->settings();
1240 SchedulerSettings scheduler_settings; 1237 SchedulerSettings scheduler_settings;
1241 scheduler_settings.begin_frame_scheduling_enabled = 1238 scheduler_settings.begin_frame_scheduling_enabled =
1242 settings.begin_frame_scheduling_enabled; 1239 settings.begin_frame_scheduling_enabled;
1243 scheduler_settings.main_frame_before_draw_enabled = 1240 scheduler_settings.main_frame_before_draw_enabled =
(...skipping 12 matching lines...) Expand all
1256 impl().scheduler = Scheduler::Create(this, 1253 impl().scheduler = Scheduler::Create(this,
1257 scheduler_settings, 1254 scheduler_settings,
1258 impl().layer_tree_host_id, 1255 impl().layer_tree_host_id,
1259 ImplThreadTaskRunner()); 1256 ImplThreadTaskRunner());
1260 impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible()); 1257 impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible());
1261 1258
1262 impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr(); 1259 impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr();
1263 completion->Signal(); 1260 completion->Signal();
1264 } 1261 }
1265 1262
1263 void ThreadProxy::DeleteContentsTexturesOnImplThread(
1264 CompletionEvent* completion) {
1265 TRACE_EVENT0("cc", "ThreadProxy::DeleteContentsTexturesOnImplThread");
1266 DCHECK(IsImplThread());
1267 DCHECK(IsMainThreadBlocked());
1268 layer_tree_host()->DeleteContentsTexturesOnImplThread(
1269 impl().layer_tree_host_impl->resource_provider());
1270 completion->Signal();
1271 }
1272
1266 void ThreadProxy::InitializeOutputSurfaceOnImplThread( 1273 void ThreadProxy::InitializeOutputSurfaceOnImplThread(
1267 CompletionEvent* completion, 1274 scoped_ptr<OutputSurface> output_surface) {
1268 scoped_ptr<OutputSurface> output_surface,
1269 bool* success,
1270 RendererCapabilities* capabilities) {
1271 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread"); 1275 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
1272 DCHECK(IsImplThread()); 1276 DCHECK(IsImplThread());
1273 DCHECK(IsMainThreadBlocked());
1274 DCHECK(success);
1275 DCHECK(capabilities);
1276 1277
1277 layer_tree_host()->DeleteContentsTexturesOnImplThread( 1278 LayerTreeHostImpl* host_impl = impl().layer_tree_host_impl.get();
1278 impl().layer_tree_host_impl->resource_provider()); 1279 bool success = host_impl->InitializeRenderer(output_surface.Pass());
1279 1280 RendererCapabilities capabilities;
1280 *success = 1281 if (success) {
1281 impl().layer_tree_host_impl->InitializeRenderer(output_surface.Pass()); 1282 capabilities =
1282 1283 host_impl->GetRendererCapabilities().MainThreadCapabilities();
1283 if (*success) {
1284 *capabilities = impl()
1285 .layer_tree_host_impl->GetRendererCapabilities()
1286 .MainThreadCapabilities();
1287 impl().scheduler->DidCreateAndInitializeOutputSurface();
1288 } 1284 }
1289 1285
1290 completion->Signal(); 1286 Proxy::MainThreadTaskRunner()->PostTask(
1287 FROM_HERE,
1288 base::Bind(&ThreadProxy::DidInitializeOutputSurface,
1289 main_thread_weak_ptr_,
1290 success,
1291 capabilities));
1292
1293 if (success)
1294 impl().scheduler->DidCreateAndInitializeOutputSurface();
1291 } 1295 }
1292 1296
1293 void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) { 1297 void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) {
1294 TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread"); 1298 TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread");
1295 DCHECK(IsImplThread()); 1299 DCHECK(IsImplThread());
1296 if (impl().layer_tree_host_impl->resource_provider()) 1300 if (impl().layer_tree_host_impl->resource_provider())
1297 impl().layer_tree_host_impl->resource_provider()->Finish(); 1301 impl().layer_tree_host_impl->resource_provider()->Finish();
1298 completion->Signal(); 1302 completion->Signal();
1299 } 1303 }
1300 1304
1301 void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) { 1305 void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
1302 TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread"); 1306 TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
1303 DCHECK(IsImplThread()); 1307 DCHECK(IsImplThread());
1308 DCHECK(IsMainThreadBlocked());
1304 layer_tree_host()->DeleteContentsTexturesOnImplThread( 1309 layer_tree_host()->DeleteContentsTexturesOnImplThread(
1305 impl().layer_tree_host_impl->resource_provider()); 1310 impl().layer_tree_host_impl->resource_provider());
1306 impl().current_resource_update_controller.reset(); 1311 impl().current_resource_update_controller.reset();
1307 impl().layer_tree_host_impl->SetNeedsBeginFrame(false); 1312 impl().layer_tree_host_impl->SetNeedsBeginFrame(false);
1308 impl().scheduler.reset(); 1313 impl().scheduler.reset();
1309 impl().layer_tree_host_impl.reset(); 1314 impl().layer_tree_host_impl.reset();
1310 impl().weak_factory.InvalidateWeakPtrs(); 1315 impl().weak_factory.InvalidateWeakPtrs();
1311 impl().contents_texture_manager = NULL; 1316 impl().contents_texture_manager = NULL;
1312 completion->Signal(); 1317 completion->Signal();
1313 } 1318 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 1471
1467 impl().timing_history.DidActivatePendingTree(); 1472 impl().timing_history.DidActivatePendingTree();
1468 } 1473 }
1469 1474
1470 void ThreadProxy::DidManageTiles() { 1475 void ThreadProxy::DidManageTiles() {
1471 DCHECK(IsImplThread()); 1476 DCHECK(IsImplThread());
1472 impl().scheduler->DidManageTiles(); 1477 impl().scheduler->DidManageTiles();
1473 } 1478 }
1474 1479
1475 } // namespace cc 1480 } // 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