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

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

Issue 1837263005: cc: Rename DisplayListRasterSource to just RasterSource. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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_list_raster_source.h"
6
7 #include <stddef.h>
8
9 #include "base/strings/stringprintf.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/trace_event/memory_dump_manager.h"
12 #include "base/trace_event/trace_event.h"
13 #include "cc/base/region.h"
14 #include "cc/debug/debug_colors.h"
15 #include "cc/playback/display_item_list.h"
16 #include "cc/playback/image_hijack_canvas.h"
17 #include "cc/playback/skip_image_canvas.h"
18 #include "skia/ext/analysis_canvas.h"
19 #include "third_party/skia/include/core/SkCanvas.h"
20 #include "third_party/skia/include/core/SkPictureRecorder.h"
21 #include "third_party/skia/include/core/SkTLazy.h"
22 #include "ui/gfx/geometry/rect_conversions.h"
23
24 namespace cc {
25
26 scoped_refptr<DisplayListRasterSource>
27 DisplayListRasterSource::CreateFromDisplayListRecordingSource(
28 const DisplayListRecordingSource* other,
29 bool can_use_lcd_text) {
30 return make_scoped_refptr(
31 new DisplayListRasterSource(other, can_use_lcd_text));
32 }
33
34 DisplayListRasterSource::DisplayListRasterSource(
35 const DisplayListRecordingSource* other,
36 bool can_use_lcd_text)
37 : display_list_(other->display_list_),
38 painter_reported_memory_usage_(other->painter_reported_memory_usage_),
39 background_color_(other->background_color_),
40 requires_clear_(other->requires_clear_),
41 can_use_lcd_text_(can_use_lcd_text),
42 is_solid_color_(other->is_solid_color_),
43 solid_color_(other->solid_color_),
44 recorded_viewport_(other->recorded_viewport_),
45 size_(other->size_),
46 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_),
47 slow_down_raster_scale_factor_for_debug_(
48 other->slow_down_raster_scale_factor_for_debug_),
49 should_attempt_to_use_distance_field_text_(false),
50 image_decode_controller_(nullptr) {
51 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
52 // Don't register a dump provider in these cases.
53 // TODO(ericrk): Get this working in Android Webview. crbug.com/517156
54 if (base::ThreadTaskRunnerHandle::IsSet()) {
55 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
56 this, "cc::DisplayListRasterSource",
57 base::ThreadTaskRunnerHandle::Get());
58 }
59 }
60
61 DisplayListRasterSource::DisplayListRasterSource(
62 const DisplayListRasterSource* other,
63 bool can_use_lcd_text)
64 : display_list_(other->display_list_),
65 painter_reported_memory_usage_(other->painter_reported_memory_usage_),
66 background_color_(other->background_color_),
67 requires_clear_(other->requires_clear_),
68 can_use_lcd_text_(can_use_lcd_text),
69 is_solid_color_(other->is_solid_color_),
70 solid_color_(other->solid_color_),
71 recorded_viewport_(other->recorded_viewport_),
72 size_(other->size_),
73 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_),
74 slow_down_raster_scale_factor_for_debug_(
75 other->slow_down_raster_scale_factor_for_debug_),
76 should_attempt_to_use_distance_field_text_(
77 other->should_attempt_to_use_distance_field_text_),
78 image_decode_controller_(other->image_decode_controller_) {
79 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
80 // Don't register a dump provider in these cases.
81 // TODO(ericrk): Get this working in Android Webview. crbug.com/517156
82 if (base::ThreadTaskRunnerHandle::IsSet()) {
83 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
84 this, "cc::DisplayListRasterSource",
85 base::ThreadTaskRunnerHandle::Get());
86 }
87 }
88
89 DisplayListRasterSource::~DisplayListRasterSource() {
90 // For MemoryDumpProvider deregistration to work correctly, this must happen
91 // on the same thread that the DisplayListRasterSource was created on.
92 DCHECK(memory_dump_thread_checker_.CalledOnValidThread());
93 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
94 this);
95 }
96
97 void DisplayListRasterSource::PlaybackToSharedCanvas(
98 SkCanvas* raster_canvas,
99 const gfx::Rect& canvas_rect,
100 float contents_scale,
101 bool include_images) const {
102 // TODO(vmpstr): This can be improved by plumbing whether the tile itself has
103 // discardable images. This way we would only pay for the hijack canvas if the
104 // tile actually needed it.
105 if (!include_images) {
106 SkipImageCanvas canvas(raster_canvas);
107 RasterCommon(&canvas, nullptr, canvas_rect, canvas_rect, contents_scale);
108 } else if (display_list_->MayHaveDiscardableImages()) {
109 const SkImageInfo& info = raster_canvas->imageInfo();
110 ImageHijackCanvas canvas(info.width(), info.height(),
111 image_decode_controller_);
112 canvas.addCanvas(raster_canvas);
113
114 RasterCommon(&canvas, nullptr, canvas_rect, canvas_rect, contents_scale);
115 } else {
116 RasterCommon(raster_canvas, nullptr, canvas_rect, canvas_rect,
117 contents_scale);
118 }
119 }
120
121 void DisplayListRasterSource::RasterForAnalysis(skia::AnalysisCanvas* canvas,
122 const gfx::Rect& canvas_rect,
123 float contents_scale) const {
124 RasterCommon(canvas, canvas, canvas_rect, canvas_rect, contents_scale);
125 }
126
127 void DisplayListRasterSource::PlaybackToCanvas(
128 SkCanvas* raster_canvas,
129 const gfx::Rect& canvas_bitmap_rect,
130 const gfx::Rect& canvas_playback_rect,
131 float contents_scale,
132 bool include_images) const {
133 PrepareForPlaybackToCanvas(raster_canvas, canvas_bitmap_rect,
134 canvas_playback_rect, contents_scale);
135
136 if (!include_images) {
137 SkipImageCanvas canvas(raster_canvas);
138 RasterCommon(&canvas, nullptr, canvas_bitmap_rect, canvas_playback_rect,
139 contents_scale);
140 } else if (display_list_->MayHaveDiscardableImages()) {
141 const SkImageInfo& info = raster_canvas->imageInfo();
142 ImageHijackCanvas canvas(info.width(), info.height(),
143 image_decode_controller_);
144 canvas.addCanvas(raster_canvas);
145 RasterCommon(&canvas, nullptr, canvas_bitmap_rect, canvas_playback_rect,
146 contents_scale);
147 } else {
148 RasterCommon(raster_canvas, nullptr, canvas_bitmap_rect,
149 canvas_playback_rect, contents_scale);
150 }
151 }
152
153 void DisplayListRasterSource::PrepareForPlaybackToCanvas(
154 SkCanvas* canvas,
155 const gfx::Rect& canvas_bitmap_rect,
156 const gfx::Rect& canvas_playback_rect,
157 float contents_scale) const {
158 // TODO(hendrikw): See if we can split this up into separate functions.
159 bool partial_update = canvas_bitmap_rect != canvas_playback_rect;
160
161 if (!partial_update)
162 canvas->discard();
163 if (clear_canvas_with_debug_color_) {
164 // Any non-painted areas in the content bounds will be left in this color.
165 if (!partial_update) {
166 canvas->clear(DebugColors::NonPaintedFillColor());
167 } else {
168 canvas->save();
169 canvas->clipRect(gfx::RectToSkRect(
170 canvas_playback_rect - canvas_bitmap_rect.OffsetFromOrigin()));
171 canvas->drawColor(DebugColors::NonPaintedFillColor());
172 canvas->restore();
173 }
174 }
175
176 // If this raster source has opaque contents, it is guaranteeing that it will
177 // draw an opaque rect the size of the layer. If it is not, then we must
178 // clear this canvas ourselves.
179 if (requires_clear_) {
180 TRACE_EVENT_INSTANT0("cc", "SkCanvas::clear", TRACE_EVENT_SCOPE_THREAD);
181 // Clearing is about ~4x faster than drawing a rect even if the content
182 // isn't covering a majority of the canvas.
183 if (!partial_update) {
184 canvas->clear(SK_ColorTRANSPARENT);
185 } else {
186 canvas->save();
187 canvas->clipRect(gfx::RectToSkRect(
188 canvas_playback_rect - canvas_bitmap_rect.OffsetFromOrigin()));
189 canvas->drawColor(SK_ColorTRANSPARENT, SkXfermode::kClear_Mode);
190 canvas->restore();
191 }
192 } else {
193 // Even if completely covered, for rasterizations that touch the edge of the
194 // layer, we also need to raster the background color underneath the last
195 // texel (since the recording won't cover it) and outside the last texel
196 // (due to linear filtering when using this texture).
197 gfx::Rect content_rect =
198 gfx::ScaleToEnclosingRect(gfx::Rect(size_), contents_scale);
199
200 // The final texel of content may only be partially covered by a
201 // rasterization; this rect represents the content rect that is fully
202 // covered by content.
203 gfx::Rect deflated_content_rect = content_rect;
204 deflated_content_rect.Inset(0, 0, 1, 1);
205 deflated_content_rect.Intersect(canvas_playback_rect);
206 if (!deflated_content_rect.Contains(canvas_playback_rect)) {
207 if (clear_canvas_with_debug_color_) {
208 // Any non-painted areas outside of the content bounds are left in
209 // this color. If this is seen then it means that cc neglected to
210 // rerasterize a tile that used to intersect with the content rect
211 // after the content bounds grew.
212 canvas->save();
213 canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
214 canvas->clipRect(gfx::RectToSkRect(content_rect),
215 SkRegion::kDifference_Op);
216 canvas->drawColor(DebugColors::MissingResizeInvalidations(),
217 SkXfermode::kSrc_Mode);
218 canvas->restore();
219 }
220
221 // Drawing at most 2 x 2 x (canvas width + canvas height) texels is 2-3X
222 // faster than clearing, so special case this.
223 canvas->save();
224 canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
225 gfx::Rect inflated_content_rect = content_rect;
226 // Only clear edges that will be inside the canvas_playback_rect, else we
227 // clear things that are still valid from a previous raster.
228 inflated_content_rect.Inset(0, 0, -1, -1);
229 inflated_content_rect.Intersect(canvas_playback_rect);
230 canvas->clipRect(gfx::RectToSkRect(inflated_content_rect),
231 SkRegion::kReplace_Op);
232 canvas->clipRect(gfx::RectToSkRect(deflated_content_rect),
233 SkRegion::kDifference_Op);
234 canvas->drawColor(background_color_, SkXfermode::kSrc_Mode);
235 canvas->restore();
236 }
237 }
238 }
239
240 void DisplayListRasterSource::RasterCommon(
241 SkCanvas* canvas,
242 SkPicture::AbortCallback* callback,
243 const gfx::Rect& canvas_bitmap_rect,
244 const gfx::Rect& canvas_playback_rect,
245 float contents_scale) const {
246 canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
247 gfx::Rect content_rect =
248 gfx::ScaleToEnclosingRect(gfx::Rect(size_), contents_scale);
249 content_rect.Intersect(canvas_playback_rect);
250
251 canvas->clipRect(gfx::RectToSkRect(content_rect), SkRegion::kIntersect_Op);
252
253 DCHECK(display_list_.get());
254 gfx::Rect canvas_target_playback_rect =
255 canvas_playback_rect - canvas_bitmap_rect.OffsetFromOrigin();
256 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
257 for (int i = 0; i < repeat_count; ++i) {
258 display_list_->Raster(canvas, callback, canvas_target_playback_rect,
259 contents_scale);
260 }
261 }
262
263 sk_sp<SkPicture> DisplayListRasterSource::GetFlattenedPicture() {
264 TRACE_EVENT0("cc", "DisplayListRasterSource::GetFlattenedPicture");
265
266 gfx::Rect display_list_rect(size_);
267 SkPictureRecorder recorder;
268 SkCanvas* canvas = recorder.beginRecording(display_list_rect.width(),
269 display_list_rect.height());
270 if (!display_list_rect.IsEmpty()) {
271 PrepareForPlaybackToCanvas(canvas, display_list_rect, display_list_rect,
272 1.f);
273 RasterCommon(canvas, nullptr, display_list_rect, display_list_rect, 1.f);
274 }
275
276 return recorder.finishRecordingAsPicture();
277 }
278
279 size_t DisplayListRasterSource::GetPictureMemoryUsage() const {
280 if (!display_list_)
281 return 0;
282 return display_list_->ApproximateMemoryUsage() +
283 painter_reported_memory_usage_;
284 }
285
286 bool DisplayListRasterSource::PerformSolidColorAnalysis(
287 const gfx::Rect& content_rect,
288 float contents_scale,
289 SkColor* color) const {
290 TRACE_EVENT0("cc", "DisplayListRasterSource::PerformSolidColorAnalysis");
291
292 gfx::Rect layer_rect =
293 gfx::ScaleToEnclosingRect(content_rect, 1.0f / contents_scale);
294
295 layer_rect.Intersect(gfx::Rect(size_));
296 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height());
297 RasterForAnalysis(&canvas, layer_rect, 1.0f);
298 return canvas.GetColorIfSolid(color);
299 }
300
301 void DisplayListRasterSource::GetDiscardableImagesInRect(
302 const gfx::Rect& layer_rect,
303 float raster_scale,
304 std::vector<DrawImage>* images) const {
305 DCHECK_EQ(0u, images->size());
306 display_list_->GetDiscardableImagesInRect(layer_rect, raster_scale, images);
307 }
308
309 bool DisplayListRasterSource::CoversRect(const gfx::Rect& layer_rect) const {
310 if (size_.IsEmpty())
311 return false;
312 gfx::Rect bounded_rect = layer_rect;
313 bounded_rect.Intersect(gfx::Rect(size_));
314 return recorded_viewport_.Contains(bounded_rect);
315 }
316
317 gfx::Size DisplayListRasterSource::GetSize() const {
318 return size_;
319 }
320
321 bool DisplayListRasterSource::IsSolidColor() const {
322 return is_solid_color_;
323 }
324
325 SkColor DisplayListRasterSource::GetSolidColor() const {
326 DCHECK(IsSolidColor());
327 return solid_color_;
328 }
329
330 bool DisplayListRasterSource::HasRecordings() const {
331 return !!display_list_.get();
332 }
333
334 gfx::Rect DisplayListRasterSource::RecordedViewport() const {
335 return recorded_viewport_;
336 }
337
338 void DisplayListRasterSource::SetShouldAttemptToUseDistanceFieldText() {
339 should_attempt_to_use_distance_field_text_ = true;
340 }
341
342 bool DisplayListRasterSource::ShouldAttemptToUseDistanceFieldText() const {
343 return should_attempt_to_use_distance_field_text_;
344 }
345
346 void DisplayListRasterSource::AsValueInto(
347 base::trace_event::TracedValue* array) const {
348 if (display_list_.get())
349 TracedValue::AppendIDRef(display_list_.get(), array);
350 }
351
352 void DisplayListRasterSource::DidBeginTracing() {
353 if (display_list_.get())
354 display_list_->EmitTraceSnapshot();
355 }
356
357 bool DisplayListRasterSource::CanUseLCDText() const {
358 return can_use_lcd_text_;
359 }
360
361 scoped_refptr<DisplayListRasterSource>
362 DisplayListRasterSource::CreateCloneWithoutLCDText() const {
363 bool can_use_lcd_text = false;
364 return scoped_refptr<DisplayListRasterSource>(
365 new DisplayListRasterSource(this, can_use_lcd_text));
366 }
367
368 void DisplayListRasterSource::SetImageDecodeController(
369 ImageDecodeController* image_decode_controller) {
370 DCHECK(image_decode_controller);
371 image_decode_controller_ = image_decode_controller;
372 }
373
374 bool DisplayListRasterSource::OnMemoryDump(
375 const base::trace_event::MemoryDumpArgs& args,
376 base::trace_event::ProcessMemoryDump* pmd) {
377 DCHECK(memory_dump_thread_checker_.CalledOnValidThread());
378
379 uint64_t memory_usage = GetPictureMemoryUsage();
380 if (memory_usage > 0) {
381 std::string dump_name = base::StringPrintf(
382 "cc/display_lists/display_list_raster_source_%p", this);
383 base::trace_event::MemoryAllocatorDump* dump =
384 pmd->CreateAllocatorDump(dump_name);
385 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
386 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
387 memory_usage);
388 }
389 return true;
390 }
391
392 } // namespace cc
OLDNEW
« no previous file with comments | « cc/playback/display_list_raster_source.h ('k') | cc/playback/display_list_raster_source_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698