Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: src/sksl/SkSLGLSLCodeGenerator.cpp

Issue 2288033003: Turned on SkSL->GLSL compiler (Closed)
Patch Set: wording cleanup Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "SkSLGLSLCodeGenerator.h" 8 #include "SkSLGLSLCodeGenerator.h"
9 9
10 #include "string.h" 10 #include "string.h"
11 11
12 #include "GLSL.std.450.h" 12 #include "GLSL.std.450.h"
13 13
14 #include "ir/SkSLExpressionStatement.h" 14 #include "ir/SkSLExpressionStatement.h"
15 #include "ir/SkSLExtension.h" 15 #include "ir/SkSLExtension.h"
16 #include "ir/SkSLIndexExpression.h" 16 #include "ir/SkSLIndexExpression.h"
17 #include "ir/SkSLVariableReference.h" 17 #include "ir/SkSLVariableReference.h"
18 18
19 #define SK_FRAGCOLOR_BUILTIN 10001
20
19 namespace SkSL { 21 namespace SkSL {
20 22
21 void GLSLCodeGenerator::write(const char* s) { 23 void GLSLCodeGenerator::write(const char* s) {
22 if (s[0] == 0) { 24 if (s[0] == 0) {
23 return; 25 return;
24 } 26 }
25 if (fAtLineStart) { 27 if (fAtLineStart) {
26 for (int i = 0; i < fIndentation; i++) { 28 for (int i = 0; i < fIndentation; i++) {
27 *fOut << " "; 29 *fOut << " ";
28 } 30 }
(...skipping 30 matching lines...) Expand all
59 if (*search == type) { 61 if (*search == type) {
60 // already written 62 // already written
61 this->write(type.name()); 63 this->write(type.name());
62 return; 64 return;
63 } 65 }
64 } 66 }
65 fWrittenStructs.push_back(&type); 67 fWrittenStructs.push_back(&type);
66 this->writeLine("struct " + type.name() + " {"); 68 this->writeLine("struct " + type.name() + " {");
67 fIndentation++; 69 fIndentation++;
68 for (const auto& f : type.fields()) { 70 for (const auto& f : type.fields()) {
69 this->writeModifiers(f.fModifiers); 71 this->writeModifiers(f.fModifiers, false);
70 // sizes (which must be static in structs) are part of the type name here 72 // sizes (which must be static in structs) are part of the type name here
71 this->writeType(*f.fType); 73 this->writeType(*f.fType);
72 this->writeLine(" " + f.fName + ";"); 74 this->writeLine(" " + f.fName + ";");
73 } 75 }
74 fIndentation--; 76 fIndentation--;
75 this->writeLine("}"); 77 this->writeLine("}");
76 } else { 78 } else {
77 this->write(type.name()); 79 this->write(type.name());
78 } 80 }
79 } 81 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 this->writeTernaryExpression((TernaryExpression&) expr, parentPreced ence); 119 this->writeTernaryExpression((TernaryExpression&) expr, parentPreced ence);
118 break; 120 break;
119 case Expression::kIndex_Kind: 121 case Expression::kIndex_Kind:
120 this->writeIndexExpression((IndexExpression&) expr); 122 this->writeIndexExpression((IndexExpression&) expr);
121 break; 123 break;
122 default: 124 default:
123 ABORT("unsupported expression: %s", expr.description().c_str()); 125 ABORT("unsupported expression: %s", expr.description().c_str());
124 } 126 }
125 } 127 }
126 128
129 static bool is_abs(Expression& expr) {
130 if (expr.fKind != Expression::kFunctionCall_Kind) {
131 return false;
132 }
133 return ((FunctionCall&) expr).fFunction.fName == "abs";
134 }
135
136 // turns min(abs(x), y) into (abs(x) > y ? y : abs(x)) to avoid a Tegra3 compile r bug. Note that
bsalomon 2016/09/08 19:51:37 Can we make it safe by introducing an intermediate
ethannicholas 2016/09/09 16:34:54 Done.
137 // this is unsafe when the expressions have side effects due to the double evalu ation.
138 void GLSLCodeGenerator::writeMinAbsHack(Expression& absExpr, Expression& otherEx pr) {
139 ASSERT(!fCaps.fCanUseMinAndAbsTogether);
140 this->write("(");
141 this->writeExpression(absExpr, kTopLevel_Precedence);
142 this->write(" > ");
143 this->writeExpression(otherExpr, kRelational_Precedence);
144 this->write(" ? ");
145 this->writeExpression(otherExpr, kTernary_Precedence);
146 this->write(" : ");
147 this->writeExpression(absExpr, kTernary_Precedence);
148 this->write(")");
149 }
150
127 void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) { 151 void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
152 if (!fCaps.fCanUseMinAndAbsTogether && c.fFunction.fName == "min") {
153 ASSERT(c.fArguments.size() == 2);
154 if (is_abs(*c.fArguments[0])) {
155 writeMinAbsHack(*c.fArguments[0], *c.fArguments[1]);
bsalomon 2016/09/08 19:51:37 this->
ethannicholas 2016/09/09 16:34:54 Done.
156 return;
157 }
158 if (is_abs(*c.fArguments[1])) {
159 writeMinAbsHack(*c.fArguments[1], *c.fArguments[0]);
bsalomon 2016/09/08 19:51:37 this->
160 return;
161 }
162 }
128 this->write(c.fFunction.fName + "("); 163 this->write(c.fFunction.fName + "(");
129 const char* separator = ""; 164 const char* separator = "";
130 for (const auto& arg : c.fArguments) { 165 for (const auto& arg : c.fArguments) {
131 this->write(separator); 166 this->write(separator);
132 separator = ", "; 167 separator = ", ";
133 this->writeExpression(*arg, kSequence_Precedence); 168 this->writeExpression(*arg, kSequence_Precedence);
134 } 169 }
135 this->write(")"); 170 this->write(")");
136 } 171 }
137 172
138 void GLSLCodeGenerator::writeConstructor(const Constructor& c) { 173 void GLSLCodeGenerator::writeConstructor(const Constructor& c) {
139 this->write(c.fType.name() + "("); 174 this->write(c.fType.name() + "(");
140 const char* separator = ""; 175 const char* separator = "";
141 for (const auto& arg : c.fArguments) { 176 for (const auto& arg : c.fArguments) {
142 this->write(separator); 177 this->write(separator);
143 separator = ", "; 178 separator = ", ";
144 this->writeExpression(*arg, kSequence_Precedence); 179 this->writeExpression(*arg, kSequence_Precedence);
145 } 180 }
146 this->write(")"); 181 this->write(")");
147 } 182 }
148 183
149 void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) { 184 void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) {
150 this->write(ref.fVariable.fName); 185 if (ref.fVariable.fModifiers.fLayout.fBuiltin == SK_FRAGCOLOR_BUILTIN) {
186 this->write("gl_FragColor");
187 } else {
188 this->write(ref.fVariable.fName);
189 }
151 } 190 }
152 191
153 void GLSLCodeGenerator::writeIndexExpression(const IndexExpression& expr) { 192 void GLSLCodeGenerator::writeIndexExpression(const IndexExpression& expr) {
154 this->writeExpression(*expr.fBase, kPostfix_Precedence); 193 this->writeExpression(*expr.fBase, kPostfix_Precedence);
155 this->write("["); 194 this->write("[");
156 this->writeExpression(*expr.fIndex, kTopLevel_Precedence); 195 this->writeExpression(*expr.fIndex, kTopLevel_Precedence);
157 this->write("]"); 196 this->write("]");
158 } 197 }
159 198
160 void GLSLCodeGenerator::writeFieldAccess(const FieldAccess& f) { 199 void GLSLCodeGenerator::writeFieldAccess(const FieldAccess& f) {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 this->write(to_string(f.fValue)); 316 this->write(to_string(f.fValue));
278 } 317 }
279 318
280 void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) { 319 void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
281 this->writeType(f.fDeclaration.fReturnType); 320 this->writeType(f.fDeclaration.fReturnType);
282 this->write(" " + f.fDeclaration.fName + "("); 321 this->write(" " + f.fDeclaration.fName + "(");
283 const char* separator = ""; 322 const char* separator = "";
284 for (const auto& param : f.fDeclaration.fParameters) { 323 for (const auto& param : f.fDeclaration.fParameters) {
285 this->write(separator); 324 this->write(separator);
286 separator = ", "; 325 separator = ", ";
287 this->writeModifiers(param->fModifiers); 326 this->writeModifiers(param->fModifiers, false);
288 this->writeType(param->fType); 327 this->writeType(param->fType);
289 this->write(" " + param->fName); 328 this->write(" " + param->fName);
290 } 329 }
291 this->write(") "); 330 this->write(") ");
292 this->writeBlock(*f.fBody); 331 this->writeBlock(*f.fBody);
293 this->writeLine(); 332 this->writeLine();
294 } 333 }
295 334
296 void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers) { 335 void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers,
297 this->write(modifiers.description()); 336 bool globalContext) {
337 if (modifiers.fFlags & Modifiers::kNoPerspective_Flag) {
338 this->write("noperspective ");
339 }
340 if (modifiers.fFlags & Modifiers::kFlat_Flag) {
341 this->write("flat ");
342 }
343 std::string layout = modifiers.fLayout.description();
344 if (layout.length()) {
345 this->write(layout + " ");
346 }
347 if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
348 (modifiers.fFlags & Modifiers::kOut_Flag)) {
349 this->write("inout ");
350 } else if (modifiers.fFlags & Modifiers::kIn_Flag) {
351 if (globalContext && fCaps.fVersion < 130) {
352 this->write(fProgramKind == Program::kVertex_Kind ? "attribute "
353 : "varying ");
354 } else {
355 this->write("in ");
356 }
357 } else if (modifiers.fFlags & Modifiers::kOut_Flag) {
358 if (globalContext && fCaps.fVersion < 130) {
359 this->write("varying ");
360 } else {
361 this->write("out ");
362 }
363 }
364 if (modifiers.fFlags & Modifiers::kUniform_Flag) {
365 this->write("uniform ");
366 }
367 if (modifiers.fFlags & Modifiers::kConst_Flag) {
368 this->write("const ");
369 }
370 if (fCaps.fUsesPrecisionModifiers) {
371 bool modifier = false;
372 if (modifiers.fFlags & Modifiers::kLowp_Flag) {
373 this->write("lowp ");
374 modifier = true;
375 }
376 if (modifiers.fFlags & Modifiers::kHighp_Flag) {
377 this->write("highp ");
378 modifier = true;
379 }
380 if (!modifier) {
381 this->write("mediump ");
382 }
383 }
298 } 384 }
299 385
300 void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { 386 void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
301 if (intf.fVariable.fName == "gl_PerVertex") { 387 if (intf.fVariable.fName == "gl_PerVertex") {
302 return; 388 return;
303 } 389 }
304 this->writeModifiers(intf.fVariable.fModifiers); 390 this->writeModifiers(intf.fVariable.fModifiers, true);
305 this->writeLine(intf.fVariable.fType.name() + " {"); 391 this->writeLine(intf.fVariable.fType.name() + " {");
306 fIndentation++; 392 fIndentation++;
307 for (const auto& f : intf.fVariable.fType.fields()) { 393 for (const auto& f : intf.fVariable.fType.fields()) {
308 this->writeModifiers(f.fModifiers); 394 this->writeModifiers(f.fModifiers, false);
309 this->writeType(*f.fType); 395 this->writeType(*f.fType);
310 this->writeLine(" " + f.fName + ";"); 396 this->writeLine(" " + f.fName + ";");
311 } 397 }
312 fIndentation--; 398 fIndentation--;
313 this->writeLine("};"); 399 this->writeLine("};");
314 } 400 }
315 401
316 void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl) { 402 void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool g lobal) {
317 ASSERT(decl.fVars.size() > 0); 403 ASSERT(decl.fVars.size() > 0);
318 this->writeModifiers(decl.fVars[0].fVar->fModifiers); 404 this->writeModifiers(decl.fVars[0].fVar->fModifiers, global);
319 this->writeType(decl.fBaseType); 405 this->writeType(decl.fBaseType);
320 std::string separator = " "; 406 std::string separator = " ";
321 for (const auto& var : decl.fVars) { 407 for (const auto& var : decl.fVars) {
322 ASSERT(var.fVar->fModifiers == decl.fVars[0].fVar->fModifiers); 408 ASSERT(var.fVar->fModifiers == decl.fVars[0].fVar->fModifiers);
323 this->write(separator); 409 this->write(separator);
324 separator = ", "; 410 separator = ", ";
325 this->write(var.fVar->fName); 411 this->write(var.fVar->fName);
326 for (const auto& size : var.fSizes) { 412 for (const auto& size : var.fSizes) {
327 this->write("["); 413 this->write("[");
328 this->writeExpression(*size, kTopLevel_Precedence); 414 this->writeExpression(*size, kTopLevel_Precedence);
(...skipping 13 matching lines...) Expand all
342 this->writeBlock((Block&) s); 428 this->writeBlock((Block&) s);
343 break; 429 break;
344 case Statement::kExpression_Kind: 430 case Statement::kExpression_Kind:
345 this->writeExpression(*((ExpressionStatement&) s).fExpression, kTopL evel_Precedence); 431 this->writeExpression(*((ExpressionStatement&) s).fExpression, kTopL evel_Precedence);
346 this->write(";"); 432 this->write(";");
347 break; 433 break;
348 case Statement::kReturn_Kind: 434 case Statement::kReturn_Kind:
349 this->writeReturnStatement((ReturnStatement&) s); 435 this->writeReturnStatement((ReturnStatement&) s);
350 break; 436 break;
351 case Statement::kVarDeclarations_Kind: 437 case Statement::kVarDeclarations_Kind:
352 this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclara tion); 438 this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclara tion, false);
353 break; 439 break;
354 case Statement::kIf_Kind: 440 case Statement::kIf_Kind:
355 this->writeIfStatement((IfStatement&) s); 441 this->writeIfStatement((IfStatement&) s);
356 break; 442 break;
357 case Statement::kFor_Kind: 443 case Statement::kFor_Kind:
358 this->writeForStatement((ForStatement&) s); 444 this->writeForStatement((ForStatement&) s);
359 break; 445 break;
360 case Statement::kWhile_Kind: 446 case Statement::kWhile_Kind:
361 this->writeWhileStatement((WhileStatement&) s); 447 this->writeWhileStatement((WhileStatement&) s);
362 break; 448 break;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 if (r.fExpression) { 523 if (r.fExpression) {
438 this->write(" "); 524 this->write(" ");
439 this->writeExpression(*r.fExpression, kTopLevel_Precedence); 525 this->writeExpression(*r.fExpression, kTopLevel_Precedence);
440 } 526 }
441 this->write(";"); 527 this->write(";");
442 } 528 }
443 529
444 void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) { 530 void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) {
445 ASSERT(fOut == nullptr); 531 ASSERT(fOut == nullptr);
446 fOut = &out; 532 fOut = &out;
533 fProgramKind = program.fKind;
447 this->write("#version " + to_string(fCaps.fVersion)); 534 this->write("#version " + to_string(fCaps.fVersion));
448 if (fCaps.fStandard == GLCaps::kGLES_Standard) { 535 if (fCaps.fStandard == GLCaps::kGLES_Standard) {
449 this->write(" es"); 536 this->write(" es");
537 } else if (fCaps.fIsCoreProfile) {
538 this->write(" core");
450 } 539 }
451 this->writeLine(); 540 this->writeLine();
452 for (const auto& e : program.fElements) { 541 for (const auto& e : program.fElements) {
453 switch (e->fKind) { 542 switch (e->fKind) {
454 case ProgramElement::kExtension_Kind: 543 case ProgramElement::kExtension_Kind:
455 this->writeExtension((Extension&) *e); 544 this->writeExtension((Extension&) *e);
456 break; 545 break;
457 case ProgramElement::kVar_Kind: { 546 case ProgramElement::kVar_Kind: {
458 VarDeclarations& decl = (VarDeclarations&) *e; 547 VarDeclarations& decl = (VarDeclarations&) *e;
459 if (decl.fVars.size() > 0 && 548 if (decl.fVars.size() > 0) {
460 decl.fVars[0].fVar->fModifiers.fLayout.fBuiltin == -1) { 549 int builtin = decl.fVars[0].fVar->fModifiers.fLayout.fBuilti n;
461 this->writeVarDeclarations(decl); 550 if (builtin == -1) {
462 this->writeLine(); 551 // normal var
552 this->writeVarDeclarations(decl, true);
553 this->writeLine();
554 } else if (builtin == SK_FRAGCOLOR_BUILTIN &&
555 fCaps.fMustDeclareFragmentShaderOutput) {
556 this->writeLine("out vec4 gl_FragColor;");
557 }
463 } 558 }
464 break; 559 break;
465 } 560 }
466 case ProgramElement::kInterfaceBlock_Kind: 561 case ProgramElement::kInterfaceBlock_Kind:
467 this->writeInterfaceBlock((InterfaceBlock&) *e); 562 this->writeInterfaceBlock((InterfaceBlock&) *e);
468 break; 563 break;
469 case ProgramElement::kFunction_Kind: 564 case ProgramElement::kFunction_Kind:
470 this->writeFunction((FunctionDefinition&) *e); 565 this->writeFunction((FunctionDefinition&) *e);
471 break; 566 break;
472 default: 567 default:
473 printf("%s\n", e->description().c_str()); 568 printf("%s\n", e->description().c_str());
474 ABORT("unsupported program element"); 569 ABORT("unsupported program element");
475 } 570 }
476 } 571 }
477 fOut = nullptr; 572 fOut = nullptr;
478 } 573 }
479 574
480 } 575 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698