Revert "Reland cc: Decode discardable images in PaintRecord backed shaders."
This reverts commit 53b8ed642644f245e3cb8d5cf2541bf3778ae7de.
Reason for revert: Causing flakiness on Linux Release (NVIDIA) for webgl_conformance_tests. See crbug.com/771156.
Original change's description:
> Reland cc: Decode discardable images in PaintRecord backed shaders.
>
> This reverts commit fe24d7f3ac1b5bcfb840a5ada01627df90a099eb. Since we
> rasterize the SkPicture with decoded images in the test, we need to
> initialize its pixels. Fix that.
>
> R=enne@chromium.org
> TBR=chrishtr@chromium.org
>
> Bug: 735741,728359
> Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel
> Change-Id: I10989e2bc28594c9fa8e291559ae2753e65de29d
> Reviewed-on: https://chromium-review.googlesource.com/695449
> Reviewed-by: enne <enne@chromium.org>
> Commit-Queue: Khushal <khushalsagar@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#505885}
TBR=chrishtr@chromium.org,enne@chromium.org,khushalsagar@chromium.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: 735741, 728359
Change-Id: I9bc577e4f6488ef3bccb991609828db20467231f
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel
Reviewed-on: https://chromium-review.googlesource.com/699755
Reviewed-by: Khushal <khushalsagar@chromium.org>
Commit-Queue: Khushal <khushalsagar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#506285}
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 5c1b29be..447d732 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -606,8 +606,6 @@
"paint/display_item_list_unittest.cc",
"paint/paint_image_unittest.cc",
"paint/paint_op_buffer_unittest.cc",
- "paint/paint_shader_unittest.cc",
- "paint/scoped_image_flags_unittest.cc",
"paint/solid_color_analyzer_unittest.cc",
"raster/playback_image_provider_unittest.cc",
"raster/raster_buffer_provider_unittest.cc",
diff --git a/cc/paint/BUILD.gn b/cc/paint/BUILD.gn
index 037891d4..387800c5 100644
--- a/cc/paint/BUILD.gn
+++ b/cc/paint/BUILD.gn
@@ -45,8 +45,6 @@
"paint_shader.h",
"record_paint_canvas.cc",
"record_paint_canvas.h",
- "scoped_image_flags.cc",
- "scoped_image_flags.h",
"skia_paint_canvas.cc",
"skia_paint_canvas.h",
"skia_paint_image_generator.cc",
diff --git a/cc/paint/discardable_image_map.cc b/cc/paint/discardable_image_map.cc
index 05dbe8b..0d23dd3 100644
--- a/cc/paint/discardable_image_map.cc
+++ b/cc/paint/discardable_image_map.cc
@@ -27,8 +27,6 @@
return dst;
}
-// This canvas is used only for tracking transform/clip/filter state from the
-// non-drawing ops.
class PaintTrackingCanvas final : public SkNoDrawCanvas {
public:
PaintTrackingCanvas(int width, int height) : SkNoDrawCanvas(width, height) {}
@@ -77,14 +75,52 @@
class DiscardableImageGenerator {
public:
- DiscardableImageGenerator(int width,
- int height,
- const PaintOpBuffer* buffer) {
- PaintTrackingCanvas canvas(width, height);
- GatherDiscardableImages(buffer, nullptr, &canvas);
- }
+ DiscardableImageGenerator(int width, int height) : canvas_(width, height) {}
~DiscardableImageGenerator() = default;
+ void GatherDiscardableImages(const PaintOpBuffer* buffer) {
+ if (!buffer->HasDiscardableImages())
+ return;
+
+ PlaybackParams params(nullptr, canvas_.getTotalMatrix());
+ canvas_.save();
+ // TODO(khushalsagar): Optimize out save/restore blocks if there are no
+ // images in the draw ops between them.
+ for (auto* op : PaintOpBuffer::Iterator(buffer)) {
+ if (op->IsDrawOp()) {
+ SkRect op_rect;
+ if (op->IsPaintOpWithFlags() && PaintOp::GetBounds(op, &op_rect)) {
+ AddImageFromFlags(op_rect,
+ static_cast<const PaintOpWithFlags*>(op)->flags);
+ }
+
+ PaintOpType op_type = static_cast<PaintOpType>(op->type);
+ if (op_type == PaintOpType::DrawImage) {
+ auto* image_op = static_cast<DrawImageOp*>(op);
+ auto* sk_image = image_op->image.GetSkImage().get();
+ AddImage(image_op->image,
+ SkRect::MakeIWH(sk_image->width(), sk_image->height()),
+ SkRect::MakeXYWH(image_op->left, image_op->top,
+ sk_image->width(), sk_image->height()),
+ nullptr, image_op->flags);
+ } else if (op_type == PaintOpType::DrawImageRect) {
+ auto* image_rect_op = static_cast<DrawImageRectOp*>(op);
+ SkMatrix matrix;
+ matrix.setRectToRect(image_rect_op->src, image_rect_op->dst,
+ SkMatrix::kFill_ScaleToFit);
+ AddImage(image_rect_op->image, image_rect_op->src, image_rect_op->dst,
+ &matrix, image_rect_op->flags);
+ } else if (op_type == PaintOpType::DrawRecord) {
+ GatherDiscardableImages(
+ static_cast<const DrawRecordOp*>(op)->record.get());
+ }
+ } else {
+ op->Raster(&canvas_, params);
+ }
+ }
+ canvas_.restore();
+ }
+
std::vector<std::pair<DrawImage, gfx::Rect>> TakeImages() {
return std::move(image_set_);
}
@@ -117,112 +153,48 @@
}
private:
- // Adds discardable images from |buffer| to the set of images tracked by
- // this generator. If |buffer| is being used in a DrawOp that requires
- // rasterization of the buffer as a pre-processing step for execution of the
- // op (for instance, with PaintRecord backed PaintShaders),
- // |top_level_op_rect| is set to the rect for that op. If provided, the
- // |top_level_op_rect| will be used as the rect for tracking the position of
- // this image in the top-level buffer.
- void GatherDiscardableImages(const PaintOpBuffer* buffer,
- const gfx::Rect* top_level_op_rect,
- PaintTrackingCanvas* canvas) {
- if (!buffer->HasDiscardableImages())
+ void AddImageFromFlags(const SkRect& rect, const PaintFlags& flags) {
+ if (!flags.HasShader() ||
+ flags.getShader()->shader_type() != PaintShader::Type::kImage)
return;
- // Prevent PaintOpBuffers from having side effects back into the canvas.
- SkAutoCanvasRestore save_restore(canvas, true);
-
- PlaybackParams params(nullptr, canvas->getTotalMatrix());
- // TODO(khushalsagar): Optimize out save/restore blocks if there are no
- // images in the draw ops between them.
- for (auto* op : PaintOpBuffer::Iterator(buffer)) {
- if (!op->IsDrawOp()) {
- op->Raster(canvas, params);
- continue;
- } else if (!PaintOp::OpHasDiscardableImages(op)) {
- continue;
- }
-
- gfx::Rect op_rect;
- base::Optional<gfx::Rect> local_op_rect;
-
- if (top_level_op_rect) {
- op_rect = *top_level_op_rect;
- } else {
- local_op_rect = ComputePaintRect(op, canvas);
- if (local_op_rect.value().IsEmpty())
- continue;
-
- op_rect = local_op_rect.value();
- }
-
- const SkMatrix& ctm = canvas->getTotalMatrix();
- if (op->IsPaintOpWithFlags()) {
- AddImageFromFlags(op_rect,
- static_cast<const PaintOpWithFlags*>(op)->flags, ctm);
- }
-
- PaintOpType op_type = static_cast<PaintOpType>(op->type);
- if (op_type == PaintOpType::DrawImage) {
- auto* image_op = static_cast<DrawImageOp*>(op);
- auto* sk_image = image_op->image.GetSkImage().get();
- AddImage(image_op->image,
- SkRect::MakeIWH(sk_image->width(), sk_image->height()),
- op_rect, ctm, image_op->flags.getFilterQuality());
- } else if (op_type == PaintOpType::DrawImageRect) {
- auto* image_rect_op = static_cast<DrawImageRectOp*>(op);
- SkMatrix matrix = ctm;
- matrix.postConcat(SkMatrix::MakeRectToRect(image_rect_op->src,
- image_rect_op->dst,
- SkMatrix::kFill_ScaleToFit));
- AddImage(image_rect_op->image, image_rect_op->src, op_rect, matrix,
- image_rect_op->flags.getFilterQuality());
- } else if (op_type == PaintOpType::DrawRecord) {
- GatherDiscardableImages(
- static_cast<const DrawRecordOp*>(op)->record.get(),
- top_level_op_rect, canvas);
- }
- }
+ const PaintImage& paint_image = flags.getShader()->paint_image();
+ SkMatrix local_matrix = flags.getShader()->GetLocalMatrix();
+ AddImage(paint_image,
+ SkRect::MakeWH(paint_image.width(), paint_image.height()), rect,
+ &local_matrix, flags);
}
- // Given the |op_rect|, which is the rect for the draw op, returns the
- // transformed rect accounting for the current transform, clip and paint
- // state on |canvas_|.
- gfx::Rect ComputePaintRect(const PaintOp* op, PaintTrackingCanvas* canvas) {
- const SkRect& clip_rect = SkRect::Make(canvas->getDeviceClipBounds());
- const SkMatrix& ctm = canvas->getTotalMatrix();
+ void AddImage(PaintImage paint_image,
+ const SkRect& src_rect,
+ const SkRect& rect,
+ const SkMatrix* local_matrix,
+ const PaintFlags& flags) {
+ if (!paint_image.IsLazyGenerated())
+ return;
- gfx::Rect transformed_rect;
- SkRect op_rect;
- if (!PaintOp::GetBounds(op, &op_rect)) {
- // If we can't provide a conservative bounding rect for the op, assume it
- // covers the complete current clip.
- transformed_rect = gfx::ToEnclosingRect(gfx::SkRectToRectF(clip_rect));
- } else {
- const PaintFlags* flags =
- op->IsPaintOpWithFlags()
- ? &static_cast<const PaintOpWithFlags*>(op)->flags
- : nullptr;
- SkPaint paint;
- if (flags)
- paint = flags->ToSkPaint();
+ const SkRect& clip_rect = SkRect::Make(canvas_.getDeviceClipBounds());
+ const SkMatrix& ctm = canvas_.getTotalMatrix();
- SkRect paint_rect = MapRect(ctm, op_rect);
- bool computed_paint_bounds =
- canvas->ComputePaintBounds(paint_rect, &paint, &paint_rect);
- if (!computed_paint_bounds) {
- // TODO(vmpstr): UMA this case.
- paint_rect = clip_rect;
- }
-
- // Clamp the image rect by the current clip rect.
- if (!paint_rect.intersect(clip_rect))
- return gfx::Rect();
-
- transformed_rect = gfx::ToEnclosingRect(gfx::SkRectToRectF(paint_rect));
+ SkRect paint_rect = MapRect(ctm, rect);
+ SkPaint paint = flags.ToSkPaint();
+ bool computed_paint_bounds =
+ canvas_.ComputePaintBounds(paint_rect, &paint, &paint_rect);
+ if (!computed_paint_bounds) {
+ // TODO(vmpstr): UMA this case.
+ paint_rect = clip_rect;
}
+ // Clamp the image rect by the current clip rect.
+ if (!paint_rect.intersect(clip_rect))
+ return;
+
+ SkFilterQuality filter_quality = flags.getFilterQuality();
+
+ SkIRect src_irect;
+ src_rect.roundOut(&src_irect);
+ gfx::Rect image_rect = gfx::ToEnclosingRect(gfx::SkRectToRectF(paint_rect));
+
// During raster, we use the device clip bounds on the canvas, which outsets
// the actual clip by 1 due to the possibility of antialiasing. Account for
// this here by outsetting the image rect by 1. Note that this only affects
@@ -233,52 +205,7 @@
// raster time, since we might be sending a larger-than-one-item display
// item to skia, which means that skia will internally determine whether to
// raster the picture (using device clip bounds that are outset).
- transformed_rect.Inset(-1, -1);
- return transformed_rect;
- }
-
- void AddImageFromFlags(const gfx::Rect& op_rect,
- const PaintFlags& flags,
- const SkMatrix& ctm) {
- if (!flags.getShader())
- return;
-
- if (flags.getShader()->shader_type() == PaintShader::Type::kImage) {
- const PaintImage& paint_image = flags.getShader()->paint_image();
- SkMatrix matrix = ctm;
- matrix.postConcat(flags.getShader()->GetLocalMatrix());
- AddImage(paint_image,
- SkRect::MakeWH(paint_image.width(), paint_image.height()),
- op_rect, matrix, flags.getFilterQuality());
- } else if (flags.getShader()->shader_type() ==
- PaintShader::Type::kPaintRecord &&
- flags.getShader()->paint_record()->HasDiscardableImages()) {
- SkRect scaled_tile_rect;
- if (!flags.getShader()->GetRasterizationTileRect(ctm,
- &scaled_tile_rect)) {
- return;
- }
-
- PaintTrackingCanvas canvas(scaled_tile_rect.width(),
- scaled_tile_rect.height());
- canvas.setMatrix(SkMatrix::MakeRectToRect(flags.getShader()->tile(),
- scaled_tile_rect,
- SkMatrix::kFill_ScaleToFit));
- GatherDiscardableImages(flags.getShader()->paint_record().get(), &op_rect,
- &canvas);
- }
- }
-
- void AddImage(PaintImage paint_image,
- const SkRect& src_rect,
- const gfx::Rect& image_rect,
- const SkMatrix& matrix,
- SkFilterQuality filter_quality) {
- if (!paint_image.IsLazyGenerated())
- return;
-
- SkIRect src_irect;
- src_rect.roundOut(&src_irect);
+ image_rect.Inset(-1, -1);
// Make a note if any image was originally specified in a non-sRGB color
// space.
@@ -290,6 +217,10 @@
color_stats_srgb_image_count_++;
}
+ SkMatrix matrix = ctm;
+ if (local_matrix)
+ matrix.postConcat(*local_matrix);
+
image_id_to_rect_[paint_image.stable_id()].Union(image_rect);
if (paint_image.ShouldAnimate()) {
@@ -304,6 +235,9 @@
image_rect);
}
+ // This canvas is used only for tracking transform/clip/filter state from the
+ // non-drawing ops.
+ PaintTrackingCanvas canvas_;
std::vector<std::pair<DrawImage, gfx::Rect>> image_set_;
base::flat_map<PaintImage::Id, gfx::Rect> image_id_to_rect_;
std::vector<DiscardableImageMap::AnimatedImageMetadata>
@@ -329,8 +263,8 @@
if (!paint_op_buffer->HasDiscardableImages())
return;
- DiscardableImageGenerator generator(bounds.right(), bounds.bottom(),
- paint_op_buffer);
+ DiscardableImageGenerator generator(bounds.right(), bounds.bottom());
+ generator.GatherDiscardableImages(paint_op_buffer);
generator.RecordColorHistograms();
image_id_to_rect_ = generator.TakeImageIdToRectMap();
animated_images_metadata_ = generator.TakeAnimatedImagesMetadata();
diff --git a/cc/paint/discardable_image_map_unittest.cc b/cc/paint/discardable_image_map_unittest.cc
index 4530746..0e8a6d20e 100644
--- a/cc/paint/discardable_image_map_unittest.cc
+++ b/cc/paint/discardable_image_map_unittest.cc
@@ -747,43 +747,6 @@
EXPECT_DCHECK_DEATH(images[2]->frame_index());
}
-TEST_F(DiscardableImageMapTest, CapturesImagesInPaintRecordShaders) {
- // Create the record to use in the shader.
- auto shader_record = sk_make_sp<PaintOpBuffer>();
- shader_record->push<ScaleOp>(2.0f, 2.0f);
- PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(100, 100));
- shader_record->push<DrawImageOp>(paint_image, 0.f, 0.f, nullptr);
-
- gfx::Rect visible_rect(500, 500);
- scoped_refptr<DisplayItemList> display_list = new DisplayItemList();
- display_list->StartPaint();
- display_list->push<ScaleOp>(2.0f, 2.0f);
- PaintFlags flags;
- SkRect tile = SkRect::MakeWH(100, 100);
- flags.setShader(PaintShader::MakePaintRecord(
- shader_record, tile, SkShader::TileMode::kClamp_TileMode,
- SkShader::TileMode::kClamp_TileMode, nullptr));
- display_list->push<DrawRectOp>(SkRect::MakeWH(200, 200), flags);
- display_list->EndPaintOfUnpaired(visible_rect);
- display_list->Finalize();
-
- display_list->GenerateDiscardableImagesMetadata();
- const auto& image_map = display_list->discardable_image_map();
-
- // The image rect is set to the rect for the DrawRectOp.
- std::vector<PositionScaleDrawImage> draw_images =
- GetDiscardableImagesInRect(image_map, visible_rect);
- std::vector<gfx::Rect> inset_rects = InsetImageRects(draw_images);
- ASSERT_EQ(draw_images.size(), 1u);
- EXPECT_EQ(draw_images[0].image, paint_image);
- // The position of the image is the position of the DrawRectOp that uses the
- // shader.
- EXPECT_EQ(gfx::Rect(400, 400), inset_rects[0]);
- // The scale of the image includes the scale at which the shader record is
- // rasterized.
- EXPECT_EQ(SkSize::Make(4.f, 4.f), draw_images[0].scale);
-}
-
class DiscardableImageMapColorSpaceTest
: public DiscardableImageMapTest,
public testing::WithParamInterface<gfx::ColorSpace> {};
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc
index 089746c..b7b1825 100644
--- a/cc/paint/paint_op_buffer.cc
+++ b/cc/paint/paint_op_buffer.cc
@@ -13,7 +13,6 @@
#include "cc/paint/paint_op_reader.h"
#include "cc/paint/paint_op_writer.h"
#include "cc/paint/paint_record.h"
-#include "cc/paint/scoped_image_flags.h"
#include "third_party/skia/include/core/SkAnnotation.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkRegion.h"
@@ -26,6 +25,22 @@
return result;
}
+bool IsImageShader(const PaintFlags& flags) {
+ return flags.HasShader() &&
+ flags.getShader()->shader_type() == PaintShader::Type::kImage;
+}
+
+bool IsImageOp(const PaintOp* op) {
+ if (op->GetType() == PaintOpType::DrawImage)
+ return true;
+ else if (op->GetType() == PaintOpType::DrawImageRect)
+ return true;
+ else if (op->IsDrawOp() && op->IsPaintOpWithFlags())
+ return IsImageShader(static_cast<const PaintOpWithFlags*>(op)->flags);
+
+ return false;
+}
+
bool QuickRejectDraw(const PaintOp* op, const SkCanvas* canvas) {
DCHECK(op->IsDrawOp());
@@ -43,6 +58,65 @@
return canvas->quickReject(rect);
}
+// Encapsulates a ImageProvider::DecodedImageHolder and a SkPaint. Use of
+// this class ensures that the DecodedImageHolder outlives the dependent
+// SkPaint.
+class ScopedImageFlags {
+ public:
+ ScopedImageFlags(ImageProvider* image_provider,
+ const PaintFlags& flags,
+ const SkMatrix& ctm) {
+ DCHECK(IsImageShader(flags));
+
+ const PaintImage& paint_image = flags.getShader()->paint_image();
+ SkMatrix matrix = flags.getShader()->GetLocalMatrix();
+
+ SkMatrix total_image_matrix = matrix;
+ total_image_matrix.preConcat(ctm);
+ SkRect src_rect =
+ SkRect::MakeIWH(paint_image.width(), paint_image.height());
+ DrawImage draw_image(paint_image, RoundOutRect(src_rect),
+ flags.getFilterQuality(), total_image_matrix);
+ scoped_decoded_draw_image_ =
+ image_provider->GetDecodedDrawImage(draw_image);
+
+ if (!scoped_decoded_draw_image_)
+ return;
+ const auto& decoded_image = scoped_decoded_draw_image_.decoded_image();
+ DCHECK(decoded_image.image());
+
+ bool need_scale = !decoded_image.is_scale_adjustment_identity();
+ if (need_scale) {
+ matrix.preScale(1.f / decoded_image.scale_adjustment().width(),
+ 1.f / decoded_image.scale_adjustment().height());
+ }
+
+ sk_sp<SkImage> sk_image =
+ sk_ref_sp<SkImage>(const_cast<SkImage*>(decoded_image.image().get()));
+ PaintImage decoded_paint_image = PaintImageBuilder()
+ .set_id(paint_image.stable_id())
+ .set_image(std::move(sk_image))
+ .TakePaintImage();
+ decoded_flags_.emplace(flags);
+ decoded_flags_.value().setFilterQuality(decoded_image.filter_quality());
+ decoded_flags_.value().setShader(
+ PaintShader::MakeImage(decoded_paint_image, flags.getShader()->tx(),
+ flags.getShader()->ty(), &matrix));
+ }
+
+ PaintFlags* decoded_flags() {
+ return decoded_flags_ ? &decoded_flags_.value() : nullptr;
+ }
+
+ ~ScopedImageFlags() = default;
+
+ private:
+ base::Optional<PaintFlags> decoded_flags_;
+ ImageProvider::ScopedDecodedDrawImage scoped_decoded_draw_image_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedImageFlags);
+};
+
void RasterWithAlpha(const PaintOp* op,
SkCanvas* canvas,
const PlaybackParams& params,
@@ -59,7 +133,7 @@
// ImageProvider if it consists of an image shader.
base::Optional<ScopedImageFlags> scoped_flags;
const PaintFlags* decoded_flags = &flags_op->flags;
- if (params.image_provider && flags_op->HasDiscardableImagesFromFlags()) {
+ if (params.image_provider && IsImageShader(flags_op->flags)) {
scoped_flags.emplace(params.image_provider, flags_op->flags,
canvas->getTotalMatrix());
decoded_flags = scoped_flags.value().decoded_flags();
@@ -1381,47 +1455,12 @@
return false;
}
-// static
-bool PaintOp::OpHasDiscardableImages(const PaintOp* op) {
- if (op->IsPaintOpWithFlags() && static_cast<const PaintOpWithFlags*>(op)
- ->HasDiscardableImagesFromFlags()) {
- return true;
- }
-
- if (op->GetType() == PaintOpType::DrawImage &&
- static_cast<const DrawImageOp*>(op)->HasDiscardableImages()) {
- return true;
- } else if (op->GetType() == PaintOpType::DrawImageRect &&
- static_cast<const DrawImageRectOp*>(op)->HasDiscardableImages()) {
- return true;
- } else if (op->GetType() == PaintOpType::DrawRecord &&
- static_cast<const DrawRecordOp*>(op)->HasDiscardableImages()) {
- return true;
- }
-
- return false;
-}
-
void PaintOp::DestroyThis() {
auto func = g_destructor_functions[type];
if (func)
func(this);
}
-bool PaintOpWithFlags::HasDiscardableImagesFromFlags() const {
- if (!IsDrawOp())
- return false;
-
- if (!flags.HasShader())
- return false;
- else if (flags.getShader()->shader_type() == PaintShader::Type::kImage)
- return flags.getShader()->paint_image().IsLazyGenerated();
- else if (flags.getShader()->shader_type() == PaintShader::Type::kPaintRecord)
- return flags.getShader()->paint_record()->HasDiscardableImages();
-
- return false;
-}
-
void PaintOpWithFlags::RasterWithFlags(SkCanvas* canvas,
const PaintFlags* flags,
const PlaybackParams& params) const {
@@ -1699,8 +1738,7 @@
// general case we defer this to the SkCanvas but if we will be
// using an ImageProvider for pre-decoding images, we can save
// performing an expensive decode that will never be rasterized.
- const bool skip_op = params.image_provider &&
- PaintOp::OpHasDiscardableImages(draw_op) &&
+ const bool skip_op = params.image_provider && IsImageOp(draw_op) &&
QuickRejectDraw(draw_op, canvas);
if (skip_op) {
// Now that we know this op will be skipped, we can push the save
@@ -1730,15 +1768,15 @@
}
}
- if (params.image_provider && PaintOp::OpHasDiscardableImages(op)) {
+ if (params.image_provider && IsImageOp(op)) {
if (QuickRejectDraw(op, canvas))
continue;
auto* flags_op = op->IsPaintOpWithFlags()
? static_cast<const PaintOpWithFlags*>(op)
: nullptr;
- if (flags_op && flags_op->HasDiscardableImagesFromFlags()) {
- ScopedImageFlags scoped_flags(params.image_provider, flags_op->flags,
+ if (flags_op && IsImageShader(flags_op->flags)) {
+ ScopedImageFlags scoped_flags(image_provider, flags_op->flags,
canvas->getTotalMatrix());
// Only rasterize the op if we successfully decoded the image.
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h
index 96eb7f7..17405ec 100644
--- a/cc/paint/paint_op_buffer.h
+++ b/cc/paint/paint_op_buffer.h
@@ -15,7 +15,6 @@
#include "base/memory/aligned_memory.h"
#include "base/optional.h"
#include "cc/base/math_util.h"
-#include "cc/paint/image_provider.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_export.h"
#include "cc/paint/paint_flags.h"
@@ -30,6 +29,7 @@
namespace cc {
class ImageDecodeCache;
+class ImageProvider;
class CC_PAINT_EXPORT ThreadsafeMatrix : public SkMatrix {
public:
@@ -137,10 +137,6 @@
// for the op.
static bool GetBounds(const PaintOp* op, SkRect* rect);
- // Returns true if executing this op will require decoding of any lazy
- // generated images.
- static bool OpHasDiscardableImages(const PaintOp* op);
-
int CountSlowPaths() const { return 0; }
int CountSlowPathsFromFlags() const { return 0; }
@@ -199,7 +195,14 @@
int CountSlowPathsFromFlags() const { return flags.getPathEffect() ? 1 : 0; }
bool HasNonAAPaint() const { return !flags.isAntiAlias(); }
- bool HasDiscardableImagesFromFlags() const;
+ bool HasDiscardableImagesFromFlags() const {
+ if (!IsDrawOp())
+ return false;
+
+ SkShader* shader = flags.getSkShader();
+ SkImage* image = shader ? shader->isAImage(nullptr, nullptr) : nullptr;
+ return image && image->isLazyGenerated();
+ }
void RasterWithFlags(SkCanvas* canvas,
const PaintFlags* flags,
@@ -978,7 +981,6 @@
friend class DisplayItemList;
friend class PaintOpBufferOffsetsTest;
friend class SolidColorAnalyzer;
- friend class ScopedImageFlags;
// Replays the paint op buffer into the canvas. If |indices| is specified, it
// contains indices in an increasing order and only the indices specified in
diff --git a/cc/paint/paint_shader.cc b/cc/paint/paint_shader.cc
index 6f0767086..7d0b8cf 100644
--- a/cc/paint/paint_shader.cc
+++ b/cc/paint/paint_shader.cc
@@ -6,25 +6,9 @@
#include "base/memory/ptr_util.h"
#include "cc/paint/paint_record.h"
-#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
namespace cc {
-namespace {
-
-sk_sp<SkPicture> ToSkPicture(sk_sp<PaintRecord> record,
- const SkRect& bounds,
- const SkMatrix* matrix,
- ImageProvider* image_provider) {
- SkPictureRecorder recorder;
- SkCanvas* canvas = recorder.beginRecording(bounds);
- if (matrix)
- canvas->setMatrix(*matrix);
- record->Playback(canvas, image_provider);
- return recorder.finishRecordingAsPicture();
-}
-
-} // namespace
sk_sp<PaintShader> PaintShader::MakeColor(SkColor color) {
sk_sp<PaintShader> shader(new PaintShader(Type::kColor));
@@ -155,96 +139,6 @@
PaintShader::PaintShader(Type type) : shader_type_(type) {}
PaintShader::~PaintShader() = default;
-bool PaintShader::GetRasterizationTileRect(const SkMatrix& ctm,
- SkRect* tile_rect) const {
- DCHECK_EQ(shader_type_, Type::kPaintRecord);
-
- // If we are using a fixed scale, the record is rasterized with the original
- // tile size and scaling is applied to the generated output.
- if (scaling_behavior_ == ScalingBehavior::kFixedScale) {
- *tile_rect = tile_;
- return true;
- }
-
- SkMatrix matrix = ctm;
- if (local_matrix_.has_value())
- matrix.preConcat(local_matrix_.value());
-
- SkSize scale;
- if (!matrix.decomposeScale(&scale)) {
- // Decomposition failed, use an approximation.
- scale.set(SkScalarSqrt(matrix.getScaleX() * matrix.getScaleX() +
- matrix.getSkewX() * matrix.getSkewX()),
- SkScalarSqrt(matrix.getScaleY() * matrix.getScaleY() +
- matrix.getSkewY() * matrix.getSkewY()));
- }
- SkSize scaled_size =
- SkSize::Make(SkScalarAbs(scale.width() * tile_.width()),
- SkScalarAbs(scale.height() * tile_.height()));
-
- // Clamp the tile size to about 4M pixels.
- // TODO(khushalsagar): We need to consider the max texture size as well.
- static const SkScalar kMaxTileArea = 2048 * 2048;
- SkScalar tile_area = scaled_size.width() * scaled_size.height();
- if (tile_area > kMaxTileArea) {
- SkScalar clamp_scale = SkScalarSqrt(kMaxTileArea / tile_area);
- scaled_size.set(scaled_size.width() * clamp_scale,
- scaled_size.height() * clamp_scale);
- }
-
- scaled_size = scaled_size.toCeil();
- if (scaled_size.isEmpty())
- return false;
-
- *tile_rect = SkRect::MakeWH(scaled_size.width(), scaled_size.height());
- return true;
-}
-
-sk_sp<PaintShader> PaintShader::CreateDecodedPaintRecord(
- const SkMatrix& ctm,
- ImageProvider* image_provider) const {
- DCHECK_EQ(shader_type_, Type::kPaintRecord);
-
- // For creating a decoded PaintRecord shader, we need to do the following:
- // 1) Figure out the scale at which the record should be rasterization given
- // the ctm and local_matrix on the shader.
- // 2) Transform this record to an SkPicture with this scale and replace
- // encoded images in this record with decodes from the ImageProvider. This
- // is done by setting the rasterization_matrix_ for this shader to be used
- // in GetSkShader.
- // 3) Since the SkShader will use a scaled SkPicture, we use a kFixedScale for
- // the decoded shader which creates an SkPicture backed SkImage for
- // creating the decoded SkShader.
- // Note that the scaling logic here is replicated from
- // SkPictureShader::refBitmapShader.
- SkRect tile_rect;
- if (!GetRasterizationTileRect(ctm, &tile_rect))
- return nullptr;
-
- sk_sp<PaintShader> shader(new PaintShader(Type::kPaintRecord));
- shader->record_ = record_;
- shader->tile_ = tile_rect;
- // Use a fixed scale since we have already scaled the tile rect and fixed the
- // raster scale.
- shader->scaling_behavior_ = ScalingBehavior::kFixedScale;
- shader->rasterization_matrix_.emplace();
- shader->rasterization_matrix_.value().setRectToRect(
- tile_, tile_rect, SkMatrix::kFill_ScaleToFit);
- shader->tx_ = tx_;
- shader->ty_ = ty_;
-
- const SkSize tile_scale =
- SkSize::Make(SkIntToScalar(tile_rect.width()) / tile_.width(),
- SkIntToScalar(tile_rect.height()) / tile_.height());
- shader->local_matrix_ = GetLocalMatrix();
- shader->local_matrix_->preScale(1 / tile_scale.width(),
- 1 / tile_scale.height());
-
- shader->image_provider_ = image_provider;
-
- return shader;
-}
-
sk_sp<SkShader> PaintShader::GetSkShader() const {
if (cached_shader_)
return cached_shader_;
@@ -288,12 +182,7 @@
tx_, ty_, local_matrix_ ? &*local_matrix_ : nullptr);
break;
case Type::kPaintRecord: {
- // Create a recording at the desired scale if this record has images which
- // have been decoded before raster.
- auto picture = ToSkPicture(
- record_, tile_,
- rasterization_matrix_ ? &rasterization_matrix_.value() : nullptr,
- image_provider_);
+ auto picture = ToSkPicture(record_, tile_);
switch (scaling_behavior_) {
// For raster scale, we create a picture shader directly.
@@ -302,7 +191,7 @@
std::move(picture), tx_, ty_,
local_matrix_ ? &*local_matrix_ : nullptr, nullptr);
break;
- // For fixed scale, we create an image shader with an image backed by
+ // For fixed scale, we create an image shader with and image backed by
// the picture.
case ScalingBehavior::kFixedScale: {
auto image = SkImage::MakeFromPicture(
diff --git a/cc/paint/paint_shader.h b/cc/paint/paint_shader.h
index 42ec44be..8a133709 100644
--- a/cc/paint/paint_shader.h
+++ b/cc/paint/paint_shader.h
@@ -16,7 +16,7 @@
#include "third_party/skia/include/core/SkShader.h"
namespace cc {
-class ImageProvider;
+
class PaintOpBuffer;
using PaintRecord = PaintOpBuffer;
@@ -111,12 +111,8 @@
return image_;
}
- const sk_sp<PaintRecord>& paint_record() const { return record_; }
- bool GetRasterizationTileRect(const SkMatrix& ctm, SkRect* tile_rect) const;
-
SkShader::TileMode tx() const { return tx_; }
SkShader::TileMode ty() const { return ty_; }
- SkRect tile() const { return tile_; }
bool IsOpaque() const;
@@ -131,17 +127,11 @@
friend class PaintOpReader;
friend class PaintOpSerializationTestUtils;
friend class PaintOpWriter;
- friend class ScopedImageFlags;
- FRIEND_TEST_ALL_PREFIXES(PaintShaderTest, DecodePaintRecord);
explicit PaintShader(Type type);
sk_sp<SkShader> GetSkShader() const;
- sk_sp<PaintShader> CreateDecodedPaintRecord(
- const SkMatrix& ctm,
- ImageProvider* image_provider) const;
-
void SetColorsAndPositions(const SkColor* colors,
const SkScalar* positions,
int count);
@@ -176,12 +166,6 @@
std::vector<SkColor> colors_;
std::vector<SkScalar> positions_;
- // The following are only used during raster to replace the decoded images in
- // the record for this shader. The |image_provider_| and
- // |decoded_image_stash_| must outlive this shader.
- ImageProvider* image_provider_ = nullptr;
- base::Optional<SkMatrix> rasterization_matrix_;
-
mutable sk_sp<SkShader> cached_shader_;
DISALLOW_COPY_AND_ASSIGN(PaintShader);
diff --git a/cc/paint/paint_shader_unittest.cc b/cc/paint/paint_shader_unittest.cc
deleted file mode 100644
index 340bbc3..0000000
--- a/cc/paint/paint_shader_unittest.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2015 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/paint/paint_shader.h"
-
-#include "cc/paint/draw_image.h"
-#include "cc/paint/image_provider.h"
-#include "cc/paint/paint_image_builder.h"
-#include "cc/paint/paint_op_buffer.h"
-#include "cc/test/fake_paint_image_generator.h"
-#include "cc/test/skia_common.h"
-#include "cc/test/test_skcanvas.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkSurface.h"
-
-namespace cc {
-namespace {
-
-class MockImageGenerator : public FakePaintImageGenerator {
- public:
- explicit MockImageGenerator(const gfx::Size& size)
- : FakePaintImageGenerator(
- SkImageInfo::MakeN32Premul(size.width(), size.height())) {}
-
- MOCK_METHOD5(GetPixels,
- bool(const SkImageInfo&, void*, size_t, size_t, uint32_t));
-};
-
-class MockImageProvider : public ImageProvider {
- public:
- MockImageProvider() = default;
- ~MockImageProvider() override = default;
-
- ScopedDecodedDrawImage GetDecodedDrawImage(
- const DrawImage& draw_image) override {
- draw_image_ = draw_image;
-
- SkBitmap bitmap;
- bitmap.allocN32Pixels(10, 10);
- bitmap.eraseColor(SK_ColorBLACK);
- sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
- return ScopedDecodedDrawImage(
- DecodedDrawImage(image, SkSize::MakeEmpty(), SkSize::Make(1.0f, 1.0f),
- draw_image.filter_quality()));
- }
-
- const DrawImage& draw_image() const { return draw_image_; }
-
- private:
- DrawImage draw_image_;
-};
-
-} // namespace
-
-TEST(PaintShaderTest, RasterizationRectForRecordShaders) {
- SkMatrix local_matrix = SkMatrix::MakeScale(0.5f, 0.5f);
- auto record_shader = PaintShader::MakePaintRecord(
- sk_make_sp<PaintOpBuffer>(), SkRect::MakeWH(100, 100),
- SkShader::TileMode::kClamp_TileMode, SkShader::TileMode::kClamp_TileMode,
- &local_matrix);
-
- SkRect tile_rect;
- SkMatrix ctm = SkMatrix::MakeScale(0.5f, 0.5f);
- EXPECT_TRUE(record_shader->GetRasterizationTileRect(ctm, &tile_rect));
- EXPECT_EQ(tile_rect, SkRect::MakeWH(25, 25));
-}
-
-TEST(PaintShaderTest, DecodePaintRecord) {
- auto record = sk_make_sp<PaintOpBuffer>();
-
- // Use a strict mock for the generator. It should never be used when
- // rasterizing this shader, since the decode should be done by the
- // ImageProvider.
- auto generator =
- sk_make_sp<testing::StrictMock<MockImageGenerator>>(gfx::Size(100, 100));
- PaintImage paint_image = PaintImageBuilder()
- .set_id(PaintImage::GetNextId())
- .set_paint_image_generator(generator)
- .TakePaintImage();
-
- record->push<DrawImageOp>(paint_image, 0.f, 0.f, nullptr);
- SkMatrix local_matrix = SkMatrix::MakeScale(0.5f, 0.5f);
- auto record_shader = PaintShader::MakePaintRecord(
- record, SkRect::MakeWH(100, 100), SkShader::TileMode::kClamp_TileMode,
- SkShader::TileMode::kClamp_TileMode, &local_matrix);
-
- PaintOpBuffer buffer;
- PaintFlags flags;
- flags.setShader(record_shader);
- buffer.push<ScaleOp>(0.5f, 0.5f);
- buffer.push<DrawRectOp>(SkRect::MakeWH(100, 100), flags);
-
- MockImageProvider image_provider;
- SaveCountingCanvas canvas;
- buffer.Playback(&canvas, &image_provider);
-
- EXPECT_EQ(canvas.draw_rect_, SkRect::MakeWH(100, 100));
- SkShader* shader = canvas.paint_.getShader();
- ASSERT_TRUE(shader);
- SkMatrix decoded_local_matrix;
- SkShader::TileMode xy[2];
- SkImage* skia_image = shader->isAImage(&decoded_local_matrix, xy);
- ASSERT_TRUE(skia_image);
- EXPECT_TRUE(skia_image->isLazyGenerated());
- EXPECT_EQ(xy[0], record_shader->tx());
- EXPECT_EQ(xy[1], record_shader->ty());
- EXPECT_EQ(decoded_local_matrix, SkMatrix::MakeScale(2.f, 2.f));
-
- // The rasterization of the shader is internal to skia, so use a raster canvas
- // to verify that the decoded paint does not have the encoded image.
- auto surface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(100, 100));
- surface->getCanvas()->drawPaint(canvas.paint_);
-
- // Using the shader requests decode for images at the correct scale.
- EXPECT_EQ(image_provider.draw_image().paint_image(), paint_image);
- EXPECT_EQ(image_provider.draw_image().scale(), SkSize::Make(0.25f, 0.25f));
-}
-
-} // namespace cc
diff --git a/cc/paint/scoped_image_flags.cc b/cc/paint/scoped_image_flags.cc
deleted file mode 100644
index cadb1da..0000000
--- a/cc/paint/scoped_image_flags.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2017 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/paint/scoped_image_flags.h"
-
-#include "cc/paint/image_provider.h"
-#include "cc/paint/paint_image_builder.h"
-
-namespace cc {
-namespace {
-SkIRect RoundOutRect(const SkRect& rect) {
- SkIRect result;
- rect.roundOut(&result);
- return result;
-}
-} // namespace
-
-ScopedImageFlags::DecodeStashingImageProvider::DecodeStashingImageProvider(
- ImageProvider* source_provider)
- : source_provider_(source_provider) {}
-ScopedImageFlags::DecodeStashingImageProvider::~DecodeStashingImageProvider() =
- default;
-
-ImageProvider::ScopedDecodedDrawImage
-ScopedImageFlags::DecodeStashingImageProvider::GetDecodedDrawImage(
- const DrawImage& draw_image) {
- auto decode = source_provider_->GetDecodedDrawImage(draw_image);
- if (!decode)
- return ScopedDecodedDrawImage();
-
- // No need to add any destruction callback to the returned image. The images
- // decoded here match the lifetime of this provider.
- auto image_to_return = ScopedDecodedDrawImage(decode.decoded_image());
- decoded_images_.push_back(std::move(decode));
- return image_to_return;
-}
-
-ScopedImageFlags::ScopedImageFlags(ImageProvider* image_provider,
- const PaintFlags& flags,
- const SkMatrix& ctm)
- : decode_stashing_image_provider_(image_provider) {
- if (flags.getShader()->shader_type() == PaintShader::Type::kImage) {
- DecodeImageShader(flags, ctm);
- } else {
- DCHECK_EQ(flags.getShader()->shader_type(),
- PaintShader::Type::kPaintRecord);
- DecodeRecordShader(flags, ctm);
- }
-}
-
-ScopedImageFlags::~ScopedImageFlags() = default;
-
-void ScopedImageFlags::DecodeImageShader(const PaintFlags& flags,
- const SkMatrix& ctm) {
- const PaintImage& paint_image = flags.getShader()->paint_image();
- SkMatrix matrix = flags.getShader()->GetLocalMatrix();
-
- SkMatrix total_image_matrix = matrix;
- total_image_matrix.preConcat(ctm);
- SkRect src_rect = SkRect::MakeIWH(paint_image.width(), paint_image.height());
- DrawImage draw_image(paint_image, RoundOutRect(src_rect),
- flags.getFilterQuality(), total_image_matrix);
- auto decoded_draw_image =
- decode_stashing_image_provider_.GetDecodedDrawImage(draw_image);
-
- if (!decoded_draw_image)
- return;
-
- const auto& decoded_image = decoded_draw_image.decoded_image();
- DCHECK(decoded_image.image());
-
- bool need_scale = !decoded_image.is_scale_adjustment_identity();
- if (need_scale) {
- matrix.preScale(1.f / decoded_image.scale_adjustment().width(),
- 1.f / decoded_image.scale_adjustment().height());
- }
-
- sk_sp<SkImage> sk_image =
- sk_ref_sp<SkImage>(const_cast<SkImage*>(decoded_image.image().get()));
- PaintImage decoded_paint_image = PaintImageBuilder()
- .set_id(paint_image.stable_id())
- .set_image(std::move(sk_image))
- .TakePaintImage();
- decoded_flags_.emplace(flags);
- decoded_flags_.value().setFilterQuality(decoded_image.filter_quality());
- decoded_flags_.value().setShader(
- PaintShader::MakeImage(decoded_paint_image, flags.getShader()->tx(),
- flags.getShader()->ty(), &matrix));
-}
-
-void ScopedImageFlags::DecodeRecordShader(const PaintFlags& flags,
- const SkMatrix& ctm) {
- auto decoded_shader = flags.getShader()->CreateDecodedPaintRecord(
- ctm, &decode_stashing_image_provider_);
- if (!decoded_shader)
- return;
-
- decoded_flags_.emplace(flags);
- decoded_flags_.value().setShader(std::move(decoded_shader));
-}
-
-} // namespace cc
diff --git a/cc/paint/scoped_image_flags.h b/cc/paint/scoped_image_flags.h
deleted file mode 100644
index 9c39bf8..0000000
--- a/cc/paint/scoped_image_flags.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2017 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_PAINT_SCOPED_IMAGE_FLAGS_H_
-#define CC_PAINT_SCOPED_IMAGE_FLAGS_H_
-
-#include "base/macros.h"
-#include "cc/paint/paint_export.h"
-#include "cc/paint/paint_op_buffer.h"
-
-namespace cc {
-class ImageProvider;
-
-// A helper class to decode images inside the provided |flags| and provide a
-// PaintFlags with the decoded images that can directly be used for
-// rasterization.
-// This class should only be used if |flags| has any discardable images.
-class CC_PAINT_EXPORT ScopedImageFlags {
- public:
- // |image_provider| must outlive this class.
- ScopedImageFlags(ImageProvider* image_provider,
- const PaintFlags& flags,
- const SkMatrix& ctm);
- ~ScopedImageFlags();
-
- // The usage of these flags should not extend beyond the lifetime of this
- // object.
- PaintFlags* decoded_flags() {
- return decoded_flags_ ? &decoded_flags_.value() : nullptr;
- }
-
- private:
- // An ImageProvider that passes decode requests through to the
- // |source_provider| but keeps the decode cached throughtout its lifetime,
- // instead of passing the ref to the caller.
- class DecodeStashingImageProvider : public ImageProvider {
- public:
- // |source_provider| must outlive this class.
- explicit DecodeStashingImageProvider(ImageProvider* source_provider);
- ~DecodeStashingImageProvider() override;
-
- // ImageProvider implementation.
- ScopedDecodedDrawImage GetDecodedDrawImage(
- const DrawImage& draw_image) override;
-
- private:
- ImageProvider* source_provider_;
- std::vector<ScopedDecodedDrawImage> decoded_images_;
-
- DISALLOW_COPY_AND_ASSIGN(DecodeStashingImageProvider);
- };
-
- void DecodeImageShader(const PaintFlags& flags, const SkMatrix& ctm);
-
- void DecodeRecordShader(const PaintFlags& flags, const SkMatrix& ctm);
-
- base::Optional<PaintFlags> decoded_flags_;
- DecodeStashingImageProvider decode_stashing_image_provider_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedImageFlags);
-};
-
-} // namespace cc
-
-#endif // CC_PAINT_SCOPED_IMAGE_FLAGS_H_
diff --git a/cc/paint/scoped_image_flags_unittest.cc b/cc/paint/scoped_image_flags_unittest.cc
deleted file mode 100644
index b8e919a9..0000000
--- a/cc/paint/scoped_image_flags_unittest.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2017 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/paint/scoped_image_flags.h"
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "cc/test/skia_common.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-class MockImageProvider : public ImageProvider {
- public:
- MockImageProvider() = default;
- ~MockImageProvider() override { EXPECT_EQ(ref_count_, 0); }
-
- ScopedDecodedDrawImage GetDecodedDrawImage(
- const DrawImage& draw_image) override {
- ref_count_++;
-
- SkBitmap bitmap;
- bitmap.allocN32Pixels(10, 10);
- sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
-
- return ScopedDecodedDrawImage(
- DecodedDrawImage(image, SkSize::MakeEmpty(), SkSize::Make(1.0f, 1.0f),
- draw_image.filter_quality()),
- base::BindOnce(&MockImageProvider::UnrefImage, base::Unretained(this)));
- }
-
- void UnrefImage(DecodedDrawImage decoded_image) {
- ref_count_--;
- CHECK_GE(ref_count_, 0);
- }
-
- int ref_count() const { return ref_count_; }
-
- private:
- int ref_count_ = 0;
-};
-} // namespace
-
-TEST(ScopedImageFlagsTest, KeepsDecodesAlive) {
- auto record = sk_make_sp<PaintOpBuffer>();
- record->push<DrawImageOp>(CreateDiscardablePaintImage(gfx::Size(10, 10)), 0.f,
- 0.f, nullptr);
- record->push<DrawImageOp>(CreateDiscardablePaintImage(gfx::Size(10, 10)), 0.f,
- 0.f, nullptr);
- record->push<DrawImageOp>(CreateDiscardablePaintImage(gfx::Size(10, 10)), 0.f,
- 0.f, nullptr);
- auto record_shader = PaintShader::MakePaintRecord(
- record, SkRect::MakeWH(100, 100), SkShader::TileMode::kClamp_TileMode,
- SkShader::TileMode::kClamp_TileMode, &SkMatrix::I());
-
- MockImageProvider provider;
- PaintFlags flags;
- flags.setShader(record_shader);
- {
- ScopedImageFlags scoped_flags(&provider, flags, SkMatrix::I());
- ASSERT_TRUE(scoped_flags.decoded_flags());
- SkPaint paint = scoped_flags.decoded_flags()->ToSkPaint();
- ASSERT_TRUE(paint.getShader());
- EXPECT_EQ(provider.ref_count(), 3);
- }
- EXPECT_EQ(provider.ref_count(), 0);
-}
-
-} // namespace cc
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-background-image-space-expected.png
index c5d0b0f0..a811512 100644
--- a/third_party/WebKit/LayoutTests/images/color-profile-background-image-space-expected.png
+++ b/third_party/WebKit/LayoutTests/images/color-profile-background-image-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/http/tests/misc/slow-loading-image-in-pattern-expected.png
index cabe47b..424b4db 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/http/tests/misc/slow-loading-image-in-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png
index 5d8eaeae..c7e1f7b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
index 9c73ba8..66498a7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
index cabe47b..424b4db 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png
index 08343bfa..a773132 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
index 05ebe12..07a3c2c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-repeat-space-padding-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-repeat-space-padding-expected.png
index eedee93..47ed2d1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-repeat-space-padding-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-repeat-space-padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/images/color-profile-svg-fill-text-expected.png
index b2aeb5a..cde34596 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
index 1df1cd4..0f4a16b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-repeat-space-padding-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-repeat-space-padding-expected.png
index 636b74b..eb90563 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-repeat-space-padding-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-repeat-space-padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-repeat-with-background-color-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-repeat-with-background-color-expected.png
index 6f502775..4dba2a8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-repeat-with-background-color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-repeat-with-background-color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/http/tests/misc/slow-loading-image-in-pattern-expected.png
index 5c897cc..d8181498 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/http/tests/misc/slow-loading-image-in-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-fill-text-expected.png
index 5773e7e..75c356c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png
index 3359ed2..13c9b2e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
deleted file mode 100644
index 7b65507..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
index 8cde405..41f9297 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
index 73cbaf7a..f268586 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png
index e138bc81..94f1612 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
index 5c897cc..d8181498 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-repeat-space-padding-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-repeat-space-padding-expected.png
index 6dd1e66..391076d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-repeat-space-padding-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-repeat-space-padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-repeat-with-background-color-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-repeat-with-background-color-expected.png
index 47bfe99..f6ab2241 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-repeat-with-background-color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-repeat-with-background-color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/http/tests/misc/slow-loading-image-in-pattern-expected.png
index fe19eb5..2304502 100644
--- a/third_party/WebKit/LayoutTests/platform/win/http/tests/misc/slow-loading-image-in-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png
index 7d0f474..15b2a7c8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png
index af34a7c..6dd3d20b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
index a8f389c6..8b8e6e0a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
index 6a319b8..e6b8478 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-fill-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
index 2699d76..6965947 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png
index 0123a81..54806de 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
index fe19eb5..2304502 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
new file mode 100644
index 0000000..9e5603dc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
Binary files differ