Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(702)

Side by Side Diff: cc/playback/display_item_list.cc

Issue 2748263002: Move cc::DisplayItemList and related classes into cc/paint/ (Closed)
Patch Set: none Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "cc/playback/display_item_list.h"
6
7 #include <stddef.h>
8
9 #include <string>
10
11 #include "base/numerics/safe_conversions.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/trace_event/trace_event.h"
14 #include "base/trace_event/trace_event_argument.h"
15 #include "cc/base/math_util.h"
16 #include "cc/debug/picture_debug_util.h"
17 #include "cc/playback/clip_display_item.h"
18 #include "cc/playback/clip_path_display_item.h"
19 #include "cc/playback/compositing_display_item.h"
20 #include "cc/playback/drawing_display_item.h"
21 #include "cc/playback/filter_display_item.h"
22 #include "cc/playback/float_clip_display_item.h"
23 #include "cc/playback/largest_display_item.h"
24 #include "cc/playback/transform_display_item.h"
25 #include "third_party/skia/include/core/SkCanvas.h"
26 #include "third_party/skia/include/core/SkPictureRecorder.h"
27 #include "ui/gfx/geometry/rect.h"
28 #include "ui/gfx/geometry/rect_conversions.h"
29 #include "ui/gfx/skia_util.h"
30
31 namespace cc {
32
33 namespace {
34
35 // We don't perform per-layer solid color analysis when there are too many skia
36 // operations.
37 const int kOpCountThatIsOkToAnalyze = 10;
38
39 bool GetCanvasClipBounds(SkCanvas* canvas, gfx::Rect* clip_bounds) {
40 SkRect canvas_clip_bounds;
41 if (!canvas->getLocalClipBounds(&canvas_clip_bounds))
42 return false;
43 *clip_bounds = ToEnclosingRect(gfx::SkRectToRectF(canvas_clip_bounds));
44 return true;
45 }
46
47 const int kDefaultNumDisplayItemsToReserve = 100;
48
49 } // namespace
50
51 DisplayItemList::Inputs::Inputs()
52 : items(LargestDisplayItemSize(),
53 LargestDisplayItemSize() * kDefaultNumDisplayItemsToReserve) {}
54
55 DisplayItemList::Inputs::~Inputs() = default;
56
57 DisplayItemList::DisplayItemList() = default;
58
59 DisplayItemList::~DisplayItemList() = default;
60
61 void DisplayItemList::Raster(SkCanvas* canvas,
62 SkPicture::AbortCallback* callback,
63 const gfx::Rect& canvas_target_playback_rect,
64 float contents_scale) const {
65 canvas->save();
66 if (!canvas_target_playback_rect.IsEmpty()) {
67 // canvas_target_playback_rect is specified in device space. We can't
68 // use clipRect because canvas CTM will be applied on it. Use clipRegion
69 // instead because it ignores canvas CTM.
70 SkRegion device_clip;
71 device_clip.setRect(gfx::RectToSkIRect(canvas_target_playback_rect));
72 canvas->clipRegion(device_clip);
73 }
74 canvas->scale(contents_scale, contents_scale);
75 Raster(canvas, callback);
76 canvas->restore();
77 }
78
79 DISABLE_CFI_PERF
80 void DisplayItemList::Raster(SkCanvas* canvas,
81 SkPicture::AbortCallback* callback) const {
82 gfx::Rect canvas_playback_rect;
83 if (!GetCanvasClipBounds(canvas, &canvas_playback_rect))
84 return;
85
86 std::vector<size_t> indices;
87 rtree_.Search(canvas_playback_rect, &indices);
88 for (size_t index : indices) {
89 inputs_.items[index].Raster(canvas, callback);
90 // We use a callback during solid color analysis on the compositor thread to
91 // break out early. Since we're handling a sequence of pictures via rtree
92 // query results ourselves, we have to respect the callback and early out.
93 if (callback && callback->abort())
94 break;
95 }
96 }
97
98 void DisplayItemList::GrowCurrentBeginItemVisualRect(
99 const gfx::Rect& visual_rect) {
100 if (!inputs_.begin_item_indices.empty())
101 inputs_.visual_rects[inputs_.begin_item_indices.back()].Union(visual_rect);
102 }
103
104 void DisplayItemList::Finalize() {
105 TRACE_EVENT0("cc", "DisplayItemList::Finalize");
106 DCHECK(inputs_.items.size() == inputs_.visual_rects.size())
107 << "items.size() " << inputs_.items.size() << " visual_rects.size() "
108 << inputs_.visual_rects.size();
109 rtree_.Build(inputs_.visual_rects);
110
111 if (!retain_visual_rects_)
112 // This clears both the vector and the vector's capacity, since
113 // visual_rects won't be used anymore.
114 std::vector<gfx::Rect>().swap(inputs_.visual_rects);
115 }
116
117 bool DisplayItemList::IsSuitableForGpuRasterization() const {
118 // TODO(wkorman): This is more permissive than Picture's implementation, since
119 // none of the items might individually trigger a veto even though they
120 // collectively have enough "bad" operations that a corresponding Picture
121 // would get vetoed. See crbug.com/513016.
122 return inputs_.all_items_are_suitable_for_gpu_rasterization;
123 }
124
125 int DisplayItemList::ApproximateOpCount() const {
126 return approximate_op_count_;
127 }
128
129 size_t DisplayItemList::ApproximateMemoryUsage() const {
130 size_t memory_usage = sizeof(*this);
131
132 size_t external_memory_usage = 0;
133 for (const auto& item : inputs_.items) {
134 size_t bytes = 0;
135 switch (item.type()) {
136 case DisplayItem::CLIP:
137 bytes = static_cast<const ClipDisplayItem&>(item).ExternalMemoryUsage();
138 break;
139 case DisplayItem::CLIP_PATH:
140 bytes =
141 static_cast<const ClipPathDisplayItem&>(item).ExternalMemoryUsage();
142 break;
143 case DisplayItem::COMPOSITING:
144 bytes = static_cast<const CompositingDisplayItem&>(item)
145 .ExternalMemoryUsage();
146 break;
147 case DisplayItem::DRAWING:
148 bytes =
149 static_cast<const DrawingDisplayItem&>(item).ExternalMemoryUsage();
150 break;
151 case DisplayItem::FLOAT_CLIP:
152 bytes = static_cast<const FloatClipDisplayItem&>(item)
153 .ExternalMemoryUsage();
154 break;
155 case DisplayItem::FILTER:
156 bytes =
157 static_cast<const FilterDisplayItem&>(item).ExternalMemoryUsage();
158 break;
159 case DisplayItem::TRANSFORM:
160 bytes = static_cast<const TransformDisplayItem&>(item)
161 .ExternalMemoryUsage();
162 break;
163 case DisplayItem::END_CLIP:
164 case DisplayItem::END_CLIP_PATH:
165 case DisplayItem::END_COMPOSITING:
166 case DisplayItem::END_FLOAT_CLIP:
167 case DisplayItem::END_FILTER:
168 case DisplayItem::END_TRANSFORM:
169 break;
170 }
171 external_memory_usage += bytes;
172 }
173
174 // Memory outside this class due to |items_|.
175 memory_usage += inputs_.items.GetCapacityInBytes() + external_memory_usage;
176
177 // TODO(jbroman): Does anything else owned by this class substantially
178 // contribute to memory usage?
179 // TODO(vmpstr): Probably DiscardableImageMap is worth counting here.
180
181 return memory_usage;
182 }
183
184 bool DisplayItemList::ShouldBeAnalyzedForSolidColor() const {
185 return ApproximateOpCount() <= kOpCountThatIsOkToAnalyze;
186 }
187
188 void DisplayItemList::EmitTraceSnapshot() const {
189 bool include_items;
190 TRACE_EVENT_CATEGORY_GROUP_ENABLED(
191 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items"), &include_items);
192 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
193 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items") ","
194 TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") ","
195 TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"),
196 "cc::DisplayItemList", this, CreateTracedValue(include_items));
197 }
198
199 std::unique_ptr<base::trace_event::TracedValue>
200 DisplayItemList::CreateTracedValue(bool include_items) const {
201 auto state = base::MakeUnique<base::trace_event::TracedValue>();
202 state->BeginDictionary("params");
203
204 if (include_items) {
205 state->BeginArray("items");
206
207 auto visual_rects_it = inputs_.visual_rects.begin();
208 for (const DisplayItem& base_item : inputs_.items) {
209 gfx::Rect visual_rect;
210 if (visual_rects_it != inputs_.visual_rects.end()) {
211 visual_rect = *visual_rects_it;
212 ++visual_rects_it;
213 }
214
215 switch (base_item.type()) {
216 case DisplayItem::CLIP: {
217 const auto& item = static_cast<const ClipDisplayItem&>(base_item);
218 std::string output =
219 base::StringPrintf("ClipDisplayItem rect: [%s] visualRect: [%s]",
220 item.clip_rect().ToString().c_str(),
221 visual_rect.ToString().c_str());
222 for (const SkRRect& rounded_rect : item.rounded_clip_rects()) {
223 base::StringAppendF(
224 &output, " rounded_rect: [rect: [%s]",
225 gfx::SkRectToRectF(rounded_rect.rect()).ToString().c_str());
226 base::StringAppendF(&output, " radii: [");
227 SkVector upper_left_radius =
228 rounded_rect.radii(SkRRect::kUpperLeft_Corner);
229 base::StringAppendF(&output, "[%f,%f],", upper_left_radius.x(),
230 upper_left_radius.y());
231 SkVector upper_right_radius =
232 rounded_rect.radii(SkRRect::kUpperRight_Corner);
233 base::StringAppendF(&output, " [%f,%f],", upper_right_radius.x(),
234 upper_right_radius.y());
235 SkVector lower_right_radius =
236 rounded_rect.radii(SkRRect::kLowerRight_Corner);
237 base::StringAppendF(&output, " [%f,%f],", lower_right_radius.x(),
238 lower_right_radius.y());
239 SkVector lower_left_radius =
240 rounded_rect.radii(SkRRect::kLowerLeft_Corner);
241 base::StringAppendF(&output, " [%f,%f]]", lower_left_radius.x(),
242 lower_left_radius.y());
243 }
244 state->AppendString(output);
245 break;
246 }
247 case DisplayItem::END_CLIP:
248 state->AppendString(
249 base::StringPrintf("EndClipDisplayItem visualRect: [%s]",
250 visual_rect.ToString().c_str()));
251 break;
252 case DisplayItem::CLIP_PATH: {
253 const auto& item = static_cast<const ClipPathDisplayItem&>(base_item);
254 state->AppendString(base::StringPrintf(
255 "ClipPathDisplayItem length: %d visualRect: [%s]",
256 item.clip_path().countPoints(), visual_rect.ToString().c_str()));
257 break;
258 }
259 case DisplayItem::END_CLIP_PATH:
260 state->AppendString(
261 base::StringPrintf("EndClipPathDisplayItem visualRect: [%s]",
262 visual_rect.ToString().c_str()));
263 break;
264 case DisplayItem::COMPOSITING: {
265 const auto& item =
266 static_cast<const CompositingDisplayItem&>(base_item);
267 std::string output = base::StringPrintf(
268 "CompositingDisplayItem alpha: %d, xfermode: %d, visualRect: "
269 "[%s]",
270 item.alpha(), static_cast<int>(item.xfermode()),
271 visual_rect.ToString().c_str());
272 if (item.has_bounds()) {
273 base::StringAppendF(
274 &output, ", bounds: [%s]",
275 gfx::SkRectToRectF(item.bounds()).ToString().c_str());
276 }
277 state->AppendString(output);
278 break;
279 }
280 case DisplayItem::END_COMPOSITING:
281 state->AppendString(
282 base::StringPrintf("EndCompositingDisplayItem visualRect: [%s]",
283 visual_rect.ToString().c_str()));
284 break;
285 case DisplayItem::DRAWING: {
286 const auto& item = static_cast<const DrawingDisplayItem&>(base_item);
287 state->BeginDictionary();
288 state->SetString("name", "DrawingDisplayItem");
289
290 state->BeginArray("visualRect");
291 state->AppendInteger(visual_rect.x());
292 state->AppendInteger(visual_rect.y());
293 state->AppendInteger(visual_rect.width());
294 state->AppendInteger(visual_rect.height());
295 state->EndArray();
296
297 state->BeginArray("cullRect");
298 state->AppendInteger(item.picture().cullRect().x());
299 state->AppendInteger(item.picture().cullRect().y());
300 state->AppendInteger(item.picture().cullRect().width());
301 state->AppendInteger(item.picture().cullRect().height());
302 state->EndArray();
303
304 std::string b64_picture;
305 PictureDebugUtil::SerializeAsBase64(ToSkPicture(&item.picture()),
306 &b64_picture);
307 state->SetString("skp64", b64_picture);
308 state->EndDictionary();
309 break;
310 }
311 case DisplayItem::FILTER: {
312 const auto& item = static_cast<const FilterDisplayItem&>(base_item);
313 state->AppendString(base::StringPrintf(
314 "FilterDisplayItem bounds: [%s] visualRect: [%s]",
315 item.bounds().ToString().c_str(),
316 visual_rect.ToString().c_str()));
317 break;
318 }
319 case DisplayItem::END_FILTER:
320 state->AppendString(
321 base::StringPrintf("EndFilterDisplayItem visualRect: [%s]",
322 visual_rect.ToString().c_str()));
323 break;
324 case DisplayItem::FLOAT_CLIP: {
325 const auto& item =
326 static_cast<const FloatClipDisplayItem&>(base_item);
327 state->AppendString(base::StringPrintf(
328 "FloatClipDisplayItem rect: [%s] visualRect: [%s]",
329 item.clip_rect().ToString().c_str(),
330 visual_rect.ToString().c_str()));
331 break;
332 }
333 case DisplayItem::END_FLOAT_CLIP:
334 state->AppendString(
335 base::StringPrintf("EndFloatClipDisplayItem visualRect: [%s]",
336 visual_rect.ToString().c_str()));
337 break;
338 case DisplayItem::TRANSFORM: {
339 const auto& item =
340 static_cast<const TransformDisplayItem&>(base_item);
341 state->AppendString(base::StringPrintf(
342 "TransformDisplayItem transform: [%s] visualRect: [%s]",
343 item.transform().ToString().c_str(),
344 visual_rect.ToString().c_str()));
345 break;
346 }
347 case DisplayItem::END_TRANSFORM:
348 state->AppendString(
349 base::StringPrintf("EndTransformDisplayItem visualRect: [%s]",
350 visual_rect.ToString().c_str()));
351 break;
352 }
353 }
354 state->EndArray(); // "items".
355 }
356
357 MathUtil::AddToTracedValue("layer_rect", rtree_.GetBounds(), state.get());
358 state->EndDictionary(); // "params".
359
360 {
361 SkPictureRecorder recorder;
362 gfx::Rect bounds = rtree_.GetBounds();
363 SkCanvas* canvas = recorder.beginRecording(bounds.width(), bounds.height());
364 canvas->translate(-bounds.x(), -bounds.y());
365 canvas->clipRect(gfx::RectToSkRect(bounds));
366 Raster(canvas, nullptr, gfx::Rect(), 1.f);
367 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
368
369 std::string b64_picture;
370 PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture);
371 state->SetString("skp64", b64_picture);
372 }
373
374 return state;
375 }
376
377 void DisplayItemList::GenerateDiscardableImagesMetadata() {
378 // This should be only called once.
379 DCHECK(image_map_.empty());
380
381 gfx::Rect bounds = rtree_.GetBounds();
382 DiscardableImageMap::ScopedMetadataGenerator generator(
383 &image_map_, gfx::Size(bounds.right(), bounds.bottom()));
384 auto* canvas = generator.canvas();
385 for (const auto& item : inputs_.items)
386 item.Raster(canvas, nullptr);
387 }
388
389 void DisplayItemList::GetDiscardableImagesInRect(
390 const gfx::Rect& rect,
391 float contents_scale,
392 std::vector<DrawImage>* images) {
393 image_map_.GetDiscardableImagesInRect(rect, contents_scale, images);
394 }
395
396 gfx::Rect DisplayItemList::GetRectForImage(ImageId image_id) const {
397 return image_map_.GetRectForImage(image_id);
398 }
399
400 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698