OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/surfaces/display_scheduler.h" | 5 #include "cc/surfaces/display_scheduler.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
11 #include "cc/output/output_surface.h" | 11 #include "cc/output/output_surface.h" |
12 | 12 |
13 namespace cc { | 13 namespace cc { |
14 | 14 |
15 DisplayScheduler::DisplayScheduler(DisplaySchedulerClient* client, | 15 DisplayScheduler::DisplayScheduler(DisplaySchedulerClient* client, |
16 BeginFrameSource* begin_frame_source, | 16 BeginFrameSource* begin_frame_source, |
17 base::SingleThreadTaskRunner* task_runner, | 17 base::SingleThreadTaskRunner* task_runner, |
18 int max_pending_swaps) | 18 int max_pending_swaps) |
19 : client_(client), | 19 : client_(client), |
20 begin_frame_source_(begin_frame_source), | 20 begin_frame_source_(begin_frame_source), |
21 task_runner_(task_runner), | 21 task_runner_(task_runner), |
22 output_surface_lost_(false), | 22 output_surface_lost_(false), |
23 root_surface_resources_locked_(true), | 23 root_surface_resources_locked_(true), |
24 inside_begin_frame_deadline_interval_(false), | 24 inside_begin_frame_deadline_interval_(false), |
25 needs_draw_(false), | 25 needs_draw_(false), |
26 entire_display_damaged_(false), | 26 expecting_root_surface_damage_because_of_resize_(false), |
27 all_active_child_surfaces_ready_to_draw_(false), | 27 all_active_child_surfaces_ready_to_draw_(false), |
28 pending_swaps_(0), | 28 pending_swaps_(0), |
29 max_pending_swaps_(max_pending_swaps), | 29 max_pending_swaps_(max_pending_swaps), |
30 root_surface_damaged_(false), | 30 root_surface_damaged_(false), |
31 expect_damage_from_root_surface_(false), | 31 expect_damage_from_root_surface_(false), |
32 weak_ptr_factory_(this) { | 32 weak_ptr_factory_(this) { |
33 begin_frame_source_->AddObserver(this); | 33 begin_frame_source_->AddObserver(this); |
34 begin_frame_deadline_closure_ = base::Bind( | 34 begin_frame_deadline_closure_ = base::Bind( |
35 &DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr()); | 35 &DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr()); |
36 } | 36 } |
37 | 37 |
38 DisplayScheduler::~DisplayScheduler() { | 38 DisplayScheduler::~DisplayScheduler() { |
39 begin_frame_source_->RemoveObserver(this); | 39 begin_frame_source_->RemoveObserver(this); |
40 } | 40 } |
41 | 41 |
42 // If we try to draw when the root surface resources are locked, the | 42 // If we try to draw when the root surface resources are locked, the |
43 // draw will fail. | 43 // draw will fail. |
44 void DisplayScheduler::SetRootSurfaceResourcesLocked(bool locked) { | 44 void DisplayScheduler::SetRootSurfaceResourcesLocked(bool locked) { |
| 45 TRACE_EVENT1("cc", "DisplayScheduler::SetRootSurfaceResourcesLocked", |
| 46 "locked", locked); |
45 root_surface_resources_locked_ = locked; | 47 root_surface_resources_locked_ = locked; |
46 ScheduleBeginFrameDeadline(); | 48 ScheduleBeginFrameDeadline(); |
47 } | 49 } |
48 | 50 |
49 // This is used to force an immediate swap before a resize. | 51 // This is used to force an immediate swap before a resize. |
50 void DisplayScheduler::ForceImmediateSwapIfPossible() { | 52 void DisplayScheduler::ForceImmediateSwapIfPossible() { |
| 53 TRACE_EVENT0("cc", "DisplayScheduler::ForceImmediateSwapIfPossible"); |
51 bool in_begin = inside_begin_frame_deadline_interval_; | 54 bool in_begin = inside_begin_frame_deadline_interval_; |
52 AttemptDrawAndSwap(); | 55 AttemptDrawAndSwap(); |
53 if (in_begin) | 56 if (in_begin) |
54 begin_frame_source_->DidFinishFrame(0); | 57 begin_frame_source_->DidFinishFrame(0); |
55 } | 58 } |
56 | 59 |
57 // Notification that there was a resize or the root surface changed and | 60 void DisplayScheduler::DisplayResized() { |
58 // that we should just draw immediately. | 61 expecting_root_surface_damage_because_of_resize_ = true; |
59 void DisplayScheduler::EntireDisplayDamaged(SurfaceId root_surface_id) { | 62 expect_damage_from_root_surface_ = true; |
60 TRACE_EVENT0("cc", "DisplayScheduler::EntireDisplayDamaged"); | |
61 needs_draw_ = true; | |
62 entire_display_damaged_ = true; | |
63 root_surface_id_ = root_surface_id; | |
64 | |
65 begin_frame_source_->SetNeedsBeginFrames(!output_surface_lost_); | |
66 ScheduleBeginFrameDeadline(); | 63 ScheduleBeginFrameDeadline(); |
67 } | 64 } |
68 | 65 |
| 66 // Notification that there was a resize or the root surface changed and |
| 67 // that we should just draw immediately. |
| 68 void DisplayScheduler::SetNewRootSurface(SurfaceId root_surface_id) { |
| 69 TRACE_EVENT0("cc", "DisplayScheduler::SetNewRootSurface"); |
| 70 root_surface_id_ = root_surface_id; |
| 71 SurfaceDamaged(root_surface_id); |
| 72 } |
| 73 |
69 // Indicates that there was damage to one of the surfaces. | 74 // Indicates that there was damage to one of the surfaces. |
70 // Has some logic to wait for multiple active surfaces before | 75 // Has some logic to wait for multiple active surfaces before |
71 // triggering the deadline. | 76 // triggering the deadline. |
72 void DisplayScheduler::SurfaceDamaged(SurfaceId surface_id) { | 77 void DisplayScheduler::SurfaceDamaged(SurfaceId surface_id) { |
73 TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamaged", "surface_id", | 78 TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamaged", "surface_id", |
74 surface_id.id); | 79 surface_id.id); |
75 | 80 |
76 needs_draw_ = true; | 81 needs_draw_ = true; |
77 | 82 |
78 if (surface_id == root_surface_id_) { | 83 if (surface_id == root_surface_id_) { |
79 root_surface_damaged_ = true; | 84 root_surface_damaged_ = true; |
| 85 expecting_root_surface_damage_because_of_resize_ = false; |
80 } else { | 86 } else { |
81 child_surface_ids_damaged_.insert(surface_id); | 87 child_surface_ids_damaged_.insert(surface_id); |
82 | 88 |
83 // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts. | 89 // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts. |
84 all_active_child_surfaces_ready_to_draw_ = base::STLIncludes( | 90 all_active_child_surfaces_ready_to_draw_ = base::STLIncludes( |
85 child_surface_ids_damaged_, child_surface_ids_to_expect_damage_from_); | 91 child_surface_ids_damaged_, child_surface_ids_to_expect_damage_from_); |
86 } | 92 } |
87 | 93 |
88 begin_frame_source_->SetNeedsBeginFrames(!output_surface_lost_); | 94 begin_frame_source_->SetNeedsBeginFrames(!output_surface_lost_); |
89 ScheduleBeginFrameDeadline(); | 95 ScheduleBeginFrameDeadline(); |
(...skipping 16 matching lines...) Expand all Loading... |
106 return; | 112 return; |
107 | 113 |
108 child_surface_ids_to_expect_damage_from_ = | 114 child_surface_ids_to_expect_damage_from_ = |
109 base::STLSetIntersection<std::vector<SurfaceId>>( | 115 base::STLSetIntersection<std::vector<SurfaceId>>( |
110 child_surface_ids_damaged_, child_surface_ids_damaged_prev_); | 116 child_surface_ids_damaged_, child_surface_ids_damaged_prev_); |
111 | 117 |
112 child_surface_ids_damaged_prev_.swap(child_surface_ids_damaged_); | 118 child_surface_ids_damaged_prev_.swap(child_surface_ids_damaged_); |
113 child_surface_ids_damaged_.clear(); | 119 child_surface_ids_damaged_.clear(); |
114 | 120 |
115 needs_draw_ = false; | 121 needs_draw_ = false; |
116 entire_display_damaged_ = false; | |
117 all_active_child_surfaces_ready_to_draw_ = | 122 all_active_child_surfaces_ready_to_draw_ = |
118 child_surface_ids_to_expect_damage_from_.empty(); | 123 child_surface_ids_to_expect_damage_from_.empty(); |
119 | 124 |
120 expect_damage_from_root_surface_ = root_surface_damaged_; | 125 expect_damage_from_root_surface_ = root_surface_damaged_; |
121 root_surface_damaged_ = false; | 126 root_surface_damaged_ = false; |
122 } | 127 } |
123 | 128 |
124 bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { | 129 bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { |
125 base::TimeTicks now = base::TimeTicks::Now(); | 130 base::TimeTicks now = base::TimeTicks::Now(); |
126 TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(), | 131 TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 current_begin_frame_args_.interval; | 165 current_begin_frame_args_.interval; |
161 } | 166 } |
162 | 167 |
163 if (root_surface_resources_locked_) { | 168 if (root_surface_resources_locked_) { |
164 TRACE_EVENT_INSTANT0("cc", "Root surface resources locked", | 169 TRACE_EVENT_INSTANT0("cc", "Root surface resources locked", |
165 TRACE_EVENT_SCOPE_THREAD); | 170 TRACE_EVENT_SCOPE_THREAD); |
166 return current_begin_frame_args_.frame_time + | 171 return current_begin_frame_args_.frame_time + |
167 current_begin_frame_args_.interval; | 172 current_begin_frame_args_.interval; |
168 } | 173 } |
169 | 174 |
170 // TODO(mithro): Be smarter about resize deadlines. | |
171 if (entire_display_damaged_) { | |
172 TRACE_EVENT_INSTANT0("cc", "Entire display damaged", | |
173 TRACE_EVENT_SCOPE_THREAD); | |
174 return base::TimeTicks(); | |
175 } | |
176 | |
177 bool root_ready_to_draw = | 175 bool root_ready_to_draw = |
178 !expect_damage_from_root_surface_ || root_surface_damaged_; | 176 !expect_damage_from_root_surface_ || root_surface_damaged_; |
179 | 177 |
180 if (all_active_child_surfaces_ready_to_draw_ && root_ready_to_draw) { | 178 if (all_active_child_surfaces_ready_to_draw_ && root_ready_to_draw) { |
181 TRACE_EVENT_INSTANT0("cc", "All active surfaces ready", | 179 TRACE_EVENT_INSTANT0("cc", "All active surfaces ready", |
182 TRACE_EVENT_SCOPE_THREAD); | 180 TRACE_EVENT_SCOPE_THREAD); |
183 return base::TimeTicks(); | 181 return base::TimeTicks(); |
184 } | 182 } |
185 | 183 |
| 184 // TODO(mithro): Be smarter about resize deadlines. |
| 185 if (expecting_root_surface_damage_because_of_resize_) { |
| 186 TRACE_EVENT_INSTANT0("cc", "Entire display damaged", |
| 187 TRACE_EVENT_SCOPE_THREAD); |
| 188 return current_begin_frame_args_.frame_time + |
| 189 current_begin_frame_args_.interval; |
| 190 } |
| 191 |
186 // Use an earlier deadline if we are only waiting for the root surface | 192 // Use an earlier deadline if we are only waiting for the root surface |
187 // in case our expect_damage_from_root_surface heuristic is incorrect. | 193 // in case our expect_damage_from_root_surface heuristic is incorrect. |
188 // TODO(mithro): Replace this with SetNeedsBeginFrame and SwapAbort | 194 // TODO(mithro): Replace this with SetNeedsBeginFrame and SwapAbort |
189 // logic. | 195 // logic. |
190 if (all_active_child_surfaces_ready_to_draw_ && | 196 if (all_active_child_surfaces_ready_to_draw_ && |
191 expect_damage_from_root_surface_) { | 197 expect_damage_from_root_surface_) { |
192 TRACE_EVENT_INSTANT0("cc", "Waiting for damage from root surface", | 198 TRACE_EVENT_INSTANT0("cc", "Waiting for damage from root surface", |
193 TRACE_EVENT_SCOPE_THREAD); | 199 TRACE_EVENT_SCOPE_THREAD); |
194 // This adjusts the deadline by DefaultEstimatedParentDrawTime for | 200 // This adjusts the deadline by DefaultEstimatedParentDrawTime for |
195 // a second time. The first one represented the Surfaces draw to display | 201 // a second time. The first one represented the Surfaces draw to display |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 } | 284 } |
279 | 285 |
280 void DisplayScheduler::DidSwapBuffersComplete() { | 286 void DisplayScheduler::DidSwapBuffersComplete() { |
281 pending_swaps_--; | 287 pending_swaps_--; |
282 TRACE_EVENT1("cc", "DisplayScheduler::DidSwapBuffersComplete", | 288 TRACE_EVENT1("cc", "DisplayScheduler::DidSwapBuffersComplete", |
283 "pending_frames", pending_swaps_); | 289 "pending_frames", pending_swaps_); |
284 ScheduleBeginFrameDeadline(); | 290 ScheduleBeginFrameDeadline(); |
285 } | 291 } |
286 | 292 |
287 } // namespace cc | 293 } // namespace cc |
OLD | NEW |