From ec4a417cf5346d41f6fc64f0396f83ed4b340696 Mon Sep 17 00:00:00 2001 From: vmpstr Date: Mon, 14 Mar 2016 15:51:06 -0700 Subject: cc: Refactor SkipImageCanvas and create it during playback. This patch moves SkipImageCanvas into a separate file in the same directory as ImageHijackCanvas and also moves the creation of SkipImageCanvas to raster source playback (the same place as ImageHijackCanvas is created). BUG=594679 R=enne, ericrk CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1799883002 Cr-Commit-Position: refs/heads/master@{#381101} --- cc/playback/display_list_raster_source.cc | 18 +++++++++--- cc/playback/display_list_raster_source.h | 6 ++-- cc/playback/display_list_raster_source_unittest.cc | 17 +++++++---- cc/playback/skip_image_canvas.cc | 33 ++++++++++++++++++++++ cc/playback/skip_image_canvas.h | 26 +++++++++++++++++ 5 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 cc/playback/skip_image_canvas.cc create mode 100644 cc/playback/skip_image_canvas.h (limited to 'cc/playback') diff --git a/cc/playback/display_list_raster_source.cc b/cc/playback/display_list_raster_source.cc index fe707ec..a6d2c84 100644 --- a/cc/playback/display_list_raster_source.cc +++ b/cc/playback/display_list_raster_source.cc @@ -14,6 +14,7 @@ #include "cc/debug/debug_colors.h" #include "cc/playback/display_item_list.h" #include "cc/playback/image_hijack_canvas.h" +#include "cc/playback/skip_image_canvas.h" #include "skia/ext/analysis_canvas.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPictureRecorder.h" @@ -96,11 +97,15 @@ DisplayListRasterSource::~DisplayListRasterSource() { void DisplayListRasterSource::PlaybackToSharedCanvas( SkCanvas* raster_canvas, const gfx::Rect& canvas_rect, - float contents_scale) const { + float contents_scale, + bool include_images) const { // TODO(vmpstr): This can be improved by plumbing whether the tile itself has // discardable images. This way we would only pay for the hijack canvas if the // tile actually needed it. - if (display_list_->MayHaveDiscardableImages()) { + if (!include_images) { + SkipImageCanvas canvas(raster_canvas); + RasterCommon(&canvas, nullptr, canvas_rect, canvas_rect, contents_scale); + } else if (display_list_->MayHaveDiscardableImages()) { const SkImageInfo& info = raster_canvas->imageInfo(); ImageHijackCanvas canvas(info.width(), info.height(), image_decode_controller_); @@ -123,11 +128,16 @@ void DisplayListRasterSource::PlaybackToCanvas( SkCanvas* raster_canvas, const gfx::Rect& canvas_bitmap_rect, const gfx::Rect& canvas_playback_rect, - float contents_scale) const { + float contents_scale, + bool include_images) const { PrepareForPlaybackToCanvas(raster_canvas, canvas_bitmap_rect, canvas_playback_rect, contents_scale); - if (display_list_->MayHaveDiscardableImages()) { + if (!include_images) { + SkipImageCanvas canvas(raster_canvas); + RasterCommon(&canvas, nullptr, canvas_bitmap_rect, canvas_playback_rect, + contents_scale); + } else if (display_list_->MayHaveDiscardableImages()) { const SkImageInfo& info = raster_canvas->imageInfo(); ImageHijackCanvas canvas(info.width(), info.height(), image_decode_controller_); diff --git a/cc/playback/display_list_raster_source.h b/cc/playback/display_list_raster_source.h index 5599f59a..361019c 100644 --- a/cc/playback/display_list_raster_source.h +++ b/cc/playback/display_list_raster_source.h @@ -48,14 +48,16 @@ class CC_EXPORT DisplayListRasterSource virtual void PlaybackToCanvas(SkCanvas* canvas, const gfx::Rect& canvas_bitmap_rect, const gfx::Rect& canvas_playback_rect, - float contents_scale) const; + float contents_scale, + bool include_images) const; // Similar to above, except that the canvas passed here can (or was already) // rasterized into by another raster source. That is, it is not safe to clear // the canvas or discard its underlying memory. void PlaybackToSharedCanvas(SkCanvas* canvas, const gfx::Rect& canvas_rect, - float contents_scale) const; + float contents_scale, + bool include_images) const; // Returns whether the given rect at given scale is of solid color in // this raster source, as well as the solid color value. diff --git a/cc/playback/display_list_raster_source_unittest.cc b/cc/playback/display_list_raster_source_unittest.cc index 2cf6f06..ffaf892 100644 --- a/cc/playback/display_list_raster_source_unittest.cc +++ b/cc/playback/display_list_raster_source_unittest.cc @@ -290,8 +290,9 @@ TEST(DisplayListRasterSourceTest, RasterFullContents) { SkCanvas canvas(bitmap); canvas.clear(SK_ColorTRANSPARENT); + const bool include_images = true; raster->PlaybackToCanvas(&canvas, canvas_rect, canvas_rect, - contents_scale); + contents_scale, include_images); SkColor* pixels = reinterpret_cast(bitmap.getPixels()); int num_pixels = bitmap.width() * bitmap.height(); @@ -342,8 +343,9 @@ TEST(DisplayListRasterSourceTest, RasterPartialContents) { // Playback the full rect which should make everything white. gfx::Rect raster_full_rect(content_bounds); gfx::Rect playback_rect(content_bounds); + const bool include_images = true; raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect, - contents_scale); + contents_scale, include_images); { SkColor* pixels = reinterpret_cast(bitmap.getPixels()); @@ -374,7 +376,7 @@ TEST(DisplayListRasterSourceTest, RasterPartialContents) { // that touches the edge pixels of the recording. playback_rect.Inset(1, 2, 0, 1); raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect, - contents_scale); + contents_scale, include_images); SkColor* pixels = reinterpret_cast(bitmap.getPixels()); int num_black = 0; @@ -438,8 +440,9 @@ TEST(DisplayListRasterSourceTest, RasterPartialClear) { // Playback the full rect which should make everything light gray (alpha=10). gfx::Rect raster_full_rect(content_bounds); gfx::Rect playback_rect(content_bounds); + const bool include_images = true; raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect, - contents_scale); + contents_scale, include_images); { SkColor* pixels = reinterpret_cast(bitmap.getPixels()); @@ -478,7 +481,7 @@ TEST(DisplayListRasterSourceTest, RasterPartialClear) { playback_rect = gfx::Rect(gfx::ScaleToCeiledSize(partial_bounds, contents_scale)); raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect, - contents_scale); + contents_scale, include_images); // Test that the whole playback_rect was cleared and repainted with new alpha. SkColor* pixels = reinterpret_cast(bitmap.getPixels()); @@ -518,7 +521,9 @@ TEST(DisplayListRasterSourceTest, RasterContentsTransparent) { bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height()); SkCanvas canvas(bitmap); - raster->PlaybackToCanvas(&canvas, canvas_rect, canvas_rect, contents_scale); + const bool include_images = true; + raster->PlaybackToCanvas(&canvas, canvas_rect, canvas_rect, contents_scale, + include_images); SkColor* pixels = reinterpret_cast(bitmap.getPixels()); int num_pixels = bitmap.width() * bitmap.height(); diff --git a/cc/playback/skip_image_canvas.cc b/cc/playback/skip_image_canvas.cc new file mode 100644 index 0000000..badaf10 --- /dev/null +++ b/cc/playback/skip_image_canvas.cc @@ -0,0 +1,33 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/playback/skip_image_canvas.h" + +#include "third_party/skia/include/core/SkShader.h" + +namespace cc { + +SkipImageCanvas::SkipImageCanvas(SkCanvas* canvas) + : SkPaintFilterCanvas(canvas) {} + +bool SkipImageCanvas::onFilter(SkTCopyOnFirstWrite* paint, + Type type) const { + if (type == kBitmap_Type) + return false; + + SkShader* shader = (*paint) ? (*paint)->getShader() : nullptr; + return !shader || !shader->isABitmap(); +} + +void SkipImageCanvas::onDrawPicture(const SkPicture* picture, + const SkMatrix* matrix, + const SkPaint* paint) { + SkTCopyOnFirstWrite filteredPaint(paint); + + // To filter nested draws, we must unfurl pictures at this stage. + if (onFilter(&filteredPaint, kPicture_Type)) + SkCanvas::onDrawPicture(picture, matrix, filteredPaint); +} + +} // namespace cc diff --git a/cc/playback/skip_image_canvas.h b/cc/playback/skip_image_canvas.h new file mode 100644 index 0000000..67206b7 --- /dev/null +++ b/cc/playback/skip_image_canvas.h @@ -0,0 +1,26 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_PLAYBACK_SKIP_IMAGE_CANVAS_H_ +#define CC_PLAYBACK_SKIP_IMAGE_CANVAS_H_ + +#include "third_party/skia/include/utils/SkPaintFilterCanvas.h" + +namespace cc { + +class SkipImageCanvas : public SkPaintFilterCanvas { + public: + explicit SkipImageCanvas(SkCanvas* canvas); + + private: + bool onFilter(SkTCopyOnFirstWrite* paint, Type type) const override; + + void onDrawPicture(const SkPicture* picture, + const SkMatrix* matrix, + const SkPaint* paint) override; +}; + +} // namespace cc + +#endif // CC_PLAYBACK_SKIP_IMAGE_CANVAS_H_ -- cgit v1.1