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>
This commit is contained in:
Ethan Nicholas 2017-04-19 15:54:07 -04:00 committed by Skia Commit-Bot
parent 7b2391bc06
commit 5338f99a8a
6 changed files with 83 additions and 22 deletions

View File

@ -4005,20 +4005,17 @@ bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w); GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w);
GrGLfloat sy0 = (GrGLfloat)srcRect.fTop; GrGLfloat sy0 = (GrGLfloat)srcRect.fTop;
GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h); GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h);
int sw = src->width();
int sh = src->height(); int sh = src->height();
if (kBottomLeft_GrSurfaceOrigin == src->origin()) { if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
sy0 = sh - sy0; sy0 = sh - sy0;
sy1 = sh - sy1; sy1 = sh - sy1;
} }
// src rect edges in normalized texture space (0 to 1) unless we're using a RECTANGLE texture. // src rect edges in normalized texture space (0 to 1)
GrGLenum srcTarget = srcTex->target(); sx0 /= sw;
if (GR_GL_TEXTURE_RECTANGLE != srcTarget) { sx1 /= sw;
int sw = src->width(); sy0 /= sh;
sx0 /= sw; sy1 /= sh;
sx1 /= sw;
sy0 /= sh;
sy1 /= sh;
}
GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0)); GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0));
GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform, GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform,

View File

@ -72,18 +72,7 @@ void GrGLSLShaderBuilder::appendTextureLookup(SkString* out,
const char* coordName, const char* coordName,
GrSLType varyingType) const { GrSLType varyingType) const {
const GrShaderVar& sampler = fProgramBuilder->samplerVariable(samplerHandle); const GrShaderVar& sampler = fProgramBuilder->samplerVariable(samplerHandle);
GrSLType samplerType = sampler.getType(); out->appendf("texture(%s, %s)", sampler.c_str(), coordName);
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);
}
append_texture_swizzle(out, fProgramBuilder->samplerSwizzle(samplerHandle)); append_texture_swizzle(out, fProgramBuilder->samplerSwizzle(samplerHandle));
} }

View File

@ -1112,6 +1112,37 @@ std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(
std::move(ifFalse))); 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, std::unique_ptr<Expression> IRGenerator::call(Position position,
const FunctionDeclaration& function, const FunctionDeclaration& function,
std::vector<std::unique_ptr<Expression>> arguments) { std::vector<std::unique_ptr<Expression>> arguments) {
@ -1149,6 +1180,10 @@ std::unique_ptr<Expression> IRGenerator::call(Position position,
this->markWrittenTo(*arguments[i], true); 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, return std::unique_ptr<FunctionCall>(new FunctionCall(position, *returnType, function,
std::move(arguments))); std::move(arguments)));
} }

View File

@ -164,6 +164,7 @@ private:
std::unique_ptr<Statement> convertVarDeclarationStatement(const ASTVarDeclarationStatement& s); std::unique_ptr<Statement> convertVarDeclarationStatement(const ASTVarDeclarationStatement& s);
std::unique_ptr<Statement> convertWhile(const ASTWhileStatement& w); std::unique_ptr<Statement> convertWhile(const ASTWhileStatement& w);
void fixRectSampling(std::vector<std::unique_ptr<Expression>>& arguments);
void checkValid(const Expression& expr); void checkValid(const Expression& expr);
void markWrittenTo(const Expression& expr, bool readWrite); void markWrittenTo(const Expression& expr, bool readWrite);

View File

@ -281,6 +281,7 @@ float texture(sampler2DArrayShadow sampler, vec4 P);
*/ */
$gvec4 texture($gsampler2DRect sampler, vec2 P); $gvec4 texture($gsampler2DRect sampler, vec2 P);
$gvec4 texture($gsampler2DRect sampler, vec3 P);
/* /*
float texture(sampler2DRectShadow sampler, vec3 P); float texture(sampler2DRectShadow sampler, vec3 P);
@ -312,7 +313,6 @@ float textureProj(sampler1DShadow sampler, vec4 P);
float textureProj(sampler1DShadow sampler, vec4 P, float bias); float textureProj(sampler1DShadow sampler, vec4 P, float bias);
float textureProj(sampler2DShadow sampler, vec4 P); float textureProj(sampler2DShadow sampler, vec4 P);
float textureProj(sampler2DShadow sampler, vec4 P, float bias); float textureProj(sampler2DShadow sampler, vec4 P, float bias);
$gvec4 textureProj($gsampler2DRect sampler, vec3 P);
$gvec4 textureProj($gsampler2DRect sampler, vec4 P); $gvec4 textureProj($gsampler2DRect sampler, vec4 P);
float textureProj(sampler2DRectShadow sampler, vec4 P); float textureProj(sampler2DRectShadow sampler, vec4 P);
$gvec4 textureLod($gsampler1D sampler, float P, float lod); $gvec4 textureLod($gsampler1D sampler, float P, float lod);

View File

@ -864,4 +864,43 @@ DEF_TEST(SkSLSwitch, r) {
"}\n"); "}\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 #endif