diff options
Diffstat (limited to 'chromium/third_party/skia/src/shaders')
27 files changed, 404 insertions, 368 deletions
diff --git a/chromium/third_party/skia/src/shaders/SkColorFilterShader.cpp b/chromium/third_party/skia/src/shaders/SkColorFilterShader.cpp index 6b39bc67b7a..c3cf2444a66 100644 --- a/chromium/third_party/skia/src/shaders/SkColorFilterShader.cpp +++ b/chromium/third_party/skia/src/shaders/SkColorFilterShader.cpp @@ -8,6 +8,7 @@ #include "include/core/SkShader.h" #include "include/core/SkString.h" #include "src/core/SkArenaAlloc.h" +#include "src/core/SkColorFilterBase.h" #include "src/core/SkRasterPipeline.h" #include "src/core/SkReadBuffer.h" #include "src/core/SkVM.h" @@ -22,7 +23,7 @@ SkColorFilterShader::SkColorFilterShader(sk_sp<SkShader> shader, float alpha, sk_sp<SkColorFilter> filter) : fShader(std::move(shader)) - , fFilter(std::move(filter)) + , fFilter(as_CFB_sp(std::move(filter))) , fAlpha (alpha) { SkASSERT(fShader); @@ -39,9 +40,7 @@ sk_sp<SkFlattenable> SkColorFilterShader::CreateProc(SkReadBuffer& buffer) { } bool SkColorFilterShader::isOpaque() const { - return fShader->isOpaque() - && fAlpha == 1.0f - && (fFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) != 0; + return fShader->isOpaque() && fAlpha == 1.0f && as_CFB(fFilter)->isAlphaUnchanged(); } void SkColorFilterShader::flatten(SkWriteBuffer& buffer) const { @@ -62,12 +61,15 @@ bool SkColorFilterShader::onAppendStages(const SkStageRec& rec) const { } skvm::Color SkColorFilterShader::onProgram(skvm::Builder* p, - skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider& matrices, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { // Run the shader. - skvm::Color c = as_SB(fShader)->program(p, x,y, paint, ctm,localM, quality,dst, uniforms,alloc); + skvm::Color c = as_SB(fShader)->program(p, device,local, paint, + matrices,localM, + quality,dst, + uniforms,alloc); if (!c) { return {}; } diff --git a/chromium/third_party/skia/src/shaders/SkColorFilterShader.h b/chromium/third_party/skia/src/shaders/SkColorFilterShader.h index e1d470086d4..c3bd0b081fc 100644 --- a/chromium/third_party/skia/src/shaders/SkColorFilterShader.h +++ b/chromium/third_party/skia/src/shaders/SkColorFilterShader.h @@ -8,7 +8,7 @@ #ifndef SkColorFilterShader_DEFINED #define SkColorFilterShader_DEFINED -#include "include/core/SkColorFilter.h" +#include "src/core/SkColorFilterBase.h" #include "src/shaders/SkShaderBase.h" class SkArenaAlloc; @@ -26,16 +26,16 @@ private: void flatten(SkWriteBuffer&) const override; bool onAppendStages(const SkStageRec&) const override; - skvm::Color onProgram(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc*) const override; SK_FLATTENABLE_HOOKS(SkColorFilterShader) - sk_sp<SkShader> fShader; - sk_sp<SkColorFilter> fFilter; - float fAlpha; + sk_sp<SkShader> fShader; + sk_sp<SkColorFilterBase> fFilter; + float fAlpha; typedef SkShaderBase INHERITED; }; diff --git a/chromium/third_party/skia/src/shaders/SkColorShader.cpp b/chromium/third_party/skia/src/shaders/SkColorShader.cpp index 83149989275..8afdda1128e 100644 --- a/chromium/third_party/skia/src/shaders/SkColorShader.cpp +++ b/chromium/third_party/skia/src/shaders/SkColorShader.cpp @@ -92,16 +92,18 @@ bool SkColor4Shader::onAppendStages(const SkStageRec& rec) const { } skvm::Color SkColorShader::onProgram(skvm::Builder* p, - skvm::F32 /*x*/, skvm::F32 /*y*/, skvm::Color /*paint*/, - const SkMatrix& /*ctm*/, const SkMatrix* /*localM*/, + skvm::Coord /*device*/, skvm::Coord /*local*/, + skvm::Color /*paint*/, + const SkMatrixProvider&, const SkMatrix* /*localM*/, SkFilterQuality /*quality*/, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc*) const { return p->uniformPremul(SkColor4f::FromColor(fColor), sk_srgb_singleton(), uniforms, dst.colorSpace()); } skvm::Color SkColor4Shader::onProgram(skvm::Builder* p, - skvm::F32 /*x*/, skvm::F32 /*y*/, skvm::Color /*paint*/, - const SkMatrix& /*ctm*/, const SkMatrix* /*localM*/, + skvm::Coord /*device*/, skvm::Coord /*local*/, + skvm::Color /*paint*/, + const SkMatrixProvider&, const SkMatrix* /*localM*/, SkFilterQuality /*quality*/, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc*) const { return p->uniformPremul(fColor, fColorSpace.get(), @@ -118,7 +120,8 @@ skvm::Color SkColor4Shader::onProgram(skvm::Builder* p, std::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor( const GrFPArgs& args) const { SkPMColor4f color = SkColorToPMColor4f(fColor, *args.fDstColorInfo); - return GrConstColorProcessor::Make(color, GrConstColorProcessor::InputMode::kModulateA); + return GrConstColorProcessor::Make(/*inputFP=*/nullptr, color, + GrConstColorProcessor::InputMode::kModulateA); } std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor( @@ -127,7 +130,7 @@ std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor( args.fDstColorInfo->colorSpace(), kUnpremul_SkAlphaType }; SkColor4f color = fColor; steps.apply(color.vec()); - return GrConstColorProcessor::Make(color.premul(), + return GrConstColorProcessor::Make(/*inputFP=*/nullptr, color.premul(), GrConstColorProcessor::InputMode::kModulateA); } diff --git a/chromium/third_party/skia/src/shaders/SkColorShader.h b/chromium/third_party/skia/src/shaders/SkColorShader.h index 0e9225cb6db..5b876655970 100644 --- a/chromium/third_party/skia/src/shaders/SkColorShader.h +++ b/chromium/third_party/skia/src/shaders/SkColorShader.h @@ -44,8 +44,8 @@ private: bool onAppendStages(const SkStageRec&) const override; - skvm::Color onProgram(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc*) const override; @@ -69,8 +69,8 @@ private: void flatten(SkWriteBuffer&) const override; bool onAppendStages(const SkStageRec&) const override; - skvm::Color onProgram(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc*) const override; diff --git a/chromium/third_party/skia/src/shaders/SkComposeShader.cpp b/chromium/third_party/skia/src/shaders/SkComposeShader.cpp index 96ebf79726f..77fbfeb42ae 100644 --- a/chromium/third_party/skia/src/shaders/SkComposeShader.cpp +++ b/chromium/third_party/skia/src/shaders/SkComposeShader.cpp @@ -127,13 +127,14 @@ bool SkShader_Blend::onAppendStages(const SkStageRec& orig_rec) const { return true; } -skvm::Color SkShader_Blend::onProgram(skvm::Builder* p, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, +skvm::Color SkShader_Blend::onProgram(skvm::Builder* p, + skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider& mats, const SkMatrix* localM, SkFilterQuality q, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { skvm::Color d,s; - if ((d = as_SB(fDst)->program(p, x,y, paint, ctm,localM, q, dst, uniforms, alloc)) && - (s = as_SB(fSrc)->program(p, x,y, paint, ctm,localM, q, dst, uniforms, alloc))) + if ((d = as_SB(fDst)->program(p, device,local, paint, mats,localM, q,dst, uniforms,alloc)) && + (s = as_SB(fSrc)->program(p, device,local, paint, mats,localM, q,dst, uniforms,alloc))) { return p->blend(fMode, s,d); } @@ -167,13 +168,14 @@ bool SkShader_Lerp::onAppendStages(const SkStageRec& orig_rec) const { return true; } -skvm::Color SkShader_Lerp::onProgram(skvm::Builder* p, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, +skvm::Color SkShader_Lerp::onProgram(skvm::Builder* p, + skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider& mats, const SkMatrix* localM, SkFilterQuality q, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { skvm::Color d,s; - if ((d = as_SB(fDst)->program(p, x,y, paint, ctm,localM, q, dst, uniforms, alloc)) && - (s = as_SB(fSrc)->program(p, x,y, paint, ctm,localM, q, dst, uniforms, alloc))) + if ((d = as_SB(fDst)->program(p, device,local, paint, mats,localM, q,dst, uniforms,alloc)) && + (s = as_SB(fSrc)->program(p, device,local, paint, mats,localM, q,dst, uniforms,alloc))) { auto t = p->uniformF(uniforms->pushF(fWeight)); return { diff --git a/chromium/third_party/skia/src/shaders/SkComposeShader.h b/chromium/third_party/skia/src/shaders/SkComposeShader.h index dd36d38816a..96ae0a04b51 100644 --- a/chromium/third_party/skia/src/shaders/SkComposeShader.h +++ b/chromium/third_party/skia/src/shaders/SkComposeShader.h @@ -27,8 +27,8 @@ protected: SkShader_Blend(SkReadBuffer&); void flatten(SkWriteBuffer&) const override; bool onAppendStages(const SkStageRec&) const override; - skvm::Color onProgram(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality, const SkColorInfo& dst, skvm::Uniforms*, SkArenaAlloc*) const override; @@ -60,8 +60,8 @@ protected: SkShader_Lerp(SkReadBuffer&); void flatten(SkWriteBuffer&) const override; bool onAppendStages(const SkStageRec&) const override; - skvm::Color onProgram(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality, const SkColorInfo& dst, skvm::Uniforms*, SkArenaAlloc*) const override; diff --git a/chromium/third_party/skia/src/shaders/SkEmptyShader.h b/chromium/third_party/skia/src/shaders/SkEmptyShader.h index edd1e27dc2d..414be6c199d 100644 --- a/chromium/third_party/skia/src/shaders/SkEmptyShader.h +++ b/chromium/third_party/skia/src/shaders/SkEmptyShader.h @@ -37,9 +37,10 @@ protected: return false; } - skvm::Color onProgram(skvm::Builder*, skvm::F32, skvm::F32, skvm::Color, const SkMatrix&, - const SkMatrix*, SkFilterQuality, const SkColorInfo&, skvm::Uniforms*, - SkArenaAlloc*) const override; + skvm::Color onProgram(skvm::Builder*, skvm::Coord, skvm::Coord, skvm::Color, + const SkMatrixProvider&, const SkMatrix*, + SkFilterQuality, const SkColorInfo&, + skvm::Uniforms*, SkArenaAlloc*) const override; private: SK_FLATTENABLE_HOOKS(SkEmptyShader) diff --git a/chromium/third_party/skia/src/shaders/SkImageShader.cpp b/chromium/third_party/skia/src/shaders/SkImageShader.cpp index 93bada25380..7f69d8413d1 100755 --- a/chromium/third_party/skia/src/shaders/SkImageShader.cpp +++ b/chromium/third_party/skia/src/shaders/SkImageShader.cpp @@ -37,11 +37,13 @@ static SkTileMode optimize(SkTileMode tm, int dimension) { SkImageShader::SkImageShader(sk_sp<SkImage> img, SkTileMode tmx, SkTileMode tmy, const SkMatrix* localMatrix, + FilterEnum filtering, bool clampAsIfUnpremul) : INHERITED(localMatrix) , fImage(std::move(img)) , fTileModeX(optimize(tmx, fImage->width())) , fTileModeY(optimize(tmy, fImage->height())) + , fFiltering(filtering) , fClampAsIfUnpremul(clampAsIfUnpremul) {} @@ -51,18 +53,26 @@ SkImageShader::SkImageShader(sk_sp<SkImage> img, sk_sp<SkFlattenable> SkImageShader::CreateProc(SkReadBuffer& buffer) { auto tmx = buffer.read32LE<SkTileMode>(SkTileMode::kLastTileMode); auto tmy = buffer.read32LE<SkTileMode>(SkTileMode::kLastTileMode); + + FilterEnum filtering = kInheritFromPaint; + if (!buffer.isVersionLT(SkPicturePriv::kFilteringInImageShader_Version)) { + filtering = buffer.read32LE<FilterEnum>(kInheritFromPaint); + } + SkMatrix localMatrix; buffer.readMatrix(&localMatrix); sk_sp<SkImage> img = buffer.readImage(); if (!img) { return nullptr; } - return SkImageShader::Make(std::move(img), tmx, tmy, &localMatrix); + + return SkImageShader::Make(std::move(img), tmx, tmy, &localMatrix, filtering); } void SkImageShader::flatten(SkWriteBuffer& buffer) const { buffer.writeUInt((unsigned)fTileModeX); buffer.writeUInt((unsigned)fTileModeY); + buffer.writeUInt((unsigned)fFiltering); buffer.writeMatrix(this->getLocalMatrix()); buffer.writeImage(fImage.get()); SkASSERT(fClampAsIfUnpremul == false); @@ -75,9 +85,7 @@ bool SkImageShader::isOpaque() const { #ifdef SK_ENABLE_LEGACY_SHADERCONTEXT static bool legacy_shader_can_handle(const SkMatrix& inv) { - if (inv.hasPerspective()) { - return false; - } + SkASSERT(!inv.hasPerspective()); // Scale+translate methods are always present, but affine might not be. if (!SkOpts::S32_alpha_D32_filter_DXDY && !inv.isScaleTranslate()) { @@ -102,6 +110,11 @@ static bool legacy_shader_can_handle(const SkMatrix& inv) { SkShaderBase::Context* SkImageShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const { + SkFilterQuality quality = this->resolveFiltering(rec.fPaint->getFilterQuality()); + + if (quality == kHigh_SkFilterQuality) { + return nullptr; + } if (fImage->alphaType() == kUnpremul_SkAlphaType) { return nullptr; } @@ -140,8 +153,16 @@ SkShaderBase::Context* SkImageShader::onMakeContext(const ContextRec& rec, return nullptr; } + // Send in a modified paint with different filter-quality if we don't agree with the paint + SkPaint modifiedPaint; + ContextRec modifiedRec = rec; + if (quality != rec.fPaint->getFilterQuality()) { + modifiedPaint = *rec.fPaint; + modifiedPaint.setFilterQuality(quality); + modifiedRec.fPaint = &modifiedPaint; + } return SkBitmapProcLegacyShader::MakeContext(*this, fTileModeX, fTileModeY, - as_IB(fImage.get()), rec, alloc); + as_IB(fImage.get()), modifiedRec, alloc); } #endif @@ -159,11 +180,14 @@ SkImage* SkImageShader::onIsAImage(SkMatrix* texM, SkTileMode xy[]) const { sk_sp<SkShader> SkImageShader::Make(sk_sp<SkImage> image, SkTileMode tmx, SkTileMode tmy, const SkMatrix* localMatrix, + FilterEnum filtering, bool clampAsIfUnpremul) { if (!image) { return sk_make_sp<SkEmptyShader>(); } - return sk_sp<SkShader>{ new SkImageShader(image, tmx, tmy, localMatrix, clampAsIfUnpremul) }; + return sk_sp<SkShader>{ + new SkImageShader(image, tmx, tmy, localMatrix, filtering, clampAsIfUnpremul) + }; } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -195,7 +219,7 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor( // are provided by the caller. bool doBicubic; GrSamplerState::Filter textureFilterMode = GrSkFilterQualityToGrFilterMode( - fImage->width(), fImage->height(), args.fFilterQuality, + fImage->width(), fImage->height(), this->resolveFiltering(args.fFilterQuality), args.fMatrixProvider.localToDevice(), *lm, args.fContext->priv().options().fSharpenMipmappedTextures, &doBicubic); GrMipMapped mipMapped = GrMipMapped::kNo; @@ -240,7 +264,7 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor( sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkTileMode tmx, SkTileMode tmy, const SkMatrix* localMatrix, SkCopyPixelsMode cpm) { return SkImageShader::Make(SkMakeImageFromRasterBitmap(src, cpm), - tmx, tmy, localMatrix); + tmx, tmy, localMatrix, SkImageShader::kInheritFromPaint); } sk_sp<SkShader> SkMakeBitmapShaderForPaint(const SkPaint& paint, const SkBitmap& src, @@ -336,14 +360,15 @@ static void tweak_quality_and_inv_matrix(SkFilterQuality* quality, SkMatrix* mat } bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater) const { - if (updater && rec.fPaint.getFilterQuality() == kMedium_SkFilterQuality) { + auto quality = this->resolveFiltering(rec.fPaint.getFilterQuality()); + + if (updater && quality == kMedium_SkFilterQuality) { // TODO: medium: recall RequestBitmap and update width/height accordingly return false; } SkRasterPipeline* p = rec.fPipeline; SkArenaAlloc* alloc = rec.fAlloc; - auto quality = rec.fPaint.getFilterQuality(); SkMatrix matrix; if (!this->computeTotalInverse(rec.fMatrixProvider.localToDevice(), rec.fLocalM, &matrix)) { @@ -464,14 +489,6 @@ bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater }; auto append_misc = [&] { - // This is an inessential optimization... it's logically safe to set this to false. - // But if... - // - we know the image is definitely normalized, and - // - we're doing some color space conversion, and - // - sRGB curves are involved, - // then we can use slightly faster math that doesn't work well outside [0,1]. - bool src_is_normalized = SkColorTypeIsNormalized(info.colorType()); - SkColorSpace* cs = info.colorSpace(); SkAlphaType at = info.alphaType(); @@ -480,7 +497,6 @@ bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater SkColor4f rgb = rec.fPaint.getColor4f(); p->append_set_rgb(alloc, rgb); - src_is_normalized = rgb.fitsInBytes(); cs = sk_srgb_singleton(); at = kUnpremul_SkAlphaType; } @@ -491,13 +507,12 @@ bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater p->append(at == kUnpremul_SkAlphaType || fClampAsIfUnpremul ? SkRasterPipeline::clamp_1 : SkRasterPipeline::clamp_a); - src_is_normalized = true; } // Transform color space and alpha type to match shader convention (dst CS, premul alpha). alloc->make<SkColorSpaceXformSteps>(cs, at, rec.fDstCS, kPremul_SkAlphaType) - ->apply(p, src_is_normalized); + ->apply(p); return true; }; @@ -624,12 +639,15 @@ SkStageUpdater* SkImageShader::onAppendUpdatableStages(const SkStageRec& rec) co return this->doStages(rec, updater) ? updater : nullptr; } -skvm::Color SkImageShader::onProgram(skvm::Builder* p, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, +skvm::Color SkImageShader::onProgram(skvm::Builder* p, + skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider& matrices, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { + quality = this->resolveFiltering(quality); + SkMatrix inv; - if (!this->computeTotalInverse(ctm, localM, &inv)) { + if (!this->computeTotalInverse(matrices.localToDevice(), localM, &inv)) { return {}; } @@ -646,7 +664,7 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p, skvm::F32 x, skvm::F32 y, inv.normalizePerspective(); // Apply matrix to convert dst coords to sample center coords. - SkShaderBase::ApplyMatrix(p, inv, &x,&y,uniforms); + local = SkShaderBase::ApplyMatrix(p, inv, local, uniforms); // Bail out if sample() can't yet handle our image's color type. switch (pm.colorType()) { @@ -771,14 +789,14 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p, skvm::F32 x, skvm::F32 y, skvm::Color c; if (quality == kNone_SkFilterQuality) { - c = sample(x,y); + c = sample(local.x,local.y); } else if (quality == kLow_SkFilterQuality) { // Our four sample points are the corners of a logical 1x1 pixel // box surrounding (x,y) at (0.5,0.5) off-center. - skvm::F32 left = x - 0.5f, - top = y - 0.5f, - right = x + 0.5f, - bottom = y + 0.5f; + skvm::F32 left = local.x - 0.5f, + top = local.y - 0.5f, + right = local.x + 0.5f, + bottom = local.y + 0.5f; // The fractional parts of right and bottom are our lerp factors in x and y respectively. skvm::F32 fx = fract(right ), @@ -791,8 +809,8 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p, skvm::F32 x, skvm::F32 y, // All bicubic samples have the same fractional offset (fx,fy) from the center. // They're either the 16 corners of a 3x3 grid/ surrounding (x,y) at (0.5,0.5) off-center. - skvm::F32 fx = fract(x + 0.5f), - fy = fract(y + 0.5f); + skvm::F32 fx = fract(local.x + 0.5f), + fy = fract(local.y + 0.5f); // See GrCubicEffect for details of these weights. // TODO: these maybe don't seem right looking at gm/bicubic and GrBicubicEffect. @@ -819,9 +837,9 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p, skvm::F32 x, skvm::F32 y, c.r = c.g = c.b = c.a = p->splat(0.0f); - skvm::F32 sy = y - 1.5f; + skvm::F32 sy = local.y - 1.5f; for (int j = 0; j < 4; j++, sy += 1.0f) { - skvm::F32 sx = x - 1.5f; + skvm::F32 sx = local.x - 1.5f; for (int i = 0; i < 4; i++, sx += 1.0f) { skvm::Color s = sample(sx,sy); skvm::F32 w = wx[i] * wy[j]; diff --git a/chromium/third_party/skia/src/shaders/SkImageShader.h b/chromium/third_party/skia/src/shaders/SkImageShader.h index 24f6b81b76c..a653a9f332a 100644 --- a/chromium/third_party/skia/src/shaders/SkImageShader.h +++ b/chromium/third_party/skia/src/shaders/SkImageShader.h @@ -17,10 +17,20 @@ class SkImageStageUpdater; class SkImageShader : public SkShaderBase { public: + enum FilterEnum { // first 4 entries match SkFilterQuality + kNone, + kLow, + kMedium, + kHigh, + // this is the special value for backward compatibility + kInheritFromPaint, + }; + static sk_sp<SkShader> Make(sk_sp<SkImage>, SkTileMode tmx, SkTileMode tmy, const SkMatrix* localMatrix, + FilterEnum, bool clampAsIfUnpremul = false); bool isOpaque() const override; @@ -36,6 +46,7 @@ private: SkTileMode tmx, SkTileMode tmy, const SkMatrix* localMatrix, + FilterEnum, bool clampAsIfUnpremul); void flatten(SkWriteBuffer&) const override; @@ -47,16 +58,21 @@ private: bool onAppendStages(const SkStageRec&) const override; SkStageUpdater* onAppendUpdatableStages(const SkStageRec&) const override; - skvm::Color onProgram(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc*) const override; bool doStages(const SkStageRec&, SkImageStageUpdater* = nullptr) const; + SkFilterQuality resolveFiltering(SkFilterQuality paintQuality) const { + return fFiltering == kInheritFromPaint ? paintQuality : (SkFilterQuality)fFiltering; + } + sk_sp<SkImage> fImage; const SkTileMode fTileModeX; const SkTileMode fTileModeY; + const FilterEnum fFiltering; const bool fClampAsIfUnpremul; friend class SkShaderBase; diff --git a/chromium/third_party/skia/src/shaders/SkLocalMatrixShader.cpp b/chromium/third_party/skia/src/shaders/SkLocalMatrixShader.cpp index 66ee52be696..c0ef126ffa4 100644 --- a/chromium/third_party/skia/src/shaders/SkLocalMatrixShader.cpp +++ b/chromium/third_party/skia/src/shaders/SkLocalMatrixShader.cpp @@ -12,6 +12,7 @@ #if SK_SUPPORT_GPU #include "src/gpu/GrFragmentProcessor.h" +#include "src/gpu/effects/generated/GrDeviceSpaceEffect.h" #endif #if SK_SUPPORT_GPU @@ -77,15 +78,18 @@ bool SkLocalMatrixShader::onAppendStages(const SkStageRec& rec) const { skvm::Color SkLocalMatrixShader::onProgram(skvm::Builder* p, - skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider& matrices, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { SkTCopyOnFirstWrite<SkMatrix> lm(this->getLocalMatrix()); if (localM) { lm.writable()->preConcat(*localM); } - return as_SB(fProxyShader)->program(p, x,y, paint, ctm,lm.get(), quality,dst, uniforms,alloc); + return as_SB(fProxyShader)->program(p, device,local, paint, + matrices,lm.get(), + quality,dst, + uniforms,alloc); } sk_sp<SkShader> SkShader::makeWithLocalMatrix(const SkMatrix& localMatrix) const { @@ -152,11 +156,16 @@ protected: return as_SB(fProxyShader)->appendStages(newRec); } - skvm::Color onProgram(skvm::Builder* p, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color onProgram(skvm::Builder* p, + skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider& matrices, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const override { - return as_SB(fProxyShader)->program(p, x,y,paint, fCTM,localM, quality,dst, uniforms,alloc); + SkOverrideDeviceMatrixProvider matrixProvider(matrices, fCTM); + return as_SB(fProxyShader)->program(p, device,local, paint, + matrixProvider,localM, + quality,dst, + uniforms,alloc); } private: @@ -172,8 +181,23 @@ private: #if SK_SUPPORT_GPU std::unique_ptr<GrFragmentProcessor> SkCTMShader::asFragmentProcessor( const GrFPArgs& args) const { - return as_SB(fProxyShader)->asFragmentProcessor( - GrFPArgs::WithPreLocalMatrix(args, this->getLocalMatrix())); + SkMatrix ctmInv; + if (!fCTM.invert(&ctmInv)) { + return nullptr; + } + + auto ctmProvider = SkOverrideDeviceMatrixProvider(args.fMatrixProvider, fCTM); + auto base = as_SB(fProxyShader)->asFragmentProcessor( + GrFPArgs::WithPreLocalMatrix(args.withNewMatrixProvider(ctmProvider), + this->getLocalMatrix())); + if (!base) { + return nullptr; + } + + // In order for the shader to be evaluated with the original CTM, we explicitly evaluate it + // at sk_FragCoord, and pass that through the inverse of the original CTM. This avoids requiring + // local coords for the shader and mapping from the draw's local to device and then back. + return GrDeviceSpaceEffect::Make(std::move(base), ctmInv); } #endif @@ -183,6 +207,5 @@ sk_sp<SkFlattenable> SkCTMShader::CreateProc(SkReadBuffer& buffer) { } sk_sp<SkShader> SkShaderBase::makeWithCTM(const SkMatrix& postM) const { - return postM.isIdentity() ? sk_ref_sp(this) - : sk_sp<SkShader>(new SkCTMShader(sk_ref_sp(this), postM)); + return sk_sp<SkShader>(new SkCTMShader(sk_ref_sp(this), postM)); } diff --git a/chromium/third_party/skia/src/shaders/SkLocalMatrixShader.h b/chromium/third_party/skia/src/shaders/SkLocalMatrixShader.h index 603e30e2603..b1fd8826901 100644 --- a/chromium/third_party/skia/src/shaders/SkLocalMatrixShader.h +++ b/chromium/third_party/skia/src/shaders/SkLocalMatrixShader.h @@ -48,8 +48,8 @@ protected: bool onAppendStages(const SkStageRec&) const override; - skvm::Color onProgram(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc*) const override; diff --git a/chromium/third_party/skia/src/shaders/SkPerlinNoiseShader.cpp b/chromium/third_party/skia/src/shaders/SkPerlinNoiseShader.cpp index 2d00c03aa4a..a17d7507f54 100644 --- a/chromium/third_party/skia/src/shaders/SkPerlinNoiseShader.cpp +++ b/chromium/third_party/skia/src/shaders/SkPerlinNoiseShader.cpp @@ -21,6 +21,7 @@ #include "src/gpu/GrCoordTransform.h" #include "src/gpu/GrRecordingContextPriv.h" #include "src/gpu/SkGr.h" +#include "src/gpu/effects/GrTextureEffect.h" #include "src/gpu/effects/generated/GrConstColorProcessor.h" #include "src/gpu/glsl/GrGLSLFragmentProcessor.h" #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" @@ -119,7 +120,7 @@ public: fPermutationsBitmap.installPixels(info, fLatticeSelector, info.minRowBytes()); fPermutationsBitmap.setImmutable(); - info = SkImageInfo::MakeN32Premul(kBlockSize, 4); + info = SkImageInfo::Make(kBlockSize, 4, kRGBA_8888_SkColorType, kPremul_SkAlphaType); fNoiseBitmap.installPixels(info, fNoise[0][0], info.minRowBytes()); fNoiseBitmap.setImmutable(); @@ -144,7 +145,7 @@ public: 1, 0, 2, 0, 0, 2, 1, 0, 1, 0, 0, 0 }; - info = SkImageInfo::MakeN32Premul(16, 1); + info = SkImageInfo::Make(16, 1, kBGRA_8888_SkColorType, kPremul_SkAlphaType); fGradientBitmap.installPixels(info, gradients, info.minRowBytes()); fGradientBitmap.setImmutable(); #endif @@ -717,13 +718,26 @@ private: class GrPerlinNoise2Effect : public GrFragmentProcessor { public: static std::unique_ptr<GrFragmentProcessor> Make( - SkPerlinNoiseShaderImpl::Type type, int numOctaves, bool stitchTiles, + SkPerlinNoiseShaderImpl::Type type, + int numOctaves, + bool stitchTiles, std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData, - GrSurfaceProxyView permutationsView, GrSurfaceProxyView noiseView, - const SkMatrix& matrix) { - return std::unique_ptr<GrFragmentProcessor>(new GrPerlinNoise2Effect( - type, numOctaves, stitchTiles, std::move(paintingData), - std::move(permutationsView), std::move(noiseView), matrix)); + GrSurfaceProxyView permutationsView, + GrSurfaceProxyView noiseView, + const SkMatrix& matrix, + const GrCaps& caps) { + static constexpr GrSamplerState kRepeatXSampler = {GrSamplerState::WrapMode::kRepeat, + GrSamplerState::WrapMode::kClamp, + GrSamplerState::Filter::kNearest}; + auto permutationsFP = + GrTextureEffect::Make(std::move(permutationsView), kPremul_SkAlphaType, + SkMatrix::I(), kRepeatXSampler, caps); + auto noiseFP = GrTextureEffect::Make(std::move(noiseView), kPremul_SkAlphaType, + SkMatrix::I(), kRepeatXSampler, caps); + + return std::unique_ptr<GrFragmentProcessor>( + new GrPerlinNoise2Effect(type, numOctaves, stitchTiles, std::move(paintingData), + std::move(permutationsFP), std::move(noiseFP), matrix)); } const char* name() const override { return "PerlinNoise"; } @@ -759,19 +773,20 @@ private: fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataInit; } - GrPerlinNoise2Effect(SkPerlinNoiseShaderImpl::Type type, int numOctaves, bool stitchTiles, + GrPerlinNoise2Effect(SkPerlinNoiseShaderImpl::Type type, + int numOctaves, + bool stitchTiles, std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData, - GrSurfaceProxyView permutationsView, - GrSurfaceProxyView noiseView, + std::unique_ptr<GrFragmentProcessor> permutationsFP, + std::unique_ptr<GrFragmentProcessor> noiseFP, const SkMatrix& matrix) : INHERITED(kGrPerlinNoise2Effect_ClassID, kNone_OptimizationFlags) , fType(type) , fNumOctaves(numOctaves) , fStitchTiles(stitchTiles) - , fPermutationsSampler(std::move(permutationsView)) - , fNoiseSampler(std::move(noiseView)) , fPaintingData(std::move(paintingData)) { - this->setTextureSamplerCnt(2); + this->registerExplicitlySampledChild(std::move(permutationsFP)); + this->registerExplicitlySampledChild(std::move(noiseFP)); fCoordTransform = GrCoordTransform(matrix); this->addCoordTransform(&fCoordTransform); } @@ -782,16 +797,11 @@ private: , fCoordTransform(that.fCoordTransform) , fNumOctaves(that.fNumOctaves) , fStitchTiles(that.fStitchTiles) - , fPermutationsSampler(that.fPermutationsSampler) - , fNoiseSampler(that.fNoiseSampler) , fPaintingData(new SkPerlinNoiseShaderImpl::PaintingData(*that.fPaintingData)) { - this->setTextureSamplerCnt(2); + this->cloneAndRegisterAllChildProcessors(that); this->addCoordTransform(&fCoordTransform); } - const TextureSampler& onTextureSampler(int i) const override { - return IthTextureSampler(i, fPermutationsSampler, fNoiseSampler); - } GR_DECLARE_FRAGMENT_PROCESSOR_TEST @@ -799,8 +809,7 @@ private: GrCoordTransform fCoordTransform; int fNumOctaves; bool fStitchTiles; - TextureSampler fPermutationsSampler; - TextureSampler fNoiseSampler; + std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> fPaintingData; typedef GrFragmentProcessor INHERITED; @@ -851,86 +860,36 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) { stitchDataUni = uniformHandler->getUniformCStr(fStitchDataUni); } - // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 - const char* chanCoordR = "0.125"; - const char* chanCoordG = "0.375"; - const char* chanCoordB = "0.625"; - const char* chanCoordA = "0.875"; - const char* chanCoord = "chanCoord"; - const char* stitchData = "stitchData"; - const char* ratio = "ratio"; - const char* noiseVec = "noiseVec"; - const char* noiseSmooth = "noiseSmooth"; - const char* floorVal = "floorVal"; - const char* fractVal = "fractVal"; - const char* uv = "uv"; - const char* ab = "ab"; - const char* latticeIdx = "latticeIdx"; - const char* bcoords = "bcoords"; - const char* lattice = "lattice"; - const char* inc8bit = "0.00390625"; // 1.0 / 256.0 - // This is the math to convert the two 16bit integer packed into rgba 8 bit input into a - // [-1,1] vector and perform a dot product between that vector and the provided vector. - const char* dotLattice = "dot(((%s.ga + %s.rb * half2(%s)) * half2(2.0) - half2(1.0)), %s);"; - // Add noise function - const GrShaderVar gPerlinNoiseArgs[] = { - GrShaderVar(chanCoord, kHalf_GrSLType), - GrShaderVar(noiseVec, kHalf2_GrSLType) - }; + const GrShaderVar gPerlinNoiseArgs[] = {{"chanCoord", kHalf_GrSLType }, + {"noiseVec ", kHalf2_GrSLType}}; - const GrShaderVar gPerlinNoiseStitchArgs[] = { - GrShaderVar(chanCoord, kHalf_GrSLType), - GrShaderVar(noiseVec, kHalf2_GrSLType), - GrShaderVar(stitchData, kHalf2_GrSLType) - }; + const GrShaderVar gPerlinNoiseStitchArgs[] = {{"chanCoord" , kHalf_GrSLType }, + {"noiseVec" , kHalf2_GrSLType}, + {"stitchData", kHalf2_GrSLType}}; SkString noiseCode; - noiseCode.appendf("\thalf4 %s;\n", floorVal); - noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec); - noiseCode.appendf("\t%s.zw = %s.xy + half2(1.0);\n", floorVal, floorVal); - noiseCode.appendf("\thalf2 %s = fract(%s);\n", fractVal, noiseVec); - - // smooth curve : t * t * (3 - 2 * t) - noiseCode.appendf("\n\thalf2 %s = %s * %s * (half2(3.0) - half2(2.0) * %s);", - noiseSmooth, fractVal, fractVal, fractVal); + noiseCode.append( + R"(half4 floorVal; + floorVal.xy = floor(noiseVec); + floorVal.zw = floorVal.xy + half2(1); + half2 fractVal = fract(noiseVec); + // smooth curve : t^2*(3 - 2*t) + half2 noiseSmooth = fractVal*fractVal*(half2(3) - 2*fractVal);)"); // Adjust frequencies if we're stitching tiles if (pne.stitchTiles()) { - noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", - floorVal, stitchData, floorVal, stitchData); - noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", - floorVal, stitchData, floorVal, stitchData); - noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }", - floorVal, stitchData, floorVal, stitchData); - noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }", - floorVal, stitchData, floorVal, stitchData); + noiseCode.append( + R"(if (floorVal.x >= stitchData.x) { floorVal.x -= stitchData.x; }; + if (floorVal.y >= stitchData.y) { floorVal.y -= stitchData.y; }; + if (floorVal.z >= stitchData.x) { floorVal.z -= stitchData.x; }; + if (floorVal.w >= stitchData.y) { floorVal.w -= stitchData.y; };)"); } - // Get texture coordinates and normalize - noiseCode.appendf("\n\t%s = fract(floor(mod(%s, 256.0)) / half4(256.0));\n", - floorVal, floorVal); - - // Get permutation for x - { - SkString xCoords(""); - xCoords.appendf("half2(%s.x, 0.5)", floorVal); - - noiseCode.appendf("\n\thalf2 %s;\n\t%s.x = ", latticeIdx, latticeIdx); - fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[0], xCoords.c_str()); - noiseCode.append(".r;"); - } - - // Get permutation for x + 1 - { - SkString xCoords(""); - xCoords.appendf("half2(%s.z, 0.5)", floorVal); - - noiseCode.appendf("\n\t%s.y = ", latticeIdx); - fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[0], xCoords.c_str()); - noiseCode.append(".r;"); - } + SkString sampleX = this->invokeChild(0, args, "half2(floorVal.x, 0.5)"); + SkString sampleY = this->invokeChild(0, args, "half2(floorVal.z, 0.5)"); + noiseCode.appendf("half2 latticeIdx = half2(%s.r, %s.r);", sampleX.c_str(), sampleY.c_str()); #if defined(SK_BUILD_FOR_ANDROID) // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Nexus 7 (Tegra 3). @@ -939,65 +898,54 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) { // (or 0.484368 here). The following rounding operation prevents these precision issues from // affecting the result of the noise by making sure that we only have multiples of 1/255. // (Note that 1/255 is about 0.003921569, which is the value used here). - noiseCode.appendf("\n\t%s = floor(%s * half2(255.0) + half2(0.5)) * half2(0.003921569);", - latticeIdx, latticeIdx); + noiseCode.append( + "latticeIdx = floor(latticeIdx * half2(255.0) + half2(0.5)) * half2(0.003921569);"); #endif // Get (x,y) coordinates with the permutated x - noiseCode.appendf("\n\thalf4 %s = fract(%s.xyxy + %s.yyww);", bcoords, latticeIdx, floorVal); + noiseCode.append("half4 bcoords = 256*latticeIdx.xyxy + floorVal.yyww;"); + + noiseCode.append("half2 uv;"); + + // This is the math to convert the two 16bit integer packed into rgba 8 bit input into a + // [-1,1] vector and perform a dot product between that vector and the provided vector. + // Save it as a string because we will repeat it 4x. + static constexpr const char* inc8bit = "0.00390625"; // 1.0 / 256.0 + SkString dotLattice = + SkStringPrintf("dot((lattice.ga + lattice.rb*%s)*2 - half2(1), fractVal)", inc8bit); + + SkString sampleA = this->invokeChild(1, args, "half2(bcoords.x, chanCoord)"); + SkString sampleB = this->invokeChild(1, args, "half2(bcoords.y, chanCoord)"); + SkString sampleC = this->invokeChild(1, args, "half2(bcoords.w, chanCoord)"); + SkString sampleD = this->invokeChild(1, args, "half2(bcoords.z, chanCoord)"); - noiseCode.appendf("\n\n\thalf2 %s;", uv); // Compute u, at offset (0,0) - { - SkString latticeCoords(""); - latticeCoords.appendf("half2(%s.x, %s)", bcoords, chanCoord); - noiseCode.appendf("\n\thalf4 %s = ", lattice); - fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str()); - noiseCode.appendf(".bgra;\n\t%s.x = ", uv); - noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); - } + noiseCode.appendf("half4 lattice = %s;", sampleA.c_str()); + noiseCode.appendf("uv.x = %s;", dotLattice.c_str()); - noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal); // Compute v, at offset (-1,0) - { - SkString latticeCoords(""); - latticeCoords.appendf("half2(%s.y, %s)", bcoords, chanCoord); - noiseCode.append("\n\tlattice = "); - fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str()); - noiseCode.appendf(".bgra;\n\t%s.y = ", uv); - noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); - } + noiseCode.append("fractVal.x -= 1.0;"); + noiseCode.appendf("lattice = %s;", sampleB.c_str()); + noiseCode.appendf("uv.y = %s;", dotLattice.c_str()); // Compute 'a' as a linear interpolation of 'u' and 'v' - noiseCode.appendf("\n\thalf2 %s;", ab); - noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth); + noiseCode.append("half2 ab;"); + noiseCode.append("ab.x = mix(uv.x, uv.y, noiseSmooth.x);"); - noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal); // Compute v, at offset (-1,-1) - { - SkString latticeCoords(""); - latticeCoords.appendf("half2(%s.w, %s)", bcoords, chanCoord); - noiseCode.append("\n\tlattice = "); - fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str()); - noiseCode.appendf(".bgra;\n\t%s.y = ", uv); - noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); - } + noiseCode.append("fractVal.y -= 1.0;"); + noiseCode.appendf("lattice = %s;", sampleC.c_str()); + noiseCode.appendf("uv.y = %s;", dotLattice.c_str()); - noiseCode.appendf("\n\t%s.x += 1.0;", fractVal); // Compute u, at offset (0,-1) - { - SkString latticeCoords(""); - latticeCoords.appendf("half2(%s.z, %s)", bcoords, chanCoord); - noiseCode.append("\n\tlattice = "); - fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str()); - noiseCode.appendf(".bgra;\n\t%s.x = ", uv); - noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); - } + noiseCode.append("fractVal.x += 1.0;"); + noiseCode.appendf("lattice = %s;", sampleD.c_str()); + noiseCode.appendf("uv.x = %s;", dotLattice.c_str()); // Compute 'b' as a linear interpolation of 'u' and 'v' - noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth); + noiseCode.append("ab.y = mix(uv.x, uv.y, noiseSmooth.x);"); // Compute the noise as a linear interpolation of 'a' and 'b' - noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth); + noiseCode.append("return mix(ab.x, ab.y, noiseSmooth.y);"); SkString noiseFuncName; if (pne.stitchTiles()) { @@ -1011,68 +959,73 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) { } // There are rounding errors if the floor operation is not performed here - fragBuilder->codeAppendf("\n\t\thalf2 %s = half2(floor(%s.xy) * %s);", - noiseVec, vCoords.c_str(), baseFrequencyUni); + fragBuilder->codeAppendf("half2 noiseVec = half2(floor(%s.xy) * %s);", + vCoords.c_str(), baseFrequencyUni); // Clear the color accumulator - fragBuilder->codeAppendf("\n\t\t%s = half4(0.0);", args.fOutputColor); + fragBuilder->codeAppendf("%s = half4(0.0);", args.fOutputColor); if (pne.stitchTiles()) { // Set up TurbulenceInitial stitch values. - fragBuilder->codeAppendf("\n\t\thalf2 %s = %s;", stitchData, stitchDataUni); + fragBuilder->codeAppendf("half2 stitchData = %s;", stitchDataUni); } - fragBuilder->codeAppendf("\n\t\thalf %s = 1.0;", ratio); + fragBuilder->codeAppendf("half ratio = 1.0;"); // Loop over all octaves fragBuilder->codeAppendf("for (int octave = 0; octave < %d; ++octave) {", pne.numOctaves()); - - fragBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor); + fragBuilder->codeAppendf(" %s += ", args.fOutputColor); if (pne.type() != SkPerlinNoiseShaderImpl::kFractalNoise_Type) { fragBuilder->codeAppend("abs("); } + + // There are 4 lines, put y coords at center of each. + static constexpr const char* chanCoordR = "0.5"; + static constexpr const char* chanCoordG = "1.5"; + static constexpr const char* chanCoordB = "2.5"; + static constexpr const char* chanCoordA = "3.5"; if (pne.stitchTiles()) { - fragBuilder->codeAppendf( - "half4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s)," - "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))", - noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData, - noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData, - noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData, - noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData); + fragBuilder->codeAppendf(R"( + half4(%s(%s, noiseVec, stitchData), %s(%s, noiseVec, stitchData)," + %s(%s, noiseVec, stitchData), %s(%s, noiseVec, stitchData)))", + noiseFuncName.c_str(), chanCoordR, + noiseFuncName.c_str(), chanCoordG, + noiseFuncName.c_str(), chanCoordB, + noiseFuncName.c_str(), chanCoordA); } else { - fragBuilder->codeAppendf( - "half4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s)," - "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))", - noiseFuncName.c_str(), chanCoordR, noiseVec, - noiseFuncName.c_str(), chanCoordG, noiseVec, - noiseFuncName.c_str(), chanCoordB, noiseVec, - noiseFuncName.c_str(), chanCoordA, noiseVec); + fragBuilder->codeAppendf(R"( + half4(%s(%s, noiseVec), %s(%s, noiseVec), + %s(%s, noiseVec), %s(%s, noiseVec)))", + noiseFuncName.c_str(), chanCoordR, + noiseFuncName.c_str(), chanCoordG, + noiseFuncName.c_str(), chanCoordB, + noiseFuncName.c_str(), chanCoordA); } if (pne.type() != SkPerlinNoiseShaderImpl::kFractalNoise_Type) { - fragBuilder->codeAppendf(")"); // end of "abs(" + fragBuilder->codeAppend(")"); // end of "abs(" } - fragBuilder->codeAppendf(" * %s;", ratio); + fragBuilder->codeAppend(" * ratio;"); - fragBuilder->codeAppendf("\n\t\t\t%s *= half2(2.0);", noiseVec); - fragBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio); + fragBuilder->codeAppend(R"(noiseVec *= half2(2.0); + ratio *= 0.5;)"); if (pne.stitchTiles()) { - fragBuilder->codeAppendf("\n\t\t\t%s *= half2(2.0);", stitchData); + fragBuilder->codeAppend("stitchData *= half2(2.0);"); } - fragBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves + fragBuilder->codeAppend("}"); // end of the for loop on octaves if (pne.type() == SkPerlinNoiseShaderImpl::kFractalNoise_Type) { // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2 // by fractalNoise and (turbulenceFunctionResult) by turbulence. - fragBuilder->codeAppendf("\n\t\t%s = %s * half4(0.5) + half4(0.5);", - args.fOutputColor,args.fOutputColor); + fragBuilder->codeAppendf("%s = %s * half4(0.5) + half4(0.5);", + args.fOutputColor, args.fOutputColor); } // Clamp values - fragBuilder->codeAppendf("\n\t\t%s = saturate(%s);", args.fOutputColor, args.fOutputColor); + fragBuilder->codeAppendf("%s = saturate(%s);", args.fOutputColor, args.fOutputColor); // Pre-multiply the result - fragBuilder->codeAppendf("\n\t\t%s = half4(%s.rgb * %s.aaa, %s.a);\n", + fragBuilder->codeAppendf("%s = half4(%s.rgb * %s.aaa, %s.a);\n", args.fOutputColor, args.fOutputColor, args.fOutputColor, args.fOutputColor); } @@ -1116,7 +1069,7 @@ void GrGLPerlinNoise::onSetData(const GrGLSLProgramDataManager& pdman, if (turbulence.stitchTiles()) { const SkPerlinNoiseShaderImpl::StitchData& stitchData = turbulence.stitchData(); pdman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth), - SkIntToScalar(stitchData.fHeight)); + SkIntToScalar(stitchData.fHeight)); } } @@ -1143,13 +1096,24 @@ private: class GrImprovedPerlinNoiseEffect : public GrFragmentProcessor { public: static std::unique_ptr<GrFragmentProcessor> Make( - int octaves, SkScalar z, + int octaves, + SkScalar z, std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData, - GrSurfaceProxyView permutationsView, GrSurfaceProxyView gradientView, - const SkMatrix& matrix) { + GrSurfaceProxyView permutationsView, + GrSurfaceProxyView gradientView, + const SkMatrix& matrix, + const GrCaps& caps) { + static constexpr GrSamplerState kRepeatXSampler = {GrSamplerState::WrapMode::kRepeat, + GrSamplerState::WrapMode::kClamp, + GrSamplerState::Filter::kNearest}; + auto permutationsFP = + GrTextureEffect::Make(std::move(permutationsView), kPremul_SkAlphaType, + SkMatrix::I(), kRepeatXSampler, caps); + auto gradientFP = GrTextureEffect::Make(std::move(gradientView), kPremul_SkAlphaType, + SkMatrix::I(), kRepeatXSampler, caps); return std::unique_ptr<GrFragmentProcessor>(new GrImprovedPerlinNoiseEffect( - octaves, z, std::move(paintingData), std::move(permutationsView), - std::move(gradientView), matrix)); + octaves, z, std::move(paintingData), std::move(permutationsFP), + std::move(gradientFP), matrix)); } const char* name() const override { return "ImprovedPerlinNoise"; } @@ -1178,18 +1142,18 @@ private: fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency; } - GrImprovedPerlinNoiseEffect(int octaves, SkScalar z, + GrImprovedPerlinNoiseEffect(int octaves, + SkScalar z, std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData, - GrSurfaceProxyView permutationsView, - GrSurfaceProxyView gradientView, + std::unique_ptr<GrFragmentProcessor> permutationsFP, + std::unique_ptr<GrFragmentProcessor> gradientFP, const SkMatrix& matrix) : INHERITED(kGrImprovedPerlinNoiseEffect_ClassID, kNone_OptimizationFlags) , fOctaves(octaves) , fZ(z) - , fPermutationsSampler(std::move(permutationsView)) - , fGradientSampler(std::move(gradientView)) , fPaintingData(std::move(paintingData)) { - this->setTextureSamplerCnt(2); + this->registerExplicitlySampledChild(std::move(permutationsFP)); + this->registerExplicitlySampledChild(std::move(gradientFP)); fCoordTransform = GrCoordTransform(matrix); this->addCoordTransform(&fCoordTransform); } @@ -1199,24 +1163,17 @@ private: , fCoordTransform(that.fCoordTransform) , fOctaves(that.fOctaves) , fZ(that.fZ) - , fPermutationsSampler(that.fPermutationsSampler) - , fGradientSampler(that.fGradientSampler) , fPaintingData(new SkPerlinNoiseShaderImpl::PaintingData(*that.fPaintingData)) { - this->setTextureSamplerCnt(2); + this->cloneAndRegisterAllChildProcessors(that); this->addCoordTransform(&fCoordTransform); } - const TextureSampler& onTextureSampler(int i) const override { - return IthTextureSampler(i, fPermutationsSampler, fGradientSampler); - } - GR_DECLARE_FRAGMENT_PROCESSOR_TEST GrCoordTransform fCoordTransform; int fOctaves; SkScalar fZ; - TextureSampler fPermutationsSampler; - TextureSampler fGradientSampler; + std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> fPaintingData; typedef GrFragmentProcessor INHERITED; @@ -1271,44 +1228,39 @@ void GrGLImprovedPerlinNoise::emitCode(EmitArgs& args) { // perm function const GrShaderVar permArgs[] = { - GrShaderVar("x", kHalf_GrSLType) + {"x", kHalf_GrSLType} }; + SkString samplePerm = this->invokeChild(0, args, "float2(x, 0.5)"); SkString permFuncName; - SkString permCode("return "); - // FIXME even though I'm creating these textures with kRepeat_TileMode, they're clamped. Not - // sure why. Using fract() (here and the next texture lookup) as a workaround. - fragBuilder->appendTextureLookup(&permCode, args.fTexSamplers[0], - "float2(fract(x / 256.0), 0.0)"); - permCode.append(".r * 255.0;"); + SkString permCode = SkStringPrintf("return %s.r * 255;", samplePerm.c_str()); fragBuilder->emitFunction(kHalf_GrSLType, "perm", SK_ARRAY_COUNT(permArgs), permArgs, permCode.c_str(), &permFuncName); // grad function const GrShaderVar gradArgs[] = { - GrShaderVar("x", kHalf_GrSLType), - GrShaderVar("p", kHalf3_GrSLType) + {"x", kHalf_GrSLType}, + {"p", kHalf3_GrSLType} }; + SkString sampleGrad = this->invokeChild(1, args, "float2(x, 0.5)"); SkString gradFuncName; - SkString gradCode("return half(dot("); - fragBuilder->appendTextureLookup(&gradCode, args.fTexSamplers[1], - "float2(fract(x / 16.0), 0.0)"); - gradCode.append(".rgb * 255.0 - float3(1.0), p));"); + SkString gradCode = SkStringPrintf("return half(dot(%s.rgb * 255.0 - float3(1.0), p));", + sampleGrad.c_str()); fragBuilder->emitFunction(kHalf_GrSLType, "grad", SK_ARRAY_COUNT(gradArgs), gradArgs, gradCode.c_str(), &gradFuncName); // lerp function const GrShaderVar lerpArgs[] = { - GrShaderVar("a", kHalf_GrSLType), - GrShaderVar("b", kHalf_GrSLType), - GrShaderVar("w", kHalf_GrSLType) + {"a", kHalf_GrSLType}, + {"b", kHalf_GrSLType}, + {"w", kHalf_GrSLType} }; SkString lerpFuncName; fragBuilder->emitFunction(kHalf_GrSLType, "lerp", SK_ARRAY_COUNT(lerpArgs), lerpArgs, "return a + w * (b - a);", &lerpFuncName); // noise function - const GrShaderVar noiseArgs[] = { - GrShaderVar("p", kHalf3_GrSLType), + const GrShaderVar noiseArgs[] = { + {"p", kHalf3_GrSLType}, }; SkString noiseFuncName; SkString noiseCode; @@ -1345,7 +1297,7 @@ void GrGLImprovedPerlinNoise::emitCode(EmitArgs& args) { // noiseOctaves function const GrShaderVar noiseOctavesArgs[] = { - GrShaderVar("p", kHalf3_GrSLType) + {"p", kHalf3_GrSLType} }; SkString noiseOctavesFuncName; SkString noiseOctavesCode; @@ -1432,9 +1384,13 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso const SkBitmap& gradientBitmap = paintingData->getGradientBitmap(); SkASSERT(SkIsPow2(gradientBitmap.width()) && SkIsPow2(gradientBitmap.height())); auto gradientView = GrMakeCachedBitmapProxyView(context, gradientBitmap); - return GrImprovedPerlinNoiseEffect::Make(fNumOctaves, fSeed, std::move(paintingData), + return GrImprovedPerlinNoiseEffect::Make(fNumOctaves, + fSeed, + std::move(paintingData), std::move(permutationsView), - std::move(gradientView), m); + std::move(gradientView), + m, + *context->priv().caps()); } if (0 == fNumOctaves) { @@ -1443,13 +1399,13 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso // TODO: Either treat the output of this shader as sRGB or allow client to specify a // color space of the noise. Either way, this case (and the GLSL) need to convert to // the destination. - auto inner = - GrConstColorProcessor::Make(SkPMColor4f::FromBytes_RGBA(0x80404040), - GrConstColorProcessor::InputMode::kModulateRGBA); + auto inner = GrConstColorProcessor::Make( + /*inputFP=*/nullptr, SkPMColor4f::FromBytes_RGBA(0x80404040), + GrConstColorProcessor::InputMode::kModulateRGBA); return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner)); } // Emit zero. - return GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT, + return GrConstColorProcessor::Make(/*inputFP=*/nullptr, SK_PMColor4fTRANSPARENT, GrConstColorProcessor::InputMode::kIgnore); } @@ -1471,7 +1427,8 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso std::move(paintingData), std::move(permutationsView), std::move(noiseView), - m); + m, + *context->priv().caps()); return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner)); } return nullptr; diff --git a/chromium/third_party/skia/src/shaders/SkPictureShader.cpp b/chromium/third_party/skia/src/shaders/SkPictureShader.cpp index 009ae54d36e..6a77004b49c 100644 --- a/chromium/third_party/skia/src/shaders/SkPictureShader.cpp +++ b/chromium/third_party/skia/src/shaders/SkPictureShader.cpp @@ -275,20 +275,24 @@ bool SkPictureShader::onAppendStages(const SkStageRec& rec) const { } skvm::Color SkPictureShader::onProgram(skvm::Builder* p, - skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider& matrices, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { auto lm = this->totalLocalMatrix(localM); // Keep bitmapShader alive by using alloc instead of stack memory auto& bitmapShader = *alloc->make<sk_sp<SkShader>>(); - bitmapShader = this->refBitmapShader(ctm, &lm, dst.colorType(), dst.colorSpace()); + bitmapShader = this->refBitmapShader(matrices.localToDevice(), &lm, + dst.colorType(), dst.colorSpace()); if (!bitmapShader) { return {}; } - return as_SB(bitmapShader)->program(p, x,y, paint, ctm, lm, quality, dst, uniforms, alloc); + return as_SB(bitmapShader)->program(p, device,local, paint, + matrices,lm, + quality,dst, + uniforms,alloc); } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/chromium/third_party/skia/src/shaders/SkPictureShader.h b/chromium/third_party/skia/src/shaders/SkPictureShader.h index 0bdc9cd9e09..01ef4b4d122 100644 --- a/chromium/third_party/skia/src/shaders/SkPictureShader.h +++ b/chromium/third_party/skia/src/shaders/SkPictureShader.h @@ -37,8 +37,8 @@ protected: SkPictureShader(SkReadBuffer&); void flatten(SkWriteBuffer&) const override; bool onAppendStages(const SkStageRec&) const override; - skvm::Color onProgram(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const override; diff --git a/chromium/third_party/skia/src/shaders/SkShader.cpp b/chromium/third_party/skia/src/shaders/SkShader.cpp index c1c09e7d9a2..e8bcdb9927c 100644 --- a/chromium/third_party/skia/src/shaders/SkShader.cpp +++ b/chromium/third_party/skia/src/shaders/SkShader.cpp @@ -189,14 +189,15 @@ bool SkShaderBase::onAppendStages(const SkStageRec& rec) const { rec.fPipeline->append(SkRasterPipeline::callback, cb); rec.fAlloc->make<SkColorSpaceXformSteps>(sk_srgb_singleton(), kPremul_SkAlphaType, rec.fDstCS, kPremul_SkAlphaType) - ->apply(rec.fPipeline, true); + ->apply(rec.fPipeline); return true; } return false; } -skvm::Color SkShaderBase::program(skvm::Builder* p, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, +skvm::Color SkShaderBase::program(skvm::Builder* p, + skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider& matrices, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { // Force opaque alpha for all opaque shaders. @@ -211,7 +212,8 @@ skvm::Color SkShaderBase::program(skvm::Builder* p, skvm::F32 x, skvm::F32 y, sk // shader program hash and blitter Key. This makes it safe for us to use // that bit to make decisions when constructing an SkVMBlitter, like doing // SrcOver -> Src strength reduction. - if (auto color = this->onProgram(p, x,y, paint, ctm,localM, quality,dst, uniforms,alloc)) { + if (auto color = this->onProgram(p, device,local, paint, matrices,localM, quality,dst, + uniforms,alloc)) { if (this->isOpaque()) { color.a = p->splat(1.0f); } @@ -220,11 +222,12 @@ skvm::Color SkShaderBase::program(skvm::Builder* p, skvm::F32 x, skvm::F32 y, sk return {}; } -skvm::Color SkShaderBase::onProgram(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, +skvm::Color SkShaderBase::onProgram(skvm::Builder*, + skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { - //SkDebugf("cannot onProgram %s\n", this->getTypeName()); + // SkDebugf("cannot onProgram %s\n", this->getTypeName()); return {}; } @@ -234,36 +237,40 @@ sk_sp<SkShader> SkShaderBase::makeInvertAlpha() const { } -void SkShaderBase::ApplyMatrix(skvm::Builder* p, const SkMatrix& m, - skvm::F32* x, skvm::F32* y, skvm::Uniforms* uniforms) { +skvm::Coord SkShaderBase::ApplyMatrix(skvm::Builder* p, const SkMatrix& m, + skvm::Coord coord, skvm::Uniforms* uniforms) { + skvm::F32 x = coord.x, + y = coord.y; if (m.isIdentity()) { // That was easy. } else if (m.isTranslate()) { - *x = p->add(*x, p->uniformF(uniforms->pushF(m[2]))); - *y = p->add(*y, p->uniformF(uniforms->pushF(m[5]))); + x = p->add(x, p->uniformF(uniforms->pushF(m[2]))); + y = p->add(y, p->uniformF(uniforms->pushF(m[5]))); } else if (m.isScaleTranslate()) { - *x = p->mad(*x, p->uniformF(uniforms->pushF(m[0])), p->uniformF(uniforms->pushF(m[2]))); - *y = p->mad(*y, p->uniformF(uniforms->pushF(m[4])), p->uniformF(uniforms->pushF(m[5]))); + x = p->mad(x, p->uniformF(uniforms->pushF(m[0])), p->uniformF(uniforms->pushF(m[2]))); + y = p->mad(y, p->uniformF(uniforms->pushF(m[4])), p->uniformF(uniforms->pushF(m[5]))); } else { // Affine or perspective. - auto dot = [&,X=*x,Y=*y](int row) { - return p->mad(X, p->uniformF(uniforms->pushF(m[3*row+0])), - p->mad(Y, p->uniformF(uniforms->pushF(m[3*row+1])), + auto dot = [&,x,y](int row) { + return p->mad(x, p->uniformF(uniforms->pushF(m[3*row+0])), + p->mad(y, p->uniformF(uniforms->pushF(m[3*row+1])), p->uniformF(uniforms->pushF(m[3*row+2])))); }; - *x = dot(0); - *y = dot(1); + x = dot(0); + y = dot(1); if (m.hasPerspective()) { - *x = p->div(*x, dot(2)); - *y = p->div(*y, dot(2)); + x = p->div(x, dot(2)); + y = p->div(y, dot(2)); } } + return {x,y}; } /////////////////////////////////////////////////////////////////////////////////////////////////// -skvm::Color SkEmptyShader::onProgram(skvm::Builder*, skvm::F32, skvm::F32, skvm::Color, - const SkMatrix&, const SkMatrix*, SkFilterQuality, - const SkColorInfo&, skvm::Uniforms*, SkArenaAlloc*) const { +skvm::Color SkEmptyShader::onProgram(skvm::Builder*, skvm::Coord, skvm::Coord, skvm::Color, + const SkMatrixProvider&, const SkMatrix*, + SkFilterQuality, const SkColorInfo&, + skvm::Uniforms*, SkArenaAlloc*) const { return {}; // signal failure } diff --git a/chromium/third_party/skia/src/shaders/SkShaderBase.h b/chromium/third_party/skia/src/shaders/SkShaderBase.h index dda4d1aac5f..9119056bd93 100644 --- a/chromium/third_party/skia/src/shaders/SkShaderBase.h +++ b/chromium/third_party/skia/src/shaders/SkShaderBase.h @@ -211,8 +211,8 @@ public: return this->onAppendUpdatableStages(rec); } - skvm::Color program(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color program(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const; @@ -241,14 +241,15 @@ protected: virtual SkStageUpdater* onAppendUpdatableStages(const SkStageRec&) const { return nullptr; } protected: - static void ApplyMatrix(skvm::Builder*, const SkMatrix&, skvm::F32* x, skvm::F32* y, skvm::Uniforms*); + static skvm::Coord ApplyMatrix(skvm::Builder*, const SkMatrix&, skvm::Coord, skvm::Uniforms*); private: // This is essentially const, but not officially so it can be modified in constructors. SkMatrix fLocalMatrix; - virtual skvm::Color onProgram(skvm::Builder*, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + virtual skvm::Color onProgram(skvm::Builder*, + skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dst, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const; diff --git a/chromium/third_party/skia/src/shaders/gradients/Sk4fLinearGradient.cpp b/chromium/third_party/skia/src/shaders/gradients/Sk4fLinearGradient.cpp index d75bec96556..944ac9fdb47 100644 --- a/chromium/third_party/skia/src/shaders/gradients/Sk4fLinearGradient.cpp +++ b/chromium/third_party/skia/src/shaders/gradients/Sk4fLinearGradient.cpp @@ -190,17 +190,17 @@ LinearGradient4fContext::shadePremulSpan(int x, int y, SkPMColor dst[], int coun const SkLinearGradient& shader = static_cast<const SkLinearGradient&>(fShader); switch (shader.fTileMode) { case SkTileMode::kDecal: - SkASSERT(false); // decal only supported via stages - // fall-through + SkASSERT(false); // decal only supported via stages + [[fallthrough]]; case SkTileMode::kClamp: this->shadeSpanInternal<premul, SkTileMode::kClamp >(x, y, dst, count, bias0, bias1); - break; + break; case SkTileMode::kRepeat: this->shadeSpanInternal<premul, SkTileMode::kRepeat>(x, y, dst, count, bias0, bias1); - break; + break; case SkTileMode::kMirror: this->shadeSpanInternal<premul, SkTileMode::kMirror>(x, y, dst, count, bias0, bias1); - break; + break; } } diff --git a/chromium/third_party/skia/src/shaders/gradients/SkGradientShader.cpp b/chromium/third_party/skia/src/shaders/gradients/SkGradientShader.cpp index 205a18f05b3..23e5d9a8495 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkGradientShader.cpp +++ b/chromium/third_party/skia/src/shaders/gradients/SkGradientShader.cpp @@ -299,7 +299,8 @@ bool SkGradientShaderBase::onAppendStages(const SkStageRec& rec) const { decal_ctx->limit_x = SkBits2Float(SkFloat2Bits(1.0f) + 1); // reuse mask + limit_x stage, or create a custom decal_1 that just stores the mask p->append(SkRasterPipeline::decal_x, decal_ctx); - // fall-through to clamp + [[fallthrough]]; + case SkTileMode::kClamp: if (!fOrigPos) { // We clamp only when the stops are evenly spaced. @@ -419,21 +420,22 @@ bool SkGradientShaderBase::onAppendStages(const SkStageRec& rec) const { } skvm::Color SkGradientShaderBase::onProgram(skvm::Builder* p, - skvm::F32 x, skvm::F32 y, skvm::Color /*paint*/, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Coord device, skvm::Coord local, + skvm::Color /*paint*/, + const SkMatrixProvider& mats, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dstInfo, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { SkMatrix inv; - if (!this->computeTotalInverse(ctm, localM, &inv)) { + if (!this->computeTotalInverse(mats.localToDevice(), localM, &inv)) { return {}; } inv.postConcat(fPtsToUnit); inv.normalizePerspective(); - SkShaderBase::ApplyMatrix(p, inv, &x,&y,uniforms); + local = SkShaderBase::ApplyMatrix(p, inv, local, uniforms); skvm::I32 mask = p->splat(~0); - skvm::F32 t = this->transformT(p,uniforms, x,y, &mask); + skvm::F32 t = this->transformT(p,uniforms, local, &mask); // Perhaps unexpectedly, clamping is handled naturally by our search, so we // don't explicitly clamp t to [0,1]. That clamp would break hard stops diff --git a/chromium/third_party/skia/src/shaders/gradients/SkGradientShaderPriv.h b/chromium/third_party/skia/src/shaders/gradients/SkGradientShaderPriv.h index 2a3bfca1808..f33c444f9b5 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkGradientShaderPriv.h +++ b/chromium/third_party/skia/src/shaders/gradients/SkGradientShaderPriv.h @@ -79,8 +79,8 @@ protected: bool onAppendStages(const SkStageRec&) const override; - skvm::Color onProgram(skvm::Builder* p, skvm::F32 x, skvm::F32 y, skvm::Color paint, - const SkMatrix& ctm, const SkMatrix* localM, + skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, + const SkMatrixProvider&, const SkMatrix* localM, SkFilterQuality quality, const SkColorInfo& dstCS, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const override; @@ -89,7 +89,7 @@ protected: // Produce t from (x,y), modifying mask if it should be anything other than ~0. virtual skvm::F32 transformT(skvm::Builder*, skvm::Uniforms*, - skvm::F32 x, skvm::F32 y, skvm::I32* mask) const = 0; + skvm::Coord coord, skvm::I32* mask) const = 0; template <typename T, typename... Args> static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) { diff --git a/chromium/third_party/skia/src/shaders/gradients/SkLinearGradient.cpp b/chromium/third_party/skia/src/shaders/gradients/SkLinearGradient.cpp index ad5129ccc3b..347fd177f00 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkLinearGradient.cpp +++ b/chromium/third_party/skia/src/shaders/gradients/SkLinearGradient.cpp @@ -76,9 +76,9 @@ void SkLinearGradient::appendGradientStages(SkArenaAlloc*, SkRasterPipeline*, } skvm::F32 SkLinearGradient::transformT(skvm::Builder* p, skvm::Uniforms*, - skvm::F32 x, skvm::F32 y, skvm::I32* mask) const { + skvm::Coord coord, skvm::I32* mask) const { // We've baked getting t in x into the matrix, so this is pretty trivial. - return x; + return coord.x; } SkShader::GradientType SkLinearGradient::asAGradient(GradientInfo* info) const { diff --git a/chromium/third_party/skia/src/shaders/gradients/SkLinearGradient.h b/chromium/third_party/skia/src/shaders/gradients/SkLinearGradient.h index c8f9bc678f5..063b9c5a647 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkLinearGradient.h +++ b/chromium/third_party/skia/src/shaders/gradients/SkLinearGradient.h @@ -30,7 +30,7 @@ protected: SkRasterPipeline* postPipeline) const final; skvm::F32 transformT(skvm::Builder*, skvm::Uniforms*, - skvm::F32 x, skvm::F32 y, skvm::I32* mask) const final; + skvm::Coord coord, skvm::I32* mask) const final; private: SK_FLATTENABLE_HOOKS(SkLinearGradient) diff --git a/chromium/third_party/skia/src/shaders/gradients/SkRadialGradient.cpp b/chromium/third_party/skia/src/shaders/gradients/SkRadialGradient.cpp index aeefe15e741..fea9ca6b316 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkRadialGradient.cpp +++ b/chromium/third_party/skia/src/shaders/gradients/SkRadialGradient.cpp @@ -64,8 +64,8 @@ void SkRadialGradient::appendGradientStages(SkArenaAlloc*, SkRasterPipeline* p, } skvm::F32 SkRadialGradient::transformT(skvm::Builder* p, skvm::Uniforms*, - skvm::F32 x, skvm::F32 y, skvm::I32* mask) const { - return sqrt(x*x + y*y); + skvm::Coord coord, skvm::I32* mask) const { + return sqrt(coord.x*coord.x + coord.y*coord.y); } ///////////////////////////////////////////////////////////////////// diff --git a/chromium/third_party/skia/src/shaders/gradients/SkRadialGradient.h b/chromium/third_party/skia/src/shaders/gradients/SkRadialGradient.h index 75680978637..7396bb21d2b 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkRadialGradient.h +++ b/chromium/third_party/skia/src/shaders/gradients/SkRadialGradient.h @@ -27,7 +27,7 @@ protected: SkRasterPipeline* postPipeline) const override; skvm::F32 transformT(skvm::Builder*, skvm::Uniforms*, - skvm::F32 x, skvm::F32 y, skvm::I32* mask) const final; + skvm::Coord coord, skvm::I32* mask) const final; private: SK_FLATTENABLE_HOOKS(SkRadialGradient) diff --git a/chromium/third_party/skia/src/shaders/gradients/SkSweepGradient.cpp b/chromium/third_party/skia/src/shaders/gradients/SkSweepGradient.cpp index b8a8c51977d..6256cc6bf35 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkSweepGradient.cpp +++ b/chromium/third_party/skia/src/shaders/gradients/SkSweepGradient.cpp @@ -13,7 +13,7 @@ SkSweepGradient::SkSweepGradient(const SkPoint& center, SkScalar t0, SkScalar t1, const Descriptor& desc) - : SkGradientShaderBase(desc, SkMatrix::MakeTrans(-center.x(), -center.y())) + : SkGradientShaderBase(desc, SkMatrix::Translate(-center.x(), -center.y())) , fCenter(center) , fTBias(-t0) , fTScale(1 / (t1 - t0)) @@ -64,14 +64,13 @@ void SkSweepGradient::flatten(SkWriteBuffer& buffer) const { void SkSweepGradient::appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* p, SkRasterPipeline*) const { p->append(SkRasterPipeline::xy_to_unit_angle); - p->append_matrix(alloc, SkMatrix::Concat(SkMatrix::MakeScale(fTScale, 1), - SkMatrix::MakeTrans(fTBias , 0))); + p->append_matrix(alloc, SkMatrix::Scale(fTScale, 1) * SkMatrix::Translate(fTBias, 0)); } skvm::F32 SkSweepGradient::transformT(skvm::Builder* p, skvm::Uniforms* uniforms, - skvm::F32 x, skvm::F32 y, skvm::I32* mask) const { - skvm::F32 xabs = abs(x), - yabs = abs(y), + skvm::Coord coord, skvm::I32* mask) const { + skvm::F32 xabs = abs(coord.x), + yabs = abs(coord.y), slope = min(xabs, yabs) / max(xabs, yabs); skvm::F32 s = slope * slope; @@ -83,9 +82,9 @@ skvm::F32 SkSweepGradient::transformT(skvm::Builder* p, skvm::Uniforms* uniforms +2.476101927459239959716796875e-2f, -5.185396969318389892578125e-2f, +0.15912117063999176025390625f); - phi = select(xabs < yabs, (1/4.0f) - phi, phi); - phi = select( x < 0.0f, (1/2.0f) - phi, phi); - phi = select( y < 0.0f, (1/1.0f) - phi, phi); + phi = select( xabs < yabs, (1/4.0f) - phi, phi); + phi = select(coord.x < 0.0f, (1/2.0f) - phi, phi); + phi = select(coord.y < 0.0f, (1/1.0f) - phi, phi); skvm::F32 t = select(is_NaN(phi), p->splat(0.0f) , phi); diff --git a/chromium/third_party/skia/src/shaders/gradients/SkSweepGradient.h b/chromium/third_party/skia/src/shaders/gradients/SkSweepGradient.h index e7beae2dae5..86ca372ba0c 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkSweepGradient.h +++ b/chromium/third_party/skia/src/shaders/gradients/SkSweepGradient.h @@ -31,7 +31,7 @@ protected: SkRasterPipeline* postPipeline) const override; skvm::F32 transformT(skvm::Builder*, skvm::Uniforms*, - skvm::F32 x, skvm::F32 y, skvm::I32* mask) const final; + skvm::Coord coord, skvm::I32* mask) const final; private: SK_FLATTENABLE_HOOKS(SkSweepGradient) diff --git a/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient.cpp b/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient.cpp index 811d719b9d5..d3ec7552176 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient.cpp +++ b/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient.cpp @@ -62,7 +62,7 @@ sk_sp<SkShader> SkTwoPointConicalGradient::Create(const SkPoint& c0, SkScalar r0 } // Concentric case: we can pretend we're radial (with a tiny twist). const SkScalar scale = sk_ieee_float_divide(1, std::max(r0, r1)); - gradientMatrix = SkMatrix::MakeTrans(-c1.x(), -c1.y()); + gradientMatrix = SkMatrix::Translate(-c1.x(), -c1.y()); gradientMatrix.postScale(scale, scale); gradientType = Type::kRadial; @@ -188,8 +188,7 @@ void SkTwoPointConicalGradient::appendGradientStages(SkArenaAlloc* alloc, SkRast auto scale = std::max(fRadius1, fRadius2) / dRadius; auto bias = -fRadius1 / dRadius; - p->append_matrix(alloc, SkMatrix::Concat(SkMatrix::MakeTrans(bias, 0), - SkMatrix::MakeScale(scale, 1))); + p->append_matrix(alloc, SkMatrix::Translate(bias, 0) * SkMatrix::Scale(scale, 1)); return; } @@ -235,11 +234,13 @@ void SkTwoPointConicalGradient::appendGradientStages(SkArenaAlloc* alloc, SkRast } skvm::F32 SkTwoPointConicalGradient::transformT(skvm::Builder* p, skvm::Uniforms* uniforms, - skvm::F32 x, skvm::F32 y, skvm::I32* mask) const { + skvm::Coord coord, skvm::I32* mask) const { // See https://skia.org/dev/design/conical, and onAppendStages() above. // There's a lot going on here, and I'm not really sure what's independent // or disjoint, what can be reordered, simplified, etc. Tweak carefully. + const skvm::F32 x = coord.x, + y = coord.y; if (fType == Type::kRadial) { float denom = 1.0f / (fRadius2 - fRadius1), scale = std::max(fRadius1, fRadius2) * denom, diff --git a/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient.h b/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient.h index a8893ce5e1f..d362ba0a303 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient.h +++ b/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient.h @@ -70,7 +70,7 @@ protected: SkRasterPipeline* postPipeline) const override; skvm::F32 transformT(skvm::Builder*, skvm::Uniforms*, - skvm::F32 x, skvm::F32 y, skvm::I32* mask) const final; + skvm::Coord coord, skvm::I32* mask) const final; private: SK_FLATTENABLE_HOOKS(SkTwoPointConicalGradient) |