| 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 |