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 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,

View File

@ -72,18 +72,7 @@ void GrGLSLShaderBuilder::appendTextureLookup(SkString* out,
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));
}

View File

@ -1112,6 +1112,37 @@ std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(
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 @@ std::unique_ptr<Expression> IRGenerator::call(Position position,
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)));
}

View File

@ -164,6 +164,7 @@ private:
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);

View File

@ -281,6 +281,7 @@ float texture(sampler2DArrayShadow sampler, vec4 P);
*/
$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 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);

View File

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