summaryrefslogtreecommitdiff
path: root/chromium/third_party/skia/src/shaders
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/src/shaders')
-rw-r--r--chromium/third_party/skia/src/shaders/SkColorFilterShader.cpp16
-rw-r--r--chromium/third_party/skia/src/shaders/SkColorFilterShader.h12
-rw-r--r--chromium/third_party/skia/src/shaders/SkColorShader.cpp15
-rw-r--r--chromium/third_party/skia/src/shaders/SkColorShader.h8
-rw-r--r--chromium/third_party/skia/src/shaders/SkComposeShader.cpp18
-rw-r--r--chromium/third_party/skia/src/shaders/SkComposeShader.h8
-rw-r--r--chromium/third_party/skia/src/shaders/SkEmptyShader.h7
-rwxr-xr-xchromium/third_party/skia/src/shaders/SkImageShader.cpp86
-rw-r--r--chromium/third_party/skia/src/shaders/SkImageShader.h20
-rw-r--r--chromium/third_party/skia/src/shaders/SkLocalMatrixShader.cpp43
-rw-r--r--chromium/third_party/skia/src/shaders/SkLocalMatrixShader.h4
-rw-r--r--chromium/third_party/skia/src/shaders/SkPerlinNoiseShader.cpp383
-rw-r--r--chromium/third_party/skia/src/shaders/SkPictureShader.cpp12
-rw-r--r--chromium/third_party/skia/src/shaders/SkPictureShader.h4
-rw-r--r--chromium/third_party/skia/src/shaders/SkShader.cpp53
-rw-r--r--chromium/third_party/skia/src/shaders/SkShaderBase.h11
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/Sk4fLinearGradient.cpp10
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/SkGradientShader.cpp14
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/SkGradientShaderPriv.h6
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/SkLinearGradient.cpp4
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/SkLinearGradient.h2
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/SkRadialGradient.cpp4
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/SkRadialGradient.h2
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/SkSweepGradient.cpp17
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/SkSweepGradient.h2
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient.cpp9
-rw-r--r--chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient.h2
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)