| 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/raster_source.h" | 5 #include "cc/playback/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" |
| 11 #include "cc/base/region.h" | 11 #include "cc/base/region.h" |
| 12 #include "cc/debug/debug_colors.h" | 12 #include "cc/debug/debug_colors.h" |
| 13 #include "cc/debug/traced_value.h" | 13 #include "cc/debug/traced_value.h" |
| 14 #include "cc/playback/display_item_list.h" | 14 #include "cc/playback/display_item_list.h" |
| 15 #include "cc/playback/image_hijack_canvas.h" | 15 #include "cc/playback/image_hijack_canvas.h" |
| 16 #include "cc/playback/skip_image_canvas.h" | 16 #include "cc/playback/skip_image_canvas.h" |
| 17 #include "skia/ext/analysis_canvas.h" | 17 #include "skia/ext/analysis_canvas.h" |
| 18 #include "third_party/skia/include/core/SkCanvas.h" | 18 #include "third_party/skia/include/core/SkCanvas.h" |
| 19 #include "third_party/skia/include/core/SkColorSpaceXformCanvas.h" |
| 19 #include "third_party/skia/include/core/SkPictureRecorder.h" | 20 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 20 #include "ui/gfx/geometry/rect_conversions.h" | 21 #include "ui/gfx/geometry/rect_conversions.h" |
| 21 | 22 |
| 22 namespace cc { | 23 namespace cc { |
| 23 | 24 |
| 24 scoped_refptr<RasterSource> RasterSource::CreateFromRecordingSource( | 25 scoped_refptr<RasterSource> RasterSource::CreateFromRecordingSource( |
| 25 const RecordingSource* other, | 26 const RecordingSource* other, |
| 26 bool can_use_lcd_text) { | 27 bool can_use_lcd_text) { |
| 27 return make_scoped_refptr(new RasterSource(other, can_use_lcd_text)); | 28 return make_scoped_refptr(new RasterSource(other, can_use_lcd_text)); |
| 28 } | 29 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 54 size_(other->size_), | 55 size_(other->size_), |
| 55 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), | 56 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), |
| 56 slow_down_raster_scale_factor_for_debug_( | 57 slow_down_raster_scale_factor_for_debug_( |
| 57 other->slow_down_raster_scale_factor_for_debug_), | 58 other->slow_down_raster_scale_factor_for_debug_), |
| 58 image_decode_cache_(other->image_decode_cache_) {} | 59 image_decode_cache_(other->image_decode_cache_) {} |
| 59 | 60 |
| 60 RasterSource::~RasterSource() { | 61 RasterSource::~RasterSource() { |
| 61 } | 62 } |
| 62 | 63 |
| 63 void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas, | 64 void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas, |
| 65 const gfx::ColorSpace& canvas_color_space, |
| 64 const gfx::Rect& canvas_bitmap_rect, | 66 const gfx::Rect& canvas_bitmap_rect, |
| 65 const gfx::Rect& canvas_playback_rect, | 67 const gfx::Rect& canvas_playback_rect, |
| 66 float raster_scale, | 68 float raster_scale, |
| 67 const PlaybackSettings& settings) const { | 69 const PlaybackSettings& settings) const { |
| 68 SkIRect raster_bounds = gfx::RectToSkIRect(canvas_bitmap_rect); | 70 SkIRect raster_bounds = gfx::RectToSkIRect(canvas_bitmap_rect); |
| 69 if (!canvas_playback_rect.IsEmpty() && | 71 if (!canvas_playback_rect.IsEmpty() && |
| 70 !raster_bounds.intersect(gfx::RectToSkIRect(canvas_playback_rect))) | 72 !raster_bounds.intersect(gfx::RectToSkIRect(canvas_playback_rect))) |
| 71 return; | 73 return; |
| 72 // Treat all subnormal values as zero for performance. | 74 // Treat all subnormal values as zero for performance. |
| 73 ScopedSubnormalFloatDisabler disabler; | 75 ScopedSubnormalFloatDisabler disabler; |
| 74 | 76 |
| 75 raster_canvas->save(); | 77 raster_canvas->save(); |
| 76 raster_canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); | 78 raster_canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); |
| 77 raster_canvas->clipRect(SkRect::MakeFromIRect(raster_bounds)); | 79 raster_canvas->clipRect(SkRect::MakeFromIRect(raster_bounds)); |
| 78 raster_canvas->scale(raster_scale, raster_scale); | 80 raster_canvas->scale(raster_scale, raster_scale); |
| 79 PlaybackToCanvas(raster_canvas, settings); | 81 PlaybackToCanvas(raster_canvas, canvas_color_space, settings); |
| 80 raster_canvas->restore(); | 82 raster_canvas->restore(); |
| 81 } | 83 } |
| 82 | 84 |
| 83 void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas, | 85 void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas, |
| 86 const gfx::ColorSpace& canvas_color_space, |
| 84 const PlaybackSettings& settings) const { | 87 const PlaybackSettings& settings) const { |
| 85 if (!settings.playback_to_shared_canvas) | 88 if (!settings.playback_to_shared_canvas) |
| 86 PrepareForPlaybackToCanvas(raster_canvas); | 89 PrepareForPlaybackToCanvas(raster_canvas); |
| 87 | 90 |
| 88 if (settings.skip_images) { | 91 if (settings.skip_images) { |
| 89 SkipImageCanvas canvas(raster_canvas); | 92 SkipImageCanvas canvas(raster_canvas); |
| 90 RasterCommon(&canvas, nullptr); | 93 RasterCommon(&canvas, canvas_color_space, nullptr); |
| 91 } else if (settings.use_image_hijack_canvas) { | 94 } else if (settings.use_image_hijack_canvas) { |
| 92 const SkImageInfo& info = raster_canvas->imageInfo(); | 95 const SkImageInfo& info = raster_canvas->imageInfo(); |
| 93 ImageHijackCanvas canvas(info.width(), info.height(), image_decode_cache_, | 96 ImageHijackCanvas canvas(info.width(), info.height(), image_decode_cache_, |
| 94 &settings.images_to_skip); | 97 &settings.images_to_skip); |
| 95 // Before adding the canvas, make sure that the ImageHijackCanvas is aware | 98 // Before adding the canvas, make sure that the ImageHijackCanvas is aware |
| 96 // of the current transform and clip, which may affect the clip bounds. | 99 // of the current transform and clip, which may affect the clip bounds. |
| 97 // Since we query the clip bounds of the current canvas to get the list of | 100 // Since we query the clip bounds of the current canvas to get the list of |
| 98 // draw commands to process, this is important to produce correct content. | 101 // draw commands to process, this is important to produce correct content. |
| 99 canvas.clipRect( | 102 canvas.clipRect( |
| 100 SkRect::MakeFromIRect(raster_canvas->getDeviceClipBounds())); | 103 SkRect::MakeFromIRect(raster_canvas->getDeviceClipBounds())); |
| 101 canvas.setMatrix(raster_canvas->getTotalMatrix()); | 104 canvas.setMatrix(raster_canvas->getTotalMatrix()); |
| 102 canvas.addCanvas(raster_canvas); | 105 canvas.addCanvas(raster_canvas); |
| 103 | 106 |
| 104 RasterCommon(&canvas, nullptr); | 107 RasterCommon(&canvas, canvas_color_space, nullptr); |
| 105 } else { | 108 } else { |
| 106 RasterCommon(raster_canvas, nullptr); | 109 RasterCommon(raster_canvas, canvas_color_space, nullptr); |
| 107 } | 110 } |
| 108 } | 111 } |
| 109 | 112 |
| 110 namespace { | 113 namespace { |
| 111 | 114 |
| 112 bool CanvasIsUnclipped(const SkCanvas* canvas) { | 115 bool CanvasIsUnclipped(const SkCanvas* canvas) { |
| 113 if (!canvas->isClipRect()) | 116 if (!canvas->isClipRect()) |
| 114 return false; | 117 return false; |
| 115 | 118 |
| 116 SkIRect bounds; | 119 SkIRect bounds; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 canvas->save(); | 192 canvas->save(); |
| 190 // Use clipRegion to bypass CTM because the rects are device rects. | 193 // Use clipRegion to bypass CTM because the rects are device rects. |
| 191 SkRegion interest_region; | 194 SkRegion interest_region; |
| 192 interest_region.setRect(interest_rect); | 195 interest_region.setRect(interest_rect); |
| 193 interest_region.op(opaque_rect, SkRegion::kDifference_Op); | 196 interest_region.op(opaque_rect, SkRegion::kDifference_Op); |
| 194 canvas->clipRegion(interest_region); | 197 canvas->clipRegion(interest_region); |
| 195 canvas->clear(background_color_); | 198 canvas->clear(background_color_); |
| 196 canvas->restore(); | 199 canvas->restore(); |
| 197 } | 200 } |
| 198 | 201 |
| 199 void RasterSource::RasterCommon(SkCanvas* canvas, | 202 void RasterSource::RasterCommon(SkCanvas* input_canvas, |
| 203 const gfx::ColorSpace& target_color_space, |
| 200 SkPicture::AbortCallback* callback) const { | 204 SkPicture::AbortCallback* callback) const { |
| 205 SkCanvas* raster_canvas = input_canvas; |
| 206 std::unique_ptr<SkCanvas> color_transform_canvas; |
| 207 if (target_color_space.IsValid()) { |
| 208 color_transform_canvas = SkCreateColorSpaceXformCanvas( |
| 209 input_canvas, target_color_space.ToSkColorSpace()); |
| 210 raster_canvas = color_transform_canvas.get(); |
| 211 } |
| 201 DCHECK(display_list_.get()); | 212 DCHECK(display_list_.get()); |
| 202 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); | 213 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); |
| 203 for (int i = 0; i < repeat_count; ++i) | 214 for (int i = 0; i < repeat_count; ++i) |
| 204 display_list_->Raster(canvas, callback); | 215 display_list_->Raster(raster_canvas, callback); |
| 205 } | 216 } |
| 206 | 217 |
| 207 sk_sp<SkPicture> RasterSource::GetFlattenedPicture() { | 218 sk_sp<SkPicture> RasterSource::GetFlattenedPicture() { |
| 208 TRACE_EVENT0("cc", "RasterSource::GetFlattenedPicture"); | 219 TRACE_EVENT0("cc", "RasterSource::GetFlattenedPicture"); |
| 209 | 220 |
| 210 SkPictureRecorder recorder; | 221 SkPictureRecorder recorder; |
| 211 SkCanvas* canvas = recorder.beginRecording(size_.width(), size_.height()); | 222 SkCanvas* canvas = recorder.beginRecording(size_.width(), size_.height()); |
| 212 if (!size_.IsEmpty()) { | 223 if (!size_.IsEmpty()) { |
| 213 PrepareForPlaybackToCanvas(canvas); | 224 PrepareForPlaybackToCanvas(canvas); |
| 214 RasterCommon(canvas, nullptr); | 225 // No target color space should be set for generating an SkPicture. |
| 226 RasterCommon(canvas, gfx::ColorSpace(), nullptr); |
| 215 } | 227 } |
| 216 | 228 |
| 217 return recorder.finishRecordingAsPicture(); | 229 return recorder.finishRecordingAsPicture(); |
| 218 } | 230 } |
| 219 | 231 |
| 220 size_t RasterSource::GetMemoryUsage() const { | 232 size_t RasterSource::GetMemoryUsage() const { |
| 221 if (!display_list_) | 233 if (!display_list_) |
| 222 return 0; | 234 return 0; |
| 223 return display_list_->ApproximateMemoryUsage() + | 235 return display_list_->ApproximateMemoryUsage() + |
| 224 painter_reported_memory_usage_; | 236 painter_reported_memory_usage_; |
| 225 } | 237 } |
| 226 | 238 |
| 227 bool RasterSource::PerformSolidColorAnalysis(const gfx::Rect& content_rect, | 239 bool RasterSource::PerformSolidColorAnalysis(const gfx::Rect& content_rect, |
| 228 float contents_scale, | 240 float contents_scale, |
| 229 SkColor* color) const { | 241 SkColor* color) const { |
| 230 TRACE_EVENT0("cc", "RasterSource::PerformSolidColorAnalysis"); | 242 TRACE_EVENT0("cc", "RasterSource::PerformSolidColorAnalysis"); |
| 231 | 243 |
| 232 gfx::Rect layer_rect = | 244 gfx::Rect layer_rect = |
| 233 gfx::ScaleToEnclosingRect(content_rect, 1.f / contents_scale); | 245 gfx::ScaleToEnclosingRect(content_rect, 1.f / contents_scale); |
| 234 | 246 |
| 235 layer_rect.Intersect(gfx::Rect(size_)); | 247 layer_rect.Intersect(gfx::Rect(size_)); |
| 236 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); | 248 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); |
| 237 canvas.translate(-layer_rect.x(), -layer_rect.y()); | 249 canvas.translate(-layer_rect.x(), -layer_rect.y()); |
| 238 RasterCommon(&canvas, &canvas); | 250 // No target color space should be set for solid color analysis (the |
| 251 // resulting solid color will be known to be sRGB). |
| 252 RasterCommon(&canvas, gfx::ColorSpace(), &canvas); |
| 239 return canvas.GetColorIfSolid(color); | 253 return canvas.GetColorIfSolid(color); |
| 240 } | 254 } |
| 241 | 255 |
| 242 void RasterSource::GetDiscardableImagesInRect( | 256 void RasterSource::GetDiscardableImagesInRect( |
| 243 const gfx::Rect& layer_rect, | 257 const gfx::Rect& layer_rect, |
| 244 float contents_scale, | 258 float contents_scale, |
| 245 std::vector<DrawImage>* images) const { | 259 std::vector<DrawImage>* images) const { |
| 246 DCHECK_EQ(0u, images->size()); | 260 DCHECK_EQ(0u, images->size()); |
| 247 display_list_->GetDiscardableImagesInRect(layer_rect, contents_scale, images); | 261 display_list_->GetDiscardableImagesInRect(layer_rect, contents_scale, images); |
| 248 } | 262 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 use_image_hijack_canvas(true) {} | 321 use_image_hijack_canvas(true) {} |
| 308 | 322 |
| 309 RasterSource::PlaybackSettings::PlaybackSettings(const PlaybackSettings&) = | 323 RasterSource::PlaybackSettings::PlaybackSettings(const PlaybackSettings&) = |
| 310 default; | 324 default; |
| 311 | 325 |
| 312 RasterSource::PlaybackSettings::PlaybackSettings(PlaybackSettings&&) = default; | 326 RasterSource::PlaybackSettings::PlaybackSettings(PlaybackSettings&&) = default; |
| 313 | 327 |
| 314 RasterSource::PlaybackSettings::~PlaybackSettings() = default; | 328 RasterSource::PlaybackSettings::~PlaybackSettings() = default; |
| 315 | 329 |
| 316 } // namespace cc | 330 } // namespace cc |
| OLD | NEW |