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/raster/raster_source.h" | 5 #include "cc/raster/raster_source.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/trace_event/trace_event.h" | 9 #include "base/trace_event/trace_event.h" |
10 #include "cc/base/math_util.h" | 10 #include "cc/base/math_util.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 size_(other->size_), | 56 size_(other->size_), |
57 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), | 57 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), |
58 slow_down_raster_scale_factor_for_debug_( | 58 slow_down_raster_scale_factor_for_debug_( |
59 other->slow_down_raster_scale_factor_for_debug_), | 59 other->slow_down_raster_scale_factor_for_debug_), |
60 image_decode_cache_(other->image_decode_cache_) {} | 60 image_decode_cache_(other->image_decode_cache_) {} |
61 | 61 |
62 RasterSource::~RasterSource() {} | 62 RasterSource::~RasterSource() {} |
63 | 63 |
64 void RasterSource::PlaybackToCanvas( | 64 void RasterSource::PlaybackToCanvas( |
65 SkCanvas* raster_canvas, | 65 SkCanvas* raster_canvas, |
66 const gfx::ColorSpace& canvas_color_space, | 66 const gfx::ColorSpace& target_color_space, |
67 const gfx::Rect& canvas_bitmap_rect, | 67 const gfx::Rect& canvas_bitmap_rect, |
68 const gfx::Rect& canvas_playback_rect, | 68 const gfx::Rect& canvas_playback_rect, |
69 const gfx::AxisTransform2d& raster_transform, | 69 const gfx::AxisTransform2d& raster_transform, |
70 const PlaybackSettings& settings) const { | 70 const PlaybackSettings& settings) const { |
71 SkIRect raster_bounds = gfx::RectToSkIRect(canvas_bitmap_rect); | 71 SkIRect raster_bounds = gfx::RectToSkIRect(canvas_bitmap_rect); |
72 if (!canvas_playback_rect.IsEmpty() && | 72 if (!canvas_playback_rect.IsEmpty() && |
73 !raster_bounds.intersect(gfx::RectToSkIRect(canvas_playback_rect))) | 73 !raster_bounds.intersect(gfx::RectToSkIRect(canvas_playback_rect))) |
74 return; | 74 return; |
75 // Treat all subnormal values as zero for performance. | 75 // Treat all subnormal values as zero for performance. |
76 ScopedSubnormalFloatDisabler disabler; | 76 ScopedSubnormalFloatDisabler disabler; |
77 | 77 |
78 raster_canvas->save(); | 78 raster_canvas->save(); |
79 raster_canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); | 79 raster_canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); |
80 raster_canvas->clipRect(SkRect::MakeFromIRect(raster_bounds)); | 80 raster_canvas->clipRect(SkRect::MakeFromIRect(raster_bounds)); |
81 raster_canvas->translate(raster_transform.translation().x(), | 81 raster_canvas->translate(raster_transform.translation().x(), |
82 raster_transform.translation().y()); | 82 raster_transform.translation().y()); |
83 raster_canvas->scale(raster_transform.scale(), raster_transform.scale()); | 83 raster_canvas->scale(raster_transform.scale(), raster_transform.scale()); |
84 PlaybackToCanvas(raster_canvas, canvas_color_space, settings); | 84 PlaybackToCanvas(raster_canvas, target_color_space, settings); |
85 raster_canvas->restore(); | 85 raster_canvas->restore(); |
86 } | 86 } |
87 | 87 |
88 void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas, | 88 void RasterSource::PlaybackToCanvas(SkCanvas* input_canvas, |
89 const gfx::ColorSpace& canvas_color_space, | 89 const gfx::ColorSpace& target_color_space, |
90 const PlaybackSettings& settings) const { | 90 const PlaybackSettings& settings) const { |
| 91 SkCanvas* raster_canvas = input_canvas; |
| 92 std::unique_ptr<SkCanvas> color_transform_canvas; |
| 93 if (target_color_space.IsValid()) { |
| 94 color_transform_canvas = SkCreateColorSpaceXformCanvas( |
| 95 input_canvas, target_color_space.ToSkColorSpace()); |
| 96 raster_canvas = color_transform_canvas.get(); |
| 97 } |
| 98 |
91 if (!settings.playback_to_shared_canvas) | 99 if (!settings.playback_to_shared_canvas) |
92 PrepareForPlaybackToCanvas(raster_canvas); | 100 PrepareForPlaybackToCanvas(raster_canvas); |
93 | 101 |
94 if (settings.skip_images) { | 102 if (settings.skip_images) { |
95 SkipImageCanvas canvas(raster_canvas); | 103 SkipImageCanvas canvas(raster_canvas); |
96 RasterCommon(&canvas, canvas_color_space, nullptr); | 104 RasterCommon(&canvas, nullptr); |
97 } else if (settings.use_image_hijack_canvas) { | 105 } else if (settings.use_image_hijack_canvas) { |
98 const SkImageInfo& info = raster_canvas->imageInfo(); | 106 const SkImageInfo& info = raster_canvas->imageInfo(); |
99 ImageHijackCanvas canvas(info.width(), info.height(), image_decode_cache_, | 107 ImageHijackCanvas canvas(info.width(), info.height(), image_decode_cache_, |
100 &settings.images_to_skip); | 108 &settings.images_to_skip, target_color_space); |
101 // Before adding the canvas, make sure that the ImageHijackCanvas is aware | 109 // Before adding the canvas, make sure that the ImageHijackCanvas is aware |
102 // of the current transform and clip, which may affect the clip bounds. | 110 // of the current transform and clip, which may affect the clip bounds. |
103 // Since we query the clip bounds of the current canvas to get the list of | 111 // Since we query the clip bounds of the current canvas to get the list of |
104 // draw commands to process, this is important to produce correct content. | 112 // draw commands to process, this is important to produce correct content. |
105 canvas.clipRect( | 113 canvas.clipRect( |
106 SkRect::MakeFromIRect(raster_canvas->getDeviceClipBounds())); | 114 SkRect::MakeFromIRect(raster_canvas->getDeviceClipBounds())); |
107 canvas.setMatrix(raster_canvas->getTotalMatrix()); | 115 canvas.setMatrix(raster_canvas->getTotalMatrix()); |
108 canvas.addCanvas(raster_canvas); | 116 canvas.addCanvas(raster_canvas); |
109 | 117 |
110 RasterCommon(&canvas, canvas_color_space, nullptr); | 118 RasterCommon(&canvas, nullptr); |
111 } else { | 119 } else { |
112 RasterCommon(raster_canvas, canvas_color_space, nullptr); | 120 RasterCommon(raster_canvas, nullptr); |
113 } | 121 } |
114 } | 122 } |
115 | 123 |
116 namespace { | 124 namespace { |
117 | 125 |
118 bool CanvasIsUnclipped(const SkCanvas* canvas) { | 126 bool CanvasIsUnclipped(const SkCanvas* canvas) { |
119 if (!canvas->isClipRect()) | 127 if (!canvas->isClipRect()) |
120 return false; | 128 return false; |
121 | 129 |
122 SkIRect bounds; | 130 SkIRect bounds; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 canvas->save(); | 203 canvas->save(); |
196 // Use clipRegion to bypass CTM because the rects are device rects. | 204 // Use clipRegion to bypass CTM because the rects are device rects. |
197 SkRegion interest_region; | 205 SkRegion interest_region; |
198 interest_region.setRect(interest_rect); | 206 interest_region.setRect(interest_rect); |
199 interest_region.op(opaque_rect, SkRegion::kDifference_Op); | 207 interest_region.op(opaque_rect, SkRegion::kDifference_Op); |
200 canvas->clipRegion(interest_region); | 208 canvas->clipRegion(interest_region); |
201 canvas->clear(background_color_); | 209 canvas->clear(background_color_); |
202 canvas->restore(); | 210 canvas->restore(); |
203 } | 211 } |
204 | 212 |
205 void RasterSource::RasterCommon(SkCanvas* input_canvas, | 213 void RasterSource::RasterCommon(SkCanvas* raster_canvas, |
206 const gfx::ColorSpace& target_color_space, | |
207 SkPicture::AbortCallback* callback) const { | 214 SkPicture::AbortCallback* callback) const { |
208 SkCanvas* raster_canvas = input_canvas; | |
209 std::unique_ptr<SkCanvas> color_transform_canvas; | |
210 if (target_color_space.IsValid()) { | |
211 color_transform_canvas = SkCreateColorSpaceXformCanvas( | |
212 input_canvas, target_color_space.ToSkColorSpace()); | |
213 raster_canvas = color_transform_canvas.get(); | |
214 } | |
215 DCHECK(display_list_.get()); | 215 DCHECK(display_list_.get()); |
216 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); | 216 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); |
217 for (int i = 0; i < repeat_count; ++i) | 217 for (int i = 0; i < repeat_count; ++i) |
218 display_list_->Raster(raster_canvas, callback); | 218 display_list_->Raster(raster_canvas, callback); |
219 } | 219 } |
220 | 220 |
221 sk_sp<SkPicture> RasterSource::GetFlattenedPicture() { | 221 sk_sp<SkPicture> RasterSource::GetFlattenedPicture() { |
222 TRACE_EVENT0("cc", "RasterSource::GetFlattenedPicture"); | 222 TRACE_EVENT0("cc", "RasterSource::GetFlattenedPicture"); |
223 | 223 |
224 SkPictureRecorder recorder; | 224 SkPictureRecorder recorder; |
225 SkCanvas* canvas = recorder.beginRecording(size_.width(), size_.height()); | 225 SkCanvas* canvas = recorder.beginRecording(size_.width(), size_.height()); |
226 if (!size_.IsEmpty()) { | 226 if (!size_.IsEmpty()) { |
227 PrepareForPlaybackToCanvas(canvas); | 227 PrepareForPlaybackToCanvas(canvas); |
228 // No target color space should be set for generating an SkPicture. | 228 RasterCommon(canvas, nullptr); |
229 RasterCommon(canvas, gfx::ColorSpace(), nullptr); | |
230 } | 229 } |
231 | 230 |
232 return recorder.finishRecordingAsPicture(); | 231 return recorder.finishRecordingAsPicture(); |
233 } | 232 } |
234 | 233 |
235 size_t RasterSource::GetMemoryUsage() const { | 234 size_t RasterSource::GetMemoryUsage() const { |
236 if (!display_list_) | 235 if (!display_list_) |
237 return 0; | 236 return 0; |
238 return display_list_->ApproximateMemoryUsage() + | 237 return display_list_->ApproximateMemoryUsage() + |
239 painter_reported_memory_usage_; | 238 painter_reported_memory_usage_; |
240 } | 239 } |
241 | 240 |
242 bool RasterSource::PerformSolidColorAnalysis(const gfx::Rect& content_rect, | 241 bool RasterSource::PerformSolidColorAnalysis(const gfx::Rect& content_rect, |
243 float contents_scale, | 242 float contents_scale, |
244 SkColor* color) const { | 243 SkColor* color) const { |
245 TRACE_EVENT0("cc", "RasterSource::PerformSolidColorAnalysis"); | 244 TRACE_EVENT0("cc", "RasterSource::PerformSolidColorAnalysis"); |
246 | 245 |
247 gfx::Rect layer_rect = | 246 gfx::Rect layer_rect = |
248 gfx::ScaleToEnclosingRect(content_rect, 1.f / contents_scale); | 247 gfx::ScaleToEnclosingRect(content_rect, 1.f / contents_scale); |
249 | 248 |
250 layer_rect.Intersect(gfx::Rect(size_)); | 249 layer_rect.Intersect(gfx::Rect(size_)); |
251 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); | 250 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); |
252 canvas.translate(-layer_rect.x(), -layer_rect.y()); | 251 canvas.translate(-layer_rect.x(), -layer_rect.y()); |
253 // No target color space should be set for solid color analysis (the | 252 // Note that because no color conversion is applied to solid color analysis, |
254 // resulting solid color will be known to be sRGB). | 253 // the resulting solid color will be known to be sRGB. |
255 RasterCommon(&canvas, gfx::ColorSpace(), &canvas); | 254 RasterCommon(&canvas, &canvas); |
256 return canvas.GetColorIfSolid(color); | 255 return canvas.GetColorIfSolid(color); |
257 } | 256 } |
258 | 257 |
259 void RasterSource::GetDiscardableImagesInRect( | 258 void RasterSource::GetDiscardableImagesInRect( |
260 const gfx::Rect& layer_rect, | 259 const gfx::Rect& layer_rect, |
261 float contents_scale, | 260 float contents_scale, |
| 261 const gfx::ColorSpace& target_color_space, |
262 std::vector<DrawImage>* images) const { | 262 std::vector<DrawImage>* images) const { |
263 DCHECK_EQ(0u, images->size()); | 263 DCHECK_EQ(0u, images->size()); |
264 display_list_->GetDiscardableImagesInRect(layer_rect, contents_scale, images); | 264 display_list_->GetDiscardableImagesInRect(layer_rect, contents_scale, |
| 265 target_color_space, images); |
265 } | 266 } |
266 | 267 |
267 gfx::Rect RasterSource::GetRectForImage(ImageId image_id) const { | 268 gfx::Rect RasterSource::GetRectForImage(ImageId image_id) const { |
268 if (!display_list_) | 269 if (!display_list_) |
269 return gfx::Rect(); | 270 return gfx::Rect(); |
270 return display_list_->GetRectForImage(image_id); | 271 return display_list_->GetRectForImage(image_id); |
271 } | 272 } |
272 | 273 |
273 bool RasterSource::CoversRect(const gfx::Rect& layer_rect) const { | 274 bool RasterSource::CoversRect(const gfx::Rect& layer_rect) const { |
274 if (size_.IsEmpty()) | 275 if (size_.IsEmpty()) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 use_image_hijack_canvas(true) {} | 325 use_image_hijack_canvas(true) {} |
325 | 326 |
326 RasterSource::PlaybackSettings::PlaybackSettings(const PlaybackSettings&) = | 327 RasterSource::PlaybackSettings::PlaybackSettings(const PlaybackSettings&) = |
327 default; | 328 default; |
328 | 329 |
329 RasterSource::PlaybackSettings::PlaybackSettings(PlaybackSettings&&) = default; | 330 RasterSource::PlaybackSettings::PlaybackSettings(PlaybackSettings&&) = default; |
330 | 331 |
331 RasterSource::PlaybackSettings::~PlaybackSettings() = default; | 332 RasterSource::PlaybackSettings::~PlaybackSettings() = default; |
332 | 333 |
333 } // namespace cc | 334 } // namespace cc |
OLD | NEW |