Index: src/sksl/SkSLIRGenerator.cpp |
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp |
index 9910513fbbdb386cef66de55f26d796f457b55c7..975b05f1c99a98bfc36b3a4870416f39cd013c55 100644 |
--- a/src/sksl/SkSLIRGenerator.cpp |
+++ b/src/sksl/SkSLIRGenerator.cpp |
@@ -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))); |
} |