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/display_item_proto_factory.h" | 24 #include "cc/playback/display_item_proto_factory.h" |
24 #include "cc/playback/drawing_display_item.h" | 25 #include "cc/playback/drawing_display_item.h" |
25 #include "cc/playback/filter_display_item.h" | 26 #include "cc/playback/filter_display_item.h" |
26 #include "cc/playback/float_clip_display_item.h" | 27 #include "cc/playback/float_clip_display_item.h" |
27 #include "cc/playback/largest_display_item.h" | 28 #include "cc/playback/largest_display_item.h" |
28 #include "cc/playback/transform_display_item.h" | 29 #include "cc/playback/transform_display_item.h" |
29 #include "cc/proto/display_item.pb.h" | 30 #include "cc/proto/display_item.pb.h" |
30 #include "cc/proto/gfx_conversions.h" | 31 #include "cc/proto/gfx_conversions.h" |
31 #include "third_party/skia/include/core/SkCanvas.h" | |
32 #include "third_party/skia/include/core/SkPictureRecorder.h" | |
33 #include "third_party/skia/include/utils/SkPictureUtils.h" | |
34 #include "ui/gfx/geometry/rect.h" | 32 #include "ui/gfx/geometry/rect.h" |
35 #include "ui/gfx/geometry/rect_conversions.h" | 33 #include "ui/gfx/geometry/rect_conversions.h" |
36 #include "ui/gfx/skia_util.h" | 34 #include "ui/gfx/skia_util.h" |
37 | 35 |
38 namespace cc { | 36 namespace cc { |
39 | 37 |
40 namespace { | 38 namespace { |
41 | 39 |
42 // We don't perform per-layer solid color analysis when there are too many skia | 40 // We don't perform per-layer solid color analysis when there are too many skia |
43 // operations. | 41 // operations. |
44 const int kOpCountThatIsOkToAnalyze = 10; | 42 const int kOpCountThatIsOkToAnalyze = 10; |
45 | 43 |
46 bool DisplayItemsTracingEnabled() { | 44 bool DisplayItemsTracingEnabled() { |
47 bool tracing_enabled; | 45 bool tracing_enabled; |
48 TRACE_EVENT_CATEGORY_GROUP_ENABLED( | 46 TRACE_EVENT_CATEGORY_GROUP_ENABLED( |
49 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items"), &tracing_enabled); | 47 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items"), &tracing_enabled); |
50 return tracing_enabled; | 48 return tracing_enabled; |
51 } | 49 } |
52 | 50 |
53 bool GetCanvasClipBounds(SkCanvas* canvas, gfx::Rect* clip_bounds) { | 51 bool GetCanvasClipBounds(PaintCanvas* canvas, gfx::Rect* clip_bounds) { |
54 SkRect canvas_clip_bounds; | 52 SkRect canvas_clip_bounds; |
55 if (!canvas->getClipBounds(&canvas_clip_bounds)) | 53 if (!canvas->getClipBounds(&canvas_clip_bounds)) |
56 return false; | 54 return false; |
57 *clip_bounds = ToEnclosingRect(gfx::SkRectToRectF(canvas_clip_bounds)); | 55 *clip_bounds = ToEnclosingRect(gfx::SkRectToRectF(canvas_clip_bounds)); |
58 return true; | 56 return true; |
59 } | 57 } |
60 | 58 |
61 const int kDefaultNumDisplayItemsToReserve = 100; | 59 const int kDefaultNumDisplayItemsToReserve = 100; |
62 | 60 |
63 } // namespace | 61 } // namespace |
(...skipping 30 matching lines...) Expand all Loading... | |
94 return list; | 92 return list; |
95 } | 93 } |
96 | 94 |
97 DisplayItemList::DisplayItemList(const DisplayItemListSettings& settings) | 95 DisplayItemList::DisplayItemList(const DisplayItemListSettings& settings) |
98 : inputs_(settings) {} | 96 : inputs_(settings) {} |
99 | 97 |
100 DisplayItemList::~DisplayItemList() { | 98 DisplayItemList::~DisplayItemList() { |
101 } | 99 } |
102 | 100 |
103 void DisplayItemList::ToProtobuf(proto::DisplayItemList* proto) { | 101 void DisplayItemList::ToProtobuf(proto::DisplayItemList* proto) { |
104 // The flattened SkPicture approach is going away, and the proto | 102 // The flattened PaintRecord approach is going away, and the proto |
danakj
2017/01/20 23:34:13
can rebase this away
| |
105 // doesn't currently support serializing that flattened picture. | 103 // doesn't currently support serializing that flattened picture. |
106 inputs_.settings.ToProtobuf(proto->mutable_settings()); | 104 inputs_.settings.ToProtobuf(proto->mutable_settings()); |
107 | 105 |
108 DCHECK_EQ(0, proto->items_size()); | 106 DCHECK_EQ(0, proto->items_size()); |
109 DCHECK_EQ(0, proto->visual_rects_size()); | 107 DCHECK_EQ(0, proto->visual_rects_size()); |
110 DCHECK(inputs_.items.size() == inputs_.visual_rects.size()) | 108 DCHECK(inputs_.items.size() == inputs_.visual_rects.size()) |
111 << "items.size() " << inputs_.items.size() << " visual_rects.size() " | 109 << "items.size() " << inputs_.items.size() << " visual_rects.size() " |
112 << inputs_.visual_rects.size(); | 110 << inputs_.visual_rects.size(); |
113 int i = 0; | 111 int i = 0; |
114 for (const auto& item : inputs_.items) { | 112 for (const auto& item : inputs_.items) { |
115 RectToProto(inputs_.visual_rects[i++], proto->add_visual_rects()); | 113 RectToProto(inputs_.visual_rects[i++], proto->add_visual_rects()); |
116 item.ToProtobuf(proto->add_items()); | 114 item.ToProtobuf(proto->add_items()); |
117 } | 115 } |
118 } | 116 } |
119 | 117 |
120 void DisplayItemList::Raster(SkCanvas* canvas, | 118 void DisplayItemList::Raster(PaintCanvas* canvas, |
121 SkPicture::AbortCallback* callback, | 119 PaintRecord::AbortCallback* callback, |
122 const gfx::Rect& canvas_target_playback_rect, | 120 const gfx::Rect& canvas_target_playback_rect, |
123 float contents_scale) const { | 121 float contents_scale) const { |
124 canvas->save(); | 122 canvas->save(); |
125 if (!canvas_target_playback_rect.IsEmpty()) { | 123 if (!canvas_target_playback_rect.IsEmpty()) { |
126 // canvas_target_playback_rect is specified in device space. We can't | 124 // canvas_target_playback_rect is specified in device space. We can't |
127 // use clipRect because canvas CTM will be applied on it. Use clipRegion | 125 // use clipRect because canvas CTM will be applied on it. Use clipRegion |
128 // instead because it ignores canvas CTM. | 126 // instead because it ignores canvas CTM. |
129 SkRegion device_clip; | 127 SkRegion device_clip; |
130 device_clip.setRect(gfx::RectToSkIRect(canvas_target_playback_rect)); | 128 device_clip.setRect(gfx::RectToSkIRect(canvas_target_playback_rect)); |
131 canvas->clipRegion(device_clip); | 129 canvas->clipRegion(device_clip); |
132 } | 130 } |
133 canvas->scale(contents_scale, contents_scale); | 131 canvas->scale(contents_scale, contents_scale); |
134 Raster(canvas, callback); | 132 Raster(canvas, callback); |
135 canvas->restore(); | 133 canvas->restore(); |
136 } | 134 } |
137 | 135 |
138 DISABLE_CFI_PERF | 136 DISABLE_CFI_PERF |
139 void DisplayItemList::Raster(SkCanvas* canvas, | 137 void DisplayItemList::Raster(PaintCanvas* canvas, |
140 SkPicture::AbortCallback* callback) const { | 138 PaintRecord::AbortCallback* callback) const { |
141 gfx::Rect canvas_playback_rect; | 139 gfx::Rect canvas_playback_rect; |
142 if (!GetCanvasClipBounds(canvas, &canvas_playback_rect)) | 140 if (!GetCanvasClipBounds(canvas, &canvas_playback_rect)) |
143 return; | 141 return; |
144 | 142 |
145 std::vector<size_t> indices; | 143 std::vector<size_t> indices; |
146 rtree_.Search(canvas_playback_rect, &indices); | 144 rtree_.Search(canvas_playback_rect, &indices); |
147 for (size_t index : indices) { | 145 for (size_t index : indices) { |
148 inputs_.items[index].Raster(canvas, callback); | 146 inputs_.items[index].Raster(canvas, callback); |
149 // We use a callback during solid color analysis on the compositor thread to | 147 // We use a callback during solid color analysis on the compositor thread to |
150 // break out early. Since we're handling a sequence of pictures via rtree | 148 // break out early. Since we're handling a sequence of pictures via rtree |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 } | 184 } |
187 | 185 |
188 int DisplayItemList::ApproximateOpCount() const { | 186 int DisplayItemList::ApproximateOpCount() const { |
189 return approximate_op_count_; | 187 return approximate_op_count_; |
190 } | 188 } |
191 | 189 |
192 size_t DisplayItemList::ApproximateMemoryUsage() const { | 190 size_t DisplayItemList::ApproximateMemoryUsage() const { |
193 size_t memory_usage = sizeof(*this); | 191 size_t memory_usage = sizeof(*this); |
194 | 192 |
195 size_t external_memory_usage = 0; | 193 size_t external_memory_usage = 0; |
196 // Warning: this double-counts SkPicture data if use_cached_picture is | 194 // Warning: this double-counts PaintRecord data if use_cached_picture is |
197 // also true. | 195 // also true. |
198 for (const auto& item : inputs_.items) { | 196 for (const auto& item : inputs_.items) { |
199 size_t bytes = 0; | 197 size_t bytes = 0; |
200 switch (item.type()) { | 198 switch (item.type()) { |
201 case DisplayItem::CLIP: | 199 case DisplayItem::CLIP: |
202 bytes = static_cast<const ClipDisplayItem&>(item).ExternalMemoryUsage(); | 200 bytes = static_cast<const ClipDisplayItem&>(item).ExternalMemoryUsage(); |
203 break; | 201 break; |
204 case DisplayItem::CLIP_PATH: | 202 case DisplayItem::CLIP_PATH: |
205 bytes = | 203 bytes = |
206 static_cast<const ClipPathDisplayItem&>(item).ExternalMemoryUsage(); | 204 static_cast<const ClipPathDisplayItem&>(item).ExternalMemoryUsage(); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 ? inputs_.visual_rects[item_index] | 262 ? inputs_.visual_rects[item_index] |
265 : gfx::Rect(), | 263 : gfx::Rect(), |
266 state.get()); | 264 state.get()); |
267 item_index++; | 265 item_index++; |
268 } | 266 } |
269 state->EndArray(); // "items". | 267 state->EndArray(); // "items". |
270 } | 268 } |
271 state->SetValue("layer_rect", MathUtil::AsValue(rtree_.GetBounds())); | 269 state->SetValue("layer_rect", MathUtil::AsValue(rtree_.GetBounds())); |
272 state->EndDictionary(); // "params". | 270 state->EndDictionary(); // "params". |
273 | 271 |
274 SkPictureRecorder recorder; | 272 PaintRecorder recorder; |
275 gfx::Rect bounds = rtree_.GetBounds(); | 273 gfx::Rect bounds = rtree_.GetBounds(); |
276 SkCanvas* canvas = recorder.beginRecording(bounds.width(), bounds.height()); | 274 PaintCanvas* canvas = |
275 recorder.beginRecording(bounds.width(), bounds.height()); | |
277 canvas->translate(-bounds.x(), -bounds.y()); | 276 canvas->translate(-bounds.x(), -bounds.y()); |
278 canvas->clipRect(gfx::RectToSkRect(bounds)); | 277 canvas->clipRect(gfx::RectToSkRect(bounds)); |
279 Raster(canvas, nullptr, gfx::Rect(), 1.f); | 278 Raster(canvas, nullptr, gfx::Rect(), 1.f); |
280 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); | 279 sk_sp<PaintRecord> picture = recorder.finishRecordingAsPicture(); |
281 | 280 |
282 std::string b64_picture; | 281 std::string b64_picture; |
283 PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture); | 282 PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture); |
284 state->SetString("skp64", b64_picture); | 283 state->SetString("skp64", b64_picture); |
285 | 284 |
286 return std::move(state); | 285 return std::move(state); |
287 } | 286 } |
288 | 287 |
289 void DisplayItemList::EmitTraceSnapshot() const { | 288 void DisplayItemList::EmitTraceSnapshot() const { |
290 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 289 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
291 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items") "," | 290 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items") "," |
292 TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") "," | 291 TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") "," |
293 TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"), | 292 TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"), |
294 "cc::DisplayItemList", this, | 293 "cc::DisplayItemList", this, |
295 TracedDisplayItemList::AsTraceableDisplayItemList(this, | 294 TracedDisplayItemList::AsTraceableDisplayItemList(this, |
296 DisplayItemsTracingEnabled())); | 295 DisplayItemsTracingEnabled())); |
297 } | 296 } |
298 | 297 |
299 void DisplayItemList::GenerateDiscardableImagesMetadata() { | 298 void DisplayItemList::GenerateDiscardableImagesMetadata() { |
300 // This should be only called once, and only after CreateAndCacheSkPicture. | 299 // This should be only called once. |
301 DCHECK(image_map_.empty()); | 300 DCHECK(image_map_.empty()); |
302 | 301 |
303 gfx::Rect bounds = rtree_.GetBounds(); | 302 gfx::Rect bounds = rtree_.GetBounds(); |
304 DiscardableImageMap::ScopedMetadataGenerator generator( | 303 DiscardableImageMap::ScopedMetadataGenerator generator( |
305 &image_map_, gfx::Size(bounds.right(), bounds.bottom())); | 304 &image_map_, gfx::Size(bounds.right(), bounds.bottom())); |
306 Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f); | 305 Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f); |
307 } | 306 } |
308 | 307 |
309 void DisplayItemList::GetDiscardableImagesInRect( | 308 void DisplayItemList::GetDiscardableImagesInRect( |
310 const gfx::Rect& rect, | 309 const gfx::Rect& rect, |
311 float contents_scale, | 310 float contents_scale, |
312 std::vector<DrawImage>* images) { | 311 std::vector<DrawImage>* images) { |
313 image_map_.GetDiscardableImagesInRect(rect, contents_scale, images); | 312 image_map_.GetDiscardableImagesInRect(rect, contents_scale, images); |
314 } | 313 } |
315 | 314 |
316 } // namespace cc | 315 } // namespace cc |
OLD | NEW |