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

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

Issue 23796002: cc: Implement deadine scheduling disabled by default (Closed) Base URL: http://git.chromium.org/chromium/src.git@schedReadback4
Patch Set: Fix context lost race conditions 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
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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 created_offscreen_context_provider_(false), 73 created_offscreen_context_provider_(false),
74 layer_tree_host_(layer_tree_host), 74 layer_tree_host_(layer_tree_host),
75 started_(false), 75 started_(false),
76 textures_acquired_(true), 76 textures_acquired_(true),
77 in_composite_and_readback_(false), 77 in_composite_and_readback_(false),
78 manage_tiles_pending_(false), 78 manage_tiles_pending_(false),
79 commit_waits_for_activation_(false), 79 commit_waits_for_activation_(false),
80 inside_commit_(false), 80 inside_commit_(false),
81 weak_factory_on_impl_thread_(this), 81 weak_factory_on_impl_thread_(this),
82 weak_factory_(this), 82 weak_factory_(this),
83 frame_did_draw_(false),
83 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_(NULL), 84 begin_frame_sent_to_main_thread_completion_event_on_impl_thread_(NULL),
84 readback_request_on_impl_thread_(NULL), 85 readback_request_on_impl_thread_(NULL),
85 commit_completion_event_on_impl_thread_(NULL), 86 commit_completion_event_on_impl_thread_(NULL),
86 completion_event_for_commit_held_on_tree_activation_(NULL), 87 completion_event_for_commit_held_on_tree_activation_(NULL),
87 texture_acquisition_completion_event_on_impl_thread_(NULL), 88 texture_acquisition_completion_event_on_impl_thread_(NULL),
88 next_frame_is_newly_committed_frame_on_impl_thread_(false), 89 next_frame_is_newly_committed_frame_on_impl_thread_(false),
89 throttle_frame_production_( 90 throttle_frame_production_(
90 layer_tree_host->settings().throttle_frame_production), 91 layer_tree_host->settings().throttle_frame_production),
91 begin_frame_scheduling_enabled_( 92 begin_frame_scheduling_enabled_(
92 layer_tree_host->settings().begin_frame_scheduling_enabled), 93 layer_tree_host->settings().begin_frame_scheduling_enabled),
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 Proxy::MainThreadTaskRunner()->PostTask( 391 Proxy::MainThreadTaskRunner()->PostTask(
391 FROM_HERE, 392 FROM_HERE,
392 base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_)); 393 base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_));
393 } 394 }
394 395
395 void ThreadProxy::SetNeedsBeginFrameOnImplThread(bool enable) { 396 void ThreadProxy::SetNeedsBeginFrameOnImplThread(bool enable) {
396 DCHECK(IsImplThread()); 397 DCHECK(IsImplThread());
397 TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginFrameOnImplThread", 398 TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginFrameOnImplThread",
398 "enable", enable); 399 "enable", enable);
399 layer_tree_host_impl_->SetNeedsBeginFrame(enable); 400 layer_tree_host_impl_->SetNeedsBeginFrame(enable);
401 UpdateBackgroundAnimateTicking();
400 } 402 }
401 403
402 void ThreadProxy::BeginFrameOnImplThread(const BeginFrameArgs& args) { 404 void ThreadProxy::BeginFrameOnImplThread(const BeginFrameArgs& args) {
403 DCHECK(IsImplThread()); 405 DCHECK(IsImplThread());
404 TRACE_EVENT0("cc", "ThreadProxy::BeginFrameOnImplThread"); 406 TRACE_EVENT0("cc", "ThreadProxy::BeginFrameOnImplThread");
407
408 base::TimeTicks monotonic_time =
409 layer_tree_host_impl_->CurrentFrameTimeTicks();
410 base::Time wall_clock_time = layer_tree_host_impl_->CurrentFrameTime();
411 if (layer_tree_host_impl_->active_tree()->root_layer())
412 layer_tree_host_impl_->Animate(monotonic_time, wall_clock_time);
413
414 // Reinitialize for the current frame.
415 frame_did_draw_ = false;
416
405 scheduler_on_impl_thread_->BeginFrame(args); 417 scheduler_on_impl_thread_->BeginFrame(args);
406 } 418 }
407 419
420 void ThreadProxy::DidBeginFrameDeadlineOnImplThread() {
421 // Do not start animations if we skip drawing the frame to avoid
422 // checkerboarding.
423 if (layer_tree_host_impl_->active_tree()->root_layer()) {
424 layer_tree_host_impl_->UpdateAnimationState(
425 frame_did_draw_ || !layer_tree_host_impl_->CanDraw());
426 }
427 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
428 }
429
408 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) { 430 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
409 DCHECK(IsImplThread()); 431 DCHECK(IsImplThread());
410 TRACE_EVENT1( 432 TRACE_EVENT1(
411 "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); 433 "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
412 scheduler_on_impl_thread_->SetCanDraw(can_draw); 434 scheduler_on_impl_thread_->SetCanDraw(can_draw);
413 UpdateBackgroundAnimateTicking(); 435 UpdateBackgroundAnimateTicking();
414 } 436 }
415 437
416 void ThreadProxy::NotifyReadyToActivate() { 438 void ThreadProxy::NotifyReadyToActivate() {
417 TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate"); 439 TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate");
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 commit_completion_event_on_impl_thread_->Signal(); 991 commit_completion_event_on_impl_thread_->Signal();
970 commit_completion_event_on_impl_thread_ = NULL; 992 commit_completion_event_on_impl_thread_ = NULL;
971 } 993 }
972 994
973 commit_waits_for_activation_ = false; 995 commit_waits_for_activation_ = false;
974 996
975 commit_complete_time_ = base::TimeTicks::HighResNow(); 997 commit_complete_time_ = base::TimeTicks::HighResNow();
976 begin_frame_to_commit_duration_history_.InsertSample( 998 begin_frame_to_commit_duration_history_.InsertSample(
977 commit_complete_time_ - begin_frame_sent_to_main_thread_time_); 999 commit_complete_time_ - begin_frame_sent_to_main_thread_time_);
978 1000
1001 // The commit may have added animations, requiring us to start
1002 // background ticking.
1003 UpdateBackgroundAnimateTicking();
1004
979 // SetVisible kicks off the next scheduler action, so this must be last. 1005 // SetVisible kicks off the next scheduler action, so this must be last.
980 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); 1006 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
981 } 1007 }
982 1008
983 void ThreadProxy::ScheduledActionUpdateVisibleTiles() { 1009 void ThreadProxy::ScheduledActionUpdateVisibleTiles() {
984 DCHECK(IsImplThread()); 1010 DCHECK(IsImplThread());
985 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles"); 1011 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles");
986 layer_tree_host_impl_->UpdateVisibleTiles(); 1012 layer_tree_host_impl_->UpdateVisibleTiles();
987 } 1013 }
988 1014
(...skipping 22 matching lines...) Expand all
1011 result.did_readback = false; 1037 result.did_readback = false;
1012 DCHECK(IsImplThread()); 1038 DCHECK(IsImplThread());
1013 DCHECK(layer_tree_host_impl_.get()); 1039 DCHECK(layer_tree_host_impl_.get());
1014 if (!layer_tree_host_impl_) 1040 if (!layer_tree_host_impl_)
1015 return result; 1041 return result;
1016 1042
1017 DCHECK(layer_tree_host_impl_->renderer()); 1043 DCHECK(layer_tree_host_impl_->renderer());
1018 if (!layer_tree_host_impl_->renderer()) 1044 if (!layer_tree_host_impl_->renderer())
1019 return result; 1045 return result;
1020 1046
1021 base::TimeTicks monotonic_time =
1022 layer_tree_host_impl_->CurrentFrameTimeTicks();
1023 base::Time wall_clock_time = layer_tree_host_impl_->CurrentFrameTime();
1024
1025 // TODO(enne): This should probably happen post-animate.
1026 if (layer_tree_host_impl_->pending_tree())
1027 layer_tree_host_impl_->pending_tree()->UpdateDrawProperties();
1028 layer_tree_host_impl_->Animate(monotonic_time, wall_clock_time);
1029 UpdateBackgroundAnimateTicking();
1030
1031 base::TimeTicks start_time = base::TimeTicks::HighResNow(); 1047 base::TimeTicks start_time = base::TimeTicks::HighResNow();
1032 base::TimeDelta draw_duration_estimate = DrawDurationEstimate(); 1048 base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
1033 base::AutoReset<bool> mark_inside(&inside_draw_, true); 1049 base::AutoReset<bool> mark_inside(&inside_draw_, true);
1034 1050
1035 // This method is called on a forced draw, regardless of whether we are able 1051 // This method is called on a forced draw, regardless of whether we are able
1036 // to produce a frame, as the calling site on main thread is blocked until its 1052 // to produce a frame, as the calling site on main thread is blocked until its
1037 // request completes, and we signal completion here. If CanDraw() is false, we 1053 // request completes, and we signal completion here. If CanDraw() is false, we
1038 // will indicate success=false to the caller, but we must still signal 1054 // will indicate success=false to the caller, but we must still signal
1039 // completion to avoid deadlock. 1055 // completion to avoid deadlock.
1040 1056
1041 // We guard PrepareToDraw() with CanDraw() because it always returns a valid 1057 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
1042 // frame, so can only be used when such a frame is possible. Since 1058 // frame, so can only be used when such a frame is possible. Since
1043 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on 1059 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
1044 // CanDraw() as well. 1060 // CanDraw() as well.
1045 1061
1046 // readback_request_on_impl_thread_ may be for the pending tree, do
1047 // not perform the readback unless explicitly requested.
1048 bool drawing_for_readback = 1062 bool drawing_for_readback =
1049 readback_requested && !!readback_request_on_impl_thread_; 1063 readback_requested && !!readback_request_on_impl_thread_;
1050 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels(); 1064 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
1051 1065
1052 LayerTreeHostImpl::FrameData frame; 1066 LayerTreeHostImpl::FrameData frame;
1053 bool draw_frame = false; 1067 bool draw_frame = false;
1054 bool start_ready_animations = true;
1055 1068
1056 if (layer_tree_host_impl_->CanDraw() && 1069 if (layer_tree_host_impl_->CanDraw() &&
1057 (!drawing_for_readback || can_do_readback)) { 1070 (!drawing_for_readback || can_do_readback)) {
1058 // If it is for a readback, make sure we draw the portion being read back. 1071 // If it is for a readback, make sure we draw the portion being read back.
1059 gfx::Rect readback_rect; 1072 gfx::Rect readback_rect;
1060 if (drawing_for_readback) 1073 if (drawing_for_readback)
1061 readback_rect = readback_request_on_impl_thread_->rect; 1074 readback_rect = readback_request_on_impl_thread_->rect;
1062 1075
1063 // Do not start animations if we skip drawing the frame to avoid
1064 // checkerboarding.
1065 if (layer_tree_host_impl_->PrepareToDraw(&frame, readback_rect) || 1076 if (layer_tree_host_impl_->PrepareToDraw(&frame, readback_rect) ||
1066 forced_draw) 1077 forced_draw)
1067 draw_frame = true; 1078 draw_frame = true;
1068 else
1069 start_ready_animations = false;
1070 } 1079 }
1071 1080
1081 frame_did_draw_ = draw_frame;
1082
1072 if (draw_frame) { 1083 if (draw_frame) {
1073 layer_tree_host_impl_->DrawLayers( 1084 layer_tree_host_impl_->DrawLayers(
1074 &frame, 1085 &frame,
1075 scheduler_on_impl_thread_->LastBeginFrameOnImplThreadTime()); 1086 scheduler_on_impl_thread_->LastBeginFrameOnImplThreadTime());
1076 result.did_draw = true; 1087 result.did_draw = true;
1077 } 1088 }
1078 layer_tree_host_impl_->DidDrawAllLayers(frame); 1089 layer_tree_host_impl_->DidDrawAllLayers(frame);
1079 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
1080 1090
1081 // Check for a pending CompositeAndReadback. 1091 // Check for a pending CompositeAndReadback.
1082 if (drawing_for_readback) { 1092 if (drawing_for_readback) {
1083 DCHECK(!swap_requested); 1093 DCHECK(!swap_requested);
1084 result.did_readback = false; 1094 result.did_readback = false;
1085 if (draw_frame && !layer_tree_host_impl_->IsContextLost()) { 1095 if (draw_frame && !layer_tree_host_impl_->IsContextLost()) {
1086 layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels, 1096 layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels,
1087 readback_request_on_impl_thread_->rect); 1097 readback_request_on_impl_thread_->rect);
1088 result.did_readback = true; 1098 result.did_readback = true;
1089 } 1099 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndReadback"); 1219 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndReadback");
1210 bool forced_draw = true; 1220 bool forced_draw = true;
1211 bool swap_requested = false; 1221 bool swap_requested = false;
1212 bool readback_requested = true; 1222 bool readback_requested = true;
1213 return DrawSwapReadbackInternal( 1223 return DrawSwapReadbackInternal(
1214 forced_draw, swap_requested, readback_requested); 1224 forced_draw, swap_requested, readback_requested);
1215 } 1225 }
1216 1226
1217 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { 1227 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
1218 if (current_resource_update_controller_on_impl_thread_) 1228 if (current_resource_update_controller_on_impl_thread_)
1219 current_resource_update_controller_on_impl_thread_ 1229 current_resource_update_controller_on_impl_thread_->PerformMoreUpdates(
1220 ->PerformMoreUpdates(time); 1230 time);
1221 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
1222 } 1231 }
1223 1232
1224 base::TimeDelta ThreadProxy::DrawDurationEstimate() { 1233 base::TimeDelta ThreadProxy::DrawDurationEstimate() {
1225 base::TimeDelta historical_estimate = 1234 base::TimeDelta historical_estimate =
1226 draw_duration_history_.Percentile(kDrawDurationEstimationPercentile); 1235 draw_duration_history_.Percentile(kDrawDurationEstimationPercentile);
1227 base::TimeDelta padding = base::TimeDelta::FromMicroseconds( 1236 base::TimeDelta padding = base::TimeDelta::FromMicroseconds(
1228 kDrawDurationEstimatePaddingInMicroseconds); 1237 kDrawDurationEstimatePaddingInMicroseconds);
1229 return historical_estimate + padding; 1238 return historical_estimate + padding;
1230 } 1239 }
1231 1240
1232 base::TimeDelta ThreadProxy::BeginFrameToCommitDurationEstimate() { 1241 base::TimeDelta ThreadProxy::BeginFrameToCommitDurationEstimate() {
1233 return begin_frame_to_commit_duration_history_.Percentile( 1242 return begin_frame_to_commit_duration_history_.Percentile(
1234 kCommitAndActivationDurationEstimationPercentile); 1243 kCommitAndActivationDurationEstimationPercentile);
1235 } 1244 }
1236 1245
1237 base::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() { 1246 base::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() {
1238 return commit_to_activate_duration_history_.Percentile( 1247 return commit_to_activate_duration_history_.Percentile(
1239 kCommitAndActivationDurationEstimationPercentile); 1248 kCommitAndActivationDurationEstimationPercentile);
1240 } 1249 }
1241 1250
1251 void ThreadProxy::PostBeginFrameDeadline(const base::Closure& closure,
1252 base::TimeTicks deadline) {
1253 base::TimeDelta delta = deadline - base::TimeTicks::Now();
1254 if (delta <= base::TimeDelta())
1255 delta = base::TimeDelta();
1256 Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta);
1257 }
1258
1242 void ThreadProxy::ReadyToFinalizeTextureUpdates() { 1259 void ThreadProxy::ReadyToFinalizeTextureUpdates() {
1243 DCHECK(IsImplThread()); 1260 DCHECK(IsImplThread());
1244 scheduler_on_impl_thread_->FinishCommit(); 1261 scheduler_on_impl_thread_->FinishCommit();
1245 } 1262 }
1246 1263
1247 void ThreadProxy::DidCommitAndDrawFrame() { 1264 void ThreadProxy::DidCommitAndDrawFrame() {
1248 DCHECK(IsMainThread()); 1265 DCHECK(IsMainThread());
1249 if (!layer_tree_host_) 1266 if (!layer_tree_host_)
1250 return; 1267 return;
1251 layer_tree_host_->DidCommitAndDrawFrame(); 1268 layer_tree_host_->DidCommitAndDrawFrame();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 scheduler_on_impl_thread_->HasInitializedOutputSurface(); 1319 scheduler_on_impl_thread_->HasInitializedOutputSurface();
1303 completion->Signal(); 1320 completion->Signal();
1304 } 1321 }
1305 1322
1306 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { 1323 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
1307 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread"); 1324 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
1308 DCHECK(IsImplThread()); 1325 DCHECK(IsImplThread());
1309 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); 1326 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
1310 const LayerTreeSettings& settings = layer_tree_host_->settings(); 1327 const LayerTreeSettings& settings = layer_tree_host_->settings();
1311 SchedulerSettings scheduler_settings; 1328 SchedulerSettings scheduler_settings;
1329 scheduler_settings.deadline_scheduling_enabled =
1330 settings.deadline_scheduling_enabled;
1312 scheduler_settings.impl_side_painting = settings.impl_side_painting; 1331 scheduler_settings.impl_side_painting = settings.impl_side_painting;
1313 scheduler_settings.timeout_and_draw_when_animation_checkerboards = 1332 scheduler_settings.timeout_and_draw_when_animation_checkerboards =
1314 settings.timeout_and_draw_when_animation_checkerboards; 1333 settings.timeout_and_draw_when_animation_checkerboards;
1315 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = 1334 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
1316 settings.maximum_number_of_failed_draws_before_draw_is_forced_; 1335 settings.maximum_number_of_failed_draws_before_draw_is_forced_;
1317 scheduler_settings.using_synchronous_renderer_compositor = 1336 scheduler_settings.using_synchronous_renderer_compositor =
1318 settings.using_synchronous_renderer_compositor; 1337 settings.using_synchronous_renderer_compositor;
1319 scheduler_settings.throttle_frame_production = 1338 scheduler_settings.throttle_frame_production =
1320 settings.throttle_frame_production; 1339 settings.throttle_frame_production;
1340 scheduler_settings.use_begin_frame_workaround_for_crbug_249806 = true;
1321 scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings); 1341 scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings);
1322 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); 1342 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
1323 1343
1324 impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr(); 1344 impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr();
1325 completion->Signal(); 1345 completion->Signal();
1326 } 1346 }
1327 1347
1328 void ThreadProxy::InitializeOutputSurfaceOnImplThread( 1348 void ThreadProxy::InitializeOutputSurfaceOnImplThread(
1329 CompletionEvent* completion, 1349 CompletionEvent* completion,
1330 scoped_ptr<OutputSurface> output_surface, 1350 scoped_ptr<OutputSurface> output_surface,
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 completion_event_for_commit_held_on_tree_activation_ = NULL; 1570 completion_event_for_commit_held_on_tree_activation_ = NULL;
1551 } 1571 }
1552 1572
1553 UpdateBackgroundAnimateTicking(); 1573 UpdateBackgroundAnimateTicking();
1554 1574
1555 commit_to_activate_duration_history_.InsertSample( 1575 commit_to_activate_duration_history_.InsertSample(
1556 base::TimeTicks::HighResNow() - commit_complete_time_); 1576 base::TimeTicks::HighResNow() - commit_complete_time_);
1557 } 1577 }
1558 1578
1559 } // namespace cc 1579 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698