rectangle texture scaling is now handled in skslc
Bug: skia:
Change-Id: I658a95576143d69656cd63aec44ff65d430d332f
Reviewed-on: https://skia-review.googlesource.com/13813
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index d585e09..7665c2a 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -4005,20 +4005,17 @@
GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w);
GrGLfloat sy0 = (GrGLfloat)srcRect.fTop;
GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h);
+ int sw = src->width();
int sh = src->height();
if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
sy0 = sh - sy0;
sy1 = sh - sy1;
}
- // src rect edges in normalized texture space (0 to 1) unless we're using a RECTANGLE texture.
- GrGLenum srcTarget = srcTex->target();
- if (GR_GL_TEXTURE_RECTANGLE != srcTarget) {
- int sw = src->width();
- sx0 /= sw;
- sx1 /= sw;
- sy0 /= sh;
- sy1 /= sh;
- }
+ // src rect edges in normalized texture space (0 to 1)
+ sx0 /= sw;
+ sx1 /= sw;
+ sy0 /= sh;
+ sy1 /= sh;
GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0));
GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform,
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
index 8658766..2c7e5e4 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
@@ -72,18 +72,7 @@
const char* coordName,
GrSLType varyingType) const {
const GrShaderVar& sampler = fProgramBuilder->samplerVariable(samplerHandle);
- GrSLType samplerType = sampler.getType();
- if (samplerType == kTexture2DRectSampler_GrSLType) {
- if (varyingType == kVec2f_GrSLType) {
- out->appendf("texture(%s, textureSize(%s) * %s)",
- sampler.c_str(), sampler.c_str(), coordName);
- } else {
- out->appendf("texture(%s, vec3(textureSize(%s) * %s.xy, %s.z))",
- sampler.c_str(), sampler.c_str(), coordName, coordName);
- }
- } else {
- out->appendf("texture(%s, %s)", sampler.c_str(), coordName);
- }
+ out->appendf("texture(%s, %s)", sampler.c_str(), coordName);
append_texture_swizzle(out, fProgramBuilder->samplerSwizzle(samplerHandle));
}
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 9910513..975b05f 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -1112,6 +1112,37 @@
std::move(ifFalse)));
}
+// scales the texture coordinates by the texture size for sampling rectangle textures.
+// For vec2 coordinates, implements the transformation:
+// texture(sampler, coord) -> texture(sampler, textureSize(sampler) * coord)
+// For vec3 coordinates, implements the transformation:
+// texture(sampler, coord) -> texture(sampler, vec3(textureSize(sampler), 1.0) * coord))
+void IRGenerator::fixRectSampling(std::vector<std::unique_ptr<Expression>>& arguments) {
+ ASSERT(arguments.size() == 2);
+ ASSERT(arguments[0]->fType == *fContext.fSampler2DRect_Type);
+ ASSERT(arguments[0]->fKind == Expression::kVariableReference_Kind);
+ const Variable& sampler = ((VariableReference&) *arguments[0]).fVariable;
+ const Symbol* textureSizeSymbol = (*fSymbolTable)["textureSize"];
+ ASSERT(textureSizeSymbol->fKind == Symbol::kFunctionDeclaration_Kind);
+ const FunctionDeclaration& textureSize = (FunctionDeclaration&) *textureSizeSymbol;
+ std::vector<std::unique_ptr<Expression>> sizeArguments;
+ sizeArguments.emplace_back(new VariableReference(Position(), sampler));
+ std::unique_ptr<Expression> vec2Size = call(Position(), textureSize, std::move(sizeArguments));
+ const Type& type = arguments[1]->fType;
+ std::unique_ptr<Expression> scale;
+ if (type == *fContext.fVec2_Type) {
+ scale = std::move(vec2Size);
+ } else {
+ ASSERT(type == *fContext.fVec3_Type);
+ std::vector<std::unique_ptr<Expression>> vec3Arguments;
+ vec3Arguments.push_back(std::move(vec2Size));
+ vec3Arguments.emplace_back(new FloatLiteral(fContext, Position(), 1.0));
+ scale.reset(new Constructor(Position(), *fContext.fVec3_Type, std::move(vec3Arguments)));
+ }
+ arguments[1].reset(new BinaryExpression(Position(), std::move(scale), Token::STAR,
+ std::move(arguments[1]), type));
+}
+
std::unique_ptr<Expression> IRGenerator::call(Position position,
const FunctionDeclaration& function,
std::vector<std::unique_ptr<Expression>> arguments) {
@@ -1149,6 +1180,10 @@
this->markWrittenTo(*arguments[i], true);
}
}
+ if (function.fBuiltin && function.fName == "texture" &&
+ arguments[0]->fType == *fContext.fSampler2DRect_Type) {
+ this->fixRectSampling(arguments);
+ }
return std::unique_ptr<FunctionCall>(new FunctionCall(position, *returnType, function,
std::move(arguments)));
}
diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h
index b0a449a..d4a6846 100644
--- a/src/sksl/SkSLIRGenerator.h
+++ b/src/sksl/SkSLIRGenerator.h
@@ -164,6 +164,7 @@
std::unique_ptr<Statement> convertVarDeclarationStatement(const ASTVarDeclarationStatement& s);
std::unique_ptr<Statement> convertWhile(const ASTWhileStatement& w);
+ void fixRectSampling(std::vector<std::unique_ptr<Expression>>& arguments);
void checkValid(const Expression& expr);
void markWrittenTo(const Expression& expr, bool readWrite);
diff --git a/src/sksl/sksl.include b/src/sksl/sksl.include
index 11e3710..3d730d4 100644
--- a/src/sksl/sksl.include
+++ b/src/sksl/sksl.include
@@ -281,6 +281,7 @@
*/
$gvec4 texture($gsampler2DRect sampler, vec2 P);
+$gvec4 texture($gsampler2DRect sampler, vec3 P);
/*
float texture(sampler2DRectShadow sampler, vec3 P);
@@ -312,7 +313,6 @@
float textureProj(sampler1DShadow sampler, vec4 P, float bias);
float textureProj(sampler2DShadow sampler, vec4 P);
float textureProj(sampler2DShadow sampler, vec4 P, float bias);
-$gvec4 textureProj($gsampler2DRect sampler, vec3 P);
$gvec4 textureProj($gsampler2DRect sampler, vec4 P);
float textureProj(sampler2DRectShadow sampler, vec4 P);
$gvec4 textureLod($gsampler1D sampler, float P, float lod);
diff --git a/tests/SkSLGLSLTest.cpp b/tests/SkSLGLSLTest.cpp
index 51a1f63..6151b94 100644
--- a/tests/SkSLGLSLTest.cpp
+++ b/tests/SkSLGLSLTest.cpp
@@ -864,4 +864,43 @@
"}\n");
}
+DEF_TEST(SkSLRectangleTexture, r) {
+ test(r,
+ "uniform sampler2D test;"
+ "void main() {"
+ " sk_FragColor = texture(test, vec2(1));"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ "#version 400\n"
+ "out vec4 sk_FragColor;\n"
+ "uniform sampler2D test;\n"
+ "void main() {\n"
+ " sk_FragColor = texture(test, vec2(1.0));\n"
+ "}\n");
+ test(r,
+ "uniform sampler2DRect test;"
+ "void main() {"
+ " sk_FragColor = texture(test, vec2(1));"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ "#version 400\n"
+ "out vec4 sk_FragColor;\n"
+ "uniform sampler2DRect test;\n"
+ "void main() {\n"
+ " sk_FragColor = texture(test, textureSize(test) * vec2(1.0));\n"
+ "}\n");
+ test(r,
+ "uniform sampler2DRect test;"
+ "void main() {"
+ " sk_FragColor = texture(test, vec3(1));"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ "#version 400\n"
+ "out vec4 sk_FragColor;\n"
+ "uniform sampler2DRect test;\n"
+ "void main() {\n"
+ " sk_FragColor = texture(test, vec3(textureSize(test), 1.0) * vec3(1.0));\n"
+ "}\n");
+}
+
#endif