Add filter-quality to imageshader factory
The old factories (makeShader) will behave as before: they will inherit
the filter-quality from the paint.
The new factory takes an explicit filter setting, and will use that
regardless of the paint.
Big follow-ups:
- update callers to not rely on setting in SkPaint
- revise/enhance settings in imageshader
- settings for scaling up and down
- control over trilerp, etc.
- other: 4x4 kernels? trilerp bias?
- move mipmaps to always be explicit requests a SkImage factory time
Bug: skia:10344
Change-Id: If87b06d4fd6eafd8b9cdecda7c00d69897066ef8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/295086
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/tests/ShaderOpacityTest.cpp b/tests/ShaderOpacityTest.cpp
index bfdf3e7..13357b3 100644
--- a/tests/ShaderOpacityTest.cpp
+++ b/tests/ShaderOpacityTest.cpp
@@ -6,10 +6,13 @@
*/
#include "include/core/SkBitmap.h"
+#include "include/core/SkCanvas.h"
#include "include/core/SkShader.h"
+#include "include/core/SkSurface.h"
#include "include/effects/SkGradientShader.h"
#include "src/shaders/SkColorShader.h"
#include "tests/Test.h"
+#include "tools/ToolUtils.h"
static void test_bitmap(skiatest::Reporter* reporter) {
SkImageInfo info = SkImageInfo::MakeN32Premul(2, 2);
@@ -95,3 +98,51 @@
test_color(reporter);
test_bitmap(reporter);
}
+
+DEF_TEST(image_shader_filtering, reporter) {
+ auto make_checker_img = [](int w, int h) {
+ auto info = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
+ auto surf = SkSurface::MakeRaster(info);
+ ToolUtils::draw_checkerboard(surf->getCanvas(), SK_ColorRED, SK_ColorBLUE, 2);
+ return surf->makeImageSnapshot();
+ };
+
+ auto img = make_checker_img(4, 4);
+
+ const SkFilterQuality quals[] = {
+ kNone_SkFilterQuality,
+ kLow_SkFilterQuality,
+ kMedium_SkFilterQuality,
+ kHigh_SkFilterQuality,
+ };
+ const SkScalar scales[] = { 3.0f, 1.0f, 0.5f, 0.25f, 0.125f };
+
+ auto make_img = [&](const SkPaint& paint) {
+ auto info = SkImageInfo::Make(70, 70, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+ auto surf = SkSurface::MakeRaster(info);
+ auto canvas = surf->getCanvas();
+ canvas->scale(1.06f, 1.06f); // nicely exaggerates noise when not filtering
+ canvas->drawRect({0, 0, 64, 64}, paint);
+ return surf->makeImageSnapshot();
+ };
+
+ SkPaint paint;
+ for (auto q : quals) {
+ for (auto scale : scales) {
+ SkMatrix m = SkMatrix::Scale(scale, scale);
+ paint.setFilterQuality(kNone_SkFilterQuality); // this setting should be ignored
+ paint.setShader(img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &m, q));
+ auto img0 = make_img(paint);
+
+ paint.setFilterQuality(q); // this should (still) be ignored
+ auto img1 = make_img(paint);
+
+ // make legacy form of shader, relying on the paint's filter-quality (q)
+ paint.setShader(img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &m));
+ auto img2 = make_img(paint);
+
+ REPORTER_ASSERT(reporter, ToolUtils::equal_pixels(img0.get(), img1.get()));
+ REPORTER_ASSERT(reporter, ToolUtils::equal_pixels(img0.get(), img2.get()));
+ }
+ }
+}