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:
parent
95eca3e051
commit
10a5ff2cac
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -135,7 +135,7 @@ protected:
|
||||
}
|
||||
|
||||
fShaders[i] = pictureRef->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
|
||||
&localMatrix, tilePtr);
|
||||
SkFilterMode::kNearest, &localMatrix, tilePtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user