plumb cubic params into gpu backend
Tiny diffs seen, but not sure how to avoid those and keep the code
path simple -- so just plan/hope to rebaseline as needed.
Change-Id: Id8ff7e85a6e70785592f76118a32def2d61599ec
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/314076
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp
index bc8b675..3cd01df 100755
--- a/src/shaders/SkImageShader.cpp
+++ b/src/shaders/SkImageShader.cpp
@@ -23,13 +23,28 @@
#include "src/shaders/SkEmptyShader.h"
SkM44 SkImageShader::CubicResamplerMatrix(float B, float C) {
- const float scale = 1.0f/18;
- B *= scale;
- C *= scale;
- return SkM44( 3*B, -9*B - 18*C, 9*B + 36*C, -3*B - 18*C,
- 1 - 6*B, 0, -3 + 36*B + 18*C, 2 - 27*B - 18*C,
- 3*B, 9*B + 18*C, 3 - 45*B - 36*C, -2 + 27*B + 18*C,
- 0, 0, -18*C, 3*B + 18*C);
+#if 0
+ constexpr SkM44 kMitchell = SkM44( 1.f/18.f, -9.f/18.f, 15.f/18.f, -7.f/18.f,
+ 16.f/18.f, 0.f/18.f, -36.f/18.f, 21.f/18.f,
+ 1.f/18.f, 9.f/18.f, 27.f/18.f, -21.f/18.f,
+ 0.f/18.f, 0.f/18.f, -6.f/18.f, 7.f/18.f);
+
+ constexpr SkM44 kCatmull = SkM44(0.0f, -0.5f, 1.0f, -0.5f,
+ 1.0f, 0.0f, -2.5f, 1.5f,
+ 0.0f, 0.5f, 2.0f, -1.5f,
+ 0.0f, 0.0f, -0.5f, 0.5f);
+
+ if (B == 1.0f/3 && C == 1.0f/3) {
+ return kMitchell;
+ }
+ if (B == 0 && C == 0.5f) {
+ return kCatmull;
+ }
+#endif
+ return SkM44( (1.f/6)*B, -(3.f/6)*B - C, (3.f/6)*B + 2*C, - (1.f/6)*B - C,
+ 1 - (2.f/6)*B, 0, -3 + (12.f/6)*B + C, 2 - (9.f/6)*B - C,
+ (1.f/6)*B, (3.f/6)*B + C, 3 - (15.f/6)*B - 2*C, -2 + (9.f/6)*B + C,
+ 0, 0, -C, (1.f/6)*B + C);
}
/**
@@ -378,29 +393,41 @@
GrSamplerState::Filter fm;
GrSamplerState::MipmapMode mm;
bool bicubic;
- if (fFilterEnum == kUseFilterOptions) {
- bicubic = false;
- switch (fFilterOptions.fSampling) {
- case SkSamplingMode::kNearest: fm = GrSamplerState::Filter::kNearest; break;
- case SkSamplingMode::kLinear : fm = GrSamplerState::Filter::kLinear ; break;
- }
- switch (fFilterOptions.fMipmap) {
- case SkMipmapMode::kNone : mm = GrSamplerState::MipmapMode::kNone ; break;
- case SkMipmapMode::kNearest: mm = GrSamplerState::MipmapMode::kNearest; break;
- case SkMipmapMode::kLinear : mm = GrSamplerState::MipmapMode::kLinear ; break;
- }
- } else {
- std::tie(fm, mm, bicubic) =
- GrInterpretFilterQuality(fImage->dimensions(),
- this->resolveFiltering(args.fFilterQuality),
- args.fMatrixProvider.localToDevice(),
- *lm,
- sharpen,
- args.fAllowFilterQualityReduction);
+ SkImage::CubicResampler kernel = GrBicubicEffect::gMitchell;
+
+ switch (fFilterEnum) {
+ case FilterEnum::kUseFilterOptions:
+ bicubic = false;
+ switch (fFilterOptions.fSampling) {
+ case SkSamplingMode::kNearest: fm = GrSamplerState::Filter::kNearest; break;
+ case SkSamplingMode::kLinear : fm = GrSamplerState::Filter::kLinear ; break;
+ }
+ switch (fFilterOptions.fMipmap) {
+ case SkMipmapMode::kNone : mm = GrSamplerState::MipmapMode::kNone ; break;
+ case SkMipmapMode::kNearest: mm = GrSamplerState::MipmapMode::kNearest; break;
+ case SkMipmapMode::kLinear : mm = GrSamplerState::MipmapMode::kLinear ; break;
+ }
+ break;
+ case FilterEnum::kUseCubicResampler:
+ bicubic = true;
+ kernel = fCubic;
+ fm = GrSamplerState::Filter::kNearest;
+ mm = GrSamplerState::MipmapMode::kNone;
+ break;
+ case FilterEnum::kInheritFromPaint:
+ default: // none, low, medium, high
+ std::tie(fm, mm, bicubic) =
+ GrInterpretFilterQuality(fImage->dimensions(),
+ this->resolveFiltering(args.fFilterQuality),
+ args.fMatrixProvider.localToDevice(),
+ *lm,
+ sharpen,
+ args.fAllowFilterQualityReduction);
+ break;
}
std::unique_ptr<GrFragmentProcessor> fp;
if (bicubic) {
- fp = producer->createBicubicFragmentProcessor(lmInverse, nullptr, nullptr, wmX, wmY);
+ fp = producer->createBicubicFragmentProcessor(lmInverse, nullptr, nullptr, wmX, wmY, kernel);
} else {
fp = producer->createFragmentProcessor(lmInverse, nullptr, nullptr, {wmX, wmY, fm, mm});
}