Commit bff70915 authored by Sushanth Rajasankar's avatar Sushanth Rajasankar Committed by Commit Bot

Add looper support for DrawImageRectOp

Similar to the pattern established by
https://chromium-review.googlesource.com/c/chromium/src/+/1713304
this change adds support for loopers for DrawImageRectOp.

Care is taken to keep image_provider->GetRasterContent outside the loop
since the raster content should be reused across loops.

Bug: 1065694
Change-Id: Ia716a0566565fe357d6c6a272659225328a781ea
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2159125Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Commit-Queue: Sushanth Rajasankar <Sushraja@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#762124}
parent 0aeaf14f
......@@ -1310,7 +1310,6 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
const PaintFlags* flags,
SkCanvas* canvas,
const PlaybackParams& params) {
SkPaint paint = flags ? flags->ToSkPaint() : SkPaint();
// TODO(crbug.com/931704): make sure to support the case where paint worklet
// generated images are used in other raster work such as canvas2d.
if (op->image.IsPaintWorklet()) {
......@@ -1322,6 +1321,11 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
ImageProvider::ScopedResult result =
params.image_provider->GetRasterContent(DrawImage(op->image));
// Check that we are not using loopers with paint worklets, since converting
// PaintFlags to SkPaint drops loopers.
DCHECK(!flags->getLooper());
SkPaint paint = flags ? flags->ToSkPaint() : SkPaint();
DCHECK(IsScaleAdjustmentIdentity(op->scale_adjustment));
SkAutoCanvasRestore save_restore(canvas, true);
canvas->concat(
......@@ -1344,8 +1348,11 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
if (!params.image_provider) {
SkRect adjusted_src = AdjustSrcRectForScale(op->src, op->scale_adjustment);
canvas->drawImageRect(op->image.GetSkImage().get(), adjusted_src, op->dst,
&paint, skconstraint);
flags->DrawToSk(canvas, [op, adjusted_src, skconstraint](SkCanvas* c,
const SkPaint& p) {
c->drawImageRect(op->image.GetSkImage().get(), adjusted_src, op->dst, &p,
skconstraint);
});
return;
}
......@@ -1374,9 +1381,13 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
op->src.makeOffset(decoded_image.src_rect_offset().width(),
decoded_image.src_rect_offset().height());
adjusted_src = AdjustSrcRectForScale(adjusted_src, scale_adjustment);
paint.setFilterQuality(decoded_image.filter_quality());
canvas->drawImageRect(decoded_image.image().get(), adjusted_src, op->dst,
&paint, skconstraint);
flags->DrawToSk(canvas, [op, &decoded_image, adjusted_src, skconstraint](
SkCanvas* c, const SkPaint& p) {
SkPaint paint_with_filter_quality(p);
paint_with_filter_quality.setFilterQuality(decoded_image.filter_quality());
c->drawImageRect(decoded_image.image().get(), adjusted_src, op->dst,
&paint_with_filter_quality, skconstraint);
});
}
void DrawIRectOp::RasterWithFlags(const DrawIRectOp* op,
......
......@@ -3132,6 +3132,56 @@ TEST(PaintOpBufferTest, ReplacesImagesFromProvider) {
buffer.Playback(&canvas, PlaybackParams(&image_provider));
}
TEST(PaintOpBufferTest, DrawImageRectOpWithLooperNoImageProvider) {
PaintOpBuffer buffer;
PaintImage image = CreateDiscardablePaintImage(gfx::Size(100, 100));
SkLayerDrawLooper::Builder sk_draw_looper_builder;
sk_draw_looper_builder.addLayer(20.0, 20.0);
SkLayerDrawLooper::LayerInfo info_unmodified;
sk_draw_looper_builder.addLayerOnTop(info_unmodified);
PaintFlags paint_flags;
paint_flags.setLooper(sk_draw_looper_builder.detach());
buffer.push<DrawImageRectOp>(
image, SkRect::MakeWH(100, 100), SkRect::MakeWH(100, 100), &paint_flags,
PaintCanvas::SrcRectConstraint::kFast_SrcRectConstraint);
testing::StrictMock<MockCanvas> canvas;
EXPECT_CALL(canvas, willSave);
EXPECT_CALL(canvas, didTranslate);
EXPECT_CALL(canvas, willRestore);
EXPECT_CALL(canvas, onDrawImageRect).Times(2);
buffer.Playback(&canvas, PlaybackParams(nullptr));
}
TEST(PaintOpBufferTest, DrawImageRectOpWithLooperWithImageProvider) {
PaintOpBuffer buffer;
PaintImage image = CreateDiscardablePaintImage(gfx::Size(100, 100));
SkLayerDrawLooper::Builder sk_draw_looper_builder;
sk_draw_looper_builder.addLayer(20.0, 20.0);
SkLayerDrawLooper::LayerInfo info_unmodified;
sk_draw_looper_builder.addLayerOnTop(info_unmodified);
PaintFlags paint_flags;
paint_flags.setLooper(sk_draw_looper_builder.detach());
buffer.push<DrawImageRectOp>(
image, SkRect::MakeWH(100, 100), SkRect::MakeWH(100, 100), &paint_flags,
PaintCanvas::SrcRectConstraint::kFast_SrcRectConstraint);
testing::StrictMock<MockCanvas> canvas;
EXPECT_CALL(canvas, willSave);
EXPECT_CALL(canvas, didTranslate);
EXPECT_CALL(canvas, willRestore);
EXPECT_CALL(canvas, onDrawImageRect).Times(2);
std::vector<SkSize> src_rect_offset = {SkSize::MakeEmpty()};
std::vector<SkSize> scale_adjustment = {SkSize::Make(1.0f, 1.0f)};
std::vector<SkFilterQuality> quality = {kHigh_SkFilterQuality};
MockImageProvider image_provider(src_rect_offset, scale_adjustment, quality);
buffer.Playback(&canvas, PlaybackParams(&image_provider));
}
TEST(PaintOpBufferTest, ReplacesImagesFromProviderOOP) {
PaintOpBuffer buffer;
SkSize expected_scale = SkSize::Make(0.2f, 0.5f);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment