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

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: . Created 6 years, 7 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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 void ThreadProxy::UpdateBackgroundAnimateTicking() { 187 void ThreadProxy::UpdateBackgroundAnimateTicking() {
188 bool should_background_tick = 188 bool should_background_tick =
189 !impl().scheduler->WillDrawIfNeeded() && 189 !impl().scheduler->WillDrawIfNeeded() &&
190 impl().layer_tree_host_impl->active_tree()->root_layer(); 190 impl().layer_tree_host_impl->active_tree()->root_layer();
191 impl().layer_tree_host_impl->UpdateBackgroundAnimateTicking( 191 impl().layer_tree_host_impl->UpdateBackgroundAnimateTicking(
192 should_background_tick); 192 should_background_tick);
193 if (should_background_tick) 193 if (should_background_tick)
194 impl().animations_frozen_until_next_draw = false; 194 impl().animations_frozen_until_next_draw = false;
195 } 195 }
196 196
197 void ThreadProxy::DoCreateAndInitializeOutputSurface() { 197 void ThreadProxy::DidLoseOutputSurface() {
198 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurface");
199 DCHECK(IsMainThread());
200 layer_tree_host()->DidLoseOutputSurface();
201
202 {
203 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
204
205 // Return lost resources to their owners immediately.
206 BlockingTaskRunner::CapturePostTasks blocked;
207
208 CompletionEvent completion;
209 Proxy::ImplThreadTaskRunner()->PostTask(
210 FROM_HERE,
211 base::Bind(&ThreadProxy::DeleteContentsTexturesOnImplThread,
212 impl_thread_weak_ptr_,
213 &completion));
214 completion.Wait();
215 }
216 }
217
218 void ThreadProxy::CreateAndInitializeOutputSurface() {
198 TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface"); 219 TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface");
199 DCHECK(IsMainThread()); 220 DCHECK(IsMainThread());
200 221
201 scoped_ptr<OutputSurface> output_surface = 222 scoped_ptr<OutputSurface> output_surface =
202 layer_tree_host()->CreateOutputSurface(); 223 layer_tree_host()->CreateOutputSurface();
203 224
204 RendererCapabilities capabilities; 225 if (output_surface) {
205 bool success = !!output_surface;
206 if (success) {
207 // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results
208 // of that call are pushed into the success and capabilities local
209 // variables.
210 CompletionEvent completion;
211 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
212
213 Proxy::ImplThreadTaskRunner()->PostTask( 226 Proxy::ImplThreadTaskRunner()->PostTask(
214 FROM_HERE, 227 FROM_HERE,
215 base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread, 228 base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
216 impl_thread_weak_ptr_, 229 impl_thread_weak_ptr_,
217 &completion, 230 base::Passed(&output_surface)));
218 base::Passed(&output_surface), 231 return;
219 &success,
220 &capabilities));
221 completion.Wait();
222 } 232 }
233
234 DidInitializeOutputSurface(false, RendererCapabilities());
235 }
236
237 void ThreadProxy::DidInitializeOutputSurface(
238 bool success,
239 const RendererCapabilities& capabilities) {
240 TRACE_EVENT0("cc", "ThreadProxy::DidInitializeOutputSurface");
241 DCHECK(IsMainThread());
223 main().renderer_capabilities_main_thread_copy = capabilities; 242 main().renderer_capabilities_main_thread_copy = capabilities;
224 layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success); 243 layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
225 244
226 if (success) { 245 if (!success) {
227 main().output_surface_creation_callback.Cancel();
228 } else if (!main().output_surface_creation_callback.IsCancelled()) {
229 Proxy::MainThreadTaskRunner()->PostTask( 246 Proxy::MainThreadTaskRunner()->PostTask(
230 FROM_HERE, main().output_surface_creation_callback.callback()); 247 FROM_HERE,
248 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
enne (OOO) 2014/05/16 22:37:29 How is this not an infinite loop during failure?
danakj 2014/05/16 22:45:29 After 5 failures, LayerTreeHost will LOG(FATAL) in
enne (OOO) 2014/05/16 22:46:31 And this will just keep posting tasks?
danakj 2014/05/16 22:48:40 This calls OnCreateAndInitializeOutputSurfaceAttem
249 main_thread_weak_ptr_));
231 } 250 }
232 } 251 }
233 252
234 void ThreadProxy::SetRendererCapabilitiesMainThreadCopy( 253 void ThreadProxy::SetRendererCapabilitiesMainThreadCopy(
235 const RendererCapabilities& capabilities) { 254 const RendererCapabilities& capabilities) {
236 main().renderer_capabilities_main_thread_copy = capabilities; 255 main().renderer_capabilities_main_thread_copy = capabilities;
237 } 256 }
238 257
239 void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() { 258 void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
240 DCHECK(IsMainThread()); 259 DCHECK(IsMainThread());
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread"); 320 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
302 DCHECK(IsImplThread()); 321 DCHECK(IsImplThread());
303 CheckOutputSurfaceStatusOnImplThread(); 322 CheckOutputSurfaceStatusOnImplThread();
304 } 323 }
305 324
306 void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() { 325 void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() {
307 TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread"); 326 TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread");
308 DCHECK(IsImplThread()); 327 DCHECK(IsImplThread());
309 if (!impl().layer_tree_host_impl->IsContextLost()) 328 if (!impl().layer_tree_host_impl->IsContextLost())
310 return; 329 return;
330 Proxy::MainThreadTaskRunner()->PostTask(
331 FROM_HERE,
332 base::Bind(&ThreadProxy::DidLoseOutputSurface, main_thread_weak_ptr_));
311 impl().scheduler->DidLoseOutputSurface(); 333 impl().scheduler->DidLoseOutputSurface();
312 } 334 }
313 335
314 void ThreadProxy::CommitVSyncParameters(base::TimeTicks timebase, 336 void ThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
315 base::TimeDelta interval) { 337 base::TimeDelta interval) {
316 impl().scheduler->CommitVSyncParameters(timebase, interval); 338 impl().scheduler->CommitVSyncParameters(timebase, interval);
317 } 339 }
318 340
319 void ThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { 341 void ThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
320 impl().scheduler->SetEstimatedParentDrawTime(draw_time); 342 impl().scheduler->SetEstimatedParentDrawTime(draw_time);
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 DCHECK(IsMainThread()); 1212 DCHECK(IsMainThread());
1191 layer_tree_host()->DidCompleteSwapBuffers(); 1213 layer_tree_host()->DidCompleteSwapBuffers();
1192 } 1214 }
1193 1215
1194 void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) { 1216 void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) {
1195 TRACE_EVENT0("cc", "ThreadProxy::SetAnimationEvents"); 1217 TRACE_EVENT0("cc", "ThreadProxy::SetAnimationEvents");
1196 DCHECK(IsMainThread()); 1218 DCHECK(IsMainThread());
1197 layer_tree_host()->SetAnimationEvents(events.Pass()); 1219 layer_tree_host()->SetAnimationEvents(events.Pass());
1198 } 1220 }
1199 1221
1200 void ThreadProxy::CreateAndInitializeOutputSurface() {
1201 TRACE_EVENT0("cc", "ThreadProxy::CreateAndInitializeOutputSurface");
1202 DCHECK(IsMainThread());
1203
1204 // Check that output surface has not been recreated by CompositeAndReadback
1205 // after this task is posted but before it is run.
1206 bool has_initialized_output_surface = true;
1207 {
1208 CompletionEvent completion;
1209 Proxy::ImplThreadTaskRunner()->PostTask(
1210 FROM_HERE,
1211 base::Bind(&ThreadProxy::HasInitializedOutputSurfaceOnImplThread,
1212 impl_thread_weak_ptr_,
1213 &completion,
1214 &has_initialized_output_surface));
1215 completion.Wait();
1216 }
1217 if (has_initialized_output_surface)
1218 return;
1219
1220 layer_tree_host()->DidLoseOutputSurface();
1221 main().output_surface_creation_callback.Reset(
1222 base::Bind(&ThreadProxy::DoCreateAndInitializeOutputSurface,
1223 base::Unretained(this)));
1224 main().output_surface_creation_callback.callback().Run();
1225 }
1226
1227 void ThreadProxy::HasInitializedOutputSurfaceOnImplThread(
1228 CompletionEvent* completion,
1229 bool* has_initialized_output_surface) {
1230 DCHECK(IsImplThread());
1231 *has_initialized_output_surface =
1232 impl().scheduler->HasInitializedOutputSurface();
1233 completion->Signal();
1234 }
1235
1236 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { 1222 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
1237 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread"); 1223 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
1238 DCHECK(IsImplThread()); 1224 DCHECK(IsImplThread());
1239 impl().layer_tree_host_impl = 1225 impl().layer_tree_host_impl =
1240 layer_tree_host()->CreateLayerTreeHostImpl(this); 1226 layer_tree_host()->CreateLayerTreeHostImpl(this);
1241 const LayerTreeSettings& settings = layer_tree_host()->settings(); 1227 const LayerTreeSettings& settings = layer_tree_host()->settings();
1242 SchedulerSettings scheduler_settings; 1228 SchedulerSettings scheduler_settings;
1243 scheduler_settings.begin_frame_scheduling_enabled = 1229 scheduler_settings.begin_frame_scheduling_enabled =
1244 settings.begin_frame_scheduling_enabled; 1230 settings.begin_frame_scheduling_enabled;
1245 scheduler_settings.main_frame_before_draw_enabled = 1231 scheduler_settings.main_frame_before_draw_enabled =
(...skipping 12 matching lines...) Expand all
1258 impl().scheduler = Scheduler::Create(this, 1244 impl().scheduler = Scheduler::Create(this,
1259 scheduler_settings, 1245 scheduler_settings,
1260 impl().layer_tree_host_id, 1246 impl().layer_tree_host_id,
1261 ImplThreadTaskRunner()); 1247 ImplThreadTaskRunner());
1262 impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible()); 1248 impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible());
1263 1249
1264 impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr(); 1250 impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr();
1265 completion->Signal(); 1251 completion->Signal();
1266 } 1252 }
1267 1253
1254 void ThreadProxy::DeleteContentsTexturesOnImplThread(
1255 CompletionEvent* completion) {
1256 TRACE_EVENT0("cc", "ThreadProxy::DeleteContentsTexturesOnImplThread");
1257 DCHECK(IsImplThread());
1258 DCHECK(IsMainThreadBlocked());
1259 layer_tree_host()->DeleteContentsTexturesOnImplThread(
1260 impl().layer_tree_host_impl->resource_provider());
1261 completion->Signal();
1262 }
1263
1268 void ThreadProxy::InitializeOutputSurfaceOnImplThread( 1264 void ThreadProxy::InitializeOutputSurfaceOnImplThread(
1269 CompletionEvent* completion, 1265 scoped_ptr<OutputSurface> output_surface) {
1270 scoped_ptr<OutputSurface> output_surface,
1271 bool* success,
1272 RendererCapabilities* capabilities) {
1273 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread"); 1266 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
1274 DCHECK(IsImplThread()); 1267 DCHECK(IsImplThread());
1275 DCHECK(IsMainThreadBlocked());
1276 DCHECK(success);
1277 DCHECK(capabilities);
1278 1268
1279 layer_tree_host()->DeleteContentsTexturesOnImplThread( 1269 LayerTreeHostImpl* host_impl = impl().layer_tree_host_impl.get();
1280 impl().layer_tree_host_impl->resource_provider()); 1270 bool success = host_impl->InitializeRenderer(output_surface.Pass());
1281 1271 RendererCapabilities capabilities;
1282 *success = 1272 if (success) {
1283 impl().layer_tree_host_impl->InitializeRenderer(output_surface.Pass()); 1273 capabilities =
1284 1274 host_impl->GetRendererCapabilities().MainThreadCapabilities();
1285 if (*success) {
1286 *capabilities = impl()
1287 .layer_tree_host_impl->GetRendererCapabilities()
1288 .MainThreadCapabilities();
1289 impl().scheduler->DidCreateAndInitializeOutputSurface();
1290 } 1275 }
1291 1276
1292 completion->Signal(); 1277 Proxy::MainThreadTaskRunner()->PostTask(
1278 FROM_HERE,
1279 base::Bind(&ThreadProxy::DidInitializeOutputSurface,
1280 main_thread_weak_ptr_,
1281 success,
1282 capabilities));
1283
1284 if (success)
1285 impl().scheduler->DidCreateAndInitializeOutputSurface();
1293 } 1286 }
1294 1287
1295 void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) { 1288 void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) {
1296 TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread"); 1289 TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread");
1297 DCHECK(IsImplThread()); 1290 DCHECK(IsImplThread());
1298 if (impl().layer_tree_host_impl->resource_provider()) 1291 if (impl().layer_tree_host_impl->resource_provider())
1299 impl().layer_tree_host_impl->resource_provider()->Finish(); 1292 impl().layer_tree_host_impl->resource_provider()->Finish();
1300 completion->Signal(); 1293 completion->Signal();
1301 } 1294 }
1302 1295
1303 void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) { 1296 void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
1304 TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread"); 1297 TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
1305 DCHECK(IsImplThread()); 1298 DCHECK(IsImplThread());
1299 DCHECK(IsMainThreadBlocked());
1306 layer_tree_host()->DeleteContentsTexturesOnImplThread( 1300 layer_tree_host()->DeleteContentsTexturesOnImplThread(
1307 impl().layer_tree_host_impl->resource_provider()); 1301 impl().layer_tree_host_impl->resource_provider());
1308 impl().current_resource_update_controller.reset(); 1302 impl().current_resource_update_controller.reset();
1309 impl().layer_tree_host_impl->SetNeedsBeginFrame(false); 1303 impl().layer_tree_host_impl->SetNeedsBeginFrame(false);
1310 impl().scheduler.reset(); 1304 impl().scheduler.reset();
1311 impl().layer_tree_host_impl.reset(); 1305 impl().layer_tree_host_impl.reset();
1312 impl().weak_factory.InvalidateWeakPtrs(); 1306 impl().weak_factory.InvalidateWeakPtrs();
1313 impl().contents_texture_manager = NULL; 1307 impl().contents_texture_manager = NULL;
1314 completion->Signal(); 1308 completion->Signal();
1315 } 1309 }
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1498 1492
1499 impl().timing_history.DidActivatePendingTree(); 1493 impl().timing_history.DidActivatePendingTree();
1500 } 1494 }
1501 1495
1502 void ThreadProxy::DidManageTiles() { 1496 void ThreadProxy::DidManageTiles() {
1503 DCHECK(IsImplThread()); 1497 DCHECK(IsImplThread());
1504 impl().scheduler->DidManageTiles(); 1498 impl().scheduler->DidManageTiles();
1505 } 1499 }
1506 1500
1507 } // namespace cc 1501 } // 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