Remove legacy support for inheriting sampling from the paint.

A follow-up CL can remove the filter-quality from onProgram.

Change-Id: I770e3b1fd0907bf3824ed402502fa67325a433d5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/381799
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2021-03-18 22:19:44 -04:00 committed by Skia Commit-Bot
parent 633b9f3cd5
commit 225cdea5b6
12 changed files with 73 additions and 165 deletions

View File

@ -234,13 +234,6 @@ public:
return this->makeShader(tmx, tmy, mode, nullptr, nullptr); 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: private:
// Allowed subclasses. // Allowed subclasses.
SkPicture(); SkPicture();

View File

@ -105,10 +105,11 @@ public:
kPictureShaderFilterParam_Version = 82, kPictureShaderFilterParam_Version = 82,
kMatrixImageFilterSampling_Version = 83, kMatrixImageFilterSampling_Version = 83,
kImageFilterImageSampling_Version = 84, kImageFilterImageSampling_Version = 84,
kNoFilterQualityShaders_Version = 85,
// Only SKPs within the min/current picture version range (inclusive) can be read. // Only SKPs within the min/current picture version range (inclusive) can be read.
kMin_Version = kEdgeAAQuadColor4f_Version, kMin_Version = kEdgeAAQuadColor4f_Version,
kCurrent_Version = kImageFilterImageSampling_Version kCurrent_Version = kNoFilterQualityShaders_Version
}; };
static_assert(SkPicturePriv::kMin_Version <= SkPicturePriv::kCubicResamplerImageShader_Version, static_assert(SkPicturePriv::kMin_Version <= SkPicturePriv::kCubicResamplerImageShader_Version,

View File

@ -239,7 +239,7 @@ bool SkPixmap::scalePixels(const SkPixmap& actualDst, const SkSamplingOptions& s
sk_sp<SkShader> shader = SkImageShader::Make(bitmap.asImage(), sk_sp<SkShader> shader = SkImageShader::Make(bitmap.asImage(),
SkTileMode::kClamp, SkTileMode::kClamp,
SkTileMode::kClamp, SkTileMode::kClamp,
&sampling, sampling,
&scale, &scale,
clampAsIfUnpremul); clampAsIfUnpremul);

View File

@ -142,7 +142,7 @@ sk_sp<SkShader> SkImage::makeShader(SkTileMode tmx, SkTileMode tmy,
const SkSamplingOptions& sampling, const SkSamplingOptions& sampling,
const SkMatrix* localMatrix) const { const SkMatrix* localMatrix) const {
return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)), tmx, tmy, return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)), tmx, tmy,
&sampling, localMatrix); sampling, localMatrix);
} }
sk_sp<SkData> SkImage::encodeToData(SkEncodedImageFormat type, int quality) const { sk_sp<SkData> SkImage::encodeToData(SkEncodedImageFormat type, int quality) const {

View File

@ -76,7 +76,7 @@ private:
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
SkShaderBase::Context* SkBitmapProcLegacyShader::MakeContext( SkShaderBase::Context* SkBitmapProcLegacyShader::MakeContext(
const SkShaderBase& shader, SkTileMode tmx, SkTileMode tmy, const SkShaderBase& shader, SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions& sampling,
const SkImage_Base* image, const ContextRec& rec, SkArenaAlloc* alloc) const SkImage_Base* image, const ContextRec& rec, SkArenaAlloc* alloc)
{ {
SkMatrix totalInverse; SkMatrix totalInverse;
@ -86,7 +86,7 @@ SkShaderBase::Context* SkBitmapProcLegacyShader::MakeContext(
} }
SkBitmapProcState* state = alloc->make<SkBitmapProcState>(image, tmx, tmy); SkBitmapProcState* state = alloc->make<SkBitmapProcState>(image, tmx, tmy);
if (!state->setup(totalInverse, rec.fPaintAlpha, rec.fPaintSampling)) { if (!state->setup(totalInverse, rec.fPaintAlpha, sampling)) {
return nullptr; return nullptr;
} }
return alloc->make<BitmapProcShaderContext>(shader, rec, state); return alloc->make<BitmapProcShaderContext>(shader, rec, state);

View File

@ -17,7 +17,8 @@ private:
friend class SkImageShader; friend class SkImageShader;
static Context* MakeContext(const SkShaderBase&, SkTileMode tmx, SkTileMode tmy, static Context* MakeContext(const SkShaderBase&, SkTileMode tmx, SkTileMode tmy,
const SkImage_Base*, const ContextRec&, SkArenaAlloc* alloc); const SkSamplingOptions&, const SkImage_Base*,
const ContextRec&, SkArenaAlloc* alloc);
using INHERITED = SkShaderBase; using INHERITED = SkShaderBase;
}; };

View File

@ -65,16 +65,15 @@ static SkTileMode optimize(SkTileMode tm, int dimension) {
SkImageShader::SkImageShader(sk_sp<SkImage> img, SkImageShader::SkImageShader(sk_sp<SkImage> img,
SkTileMode tmx, SkTileMode tmy, SkTileMode tmx, SkTileMode tmy,
const SkSamplingOptions* sampling, const SkSamplingOptions& sampling,
const SkMatrix* localMatrix, const SkMatrix* localMatrix,
bool clampAsIfUnpremul) bool clampAsIfUnpremul)
: INHERITED(localMatrix) : INHERITED(localMatrix)
, fImage(std::move(img)) , fImage(std::move(img))
, fSampling(sampling ? *sampling : SkSamplingOptions()) , fSampling(sampling)
, fTileModeX(optimize(tmx, fImage->width())) , fTileModeX(optimize(tmx, fImage->width()))
, fTileModeY(optimize(tmy, fImage->height())) , fTileModeY(optimize(tmy, fImage->height()))
, fClampAsIfUnpremul(clampAsIfUnpremul) , fClampAsIfUnpremul(clampAsIfUnpremul)
, fUseSamplingOptions(sampling != nullptr)
{} {}
// just used for legacy-unflattening // just used for legacy-unflattening
@ -132,18 +131,7 @@ sk_sp<SkFlattenable> SkImageShader::PreSamplingCreate(SkReadBuffer& buffer) {
SkMatrix localMatrix; SkMatrix localMatrix;
buffer.readMatrix(&localMatrix); buffer.readMatrix(&localMatrix);
sk_sp<SkImage> img = buffer.readImage(); sk_sp<SkImage> img = buffer.readImage();
if (!img) { return img ? SkImageShader::Make(std::move(img), tmx, tmy, op, &localMatrix) : nullptr;
return nullptr;
}
switch (fe) {
case LegacyFilterEnum::kUseFilterOptions:
case LegacyFilterEnum::kUseCubicResampler:
return SkImageShader::Make(std::move(img), tmx, tmy, &op, &localMatrix);
default:
break;
}
return SkImageShader::Make(std::move(img), tmx, tmy, nullptr, &localMatrix);
} }
// fClampAsIfUnpremul is always false when constructed through public APIs, // fClampAsIfUnpremul is always false when constructed through public APIs,
@ -157,12 +145,16 @@ sk_sp<SkFlattenable> SkImageShader::CreateProc(SkReadBuffer& buffer) {
auto tmx = buffer.read32LE<SkTileMode>(SkTileMode::kLastTileMode); auto tmx = buffer.read32LE<SkTileMode>(SkTileMode::kLastTileMode);
auto tmy = buffer.read32LE<SkTileMode>(SkTileMode::kLastTileMode); auto tmy = buffer.read32LE<SkTileMode>(SkTileMode::kLastTileMode);
SkSamplingOptions sampling, SkSamplingOptions sampling;
*samplingPtr = nullptr; bool readSampling = true;
if (buffer.isVersionLT(SkPicturePriv::kNoFilterQualityShaders_Version) &&
if (buffer.readBool()) { // fUseSamplingOptions !buffer.readBool() /* legacy has_sampling */)
{
readSampling = false;
// we just default to Nearest in sampling
}
if (readSampling) {
sampling = SkSamplingPriv::Read(buffer); sampling = SkSamplingPriv::Read(buffer);
samplingPtr = &sampling;
} }
SkMatrix localMatrix; SkMatrix localMatrix;
@ -172,17 +164,14 @@ sk_sp<SkFlattenable> SkImageShader::CreateProc(SkReadBuffer& buffer) {
return nullptr; return nullptr;
} }
return SkImageShader::Make(std::move(img), tmx, tmy, samplingPtr, &localMatrix); return SkImageShader::Make(std::move(img), tmx, tmy, sampling, &localMatrix);
} }
void SkImageShader::flatten(SkWriteBuffer& buffer) const { void SkImageShader::flatten(SkWriteBuffer& buffer) const {
buffer.writeUInt((unsigned)fTileModeX); buffer.writeUInt((unsigned)fTileModeX);
buffer.writeUInt((unsigned)fTileModeY); buffer.writeUInt((unsigned)fTileModeY);
buffer.writeBool(fUseSamplingOptions); SkSamplingPriv::Write(buffer, fSampling);
if (fUseSamplingOptions) {
SkSamplingPriv::Write(buffer, fSampling);
}
buffer.writeMatrix(this->getLocalMatrix()); buffer.writeMatrix(this->getLocalMatrix());
buffer.writeImage(fImage.get()); buffer.writeImage(fImage.get());
@ -242,9 +231,6 @@ SkShaderBase::Context* SkImageShader::onMakeContext(const ContextRec& rec,
return nullptr; return nullptr;
} }
SkSamplingOptions sampling = fUseSamplingOptions ? fSampling
: rec.fPaintSampling;
auto supported = [](const SkSamplingOptions& sampling) { auto supported = [](const SkSamplingOptions& sampling) {
const std::tuple<SkFilterMode,SkMipmapMode> supported[] = { const std::tuple<SkFilterMode,SkMipmapMode> supported[] = {
{SkFilterMode::kNearest, SkMipmapMode::kNone}, // legacy kNone_SkFilterQuality {SkFilterMode::kNearest, SkMipmapMode::kNone}, // legacy kNone_SkFilterQuality
@ -258,7 +244,7 @@ SkShaderBase::Context* SkImageShader::onMakeContext(const ContextRec& rec,
} }
return false; return false;
}; };
if (sampling.useCubic || !supported(sampling)) { if (fSampling.useCubic || !supported(fSampling)) {
return nullptr; return nullptr;
} }
@ -287,12 +273,8 @@ SkShaderBase::Context* SkImageShader::onMakeContext(const ContextRec& rec,
return nullptr; return nullptr;
} }
// Can remove this once fUseSamplingOptions is always true return SkBitmapProcLegacyShader::MakeContext(*this, fTileModeX, fTileModeY, fSampling,
ContextRec modifiedRec = rec; as_IB(fImage.get()), rec, alloc);
modifiedRec.fPaintSampling = sampling;
return SkBitmapProcLegacyShader::MakeContext(*this, fTileModeX, fTileModeY,
as_IB(fImage.get()), modifiedRec, alloc);
} }
#endif #endif
@ -309,14 +291,14 @@ SkImage* SkImageShader::onIsAImage(SkMatrix* texM, SkTileMode xy[]) const {
sk_sp<SkShader> SkImageShader::Make(sk_sp<SkImage> image, sk_sp<SkShader> SkImageShader::Make(sk_sp<SkImage> image,
SkTileMode tmx, SkTileMode tmy, SkTileMode tmx, SkTileMode tmy,
const SkSamplingOptions* options, const SkSamplingOptions& options,
const SkMatrix* localMatrix, const SkMatrix* localMatrix,
bool clampAsIfUnpremul) { bool clampAsIfUnpremul) {
auto is_unit = [](float x) { auto is_unit = [](float x) {
return x >= 0 && x <= 1; return x >= 0 && x <= 1;
}; };
if (options && options->useCubic) { if (options.useCubic) {
if (!is_unit(options->cubic.B) || !is_unit(options->cubic.C)) { if (!is_unit(options.cubic.B) || !is_unit(options.cubic.C)) {
return nullptr; return nullptr;
} }
} }
@ -358,33 +340,22 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
// below we check the matrix scale factors to determine how to interpret the filter // below we check the matrix scale factors to determine how to interpret the filter
// quality setting. This completely ignores the complexity of the drawVertices case // quality setting. This completely ignores the complexity of the drawVertices case
// where explicit local coords are provided by the caller. // where explicit local coords are provided by the caller.
bool sharpen = args.fContext->priv().options().fSharpenMipmappedTextures;
GrSamplerState::Filter fm = GrSamplerState::Filter::kNearest; GrSamplerState::Filter fm = GrSamplerState::Filter::kNearest;
GrSamplerState::MipmapMode mm = GrSamplerState::MipmapMode::kNone; GrSamplerState::MipmapMode mm = GrSamplerState::MipmapMode::kNone;
SkCubicResampler kernel = kInvalidCubicResampler; SkCubicResampler kernel = kInvalidCubicResampler;
if (fUseSamplingOptions) { if (fSampling.useCubic) {
if (fSampling.useCubic) { kernel = fSampling.cubic;
kernel = fSampling.cubic; } else {
} else { switch (fSampling.filter) {
switch (fSampling.filter) { case SkFilterMode::kNearest: fm = GrSamplerState::Filter::kNearest; break;
case SkFilterMode::kNearest: fm = GrSamplerState::Filter::kNearest; break; case SkFilterMode::kLinear : fm = GrSamplerState::Filter::kLinear ; break;
case SkFilterMode::kLinear : fm = GrSamplerState::Filter::kLinear ; break; }
} switch (fSampling.mipmap) {
switch (fSampling.mipmap) { case SkMipmapMode::kNone : mm = GrSamplerState::MipmapMode::kNone ; break;
case SkMipmapMode::kNone : mm = GrSamplerState::MipmapMode::kNone ; break; case SkMipmapMode::kNearest: mm = GrSamplerState::MipmapMode::kNearest; break;
case SkMipmapMode::kNearest: mm = GrSamplerState::MipmapMode::kNearest; break; case SkMipmapMode::kLinear : mm = GrSamplerState::MipmapMode::kLinear ; break;
case SkMipmapMode::kLinear : mm = GrSamplerState::MipmapMode::kLinear ; break;
}
} }
} else { // inherit filterquality from paint
std::tie(fm, mm, kernel) =
GrInterpretSamplingOptions(fImage->dimensions(),
args.fSampling,
args.fMatrixProvider.localToDevice(),
*lm,
sharpen,
args.fAllowFilterQualityReduction);
} }
std::unique_ptr<GrFragmentProcessor> fp; std::unique_ptr<GrFragmentProcessor> fp;
@ -453,7 +424,7 @@ sk_sp<SkShader> SkMakeBitmapShaderForPaint(const SkPaint& paint, const SkBitmap&
const SkSamplingOptions& sampling, const SkSamplingOptions& sampling,
const SkMatrix* localMatrix, SkCopyPixelsMode mode) { const SkMatrix* localMatrix, SkCopyPixelsMode mode) {
auto s = SkImageShader::Make(SkMakeImageFromRasterBitmap(src, mode), auto s = SkImageShader::Make(SkMakeImageFromRasterBitmap(src, mode),
tmx, tmy, &sampling, localMatrix); tmx, tmy, sampling, localMatrix);
if (!s) { if (!s) {
return nullptr; return nullptr;
} }
@ -550,10 +521,8 @@ static SkMatrix tweak_inv_matrix(SkFilterMode filter, SkMatrix matrix) {
} }
bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater) const { bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater) const {
auto sampling = fUseSamplingOptions ? fSampling
: SkSamplingOptions(rec.fPaint.getFilterQuality());
// We only support certain sampling options in stages so far // We only support certain sampling options in stages so far
auto sampling = fSampling;
if (sampling.useCubic) { if (sampling.useCubic) {
if (!is_default_cubic_resampler(sampling.cubic)) { if (!is_default_cubic_resampler(sampling.cubic)) {
return false; return false;
@ -842,7 +811,7 @@ SkStageUpdater* SkImageShader::onAppendUpdatableStages(const SkStageRec& rec) co
skvm::Color SkImageShader::onProgram(skvm::Builder* p, skvm::Color SkImageShader::onProgram(skvm::Builder* p,
skvm::Coord device, skvm::Coord origLocal, skvm::Color paint, skvm::Coord device, skvm::Coord origLocal, skvm::Color paint,
const SkMatrixProvider& matrices, const SkMatrix* localM, const SkMatrixProvider& matrices, const SkMatrix* localM,
SkFilterQuality paintQuality, const SkColorInfo& dst, SkFilterQuality, const SkColorInfo& dst,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const {
SkMatrix baseInv; SkMatrix baseInv;
if (!this->computeTotalInverse(matrices.localToDevice(), localM, &baseInv)) { if (!this->computeTotalInverse(matrices.localToDevice(), localM, &baseInv)) {
@ -850,7 +819,7 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p,
} }
baseInv.normalizePerspective(); baseInv.normalizePerspective();
auto sampling = fUseSamplingOptions ? fSampling : SkSamplingOptions(paintQuality); auto sampling = fSampling;
auto* access = SkMipmapAccessor::Make(alloc, fImage.get(), baseInv, sampling.mipmap); auto* access = SkMipmapAccessor::Make(alloc, fImage.get(), baseInv, sampling.mipmap);
if (!access) { if (!access) {
return {}; return {};

View File

@ -20,7 +20,7 @@ public:
static sk_sp<SkShader> Make(sk_sp<SkImage>, static sk_sp<SkShader> Make(sk_sp<SkImage>,
SkTileMode tmx, SkTileMode tmx,
SkTileMode tmy, SkTileMode tmy,
const SkSamplingOptions*, // null means inherit-from-paint-fq const SkSamplingOptions&,
const SkMatrix* localMatrix, const SkMatrix* localMatrix,
bool clampAsIfUnpremul = false); bool clampAsIfUnpremul = false);
@ -38,7 +38,7 @@ private:
SkImageShader(sk_sp<SkImage>, SkImageShader(sk_sp<SkImage>,
SkTileMode tmx, SkTileMode tmx,
SkTileMode tmy, SkTileMode tmy,
const SkSamplingOptions*, const SkSamplingOptions&,
const SkMatrix* localMatrix, const SkMatrix* localMatrix,
bool clampAsIfUnpremul = false); bool clampAsIfUnpremul = false);
@ -63,7 +63,6 @@ private:
const SkTileMode fTileModeX; const SkTileMode fTileModeX;
const SkTileMode fTileModeY; const SkTileMode fTileModeY;
const bool fClampAsIfUnpremul; const bool fClampAsIfUnpremul;
const bool fUseSamplingOptions; // else inherit filterquality from paint
friend class SkShaderBase; friend class SkShaderBase;
using INHERITED = SkShaderBase; using INHERITED = SkShaderBase;

View File

@ -40,26 +40,9 @@ sk_sp<SkShader> SkPicture::makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMo
if (localMatrix && !localMatrix->invert(nullptr)) { if (localMatrix && !localMatrix->invert(nullptr)) {
return nullptr; return nullptr;
} }
return SkPictureShader::Make(sk_ref_sp(this), tmx, tmy, (SkPictureShader::FilterEnum)filter, return SkPictureShader::Make(sk_ref_sp(this), tmx, tmy, filter, localMatrix, tile);
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)) {
return nullptr;
}
return SkPictureShader::Make(sk_ref_sp(this), tmx, tmy, SkPictureShader::kInheritFromPaint,
localMatrix, tile);
}
sk_sp<SkShader> SkPicture::makeShader(SkTileMode tmx, SkTileMode tmy,
const SkMatrix* localMatrix) const {
return this->makeShader(tmx, tmy, localMatrix, nullptr);
}
#endif
namespace { namespace {
static unsigned gImageFromPictureKeyNamespaceLabel; static unsigned gImageFromPictureKeyNamespaceLabel;
@ -124,7 +107,7 @@ struct ImageFromPictureRec : public SkResourceCache::Rec {
} // namespace } // namespace
SkPictureShader::SkPictureShader(sk_sp<SkPicture> picture, SkTileMode tmx, SkTileMode tmy, SkPictureShader::SkPictureShader(sk_sp<SkPicture> picture, SkTileMode tmx, SkTileMode tmy,
FilterEnum filter, const SkMatrix* localMatrix, const SkRect* tile) SkFilterMode filter, const SkMatrix* localMatrix, const SkRect* tile)
: INHERITED(localMatrix) : INHERITED(localMatrix)
, fPicture(std::move(picture)) , fPicture(std::move(picture))
, fTile(tile ? *tile : fPicture->cullRect()) , fTile(tile ? *tile : fPicture->cullRect())
@ -133,7 +116,7 @@ SkPictureShader::SkPictureShader(sk_sp<SkPicture> picture, SkTileMode tmx, SkTil
, fFilter(filter) {} , fFilter(filter) {}
sk_sp<SkShader> SkPictureShader::Make(sk_sp<SkPicture> picture, SkTileMode tmx, SkTileMode tmy, sk_sp<SkShader> SkPictureShader::Make(sk_sp<SkPicture> picture, SkTileMode tmx, SkTileMode tmy,
FilterEnum filter, const SkMatrix* lm, const SkRect* tile) { SkFilterMode filter, const SkMatrix* lm, const SkRect* tile) {
if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) { if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) {
return SkShaders::Empty(); return SkShaders::Empty();
} }
@ -148,15 +131,23 @@ sk_sp<SkFlattenable> SkPictureShader::CreateProc(SkReadBuffer& buffer) {
SkRect tile = buffer.readRect(); SkRect tile = buffer.readRect();
sk_sp<SkPicture> picture; sk_sp<SkPicture> picture;
FilterEnum filter;
if (buffer.isVersionLT(SkPicturePriv::kPictureShaderFilterParam_Version)) { SkFilterMode filter = SkFilterMode::kNearest;
filter = kInheritFromPaint; if (buffer.isVersionLT(SkPicturePriv::kNoFilterQualityShaders_Version)) {
bool didSerialize = buffer.readBool(); if (buffer.isVersionLT(SkPicturePriv::kPictureShaderFilterParam_Version)) {
if (didSerialize) { bool didSerialize = buffer.readBool();
if (didSerialize) {
picture = SkPicturePriv::MakeFromBuffer(buffer);
}
} else {
unsigned legacyFilter = buffer.read32();
if (legacyFilter <= (unsigned)SkFilterMode::kLast) {
filter = (SkFilterMode)legacyFilter;
}
picture = SkPicturePriv::MakeFromBuffer(buffer); picture = SkPicturePriv::MakeFromBuffer(buffer);
} }
} else { } else {
filter = buffer.read32LE(SkPictureShader::kLastFilterEnum); filter = buffer.read32LE(SkFilterMode::kLast);
picture = SkPicturePriv::MakeFromBuffer(buffer); picture = SkPicturePriv::MakeFromBuffer(buffer);
} }
return SkPictureShader::Make(picture, tmx, tmy, filter, &lm, &tile); return SkPictureShader::Make(picture, tmx, tmy, filter, &lm, &tile);
@ -171,25 +162,6 @@ void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
SkPicturePriv::Flatten(fPicture, buffer); SkPicturePriv::Flatten(fPicture, buffer);
} }
// These are tricky "downscales" -- need to deduce the caller's intention.
// For now, map anything that is not "nearest/none" to kLinear
//
// The "modern" version of pictureshader explicitly takes SkFilterMode.
// The legacy version inherits it from the paint, hence the extra conversions/plumbing
// needed to downscale either filter-quality or sampling (from the paint) if we're in
// legacy mode. When all clients only use the modern/explicit version, we can eliminate
// all of this extra stuff.
static SkFilterMode sampling_to_filter(const SkSamplingOptions& sampling) {
return sampling == SkSamplingOptions() ? SkFilterMode::kNearest
: SkFilterMode::kLinear;
}
static SkFilterMode quality_to_filter(SkFilterQuality quality) {
return quality == kNone_SkFilterQuality ? SkFilterMode::kNearest
: SkFilterMode::kLinear;
}
static sk_sp<SkColorSpace> ref_or_srgb(SkColorSpace* cs) { static sk_sp<SkColorSpace> ref_or_srgb(SkColorSpace* cs) {
return cs ? sk_ref_sp(cs) : SkColorSpace::MakeSRGB(); return cs ? sk_ref_sp(cs) : SkColorSpace::MakeSRGB();
} }
@ -280,8 +252,7 @@ struct CachedImageInfo {
sk_sp<SkShader> SkPictureShader::rasterShader(const SkMatrix& viewMatrix, sk_sp<SkShader> SkPictureShader::rasterShader(const SkMatrix& viewMatrix,
SkTCopyOnFirstWrite<SkMatrix>* localMatrix, SkTCopyOnFirstWrite<SkMatrix>* localMatrix,
SkColorType dstColorType, SkColorType dstColorType,
SkColorSpace* dstColorSpace, SkColorSpace* dstColorSpace) const {
SkFilterMode paintFilter) const {
const int maxTextureSize_NotUsedForCPU = 0; const int maxTextureSize_NotUsedForCPU = 0;
CachedImageInfo info = CachedImageInfo::Make(fTile, viewMatrix, localMatrix, CachedImageInfo info = CachedImageInfo::Make(fTile, viewMatrix, localMatrix,
dstColorType, dstColorSpace, dstColorType, dstColorSpace,
@ -303,17 +274,7 @@ sk_sp<SkShader> SkPictureShader::rasterShader(const SkMatrix& viewMatrix,
SkResourceCache::Add(new ImageFromPictureRec(key, image)); SkResourceCache::Add(new ImageFromPictureRec(key, image));
SkPicturePriv::AddedToCache(fPicture.get()); SkPicturePriv::AddedToCache(fPicture.get());
} }
return this->makeShader(image.get(), paintFilter); return image->makeShader(fTmx, fTmy, SkSamplingOptions(fFilter), nullptr);
}
sk_sp<SkShader> SkPictureShader::makeShader(const SkImage* image, SkFilterMode paintFilter) const {
SkFilterMode filter;
if (fFilter == kInheritFromPaint) {
filter = paintFilter;
} else {
filter = (SkFilterMode)fFilter;
}
return image->makeShader(fTmx, fTmy, SkSamplingOptions(filter), nullptr);
} }
bool SkPictureShader::onAppendStages(const SkStageRec& rec) const { bool SkPictureShader::onAppendStages(const SkStageRec& rec) const {
@ -321,8 +282,7 @@ bool SkPictureShader::onAppendStages(const SkStageRec& rec) const {
// Keep bitmapShader alive by using alloc instead of stack memory // Keep bitmapShader alive by using alloc instead of stack memory
auto& bitmapShader = *rec.fAlloc->make<sk_sp<SkShader>>(); auto& bitmapShader = *rec.fAlloc->make<sk_sp<SkShader>>();
bitmapShader = this->rasterShader(rec.fMatrixProvider.localToDevice(), &lm, bitmapShader = this->rasterShader(rec.fMatrixProvider.localToDevice(), &lm,
rec.fDstColorType, rec.fDstCS, rec.fDstColorType, rec.fDstCS);
quality_to_filter(rec.fPaint.getFilterQuality()));
if (!bitmapShader) { if (!bitmapShader) {
return false; return false;
} }
@ -343,8 +303,7 @@ skvm::Color SkPictureShader::onProgram(skvm::Builder* p,
// Keep bitmapShader alive by using alloc instead of stack memory // Keep bitmapShader alive by using alloc instead of stack memory
auto& bitmapShader = *alloc->make<sk_sp<SkShader>>(); auto& bitmapShader = *alloc->make<sk_sp<SkShader>>();
bitmapShader = this->rasterShader(matrices.localToDevice(), &lm, bitmapShader = this->rasterShader(matrices.localToDevice(), &lm,
dst.colorType(), dst.colorSpace(), dst.colorType(), dst.colorSpace());
quality_to_filter(quality));
if (!bitmapShader) { if (!bitmapShader) {
return {}; return {};
} }
@ -362,8 +321,7 @@ SkShaderBase::Context* SkPictureShader::onMakeContext(const ContextRec& rec, SkA
const { const {
auto lm = this->totalLocalMatrix(rec.fLocalMatrix); auto lm = this->totalLocalMatrix(rec.fLocalMatrix);
sk_sp<SkShader> bitmapShader = this->rasterShader(*rec.fMatrix, &lm, rec.fDstColorType, sk_sp<SkShader> bitmapShader = this->rasterShader(*rec.fMatrix, &lm, rec.fDstColorType,
rec.fDstColorSpace, rec.fDstColorSpace);
sampling_to_filter(rec.fPaintSampling));
if (!bitmapShader) { if (!bitmapShader) {
return nullptr; return nullptr;
} }
@ -467,7 +425,7 @@ std::unique_ptr<GrFragmentProcessor> SkPictureShader::asFragmentProcessor(
const GrSamplerState sampler(static_cast<GrSamplerState::WrapMode>(fTmx), const GrSamplerState sampler(static_cast<GrSamplerState::WrapMode>(fTmx),
static_cast<GrSamplerState::WrapMode>(fTmy), static_cast<GrSamplerState::WrapMode>(fTmy),
sampling_to_filter(args.fSampling)); fFilter);
return GrTextureEffect::Make(std::move(view), kPremul_SkAlphaType, inv, sampler, return GrTextureEffect::Make(std::move(view), kPremul_SkAlphaType, inv, sampler,
*ctx->priv().caps()); *ctx->priv().caps());
} }

View File

@ -24,15 +24,7 @@ class SkPicture;
*/ */
class SkPictureShader : public SkShaderBase { class SkPictureShader : public SkShaderBase {
public: public:
enum FilterEnum { static sk_sp<SkShader> Make(sk_sp<SkPicture>, SkTileMode, SkTileMode, SkFilterMode,
kNearest, // SkFilterMode::kNearest
kLinear, // SkFilterMode::kLinear
kInheritFromPaint,
kLastFilterEnum = kInheritFromPaint,
};
static sk_sp<SkShader> Make(sk_sp<SkPicture>, SkTileMode, SkTileMode, FilterEnum,
const SkMatrix*, const SkRect*); const SkMatrix*, const SkRect*);
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
@ -55,14 +47,11 @@ protected:
private: private:
SK_FLATTENABLE_HOOKS(SkPictureShader) SK_FLATTENABLE_HOOKS(SkPictureShader)
SkPictureShader(sk_sp<SkPicture>, SkTileMode, SkTileMode, FilterEnum, SkPictureShader(sk_sp<SkPicture>, SkTileMode, SkTileMode, SkFilterMode,
const SkMatrix*, const SkRect*); const SkMatrix*, const SkRect*);
sk_sp<SkShader> rasterShader(const SkMatrix&, SkTCopyOnFirstWrite<SkMatrix>* localMatrix, sk_sp<SkShader> rasterShader(const SkMatrix&, SkTCopyOnFirstWrite<SkMatrix>* localMatrix,
SkColorType dstColorType, SkColorSpace* dstColorSpace, SkColorType dstColorType, SkColorSpace* dstColorSpace) const;
SkFilterMode paintFilter) const;
sk_sp<SkShader> makeShader(const SkImage*, SkFilterMode paintFilter) const;
class PictureShaderContext : public Context { class PictureShaderContext : public Context {
public: public:
@ -83,7 +72,7 @@ private:
sk_sp<SkPicture> fPicture; sk_sp<SkPicture> fPicture;
SkRect fTile; SkRect fTile;
SkTileMode fTmx, fTmy; SkTileMode fTmx, fTmy;
FilterEnum fFilter; SkFilterMode fFilter;
using INHERITED = SkShaderBase; using INHERITED = SkShaderBase;
}; };

View File

@ -145,7 +145,7 @@ sk_sp<SkShader> SkBitmap::makeShader(SkTileMode tmx, SkTileMode tmy,
return nullptr; return nullptr;
} }
return SkImageShader::Make(SkMakeImageFromRasterBitmap(*this, kIfMutable_SkCopyPixelsMode), return SkImageShader::Make(SkMakeImageFromRasterBitmap(*this, kIfMutable_SkCopyPixelsMode),
tmx, tmy, &sampling, lm); tmx, tmy, sampling, lm);
} }
bool SkShaderBase::appendStages(const SkStageRec& rec) const { bool SkShaderBase::appendStages(const SkStageRec& rec) const {

View File

@ -90,7 +90,6 @@ public:
, fLocalMatrix(localM) , fLocalMatrix(localM)
, fDstColorType(dstColorType) , fDstColorType(dstColorType)
, fDstColorSpace(dstColorSpace) { , fDstColorSpace(dstColorSpace) {
fPaintSampling = SkSamplingOptions(paint.getFilterQuality());
fPaintAlpha = paint.getAlpha(); fPaintAlpha = paint.getAlpha();
fPaintDither = paint.isDither(); fPaintDither = paint.isDither();
} }
@ -99,7 +98,6 @@ public:
const SkMatrix* fLocalMatrix; // optional local matrix const SkMatrix* fLocalMatrix; // optional local matrix
SkColorType fDstColorType; // the color type of the dest surface SkColorType fDstColorType; // the color type of the dest surface
SkColorSpace* fDstColorSpace; // the color space of the dest surface (if any) SkColorSpace* fDstColorSpace; // the color space of the dest surface (if any)
SkSamplingOptions fPaintSampling; // only used for legacy-built shaders (inherit sampling)
SkAlpha fPaintAlpha; SkAlpha fPaintAlpha;
bool fPaintDither; bool fPaintDither;