aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Ethan Nicholas <ethannicholas@google.com>2017-02-09 17:01:22 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-13 14:49:09 +0000
commit3865711259e25a90a1d72480f848863ada202067 (patch)
tree4fc40848238f7d38123fa19032513751923e6bea
parentb34727f1a3150de2e3e95beb79900a0a848a984c (diff)
Replaced all calls to fragmentPosition() with sk_FragCoord
Change-Id: I2ed4558aea74b3ae7ee11dfe4736cdbcb16ae49e Reviewed-on: https://skia-review.googlesource.com/8278 Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
-rw-r--r--include/gpu/GrProcessor.h4
-rw-r--r--src/effects/GrCircleBlurFragmentProcessor.cpp8
-rw-r--r--src/effects/SkBlurMaskFilter.cpp10
-rw-r--r--src/effects/SkLightingImageFilter.cpp16
-rw-r--r--src/effects/SkRRectsGaussianEdgeMaskFilter.cpp5
-rw-r--r--src/gpu/GrProgramDesc.cpp7
-rw-r--r--src/gpu/GrProgramDesc.h6
-rw-r--r--src/gpu/GrXferProcessor.cpp1
-rw-r--r--src/gpu/effects/GrConvexPolyEffect.cpp29
-rw-r--r--src/gpu/effects/GrDitherEffect.cpp9
-rw-r--r--src/gpu/effects/GrOvalEffect.cpp16
-rw-r--r--src/gpu/effects/GrRRectEffect.cpp94
-rw-r--r--src/gpu/effects/GrTextureDomain.cpp5
-rw-r--r--src/gpu/gl/GrGLGpuProgramCache.cpp9
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp12
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h7
-rw-r--r--src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp5
-rw-r--r--src/gpu/glsl/GrGLSLFragmentShaderBuilder.h6
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.cpp4
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.h8
-rw-r--r--src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp4
-rw-r--r--src/gpu/glsl/GrGLSLXferProcessor.cpp5
-rw-r--r--src/gpu/ops/GrDrawOp.h3
-rw-r--r--src/gpu/ops/GrPLSPathRenderer.cpp8
-rw-r--r--src/gpu/vk/GrVkPipelineStateBuilder.cpp22
-rw-r--r--src/gpu/vk/GrVkPipelineStateBuilder.h11
-rw-r--r--src/gpu/vk/GrVkPipelineStateCache.cpp9
-rw-r--r--src/sksl/README4
-rw-r--r--src/sksl/SkSLIRGenerator.cpp13
-rw-r--r--src/sksl/ir/SkSLProgram.h9
-rw-r--r--tests/ImageStorageTest.cpp4
-rw-r--r--tests/SkSLErrorTest.cpp9
32 files changed, 184 insertions, 178 deletions
diff --git a/include/gpu/GrProcessor.h b/include/gpu/GrProcessor.h
index fa6574dc8d..388bd54092 100644
--- a/include/gpu/GrProcessor.h
+++ b/include/gpu/GrProcessor.h
@@ -105,8 +105,7 @@ public:
*/
enum RequiredFeatures {
kNone_RequiredFeatures = 0,
- kFragmentPosition_RequiredFeature = 1 << 0,
- kSampleLocations_RequiredFeature = 1 << 1
+ kSampleLocations_RequiredFeature = 1 << 0
};
GR_DECL_BITFIELD_OPS_FRIENDS(RequiredFeatures);
@@ -148,7 +147,6 @@ protected:
* must call these methods from its constructor. Otherwise, requests to use these features will
* be denied.
*/
- void setWillReadFragmentPosition() { fRequiredFeatures |= kFragmentPosition_RequiredFeature; }
void setWillUseSampleLocations() { fRequiredFeatures |= kSampleLocations_RequiredFeature; }
void combineRequiredFeatures(const GrProcessor& other) {
diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp
index d161195a64..c54a71c809 100644
--- a/src/effects/GrCircleBlurFragmentProcessor.cpp
+++ b/src/effects/GrCircleBlurFragmentProcessor.cpp
@@ -47,7 +47,6 @@ void GrCircleBlurFragmentProcessor::GLSLProcessor::emitCode(EmitArgs& args) {
&dataName);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- const char *fragmentPos = fragBuilder->fragmentPosition();
if (args.fInputColor) {
fragBuilder->codeAppendf("vec4 src=%s;", args.fInputColor);
@@ -57,9 +56,9 @@ void GrCircleBlurFragmentProcessor::GLSLProcessor::emitCode(EmitArgs& args) {
// We just want to compute "(length(vec) - %s.z + 0.5) * %s.w" but need to rearrange
// for precision.
- fragBuilder->codeAppendf("vec2 vec = vec2( (%s.x - %s.x) * %s.w , (%s.y - %s.y) * %s.w );",
- fragmentPos, dataName, dataName,
- fragmentPos, dataName, dataName);
+ fragBuilder->codeAppendf("vec2 vec = vec2( (sk_FragCoord.x - %s.x) * %s.w, "
+ "(sk_FragCoord.y - %s.y) * %s.w );",
+ dataName, dataName, dataName, dataName);
fragBuilder->codeAppendf("float dist = length(vec) + (0.5 - %s.z) * %s.w;",
dataName, dataName);
@@ -96,7 +95,6 @@ GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(const SkRect& circl
, fBlurProfileSampler(blurProfile, GrSamplerParams::kBilerp_FilterMode) {
this->initClassID<GrCircleBlurFragmentProcessor>();
this->addTextureSampler(&fBlurProfileSampler);
- this->setWillReadFragmentPosition();
}
GrGLSLFragmentProcessor* GrCircleBlurFragmentProcessor::onCreateGLSLInstance() const {
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 225d6f67cc..f41648dc4b 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -904,7 +904,6 @@ void GrGLRectBlurEffect::emitCode(EmitArgs& args) {
&profileSizeName);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- const char *fragmentPos = fragBuilder->fragmentPosition();
if (args.fInputColor) {
fragBuilder->codeAppendf("vec4 src=%s;", args.fInputColor);
@@ -912,8 +911,8 @@ void GrGLRectBlurEffect::emitCode(EmitArgs& args) {
fragBuilder->codeAppendf("vec4 src=vec4(1);");
}
- fragBuilder->codeAppendf("%s vec2 translatedPos = %s.xy - %s.xy;", precisionString.c_str(),
- fragmentPos, rectName);
+ fragBuilder->codeAppendf("%s vec2 translatedPos = sk_FragCoord.xy - %s.xy;",
+ precisionString.c_str(), rectName);
fragBuilder->codeAppendf("%s float width = %s.z - %s.x;", precisionString.c_str(), rectName,
rectName);
fragBuilder->codeAppendf("%s float height = %s.w - %s.y;", precisionString.c_str(), rectName,
@@ -984,7 +983,6 @@ GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture* b
, fPrecision(precision) {
this->initClassID<GrRectBlurEffect>();
this->addTextureSampler(&fBlurProfileSampler);
- this->setWillReadFragmentPosition();
}
void GrRectBlurEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
@@ -1218,7 +1216,6 @@ GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
, fNinePatchSampler(ninePatchTexture) {
this->initClassID<GrRRectBlurEffect>();
this->addTextureSampler(&fNinePatchSampler);
- this->setWillReadFragmentPosition();
}
bool GrRRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const {
@@ -1286,12 +1283,11 @@ void GrGLRRectBlurEffect::emitCode(EmitArgs& args) {
&blurRadiusName);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- const char* fragmentPos = fragBuilder->fragmentPosition();
// warp the fragment position to the appropriate part of the 9patch blur texture
fragBuilder->codeAppendf("vec2 rectCenter = (%s.xy + %s.zw)/2.0;", rectName, rectName);
- fragBuilder->codeAppendf("vec2 translatedFragPos = %s.xy - %s.xy;", fragmentPos, rectName);
+ fragBuilder->codeAppendf("vec2 translatedFragPos = sk_FragCoord.xy - %s.xy;", rectName);
fragBuilder->codeAppendf("float threshold = %s + 2.0*%s;", cornerRadiusName, blurRadiusName);
fragBuilder->codeAppendf("vec2 middle = %s.zw - %s.xy - 2.0*threshold;", rectName, rectName);
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 92057f0802..fc7b29b490 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -770,8 +770,6 @@ public:
virtual bool isEqual(const SkImageFilterLight& other) const {
return fColor == other.fColor;
}
- // Called to know whether the generated GrGLLight will require access to the fragment position.
- virtual bool requiresFragmentPosition() const = 0;
virtual SkImageFilterLight* transform(const SkMatrix& matrix) const = 0;
// Defined below SkLight's subclasses.
@@ -820,7 +818,6 @@ public:
return nullptr;
#endif
}
- bool requiresFragmentPosition() const override { return false; }
bool isEqual(const SkImageFilterLight& other) const override {
if (other.type() != kDistant_LightType) {
@@ -879,7 +876,6 @@ public:
return nullptr;
#endif
}
- bool requiresFragmentPosition() const override { return true; }
bool isEqual(const SkImageFilterLight& other) const override {
if (other.type() != kPoint_LightType) {
return false;
@@ -993,7 +989,6 @@ public:
return nullptr;
#endif
}
- bool requiresFragmentPosition() const override { return true; }
LightType type() const override { return kSpot_LightType; }
const SkPoint3& location() const { return fLocation; }
const SkPoint3& target() const { return fTarget; }
@@ -1715,9 +1710,6 @@ GrLightingEffect::GrLightingEffect(GrTexture* texture,
, fBoundaryMode(boundaryMode)
, fDomain(create_domain(texture, srcBounds, GrTextureDomain::kDecal_Mode)) {
fLight->ref();
- if (light->requiresFragmentPosition()) {
- this->setWillReadFragmentPosition();
- }
}
GrLightingEffect::~GrLightingEffect() {
@@ -2102,8 +2094,8 @@ void GrGLPointLight::emitSurfaceToLight(GrGLSLUniformHandler* uniformHandler,
fLocationUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec3f_GrSLType, kDefault_GrSLPrecision,
"LightLocation", &loc);
- fragBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))",
- loc, fragBuilder->fragmentPosition(), z);
+ fragBuilder->codeAppendf("normalize(%s - vec3(sk_FragCoord.xy, %s))",
+ loc, z);
}
///////////////////////////////////////////////////////////////////////////////
@@ -2129,8 +2121,8 @@ void GrGLSpotLight::emitSurfaceToLight(GrGLSLUniformHandler* uniformHandler,
kVec3f_GrSLType, kDefault_GrSLPrecision,
"LightLocation", &location);
- fragBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))",
- location, fragBuilder->fragmentPosition(), z);
+ fragBuilder->codeAppendf("normalize(%s - vec3(sk_FragCoord.xy, %s))",
+ location, z);
}
void GrGLSpotLight::emitLightColor(GrGLSLUniformHandler* uniformHandler,
diff --git a/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp b/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp
index f6b2ce31b5..223887bab9 100644
--- a/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp
+++ b/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp
@@ -209,7 +209,6 @@ public:
RRectsGaussianEdgeFP(const SkRRect& first, const SkRRect& second, SkScalar radius)
: INHERITED(kNone_OptimizationFlags), fFirst(first), fSecond(second), fRadius(radius) {
this->initClassID<RRectsGaussianEdgeFP>();
- this->setWillReadFragmentPosition();
fFirstMode = ComputeMode(fFirst);
fSecondMode = ComputeMode(fSecond);
@@ -233,8 +232,8 @@ public:
// Positive distance is towards the center of the circle.
// Map all the cases to the lower right quadrant.
- fragBuilder->codeAppendf("vec2 delta = abs(%s.xy - %s.%s);",
- fragBuilder->fragmentPosition(), posName, indices);
+ fragBuilder->codeAppendf("vec2 delta = abs(sk_FragCoord.xy - %s.%s);",
+ posName, indices);
switch (mode) {
case kCircle_Mode:
diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp
index 87a4a275d7..d17c187033 100644
--- a/src/gpu/GrProgramDesc.cpp
+++ b/src/gpu/GrProgramDesc.cpp
@@ -197,13 +197,6 @@ bool GrProgramDesc::Build(GrProgramDesc* desc,
GrRenderTarget* rt = pipeline.getRenderTarget();
- if (requiredFeatures & (GrProcessor::kFragmentPosition_RequiredFeature |
- GrProcessor::kSampleLocations_RequiredFeature)) {
- header->fSurfaceOriginKey = GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(rt->origin());
- } else {
- header->fSurfaceOriginKey = 0;
- }
-
if (requiredFeatures & GrProcessor::kSampleLocations_RequiredFeature) {
SkASSERT(pipeline.isHWAntialiasState());
header->fSamplePatternKey =
diff --git a/src/gpu/GrProgramDesc.h b/src/gpu/GrProgramDesc.h
index 2a26f2d1c0..a20cdfc56b 100644
--- a/src/gpu/GrProgramDesc.h
+++ b/src/gpu/GrProgramDesc.h
@@ -12,6 +12,7 @@
#include "GrTypesPriv.h"
#include "SkOpts.h"
#include "SkTArray.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
class GrShaderCaps;
class GrPipeline;
@@ -80,6 +81,11 @@ public:
return !(*this == other);
}
+ void setSurfaceOriginKey(int key) {
+ KeyHeader* header = this->atOffset<KeyHeader, kHeaderOffset>();
+ header->fSurfaceOriginKey = key;
+ }
+
static bool Less(const GrProgramDesc& a, const GrProgramDesc& b) {
SkASSERT(SkIsAlign4(a.keyLength()));
int l = a.keyLength() >> 2;
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp
index 9e7948c415..bc90f99ec7 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -27,7 +27,6 @@ GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture,
fDstTexture.reset(dstTexture->texture());
fDstTextureOffset = dstTexture->offset();
this->addTextureSampler(&fDstTexture);
- this->setWillReadFragmentPosition();
}
}
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index da77eb8c05..db8c2d999e 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -34,7 +34,6 @@ private:
AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect)
: INHERITED(kModulatesInput_OptimizationFlag), fRect(rect), fEdgeType(edgeType) {
this->initClassID<AARectEffect>();
- this->setWillReadFragmentPosition();
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
@@ -115,24 +114,27 @@ void GLAARectEffect::emitCode(EmitArgs& args) {
&rectName);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- const char* fragmentPos = fragBuilder->fragmentPosition();
if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) {
// The amount of coverage removed in x and y by the edges is computed as a pair of negative
// numbers, xSub and ySub.
fragBuilder->codeAppend("\t\tfloat xSub, ySub;\n");
- fragBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName);
- fragBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
- fragBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName);
- fragBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
+ fragBuilder->codeAppendf("\t\txSub = min(sk_FragCoord.x - %s.x, 0.0);\n", rectName);
+ fragBuilder->codeAppendf("\t\txSub += min(%s.z - sk_FragCoord.x, 0.0);\n", rectName);
+ fragBuilder->codeAppendf("\t\tySub = min(sk_FragCoord.y - %s.y, 0.0);\n", rectName);
+ fragBuilder->codeAppendf("\t\tySub += min(%s.w - sk_FragCoord.y, 0.0);\n", rectName);
// Now compute coverage in x and y and multiply them to get the fraction of the pixel
// covered.
fragBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
} else {
fragBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
- fragBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
- fragBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
- fragBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
- fragBuilder->codeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
+ fragBuilder->codeAppendf("\t\talpha *= (sk_FragCoord.x - %s.x) > -0.5 ? 1.0 : 0.0;\n",
+ rectName);
+ fragBuilder->codeAppendf("\t\talpha *= (%s.z - sk_FragCoord.x) > -0.5 ? 1.0 : 0.0;\n",
+ rectName);
+ fragBuilder->codeAppendf("\t\talpha *= (sk_FragCoord.y - %s.y) > -0.5 ? 1.0 : 0.0;\n",
+ rectName);
+ fragBuilder->codeAppendf("\t\talpha *= (%s.w - sk_FragCoord.y) > -0.5 ? 1.0 : 0.0;\n",
+ rectName);
}
if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) {
@@ -201,10 +203,10 @@ void GrGLConvexPolyEffect::emitCode(EmitArgs& args) {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppend("\t\tfloat alpha = 1.0;\n");
fragBuilder->codeAppend("\t\tfloat edge;\n");
- const char* fragmentPos = fragBuilder->fragmentPosition();
for (int i = 0; i < cpe.getEdgeCount(); ++i) {
- fragBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
- edgeArrayName, i, fragmentPos, fragmentPos);
+ fragBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(sk_FragCoord.x, sk_FragCoord.y, "
+ "1));\n",
+ edgeArrayName, i);
if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) {
fragBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
} else {
@@ -349,7 +351,6 @@ GrConvexPolyEffect::GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, cons
for (int i = 0; i < n; ++i) {
fEdges[3 * i + 2] += SK_ScalarHalf;
}
- this->setWillReadFragmentPosition();
}
bool GrConvexPolyEffect::onIsEqual(const GrFragmentProcessor& other) const {
diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp
index a2394aacee..34a15651d2 100644
--- a/src/gpu/effects/GrDitherEffect.cpp
+++ b/src/gpu/effects/GrDitherEffect.cpp
@@ -26,10 +26,7 @@ public:
const char* name() const override { return "Dither"; }
private:
- DitherEffect() : INHERITED(kNone_OptimizationFlags) {
- this->initClassID<DitherEffect>();
- this->setWillReadFragmentPosition();
- }
+ DitherEffect() : INHERITED(kNone_OptimizationFlags) { this->initClassID<DitherEffect>(); }
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
@@ -81,8 +78,8 @@ void GLDitherEffect::emitCode(EmitArgs& args) {
// For each channel c, add the random offset to the pixel to either bump
// it up or let it remain constant during quantization.
fragBuilder->codeAppendf("\t\tfloat r = "
- "fract(sin(dot(%s.xy ,vec2(12.9898,78.233))) * 43758.5453);\n",
- fragBuilder->fragmentPosition());
+ "fract(sin(dot(sk_FragCoord.xy, vec2(12.9898,78.233))) * "
+ "43758.5453);\n");
fragBuilder->codeAppendf("\t\t%s = (1.0/255.0) * vec4(r, r, r, r) + %s;\n",
args.fOutputColor, GrGLSLExpr4(args.fInputColor).c_str());
}
diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp
index 6ad6e7b988..b64ac56859 100644
--- a/src/gpu/effects/GrOvalEffect.cpp
+++ b/src/gpu/effects/GrOvalEffect.cpp
@@ -66,7 +66,6 @@ void CircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
CircleEffect::CircleEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar r)
: INHERITED(kModulatesInput_OptimizationFlag), fCenter(c), fRadius(r), fEdgeType(edgeType) {
this->initClassID<CircleEffect>();
- this->setWillReadFragmentPosition();
}
bool CircleEffect::onIsEqual(const GrFragmentProcessor& other) const {
@@ -124,7 +123,6 @@ void GLCircleEffect::emitCode(EmitArgs& args) {
&circleName);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- const char* fragmentPos = fragBuilder->fragmentPosition();
SkASSERT(kHairlineAA_GrProcessorEdgeType != ce.getEdgeType());
// TODO: Right now the distance to circle caclulation is performed in a space normalized to the
@@ -132,11 +130,13 @@ void GLCircleEffect::emitCode(EmitArgs& args) {
// mediump. It'd be nice to only to this on mediump devices but we currently don't have the
// caps here.
if (GrProcessorEdgeTypeIsInverseFill(ce.getEdgeType())) {
- fragBuilder->codeAppendf("float d = (length((%s.xy - %s.xy) * %s.w) - 1.0) * %s.z;",
- circleName, fragmentPos, circleName, circleName);
+ fragBuilder->codeAppendf("float d = (length((%s.xy - sk_FragCoord.xy) * %s.w) - 1.0) * "
+ "%s.z;",
+ circleName, circleName, circleName);
} else {
- fragBuilder->codeAppendf("float d = (1.0 - length((%s.xy - %s.xy) * %s.w)) * %s.z;",
- circleName, fragmentPos, circleName, circleName);
+ fragBuilder->codeAppendf("float d = (1.0 - length((%s.xy - sk_FragCoord.xy) * %s.w)) * "
+ "%s.z;",
+ circleName, circleName, circleName);
}
if (GrProcessorEdgeTypeIsAA(ce.getEdgeType())) {
fragBuilder->codeAppend("d = clamp(d, 0.0, 1.0);");
@@ -237,7 +237,6 @@ EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkS
, fRadii(SkVector::Make(rx, ry))
, fEdgeType(edgeType) {
this->initClassID<EllipseEffect>();
- this->setWillReadFragmentPosition();
}
bool EllipseEffect::onIsEqual(const GrFragmentProcessor& other) const {
@@ -309,10 +308,9 @@ void GLEllipseEffect::emitCode(EmitArgs& args) {
}
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- const char* fragmentPos = fragBuilder->fragmentPosition();
// d is the offset to the ellipse center
- fragBuilder->codeAppendf("vec2 d = %s.xy - %s.xy;", fragmentPos, ellipseName);
+ fragBuilder->codeAppendf("vec2 d = sk_FragCoord.xy - %s.xy;", ellipseName);
if (scaleName) {
fragBuilder->codeAppendf("d *= %s.y;", scaleName);
}
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 468deae547..dabf11ae8d 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -100,7 +100,6 @@ CircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t
, fEdgeType(edgeType)
, fCircularCornerFlags(circularCornerFlags) {
this->initClassID<CircularRRectEffect>();
- this->setWillReadFragmentPosition();
}
bool CircularRRectEffect::onIsEqual(const GrFragmentProcessor& other) const {
@@ -181,7 +180,6 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
}
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- const char* fragmentPos = fragBuilder->fragmentPosition();
// At each quarter-circle corner we compute a vector that is the offset of the fragment position
// from the circle center. The vector is pinned in x and y to be in the quarter-plane relevant
// to that corner. This means that points near the interior near the rrect top edge will have
@@ -199,84 +197,86 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
// alphas together.
switch (crre.getCircularCornerFlags()) {
case CircularRRectEffect::kAll_CornerFlags:
- fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - %s.xy;", rectName, fragmentPos);
- fragBuilder->codeAppendf("vec2 dxy1 = %s.xy - %s.zw;", fragmentPos, rectName);
+ fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
+ fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
fragBuilder->codeAppend("vec2 dxy = max(max(dxy0, dxy1), 0.0);");
fragBuilder->codeAppendf("float alpha = %s;", clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTopLeft_CornerFlag:
- fragBuilder->codeAppendf("vec2 dxy = max(%s.xy - %s.xy, 0.0);",
- rectName, fragmentPos);
- fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);",
- rectName, fragmentPos);
- fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);",
- rectName, fragmentPos);
+ fragBuilder->codeAppendf("vec2 dxy = max(%s.xy - sk_FragCoord.xy, 0.0);",
+ rectName);
+ fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
+ rectName);
+ fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
+ rectName);
fragBuilder->codeAppendf("float alpha = bottomAlpha * rightAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTopRight_CornerFlag:
- fragBuilder->codeAppendf("vec2 dxy = max(vec2(%s.x - %s.z, %s.y - %s.y), 0.0);",
- fragmentPos, rectName, rectName, fragmentPos);
- fragBuilder->codeAppendf("float leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);",
- fragmentPos, rectName);
- fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);",
- rectName, fragmentPos);
+ fragBuilder->codeAppendf("vec2 dxy = max(vec2(sk_FragCoord.x - %s.z, "
+ "%s.y - sk_FragCoord.y), 0.0);",
+ rectName, rectName);
+ fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
+ rectName);
+ fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
+ rectName);
fragBuilder->codeAppendf("float alpha = bottomAlpha * leftAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottomRight_CornerFlag:
- fragBuilder->codeAppendf("vec2 dxy = max(%s.xy - %s.zw, 0.0);",
- fragmentPos, rectName);
- fragBuilder->codeAppendf("float leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);",
- fragmentPos, rectName);
- fragBuilder->codeAppendf("float topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);",
- fragmentPos, rectName);
+ fragBuilder->codeAppendf("vec2 dxy = max(sk_FragCoord.xy - %s.zw, 0.0);",
+ rectName);
+ fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
+ rectName);
+ fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
+ rectName);
fragBuilder->codeAppendf("float alpha = topAlpha * leftAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottomLeft_CornerFlag:
- fragBuilder->codeAppendf("vec2 dxy = max(vec2(%s.x - %s.x, %s.y - %s.w), 0.0);",
- rectName, fragmentPos, fragmentPos, rectName);
- fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);",
- rectName, fragmentPos);
- fragBuilder->codeAppendf("float topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);",
- fragmentPos, rectName);
+ fragBuilder->codeAppendf("vec2 dxy = max(vec2(%s.x - sk_FragCoord.x, sk_FragCoord.y - "
+ "%s.w), 0.0);",
+ rectName, rectName);
+ fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
+ rectName);
+ fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
+ rectName);
fragBuilder->codeAppendf("float alpha = topAlpha * rightAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kLeft_CornerFlags:
- fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - %s.xy;", rectName, fragmentPos);
- fragBuilder->codeAppendf("float dy1 = %s.y - %s.w;", fragmentPos, rectName);
+ fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
+ fragBuilder->codeAppendf("float dy1 = sk_FragCoord.y - %s.w;", rectName);
fragBuilder->codeAppend("vec2 dxy = max(vec2(dxy0.x, max(dxy0.y, dy1)), 0.0);");
- fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);",
- rectName, fragmentPos);
+ fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
+ rectName);
fragBuilder->codeAppendf("float alpha = rightAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTop_CornerFlags:
- fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - %s.xy;", rectName, fragmentPos);
- fragBuilder->codeAppendf("float dx1 = %s.x - %s.z;", fragmentPos, rectName);
+ fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
+ fragBuilder->codeAppendf("float dx1 = sk_FragCoord.x - %s.z;", rectName);
fragBuilder->codeAppend("vec2 dxy = max(vec2(max(dxy0.x, dx1), dxy0.y), 0.0);");
- fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);",
- rectName, fragmentPos);
+ fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
+ rectName);
fragBuilder->codeAppendf("float alpha = bottomAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kRight_CornerFlags:
- fragBuilder->codeAppendf("float dy0 = %s.y - %s.y;", rectName, fragmentPos);
- fragBuilder->codeAppendf("vec2 dxy1 = %s.xy - %s.zw;", fragmentPos, rectName);
+ fragBuilder->codeAppendf("float dy0 = %s.y - sk_FragCoord.y;", rectName);
+ fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
fragBuilder->codeAppend("vec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1.y)), 0.0);");
- fragBuilder->codeAppendf("float leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);",
- fragmentPos, rectName);
+ fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
+ rectName);
fragBuilder->codeAppendf("float alpha = leftAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottom_CornerFlags:
- fragBuilder->codeAppendf("float dx0 = %s.x - %s.x;", rectName, fragmentPos);
- fragBuilder->codeAppendf("vec2 dxy1 = %s.xy - %s.zw;", fragmentPos, rectName);
+ fragBuilder->codeAppendf("float dx0 = %s.x - sk_FragCoord.x;", rectName);
+ fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
fragBuilder->codeAppend("vec2 dxy = max(vec2(max(dx0, dxy1.x), dxy1.y), 0.0);");
- fragBuilder->codeAppendf("float topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);",
- fragmentPos, rectName);
+ fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
+ rectName);
fragBuilder->codeAppendf("float alpha = topAlpha * %s;",
clampedCircleDistance.c_str());
break;
@@ -436,7 +436,6 @@ void EllipticalRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) c
EllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const SkRRect& rrect)
: INHERITED(kModulatesInput_OptimizationFlag), fRRect(rrect), fEdgeType(edgeType) {
this->initClassID<EllipticalRRectEffect>();
- this->setWillReadFragmentPosition();
}
bool EllipticalRRectEffect::onIsEqual(const GrFragmentProcessor& other) const {
@@ -520,7 +519,6 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
&rectName);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- const char* fragmentPos = fragBuilder->fragmentPosition();
// At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos
// to the ellipse center. The vector is pinned in x and y to be in the quarter-plane relevant
// to that corner. This means that points near the interior near the rrect top edge will have
@@ -533,8 +531,8 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
// The code below is a simplified version of the above that performs maxs on the vector
// components before computing distances and alpha values so that only one distance computation
// need be computed to determine the min alpha.
- fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - %s.xy;", rectName, fragmentPos);
- fragBuilder->codeAppendf("vec2 dxy1 = %s.xy - %s.zw;", fragmentPos, rectName);
+ fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
+ fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
// If we're on a device with a "real" mediump then we'll do the distance computation in a space
// that is normalized by the largest radius. The scale uniform will be scale, 1/scale. The
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index aa449d4052..58707f5744 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -419,7 +419,6 @@ GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentPro
fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft;
fDeviceSpaceOffset.fY = deviceSpaceOffset.fY - subset.fTop;
this->initClassID<GrDeviceSpaceTextureDecalFragmentProcessor>();
- this->setWillReadFragmentPosition();
}
sk_sp<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::Make(
@@ -444,7 +443,6 @@ GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentPro
fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft;
fDeviceSpaceOffset.fY = deviceSpaceOffset.fY - subset.fTop;
this->initClassID<GrDeviceSpaceTextureDecalFragmentProcessor>();
- this->setWillReadFragmentPosition();
}
GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLSLInstance() const {
@@ -459,8 +457,7 @@ GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLS
kDefault_GrSLPrecision,
"scaleAndTranslate",
&scaleAndTranslateName);
- args.fFragBuilder->codeAppendf("vec2 coords = %s.xy * %s.xy + %s.zw;",
- args.fFragBuilder->fragmentPosition(),
+ args.fFragBuilder->codeAppendf("vec2 coords = sk_FragCoord.xy * %s.xy + %s.zw;",
scaleAndTranslateName, scaleAndTranslateName);
fGLDomain.sampleTexture(args.fFragBuilder,
args.fUniformHandler,
diff --git a/src/gpu/gl/GrGLGpuProgramCache.cpp b/src/gpu/gl/GrGLGpuProgramCache.cpp
index c1ca16096a..2ff5dc79b4 100644
--- a/src/gpu/gl/GrGLGpuProgramCache.cpp
+++ b/src/gpu/gl/GrGLGpuProgramCache.cpp
@@ -81,11 +81,18 @@ GrGLProgram* GrGLGpu::ProgramCache::refProgram(const GrGLGpu* gpu,
desc.finalize();
std::unique_ptr<Entry>* entry = fMap.find(desc);
if (!entry) {
+ // Didn't find an origin-independent version, check with the specific origin
+ GrSurfaceOrigin origin = pipeline.getRenderTarget()->origin();
+ desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
+ desc.finalize();
+ entry = fMap.find(desc);
+ }
+ if (!entry) {
// We have a cache miss
#ifdef PROGRAM_CACHE_STATS
++fCacheMisses;
#endif
- GrGLProgram* program = GrGLProgramBuilder::CreateProgram(pipeline, primProc, desc, fGpu);
+ GrGLProgram* program = GrGLProgramBuilder::CreateProgram(pipeline, primProc, &desc, fGpu);
if (nullptr == program) {
return nullptr;
}
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index c3e81fb358..4f1909eecf 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -30,7 +30,7 @@
GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
- const GrProgramDesc& desc,
+ GrProgramDesc* desc,
GrGLGpu* gpu) {
GrAutoLocaleSetter als("C");
@@ -56,7 +56,7 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrPipeline& pipeline,
GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu,
const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
- const GrProgramDesc& desc)
+ GrProgramDesc* desc)
: INHERITED(pipeline, primProc, desc)
, fGpu(gpu)
, fVaryingHandler(this)
@@ -89,6 +89,12 @@ bool GrGLProgramBuilder::compileAndAttachShaders(GrGLSLShaderBuilder& shader,
}
*shaderIds->append() = shaderId;
+ if (outInputs->fFlipY) {
+ GrProgramDesc* d = this->desc();
+ d->setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(
+ this->pipeline().getRenderTarget()->origin()));
+ d->finalize();
+ }
return true;
}
@@ -244,7 +250,7 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
return new GrGLProgram(fGpu,
- this->desc(),
+ *this->desc(),
fUniformHandles,
programID,
fUniformHandler.fUniforms,
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 84d6d91a57..cfbb734155 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -29,11 +29,14 @@ public:
* The program implements what is specified in the stages given as input.
* After successful generation, the builder result objects are available
* to be used.
+ * This function may modify the GrProgramDesc by setting the surface origin
+ * key to 0 (unspecified) if it turns out the program does not care about
+ * the surface origin.
* @return true if generation was successful.
*/
static GrGLProgram* CreateProgram(const GrPipeline&,
const GrPrimitiveProcessor&,
- const GrProgramDesc&,
+ GrProgramDesc*,
GrGLGpu*);
const GrCaps* caps() const override;
@@ -42,7 +45,7 @@ public:
private:
GrGLProgramBuilder(GrGLGpu*, const GrPipeline&, const GrPrimitiveProcessor&,
- const GrProgramDesc&);
+ GrProgramDesc*);
bool compileAndAttachShaders(GrGLSLShaderBuilder& shader,
GrGLuint programId,
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index 7ef734876c..f583420f29 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -130,11 +130,6 @@ SkString GrGLSLFragmentShaderBuilder::ensureCoords2D(const GrShaderVar& coords)
return coords2D;
}
-const char* GrGLSLFragmentShaderBuilder::fragmentPosition() {
- SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kFragmentPosition_RequiredFeature;)
- return "sk_FragCoord";
-}
-
const char* GrGLSLFragmentShaderBuilder::distanceVectorName() const {
return "fsDistanceVector";
}
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
index f7d2323074..ab806ea914 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
@@ -47,11 +47,6 @@ public:
*/
virtual SkString ensureCoords2D(const GrShaderVar&) = 0;
-
- /** Returns a variable name that represents the position of the fragment in the FS. The position
- is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
- virtual const char* fragmentPosition() = 0;
-
// TODO: remove this method.
void declAppendf(const char* fmt, ...);
@@ -167,7 +162,6 @@ public:
// Shared GrGLSLFragmentBuilder interface.
bool enableFeature(GLSLFeature) override;
virtual SkString ensureCoords2D(const GrShaderVar&) override;
- const char* fragmentPosition() override;
const char* distanceVectorName() const override;
// GrGLSLFPFragmentBuilder interface.
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index c8058251e1..2b8a3a7264 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -20,7 +20,7 @@ const int GrGLSLProgramBuilder::kVarsPerBlock = 8;
GrGLSLProgramBuilder::GrGLSLProgramBuilder(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
- const GrProgramDesc& desc)
+ GrProgramDesc* desc)
: fVS(this)
, fGS(this)
, fFS(this)
@@ -348,7 +348,7 @@ void GrGLSLProgramBuilder::emitImageStorage(const GrProcessor::ImageStorageAcces
void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) {
// Swizzle the fragment shader outputs if necessary.
GrSwizzle swizzle;
- swizzle.setFromKey(this->desc().header().fOutputSwizzle);
+ swizzle.setFromKey(this->desc()->header().fOutputSwizzle);
if (swizzle != GrSwizzle::RGBA()) {
fFS.codeAppendf("%s = %s.%s;", fFS.getPrimaryColorOutputName(),
fFS.getPrimaryColorOutputName(),
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index 2dba90fa90..3074110f60 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -40,8 +40,8 @@ public:
const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
const GrPipeline& pipeline() const { return fPipeline; }
- const GrProgramDesc& desc() const { return fDesc; }
- const GrProgramDesc::KeyHeader& header() const { return fDesc.header(); }
+ GrProgramDesc* desc() { return fDesc; }
+ const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); }
void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
@@ -99,7 +99,7 @@ public:
const GrPipeline& fPipeline;
const GrPrimitiveProcessor& fPrimProc;
- const GrProgramDesc& fDesc;
+ GrProgramDesc* fDesc;
BuiltinUniformHandles fUniformHandles;
@@ -110,7 +110,7 @@ public:
protected:
explicit GrGLSLProgramBuilder(const GrPipeline&,
const GrPrimitiveProcessor&,
- const GrProgramDesc&);
+ GrProgramDesc*);
void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
diff --git a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp
index f8302b38fe..2aded892d4 100644
--- a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp
@@ -22,7 +22,7 @@ void GrGLSLVertexBuilder::transformToNormalizedDeviceSpace(const GrShaderVar& po
fProgramBuilder->addRTAdjustmentUniform(kHigh_GrSLPrecision,
fProgramBuilder->rtAdjustment(),
&fRtAdjustName);
- if (this->getProgramBuilder()->desc().header().fSnapVerticesToPixelCenters) {
+ if (this->getProgramBuilder()->desc()->header().fSnapVerticesToPixelCenters) {
if (kVec3f_GrSLType == posVar.getType()) {
const char* p = posVar.c_str();
this->codeAppendf("{vec2 _posTmp = vec2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p);
@@ -47,7 +47,7 @@ void GrGLSLVertexBuilder::transformToNormalizedDeviceSpace(const GrShaderVar& po
}
// We could have the GrGeometryProcessor do this, but its just easier to have it performed
// here. If we ever need to set variable pointsize, then we can reinvestigate.
- if (this->getProgramBuilder()->desc().header().fHasPointSize) {
+ if (this->getProgramBuilder()->desc()->header().fHasPointSize) {
this->codeAppend("gl_PointSize = 1.0;");
}
}
diff --git a/src/gpu/glsl/GrGLSLXferProcessor.cpp b/src/gpu/glsl/GrGLSLXferProcessor.cpp
index e2698199fd..4101080090 100644
--- a/src/gpu/glsl/GrGLSLXferProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLXferProcessor.cpp
@@ -49,11 +49,10 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
kDefault_GrSLPrecision,
"DstTextureCoordScale",
&dstCoordScaleName);
- const char* fragPos = fragBuilder->fragmentPosition();
fragBuilder->codeAppend("// Read color from copy of the destination.\n");
- fragBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
- fragPos, dstTopLeftName, dstCoordScaleName);
+ fragBuilder->codeAppendf("vec2 _dstTexCoord = (sk_FragCoord.xy - %s) * %s;",
+ dstTopLeftName, dstCoordScaleName);
if (!topDown) {
fragBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
diff --git a/src/gpu/ops/GrDrawOp.h b/src/gpu/ops/GrDrawOp.h
index 9e949b13cd..447a4ddff6 100644
--- a/src/gpu/ops/GrDrawOp.h
+++ b/src/gpu/ops/GrDrawOp.h
@@ -64,9 +64,6 @@ public:
bool installPipeline(const GrPipeline::CreateArgs&);
- // TODO no GrPrimitiveProcessors yet read fragment position
- bool willReadFragmentPosition() const { return false; }
-
protected:
static SkString DumpPipelineInfo(const GrPipeline& pipeline) {
SkString string;
diff --git a/src/gpu/ops/GrPLSPathRenderer.cpp b/src/gpu/ops/GrPLSPathRenderer.cpp
index 835ce2c463..80a4cda688 100644
--- a/src/gpu/ops/GrPLSPathRenderer.cpp
+++ b/src/gpu/ops/GrPLSPathRenderer.cpp
@@ -344,8 +344,7 @@ public:
// gl_FragCoord. The oriented box positioning of the subsamples is of course not
// optimal, but it greatly simplifies the math and this simplification is necessary for
// performance reasons.
- fsBuilder->codeAppendf("highp vec2 firstSample = %s.xy - vec2(0.25);",
- fsBuilder->fragmentPosition());
+ fsBuilder->codeAppendf("highp vec2 firstSample = sk_FragCoord.xy - vec2(0.25);");
fsBuilder->codeAppendf("highp vec2 delta1 = %s;", delta1.fsIn());
fsBuilder->codeAppendf("highp vec2 delta2 = %s;", delta2.fsIn());
fsBuilder->codeAppendf("highp vec2 delta3 = %s;", delta3.fsIn());
@@ -423,7 +422,6 @@ private:
kHigh_GrSLPrecision);
fInWindings = &this->addVertexAttrib("inWindings", kInt_GrVertexAttribType,
kLow_GrSLPrecision);
- this->setWillReadFragmentPosition();
}
const Attribute* fInPosition;
@@ -542,8 +540,7 @@ public:
fsBuilder->codeAppend("highp vec2 uvIncY = uvdX * 0.1 + uvdY * 0.55;");
fsBuilder->codeAppendf("highp vec2 uv = %s.xy - uvdX * 0.35 - uvdY * 0.25;",
uv.fsIn());
- fsBuilder->codeAppendf("highp vec2 firstSample = %s.xy - vec2(0.25);",
- fsBuilder->fragmentPosition());
+ fsBuilder->codeAppendf("highp vec2 firstSample = sk_FragCoord.xy - vec2(0.25);");
fsBuilder->codeAppendf("highp float d = dot(%s, (firstSample - %s).yx) * 2.0;",
delta.fsIn(), ep1.fsIn());
fsBuilder->codeAppendf("pls.windings[0] += %s(d, uv) ? %s : 0;", inQuadName.c_str(),
@@ -604,7 +601,6 @@ private:
kHigh_GrSLPrecision);
fInWindings = &this->addVertexAttrib("inWindings", kInt_GrVertexAttribType,
kLow_GrSLPrecision);
- this->setWillReadFragmentPosition();
}
const Attribute* fInPosition;
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
index 4125938bae..1363045bd6 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
@@ -19,7 +19,7 @@ GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
const GrStencilSettings& stencil,
const GrPrimitiveProcessor& primProc,
GrPrimitiveType primitiveType,
- const GrVkPipelineState::Desc& desc,
+ GrVkPipelineState::Desc* desc,
const GrVkRenderPass& renderPass) {
// create a builder. This will be handed off to effects so they can use it to add
// uniforms, varyings, textures, etc
@@ -39,7 +39,7 @@ GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
- const GrProgramDesc& desc)
+ GrProgramDesc* desc)
: INHERITED(pipeline, primProc, desc)
, fGpu(gpu)
, fVaryingHandler(this)
@@ -62,7 +62,8 @@ bool GrVkPipelineStateBuilder::createVkShaderModule(VkShaderStageFlagBits stage,
const GrGLSLShaderBuilder& builder,
VkShaderModule* shaderModule,
VkPipelineShaderStageCreateInfo* stageInfo,
- const SkSL::Program::Settings& settings) {
+ const SkSL::Program::Settings& settings,
+ GrVkPipelineState::Desc* desc) {
SkString shaderString;
for (int i = 0; i < builder.fCompilerStrings.count(); ++i) {
if (builder.fCompilerStrings[i]) {
@@ -80,13 +81,18 @@ bool GrVkPipelineStateBuilder::createVkShaderModule(VkShaderStageFlagBits stage,
if (inputs.fRTHeight) {
this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
}
+ if (inputs.fFlipY) {
+ desc->setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(
+ this->pipeline().getRenderTarget()->origin()));
+ desc->finalize();
+ }
return result;
}
GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& stencil,
GrPrimitiveType primitiveType,
const GrVkRenderPass& renderPass,
- const GrVkPipelineState::Desc& desc) {
+ GrVkPipelineState::Desc* desc) {
VkDescriptorSetLayout dsLayout[2];
VkPipelineLayout pipelineLayout;
VkShaderModule vertShaderModule;
@@ -133,7 +139,8 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s
fVS,
&vertShaderModule,
&shaderStageInfo[0],
- settings));
+ settings,
+ desc));
// TODO: geometry shader support.
SkASSERT(!this->primitiveProcessor().willUseGeoShader());
@@ -142,7 +149,8 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s
fFS,
&fragShaderModule,
&shaderStageInfo[1],
- settings));
+ settings,
+ desc));
GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
stencil,
@@ -165,7 +173,7 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s
}
return new GrVkPipelineState(fGpu,
- desc,
+ *desc,
pipeline,
pipelineLayout,
samplerDSHandle,
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.h b/src/gpu/vk/GrVkPipelineStateBuilder.h
index cf4a983119..ae59ec4e02 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.h
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.h
@@ -28,6 +28,8 @@ public:
*
* The GrVkPipelineState implements what is specified in the GrPipeline and GrPrimitiveProcessor
* as input. After successful generation, the builder result objects are available to be used.
+ * This function may modify the program key by setting the surface origin key to 0 (unspecified)
+ * if it turns out the program does not care about the surface origin.
* @return true if generation was successful.
*/
static GrVkPipelineState* CreatePipelineState(GrVkGpu*,
@@ -35,7 +37,7 @@ public:
const GrStencilSettings&,
const GrPrimitiveProcessor&,
GrPrimitiveType,
- const GrVkPipelineState::Desc&,
+ GrVkPipelineState::Desc*,
const GrVkRenderPass& renderPass);
const GrCaps* caps() const override;
@@ -49,18 +51,19 @@ private:
GrVkPipelineStateBuilder(GrVkGpu*,
const GrPipeline&,
const GrPrimitiveProcessor&,
- const GrProgramDesc&);
+ GrProgramDesc*);
GrVkPipelineState* finalize(const GrStencilSettings&,
GrPrimitiveType primitiveType,
const GrVkRenderPass& renderPass,
- const GrVkPipelineState::Desc&);
+ GrVkPipelineState::Desc*);
bool createVkShaderModule(VkShaderStageFlagBits stage,
const GrGLSLShaderBuilder& builder,
VkShaderModule* shaderModule,
VkPipelineShaderStageCreateInfo* stageInfo,
- const SkSL::Program::Settings& settings);
+ const SkSL::Program::Settings& settings,
+ GrVkPipelineState::Desc* desc);
GrGLSLUniformHandler* uniformHandler() override { return &fUniformHandler; }
const GrGLSLUniformHandler* uniformHandler() const override { return &fUniformHandler; }
diff --git a/src/gpu/vk/GrVkPipelineStateCache.cpp b/src/gpu/vk/GrVkPipelineStateCache.cpp
index 7b935eb0d1..f8d77a96d6 100644
--- a/src/gpu/vk/GrVkPipelineStateCache.cpp
+++ b/src/gpu/vk/GrVkPipelineStateCache.cpp
@@ -101,6 +101,13 @@ sk_sp<GrVkPipelineState> GrVkResourceProvider::PipelineStateCache::refPipelineSt
std::unique_ptr<Entry>* entry = fMap.find(desc);
if (!entry) {
+ // Didn't find an origin-independent version, check with the specific origin
+ GrSurfaceOrigin origin = pipeline.getRenderTarget()->origin();
+ desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
+ desc.finalize();
+ entry = fMap.find(desc);
+ }
+ if (!entry) {
#ifdef GR_PIPELINE_STATE_CACHE_STATS
++fCacheMisses;
#endif
@@ -110,7 +117,7 @@ sk_sp<GrVkPipelineState> GrVkResourceProvider::PipelineStateCache::refPipelineSt
stencil,
primProc,
primitiveType,
- desc,
+ &desc,
renderPass));
if (nullptr == pipelineState) {
return nullptr;
diff --git a/src/sksl/README b/src/sksl/README
index 98103fa64f..25b07c18e1 100644
--- a/src/sksl/README
+++ b/src/sksl/README
@@ -34,8 +34,10 @@ following differences between SkSL and GLSL:
* no #version statement is required, and will be ignored if present
* the output color is sk_FragColor (do not declare it)
* use sk_VertexID instead of gl_VertexID
+* the fragment coordinate is sk_FragCoord, and is always relative to the upper
+ left.
* lowp, mediump, and highp are always permitted (but will only be respected if
- you run on a GLES device)
+ you run on a device which supports them)
* you do not need to include ".0" to make a number a float (meaning that
"vec2(x, y) * 4" is perfectly legal in SkSL, unlike GLSL where it would often
have to be expressed "vec2(x, y) * 4.0". There is no performance penalty for
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 687ccb98ce..70df81b62e 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -624,11 +624,14 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTIdentifier&
f->fFunctions));
}
case Symbol::kVariable_Kind: {
- Variable* var = (Variable*) result;
- if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN &&
- fSettings->fFlipY &&
- (!fSettings->fCaps || !fSettings->fCaps->fragCoordConventionsExtensionString())) {
- fInputs.fRTHeight = true;
+ const Variable* var = (const Variable*) result;
+ if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN) {
+ fInputs.fFlipY = true;
+ if (fSettings->fFlipY &&
+ (!fSettings->fCaps ||
+ !fSettings->fCaps->fragCoordConventionsExtensionString())) {
+ fInputs.fRTHeight = true;
+ }
}
// default to kRead_RefKind; this will be corrected later if the variable is written to
return std::unique_ptr<VariableReference>(new VariableReference(
diff --git a/src/sksl/ir/SkSLProgram.h b/src/sksl/ir/SkSLProgram.h
index 6a73be6983..e4a975b279 100644
--- a/src/sksl/ir/SkSLProgram.h
+++ b/src/sksl/ir/SkSLProgram.h
@@ -27,6 +27,8 @@ namespace SkSL {
struct Program {
struct Settings {
const GrShaderCaps* fCaps = nullptr;
+ // if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the y coordinate
+ // must be flipped.
bool fFlipY = false;
};
@@ -34,12 +36,17 @@ struct Program {
// if true, this program requires the render target height uniform to be defined
bool fRTHeight;
+ // if true, this program must be recompiled if the flipY setting changes. If false, the
+ // program will compile to the same code regardless of the flipY setting.
+ bool fFlipY;
+
void reset() {
fRTHeight = false;
+ fFlipY = false;
}
bool isEmpty() {
- return !fRTHeight;
+ return !fRTHeight && !fFlipY;
}
};
diff --git a/tests/ImageStorageTest.cpp b/tests/ImageStorageTest.cpp
index 20c9713745..aa34831d1e 100644
--- a/tests/ImageStorageTest.cpp
+++ b/tests/ImageStorageTest.cpp
@@ -31,7 +31,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageStorageLoad, reporter, ctxInfo) {
: INHERITED(kNone_OptimizationFlags)
, fImageStorageAccess(std::move(texture), kRead_GrIOType, mm, restrict) {
this->initClassID<TestFP>();
- this->setWillReadFragmentPosition();
this->addImageStorageAccess(&fImageStorageAccess);
}
@@ -51,8 +50,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageStorageLoad, reporter, ctxInfo) {
const TestFP& tfp = args.fFp.cast<TestFP>();
GrGLSLFPFragmentBuilder* fb = args.fFragBuilder;
SkString imageLoadStr;
- fb->codeAppendf("highp vec2 coord = %s.xy;",
- args.fFragBuilder->fragmentPosition());
+ fb->codeAppend("highp vec2 coord = sk_FragCoord.xy;");
fb->appendImageStorageLoad(&imageLoadStr, args.fImageStorages[0],
"ivec2(coord)");
if (GrPixelConfigIsSint(tfp.fImageStorageAccess.texture()->config())) {
diff --git a/tests/SkSLErrorTest.cpp b/tests/SkSLErrorTest.cpp
index 9c34ab41fb..301281c28e 100644
--- a/tests/SkSLErrorTest.cpp
+++ b/tests/SkSLErrorTest.cpp
@@ -421,4 +421,13 @@ DEF_TEST(SkSLDivByZero, r) {
"error: 1: division by zero\n1 error\n");
}
+DEF_TEST(SkSLUnsupportedGLSLIdentifiers, r) {
+ test_failure(r,
+ "void main() { float x = gl_FragCoord.x; };",
+ "error: 1: unknown identifier 'gl_FragCoord'\n1 error\n");
+ test_failure(r,
+ "void main() { float r = gl_FragColor.r; };",
+ "error: 1: unknown identifier 'gl_FragColor'\n1 error\n");
+}
+
#endif