aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gn/gpu.gni2
-rw-r--r--gn/sksl.gni1
-rw-r--r--src/effects/GrAlphaThresholdFragmentProcessor.cpp6
-rw-r--r--src/effects/GrCircleBlurFragmentProcessor.cpp6
-rw-r--r--src/effects/SkBlurMaskFilter.cpp248
-rw-r--r--src/gpu/effects/GrArithmeticFP.cpp10
-rw-r--r--src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp2
-rw-r--r--src/gpu/effects/GrCircleEffect.cpp6
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp2
-rw-r--r--src/gpu/effects/GrDitherEffect.cpp2
-rw-r--r--src/gpu/effects/GrEllipseEffect.cpp6
-rw-r--r--src/gpu/effects/GrRectBlurEffect.cpp167
-rw-r--r--src/gpu/effects/GrRectBlurEffect.fp123
-rw-r--r--src/gpu/effects/GrRectBlurEffect.h100
-rw-r--r--src/gpu/effects/GrSimpleTextureEffect.cpp4
-rw-r--r--src/sksl/SkSLCPP.h3
-rw-r--r--src/sksl/SkSLCPPCodeGenerator.cpp59
-rw-r--r--src/sksl/SkSLCPPCodeGenerator.h4
-rw-r--r--src/sksl/SkSLGLSLCodeGenerator.h2
-rw-r--r--src/sksl/ir/SkSLLayout.h12
20 files changed, 499 insertions, 266 deletions
diff --git a/gn/gpu.gni b/gn/gpu.gni
index ef751dba4c..6922c07590 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -350,6 +350,8 @@ skia_gpu_sources = [
"$_src/gpu/effects/GrOvalEffect.h",
"$_src/gpu/effects/GrPorterDuffXferProcessor.cpp",
"$_src/gpu/effects/GrPorterDuffXferProcessor.h",
+ "$_src/gpu/effects/GrRectBlurEffect.cpp",
+ "$_src/gpu/effects/GrRectBlurEffect.h",
"$_src/gpu/effects/GrRRectEffect.cpp",
"$_src/gpu/effects/GrRRectEffect.h",
"$_src/gpu/effects/GrShadowGeoProc.cpp",
diff --git a/gn/sksl.gni b/gn/sksl.gni
index 1de85f6fae..615b5dcbcc 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -33,5 +33,6 @@ skia_gpu_processor_sources = [
"$_src/gpu/effects/GrConfigConversionEffect.fp",
"$_src/gpu/effects/GrDitherEffect.fp",
"$_src/gpu/effects/GrEllipseEffect.fp",
+ "$_src/gpu/effects/GrRectBlurEffect.fp",
"$_src/gpu/effects/GrSimpleTextureEffect.fp",
]
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
index e1badf7f21..5ef0221be7 100644
--- a/src/effects/GrAlphaThresholdFragmentProcessor.cpp
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
@@ -34,6 +34,12 @@ public:
const GrAlphaThresholdFragmentProcessor& _outer =
args.fFp.cast<GrAlphaThresholdFragmentProcessor>();
(void)_outer;
+ auto colorXform = _outer.colorXform();
+ (void)colorXform;
+ auto innerThreshold = _outer.innerThreshold();
+ (void)innerThreshold;
+ auto outerThreshold = _outer.outerThreshold();
+ (void)outerThreshold;
fColorSpaceHelper.emitCode(args.fUniformHandler, _outer.colorXform().get());
fInnerThresholdVar = args.fUniformHandler->addUniform(
kFragment_GrShaderFlag, kHalf_GrSLType, kDefault_GrSLPrecision, "innerThreshold");
diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp
index 5a825f49f5..647afb8076 100644
--- a/src/effects/GrCircleBlurFragmentProcessor.cpp
+++ b/src/effects/GrCircleBlurFragmentProcessor.cpp
@@ -263,6 +263,12 @@ public:
const GrCircleBlurFragmentProcessor& _outer =
args.fFp.cast<GrCircleBlurFragmentProcessor>();
(void)_outer;
+ auto circleRect = _outer.circleRect();
+ (void)circleRect;
+ auto textureRadius = _outer.textureRadius();
+ (void)textureRadius;
+ auto solidRadius = _outer.solidRadius();
+ (void)solidRadius;
fCircleDataVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
kDefault_GrSLPrecision, "circleData");
fragBuilder->codeAppendf(
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index ca7de71914..7da42459f4 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -26,6 +26,7 @@
#include "GrShaderCaps.h"
#include "GrStyle.h"
#include "GrTextureProxy.h"
+#include "effects/GrRectBlurEffect.h"
#include "effects/GrSimpleTextureEffect.h"
#include "effects/GrTextureDomain.h"
#include "glsl/GrGLSLFragmentProcessor.h"
@@ -761,253 +762,6 @@ void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
#if SK_SUPPORT_GPU
-class GrGLRectBlurEffect;
-
-class GrRectBlurEffect : public GrFragmentProcessor {
-public:
- ~GrRectBlurEffect() override { }
-
- const char* name() const override { return "RectBlur"; }
-
- static std::unique_ptr<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider,
- const SkRect& rect, float sigma) {
- int doubleProfileSize = SkScalarCeilToInt(12*sigma);
-
- if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) {
- // if the blur sigma is too large so the gaussian overlaps the whole
- // rect in either direction, fall back to CPU path for now.
- return nullptr;
- }
-
- sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(resourceProvider, sigma));
- if (!blurProfile) {
- return nullptr;
- }
- // in OpenGL ES, mediump floats have a minimum range of 2^14. If we have coordinates bigger
- // than that, the shader math will end up with infinities and result in the blur effect not
- // working correctly. To avoid this, we switch into highp when the coordinates are too big.
- // As 2^14 is the minimum range but the actual range can be bigger, we might end up
- // switching to highp sooner than strictly necessary, but most devices that have a bigger
- // range for mediump also have mediump being exactly the same as highp (e.g. all non-OpenGL
- // ES devices), and thus incur no additional penalty for the switch.
- static const SkScalar kMAX_BLUR_COORD = SkIntToScalar(16000);
- GrSLPrecision precision;
- if (SkScalarAbs(rect.top()) > kMAX_BLUR_COORD ||
- SkScalarAbs(rect.left()) > kMAX_BLUR_COORD ||
- SkScalarAbs(rect.bottom()) > kMAX_BLUR_COORD ||
- SkScalarAbs(rect.right()) > kMAX_BLUR_COORD ||
- SkScalarAbs(rect.width()) > kMAX_BLUR_COORD ||
- SkScalarAbs(rect.height()) > kMAX_BLUR_COORD) {
- precision = kHigh_GrSLPrecision;
- } else {
- precision = kDefault_GrSLPrecision;
- }
-
- return std::unique_ptr<GrFragmentProcessor>(
- new GrRectBlurEffect(rect, sigma, std::move(blurProfile), precision));
- }
-
- std::unique_ptr<GrFragmentProcessor> clone() const override {
- return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(
- fRect, fSigma, sk_ref_sp(fBlurProfileSampler.proxy()), fPrecision));
- }
-
- const SkRect& getRect() const { return fRect; }
- float getSigma() const { return fSigma; }
- GrSLPrecision precision() const { return fPrecision; }
-
-private:
- GrRectBlurEffect(const SkRect& rect, float sigma,
- sk_sp<GrTextureProxy> blurProfile, GrSLPrecision fPrecision);
-
- GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
-
- void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
-
- bool onIsEqual(const GrFragmentProcessor&) const override;
-
- static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrResourceProvider*, float sigma);
-
- SkRect fRect;
- float fSigma;
- TextureSampler fBlurProfileSampler;
- GrSLPrecision fPrecision;
-
- GR_DECLARE_FRAGMENT_PROCESSOR_TEST
-
- typedef GrFragmentProcessor INHERITED;
-};
-
-class GrGLRectBlurEffect : public GrGLSLFragmentProcessor {
-public:
- void emitCode(EmitArgs&) override;
-
- static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b);
-
-protected:
- void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override;
-
-private:
- typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
-
- UniformHandle fProxyRectUniform;
- UniformHandle fProfileSizeUniform;
-
- typedef GrGLSLFragmentProcessor INHERITED;
-};
-
-void OutputRectBlurProfileLookup(GrGLSLFPFragmentBuilder* fragBuilder,
- GrGLSLFragmentProcessor::SamplerHandle sampler,
- const char *output,
- const char *profileSize, const char *loc,
- const char *blurred_width,
- const char *sharp_width) {
- fragBuilder->codeAppendf("half %s;", output);
- fragBuilder->codeAppendf("{");
- fragBuilder->codeAppendf("half coord = ((abs(%s - 0.5 * %s) - 0.5 * %s)) / %s;",
- loc, blurred_width, sharp_width, profileSize);
- fragBuilder->codeAppendf("%s = ", output);
- fragBuilder->appendTextureLookup(sampler, "half2(coord,0.5)");
- fragBuilder->codeAppend(".a;");
- fragBuilder->codeAppendf("}");
-}
-
-
-void GrGLRectBlurEffect::GenKey(const GrProcessor& proc, const GrShaderCaps&,
- GrProcessorKeyBuilder* b) {
- const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>();
-
- b->add32(rbe.precision());
-}
-
-
-void GrGLRectBlurEffect::emitCode(EmitArgs& args) {
- const GrRectBlurEffect& rbe = args.fFp.cast<GrRectBlurEffect>();
-
- GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
-
- const char *rectName;
- const char *profileSizeName;
-
- const char* floatType = rbe.precision() == kHigh_GrSLPrecision ? "float" : "half";
- fProxyRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
- rbe.precision() == kHigh_GrSLPrecision ?
- kFloat4_GrSLType : kHalf4_GrSLType,
- "proxyRect",
- &rectName);
- fProfileSizeUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
- kHalf_GrSLType,
- "profileSize",
- &profileSizeName);
-
- GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
-
- if (args.fInputColor) {
- fragBuilder->codeAppendf("half4 src=%s;", args.fInputColor);
- } else {
- fragBuilder->codeAppendf("half4 src=half4(1);");
- }
-
- fragBuilder->codeAppendf("%s2 translatedPos = sk_FragCoord.xy - %s.xy;", floatType, rectName);
- fragBuilder->codeAppendf("%s width = %s.z - %s.x;", floatType, rectName, rectName);
- fragBuilder->codeAppendf("%s height = %s.w - %s.y;", floatType, rectName, rectName);
-
- fragBuilder->codeAppendf("%s2 smallDims = half2(width - %s, height - %s);", floatType,
- profileSizeName, profileSizeName);
- fragBuilder->codeAppendf("%s center = 2.0 * floor(%s/2.0 + .25) - 1.0;", floatType,
- profileSizeName);
- fragBuilder->codeAppendf("%s2 wh = smallDims - half2(center,center);", floatType);
-
- OutputRectBlurProfileLookup(fragBuilder, args.fTexSamplers[0], "horiz_lookup", profileSizeName,
- "translatedPos.x", "width", "wh.x");
- OutputRectBlurProfileLookup(fragBuilder, args.fTexSamplers[0], "vert_lookup", profileSizeName,
- "translatedPos.y", "height", "wh.y");
-
- fragBuilder->codeAppendf("half final = horiz_lookup * vert_lookup;");
- fragBuilder->codeAppendf("%s = src * final;", args.fOutputColor);
-}
-
-void GrGLRectBlurEffect::onSetData(const GrGLSLProgramDataManager& pdman,
- const GrFragmentProcessor& proc) {
- const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>();
- SkRect rect = rbe.getRect();
-
- pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma()));
-}
-
-sk_sp<GrTextureProxy> GrRectBlurEffect::CreateBlurProfileTexture(
- GrResourceProvider* resourceProvider,
- float sigma) {
- unsigned int profileSize = SkScalarCeilToInt(6*sigma);
-
- static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
- GrUniqueKey key;
- GrUniqueKey::Builder builder(&key, kDomain, 1);
- builder[0] = profileSize;
- builder.finish();
-
- sk_sp<GrTextureProxy> blurProfile(resourceProvider->findOrCreateProxyByUniqueKey(
- key, kTopLeft_GrSurfaceOrigin));
- if (!blurProfile) {
- GrSurfaceDesc texDesc;
- texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
- texDesc.fWidth = profileSize;
- texDesc.fHeight = 1;
- texDesc.fConfig = kAlpha_8_GrPixelConfig;
-
- std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
-
- blurProfile = GrSurfaceProxy::MakeDeferred(resourceProvider,
- texDesc, SkBudgeted::kYes, profile.get(), 0);
- if (!blurProfile) {
- return nullptr;
- }
-
- SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
- resourceProvider->assignUniqueKeyToProxy(key, blurProfile.get());
- }
-
- return blurProfile;
-}
-
-GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma,
- sk_sp<GrTextureProxy> blurProfile,
- GrSLPrecision precision)
- : INHERITED(kGrRectBlurEffect_ClassID, kCompatibleWithCoverageAsAlpha_OptimizationFlag)
- , fRect(rect)
- , fSigma(sigma)
- , fBlurProfileSampler(std::move(blurProfile))
- , fPrecision(precision) {
- this->addTextureSampler(&fBlurProfileSampler);
-}
-
-void GrRectBlurEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const {
- GrGLRectBlurEffect::GenKey(*this, caps, b);
-}
-
-GrGLSLFragmentProcessor* GrRectBlurEffect::onCreateGLSLInstance() const {
- return new GrGLRectBlurEffect;
-}
-
-bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
- const GrRectBlurEffect& s = sBase.cast<GrRectBlurEffect>();
- return this->getSigma() == s.getSigma() && this->getRect() == s.getRect();
-}
-
-GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
-
-#if GR_TEST_UTILS
-std::unique_ptr<GrFragmentProcessor> GrRectBlurEffect::TestCreate(GrProcessorTestData* d) {
- float sigma = d->fRandom->nextRangeF(3,8);
- float width = d->fRandom->nextRangeF(200,300);
- float height = d->fRandom->nextRangeF(200,300);
- return GrRectBlurEffect::Make(d->resourceProvider(),
- SkRect::MakeWH(width, height), sigma);
-}
-#endif
-
bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context,
GrRenderTargetContext* renderTargetContext,
GrPaint&& paint,
diff --git a/src/gpu/effects/GrArithmeticFP.cpp b/src/gpu/effects/GrArithmeticFP.cpp
index bc73b45dc2..fec3fbffad 100644
--- a/src/gpu/effects/GrArithmeticFP.cpp
+++ b/src/gpu/effects/GrArithmeticFP.cpp
@@ -23,6 +23,16 @@ public:
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrArithmeticFP& _outer = args.fFp.cast<GrArithmeticFP>();
(void)_outer;
+ auto k1 = _outer.k1();
+ (void)k1;
+ auto k2 = _outer.k2();
+ (void)k2;
+ auto k3 = _outer.k3();
+ (void)k3;
+ auto k4 = _outer.k4();
+ (void)k4;
+ auto enforcePMColor = _outer.enforcePMColor();
+ (void)enforcePMColor;
fKVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
kDefault_GrSLPrecision, "k");
SkString _child0("_child0");
diff --git a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp
index 551adeac8f..2e42b238ab 100644
--- a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp
+++ b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp
@@ -24,6 +24,8 @@ public:
const GrBlurredEdgeFragmentProcessor& _outer =
args.fFp.cast<GrBlurredEdgeFragmentProcessor>();
(void)_outer;
+ auto mode = _outer.mode();
+ (void)mode;
fragBuilder->codeAppendf(
"half factor = half(1.0 - float(%s.w));\n@switch (%d) {\n case 0:\n "
"factor = half(exp(float(float(-factor * factor) * 4.0)) - "
diff --git a/src/gpu/effects/GrCircleEffect.cpp b/src/gpu/effects/GrCircleEffect.cpp
index 3c0e11b621..b181669d4d 100644
--- a/src/gpu/effects/GrCircleEffect.cpp
+++ b/src/gpu/effects/GrCircleEffect.cpp
@@ -23,6 +23,12 @@ public:
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrCircleEffect& _outer = args.fFp.cast<GrCircleEffect>();
(void)_outer;
+ auto edgeType = _outer.edgeType();
+ (void)edgeType;
+ auto center = _outer.center();
+ (void)center;
+ auto radius = _outer.radius();
+ (void)radius;
prevRadius = -1.0;
fCircleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
kDefault_GrSLPrecision, "circle");
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index 0d2a139816..d8c9044bbb 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -23,6 +23,8 @@ public:
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrConfigConversionEffect& _outer = args.fFp.cast<GrConfigConversionEffect>();
(void)_outer;
+ auto pmConversion = _outer.pmConversion();
+ (void)pmConversion;
fragBuilder->forceHighPrecision();
fragBuilder->codeAppendf(
diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp
index 2498ffc134..88b8bdba9d 100644
--- a/src/gpu/effects/GrDitherEffect.cpp
+++ b/src/gpu/effects/GrDitherEffect.cpp
@@ -23,6 +23,8 @@ public:
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrDitherEffect& _outer = args.fFp.cast<GrDitherEffect>();
(void)_outer;
+ auto rangeType = _outer.rangeType();
+ (void)rangeType;
fragBuilder->codeAppendf(
"half value;\nhalf range;\n@switch (%d) {\n case 0:\n range = "
"0.0039215686274509803;\n break;\n case 1:\n range = "
diff --git a/src/gpu/effects/GrEllipseEffect.cpp b/src/gpu/effects/GrEllipseEffect.cpp
index 8621c9a242..61b8f96c07 100644
--- a/src/gpu/effects/GrEllipseEffect.cpp
+++ b/src/gpu/effects/GrEllipseEffect.cpp
@@ -23,6 +23,12 @@ public:
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrEllipseEffect& _outer = args.fFp.cast<GrEllipseEffect>();
(void)_outer;
+ auto edgeType = _outer.edgeType();
+ (void)edgeType;
+ auto center = _outer.center();
+ (void)center;
+ auto radii = _outer.radii();
+ (void)radii;
prevRadii = half2(-1.0);
useScale = sk_Caps.floatPrecisionVaries;
fEllipseVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
diff --git a/src/gpu/effects/GrRectBlurEffect.cpp b/src/gpu/effects/GrRectBlurEffect.cpp
new file mode 100644
index 0000000000..3b2d8a1927
--- /dev/null
+++ b/src/gpu/effects/GrRectBlurEffect.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * This file was autogenerated from GrRectBlurEffect.fp; do not modify.
+ */
+#include "GrRectBlurEffect.h"
+#if SK_SUPPORT_GPU
+#include "glsl/GrGLSLColorSpaceXformHelper.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLRectBlurEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLRectBlurEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrRectBlurEffect& _outer = args.fFp.cast<GrRectBlurEffect>();
+ (void)_outer;
+ auto rect = _outer.rect();
+ (void)rect;
+ auto sigma = _outer.sigma();
+ (void)sigma;
+ highPrecision = ((((abs(rect.left()) > 16000.0 || abs(rect.top()) > 16000.0) ||
+ abs(rect.right()) > 16000.0) ||
+ abs(rect.bottom()) > 16000.0) ||
+ abs(rect.right() - rect.left()) > 16000.0) ||
+ abs(rect.bottom() - rect.top()) > 16000.0;
+ fRectVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
+ kDefault_GrSLPrecision, "rect");
+ if (!highPrecision) {
+ fProxyRectHalfVar =
+ args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
+ kDefault_GrSLPrecision, "proxyRectHalf");
+ }
+ if (highPrecision) {
+ fProxyRectFloatVar =
+ args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
+ kDefault_GrSLPrecision, "proxyRectFloat");
+ }
+ fProfileSizeVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
+ kDefault_GrSLPrecision, "profileSize");
+ fragBuilder->codeAppendf(
+ "bool highPrecision = %s;\n@if (highPrecision) {\n float2 translatedPos = "
+ "sk_FragCoord.xy - %s.xy;\n float width = %s.z - %s.x;\n float height = %s.w "
+ "- %s.y;\n float2 smallDims = float2(width - float(%s), height - float(%s));\n "
+ " float center = 2.0 * floor(float(float(%s / 2.0) + 0.25)) - 1.0;\n float2 wh "
+ "= smallDims - float2(center, center);\n half hcoord = "
+ "half((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / float(%s));\n half "
+ "hlookup = texture(%s, float2(float(hcoord), 0.5)).%s.w",
+ (highPrecision ? "true" : "false"), args.fUniformHandler->getUniformCStr(fRectVar),
+ args.fUniformHandler->getUniformCStr(fRectVar),
+ args.fUniformHandler->getUniformCStr(fRectVar),
+ args.fUniformHandler->getUniformCStr(fRectVar),
+ args.fUniformHandler->getUniformCStr(fRectVar),
+ args.fUniformHandler->getUniformCStr(fProfileSizeVar),
+ args.fUniformHandler->getUniformCStr(fProfileSizeVar),
+ args.fUniformHandler->getUniformCStr(fProfileSizeVar),
+ args.fUniformHandler->getUniformCStr(fProfileSizeVar),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
+ fragBuilder->codeAppendf(
+ ";\n half vcoord = half((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y) / "
+ "float(%s));\n half vlookup = texture(%s, float2(float(vcoord), 0.5)).%s.w;\n "
+ " %s = (%s * hlookup) * vlookup;\n} else {\n half2 translatedPos = "
+ "half2(sk_FragCoord.xy - %s.xy);\n half width = half(%s.z - %s.x);\n half "
+ "height = half(%s.w - %s.y);\n half2 smallDims = half2(width - %s, height - "
+ "%s);\n half center = half(2.0 * floor(float(float(%s / 2.0) + 0.25)) - 1.0);\n "
+ " half2 wh = smallDims - half2(float2(floa",
+ args.fUniformHandler->getUniformCStr(fProfileSizeVar),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ args.fOutputColor, args.fInputColor ? args.fInputColor : "half4(1)",
+ args.fUniformHandler->getUniformCStr(fRectVar),
+ args.fUniformHandler->getUniformCStr(fRectVar),
+ args.fUniformHandler->getUniformCStr(fRectVar),
+ args.fUniformHandler->getUniformCStr(fRectVar),
+ args.fUniformHandler->getUniformCStr(fRectVar),
+ args.fUniformHandler->getUniformCStr(fProfileSizeVar),
+ args.fUniformHandler->getUniformCStr(fProfileSizeVar),
+ args.fUniformHandler->getUniformCStr(fProfileSizeVar));
+ fragBuilder->codeAppendf(
+ "t(center), float(center)));\n half hcoord = "
+ "half((abs(float(float(translatedPos.x) - 0.5 * float(width))) - 0.5 * "
+ "float(wh.x)) / float(%s));\n half hlookup = texture(%s, float2(float(hcoord), "
+ "0.5)).%s.w;\n half vcoord = half((abs(float(float(translatedPos.y) - 0.5 * "
+ "float(height))) - 0.5 * float(wh.y)) / float(%s));\n half vlookup = "
+ "texture(%s, float2(float(vcoord), 0.5)).%s.w;\n %s = (%s * hlookup) * "
+ "vlookup;\n}\n",
+ args.fUniformHandler->getUniformCStr(fProfileSizeVar),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ args.fUniformHandler->getUniformCStr(fProfileSizeVar),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ args.fOutputColor, args.fInputColor ? args.fInputColor : "half4(1)");
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrRectBlurEffect& _outer = _proc.cast<GrRectBlurEffect>();
+ {
+ const SkRect rectValue = _outer.rect();
+ pdman.set4fv(fRectVar, 1, (float*)&rectValue);
+ }
+ UniformHandle& rect = fRectVar;
+ (void)rect;
+ auto sigma = _outer.sigma();
+ (void)sigma;
+ UniformHandle& blurProfile = fBlurProfileVar;
+ (void)blurProfile;
+ UniformHandle& proxyRectHalf = fProxyRectHalfVar;
+ (void)proxyRectHalf;
+ UniformHandle& proxyRectFloat = fProxyRectFloatVar;
+ (void)proxyRectFloat;
+ UniformHandle& profileSize = fProfileSizeVar;
+ (void)profileSize;
+
+ pdman.set1f(profileSize, SkScalarCeilToScalar(6 * sigma));
+ }
+ bool highPrecision;
+ UniformHandle fProxyRectHalfVar;
+ UniformHandle fProxyRectFloatVar;
+ UniformHandle fProfileSizeVar;
+ UniformHandle fRectVar;
+ UniformHandle fBlurProfileVar;
+};
+GrGLSLFragmentProcessor* GrRectBlurEffect::onCreateGLSLInstance() const {
+ return new GrGLSLRectBlurEffect();
+}
+void GrRectBlurEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrRectBlurEffect& that = other.cast<GrRectBlurEffect>();
+ (void)that;
+ if (fRect != that.fRect) return false;
+ if (fSigma != that.fSigma) return false;
+ if (fBlurProfile != that.fBlurProfile) return false;
+ return true;
+}
+GrRectBlurEffect::GrRectBlurEffect(const GrRectBlurEffect& src)
+ : INHERITED(kGrRectBlurEffect_ClassID, src.optimizationFlags())
+ , fRect(src.fRect)
+ , fSigma(src.fSigma)
+ , fBlurProfile(src.fBlurProfile) {
+ this->addTextureSampler(&fBlurProfile);
+}
+std::unique_ptr<GrFragmentProcessor> GrRectBlurEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(*this));
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrRectBlurEffect::TestCreate(GrProcessorTestData* data) {
+ float sigma = data->fRandom->nextRangeF(3, 8);
+ float width = data->fRandom->nextRangeF(200, 300);
+ float height = data->fRandom->nextRangeF(200, 300);
+ return GrRectBlurEffect::Make(data->resourceProvider(), SkRect::MakeWH(width, height), sigma);
+}
+#endif
+#endif
diff --git a/src/gpu/effects/GrRectBlurEffect.fp b/src/gpu/effects/GrRectBlurEffect.fp
new file mode 100644
index 0000000000..fe5d59ed0b
--- /dev/null
+++ b/src/gpu/effects/GrRectBlurEffect.fp
@@ -0,0 +1,123 @@
+@header {
+ #include "GrResourceProvider.h"
+ #include "../effects/SkBlurMask.h"
+}
+
+in uniform float4 rect;
+in float sigma;
+in uniform sampler2D blurProfile;
+
+// in OpenGL ES, mediump floats have a minimum range of 2^14. If we have coordinates bigger than
+// that, the shader math will end up with infinities and result in the blur effect not working
+// correctly. To avoid this, we switch into highp when the coordinates are too big. As 2^14 is the
+// minimum range but the actual range can be bigger, we might end up switching to highp sooner than
+// strictly necessary, but most devices that have a bigger range for mediump also have mediump being
+// exactly the same as highp (e.g. all non-OpenGL ES devices), and thus incur no additional penalty
+// for the switch.
+layout(key) bool highPrecision = abs(rect.x) > 16000 || abs(rect.y) > 16000 ||
+ abs(rect.z) > 16000 || abs(rect.w) > 16000 ||
+ abs(rect.z - rect.x) > 16000 || abs(rect.w - rect.y) > 16000;
+
+layout(when=!highPrecision) uniform half4 proxyRectHalf;
+layout(when=highPrecision) uniform float4 proxyRectFloat;
+uniform half profileSize;
+
+
+@class {
+ static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrResourceProvider* resourceProvider,
+ float sigma) {
+ unsigned int profileSize = SkScalarCeilToInt(6 * sigma);
+
+ static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
+ GrUniqueKey key;
+ GrUniqueKey::Builder builder(&key, kDomain, 1);
+ builder[0] = profileSize;
+ builder.finish();
+
+ sk_sp<GrTextureProxy> blurProfile(resourceProvider->findOrCreateProxyByUniqueKey(
+ key, kTopLeft_GrSurfaceOrigin));
+ if (!blurProfile) {
+ GrSurfaceDesc texDesc;
+ texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
+ texDesc.fWidth = profileSize;
+ texDesc.fHeight = 1;
+ texDesc.fConfig = kAlpha_8_GrPixelConfig;
+
+ std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
+
+ blurProfile = GrSurfaceProxy::MakeDeferred(resourceProvider,
+ texDesc, SkBudgeted::kYes, profile.get(), 0);
+ if (!blurProfile) {
+ return nullptr;
+ }
+
+ SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
+ resourceProvider->assignUniqueKeyToProxy(key, blurProfile.get());
+ }
+
+ return blurProfile;
+ }
+}
+
+@make {
+ static std::unique_ptr<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider,
+ const SkRect& rect, float sigma) {
+ int doubleProfileSize = SkScalarCeilToInt(12*sigma);
+
+ if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) {
+ // if the blur sigma is too large so the gaussian overlaps the whole
+ // rect in either direction, fall back to CPU path for now.
+ return nullptr;
+ }
+
+ sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(resourceProvider, sigma));
+ if (!blurProfile) {
+ return nullptr;
+ }
+
+ return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(rect, sigma,
+ std::move(blurProfile)));
+ }
+}
+
+void main() {
+ @if (highPrecision) {
+ float2 translatedPos = sk_FragCoord.xy - rect.xy;
+ float width = rect.z - rect.x;
+ float height = rect.w - rect.y;
+ float2 smallDims = float2(width - profileSize, height - profileSize);
+ float center = 2 * floor(profileSize / 2 + 0.25) - 1;
+ float2 wh = smallDims - float2(center, center);
+ half hcoord = ((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x)) / profileSize;
+ half hlookup = texture(blurProfile, float2(hcoord, 0.5)).a;
+ half vcoord = ((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y)) / profileSize;
+ half vlookup = texture(blurProfile, float2(vcoord, 0.5)).a;
+ sk_OutColor = sk_InColor * hlookup * vlookup;
+ } else {
+ half2 translatedPos = sk_FragCoord.xy - rect.xy;
+ half width = rect.z - rect.x;
+ half height = rect.w - rect.y;
+ half2 smallDims = half2(width - profileSize, height - profileSize);
+ half center = 2 * floor(profileSize / 2 + 0.25) - 1;
+ half2 wh = smallDims - float2(center, center);
+ half hcoord = ((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x)) / profileSize;
+ half hlookup = texture(blurProfile, float2(hcoord, 0.5)).a;
+ half vcoord = ((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y)) / profileSize;
+ half vlookup = texture(blurProfile, float2(vcoord, 0.5)).a;
+ sk_OutColor = sk_InColor * hlookup * vlookup;
+ }
+}
+
+@setData(pdman) {
+ pdman.set1f(profileSize, SkScalarCeilToScalar(6 * sigma));
+}
+
+@optimizationFlags { kCompatibleWithCoverageAsAlpha_OptimizationFlag }
+
+@test(data) {
+ float sigma = data->fRandom->nextRangeF(3,8);
+ float width = data->fRandom->nextRangeF(200,300);
+ float height = data->fRandom->nextRangeF(200,300);
+ return GrRectBlurEffect::Make(data->resourceProvider(),
+ SkRect::MakeWH(width, height), sigma);
+}
diff --git a/src/gpu/effects/GrRectBlurEffect.h b/src/gpu/effects/GrRectBlurEffect.h
new file mode 100644
index 0000000000..7a8bc2c005
--- /dev/null
+++ b/src/gpu/effects/GrRectBlurEffect.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * This file was autogenerated from GrRectBlurEffect.fp; do not modify.
+ */
+#ifndef GrRectBlurEffect_DEFINED
+#define GrRectBlurEffect_DEFINED
+#include "SkTypes.h"
+#if SK_SUPPORT_GPU
+
+#include "GrResourceProvider.h"
+#include "../effects/SkBlurMask.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+#include "GrColorSpaceXform.h"
+class GrRectBlurEffect : public GrFragmentProcessor {
+public:
+ static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrResourceProvider* resourceProvider,
+ float sigma) {
+ unsigned int profileSize = SkScalarCeilToInt(6 * sigma);
+
+ static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
+ GrUniqueKey key;
+ GrUniqueKey::Builder builder(&key, kDomain, 1);
+ builder[0] = profileSize;
+ builder.finish();
+
+ sk_sp<GrTextureProxy> blurProfile(
+ resourceProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin));
+ if (!blurProfile) {
+ GrSurfaceDesc texDesc;
+ texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
+ texDesc.fWidth = profileSize;
+ texDesc.fHeight = 1;
+ texDesc.fConfig = kAlpha_8_GrPixelConfig;
+
+ std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
+
+ blurProfile = GrSurfaceProxy::MakeDeferred(resourceProvider, texDesc, SkBudgeted::kYes,
+ profile.get(), 0);
+ if (!blurProfile) {
+ return nullptr;
+ }
+
+ SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
+ resourceProvider->assignUniqueKeyToProxy(key, blurProfile.get());
+ }
+
+ return blurProfile;
+ }
+ SkRect rect() const { return fRect; }
+ float sigma() const { return fSigma; }
+
+ static std::unique_ptr<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider,
+ const SkRect& rect, float sigma) {
+ int doubleProfileSize = SkScalarCeilToInt(12 * sigma);
+
+ if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) {
+ // if the blur sigma is too large so the gaussian overlaps the whole
+ // rect in either direction, fall back to CPU path for now.
+ return nullptr;
+ }
+
+ sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(resourceProvider, sigma));
+ if (!blurProfile) {
+ return nullptr;
+ }
+
+ return std::unique_ptr<GrFragmentProcessor>(
+ new GrRectBlurEffect(rect, sigma, std::move(blurProfile)));
+ }
+ GrRectBlurEffect(const GrRectBlurEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "RectBlurEffect"; }
+
+private:
+ GrRectBlurEffect(SkRect rect, float sigma, sk_sp<GrTextureProxy> blurProfile)
+ : INHERITED(kGrRectBlurEffect_ClassID,
+ (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+ , fRect(rect)
+ , fSigma(sigma)
+ , fBlurProfile(std::move(blurProfile)) {
+ this->addTextureSampler(&fBlurProfile);
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ SkRect fRect;
+ float fSigma;
+ TextureSampler fBlurProfile;
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
+#endif
diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp
index 2c44ce4111..c3634f5739 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.cpp
+++ b/src/gpu/effects/GrSimpleTextureEffect.cpp
@@ -23,6 +23,10 @@ public:
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrSimpleTextureEffect& _outer = args.fFp.cast<GrSimpleTextureEffect>();
(void)_outer;
+ auto colorXform = _outer.colorXform();
+ (void)colorXform;
+ auto matrix = _outer.matrix();
+ (void)matrix;
fColorSpaceHelper.emitCode(args.fUniformHandler, _outer.colorXform().get());
SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fragBuilder->codeAppendf(
diff --git a/src/sksl/SkSLCPP.h b/src/sksl/SkSLCPP.h
index 808e83290f..d67990820b 100644
--- a/src/sksl/SkSLCPP.h
+++ b/src/sksl/SkSLCPP.h
@@ -10,8 +10,11 @@
// functions used by CPP programs created by skslc
+#include <cmath>
#include "SkPoint.h"
+using std::abs;
+
// macros to make sk_Caps.<cap name> work from C++ code
#define sk_Caps (*args.fShaderCaps)
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index a7008400ce..0b2ef78016 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -148,10 +148,15 @@ void CPPCodeGenerator::writeRuntimeValue(const Type& type, const String& cppCode
this->write(type.name() + "(%f, %f)");
fFormatArgs.push_back(cppCode + ".fX");
fFormatArgs.push_back(cppCode + ".fY");
+ } else if (type == *fContext.fFloat4_Type || type == *fContext.fHalf4_Type) {
+ this->write(type.name() + "(%f, %f, %f, %f)");
+ fFormatArgs.push_back(cppCode + ".left()");
+ fFormatArgs.push_back(cppCode + ".top()");
+ fFormatArgs.push_back(cppCode + ".right()");
+ fFormatArgs.push_back(cppCode + ".bottom()");
} else {
- this->write(type.name());
- this->write("\n");
- ABORT("unsupported runtime value type\n");
+ printf("unsupported runtime value type '%s'\n", String(type.fName).c_str());
+ ASSERT(false);
}
}
@@ -180,7 +185,26 @@ void CPPCodeGenerator::writeIntLiteral(const IntLiteral& i) {
this->write(to_string((int32_t) i.fValue));
}
+void CPPCodeGenerator::writeSwizzle(const Swizzle& swizzle) {
+ if (fCPPMode) {
+ ASSERT(swizzle.fComponents.size() == 1); // no support for multiple swizzle components yet
+ this->writeExpression(*swizzle.fBase, kPostfix_Precedence);
+ switch (swizzle.fComponents[0]) {
+ case 0: this->write(".left()"); break;
+ case 1: this->write(".top()"); break;
+ case 2: this->write(".right()"); break;
+ case 3: this->write(".bottom()"); break;
+ }
+ } else {
+ INHERITED::writeSwizzle(swizzle);
+ }
+}
+
void CPPCodeGenerator::writeVariableReference(const VariableReference& ref) {
+ if (fCPPMode) {
+ this->write(ref.fVariable.fName);
+ return;
+ }
switch (ref.fVariable.fModifiers.fLayout.fBuiltin) {
case SK_INCOLOR_BUILTIN:
this->write("%s");
@@ -434,15 +458,22 @@ void CPPCodeGenerator::writePrivateVarValues() {
for (const auto& raw : decls->fVars) {
VarDeclaration& decl = (VarDeclaration&) *raw;
if (is_private(*decl.fVar) && decl.fValue) {
- this->writef("%s = %s;\n",
- String(decl.fVar->fName).c_str(),
- decl.fValue->description().c_str());
+ this->writef("%s = ", String(decl.fVar->fName).c_str());
+ fCPPMode = true;
+ this->writeExpression(*decl.fValue, kAssignment_Precedence);
+ fCPPMode = false;
+ this->write(";\n");
}
}
}
}
}
+static bool is_accessible(const Variable& var) {
+ return Type::kSampler_Kind != var.fType.kind() &&
+ Type::kOther_Kind != var.fType.kind();
+}
+
void CPPCodeGenerator::writeCodeAppend(const String& code) {
// codeAppendf can only handle appending 1024 bytes at a time, so we need to break the string
// into chunks. Unfortunately we can't tell exactly how long the string is going to end up,
@@ -484,6 +515,22 @@ bool CPPCodeGenerator::writeEmitCode(std::vector<const Variable*>& uniforms) {
this->writef(" const %s& _outer = args.fFp.cast<%s>();\n"
" (void) _outer;\n",
fFullName.c_str(), fFullName.c_str());
+ for (const auto& p : fProgram.fElements) {
+ if (ProgramElement::kVar_Kind == p->fKind) {
+ const VarDeclarations* decls = (const VarDeclarations*) p.get();
+ for (const auto& raw : decls->fVars) {
+ VarDeclaration& decl = (VarDeclaration&) *raw;
+ String nameString(decl.fVar->fName);
+ const char* name = nameString.c_str();
+ if (SectionAndParameterHelper::IsParameter(*decl.fVar) &&
+ is_accessible(*decl.fVar)) {
+ this->writef(" auto %s = _outer.%s();\n"
+ " (void) %s;\n",
+ name, name, name);
+ }
+ }
+ }
+ }
this->writePrivateVarValues();
for (const auto u : uniforms) {
this->addUniform(*u);
diff --git a/src/sksl/SkSLCPPCodeGenerator.h b/src/sksl/SkSLCPPCodeGenerator.h
index ea4d030826..a93b885a5c 100644
--- a/src/sksl/SkSLCPPCodeGenerator.h
+++ b/src/sksl/SkSLCPPCodeGenerator.h
@@ -41,6 +41,8 @@ private:
void writeIntLiteral(const IntLiteral& i) override;
+ void writeSwizzle(const Swizzle& swizzle) override;
+
void writeVariableReference(const VariableReference& ref) override;
String getSamplerHandle(const Variable& var);
@@ -87,6 +89,8 @@ private:
std::vector<String> fFormatArgs;
std::set<int> fWrittenTransformedCoords;
bool fNeedColorSpaceHelper = false;
+ // if true, we are writing a C++ expression instead of a GLSL expression
+ bool fCPPMode = false;
typedef GLSLCodeGenerator INHERITED;
};
diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h
index 7c736b35a1..e9a63ac48f 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.h
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -142,7 +142,7 @@ protected:
void writeFieldAccess(const FieldAccess& f);
- void writeSwizzle(const Swizzle& swizzle);
+ virtual void writeSwizzle(const Swizzle& swizzle);
static Precedence GetBinaryPrecedence(Token::Kind op);
diff --git a/src/sksl/ir/SkSLLayout.h b/src/sksl/ir/SkSLLayout.h
index 8bf0472a95..dc676280d6 100644
--- a/src/sksl/ir/SkSLLayout.h
+++ b/src/sksl/ir/SkSLLayout.h
@@ -232,18 +232,6 @@ struct Layout {
result += separator + "when = " + fWhen;
separator = ", ";
}
- switch (fKey) {
- case kNo_Key:
- break;
- case kKey_Key:
- result += separator + "key";
- separator = ", ";
- break;
- case kIdentity_Key:
- result += separator + "key=identity";
- separator = ", ";
- break;
- }
if (result.size() > 0) {
result = "layout (" + result + ")";
}