Must pass filtering to picture shader

Change-Id: I820867df80daa1594d6202cad5e8e95c060293fe
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/386838
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Mike Reed 2021-03-18 17:18:58 -04:00 committed by Skia Commit-Bot
parent 95eca3e051
commit 10a5ff2cac
15 changed files with 36 additions and 81 deletions

View File

@ -33,7 +33,8 @@ static sk_sp<SkShader> make_picture_shader() {
SkPictureRecorder recorder;
recorder.beginRecording(100, 100)->drawCircle(50, 50, 50, p);
return recorder.finishRecordingAsPicture()->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat);
return recorder.finishRecordingAsPicture()->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
SkFilterMode::kNearest);
}
class ShaderMFBench final : public Benchmark {

View File

@ -54,7 +54,7 @@ void draw(SkCanvas* canvas) {
SkPictureRecorder rec;
draw_wheel(rec.beginRecording(512, 512));
paint.setShader(rec.finishRecordingAsPicture()->makeShader(
SkTileMode::kRepeat, SkTileMode::kRepeat, &matrix, nullptr));
SkTileMode::kRepeat, SkTileMode::kRepeat, SkFilterMode::kNearest, &matrix, nullptr));
canvas->drawPaint(paint);
}
} // END FIDDLE

View File

@ -226,7 +226,8 @@ static sk_sp<SkShader> make_fuzz_shader(Fuzz* fuzz, int depth) {
if (useTile) {
fuzz->next(&tile);
}
return pic->makeShader(tmX, tmY, useMatrix ? &matrix : nullptr, useTile ? &tile : nullptr);
return pic->makeShader(tmX, tmY, SkFilterMode::kNearest,
useMatrix ? &matrix : nullptr, useTile ? &tile : nullptr);
}
// EFFECTS:
case 9:

View File

@ -30,7 +30,8 @@ DEF_SIMPLE_GM(bug6643, canvas, 200, 200) {
recorder.beginRecording(200, 200)->drawPaint(p);
p.setShader(recorder.finishRecordingAsPicture()->makeShader(
SkTileMode::kRepeat, SkTileMode::kRepeat));
SkTileMode::kRepeat, SkTileMode::kRepeat,
SkFilterMode::kNearest, nullptr, nullptr));
canvas->drawColor(SK_ColorWHITE);
canvas->drawPaint(p);
}

View File

@ -922,8 +922,8 @@ DEF_SIMPLE_GM(fancy_gradients, canvas, 800, 300) {
SkMatrix m = SkMatrix::I();
m.preRotate(45);
return recorder.finishRecordingAsPicture()->makeShader(
SkTileMode::kRepeat,
SkTileMode::kRepeat, &m, nullptr);
SkTileMode::kRepeat, SkTileMode::kRepeat,
SkFilterMode::kNearest, &m, nullptr);
});
draw_circle_shader(canvas, 400, 150, 100, []() -> sk_sp<SkShader> {
@ -944,7 +944,7 @@ DEF_SIMPLE_GM(fancy_gradients, canvas, 800, 300) {
return recorder.finishRecordingAsPicture()->makeShader(
SkTileMode::kRepeat,
SkTileMode::kRepeat);
SkTileMode::kRepeat, SkFilterMode::kNearest);
});
draw_circle_shader(canvas, 650, 150, 100, []() -> sk_sp<SkShader> {

View File

@ -163,6 +163,7 @@ private:
auto pictureShader = fPicture->makeShader(kTileConfigs[tileMode].tmx,
kTileConfigs[tileMode].tmy,
SkFilterMode::kNearest,
fUseLocalMatrixWrapper ? nullptr : &localMatrix,
nullptr);
paint.setShader(fUseLocalMatrixWrapper
@ -222,70 +223,7 @@ DEF_SIMPLE_GM(tiled_picture_shader, canvas, 400, 400) {
p.setColor(0xFFB6B6B6); // gray
canvas->drawPaint(p);
p.setShader(picture->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
p.setShader(picture->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
SkFilterMode::kNearest));
canvas->drawPaint(p);
}
#ifdef SK_SUPPORT_LEGACY_SETFILTERQUALITY
/*
Test picture-shader's filtering (after the tile is created.
The GM draws a 2x2 grid of tiled images (circle, square, X)
Column 0 should be hard-edged
Column 1 should be filtered
Row 0 deduces this from the paint (legacy behavior)
Row 1 takes this as an explicit parameter (SkFilterMode)
*/
DEF_SIMPLE_GM(picture_shader_filter, canvas, 230, 230) {
auto pic = [&] {
SkRect r = SkRect::MakeWH(100, 100);
SkPictureRecorder recorder;
SkCanvas* c = recorder.beginRecording(r);
SkPaint paint;
paint.setStroke(true);
c->drawRect({5, 5, 95, 95}, paint);
c->drawCircle(50, 50, 30, paint);
c->drawLine(5, 1, 95,95, paint);
c->drawLine(5,95, 95, 1, paint);
return recorder.finishRecordingAsPicture();
}();
struct {
SkPoint fLoc;
SkFilterMode fFilter;
bool fInheritFromPaint;
void setup(SkPaint* paint, sk_sp<SkPicture> pic) const {
SkTileMode tm = SkTileMode::kRepeat;
sk_sp<SkShader> sh;
if (fInheritFromPaint) {
sh = pic->makeShader(tm, tm, nullptr, nullptr);
paint->setFilterQuality(fFilter == SkFilterMode::kNearest ? kNone_SkFilterQuality
: kLow_SkFilterQuality);
} else {
sh = pic->makeShader(tm, tm, fFilter, nullptr, nullptr);
// the draw should ignore paint's filterquality,
// but we'll set it to something wacky just to be test that
paint->setFilterQuality(kHigh_SkFilterQuality);
}
paint->setShader(sh);
}
} recs[] = {
{ {0, 0}, SkFilterMode::kNearest, true },
{ {1, 0}, SkFilterMode::kLinear, true },
{ {0, 1}, SkFilterMode::kNearest, false },
{ {1, 1}, SkFilterMode::kLinear, false },
};
canvas->translate(10, 10);
canvas->scale(1.0f/3, 1.0f/3);
for (const auto& r : recs) {
SkAutoCanvasRestore acr(canvas, true);
canvas->translate(r.fLoc.fX * 330, r.fLoc.fY * 330);
SkPaint paint;
r.setup(&paint, pic);
canvas->drawRect({0, 0, 300, 300}, paint);
}
}
#endif

View File

@ -67,7 +67,8 @@ public:
void onDraw(SkCanvas* canvas) override {
SkPaint paint;
paint.setShader(fPicture->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
paint.setShader(fPicture->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
SkFilterMode::kNearest));
{
// Render in a funny color space that converts green to yellow.

View File

@ -135,7 +135,7 @@ protected:
}
fShaders[i] = pictureRef->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
&localMatrix, tilePtr);
SkFilterMode::kNearest, &localMatrix, tilePtr);
}
}

View File

@ -11,6 +11,7 @@
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkShader.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypes.h"
@ -20,7 +21,6 @@ struct SkDeserialProcs;
class SkImage;
class SkMatrix;
struct SkSerialProcs;
class SkShader;
class SkStream;
class SkWStream;
@ -230,11 +230,16 @@ public:
sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode,
const SkMatrix* localMatrix, const SkRect* tileRect) const;
// DEPRECATED
sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode) const {
return this->makeShader(tmx, tmy, mode, nullptr, nullptr);
}
#ifdef SK_SUPPORT_LEGACY_PICTURESHADER_NOFILTER
sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy,
const SkMatrix* localMatrix, const SkRect* tileRect) const;
sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy,
const SkMatrix* localMatrix = nullptr) const;
#endif
private:
// Allowed subclasses.

View File

@ -189,6 +189,7 @@ private:
const auto child_tile = SkRect::MakeSize(fChildSize);
auto child_shader = child_content->makeShader(fChildTileMode,
fChildTileMode,
SkFilterMode::kLinear,
nullptr,
&child_tile);
@ -197,6 +198,7 @@ private:
const auto displ_matrix = this->displacementMatrix();
auto displ_shader = displ_content->makeShader(displ_mode,
displ_mode,
SkFilterMode::kLinear,
&displ_matrix,
&displ_tile);

View File

@ -83,7 +83,8 @@ protected:
SkRect::MakeWH(fLayerSize.width(), fLayerSize.height()), tile);
const auto tm = fMirrorEdges ? SkTileMode::kMirror : SkTileMode::kRepeat;
auto layer_shader = fLayerPicture->makeShader(tm, tm, &layerShaderMatrix);
auto layer_shader = fLayerPicture->makeShader(tm, tm, SkFilterMode::kLinear,
&layerShaderMatrix, nullptr);
if (fPhase) {
// To implement AE phase semantics, we construct a mask shader for the pass-through

View File

@ -114,6 +114,7 @@ bool SkSVGPattern::onAsPaint(const SkSVGRenderContext& ctx, SkPaint* paint) cons
paint->setShader(recorder.finishRecordingAsPicture()->makeShader(
SkTileMode::kRepeat,
SkTileMode::kRepeat,
SkFilterMode::kLinear,
patternTransform,
&tile));
return true;

View File

@ -44,6 +44,7 @@ sk_sp<SkShader> SkPicture::makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMo
localMatrix, tile);
}
#ifdef SK_SUPPORT_LEGACY_PICTURESHADER_NOFILTER
sk_sp<SkShader> SkPicture::makeShader(SkTileMode tmx, SkTileMode tmy, const SkMatrix* localMatrix,
const SkRect* tile) const {
if (localMatrix && !localMatrix->invert(nullptr)) {
@ -57,6 +58,7 @@ sk_sp<SkShader> SkPicture::makeShader(SkTileMode tmx, SkTileMode tmy,
const SkMatrix* localMatrix) const {
return this->makeShader(tmx, tmy, localMatrix, nullptr);
}
#endif
namespace {
static unsigned gImageFromPictureKeyNamespaceLabel;

View File

@ -30,7 +30,8 @@ DEF_TEST(PictureShader_caching, reporter) {
{
SkPaint paint;
paint.setShader(picture->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
paint.setShader(picture->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
SkFilterMode::kNearest));
surface->getCanvas()->drawPaint(paint);
// We should have about 3 refs by now: local + shader + shader cache.
@ -40,7 +41,8 @@ DEF_TEST(PictureShader_caching, reporter) {
// Draw another picture shader to have a chance to purge.
{
SkPaint paint;
paint.setShader(makePicture()->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
paint.setShader(makePicture()->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
SkFilterMode::kNearest));
surface->getCanvas()->drawPaint(paint);
}
@ -87,7 +89,7 @@ DEF_TEST(PictureShader_caching2, reporter) {
SkTileMode::kClamp, SkTileMode::kRepeat, SkTileMode::kRepeat, SkTileMode::kDecal
}) {
SkPaint paint;
paint.setShader(picture->makeShader(m, m));
paint.setShader(picture->makeShader(m, m, SkFilterMode::kNearest));
surface->getCanvas()->drawPaint(paint);
}

View File

@ -163,7 +163,7 @@ DEF_TEST(serial_procs_picture, reporter) {
p0 = make_pic([p1](SkCanvas* c) {
SkPaint paint;
SkTileMode tm = SkTileMode::kClamp;
paint.setShader(p1->makeShader(tm, tm));
paint.setShader(p1->makeShader(tm, tm, SkFilterMode::kNearest));
c->drawPaint(paint);
});
test_pictures(reporter, p0, 1, true);