| 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" |
| 11 #include "cc/base/region.h" | 11 #include "cc/base/region.h" |
| 12 #include "cc/layers/content_layer_client.h" | 12 #include "cc/layers/content_layer_client.h" |
| 13 #include "cc/playback/display_item_list.h" | 13 #include "cc/playback/display_item_list.h" |
| 14 #include "cc/playback/display_list_raster_source.h" | 14 #include "cc/playback/display_list_raster_source.h" |
| 15 #include "skia/ext/analysis_canvas.h" | 15 #include "skia/ext/analysis_canvas.h" |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 // Layout pixel buffer around the visible layer rect to record. Any base | |
| 20 // picture that intersects the visible layer rect expanded by this distance | |
| 21 // will be recorded. | |
| 22 const int kPixelDistanceToRecord = 4000; | |
| 23 | |
| 24 // This is the distance, in layer space, by which the recorded viewport has to | |
| 25 // change before causing a paint of the new content. For example, it means | |
| 26 // that one has to scroll a very large page by 512 pixels before we will | |
| 27 // re-record a new DisplayItemList for an updated recorded viewport. | |
| 28 const int kMinimumDistanceBeforeUpdatingRecordedViewport = 512; | |
| 29 | |
| 30 #ifdef NDEBUG | 19 #ifdef NDEBUG |
| 31 const bool kDefaultClearCanvasSetting = false; | 20 const bool kDefaultClearCanvasSetting = false; |
| 32 #else | 21 #else |
| 33 const bool kDefaultClearCanvasSetting = true; | 22 const bool kDefaultClearCanvasSetting = true; |
| 34 #endif | 23 #endif |
| 35 | 24 |
| 36 DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER( | 25 DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER( |
| 37 ScopedDisplayListRecordingSourceUpdateTimer, | 26 ScopedDisplayListRecordingSourceUpdateTimer, |
| 38 "Compositing.%s.DisplayListRecordingSource.UpdateUs", | 27 "Compositing.%s.DisplayListRecordingSource.UpdateUs", |
| 39 "Compositing.%s.DisplayListRecordingSource.UpdateInvalidatedAreaPerMs"); | 28 "Compositing.%s.DisplayListRecordingSource.UpdateInvalidatedAreaPerMs"); |
| 40 | 29 |
| 41 } // namespace | 30 } // namespace |
| 42 | 31 |
| 43 namespace cc { | 32 namespace cc { |
| 44 | 33 |
| 45 DisplayListRecordingSource::DisplayListRecordingSource() | 34 DisplayListRecordingSource::DisplayListRecordingSource() |
| 46 : slow_down_raster_scale_factor_for_debug_(0), | 35 : slow_down_raster_scale_factor_for_debug_(0), |
| 47 generate_discardable_images_metadata_(false), | 36 generate_discardable_images_metadata_(false), |
| 48 requires_clear_(false), | 37 requires_clear_(false), |
| 49 is_solid_color_(false), | 38 is_solid_color_(false), |
| 50 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting), | 39 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting), |
| 51 solid_color_(SK_ColorTRANSPARENT), | 40 solid_color_(SK_ColorTRANSPARENT), |
| 52 background_color_(SK_ColorTRANSPARENT), | 41 background_color_(SK_ColorTRANSPARENT), |
| 53 pixel_record_distance_(kPixelDistanceToRecord), | |
| 54 painter_reported_memory_usage_(0) {} | 42 painter_reported_memory_usage_(0) {} |
| 55 | 43 |
| 56 DisplayListRecordingSource::~DisplayListRecordingSource() { | 44 DisplayListRecordingSource::~DisplayListRecordingSource() { |
| 57 } | 45 } |
| 58 | 46 |
| 59 // This method only really makes sense to call if the size of the layer didn't | 47 void DisplayListRecordingSource::UpdateInvalidationForNewViewport( |
| 60 // change. | 48 const gfx::Rect& old_recorded_viewport, |
| 61 bool DisplayListRecordingSource::ExposesEnoughNewArea( | 49 const gfx::Rect& new_recorded_viewport, |
| 62 const gfx::Rect& current_recorded_viewport, | 50 Region* invalidation) { |
| 63 const gfx::Rect& potential_new_recorded_viewport, | 51 // Invalidate newly-exposed and no-longer-exposed areas. |
| 64 const gfx::Size& layer_size) { | 52 Region newly_exposed_region(new_recorded_viewport); |
| 65 // If both are empty, nothing to do. | 53 newly_exposed_region.Subtract(old_recorded_viewport); |
| 66 if (current_recorded_viewport.IsEmpty() && | 54 invalidation->Union(newly_exposed_region); |
| 67 potential_new_recorded_viewport.IsEmpty()) | |
| 68 return false; | |
| 69 | 55 |
| 70 // Re-record when going from empty to not-empty, to cover cases where | 56 Region no_longer_exposed_region(old_recorded_viewport); |
| 71 // the layer is recorded for the first time, or otherwise becomes visible. | 57 no_longer_exposed_region.Subtract(new_recorded_viewport); |
| 72 if (current_recorded_viewport.IsEmpty()) | 58 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 } | 59 } |
| 106 | 60 |
| 107 bool DisplayListRecordingSource::UpdateAndExpandInvalidation( | 61 bool DisplayListRecordingSource::UpdateAndExpandInvalidation( |
| 108 ContentLayerClient* painter, | 62 ContentLayerClient* painter, |
| 109 Region* invalidation, | 63 Region* invalidation, |
| 110 const gfx::Size& layer_size, | 64 const gfx::Size& layer_size, |
| 111 const gfx::Rect& visible_layer_rect, | 65 const gfx::Rect& visible_layer_rect, |
| 112 int frame_number, | 66 int frame_number, |
| 113 RecordingMode recording_mode) { | 67 RecordingMode recording_mode) { |
| 114 ScopedDisplayListRecordingSourceUpdateTimer timer; | 68 ScopedDisplayListRecordingSourceUpdateTimer timer; |
| 115 bool updated = false; | 69 bool updated = false; |
| 116 | 70 |
| 71 // TODO(chrishtr): delete this conditional once synchronized paint launches. |
| 117 if (size_ != layer_size) { | 72 if (size_ != layer_size) { |
| 118 size_ = layer_size; | 73 size_ = layer_size; |
| 119 updated = true; | 74 updated = true; |
| 120 } | 75 } |
| 121 | 76 |
| 122 // The recorded viewport is the visible layer rect, expanded | 77 gfx::Rect new_recorded_viewport = painter->PaintableRegion(); |
| 123 // by the pixel record distance, up to a maximum of the total | 78 if (new_recorded_viewport != recorded_viewport_) { |
| 124 // layer size. | 79 UpdateInvalidationForNewViewport(recorded_viewport_, new_recorded_viewport, |
| 125 gfx::Rect potential_new_recorded_viewport = visible_layer_rect; | 80 invalidation); |
| 126 potential_new_recorded_viewport.Inset(-pixel_record_distance_, | 81 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; | 82 updated = true; |
| 146 } | 83 } |
| 147 | 84 |
| 148 // Count the area that is being invalidated. | 85 // Count the area that is being invalidated. |
| 149 Region recorded_invalidation(*invalidation); | 86 Region recorded_invalidation(*invalidation); |
| 150 recorded_invalidation.Intersect(recorded_viewport_); | 87 recorded_invalidation.Intersect(recorded_viewport_); |
| 151 for (Region::Iterator it(recorded_invalidation); it.has_rect(); it.next()) | 88 for (Region::Iterator it(recorded_invalidation); it.has_rect(); it.next()) |
| 152 timer.AddArea(it.rect().size().GetCheckedArea()); | 89 timer.AddArea(it.rect().size().GetCheckedArea()); |
| 153 | 90 |
| 154 if (!updated && !invalidation->Intersects(recorded_viewport_)) | 91 if (!updated && !invalidation->Intersects(recorded_viewport_)) |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 } | 182 } |
| 246 | 183 |
| 247 void DisplayListRecordingSource::Clear() { | 184 void DisplayListRecordingSource::Clear() { |
| 248 recorded_viewport_ = gfx::Rect(); | 185 recorded_viewport_ = gfx::Rect(); |
| 249 display_list_ = nullptr; | 186 display_list_ = nullptr; |
| 250 painter_reported_memory_usage_ = 0; | 187 painter_reported_memory_usage_ = 0; |
| 251 is_solid_color_ = false; | 188 is_solid_color_ = false; |
| 252 } | 189 } |
| 253 | 190 |
| 254 } // namespace cc | 191 } // namespace cc |
| OLD | NEW |