Chromium Code Reviews| Index: cc/surfaces/display_scheduler.cc |
| diff --git a/cc/surfaces/display_scheduler.cc b/cc/surfaces/display_scheduler.cc |
| index 98f52e52b60ca4c53a846032eb57eaf77017ef1e..61bdecb0bbacc0f09fedee76ec5bd2a35d513106 100644 |
| --- a/cc/surfaces/display_scheduler.cc |
| +++ b/cc/surfaces/display_scheduler.cc |
| @@ -28,7 +28,8 @@ DisplayScheduler::DisplayScheduler(DisplaySchedulerClient* client, |
| pending_swaps_(0), |
| max_pending_swaps_(max_pending_swaps), |
| root_surface_damaged_(false), |
| - expect_damage_from_root_surface_(false), |
| + root_surface_active_(false), |
| + current_active_child_surface_ids_index_(0), |
| weak_ptr_factory_(this) { |
| begin_frame_source_->AddObserver(this); |
| begin_frame_deadline_closure_ = base::Bind( |
| @@ -79,10 +80,11 @@ void DisplayScheduler::SurfaceDamaged(SurfaceId surface_id) { |
| root_surface_damaged_ = true; |
| } else { |
| child_surface_ids_damaged_.insert(surface_id); |
| + UpdateFutureActiveChildSurfaceIDs(surface_id); |
|
sunnyps
2015/07/23 21:10:38
nit: Instead of a separate method, just update the
|
| // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts. |
| all_active_child_surfaces_ready_to_draw_ = base::STLIncludes( |
| - child_surface_ids_damaged_, child_surface_ids_to_expect_damage_from_); |
| + child_surface_ids_damaged_, CurrentActiveChildSurfaceIDs()); |
| } |
| begin_frame_source_->SetNeedsBeginFrames(!output_surface_lost_); |
| @@ -105,20 +107,13 @@ void DisplayScheduler::DrawAndSwap() { |
| if (!success) |
| return; |
| - child_surface_ids_to_expect_damage_from_ = |
| - base::STLSetIntersection<std::vector<SurfaceId>>( |
| - child_surface_ids_damaged_, child_surface_ids_damaged_prev_); |
| - |
| - child_surface_ids_damaged_prev_.swap(child_surface_ids_damaged_); |
| - child_surface_ids_damaged_.clear(); |
| + UpdateActiveSurfaces(); |
|
sunnyps
2015/07/23 21:10:38
nit: No need for a separate method here. It's easi
|
| + // Update state regarding what needs to be drawn. |
| needs_draw_ = false; |
| entire_display_damaged_ = false; |
| - all_active_child_surfaces_ready_to_draw_ = |
| - child_surface_ids_to_expect_damage_from_.empty(); |
| - |
| - expect_damage_from_root_surface_ = root_surface_damaged_; |
| root_surface_damaged_ = false; |
| + child_surface_ids_damaged_.clear(); |
| } |
| bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { |
| @@ -174,8 +169,7 @@ base::TimeTicks DisplayScheduler::DesiredBeginFrameDeadlineTime() { |
| return base::TimeTicks(); |
| } |
| - bool root_ready_to_draw = |
| - !expect_damage_from_root_surface_ || root_surface_damaged_; |
| + bool root_ready_to_draw = !root_surface_active_ || root_surface_damaged_; |
| if (all_active_child_surfaces_ready_to_draw_ && root_ready_to_draw) { |
| TRACE_EVENT_INSTANT0("cc", "All active surfaces ready", |
| @@ -187,8 +181,7 @@ base::TimeTicks DisplayScheduler::DesiredBeginFrameDeadlineTime() { |
| // in case our expect_damage_from_root_surface heuristic is incorrect. |
| // TODO(mithro): Replace this with SetNeedsBeginFrame and SwapAbort |
| // logic. |
| - if (all_active_child_surfaces_ready_to_draw_ && |
| - expect_damage_from_root_surface_) { |
| + if (all_active_child_surfaces_ready_to_draw_ && root_surface_active_) { |
|
sunnyps
2015/07/23 21:10:38
nit: Rename to child_surfaces_ready_to_draw_
brianderson
2015/07/23 22:21:48
Done.
|
| TRACE_EVENT_INSTANT0("cc", "Waiting for damage from root surface", |
| TRACE_EVENT_SCOPE_THREAD); |
| // This adjusts the deadline by DefaultEstimatedParentDrawTime for |
| @@ -249,17 +242,28 @@ void DisplayScheduler::AttemptDrawAndSwap() { |
| begin_frame_deadline_task_.Cancel(); |
| begin_frame_deadline_task_time_ = base::TimeTicks(); |
| - if (needs_draw_ && !output_surface_lost_) { |
| - if (pending_swaps_ < max_pending_swaps_ && !root_surface_resources_locked_) |
| - DrawAndSwap(); |
| + bool stay_active = |
| + !output_surface_lost_ && (needs_draw_ || root_surface_active_ || |
| + !CurrentActiveChildSurfaceIDs().empty()); |
| + |
|
sunnyps
2015/07/23 21:10:38
nit: This could be better structured as:
if (!sta
brianderson
2015/07/23 22:21:48
Done.
|
| + if (stay_active) { |
| + if (needs_draw_) { |
| + if (pending_swaps_ < max_pending_swaps_ && |
| + !root_surface_resources_locked_) |
| + DrawAndSwap(); |
| + } else { |
| + // In order to properly go idle, make sure to update expectations that |
| + // will cause |stay_active| to go false even if we have nothing to draw. |
| + // Verify no child surfaces are currently damaged, since |
| + // UpdateSurfaceDamageExpectatations will clear that list. |
| + DCHECK(child_surface_ids_damaged_.empty()); |
| + DCHECK(!entire_display_damaged_); |
| + DCHECK(!root_surface_damaged_); |
| + UpdateActiveSurfaces(); |
| + } |
| } else { |
| // We are going idle, so reset expectations. |
| - child_surface_ids_to_expect_damage_from_.clear(); |
| - child_surface_ids_damaged_prev_.clear(); |
| - child_surface_ids_damaged_.clear(); |
| - all_active_child_surfaces_ready_to_draw_ = true; |
| - expect_damage_from_root_surface_ = false; |
| - |
| + ClearActiveSurfaces(); |
|
sunnyps
2015/07/23 21:10:38
nit: Probably doesn't need a separate method.
|
| begin_frame_source_->SetNeedsBeginFrames(false); |
| } |
| } |
| @@ -284,4 +288,36 @@ void DisplayScheduler::DidSwapBuffersComplete() { |
| ScheduleBeginFrameDeadline(); |
| } |
| +std::set<SurfaceId>& DisplayScheduler::CurrentActiveChildSurfaceIDs() { |
|
sunnyps
2015/07/23 21:10:38
nit: inline this
|
| + return active_child_surface_ids_[current_active_child_surface_ids_index_]; |
| +} |
| + |
| +void DisplayScheduler::UpdateFutureActiveChildSurfaceIDs(SurfaceId surface_id) { |
| + for (int i = 0; i < kActiveChildSurfaceIdsSize; i++) |
| + active_child_surface_ids_[i].insert(surface_id); |
| +} |
| + |
| +void DisplayScheduler::ClearActiveSurfaces() { |
| + root_surface_active_ = false; |
| + |
| + current_active_child_surface_ids_index_ = 0; |
| + for (int i = 0; i < kActiveChildSurfaceIdsSize; i++) |
| + active_child_surface_ids_[i].clear(); |
| + |
| + all_active_child_surfaces_ready_to_draw_ = true; |
| +} |
| + |
| +void DisplayScheduler::UpdateActiveSurfaces() { |
| + root_surface_active_ = root_surface_damaged_; |
| + |
| + CurrentActiveChildSurfaceIDs().clear(); |
| + |
| + current_active_child_surface_ids_index_++; |
|
sunnyps
2015/07/23 21:10:38
nit: index = (index + 1) % N
brianderson
2015/07/23 22:21:49
Done.
|
| + if (current_active_child_surface_ids_index_ >= kActiveChildSurfaceIdsSize) |
| + current_active_child_surface_ids_index_ = 0; |
| + |
| + all_active_child_surfaces_ready_to_draw_ = |
|
sunnyps
2015/07/23 21:10:38
nit: This could be an inline function.
brianderson
2015/07/23 22:21:48
My goal in writing all the helper methods was to p
|
| + CurrentActiveChildSurfaceIDs().empty(); |
| +} |
| + |
| } // namespace cc |