OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/playback/display_list_recording_source.h" | 5 #include "cc/playback/display_list_recording_source.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/numerics/safe_math.h" | 9 #include "base/numerics/safe_math.h" |
10 #include "cc/base/histograms.h" | 10 #include "cc/base/histograms.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 is_solid_color_(false), | 49 is_solid_color_(false), |
50 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting), | 50 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting), |
51 solid_color_(SK_ColorTRANSPARENT), | 51 solid_color_(SK_ColorTRANSPARENT), |
52 background_color_(SK_ColorTRANSPARENT), | 52 background_color_(SK_ColorTRANSPARENT), |
53 pixel_record_distance_(kPixelDistanceToRecord), | 53 pixel_record_distance_(kPixelDistanceToRecord), |
54 painter_reported_memory_usage_(0) {} | 54 painter_reported_memory_usage_(0) {} |
55 | 55 |
56 DisplayListRecordingSource::~DisplayListRecordingSource() { | 56 DisplayListRecordingSource::~DisplayListRecordingSource() { |
57 } | 57 } |
58 | 58 |
59 // This method only really makes sense to call if the size of the layer didn't | 59 void DisplayListRecordingSource::UpdateInvalidationForNewViewport( |
60 // change. | 60 const gfx::Rect& old_recorded_viewport, |
61 bool DisplayListRecordingSource::ExposesEnoughNewArea( | 61 const gfx::Rect& new_recorded_viewport, |
62 const gfx::Rect& current_recorded_viewport, | 62 Region* invalidation) { |
63 const gfx::Rect& potential_new_recorded_viewport, | 63 // Invalidate newly-exposed and no-longer-exposed areas. |
64 const gfx::Size& layer_size) { | 64 Region newly_exposed_region(new_recorded_viewport); |
65 // If both are empty, nothing to do. | 65 newly_exposed_region.Subtract(old_recorded_viewport); |
66 if (current_recorded_viewport.IsEmpty() && | 66 invalidation->Union(newly_exposed_region); |
67 potential_new_recorded_viewport.IsEmpty()) | |
68 return false; | |
69 | 67 |
70 // Re-record when going from empty to not-empty, to cover cases where | 68 Region no_longer_exposed_region(old_recorded_viewport); |
71 // the layer is recorded for the first time, or otherwise becomes visible. | 69 no_longer_exposed_region.Subtract(new_recorded_viewport); |
72 if (current_recorded_viewport.IsEmpty()) | 70 invalidation->Union(no_longer_exposed_region); |
73 return true; | |
74 | |
75 // Re-record if the new viewport includes area outside of a skirt around the | |
76 // existing viewport. | |
77 gfx::Rect expanded_viewport(current_recorded_viewport); | |
78 expanded_viewport.Inset(-kMinimumDistanceBeforeUpdatingRecordedViewport, | |
79 -kMinimumDistanceBeforeUpdatingRecordedViewport); | |
80 if (!expanded_viewport.Contains(potential_new_recorded_viewport)) | |
81 return true; | |
82 | |
83 // Even if the new viewport doesn't include enough new area to satisfy the | |
84 // condition above, re-record anyway if touches a layer edge not touched by | |
85 // the existing viewport. Viewports are clipped to layer boundaries, so if the | |
86 // new viewport touches a layer edge not touched by the existing viewport, | |
87 // the new viewport must expose new area that touches this layer edge. Since | |
88 // this new area touches a layer edge, it's impossible to expose more area in | |
89 // that direction, so recording cannot be deferred until the exposed new area | |
90 // satisfies the condition above. | |
91 if (potential_new_recorded_viewport.x() == 0 && | |
92 current_recorded_viewport.x() != 0) | |
93 return true; | |
94 if (potential_new_recorded_viewport.y() == 0 && | |
95 current_recorded_viewport.y() != 0) | |
96 return true; | |
97 if (potential_new_recorded_viewport.right() == layer_size.width() && | |
98 current_recorded_viewport.right() != layer_size.width()) | |
99 return true; | |
100 if (potential_new_recorded_viewport.bottom() == layer_size.height() && | |
101 current_recorded_viewport.bottom() != layer_size.height()) | |
102 return true; | |
103 | |
104 return false; | |
105 } | 71 } |
106 | 72 |
107 bool DisplayListRecordingSource::UpdateAndExpandInvalidation( | 73 bool DisplayListRecordingSource::UpdateAndExpandInvalidation( |
108 ContentLayerClient* painter, | 74 ContentLayerClient* painter, |
109 Region* invalidation, | 75 Region* invalidation, |
110 const gfx::Size& layer_size, | 76 const gfx::Size& layer_size, |
111 const gfx::Rect& visible_layer_rect, | 77 const gfx::Rect& visible_layer_rect, |
112 int frame_number, | 78 int frame_number, |
113 RecordingMode recording_mode) { | 79 RecordingMode recording_mode) { |
114 ScopedDisplayListRecordingSourceUpdateTimer timer; | 80 ScopedDisplayListRecordingSourceUpdateTimer timer; |
115 bool updated = false; | 81 bool updated = false; |
116 | 82 |
| 83 // TODO(chrishtr): delete this conditional once synchronized paint launches. |
117 if (size_ != layer_size) { | 84 if (size_ != layer_size) { |
118 size_ = layer_size; | 85 size_ = layer_size; |
119 updated = true; | 86 updated = true; |
120 } | 87 } |
121 | 88 |
122 // The recorded viewport is the visible layer rect, expanded | 89 gfx::Rect new_recorded_viewport = painter->PaintableRegion(); |
123 // by the pixel record distance, up to a maximum of the total | 90 if (new_recorded_viewport != recorded_viewport_) { |
124 // layer size. | 91 UpdateInvalidationForNewViewport(recorded_viewport_, new_recorded_viewport, |
125 gfx::Rect potential_new_recorded_viewport = visible_layer_rect; | 92 invalidation); |
126 potential_new_recorded_viewport.Inset(-pixel_record_distance_, | 93 recorded_viewport_ = new_recorded_viewport; |
127 -pixel_record_distance_); | |
128 potential_new_recorded_viewport.Intersect(gfx::Rect(GetSize())); | |
129 | |
130 if (updated || | |
131 ExposesEnoughNewArea(recorded_viewport_, potential_new_recorded_viewport, | |
132 GetSize())) { | |
133 gfx::Rect old_recorded_viewport = recorded_viewport_; | |
134 recorded_viewport_ = potential_new_recorded_viewport; | |
135 | |
136 // Invalidate newly-exposed and no-longer-exposed areas. | |
137 Region newly_exposed_region(recorded_viewport_); | |
138 newly_exposed_region.Subtract(old_recorded_viewport); | |
139 invalidation->Union(newly_exposed_region); | |
140 | |
141 Region no_longer_exposed_region(old_recorded_viewport); | |
142 no_longer_exposed_region.Subtract(recorded_viewport_); | |
143 invalidation->Union(no_longer_exposed_region); | |
144 | |
145 updated = true; | 94 updated = true; |
146 } | 95 } |
147 | 96 |
148 // Count the area that is being invalidated. | 97 // Count the area that is being invalidated. |
149 Region recorded_invalidation(*invalidation); | 98 Region recorded_invalidation(*invalidation); |
150 recorded_invalidation.Intersect(recorded_viewport_); | 99 recorded_invalidation.Intersect(recorded_viewport_); |
151 for (Region::Iterator it(recorded_invalidation); it.has_rect(); it.next()) | 100 for (Region::Iterator it(recorded_invalidation); it.has_rect(); it.next()) |
152 timer.AddArea(it.rect().size().GetCheckedArea()); | 101 timer.AddArea(it.rect().size().GetCheckedArea()); |
153 | 102 |
154 if (!updated && !invalidation->Intersects(recorded_viewport_)) | 103 if (!updated && !invalidation->Intersects(recorded_viewport_)) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 } | 194 } |
246 | 195 |
247 void DisplayListRecordingSource::Clear() { | 196 void DisplayListRecordingSource::Clear() { |
248 recorded_viewport_ = gfx::Rect(); | 197 recorded_viewport_ = gfx::Rect(); |
249 display_list_ = nullptr; | 198 display_list_ = nullptr; |
250 painter_reported_memory_usage_ = 0; | 199 painter_reported_memory_usage_ = 0; |
251 is_solid_color_ = false; | 200 is_solid_color_ = false; |
252 } | 201 } |
253 | 202 |
254 } // namespace cc | 203 } // namespace cc |
OLD | NEW |