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

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

Issue 1418573002: cc: Add image decode control in the compositor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 11 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
« no previous file with comments | « cc/playback/display_list_raster_source.h ('k') | cc/playback/draw_image.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_list_raster_source.h" 5 #include "cc/playback/display_list_raster_source.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/containers/adapters.h"
9 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
10 #include "cc/base/region.h" 11 #include "cc/base/region.h"
11 #include "cc/debug/debug_colors.h" 12 #include "cc/debug/debug_colors.h"
13 #include "cc/playback/discardable_image_map.h"
12 #include "cc/playback/display_item_list.h" 14 #include "cc/playback/display_item_list.h"
15 #include "cc/tiles/image_decode_controller.h"
13 #include "skia/ext/analysis_canvas.h" 16 #include "skia/ext/analysis_canvas.h"
14 #include "third_party/skia/include/core/SkCanvas.h" 17 #include "third_party/skia/include/core/SkCanvas.h"
15 #include "third_party/skia/include/core/SkPictureRecorder.h" 18 #include "third_party/skia/include/core/SkPictureRecorder.h"
19 #include "third_party/skia/include/utils/SkNWayCanvas.h"
16 #include "ui/gfx/geometry/rect_conversions.h" 20 #include "ui/gfx/geometry/rect_conversions.h"
17 21
18 namespace cc { 22 namespace cc {
19 23
24 namespace {
25
26 SkIRect RoundOutRect(const SkRect& rect) {
27 SkIRect result;
28 rect.roundOut(&result);
29 return result;
30 }
31
32 class ImageHijackCanvas : public SkNWayCanvas {
33 public:
34 ImageHijackCanvas(int width,
35 int height,
36 ImageDecodeController* image_decode_controller)
37 : SkNWayCanvas(width, height),
38 image_decode_controller_(image_decode_controller) {}
39
40 protected:
41 // Ensure that pictures are unpacked by this canvas, instead of being
42 // forwarded to the raster canvas.
43 void onDrawPicture(const SkPicture* picture,
44 const SkMatrix* matrix,
45 const SkPaint* paint) override {
46 SkCanvas::onDrawPicture(picture, matrix, paint);
47 }
48
49 void onDrawImage(const SkImage* image,
50 SkScalar x,
51 SkScalar y,
52 const SkPaint* paint) override {
53 if (!image->isLazyGenerated()) {
54 SkNWayCanvas::onDrawImage(image, x, y, paint);
55 return;
56 }
57
58 SkMatrix ctm = getTotalMatrix();
59
60 SkSize scale;
61 bool is_decomposable = ExtractScale(ctm, &scale);
62 ScopedDecodedImageLock scoped_lock(
63 image_decode_controller_, image,
64 SkRect::MakeIWH(image->width(), image->height()), scale,
65 is_decomposable, ctm.hasPerspective(), paint);
66 const DecodedDrawImage& decoded_image = scoped_lock.decoded_image();
67 DCHECK_EQ(0, static_cast<int>(decoded_image.src_rect_offset().width()));
68 DCHECK_EQ(0, static_cast<int>(decoded_image.src_rect_offset().height()));
69 const SkPaint* decoded_paint = scoped_lock.decoded_paint();
70
71 bool need_scale = !decoded_image.is_scale_adjustment_identity();
72 if (need_scale) {
73 SkNWayCanvas::save();
74 SkNWayCanvas::scale(1.f / (decoded_image.scale_adjustment().width()),
75 1.f / (decoded_image.scale_adjustment().height()));
76 }
77 SkNWayCanvas::onDrawImage(decoded_image.image(), x, y, decoded_paint);
78 if (need_scale)
79 SkNWayCanvas::restore();
80 }
81
82 void onDrawImageRect(const SkImage* image,
83 const SkRect* src,
84 const SkRect& dst,
85 const SkPaint* paint,
86 SrcRectConstraint constraint) override {
87 if (!image->isLazyGenerated()) {
88 SkNWayCanvas::onDrawImageRect(image, src, dst, paint, constraint);
89 return;
90 }
91
92 SkRect src_storage;
93 if (!src) {
94 src_storage = SkRect::MakeIWH(image->width(), image->height());
95 src = &src_storage;
96 }
97 SkMatrix matrix;
98 matrix.setRectToRect(*src, dst, SkMatrix::kFill_ScaleToFit);
99 matrix.postConcat(getTotalMatrix());
100
101 SkSize scale;
102 bool is_decomposable = ExtractScale(matrix, &scale);
103 ScopedDecodedImageLock scoped_lock(image_decode_controller_, image, *src,
104 scale, is_decomposable,
105 matrix.hasPerspective(), paint);
106 const DecodedDrawImage& decoded_image = scoped_lock.decoded_image();
107 const SkPaint* decoded_paint = scoped_lock.decoded_paint();
108
109 SkRect adjusted_src =
110 src->makeOffset(decoded_image.src_rect_offset().width(),
111 decoded_image.src_rect_offset().height());
112 if (!decoded_image.is_scale_adjustment_identity()) {
113 float x_scale = decoded_image.scale_adjustment().width();
114 float y_scale = decoded_image.scale_adjustment().height();
115 adjusted_src = SkRect::MakeXYWH(
116 adjusted_src.x() * x_scale, adjusted_src.y() * y_scale,
117 adjusted_src.width() * x_scale, adjusted_src.height() * y_scale);
118 }
119 SkNWayCanvas::onDrawImageRect(decoded_image.image(), &adjusted_src, dst,
120 decoded_paint, constraint);
121 }
122
123 void onDrawImageNine(const SkImage* image,
124 const SkIRect& center,
125 const SkRect& dst,
126 const SkPaint* paint) override {
127 // No cc embedder issues image nine calls.
128 NOTREACHED();
129 }
130
131 private:
132 class ScopedDecodedImageLock {
133 public:
134 ScopedDecodedImageLock(ImageDecodeController* image_decode_controller,
135 const SkImage* image,
136 const SkRect& src_rect,
137 const SkSize& scale,
138 bool is_decomposable,
139 bool has_perspective,
140 const SkPaint* paint)
141 : image_decode_controller_(image_decode_controller),
142 paint_(paint),
143 draw_image_(image,
144 RoundOutRect(src_rect),
145 scale,
146 paint ? paint->getFilterQuality() : kNone_SkFilterQuality,
147 has_perspective,
148 is_decomposable),
149 decoded_draw_image_(
150 image_decode_controller_->GetDecodedImageForDraw(draw_image_)) {
151 DCHECK(image->isLazyGenerated());
152 if (paint) {
153 decoded_paint_ = *paint;
154 decoded_paint_.setFilterQuality(decoded_draw_image_.filter_quality());
155 }
156 }
157
158 ~ScopedDecodedImageLock() {
159 image_decode_controller_->DrawWithImageFinished(draw_image_,
160 decoded_draw_image_);
161 }
162
163 const DecodedDrawImage& decoded_image() const {
164 return decoded_draw_image_;
165 }
166 const SkPaint* decoded_paint() const {
167 return paint_ ? &decoded_paint_ : nullptr;
168 }
169
170 private:
171 ImageDecodeController* image_decode_controller_;
172 const SkPaint* paint_;
173 DrawImage draw_image_;
174 DecodedDrawImage decoded_draw_image_;
175 SkPaint decoded_paint_;
176 };
177
178 ImageDecodeController* image_decode_controller_;
179 };
180
181 } // namespace
182
20 scoped_refptr<DisplayListRasterSource> 183 scoped_refptr<DisplayListRasterSource>
21 DisplayListRasterSource::CreateFromDisplayListRecordingSource( 184 DisplayListRasterSource::CreateFromDisplayListRecordingSource(
22 const DisplayListRecordingSource* other, 185 const DisplayListRecordingSource* other,
23 bool can_use_lcd_text) { 186 bool can_use_lcd_text) {
24 return make_scoped_refptr( 187 return make_scoped_refptr(
25 new DisplayListRasterSource(other, can_use_lcd_text)); 188 new DisplayListRasterSource(other, can_use_lcd_text));
26 } 189 }
27 190
28 DisplayListRasterSource::DisplayListRasterSource( 191 DisplayListRasterSource::DisplayListRasterSource(
29 const DisplayListRecordingSource* other, 192 const DisplayListRecordingSource* other,
30 bool can_use_lcd_text) 193 bool can_use_lcd_text)
31 : display_list_(other->display_list_), 194 : display_list_(other->display_list_),
32 painter_reported_memory_usage_(other->painter_reported_memory_usage_), 195 painter_reported_memory_usage_(other->painter_reported_memory_usage_),
33 background_color_(other->background_color_), 196 background_color_(other->background_color_),
34 requires_clear_(other->requires_clear_), 197 requires_clear_(other->requires_clear_),
35 can_use_lcd_text_(can_use_lcd_text), 198 can_use_lcd_text_(can_use_lcd_text),
36 is_solid_color_(other->is_solid_color_), 199 is_solid_color_(other->is_solid_color_),
37 solid_color_(other->solid_color_), 200 solid_color_(other->solid_color_),
38 recorded_viewport_(other->recorded_viewport_), 201 recorded_viewport_(other->recorded_viewport_),
39 size_(other->size_), 202 size_(other->size_),
40 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), 203 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_),
41 slow_down_raster_scale_factor_for_debug_( 204 slow_down_raster_scale_factor_for_debug_(
42 other->slow_down_raster_scale_factor_for_debug_), 205 other->slow_down_raster_scale_factor_for_debug_),
43 should_attempt_to_use_distance_field_text_(false) {} 206 should_attempt_to_use_distance_field_text_(false),
207 image_decode_controller_(nullptr) {}
44 208
45 DisplayListRasterSource::DisplayListRasterSource( 209 DisplayListRasterSource::DisplayListRasterSource(
46 const DisplayListRasterSource* other, 210 const DisplayListRasterSource* other,
47 bool can_use_lcd_text) 211 bool can_use_lcd_text)
48 : display_list_(other->display_list_), 212 : display_list_(other->display_list_),
49 painter_reported_memory_usage_(other->painter_reported_memory_usage_), 213 painter_reported_memory_usage_(other->painter_reported_memory_usage_),
50 background_color_(other->background_color_), 214 background_color_(other->background_color_),
51 requires_clear_(other->requires_clear_), 215 requires_clear_(other->requires_clear_),
52 can_use_lcd_text_(can_use_lcd_text), 216 can_use_lcd_text_(can_use_lcd_text),
53 is_solid_color_(other->is_solid_color_), 217 is_solid_color_(other->is_solid_color_),
54 solid_color_(other->solid_color_), 218 solid_color_(other->solid_color_),
55 recorded_viewport_(other->recorded_viewport_), 219 recorded_viewport_(other->recorded_viewport_),
56 size_(other->size_), 220 size_(other->size_),
57 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), 221 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_),
58 slow_down_raster_scale_factor_for_debug_( 222 slow_down_raster_scale_factor_for_debug_(
59 other->slow_down_raster_scale_factor_for_debug_), 223 other->slow_down_raster_scale_factor_for_debug_),
60 should_attempt_to_use_distance_field_text_( 224 should_attempt_to_use_distance_field_text_(
61 other->should_attempt_to_use_distance_field_text_) {} 225 other->should_attempt_to_use_distance_field_text_),
226 image_decode_controller_(other->image_decode_controller_) {}
62 227
63 DisplayListRasterSource::~DisplayListRasterSource() { 228 DisplayListRasterSource::~DisplayListRasterSource() {
64 } 229 }
65 230
66 void DisplayListRasterSource::PlaybackToSharedCanvas( 231 void DisplayListRasterSource::PlaybackToSharedCanvas(
67 SkCanvas* canvas, 232 SkCanvas* raster_canvas,
68 const gfx::Rect& canvas_rect, 233 const gfx::Rect& canvas_rect,
69 float contents_scale) const { 234 float contents_scale) const {
70 RasterCommon(canvas, NULL, canvas_rect, canvas_rect, contents_scale); 235 // TODO(vmpstr): This can be improved by plumbing whether the tile itself has
236 // discardable images. This way we would only pay for the hijack canvas if the
237 // tile actually needed it.
238 if (display_list_->MayHaveDiscardableImages()) {
239 const SkImageInfo& info = raster_canvas->imageInfo();
240 ImageHijackCanvas canvas(info.width(), info.height(),
241 image_decode_controller_);
242 canvas.addCanvas(raster_canvas);
243
244 RasterCommon(&canvas, nullptr, canvas_rect, canvas_rect, contents_scale);
245 } else {
246 RasterCommon(raster_canvas, nullptr, canvas_rect, canvas_rect,
247 contents_scale);
248 }
71 } 249 }
72 250
73 void DisplayListRasterSource::RasterForAnalysis(skia::AnalysisCanvas* canvas, 251 void DisplayListRasterSource::RasterForAnalysis(skia::AnalysisCanvas* canvas,
74 const gfx::Rect& canvas_rect, 252 const gfx::Rect& canvas_rect,
75 float contents_scale) const { 253 float contents_scale) const {
76 RasterCommon(canvas, canvas, canvas_rect, canvas_rect, contents_scale); 254 RasterCommon(canvas, canvas, canvas_rect, canvas_rect, contents_scale);
77 } 255 }
78 256
79 void DisplayListRasterSource::PlaybackToCanvas( 257 void DisplayListRasterSource::PlaybackToCanvas(
80 SkCanvas* canvas, 258 SkCanvas* raster_canvas,
81 const gfx::Rect& canvas_bitmap_rect, 259 const gfx::Rect& canvas_bitmap_rect,
82 const gfx::Rect& canvas_playback_rect, 260 const gfx::Rect& canvas_playback_rect,
83 float contents_scale) const { 261 float contents_scale) const {
84 PrepareForPlaybackToCanvas(canvas, canvas_bitmap_rect, canvas_playback_rect, 262 PrepareForPlaybackToCanvas(raster_canvas, canvas_bitmap_rect,
85 contents_scale); 263 canvas_playback_rect, contents_scale);
86 RasterCommon(canvas, NULL, canvas_bitmap_rect, canvas_playback_rect, 264
265 SkImageInfo info = raster_canvas->imageInfo();
266 ImageHijackCanvas canvas(info.width(), info.height(),
267 image_decode_controller_);
268 canvas.addCanvas(raster_canvas);
269 RasterCommon(&canvas, NULL, canvas_bitmap_rect, canvas_playback_rect,
87 contents_scale); 270 contents_scale);
88 } 271 }
89 272
90 void DisplayListRasterSource::PrepareForPlaybackToCanvas( 273 void DisplayListRasterSource::PrepareForPlaybackToCanvas(
91 SkCanvas* canvas, 274 SkCanvas* canvas,
92 const gfx::Rect& canvas_bitmap_rect, 275 const gfx::Rect& canvas_bitmap_rect,
93 const gfx::Rect& canvas_playback_rect, 276 const gfx::Rect& canvas_playback_rect,
94 float contents_scale) const { 277 float contents_scale) const {
95 // TODO(hendrikw): See if we can split this up into separate functions. 278 // TODO(hendrikw): See if we can split this up into separate functions.
96 bool partial_update = canvas_bitmap_rect != canvas_playback_rect; 279 bool partial_update = canvas_bitmap_rect != canvas_playback_rect;
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 return can_use_lcd_text_; 482 return can_use_lcd_text_;
300 } 483 }
301 484
302 scoped_refptr<DisplayListRasterSource> 485 scoped_refptr<DisplayListRasterSource>
303 DisplayListRasterSource::CreateCloneWithoutLCDText() const { 486 DisplayListRasterSource::CreateCloneWithoutLCDText() const {
304 bool can_use_lcd_text = false; 487 bool can_use_lcd_text = false;
305 return scoped_refptr<DisplayListRasterSource>( 488 return scoped_refptr<DisplayListRasterSource>(
306 new DisplayListRasterSource(this, can_use_lcd_text)); 489 new DisplayListRasterSource(this, can_use_lcd_text));
307 } 490 }
308 491
492 void DisplayListRasterSource::SetImageDecodeController(
493 ImageDecodeController* image_decode_controller) {
494 DCHECK(image_decode_controller);
495 // Note that although this function should only be called once, tests tend to
496 // call it several times using the same controller.
497 DCHECK(!image_decode_controller_ ||
498 image_decode_controller_ == image_decode_controller);
499 image_decode_controller_ = image_decode_controller;
500 }
501
309 } // namespace cc 502 } // namespace cc
OLDNEW
« no previous file with comments | « cc/playback/display_list_raster_source.h ('k') | cc/playback/draw_image.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698