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_item_list.h" | 5 #include "cc/playback/display_item_list.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 | 10 |
11 #include "base/numerics/safe_conversions.h" | 11 #include "base/numerics/safe_conversions.h" |
12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
13 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
14 #include "base/trace_event/trace_event_argument.h" | 14 #include "base/trace_event/trace_event_argument.h" |
15 #include "cc/base/math_util.h" | 15 #include "cc/base/math_util.h" |
16 #include "cc/debug/picture_debug_util.h" | 16 #include "cc/debug/picture_debug_util.h" |
17 #include "cc/debug/traced_display_item_list.h" | 17 #include "cc/debug/traced_display_item_list.h" |
18 #include "cc/debug/traced_value.h" | 18 #include "cc/debug/traced_value.h" |
| 19 #include "cc/paint/paint_recorder.h" |
19 #include "cc/playback/clip_display_item.h" | 20 #include "cc/playback/clip_display_item.h" |
20 #include "cc/playback/clip_path_display_item.h" | 21 #include "cc/playback/clip_path_display_item.h" |
21 #include "cc/playback/compositing_display_item.h" | 22 #include "cc/playback/compositing_display_item.h" |
22 #include "cc/playback/display_item_list_settings.h" | 23 #include "cc/playback/display_item_list_settings.h" |
23 #include "cc/playback/drawing_display_item.h" | 24 #include "cc/playback/drawing_display_item.h" |
24 #include "cc/playback/filter_display_item.h" | 25 #include "cc/playback/filter_display_item.h" |
25 #include "cc/playback/float_clip_display_item.h" | 26 #include "cc/playback/float_clip_display_item.h" |
26 #include "cc/playback/largest_display_item.h" | 27 #include "cc/playback/largest_display_item.h" |
27 #include "cc/playback/transform_display_item.h" | 28 #include "cc/playback/transform_display_item.h" |
28 #include "third_party/skia/include/core/SkCanvas.h" | |
29 #include "third_party/skia/include/core/SkPictureRecorder.h" | |
30 #include "third_party/skia/include/utils/SkPictureUtils.h" | |
31 #include "ui/gfx/geometry/rect.h" | 29 #include "ui/gfx/geometry/rect.h" |
32 #include "ui/gfx/geometry/rect_conversions.h" | 30 #include "ui/gfx/geometry/rect_conversions.h" |
33 #include "ui/gfx/skia_util.h" | 31 #include "ui/gfx/skia_util.h" |
34 | 32 |
35 namespace cc { | 33 namespace cc { |
36 | 34 |
37 namespace { | 35 namespace { |
38 | 36 |
39 // We don't perform per-layer solid color analysis when there are too many skia | 37 // We don't perform per-layer solid color analysis when there are too many skia |
40 // operations. | 38 // operations. |
41 const int kOpCountThatIsOkToAnalyze = 10; | 39 const int kOpCountThatIsOkToAnalyze = 10; |
42 | 40 |
43 bool DisplayItemsTracingEnabled() { | 41 bool DisplayItemsTracingEnabled() { |
44 bool tracing_enabled; | 42 bool tracing_enabled; |
45 TRACE_EVENT_CATEGORY_GROUP_ENABLED( | 43 TRACE_EVENT_CATEGORY_GROUP_ENABLED( |
46 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items"), &tracing_enabled); | 44 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items"), &tracing_enabled); |
47 return tracing_enabled; | 45 return tracing_enabled; |
48 } | 46 } |
49 | 47 |
50 bool GetCanvasClipBounds(SkCanvas* canvas, gfx::Rect* clip_bounds) { | 48 bool GetCanvasClipBounds(PaintCanvas* canvas, gfx::Rect* clip_bounds) { |
51 SkRect canvas_clip_bounds; | 49 SkRect canvas_clip_bounds; |
52 if (!canvas->getClipBounds(&canvas_clip_bounds)) | 50 if (!canvas->getClipBounds(&canvas_clip_bounds)) |
53 return false; | 51 return false; |
54 *clip_bounds = ToEnclosingRect(gfx::SkRectToRectF(canvas_clip_bounds)); | 52 *clip_bounds = ToEnclosingRect(gfx::SkRectToRectF(canvas_clip_bounds)); |
55 return true; | 53 return true; |
56 } | 54 } |
57 | 55 |
58 const int kDefaultNumDisplayItemsToReserve = 100; | 56 const int kDefaultNumDisplayItemsToReserve = 100; |
59 | 57 |
60 } // namespace | 58 } // namespace |
61 | 59 |
62 DisplayItemList::Inputs::Inputs(const DisplayItemListSettings& settings) | 60 DisplayItemList::Inputs::Inputs(const DisplayItemListSettings& settings) |
63 : items(LargestDisplayItemSize(), | 61 : items(LargestDisplayItemSize(), |
64 LargestDisplayItemSize() * kDefaultNumDisplayItemsToReserve), | 62 LargestDisplayItemSize() * kDefaultNumDisplayItemsToReserve), |
65 settings(settings) {} | 63 settings(settings) {} |
66 | 64 |
67 DisplayItemList::Inputs::~Inputs() {} | 65 DisplayItemList::Inputs::~Inputs() {} |
68 | 66 |
69 scoped_refptr<DisplayItemList> DisplayItemList::Create( | 67 scoped_refptr<DisplayItemList> DisplayItemList::Create( |
70 const DisplayItemListSettings& settings) { | 68 const DisplayItemListSettings& settings) { |
71 return make_scoped_refptr(new DisplayItemList(settings)); | 69 return make_scoped_refptr(new DisplayItemList(settings)); |
72 } | 70 } |
73 | 71 |
74 DisplayItemList::DisplayItemList(const DisplayItemListSettings& settings) | 72 DisplayItemList::DisplayItemList(const DisplayItemListSettings& settings) |
75 : inputs_(settings) {} | 73 : inputs_(settings) {} |
76 | 74 |
77 DisplayItemList::~DisplayItemList() { | 75 DisplayItemList::~DisplayItemList() { |
78 } | 76 } |
79 | 77 |
80 void DisplayItemList::Raster(SkCanvas* canvas, | 78 void DisplayItemList::Raster(PaintCanvas* canvas, |
81 SkPicture::AbortCallback* callback, | 79 PaintRecord::AbortCallback* callback, |
82 const gfx::Rect& canvas_target_playback_rect, | 80 const gfx::Rect& canvas_target_playback_rect, |
83 float contents_scale) const { | 81 float contents_scale) const { |
84 canvas->save(); | 82 canvas->save(); |
85 if (!canvas_target_playback_rect.IsEmpty()) { | 83 if (!canvas_target_playback_rect.IsEmpty()) { |
86 // canvas_target_playback_rect is specified in device space. We can't | 84 // canvas_target_playback_rect is specified in device space. We can't |
87 // use clipRect because canvas CTM will be applied on it. Use clipRegion | 85 // use clipRect because canvas CTM will be applied on it. Use clipRegion |
88 // instead because it ignores canvas CTM. | 86 // instead because it ignores canvas CTM. |
89 SkRegion device_clip; | 87 SkRegion device_clip; |
90 device_clip.setRect(gfx::RectToSkIRect(canvas_target_playback_rect)); | 88 device_clip.setRect(gfx::RectToSkIRect(canvas_target_playback_rect)); |
91 canvas->clipRegion(device_clip); | 89 canvas->clipRegion(device_clip); |
92 } | 90 } |
93 canvas->scale(contents_scale, contents_scale); | 91 canvas->scale(contents_scale, contents_scale); |
94 Raster(canvas, callback); | 92 Raster(canvas, callback); |
95 canvas->restore(); | 93 canvas->restore(); |
96 } | 94 } |
97 | 95 |
98 DISABLE_CFI_PERF | 96 DISABLE_CFI_PERF |
99 void DisplayItemList::Raster(SkCanvas* canvas, | 97 void DisplayItemList::Raster(PaintCanvas* canvas, |
100 SkPicture::AbortCallback* callback) const { | 98 PaintRecord::AbortCallback* callback) const { |
101 gfx::Rect canvas_playback_rect; | 99 gfx::Rect canvas_playback_rect; |
102 if (!GetCanvasClipBounds(canvas, &canvas_playback_rect)) | 100 if (!GetCanvasClipBounds(canvas, &canvas_playback_rect)) |
103 return; | 101 return; |
104 | 102 |
105 std::vector<size_t> indices; | 103 std::vector<size_t> indices; |
106 rtree_.Search(canvas_playback_rect, &indices); | 104 rtree_.Search(canvas_playback_rect, &indices); |
107 for (size_t index : indices) { | 105 for (size_t index : indices) { |
108 inputs_.items[index].Raster(canvas, callback); | 106 inputs_.items[index].Raster(canvas, callback); |
109 // We use a callback during solid color analysis on the compositor thread to | 107 // We use a callback during solid color analysis on the compositor thread to |
110 // break out early. Since we're handling a sequence of pictures via rtree | 108 // break out early. Since we're handling a sequence of pictures via rtree |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 } | 142 } |
145 | 143 |
146 int DisplayItemList::ApproximateOpCount() const { | 144 int DisplayItemList::ApproximateOpCount() const { |
147 return approximate_op_count_; | 145 return approximate_op_count_; |
148 } | 146 } |
149 | 147 |
150 size_t DisplayItemList::ApproximateMemoryUsage() const { | 148 size_t DisplayItemList::ApproximateMemoryUsage() const { |
151 size_t memory_usage = sizeof(*this); | 149 size_t memory_usage = sizeof(*this); |
152 | 150 |
153 size_t external_memory_usage = 0; | 151 size_t external_memory_usage = 0; |
154 // Warning: this double-counts SkPicture data if use_cached_picture is | |
155 // also true. | |
156 for (const auto& item : inputs_.items) { | 152 for (const auto& item : inputs_.items) { |
157 size_t bytes = 0; | 153 size_t bytes = 0; |
158 switch (item.type()) { | 154 switch (item.type()) { |
159 case DisplayItem::CLIP: | 155 case DisplayItem::CLIP: |
160 bytes = static_cast<const ClipDisplayItem&>(item).ExternalMemoryUsage(); | 156 bytes = static_cast<const ClipDisplayItem&>(item).ExternalMemoryUsage(); |
161 break; | 157 break; |
162 case DisplayItem::CLIP_PATH: | 158 case DisplayItem::CLIP_PATH: |
163 bytes = | 159 bytes = |
164 static_cast<const ClipPathDisplayItem&>(item).ExternalMemoryUsage(); | 160 static_cast<const ClipPathDisplayItem&>(item).ExternalMemoryUsage(); |
165 break; | 161 break; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 ? inputs_.visual_rects[item_index] | 218 ? inputs_.visual_rects[item_index] |
223 : gfx::Rect(), | 219 : gfx::Rect(), |
224 state.get()); | 220 state.get()); |
225 item_index++; | 221 item_index++; |
226 } | 222 } |
227 state->EndArray(); // "items". | 223 state->EndArray(); // "items". |
228 } | 224 } |
229 state->SetValue("layer_rect", MathUtil::AsValue(rtree_.GetBounds())); | 225 state->SetValue("layer_rect", MathUtil::AsValue(rtree_.GetBounds())); |
230 state->EndDictionary(); // "params". | 226 state->EndDictionary(); // "params". |
231 | 227 |
232 SkPictureRecorder recorder; | 228 PaintRecorder recorder; |
233 gfx::Rect bounds = rtree_.GetBounds(); | 229 gfx::Rect bounds = rtree_.GetBounds(); |
234 SkCanvas* canvas = recorder.beginRecording(bounds.width(), bounds.height()); | 230 PaintCanvas* canvas = |
| 231 recorder.beginRecording(bounds.width(), bounds.height()); |
235 canvas->translate(-bounds.x(), -bounds.y()); | 232 canvas->translate(-bounds.x(), -bounds.y()); |
236 canvas->clipRect(gfx::RectToSkRect(bounds)); | 233 canvas->clipRect(gfx::RectToSkRect(bounds)); |
237 Raster(canvas, nullptr, gfx::Rect(), 1.f); | 234 Raster(canvas, nullptr, gfx::Rect(), 1.f); |
238 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); | 235 sk_sp<PaintRecord> picture = recorder.finishRecordingAsPicture(); |
239 | 236 |
240 std::string b64_picture; | 237 std::string b64_picture; |
241 PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture); | 238 PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture); |
242 state->SetString("skp64", b64_picture); | 239 state->SetString("skp64", b64_picture); |
243 | 240 |
244 return std::move(state); | 241 return std::move(state); |
245 } | 242 } |
246 | 243 |
247 void DisplayItemList::EmitTraceSnapshot() const { | 244 void DisplayItemList::EmitTraceSnapshot() const { |
248 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 245 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
249 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items") "," | 246 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items") "," |
250 TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") "," | 247 TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") "," |
251 TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"), | 248 TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"), |
252 "cc::DisplayItemList", this, | 249 "cc::DisplayItemList", this, |
253 TracedDisplayItemList::AsTraceableDisplayItemList(this, | 250 TracedDisplayItemList::AsTraceableDisplayItemList(this, |
254 DisplayItemsTracingEnabled())); | 251 DisplayItemsTracingEnabled())); |
255 } | 252 } |
256 | 253 |
257 void DisplayItemList::GenerateDiscardableImagesMetadata() { | 254 void DisplayItemList::GenerateDiscardableImagesMetadata() { |
258 // This should be only called once, and only after CreateAndCacheSkPicture. | 255 // This should be only called once. |
259 DCHECK(image_map_.empty()); | 256 DCHECK(image_map_.empty()); |
260 | 257 |
261 gfx::Rect bounds = rtree_.GetBounds(); | 258 gfx::Rect bounds = rtree_.GetBounds(); |
262 DiscardableImageMap::ScopedMetadataGenerator generator( | 259 DiscardableImageMap::ScopedMetadataGenerator generator( |
263 &image_map_, gfx::Size(bounds.right(), bounds.bottom())); | 260 &image_map_, gfx::Size(bounds.right(), bounds.bottom())); |
264 Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f); | 261 Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f); |
265 } | 262 } |
266 | 263 |
267 void DisplayItemList::GetDiscardableImagesInRect( | 264 void DisplayItemList::GetDiscardableImagesInRect( |
268 const gfx::Rect& rect, | 265 const gfx::Rect& rect, |
269 float contents_scale, | 266 float contents_scale, |
270 std::vector<DrawImage>* images) { | 267 std::vector<DrawImage>* images) { |
271 image_map_.GetDiscardableImagesInRect(rect, contents_scale, images); | 268 image_map_.GetDiscardableImagesInRect(rect, contents_scale, images); |
272 } | 269 } |
273 | 270 |
274 } // namespace cc | 271 } // namespace cc |
OLD | NEW |