other ways to organize samplingoptions?

do not land

Change-Id: I5fa7b2a0d1eb7e893d9b333f850a2f515d7ce065
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/336956
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Reed 2020-11-20 18:45:36 -05:00 committed by Skia Commit-Bot
parent 797831c3aa
commit a03f8bf837
9 changed files with 88 additions and 79 deletions

View File

@ -14,9 +14,8 @@
class FilteringBench : public Benchmark {
public:
FilteringBench(SkFilterOptions options) : fOptions(options) {
fName.printf("filteroptions_sampling_%d_mipmap_%d",
(int)options.fSampling, (int)options.fMipmap);
FilteringBench(SkFilterMode fm, SkMipmapMode mm) : fSampling(fm, mm) {
fName.printf("samplingoptions_filter_%d_mipmap_%d", (int)fm, (int)mm);
}
protected:
@ -30,7 +29,7 @@ protected:
img = img->makeRasterImage();
fRect = SkRect::MakeIWH(img->width(), img->height());
fShader = img->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, fOptions);
fShader = img->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, fSampling);
}
void onDraw(int loops, SkCanvas* canvas) override {
@ -50,15 +49,15 @@ private:
SkString fName;
SkRect fRect;
sk_sp<SkShader> fShader;
SkFilterOptions fOptions;
SkSamplingOptions fSampling;
using INHERITED = Benchmark;
};
DEF_BENCH( return new FilteringBench({SkSamplingMode::kLinear, SkMipmapMode::kLinear}); )
DEF_BENCH( return new FilteringBench({SkSamplingMode::kLinear, SkMipmapMode::kNearest}); )
DEF_BENCH( return new FilteringBench({SkSamplingMode::kLinear, SkMipmapMode::kNone}); )
DEF_BENCH( return new FilteringBench(SkFilterMode::kLinear, SkMipmapMode::kLinear); )
DEF_BENCH( return new FilteringBench(SkFilterMode::kLinear, SkMipmapMode::kNearest); )
DEF_BENCH( return new FilteringBench(SkFilterMode::kLinear, SkMipmapMode::kNone); )
DEF_BENCH( return new FilteringBench({SkSamplingMode::kNearest, SkMipmapMode::kLinear}); )
DEF_BENCH( return new FilteringBench({SkSamplingMode::kNearest, SkMipmapMode::kNearest}); )
DEF_BENCH( return new FilteringBench({SkSamplingMode::kNearest, SkMipmapMode::kNone}); )
DEF_BENCH( return new FilteringBench(SkFilterMode::kNearest, SkMipmapMode::kLinear); )
DEF_BENCH( return new FilteringBench(SkFilterMode::kNearest, SkMipmapMode::kNearest); )
DEF_BENCH( return new FilteringBench(SkFilterMode::kNearest, SkMipmapMode::kNone); )

View File

@ -40,7 +40,8 @@ DEF_SIMPLE_GM(bicubic, canvas, 300, 320) {
{ 1.0f/3, 1.0f/3 },
};
for (auto c : cubics) {
paint.setShader(img->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, c));
paint.setShader(img->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
SkSamplingOptions(c)));
canvas->drawRect(r, paint);
canvas->translate(0, img->height() + 1.0f);
}

View File

@ -346,15 +346,15 @@ class ShowMipLevels3 : public skiagm::GM {
canvas->translate(10, 10);
for (auto mm : {SkMipmapMode::kNone, SkMipmapMode::kNearest, SkMipmapMode::kLinear}) {
for (auto sa : {SkSamplingMode::kNearest, SkSamplingMode::kLinear}) {
canvas->translate(0, draw_downscaling(canvas, {sa, mm}));
for (auto fm : {SkFilterMode::kNearest, SkFilterMode::kLinear}) {
canvas->translate(0, draw_downscaling(canvas, {fm, mm}));
}
}
return DrawResult::kOk;
}
private:
SkScalar draw_downscaling(SkCanvas* canvas, SkFilterOptions options) {
SkScalar draw_downscaling(SkCanvas* canvas, SkSamplingOptions sampling) {
SkAutoCanvasRestore acr(canvas, true);
SkPaint paint;
@ -362,7 +362,7 @@ private:
for (float scale = 1; scale >= 0.1f; scale *= 0.7f) {
SkMatrix matrix = SkMatrix::Scale(scale, scale);
paint.setShader(fImg->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
options, &matrix));
sampling, &matrix));
canvas->drawRect(r, paint);
canvas->translate(r.width() + 10, 0);
}

View File

@ -20,6 +20,13 @@
#include "include/gpu/GrTypes.h"
#include <functional> // std::function
// DEPRECATED -- use SkSamplingOptions
enum class SkSamplingMode { kNearest, kLinear };
struct SkFilterOptions {
SkSamplingMode fSampling;
SkMipmapMode fMipmap;
};
#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
#include <android/hardware_buffer.h>
#endif
@ -718,6 +725,8 @@ public:
return this->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, &localMatrix);
}
// DEPRECATED -- use SkSamplingOptions
sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, const SkFilterOptions&) const;
/** Copies SkImage pixel address, row bytes, and SkImageInfo to pixmap, if address
is available, and returns true. If pixel address is not available, return

View File

@ -10,7 +10,7 @@
#include "include/core/SkFilterQuality.h"
enum class SkSamplingMode {
enum class SkFilterMode {
kNearest, // single sample point (nearest neighbor)
kLinear, // interporate between 2x2 sample points (bilinear interpolation)
};
@ -42,36 +42,24 @@ struct SkCubicResampler {
float B, C;
};
struct SkFilterOptions {
SkSamplingMode fSampling;
SkMipmapMode fMipmap;
};
struct SkSamplingOptions {
bool fUseCubic;
SkCubicResampler fCubic; //!< use if fUseCubic is true
SkFilterOptions fFilter; //!< use if fUseCubic is false
bool fUseCubic = false;
SkCubicResampler fCubic = {0, 0};
SkFilterMode fFilter = SkFilterMode::kNearest;
SkMipmapMode fMipmap = SkMipmapMode::kNone;
SkSamplingOptions()
SkSamplingOptions() = default;
SkSamplingOptions(SkFilterMode fm, SkMipmapMode mm)
: fUseCubic(false)
, fCubic({0,0})
, fFilter({SkSamplingMode::kNearest, SkMipmapMode::kNone})
{}
, fFilter(fm)
, fMipmap(mm) {}
SkSamplingOptions(const SkFilterOptions& filter)
: fUseCubic(false)
, fCubic({0,0}) // ignored
, fFilter(filter)
{}
SkSamplingOptions(const SkCubicResampler& cubic)
explicit SkSamplingOptions(const SkCubicResampler& cubic)
: fUseCubic(true)
, fCubic(cubic)
, fFilter({SkSamplingMode::kNearest, SkMipmapMode::kNone}) // ignored
{}
, fCubic(cubic) {}
// Soon to go away
static SkSamplingOptions Make(SkFilterQuality);
explicit SkSamplingOptions(SkFilterQuality);
};
#endif

View File

@ -219,15 +219,16 @@ class CubicResamplerDemo : public Sample {
lm.postTranslate(r.width() + 10, 0);
paint.setShader(fImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
SkFilterOptions{ SkSamplingMode::kLinear,
SkMipmapMode::kNone },
SkSamplingOptions{ SkFilterMode::kLinear,
SkMipmapMode::kNone },
&lm));
canvas->drawRect(r, paint);
r.offset(r.width() + 10, 0);
lm.postTranslate(r.width() + 10, 0);
paint.setShader(fImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, cubic, &lm));
paint.setShader(fImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
SkSamplingOptions(cubic), &lm));
canvas->drawRect(r, paint);
}
};

View File

@ -239,7 +239,7 @@ bool SkPixmap::scalePixels(const SkPixmap& actualDst, SkFilterQuality quality) c
SkMatrix::kFill_ScaleToFit);
// We'll create a shader to do this draw so we have control over the bicubic clamp.
SkSamplingOptions sampling = SkSamplingOptions::Make(quality);
auto sampling = SkSamplingOptions(quality);
sk_sp<SkShader> shader = SkImageShader::Make(SkImage::MakeFromBitmap(bitmap),
SkTileMode::kClamp,
SkTileMode::kClamp,

View File

@ -150,11 +150,18 @@ sk_sp<SkShader> SkImage::makeShader(SkTileMode tmx, SkTileMode tmy,
sk_sp<SkShader> SkImage::makeShader(SkTileMode tmx, SkTileMode tmy,
const SkMatrix* localMatrix, SkFilterQuality filtering) const {
SkSamplingOptions sampling = SkSamplingOptions::Make(filtering);
auto sampling = SkSamplingOptions(filtering);
return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)), tmx, tmy, &sampling,
localMatrix);
}
// DEPRECATED
sk_sp<SkShader> SkImage::makeShader(SkTileMode tmx, SkTileMode tmy,
const SkFilterOptions& options) const {
return this->makeShader(tmx, tmy, SkSamplingOptions((SkFilterMode)options.fSampling,
options.fMipmap));
}
sk_sp<SkData> SkImage::encodeToData(SkEncodedImageFormat type, int quality) const {
// Context TODO: Elevate GrDirectContext requirement to public API.
auto dContext = as_IB(this)->directContext();
@ -636,22 +643,26 @@ sk_sp<SkImage> SkMipmapBuilder::attachTo(const SkImage* src) {
return src->withMipmaps(fMM);
}
SkSamplingOptions SkSamplingOptions::Make(SkFilterQuality fq) {
SkSamplingOptions::SkSamplingOptions(SkFilterQuality fq) {
switch (fq) {
case SkFilterQuality::kLow_SkFilterQuality:
return SkSamplingOptions({
SkSamplingMode::kLinear,
SkMipmapMode::kNone
});
case SkFilterQuality::kMedium_SkFilterQuality:
return SkSamplingOptions({
SkSamplingMode::kLinear,
SkMipmapMode::kNearest
});
case SkFilterQuality::kHigh_SkFilterQuality:
return SkSamplingOptions({1.0f/3, 1.0f/3});
fUseCubic = true;
fCubic = {1.0f/3, 1.0f/3};
break;
case SkFilterQuality::kMedium_SkFilterQuality:
fUseCubic = false;
fFilter = SkFilterMode::kLinear;
fMipmap = SkMipmapMode::kNearest;
break;
case SkFilterQuality::kLow_SkFilterQuality:
fUseCubic = false;
fFilter = SkFilterMode::kLinear;
fMipmap = SkMipmapMode::kNone;
break;
case SkFilterQuality::kNone_SkFilterQuality:
break; // fall out
fUseCubic = false;
fFilter = SkFilterMode::kNearest;
fMipmap = SkMipmapMode::kNone;
break;
}
return SkSamplingOptions(); // kNone_SkFilterQuality
}

View File

@ -107,15 +107,15 @@ sk_sp<SkFlattenable> SkImageShader::PreSamplingCreate(SkReadBuffer& buffer) {
if (buffer.isVersionLT(SkPicturePriv::kCubicResamplerImageShader_Version)) {
if (!buffer.isVersionLT(SkPicturePriv::kFilterOptionsInImageShader_Version)) {
op.fUseCubic = false;
op.fFilter.fSampling = buffer.read32LE<SkSamplingMode>(SkSamplingMode::kLinear);
op.fFilter.fMipmap = buffer.read32LE<SkMipmapMode>(SkMipmapMode::kLinear);
op.fFilter = buffer.read32LE<SkFilterMode>(SkFilterMode::kLinear);
op.fMipmap = buffer.read32LE<SkMipmapMode>(SkMipmapMode::kLinear);
}
} else {
switch (fe) {
case LegacyFilterEnum::kUseFilterOptions:
op.fUseCubic = false;
op.fFilter.fSampling = buffer.read32LE<SkSamplingMode>(SkSamplingMode::kLinear);
op.fFilter.fMipmap = buffer.read32LE<SkMipmapMode>(SkMipmapMode::kLinear);
op.fFilter = buffer.read32LE<SkFilterMode>(SkFilterMode::kLinear);
op.fMipmap = buffer.read32LE<SkMipmapMode>(SkMipmapMode::kLinear);
break;
case LegacyFilterEnum::kUseCubicResampler:
op.fUseCubic = true;
@ -150,8 +150,8 @@ static void write_sampling(SkWriteBuffer& buffer, SkSamplingOptions sampling) {
buffer.writeScalar(sampling.fCubic.B);
buffer.writeScalar(sampling.fCubic.C);
} else {
buffer.writeUInt((unsigned)sampling.fFilter.fSampling);
buffer.writeUInt((unsigned)sampling.fFilter.fMipmap);
buffer.writeUInt((unsigned)sampling.fFilter);
buffer.writeUInt((unsigned)sampling.fMipmap);
}
}
@ -162,8 +162,8 @@ static SkSamplingOptions read_sampling(SkReadBuffer& buffer) {
sampling.fCubic.B = buffer.readScalar();
sampling.fCubic.C = buffer.readScalar();
} else {
sampling.fFilter.fSampling = buffer.read32LE<SkSamplingMode>(SkSamplingMode::kLinear);
sampling.fFilter.fMipmap = buffer.read32LE<SkMipmapMode>(SkMipmapMode::kLinear);
sampling.fFilter = buffer.read32LE<SkFilterMode>(SkFilterMode::kLinear);
sampling.fMipmap = buffer.read32LE<SkMipmapMode>(SkMipmapMode::kLinear);
}
return sampling;
}
@ -231,14 +231,14 @@ static bool sampling_to_quality(SkSamplingOptions sampling, SkFilterQuality* qua
q = kHigh_SkFilterQuality;
}
} else {
switch (sampling.fFilter.fMipmap) {
switch (sampling.fMipmap) {
case SkMipmapMode::kNone:
q = sampling.fFilter.fSampling == SkSamplingMode::kLinear ?
q = sampling.fFilter == SkFilterMode::kLinear ?
kLow_SkFilterQuality :
kNone_SkFilterQuality;
break;
case SkMipmapMode::kNearest:
if (sampling.fFilter.fSampling == SkSamplingMode::kLinear) {
if (sampling.fFilter == SkFilterMode::kLinear) {
q = kMedium_SkFilterQuality;
}
break;
@ -455,11 +455,11 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
if (bicubic) {
kernel = fSampling.fCubic;
} else {
switch (fSampling.fFilter.fSampling) {
case SkSamplingMode::kNearest: fm = GrSamplerState::Filter::kNearest; break;
case SkSamplingMode::kLinear : fm = GrSamplerState::Filter::kLinear ; break;
switch (fSampling.fFilter) {
case SkFilterMode::kNearest: fm = GrSamplerState::Filter::kNearest; break;
case SkFilterMode::kLinear : fm = GrSamplerState::Filter::kLinear ; break;
}
switch (fSampling.fFilter.fMipmap) {
switch (fSampling.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;
@ -885,8 +885,8 @@ SkStageUpdater* SkImageShader::onAppendUpdatableStages(const SkStageRec& rec) co
}
enum class SamplingEnum {
kNearest,
kLinear,
kNearest, // matches SkFilterMode::kNearest
kLinear, // matches SkFilterMode::kLinear
kBicubic,
};
@ -906,7 +906,7 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p,
*lower = nullptr;
SkMatrix upperInv;
float lowerWeight = 0;
SamplingEnum sampling = (SamplingEnum)fSampling.fFilter.fSampling;
SamplingEnum sampling = (SamplingEnum)fSampling.fFilter;
auto post_scale = [&](SkISize level, const SkMatrix& base) {
return SkMatrix::Scale(SkIntToScalar(level.width()) / fImage->width(),
@ -924,7 +924,7 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p,
cubic = fSampling.fCubic;
} else {
auto* access = alloc->make<SkMipmapAccessor>(as_IB(fImage.get()), baseInv,
fSampling.fFilter.fMipmap);
fSampling.fMipmap);
upper = &access->level();
upperInv = post_scale(upper->dimensions(), baseInv);
lowerWeight = access->lowerWeight();