Index: src/sksl/SkSLIRGenerator.cpp |
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp |
index f250c4bb0cc0d59c44c2a72244c78ce0203f6985..db033d63b99836ee598a55cb8bc63b7213dc0f13 100644 |
--- a/src/sksl/SkSLIRGenerator.cpp |
+++ b/src/sksl/SkSLIRGenerator.cpp |
@@ -182,7 +182,6 @@ std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarD |
currentVarSizes.push_back(nullptr); |
} |
} |
- sizes.push_back(std::move(currentVarSizes)); |
auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifiers, decl.fNames[i], |
*type, storage)); |
std::unique_ptr<Expression> value; |
@@ -193,12 +192,22 @@ std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarD |
} |
value = this->coerce(std::move(value), *type); |
} |
- variables.push_back(var.get()); |
- fSymbolTable->add(decl.fNames[i], std::move(var)); |
- values.push_back(std::move(value)); |
+ if ("gl_FragCoord" == decl.fNames[i] && (*fSymbolTable)[decl.fNames[i]]) { |
+ // already defined, just update the modifiers |
+ Variable* old = (Variable*) (*fSymbolTable)[decl.fNames[i]]; |
+ old->fModifiers = var->fModifiers; |
+ } else { |
+ variables.push_back(var.get()); |
+ fSymbolTable->add(decl.fNames[i], std::move(var)); |
+ values.push_back(std::move(value)); |
+ sizes.push_back(std::move(currentVarSizes)); |
+ } |
} |
- return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition, std::move(variables), |
- std::move(sizes), std::move(values))); |
+ return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition, |
+ baseType, |
+ std::move(variables), |
+ std::move(sizes), |
+ std::move(values))); |
} |
std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { |
@@ -573,8 +582,10 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTIdentifier& |
case Symbol::kField_Kind: { |
const Field* field = (const Field*) result; |
VariableReference* base = new VariableReference(identifier.fPosition, field->fOwner); |
- return std::unique_ptr<Expression>(new FieldAccess(std::unique_ptr<Expression>(base), |
- field->fFieldIndex)); |
+ return std::unique_ptr<Expression>(new FieldAccess( |
+ std::unique_ptr<Expression>(base), |
+ field->fFieldIndex, |
+ FieldAccess::kAnonymousInterfaceBlock_OwnerKind)); |
} |
case Symbol::kType_Kind: { |
const Type* t = (const Type*) result; |
@@ -616,6 +627,12 @@ std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr |
type.description().c_str()); |
} |
+static bool is_matrix_multiply(const Type& left, const Type& right) { |
+ if (left.kind() == Type::kMatrix_Kind) { |
+ return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVector_Kind; |
+ } |
+ return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Kind; |
+} |
/** |
* Determines the operand and result types of a binary expression. Returns true if the expression is |
* legal, false otherwise. If false, the values of the out parameters are undefined. |
@@ -651,18 +668,41 @@ static bool determine_binary_type(const Context& context, |
right.canCoerceTo(*context.fBool_Type); |
case Token::STAR: // fall through |
case Token::STAREQ: |
- // FIXME need to handle non-square matrices |
- if (left.kind() == Type::kMatrix_Kind && right.kind() == Type::kVector_Kind) { |
- *outLeftType = &left; |
- *outRightType = &right; |
- *outResultType = &right; |
- return left.rows() == right.columns(); |
- } |
- if (left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Kind) { |
- *outLeftType = &left; |
- *outRightType = &right; |
- *outResultType = &left; |
- return left.columns() == right.columns(); |
+ if (is_matrix_multiply(left, right)) { |
+ // determine final component type |
+ if (determine_binary_type(context, Token::STAR, left.componentType(), |
+ right.componentType(), outLeftType, outRightType, |
+ outResultType, false)) { |
+ *outLeftType = &(*outResultType)->toCompound(context, left.columns(), |
+ left.rows());; |
+ *outRightType = &(*outResultType)->toCompound(context, right.columns(), |
+ right.rows());; |
+ int leftColumns = left.columns(); |
+ int leftRows = left.rows(); |
+ int rightColumns; |
+ int rightRows; |
+ if (right.kind() == Type::kVector_Kind) { |
+ // matrix * vector treats the vector as a column vector, so we need to |
+ // transpose it |
+ rightColumns = right.rows(); |
+ rightRows = right.columns(); |
+ ASSERT(rightColumns == 1); |
+ } else { |
+ rightColumns = right.columns(); |
+ rightRows = right.rows(); |
+ } |
+ if (rightColumns > 1) { |
+ *outResultType = &(*outResultType)->toCompound(context, rightColumns, |
+ leftRows); |
+ } else { |
+ // result was a column vector, transpose it back to a row |
+ *outResultType = &(*outResultType)->toCompound(context, leftRows, |
+ rightColumns); |
+ } |
+ return leftColumns == rightRows; |
+ } else { |
+ return false; |
+ } |
} |
// fall through |
default: |