OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkSLIRGenerator.h" | 8 #include "SkSLIRGenerator.h" |
9 | 9 |
10 #include "limits.h" | 10 #include "limits.h" |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 } | 175 } |
176 type = new Type(name, Type::kArray_Kind, *type, (int) count); | 176 type = new Type(name, Type::kArray_Kind, *type, (int) count); |
177 fSymbolTable->takeOwnership((Type*) type); | 177 fSymbolTable->takeOwnership((Type*) type); |
178 currentVarSizes.push_back(std::move(size)); | 178 currentVarSizes.push_back(std::move(size)); |
179 } else { | 179 } else { |
180 type = new Type(type->fName + "[]", Type::kArray_Kind, *type, -1
); | 180 type = new Type(type->fName + "[]", Type::kArray_Kind, *type, -1
); |
181 fSymbolTable->takeOwnership((Type*) type); | 181 fSymbolTable->takeOwnership((Type*) type); |
182 currentVarSizes.push_back(nullptr); | 182 currentVarSizes.push_back(nullptr); |
183 } | 183 } |
184 } | 184 } |
185 sizes.push_back(std::move(currentVarSizes)); | |
186 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi
ers, decl.fNames[i], | 185 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi
ers, decl.fNames[i], |
187 *type, storage)); | 186 *type, storage)); |
188 std::unique_ptr<Expression> value; | 187 std::unique_ptr<Expression> value; |
189 if (decl.fValues[i]) { | 188 if (decl.fValues[i]) { |
190 value = this->convertExpression(*decl.fValues[i]); | 189 value = this->convertExpression(*decl.fValues[i]); |
191 if (!value) { | 190 if (!value) { |
192 return nullptr; | 191 return nullptr; |
193 } | 192 } |
194 value = this->coerce(std::move(value), *type); | 193 value = this->coerce(std::move(value), *type); |
195 } | 194 } |
196 variables.push_back(var.get()); | 195 if ("gl_FragCoord" == decl.fNames[i] && (*fSymbolTable)[decl.fNames[i]])
{ |
197 fSymbolTable->add(decl.fNames[i], std::move(var)); | 196 // already defined, just update the modifiers |
198 values.push_back(std::move(value)); | 197 Variable* old = (Variable*) (*fSymbolTable)[decl.fNames[i]]; |
| 198 old->fModifiers = var->fModifiers; |
| 199 } else { |
| 200 variables.push_back(var.get()); |
| 201 fSymbolTable->add(decl.fNames[i], std::move(var)); |
| 202 values.push_back(std::move(value)); |
| 203 sizes.push_back(std::move(currentVarSizes)); |
| 204 } |
199 } | 205 } |
200 return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition, st
d::move(variables), | 206 return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition, |
201 std::move(sizes),
std::move(values))); | 207 baseType, |
| 208 std::move(variable
s), |
| 209 std::move(sizes), |
| 210 std::move(values))
); |
202 } | 211 } |
203 | 212 |
204 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { | 213 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { |
205 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.f
Test), | 214 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.f
Test), |
206 *fContext.fBool_Type); | 215 *fContext.fBool_Type); |
207 if (!test) { | 216 if (!test) { |
208 return nullptr; | 217 return nullptr; |
209 } | 218 } |
210 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue); | 219 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue); |
211 if (!ifTrue) { | 220 if (!ifTrue) { |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 } | 575 } |
567 case Symbol::kVariable_Kind: { | 576 case Symbol::kVariable_Kind: { |
568 const Variable* var = (const Variable*) result; | 577 const Variable* var = (const Variable*) result; |
569 this->markReadFrom(*var); | 578 this->markReadFrom(*var); |
570 return std::unique_ptr<VariableReference>(new VariableReference(iden
tifier.fPosition, | 579 return std::unique_ptr<VariableReference>(new VariableReference(iden
tifier.fPosition, |
571 *var
)); | 580 *var
)); |
572 } | 581 } |
573 case Symbol::kField_Kind: { | 582 case Symbol::kField_Kind: { |
574 const Field* field = (const Field*) result; | 583 const Field* field = (const Field*) result; |
575 VariableReference* base = new VariableReference(identifier.fPosition
, field->fOwner); | 584 VariableReference* base = new VariableReference(identifier.fPosition
, field->fOwner); |
576 return std::unique_ptr<Expression>(new FieldAccess(std::unique_ptr<E
xpression>(base), | 585 return std::unique_ptr<Expression>(new FieldAccess( |
577 field->fFieldInde
x)); | 586 std::unique_ptr<Expression>(ba
se), |
| 587 field->fFieldIndex, |
| 588 FieldAccess::kAnonymousInterfa
ceBlock_OwnerKind)); |
578 } | 589 } |
579 case Symbol::kType_Kind: { | 590 case Symbol::kType_Kind: { |
580 const Type* t = (const Type*) result; | 591 const Type* t = (const Type*) result; |
581 return std::unique_ptr<TypeReference>(new TypeReference(fContext, id
entifier.fPosition, | 592 return std::unique_ptr<TypeReference>(new TypeReference(fContext, id
entifier.fPosition, |
582 *t)); | 593 *t)); |
583 } | 594 } |
584 default: | 595 default: |
585 ABORT("unsupported symbol type %d\n", result->fKind); | 596 ABORT("unsupported symbol type %d\n", result->fKind); |
586 } | 597 } |
587 | 598 |
(...skipping 21 matching lines...) Expand all Loading... |
609 args.push_back(std::move(expr)); | 620 args.push_back(std::move(expr)); |
610 ASTIdentifier id(Position(), type.description()); | 621 ASTIdentifier id(Position(), type.description()); |
611 std::unique_ptr<Expression> ctor = this->convertIdentifier(id); | 622 std::unique_ptr<Expression> ctor = this->convertIdentifier(id); |
612 ASSERT(ctor); | 623 ASSERT(ctor); |
613 return this->call(Position(), std::move(ctor), std::move(args)); | 624 return this->call(Position(), std::move(ctor), std::move(args)); |
614 } | 625 } |
615 ABORT("cannot coerce %s to %s", expr->fType.description().c_str(), | 626 ABORT("cannot coerce %s to %s", expr->fType.description().c_str(), |
616 type.description().c_str()); | 627 type.description().c_str()); |
617 } | 628 } |
618 | 629 |
| 630 static bool is_matrix_multiply(const Type& left, const Type& right) { |
| 631 if (left.kind() == Type::kMatrix_Kind) { |
| 632 return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVect
or_Kind; |
| 633 } |
| 634 return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Ki
nd; |
| 635 } |
619 /** | 636 /** |
620 * Determines the operand and result types of a binary expression. Returns true
if the expression is | 637 * Determines the operand and result types of a binary expression. Returns true
if the expression is |
621 * legal, false otherwise. If false, the values of the out parameters are undefi
ned. | 638 * legal, false otherwise. If false, the values of the out parameters are undefi
ned. |
622 */ | 639 */ |
623 static bool determine_binary_type(const Context& context, | 640 static bool determine_binary_type(const Context& context, |
624 Token::Kind op, | 641 Token::Kind op, |
625 const Type& left, | 642 const Type& left, |
626 const Type& right, | 643 const Type& right, |
627 const Type** outLeftType, | 644 const Type** outLeftType, |
628 const Type** outRightType, | 645 const Type** outRightType, |
(...skipping 15 matching lines...) Expand all Loading... |
644 case Token::LOGICALOREQ: // fall through | 661 case Token::LOGICALOREQ: // fall through |
645 case Token::LOGICALANDEQ: // fall through | 662 case Token::LOGICALANDEQ: // fall through |
646 case Token::LOGICALXOREQ: | 663 case Token::LOGICALXOREQ: |
647 *outLeftType = context.fBool_Type.get(); | 664 *outLeftType = context.fBool_Type.get(); |
648 *outRightType = context.fBool_Type.get(); | 665 *outRightType = context.fBool_Type.get(); |
649 *outResultType = context.fBool_Type.get(); | 666 *outResultType = context.fBool_Type.get(); |
650 return left.canCoerceTo(*context.fBool_Type) && | 667 return left.canCoerceTo(*context.fBool_Type) && |
651 right.canCoerceTo(*context.fBool_Type); | 668 right.canCoerceTo(*context.fBool_Type); |
652 case Token::STAR: // fall through | 669 case Token::STAR: // fall through |
653 case Token::STAREQ: | 670 case Token::STAREQ: |
654 // FIXME need to handle non-square matrices | 671 if (is_matrix_multiply(left, right)) { |
655 if (left.kind() == Type::kMatrix_Kind && right.kind() == Type::kVect
or_Kind) { | 672 // determine final component type |
656 *outLeftType = &left; | 673 if (determine_binary_type(context, Token::STAR, left.componentTy
pe(), |
657 *outRightType = &right; | 674 right.componentType(), outLeftType, ou
tRightType, |
658 *outResultType = &right; | 675 outResultType, false)) { |
659 return left.rows() == right.columns(); | 676 *outLeftType = &(*outResultType)->toCompound(context, left.c
olumns(), |
660 } | 677 left.rows());; |
661 if (left.kind() == Type::kVector_Kind && right.kind() == Type::kMatr
ix_Kind) { | 678 *outRightType = &(*outResultType)->toCompound(context, right
.columns(), |
662 *outLeftType = &left; | 679 right.rows());
; |
663 *outRightType = &right; | 680 int leftColumns = left.columns(); |
664 *outResultType = &left; | 681 int leftRows = left.rows(); |
665 return left.columns() == right.columns(); | 682 int rightColumns; |
| 683 int rightRows; |
| 684 if (right.kind() == Type::kVector_Kind) { |
| 685 // matrix * vector treats the vector as a column vector,
so we need to |
| 686 // transpose it |
| 687 rightColumns = right.rows(); |
| 688 rightRows = right.columns(); |
| 689 ASSERT(rightColumns == 1); |
| 690 } else { |
| 691 rightColumns = right.columns(); |
| 692 rightRows = right.rows(); |
| 693 } |
| 694 if (rightColumns > 1) { |
| 695 *outResultType = &(*outResultType)->toCompound(context,
rightColumns, |
| 696 leftRows)
; |
| 697 } else { |
| 698 // result was a column vector, transpose it back to a ro
w |
| 699 *outResultType = &(*outResultType)->toCompound(context,
leftRows, |
| 700 rightColu
mns); |
| 701 } |
| 702 return leftColumns == rightRows; |
| 703 } else { |
| 704 return false; |
| 705 } |
666 } | 706 } |
667 // fall through | 707 // fall through |
668 default: | 708 default: |
669 isLogical = false; | 709 isLogical = false; |
670 } | 710 } |
671 // FIXME: need to disallow illegal operations like vec3 > vec3. Also do not
currently have | 711 // FIXME: need to disallow illegal operations like vec3 > vec3. Also do not
currently have |
672 // full support for numbers other than float. | 712 // full support for numbers other than float. |
673 if (left == right) { | 713 if (left == right) { |
674 *outLeftType = &left; | 714 *outLeftType = &left; |
675 *outRightType = &left; | 715 *outRightType = &left; |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 case Expression::kIndex_Kind: | 1258 case Expression::kIndex_Kind: |
1219 this->markWrittenTo(*((IndexExpression&) expr).fBase); | 1259 this->markWrittenTo(*((IndexExpression&) expr).fBase); |
1220 break; | 1260 break; |
1221 default: | 1261 default: |
1222 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
n() + "'"); | 1262 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
n() + "'"); |
1223 break; | 1263 break; |
1224 } | 1264 } |
1225 } | 1265 } |
1226 | 1266 |
1227 } | 1267 } |
OLD | NEW |