Revert "Revert "added support for sk_Dimensions to SkSL""
This reverts commit e6ab998bc2e675ab0a426ec9434be887e5527ab3.
Bug: skia:
Change-Id: I19451f924d514dadac9d2c326bcc8404a1b501e9
Reviewed-on: https://skia-review.googlesource.com/149239
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 102dc4a..8a5308f 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -133,7 +133,11 @@
void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
const GrRenderTargetProxy* proxy) {
GrRenderTarget* rt = proxy->peekRenderTarget();
- // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
+ // Load the RT size uniforms if they are needed
+ if (fBuiltinUniformHandles.fRTWidthUni.isValid() &&
+ fRenderTargetState.fRenderTargetSize.fWidth != rt->width()) {
+ fProgramDataManager.set1f(fBuiltinUniformHandles.fRTWidthUni, SkIntToScalar(rt->width()));
+ }
if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index ba290ac..f6890fd 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -159,6 +159,15 @@
SkASSERT(fInstanceStride == primProc.debugOnly_instanceStride());
}
+void GrGLProgramBuilder::addInputVars(const SkSL::Program::Inputs& inputs) {
+ if (inputs.fRTWidth) {
+ this->addRTWidthUniform(SKSL_RTWIDTH_NAME);
+ }
+ if (inputs.fRTHeight) {
+ this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
+ }
+}
+
GrGLProgram* GrGLProgramBuilder::finalize() {
TRACE_EVENT0("skia", TRACE_FUNC);
@@ -204,9 +213,7 @@
if (GR_GL_GET_ERROR(this->gpu()->glInterface()) == GR_GL_NO_ERROR) {
cached = this->checkLinkStatus(programID);
if (cached) {
- if (inputs.fRTHeight) {
- this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
- }
+ this->addInputVars(inputs);
this->computeCountsAndStrides(programID, primProc, false);
}
} else {
@@ -231,9 +238,7 @@
return nullptr;
}
inputs = fs->fInputs;
- if (inputs.fRTHeight) {
- this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
- }
+ this->addInputVars(inputs);
if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
GR_GL_FRAGMENT_SHADER, &shadersToDelete, settings,
inputs)) {
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 64e4269..b601b6b 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -48,6 +48,7 @@
GrGLProgramBuilder(GrGLGpu*, const GrPipeline&, const GrPrimitiveProcessor&,
GrProgramDesc*);
+ void addInputVars(const SkSL::Program::Inputs& inputs);
bool compileAndAttachShaders(const char* glsl,
int length,
GrGLuint programId,
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 66e333a..7b7b18d 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -371,6 +371,15 @@
this->uniformHandler()->appendUniformDecls(visibility, out);
}
+void GrGLSLProgramBuilder::addRTWidthUniform(const char* name) {
+ SkASSERT(!fUniformHandles.fRTWidthUni.isValid());
+ GrGLSLUniformHandler* uniformHandler = this->uniformHandler();
+ fUniformHandles.fRTWidthUni =
+ uniformHandler->internalAddUniformArray(kFragment_GrShaderFlag,
+ kHalf_GrSLType, kDefault_GrSLPrecision,
+ name, false, 0, nullptr);
+}
+
void GrGLSLProgramBuilder::addRTHeightUniform(const char* name) {
SkASSERT(!fUniformHandles.fRTHeightUni.isValid());
GrGLSLUniformHandler* uniformHandler = this->uniformHandler();
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index 8d263b8..073cfc6 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -49,8 +49,12 @@
return this->uniformHandler()->samplerSwizzle(handle);
}
- // Used to add a uniform for the RenderTarget height (used for frag position) without mangling
+ // Used to add a uniform for the RenderTarget width (used for sk_Width) without mangling
// the name of the uniform inside of a stage.
+ void addRTWidthUniform(const char* name);
+
+ // Used to add a uniform for the RenderTarget height (used for sk_Height and frag position)
+ // without mangling the name of the uniform inside of a stage.
void addRTHeightUniform(const char* name);
// Generates a name for a variable. The generated string will be name prefixed by the prefix
diff --git a/src/gpu/glsl/GrGLSLUniformHandler.h b/src/gpu/glsl/GrGLSLUniformHandler.h
index ae87faf..26681c1 100644
--- a/src/gpu/glsl/GrGLSLUniformHandler.h
+++ b/src/gpu/glsl/GrGLSLUniformHandler.h
@@ -20,7 +20,9 @@
// Handles for program uniforms (other than per-effect uniforms)
struct GrGLSLBuiltinUniformHandles {
GrGLSLProgramDataManager::UniformHandle fRTAdjustmentUni;
- // We use the render target height to provide a y-down frag coord when specifying
+ // Render target width, used to implement sk_Width
+ GrGLSLProgramDataManager::UniformHandle fRTWidthUni;
+ // Render target height, used to implement sk_Height and to calculate sk_FragCoord when
// origin_upper_left is not supported.
GrGLSLProgramDataManager::UniformHandle fRTHeightUni;
};
diff --git a/src/sksl/README b/src/sksl/README
index dd0af98..5062ed9 100644
--- a/src/sksl/README
+++ b/src/sksl/README
@@ -57,6 +57,7 @@
Use swizzles instead.
* Use texture() instead of textureProj(), e.g. texture(sampler2D, float3) is
equivalent to GLSL's textureProj(sampler2D, float3)
+* Render target width and height are available via sk_Width and sk_Height
* some built-in functions and one or two rarely-used language features are not
yet supported (sorry!)
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index 9d39595..4eab6ba 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -246,6 +246,12 @@
this->write("%s");
fFormatArgs.push_back(String("args.fOutputColor"));
break;
+ case SK_WIDTH_BUILTIN:
+ this->write("sk_Width");
+ break;
+ case SK_HEIGHT_BUILTIN:
+ this->write("sk_Height");
+ break;
default:
if (ref.fVariable.fType.kind() == Type::kSampler_Kind) {
this->write("%s");
@@ -446,6 +452,9 @@
}
}
+void CPPCodeGenerator::writeInputVars() {
+}
+
void CPPCodeGenerator::writePrivateVars() {
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {
diff --git a/src/sksl/SkSLCPPCodeGenerator.h b/src/sksl/SkSLCPPCodeGenerator.h
index 014f917..39255d6 100644
--- a/src/sksl/SkSLCPPCodeGenerator.h
+++ b/src/sksl/SkSLCPPCodeGenerator.h
@@ -68,6 +68,8 @@
void writeVarInitializer(const Variable& var, const Expression& value) override;
+ void writeInputVars() override;
+
void writePrivateVars();
void writePrivateVarValues();
diff --git a/src/sksl/SkSLCompiler.h b/src/sksl/SkSLCompiler.h
index f902962..339da2b 100644
--- a/src/sksl/SkSLCompiler.h
+++ b/src/sksl/SkSLCompiler.h
@@ -28,6 +28,8 @@
#define SK_LASTFRAGCOLOR_BUILTIN 10008
#define SK_MAIN_X_BUILTIN 10009
#define SK_MAIN_Y_BUILTIN 10010
+#define SK_WIDTH_BUILTIN 10011
+#define SK_HEIGHT_BUILTIN 10012
#define SK_FRAGCOORD_BUILTIN 15
#define SK_CLOCKWISE_BUILTIN 17
#define SK_VERTEXID_BUILTIN 42
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 85e26a1..a12357e 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -730,7 +730,7 @@
if (!fProgram.fSettings.fFlipY) {
this->write("gl_FragCoord");
} else if (const char* extension =
- fProgram.fSettings.fCaps->fragCoordConventionsExtensionString()) {
+ fProgram.fSettings.fCaps->fragCoordConventionsExtensionString()) {
if (!fSetupFragPositionGlobal) {
if (fProgram.fSettings.fCaps->generation() < k150_GrGLSLGeneration) {
this->writeExtension(extension);
@@ -740,20 +740,13 @@
}
this->write("gl_FragCoord");
} else {
- if (!fSetupFragPositionGlobal) {
+ if (!fSetupFragPositionLocal) {
// The Adreno compiler seems to be very touchy about access to "gl_FragCoord".
// Accessing glFragCoord.zw can cause a program to fail to link. Additionally,
// depending on the surrounding code, accessing .xy with a uniform involved can
// do the same thing. Copying gl_FragCoord.xy into a temp float2 beforehand
// (and only accessing .xy) seems to "fix" things.
const char* precision = usesPrecisionModifiers() ? "highp " : "";
- fGlobals.writeText("uniform ");
- fGlobals.writeText(precision);
- fGlobals.writeText("float " SKSL_RTHEIGHT_NAME ";\n");
- fSetupFragPositionGlobal = true;
- }
- if (!fSetupFragPositionLocal) {
- const char* precision = usesPrecisionModifiers() ? "highp " : "";
fFunctionHeader += precision;
fFunctionHeader += " vec2 _sktmpCoord = gl_FragCoord.xy;\n";
fFunctionHeader += precision;
@@ -777,6 +770,12 @@
case SK_FRAGCOORD_BUILTIN:
this->writeFragCoord();
break;
+ case SK_WIDTH_BUILTIN:
+ this->write("u_skRTWidth");
+ break;
+ case SK_HEIGHT_BUILTIN:
+ this->write("u_skRTHeight");
+ break;
case SK_CLOCKWISE_BUILTIN:
this->write(fProgram.fSettings.fFlipY ? "(!gl_FrontFacing)" : "gl_FrontFacing");
break;
@@ -1494,6 +1493,21 @@
}
}
+void GLSLCodeGenerator::writeInputVars() {
+ if (fProgram.fInputs.fRTWidth) {
+ const char* precision = usesPrecisionModifiers() ? "highp " : "";
+ fGlobals.writeText("uniform ");
+ fGlobals.writeText(precision);
+ fGlobals.writeText("float " SKSL_RTWIDTH_NAME ";\n");
+ }
+ if (fProgram.fInputs.fRTHeight) {
+ const char* precision = usesPrecisionModifiers() ? "highp " : "";
+ fGlobals.writeText("uniform ");
+ fGlobals.writeText(precision);
+ fGlobals.writeText("float " SKSL_RTHEIGHT_NAME ";\n");
+ }
+}
+
bool GLSLCodeGenerator::generateCode() {
fProgramKind = fProgram.fKind;
if (fProgramKind != Program::kPipelineStage_Kind) {
@@ -1512,6 +1526,7 @@
fOut = rawOut;
write_stringstream(fExtensions, *rawOut);
+ this->writeInputVars();
write_stringstream(fGlobals, *rawOut);
if (!fProgram.fSettings.fCaps->canUseFragCoord()) {
diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h
index 3083b3e..95aa464 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.h
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -118,7 +118,7 @@
void writeModifiers(const Modifiers& modifiers, bool globalContext);
- void writeGlobalVars(const VarDeclaration& vs);
+ virtual void writeInputVars();
virtual void writeVarInitializer(const Variable& var, const Expression& value);
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index a793ddd..5d4e5c3 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -1025,16 +1025,25 @@
}
case Symbol::kVariable_Kind: {
const Variable* var = (const Variable*) result;
-#ifndef SKSL_STANDALONE
- if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN) {
- fInputs.fFlipY = true;
- if (fSettings->fFlipY &&
- (!fSettings->fCaps ||
- !fSettings->fCaps->fragCoordConventionsExtensionString())) {
+ switch (var->fModifiers.fLayout.fBuiltin) {
+ case SK_WIDTH_BUILTIN:
+ fInputs.fRTWidth = true;
+ break;
+ case SK_HEIGHT_BUILTIN:
fInputs.fRTHeight = true;
- }
- }
+ break;
+#ifndef SKSL_STANDALONE
+ case SK_FRAGCOORD_BUILTIN:
+ if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN) {
+ fInputs.fFlipY = true;
+ if (fSettings->fFlipY &&
+ (!fSettings->fCaps ||
+ !fSettings->fCaps->fragCoordConventionsExtensionString())) {
+ fInputs.fRTHeight = true;
+ }
+ }
#endif
+ }
// default to kRead_RefKind; this will be corrected later if the variable is written to
return std::unique_ptr<VariableReference>(new VariableReference(
identifier.fOffset,
diff --git a/src/sksl/ir/SkSLProgram.h b/src/sksl/ir/SkSLProgram.h
index 59c9122..4cbde55 100644
--- a/src/sksl/ir/SkSLProgram.h
+++ b/src/sksl/ir/SkSLProgram.h
@@ -18,6 +18,9 @@
#include "SkSLProgramElement.h"
#include "SkSLSymbolTable.h"
+// name of the render target width uniform
+#define SKSL_RTWIDTH_NAME "u_skRTWidth"
+
// name of the render target height uniform
#define SKSL_RTHEIGHT_NAME "u_skRTHeight"
@@ -88,6 +91,9 @@
};
struct Inputs {
+ // if true, this program requires the render target width uniform to be defined
+ bool fRTWidth;
+
// if true, this program requires the render target height uniform to be defined
bool fRTHeight;
@@ -96,12 +102,13 @@
bool fFlipY;
void reset() {
+ fRTWidth = false;
fRTHeight = false;
fFlipY = false;
}
bool isEmpty() {
- return !fRTHeight && !fFlipY;
+ return !fRTWidth && !fRTHeight && !fFlipY;
}
};
diff --git a/src/sksl/sksl_fp.inc b/src/sksl/sksl_fp.inc
index d407fd0..c5edc00 100644
--- a/src/sksl/sksl_fp.inc
+++ b/src/sksl/sksl_fp.inc
@@ -20,6 +20,9 @@
layout(builtin=10004) out half4 sk_OutColor;
layout(builtin=10005) float2[] sk_TransformedCoords2D;
layout(builtin=10006) sampler2D[] sk_TextureSamplers;
+layout(builtin=10011) half sk_Width;
+layout(builtin=10012) half sk_Height;
half4 process(fragmentProcessor fp);
+
)
diff --git a/src/sksl/sksl_frag.inc b/src/sksl/sksl_frag.inc
index 202747a..5bc5f55 100644
--- a/src/sksl/sksl_frag.inc
+++ b/src/sksl/sksl_frag.inc
@@ -17,5 +17,7 @@
layout(location=0,index=0,builtin=10001) out half4 sk_FragColor;
layout(builtin=10008) half4 sk_LastFragColor;
+layout(builtin=10011) half sk_Width;
+layout(builtin=10012) half sk_Height;
)