From cae3a4c8ab7082df009a1e340f10292350e0c763 Mon Sep 17 00:00:00 2001 From: Ethan Nicholas Date: Thu, 2 Feb 2017 10:43:58 -0500 Subject: Revert "Replaced all calls to fragmentPosition() with sk_FragCoord" This reverts commit de4d301881e7fd084f1f0b359ec6f9b2bf8bd4c5. Reason for revert: several Chrome rendering bugs on Mac BUG=skia: Change-Id: I492082b0b7e7c902ede4b598c5809f604d210ce1 Reviewed-on: https://skia-review.googlesource.com/7887 Reviewed-by: Ethan Nicholas Commit-Queue: Ethan Nicholas --- src/effects/GrCircleBlurFragmentProcessor.cpp | 8 ++- src/effects/SkBlurMaskFilter.cpp | 10 ++- src/effects/SkLightingImageFilter.cpp | 16 +++-- src/effects/SkRRectsGaussianEdgeMaskFilter.cpp | 5 +- src/gpu/GrProgramDesc.cpp | 9 ++- src/gpu/GrProgramDesc.h | 6 -- src/gpu/GrXferProcessor.cpp | 1 + src/gpu/effects/GrConvexPolyEffect.cpp | 29 ++++---- src/gpu/effects/GrDitherEffect.cpp | 9 ++- src/gpu/effects/GrOvalEffect.cpp | 16 +++-- src/gpu/effects/GrRRectEffect.cpp | 94 +++++++++++++------------- src/gpu/effects/GrTextureDomain.cpp | 5 +- src/gpu/gl/GrGLGpuProgramCache.cpp | 9 +-- src/gpu/gl/builders/GrGLProgramBuilder.cpp | 13 +--- src/gpu/gl/builders/GrGLProgramBuilder.h | 7 +- src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp | 5 ++ src/gpu/glsl/GrGLSLFragmentShaderBuilder.h | 6 ++ src/gpu/glsl/GrGLSLProgramBuilder.cpp | 4 +- src/gpu/glsl/GrGLSLProgramBuilder.h | 8 +-- src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp | 4 +- src/gpu/glsl/GrGLSLXferProcessor.cpp | 5 +- src/gpu/ops/GrDrawOp.h | 3 + src/gpu/ops/GrPLSPathRenderer.cpp | 8 ++- src/gpu/vk/GrVkPipelineStateBuilder.cpp | 23 ++----- src/gpu/vk/GrVkPipelineStateBuilder.h | 11 ++- src/gpu/vk/GrVkPipelineStateCache.cpp | 9 +-- src/sksl/README | 4 +- src/sksl/SkSLIRGenerator.cpp | 13 ++-- src/sksl/ir/SkSLProgram.h | 9 +-- 29 files changed, 172 insertions(+), 177 deletions(-) (limited to 'src') diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp index c54a71c809..d161195a64 100644 --- a/src/effects/GrCircleBlurFragmentProcessor.cpp +++ b/src/effects/GrCircleBlurFragmentProcessor.cpp @@ -47,6 +47,7 @@ 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); @@ -56,9 +57,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( (sk_FragCoord.x - %s.x) * %s.w, " - "(sk_FragCoord.y - %s.y) * %s.w );", - dataName, dataName, dataName, dataName); + 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("float dist = length(vec) + (0.5 - %s.z) * %s.w;", dataName, dataName); @@ -95,6 +96,7 @@ GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(const SkRect& circl , fBlurProfileSampler(blurProfile, GrSamplerParams::kBilerp_FilterMode) { this->initClassID(); this->addTextureSampler(&fBlurProfileSampler); + this->setWillReadFragmentPosition(); } GrGLSLFragmentProcessor* GrCircleBlurFragmentProcessor::onCreateGLSLInstance() const { diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index f41648dc4b..225d6f67cc 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -904,6 +904,7 @@ 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); @@ -911,8 +912,8 @@ void GrGLRectBlurEffect::emitCode(EmitArgs& args) { fragBuilder->codeAppendf("vec4 src=vec4(1);"); } - fragBuilder->codeAppendf("%s vec2 translatedPos = sk_FragCoord.xy - %s.xy;", - precisionString.c_str(), rectName); + fragBuilder->codeAppendf("%s vec2 translatedPos = %s.xy - %s.xy;", precisionString.c_str(), + fragmentPos, 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, @@ -983,6 +984,7 @@ GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture* b , fPrecision(precision) { this->initClassID(); this->addTextureSampler(&fBlurProfileSampler); + this->setWillReadFragmentPosition(); } void GrRectBlurEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, @@ -1216,6 +1218,7 @@ GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur , fNinePatchSampler(ninePatchTexture) { this->initClassID(); this->addTextureSampler(&fNinePatchSampler); + this->setWillReadFragmentPosition(); } bool GrRRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const { @@ -1283,11 +1286,12 @@ 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 = sk_FragCoord.xy - %s.xy;", rectName); + fragBuilder->codeAppendf("vec2 translatedFragPos = %s.xy - %s.xy;", fragmentPos, 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 fc7b29b490..92057f0802 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -770,6 +770,8 @@ 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. @@ -818,6 +820,7 @@ public: return nullptr; #endif } + bool requiresFragmentPosition() const override { return false; } bool isEqual(const SkImageFilterLight& other) const override { if (other.type() != kDistant_LightType) { @@ -876,6 +879,7 @@ public: return nullptr; #endif } + bool requiresFragmentPosition() const override { return true; } bool isEqual(const SkImageFilterLight& other) const override { if (other.type() != kPoint_LightType) { return false; @@ -989,6 +993,7 @@ 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; } @@ -1710,6 +1715,9 @@ GrLightingEffect::GrLightingEffect(GrTexture* texture, , fBoundaryMode(boundaryMode) , fDomain(create_domain(texture, srcBounds, GrTextureDomain::kDecal_Mode)) { fLight->ref(); + if (light->requiresFragmentPosition()) { + this->setWillReadFragmentPosition(); + } } GrLightingEffect::~GrLightingEffect() { @@ -2094,8 +2102,8 @@ void GrGLPointLight::emitSurfaceToLight(GrGLSLUniformHandler* uniformHandler, fLocationUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kVec3f_GrSLType, kDefault_GrSLPrecision, "LightLocation", &loc); - fragBuilder->codeAppendf("normalize(%s - vec3(sk_FragCoord.xy, %s))", - loc, z); + fragBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))", + loc, fragBuilder->fragmentPosition(), z); } /////////////////////////////////////////////////////////////////////////////// @@ -2121,8 +2129,8 @@ void GrGLSpotLight::emitSurfaceToLight(GrGLSLUniformHandler* uniformHandler, kVec3f_GrSLType, kDefault_GrSLPrecision, "LightLocation", &location); - fragBuilder->codeAppendf("normalize(%s - vec3(sk_FragCoord.xy, %s))", - location, z); + fragBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))", + location, fragBuilder->fragmentPosition(), z); } void GrGLSpotLight::emitLightColor(GrGLSLUniformHandler* uniformHandler, diff --git a/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp b/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp index 223887bab9..f6b2ce31b5 100644 --- a/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp +++ b/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp @@ -209,6 +209,7 @@ public: RRectsGaussianEdgeFP(const SkRRect& first, const SkRRect& second, SkScalar radius) : INHERITED(kNone_OptimizationFlags), fFirst(first), fSecond(second), fRadius(radius) { this->initClassID(); + this->setWillReadFragmentPosition(); fFirstMode = ComputeMode(fFirst); fSecondMode = ComputeMode(fSecond); @@ -232,8 +233,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(sk_FragCoord.xy - %s.%s);", - posName, indices); + fragBuilder->codeAppendf("vec2 delta = abs(%s.xy - %s.%s);", + fragBuilder->fragmentPosition(), posName, indices); switch (mode) { case kCircle_Mode: diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp index 080ba5ec2d..87a4a275d7 100644 --- a/src/gpu/GrProgramDesc.cpp +++ b/src/gpu/GrProgramDesc.cpp @@ -195,10 +195,15 @@ bool GrProgramDesc::Build(GrProgramDesc* desc, // make sure any padding in the header is zeroed. memset(header, 0, kHeaderSize); - header->fSurfaceOriginKey = 0; - 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 a20cdfc56b..2a26f2d1c0 100644 --- a/src/gpu/GrProgramDesc.h +++ b/src/gpu/GrProgramDesc.h @@ -12,7 +12,6 @@ #include "GrTypesPriv.h" #include "SkOpts.h" #include "SkTArray.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" class GrShaderCaps; class GrPipeline; @@ -81,11 +80,6 @@ public: return !(*this == other); } - void setSurfaceOriginKey(int key) { - KeyHeader* header = this->atOffset(); - 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 d88259d48f..df1f35eafe 100644 --- a/src/gpu/GrXferProcessor.cpp +++ b/src/gpu/GrXferProcessor.cpp @@ -27,6 +27,7 @@ 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 db8c2d999e..da77eb8c05 100644 --- a/src/gpu/effects/GrConvexPolyEffect.cpp +++ b/src/gpu/effects/GrConvexPolyEffect.cpp @@ -34,6 +34,7 @@ private: AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect) : INHERITED(kModulatesInput_OptimizationFlag), fRect(rect), fEdgeType(edgeType) { this->initClassID(); + this->setWillReadFragmentPosition(); } GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; @@ -114,27 +115,24 @@ 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(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); + 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); // 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 *= (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); + 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); } if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) { @@ -203,10 +201,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(sk_FragCoord.x, sk_FragCoord.y, " - "1));\n", - edgeArrayName, i); + fragBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n", + edgeArrayName, i, fragmentPos, fragmentPos); if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) { fragBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); } else { @@ -351,6 +349,7 @@ 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 34a15651d2..a2394aacee 100644 --- a/src/gpu/effects/GrDitherEffect.cpp +++ b/src/gpu/effects/GrDitherEffect.cpp @@ -26,7 +26,10 @@ public: const char* name() const override { return "Dither"; } private: - DitherEffect() : INHERITED(kNone_OptimizationFlags) { this->initClassID(); } + DitherEffect() : INHERITED(kNone_OptimizationFlags) { + this->initClassID(); + this->setWillReadFragmentPosition(); + } GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; @@ -78,8 +81,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(sk_FragCoord.xy, vec2(12.9898,78.233))) * " - "43758.5453);\n"); + "fract(sin(dot(%s.xy ,vec2(12.9898,78.233))) * 43758.5453);\n", + fragBuilder->fragmentPosition()); 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 b64ac56859..6ad6e7b988 100644 --- a/src/gpu/effects/GrOvalEffect.cpp +++ b/src/gpu/effects/GrOvalEffect.cpp @@ -66,6 +66,7 @@ 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(); + this->setWillReadFragmentPosition(); } bool CircleEffect::onIsEqual(const GrFragmentProcessor& other) const { @@ -123,6 +124,7 @@ 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 @@ -130,13 +132,11 @@ 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 - sk_FragCoord.xy) * %s.w) - 1.0) * " - "%s.z;", - circleName, circleName, circleName); + fragBuilder->codeAppendf("float d = (length((%s.xy - %s.xy) * %s.w) - 1.0) * %s.z;", + circleName, fragmentPos, circleName, circleName); } else { - fragBuilder->codeAppendf("float d = (1.0 - length((%s.xy - sk_FragCoord.xy) * %s.w)) * " - "%s.z;", - circleName, circleName, circleName); + fragBuilder->codeAppendf("float d = (1.0 - length((%s.xy - %s.xy) * %s.w)) * %s.z;", + circleName, fragmentPos, circleName, circleName); } if (GrProcessorEdgeTypeIsAA(ce.getEdgeType())) { fragBuilder->codeAppend("d = clamp(d, 0.0, 1.0);"); @@ -237,6 +237,7 @@ EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkS , fRadii(SkVector::Make(rx, ry)) , fEdgeType(edgeType) { this->initClassID(); + this->setWillReadFragmentPosition(); } bool EllipseEffect::onIsEqual(const GrFragmentProcessor& other) const { @@ -308,9 +309,10 @@ 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 = sk_FragCoord.xy - %s.xy;", ellipseName); + fragBuilder->codeAppendf("vec2 d = %s.xy - %s.xy;", fragmentPos, ellipseName); if (scaleName) { fragBuilder->codeAppendf("d *= %s.y;", scaleName); } diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp index dabf11ae8d..468deae547 100644 --- a/src/gpu/effects/GrRRectEffect.cpp +++ b/src/gpu/effects/GrRRectEffect.cpp @@ -100,6 +100,7 @@ CircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t , fEdgeType(edgeType) , fCircularCornerFlags(circularCornerFlags) { this->initClassID(); + this->setWillReadFragmentPosition(); } bool CircularRRectEffect::onIsEqual(const GrFragmentProcessor& other) const { @@ -180,6 +181,7 @@ 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 @@ -197,86 +199,84 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) { // alphas together. switch (crre.getCircularCornerFlags()) { case CircularRRectEffect::kAll_CornerFlags: - fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName); - fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName); + fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - %s.xy;", rectName, fragmentPos); + fragBuilder->codeAppendf("vec2 dxy1 = %s.xy - %s.zw;", fragmentPos, 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 - 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("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("float alpha = bottomAlpha * rightAlpha * %s;", clampedCircleDistance.c_str()); break; case CircularRRectEffect::kTopRight_CornerFlag: - 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("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("float alpha = bottomAlpha * leftAlpha * %s;", clampedCircleDistance.c_str()); break; case CircularRRectEffect::kBottomRight_CornerFlag: - 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("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("float alpha = topAlpha * leftAlpha * %s;", clampedCircleDistance.c_str()); break; case CircularRRectEffect::kBottomLeft_CornerFlag: - 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("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("float alpha = topAlpha * rightAlpha * %s;", clampedCircleDistance.c_str()); break; case CircularRRectEffect::kLeft_CornerFlags: - fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName); - fragBuilder->codeAppendf("float dy1 = sk_FragCoord.y - %s.w;", rectName); + fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - %s.xy;", rectName, fragmentPos); + fragBuilder->codeAppendf("float dy1 = %s.y - %s.w;", fragmentPos, rectName); fragBuilder->codeAppend("vec2 dxy = max(vec2(dxy0.x, max(dxy0.y, dy1)), 0.0);"); - fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);", - rectName); + fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);", + rectName, fragmentPos); fragBuilder->codeAppendf("float alpha = rightAlpha * %s;", clampedCircleDistance.c_str()); break; case CircularRRectEffect::kTop_CornerFlags: - fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName); - fragBuilder->codeAppendf("float dx1 = sk_FragCoord.x - %s.z;", rectName); + fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - %s.xy;", rectName, fragmentPos); + fragBuilder->codeAppendf("float dx1 = %s.x - %s.z;", fragmentPos, rectName); fragBuilder->codeAppend("vec2 dxy = max(vec2(max(dxy0.x, dx1), dxy0.y), 0.0);"); - fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);", - rectName); + fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);", + rectName, fragmentPos); fragBuilder->codeAppendf("float alpha = bottomAlpha * %s;", clampedCircleDistance.c_str()); break; case CircularRRectEffect::kRight_CornerFlags: - fragBuilder->codeAppendf("float dy0 = %s.y - sk_FragCoord.y;", rectName); - fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName); + fragBuilder->codeAppendf("float dy0 = %s.y - %s.y;", rectName, fragmentPos); + fragBuilder->codeAppendf("vec2 dxy1 = %s.xy - %s.zw;", fragmentPos, rectName); fragBuilder->codeAppend("vec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1.y)), 0.0);"); - fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);", - rectName); + fragBuilder->codeAppendf("float leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);", + fragmentPos, rectName); fragBuilder->codeAppendf("float alpha = leftAlpha * %s;", clampedCircleDistance.c_str()); break; case CircularRRectEffect::kBottom_CornerFlags: - fragBuilder->codeAppendf("float dx0 = %s.x - sk_FragCoord.x;", rectName); - fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName); + fragBuilder->codeAppendf("float dx0 = %s.x - %s.x;", rectName, fragmentPos); + fragBuilder->codeAppendf("vec2 dxy1 = %s.xy - %s.zw;", fragmentPos, rectName); fragBuilder->codeAppend("vec2 dxy = max(vec2(max(dx0, dxy1.x), dxy1.y), 0.0);"); - fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);", - rectName); + fragBuilder->codeAppendf("float topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);", + fragmentPos, rectName); fragBuilder->codeAppendf("float alpha = topAlpha * %s;", clampedCircleDistance.c_str()); break; @@ -436,6 +436,7 @@ void EllipticalRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) c EllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const SkRRect& rrect) : INHERITED(kModulatesInput_OptimizationFlag), fRRect(rrect), fEdgeType(edgeType) { this->initClassID(); + this->setWillReadFragmentPosition(); } bool EllipticalRRectEffect::onIsEqual(const GrFragmentProcessor& other) const { @@ -519,6 +520,7 @@ 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 @@ -531,8 +533,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 - sk_FragCoord.xy;", rectName); - fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName); + fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - %s.xy;", rectName, fragmentPos); + fragBuilder->codeAppendf("vec2 dxy1 = %s.xy - %s.zw;", fragmentPos, 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 58707f5744..aa449d4052 100644 --- a/src/gpu/effects/GrTextureDomain.cpp +++ b/src/gpu/effects/GrTextureDomain.cpp @@ -419,6 +419,7 @@ GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentPro fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft; fDeviceSpaceOffset.fY = deviceSpaceOffset.fY - subset.fTop; this->initClassID(); + this->setWillReadFragmentPosition(); } sk_sp GrDeviceSpaceTextureDecalFragmentProcessor::Make( @@ -443,6 +444,7 @@ GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentPro fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft; fDeviceSpaceOffset.fY = deviceSpaceOffset.fY - subset.fTop; this->initClassID(); + this->setWillReadFragmentPosition(); } GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLSLInstance() const { @@ -457,7 +459,8 @@ GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLS kDefault_GrSLPrecision, "scaleAndTranslate", &scaleAndTranslateName); - args.fFragBuilder->codeAppendf("vec2 coords = sk_FragCoord.xy * %s.xy + %s.zw;", + args.fFragBuilder->codeAppendf("vec2 coords = %s.xy * %s.xy + %s.zw;", + args.fFragBuilder->fragmentPosition(), scaleAndTranslateName, scaleAndTranslateName); fGLDomain.sampleTexture(args.fFragBuilder, args.fUniformHandler, diff --git a/src/gpu/gl/GrGLGpuProgramCache.cpp b/src/gpu/gl/GrGLGpuProgramCache.cpp index 2ff5dc79b4..c1ca16096a 100644 --- a/src/gpu/gl/GrGLGpuProgramCache.cpp +++ b/src/gpu/gl/GrGLGpuProgramCache.cpp @@ -80,19 +80,12 @@ GrGLProgram* GrGLGpu::ProgramCache::refProgram(const GrGLGpu* gpu, } desc.finalize(); std::unique_ptr* 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 f3548e6bae..c3e81fb358 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, - GrProgramDesc* desc, + const 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, - GrProgramDesc* desc) + const GrProgramDesc& desc) : INHERITED(pipeline, primProc, desc) , fGpu(gpu) , fVaryingHandler(this) @@ -89,13 +89,6 @@ bool GrGLProgramBuilder::compileAndAttachShaders(GrGLSLShaderBuilder& shader, } *shaderIds->append() = shaderId; - if (!outInputs->fFlipY) { - GrProgramDesc* d = this->desc(); - // the program doesn't care about the surface origin, set the key to zero to indicate that - // it doesn't matter - d->setSurfaceOriginKey(0); - d->finalize(); - } return true; } @@ -251,7 +244,7 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray& 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 cfbb734155..84d6d91a57 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -29,14 +29,11 @@ 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&, - GrProgramDesc*, + const GrProgramDesc&, GrGLGpu*); const GrCaps* caps() const override; @@ -45,7 +42,7 @@ public: private: GrGLProgramBuilder(GrGLGpu*, const GrPipeline&, const GrPrimitiveProcessor&, - GrProgramDesc*); + const GrProgramDesc&); bool compileAndAttachShaders(GrGLSLShaderBuilder& shader, GrGLuint programId, diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp index f583420f29..7ef734876c 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp @@ -130,6 +130,11 @@ 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 ab806ea914..f7d2323074 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h @@ -47,6 +47,11 @@ 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, ...); @@ -162,6 +167,7 @@ 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 2b8a3a7264..c8058251e1 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, - GrProgramDesc* desc) + const 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 3074110f60..2dba90fa90 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; } - GrProgramDesc* desc() { return fDesc; } - const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); } + const GrProgramDesc& desc() const { 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; - GrProgramDesc* fDesc; + const GrProgramDesc& fDesc; BuiltinUniformHandles fUniformHandles; @@ -110,7 +110,7 @@ public: protected: explicit GrGLSLProgramBuilder(const GrPipeline&, const GrPrimitiveProcessor&, - GrProgramDesc*); + const 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 2aded892d4..f8302b38fe 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 4101080090..e2698199fd 100644 --- a/src/gpu/glsl/GrGLSLXferProcessor.cpp +++ b/src/gpu/glsl/GrGLSLXferProcessor.cpp @@ -49,10 +49,11 @@ 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 = (sk_FragCoord.xy - %s) * %s;", - dstTopLeftName, dstCoordScaleName); + fragBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;", + fragPos, 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 447a4ddff6..9e949b13cd 100644 --- a/src/gpu/ops/GrDrawOp.h +++ b/src/gpu/ops/GrDrawOp.h @@ -64,6 +64,9 @@ 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 80a4cda688..835ce2c463 100644 --- a/src/gpu/ops/GrPLSPathRenderer.cpp +++ b/src/gpu/ops/GrPLSPathRenderer.cpp @@ -344,7 +344,8 @@ 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 = sk_FragCoord.xy - vec2(0.25);"); + fsBuilder->codeAppendf("highp vec2 firstSample = %s.xy - vec2(0.25);", + fsBuilder->fragmentPosition()); fsBuilder->codeAppendf("highp vec2 delta1 = %s;", delta1.fsIn()); fsBuilder->codeAppendf("highp vec2 delta2 = %s;", delta2.fsIn()); fsBuilder->codeAppendf("highp vec2 delta3 = %s;", delta3.fsIn()); @@ -422,6 +423,7 @@ private: kHigh_GrSLPrecision); fInWindings = &this->addVertexAttrib("inWindings", kInt_GrVertexAttribType, kLow_GrSLPrecision); + this->setWillReadFragmentPosition(); } const Attribute* fInPosition; @@ -540,7 +542,8 @@ 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 = sk_FragCoord.xy - vec2(0.25);"); + fsBuilder->codeAppendf("highp vec2 firstSample = %s.xy - vec2(0.25);", + fsBuilder->fragmentPosition()); 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(), @@ -601,6 +604,7 @@ 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 f7a61730a5..4125938bae 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, - GrVkPipelineState::Desc* desc, + const 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, - GrProgramDesc* desc) + const GrProgramDesc& desc) : INHERITED(pipeline, primProc, desc) , fGpu(gpu) , fVaryingHandler(this) @@ -62,8 +62,7 @@ bool GrVkPipelineStateBuilder::createVkShaderModule(VkShaderStageFlagBits stage, const GrGLSLShaderBuilder& builder, VkShaderModule* shaderModule, VkPipelineShaderStageCreateInfo* stageInfo, - const SkSL::Program::Settings& settings, - GrVkPipelineState::Desc* desc) { + const SkSL::Program::Settings& settings) { SkString shaderString; for (int i = 0; i < builder.fCompilerStrings.count(); ++i) { if (builder.fCompilerStrings[i]) { @@ -81,19 +80,13 @@ bool GrVkPipelineStateBuilder::createVkShaderModule(VkShaderStageFlagBits stage, if (inputs.fRTHeight) { this->addRTHeightUniform(SKSL_RTHEIGHT_NAME); } - if (!inputs.fFlipY) { - // the program doesn't care about the surface origin, set the key to zero to indicate that - // it doesn't matter - desc->setSurfaceOriginKey(0); - desc->finalize(); - } return result; } GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& stencil, GrPrimitiveType primitiveType, const GrVkRenderPass& renderPass, - GrVkPipelineState::Desc* desc) { + const GrVkPipelineState::Desc& desc) { VkDescriptorSetLayout dsLayout[2]; VkPipelineLayout pipelineLayout; VkShaderModule vertShaderModule; @@ -140,8 +133,7 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s fVS, &vertShaderModule, &shaderStageInfo[0], - settings, - desc)); + settings)); // TODO: geometry shader support. SkASSERT(!this->primitiveProcessor().willUseGeoShader()); @@ -150,8 +142,7 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s fFS, &fragShaderModule, &shaderStageInfo[1], - settings, - desc)); + settings)); GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline, stencil, @@ -174,7 +165,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 ae59ec4e02..cf4a983119 100644 --- a/src/gpu/vk/GrVkPipelineStateBuilder.h +++ b/src/gpu/vk/GrVkPipelineStateBuilder.h @@ -28,8 +28,6 @@ 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*, @@ -37,7 +35,7 @@ public: const GrStencilSettings&, const GrPrimitiveProcessor&, GrPrimitiveType, - GrVkPipelineState::Desc*, + const GrVkPipelineState::Desc&, const GrVkRenderPass& renderPass); const GrCaps* caps() const override; @@ -51,19 +49,18 @@ private: GrVkPipelineStateBuilder(GrVkGpu*, const GrPipeline&, const GrPrimitiveProcessor&, - GrProgramDesc*); + const GrProgramDesc&); GrVkPipelineState* finalize(const GrStencilSettings&, GrPrimitiveType primitiveType, const GrVkRenderPass& renderPass, - GrVkPipelineState::Desc*); + const GrVkPipelineState::Desc&); bool createVkShaderModule(VkShaderStageFlagBits stage, const GrGLSLShaderBuilder& builder, VkShaderModule* shaderModule, VkPipelineShaderStageCreateInfo* stageInfo, - const SkSL::Program::Settings& settings, - GrVkPipelineState::Desc* desc); + const SkSL::Program::Settings& settings); 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 f8d77a96d6..7b935eb0d1 100644 --- a/src/gpu/vk/GrVkPipelineStateCache.cpp +++ b/src/gpu/vk/GrVkPipelineStateCache.cpp @@ -100,13 +100,6 @@ sk_sp GrVkResourceProvider::PipelineStateCache::refPipelineSt desc.finalize(); std::unique_ptr* 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; @@ -117,7 +110,7 @@ sk_sp 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 a4117ca09e..d18367f8d2 100644 --- a/src/sksl/README +++ b/src/sksl/README @@ -33,10 +33,8 @@ following differences between SkSL and GLSL: 'do_something_else();', depending on whether that cap is enabled or not. * no #version statement is required, and will be ignored if present * the output color is sk_FragColor (do not declare it) -* 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 device which supports them) + you run on a GLES device) * 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 ebb4c52a34..55d9d2c8d6 100644 --- a/src/sksl/SkSLIRGenerator.cpp +++ b/src/sksl/SkSLIRGenerator.cpp @@ -624,14 +624,11 @@ std::unique_ptr IRGenerator::convertIdentifier(const ASTIdentifier& f->fFunctions)); } case Symbol::kVariable_Kind: { - 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; - } + Variable* var = (Variable*) result; + if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN && + 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(new VariableReference( diff --git a/src/sksl/ir/SkSLProgram.h b/src/sksl/ir/SkSLProgram.h index e4a975b279..6a73be6983 100644 --- a/src/sksl/ir/SkSLProgram.h +++ b/src/sksl/ir/SkSLProgram.h @@ -27,8 +27,6 @@ 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; }; @@ -36,17 +34,12 @@ 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 && !fFlipY; + return !fRTHeight; } }; -- cgit v1.2.3