SkSLGLSLCodeGenerator.cpp 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604
  1. /*
  2. * Copyright 2016 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/sksl/SkSLGLSLCodeGenerator.h"
  8. #include "src/sksl/SkSLCompiler.h"
  9. #include "src/sksl/ir/SkSLExpressionStatement.h"
  10. #include "src/sksl/ir/SkSLExtension.h"
  11. #include "src/sksl/ir/SkSLIndexExpression.h"
  12. #include "src/sksl/ir/SkSLModifiersDeclaration.h"
  13. #include "src/sksl/ir/SkSLNop.h"
  14. #include "src/sksl/ir/SkSLVariableReference.h"
  15. #ifndef SKSL_STANDALONE
  16. #include "include/private/SkOnce.h"
  17. #endif
  18. namespace SkSL {
  19. void GLSLCodeGenerator::write(const char* s) {
  20. if (s[0] == 0) {
  21. return;
  22. }
  23. if (fAtLineStart) {
  24. for (int i = 0; i < fIndentation; i++) {
  25. fOut->writeText(" ");
  26. }
  27. }
  28. fOut->writeText(s);
  29. fAtLineStart = false;
  30. }
  31. void GLSLCodeGenerator::writeLine(const char* s) {
  32. this->write(s);
  33. fOut->writeText(fLineEnding);
  34. fAtLineStart = true;
  35. }
  36. void GLSLCodeGenerator::write(const String& s) {
  37. this->write(s.c_str());
  38. }
  39. void GLSLCodeGenerator::write(StringFragment s) {
  40. if (!s.fLength) {
  41. return;
  42. }
  43. if (fAtLineStart) {
  44. for (int i = 0; i < fIndentation; i++) {
  45. fOut->writeText(" ");
  46. }
  47. }
  48. fOut->write(s.fChars, s.fLength);
  49. fAtLineStart = false;
  50. }
  51. void GLSLCodeGenerator::writeLine(const String& s) {
  52. this->writeLine(s.c_str());
  53. }
  54. void GLSLCodeGenerator::writeLine() {
  55. this->writeLine("");
  56. }
  57. void GLSLCodeGenerator::writeExtension(const String& name) {
  58. this->writeExtension(name, true);
  59. }
  60. void GLSLCodeGenerator::writeExtension(const String& name, bool require) {
  61. fExtensions.writeText("#extension ");
  62. fExtensions.write(name.c_str(), name.length());
  63. fExtensions.writeText(require ? " : require\n" : " : enable\n");
  64. }
  65. bool GLSLCodeGenerator::usesPrecisionModifiers() const {
  66. return fProgram.fSettings.fCaps->usesPrecisionModifiers();
  67. }
  68. String GLSLCodeGenerator::getTypeName(const Type& type) {
  69. switch (type.kind()) {
  70. case Type::kVector_Kind: {
  71. Type component = type.componentType();
  72. String result;
  73. if (component == *fContext.fFloat_Type || component == *fContext.fHalf_Type) {
  74. result = "vec";
  75. }
  76. else if (component == *fContext.fDouble_Type) {
  77. result = "dvec";
  78. }
  79. else if (component.isSigned()) {
  80. result = "ivec";
  81. }
  82. else if (component.isUnsigned()) {
  83. result = "uvec";
  84. }
  85. else if (component == *fContext.fBool_Type) {
  86. result = "bvec";
  87. }
  88. else {
  89. ABORT("unsupported vector type");
  90. }
  91. result += to_string(type.columns());
  92. return result;
  93. }
  94. case Type::kMatrix_Kind: {
  95. String result;
  96. Type component = type.componentType();
  97. if (component == *fContext.fFloat_Type || component == *fContext.fHalf_Type) {
  98. result = "mat";
  99. }
  100. else if (component == *fContext.fDouble_Type) {
  101. result = "dmat";
  102. }
  103. else {
  104. ABORT("unsupported matrix type");
  105. }
  106. result += to_string(type.columns());
  107. if (type.columns() != type.rows()) {
  108. result += "x";
  109. result += to_string(type.rows());
  110. }
  111. return result;
  112. }
  113. case Type::kArray_Kind: {
  114. String result = this->getTypeName(type.componentType()) + "[";
  115. if (type.columns() != -1) {
  116. result += to_string(type.columns());
  117. }
  118. result += "]";
  119. return result;
  120. }
  121. case Type::kScalar_Kind: {
  122. if (type == *fContext.fHalf_Type) {
  123. return "float";
  124. }
  125. else if (type == *fContext.fShort_Type) {
  126. return "int";
  127. }
  128. else if (type == *fContext.fUShort_Type) {
  129. return "uint";
  130. }
  131. else if (type == *fContext.fByte_Type) {
  132. return "int";
  133. }
  134. else if (type == *fContext.fUByte_Type) {
  135. return "uint";
  136. }
  137. else {
  138. return type.name();
  139. }
  140. break;
  141. }
  142. default:
  143. return type.name();
  144. }
  145. }
  146. void GLSLCodeGenerator::writeType(const Type& type) {
  147. if (type.kind() == Type::kStruct_Kind) {
  148. for (const Type* search : fWrittenStructs) {
  149. if (*search == type) {
  150. // already written
  151. this->write(type.fName);
  152. return;
  153. }
  154. }
  155. fWrittenStructs.push_back(&type);
  156. this->write("struct ");
  157. this->write(type.fName);
  158. this->writeLine(" {");
  159. fIndentation++;
  160. for (const auto& f : type.fields()) {
  161. this->writeModifiers(f.fModifiers, false);
  162. this->writeTypePrecision(*f.fType);
  163. // sizes (which must be static in structs) are part of the type name here
  164. this->writeType(*f.fType);
  165. this->write(" ");
  166. this->write(f.fName);
  167. this->writeLine(";");
  168. }
  169. fIndentation--;
  170. this->write("}");
  171. } else {
  172. this->write(this->getTypeName(type));
  173. }
  174. }
  175. void GLSLCodeGenerator::writeExpression(const Expression& expr, Precedence parentPrecedence) {
  176. switch (expr.fKind) {
  177. case Expression::kBinary_Kind:
  178. this->writeBinaryExpression((BinaryExpression&) expr, parentPrecedence);
  179. break;
  180. case Expression::kBoolLiteral_Kind:
  181. this->writeBoolLiteral((BoolLiteral&) expr);
  182. break;
  183. case Expression::kConstructor_Kind:
  184. this->writeConstructor((Constructor&) expr, parentPrecedence);
  185. break;
  186. case Expression::kIntLiteral_Kind:
  187. this->writeIntLiteral((IntLiteral&) expr);
  188. break;
  189. case Expression::kFieldAccess_Kind:
  190. this->writeFieldAccess(((FieldAccess&) expr));
  191. break;
  192. case Expression::kFloatLiteral_Kind:
  193. this->writeFloatLiteral(((FloatLiteral&) expr));
  194. break;
  195. case Expression::kFunctionCall_Kind:
  196. this->writeFunctionCall((FunctionCall&) expr);
  197. break;
  198. case Expression::kPrefix_Kind:
  199. this->writePrefixExpression((PrefixExpression&) expr, parentPrecedence);
  200. break;
  201. case Expression::kPostfix_Kind:
  202. this->writePostfixExpression((PostfixExpression&) expr, parentPrecedence);
  203. break;
  204. case Expression::kSetting_Kind:
  205. this->writeSetting((Setting&) expr);
  206. break;
  207. case Expression::kSwizzle_Kind:
  208. this->writeSwizzle((Swizzle&) expr);
  209. break;
  210. case Expression::kVariableReference_Kind:
  211. this->writeVariableReference((VariableReference&) expr);
  212. break;
  213. case Expression::kTernary_Kind:
  214. this->writeTernaryExpression((TernaryExpression&) expr, parentPrecedence);
  215. break;
  216. case Expression::kIndex_Kind:
  217. this->writeIndexExpression((IndexExpression&) expr);
  218. break;
  219. default:
  220. ABORT("unsupported expression: %s", expr.description().c_str());
  221. }
  222. }
  223. static bool is_abs(Expression& expr) {
  224. if (expr.fKind != Expression::kFunctionCall_Kind) {
  225. return false;
  226. }
  227. return ((FunctionCall&) expr).fFunction.fName == "abs";
  228. }
  229. // turns min(abs(x), y) into ((tmpVar1 = abs(x)) < (tmpVar2 = y) ? tmpVar1 : tmpVar2) to avoid a
  230. // Tegra3 compiler bug.
  231. void GLSLCodeGenerator::writeMinAbsHack(Expression& absExpr, Expression& otherExpr) {
  232. SkASSERT(!fProgram.fSettings.fCaps->canUseMinAndAbsTogether());
  233. String tmpVar1 = "minAbsHackVar" + to_string(fVarCount++);
  234. String tmpVar2 = "minAbsHackVar" + to_string(fVarCount++);
  235. this->fFunctionHeader += String(" ") + this->getTypePrecision(absExpr.fType) +
  236. this->getTypeName(absExpr.fType) + " " + tmpVar1 + ";\n";
  237. this->fFunctionHeader += String(" ") + this->getTypePrecision(otherExpr.fType) +
  238. this->getTypeName(otherExpr.fType) + " " + tmpVar2 + ";\n";
  239. this->write("((" + tmpVar1 + " = ");
  240. this->writeExpression(absExpr, kTopLevel_Precedence);
  241. this->write(") < (" + tmpVar2 + " = ");
  242. this->writeExpression(otherExpr, kAssignment_Precedence);
  243. this->write(") ? " + tmpVar1 + " : " + tmpVar2 + ")");
  244. }
  245. void GLSLCodeGenerator::writeInverseSqrtHack(const Expression& x) {
  246. this->write("(1.0 / sqrt(");
  247. this->writeExpression(x, kTopLevel_Precedence);
  248. this->write("))");
  249. }
  250. void GLSLCodeGenerator::writeDeterminantHack(const Expression& mat) {
  251. String name;
  252. if (mat.fType == *fContext.fFloat2x2_Type || mat.fType == *fContext.fHalf2x2_Type) {
  253. name = "_determinant2";
  254. if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
  255. fWrittenIntrinsics.insert(name);
  256. fExtraFunctions.writeText((
  257. "float " + name + "(mat2 m) {"
  258. " return m[0][0] * m[1][1] - m[0][1] * m[1][0];"
  259. "}"
  260. ).c_str());
  261. }
  262. }
  263. else if (mat.fType == *fContext.fFloat3x3_Type || mat.fType == *fContext.fHalf3x3_Type) {
  264. name = "_determinant3";
  265. if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
  266. fWrittenIntrinsics.insert(name);
  267. fExtraFunctions.writeText((
  268. "float " + name + "(mat3 m) {"
  269. " float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];"
  270. " float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];"
  271. " float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];"
  272. " float b01 = a22 * a11 - a12 * a21;"
  273. " float b11 = -a22 * a10 + a12 * a20;"
  274. " float b21 = a21 * a10 - a11 * a20;"
  275. " return a00 * b01 + a01 * b11 + a02 * b21;"
  276. "}"
  277. ).c_str());
  278. }
  279. }
  280. else if (mat.fType == *fContext.fFloat4x4_Type || mat.fType == *fContext.fHalf4x4_Type) {
  281. name = "_determinant3";
  282. if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
  283. fWrittenIntrinsics.insert(name);
  284. fExtraFunctions.writeText((
  285. "mat4 " + name + "(mat4 m) {"
  286. " float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3];"
  287. " float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3];"
  288. " float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3];"
  289. " float a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3];"
  290. " float b00 = a00 * a11 - a01 * a10;"
  291. " float b01 = a00 * a12 - a02 * a10;"
  292. " float b02 = a00 * a13 - a03 * a10;"
  293. " float b03 = a01 * a12 - a02 * a11;"
  294. " float b04 = a01 * a13 - a03 * a11;"
  295. " float b05 = a02 * a13 - a03 * a12;"
  296. " float b06 = a20 * a31 - a21 * a30;"
  297. " float b07 = a20 * a32 - a22 * a30;"
  298. " float b08 = a20 * a33 - a23 * a30;"
  299. " float b09 = a21 * a32 - a22 * a31;"
  300. " float b10 = a21 * a33 - a23 * a31;"
  301. " float b11 = a22 * a33 - a23 * a32;"
  302. " return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;"
  303. "}"
  304. ).c_str());
  305. }
  306. }
  307. else {
  308. SkASSERT(false);
  309. }
  310. this->write(name + "(");
  311. this->writeExpression(mat, kTopLevel_Precedence);
  312. this->write(")");
  313. }
  314. void GLSLCodeGenerator::writeInverseHack(const Expression& mat) {
  315. String name;
  316. if (mat.fType == *fContext.fFloat2x2_Type || mat.fType == *fContext.fHalf2x2_Type) {
  317. name = "_inverse2";
  318. if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
  319. fWrittenIntrinsics.insert(name);
  320. fExtraFunctions.writeText((
  321. "mat2 " + name + "(mat2 m) {"
  322. " return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) / "
  323. "(m[0][0] * m[1][1] - m[0][1] * m[1][0]);"
  324. "}"
  325. ).c_str());
  326. }
  327. }
  328. else if (mat.fType == *fContext.fFloat3x3_Type || mat.fType == *fContext.fHalf3x3_Type) {
  329. name = "_inverse3";
  330. if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
  331. fWrittenIntrinsics.insert(name);
  332. fExtraFunctions.writeText((
  333. "mat3 " + name + "(mat3 m) {"
  334. " float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];"
  335. " float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];"
  336. " float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];"
  337. " float b01 = a22 * a11 - a12 * a21;"
  338. " float b11 = -a22 * a10 + a12 * a20;"
  339. " float b21 = a21 * a10 - a11 * a20;"
  340. " float det = a00 * b01 + a01 * b11 + a02 * b21;"
  341. " return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),"
  342. " b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),"
  343. " b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;"
  344. "}"
  345. ).c_str());
  346. }
  347. }
  348. else if (mat.fType == *fContext.fFloat4x4_Type || mat.fType == *fContext.fHalf4x4_Type) {
  349. name = "_inverse4";
  350. if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
  351. fWrittenIntrinsics.insert(name);
  352. fExtraFunctions.writeText((
  353. "mat4 " + name + "(mat4 m) {"
  354. " float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3];"
  355. " float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3];"
  356. " float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3];"
  357. " float a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3];"
  358. " float b00 = a00 * a11 - a01 * a10;"
  359. " float b01 = a00 * a12 - a02 * a10;"
  360. " float b02 = a00 * a13 - a03 * a10;"
  361. " float b03 = a01 * a12 - a02 * a11;"
  362. " float b04 = a01 * a13 - a03 * a11;"
  363. " float b05 = a02 * a13 - a03 * a12;"
  364. " float b06 = a20 * a31 - a21 * a30;"
  365. " float b07 = a20 * a32 - a22 * a30;"
  366. " float b08 = a20 * a33 - a23 * a30;"
  367. " float b09 = a21 * a32 - a22 * a31;"
  368. " float b10 = a21 * a33 - a23 * a31;"
  369. " float b11 = a22 * a33 - a23 * a32;"
  370. " float det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - "
  371. " b04 * b07 + b05 * b06;"
  372. " return mat4("
  373. " a11 * b11 - a12 * b10 + a13 * b09,"
  374. " a02 * b10 - a01 * b11 - a03 * b09,"
  375. " a31 * b05 - a32 * b04 + a33 * b03,"
  376. " a22 * b04 - a21 * b05 - a23 * b03,"
  377. " a12 * b08 - a10 * b11 - a13 * b07,"
  378. " a00 * b11 - a02 * b08 + a03 * b07,"
  379. " a32 * b02 - a30 * b05 - a33 * b01,"
  380. " a20 * b05 - a22 * b02 + a23 * b01,"
  381. " a10 * b10 - a11 * b08 + a13 * b06,"
  382. " a01 * b08 - a00 * b10 - a03 * b06,"
  383. " a30 * b04 - a31 * b02 + a33 * b00,"
  384. " a21 * b02 - a20 * b04 - a23 * b00,"
  385. " a11 * b07 - a10 * b09 - a12 * b06,"
  386. " a00 * b09 - a01 * b07 + a02 * b06,"
  387. " a31 * b01 - a30 * b03 - a32 * b00,"
  388. " a20 * b03 - a21 * b01 + a22 * b00) / det;"
  389. "}"
  390. ).c_str());
  391. }
  392. }
  393. else {
  394. SkASSERT(false);
  395. }
  396. this->write(name + "(");
  397. this->writeExpression(mat, kTopLevel_Precedence);
  398. this->write(")");
  399. }
  400. void GLSLCodeGenerator::writeTransposeHack(const Expression& mat) {
  401. String name = "transpose" + to_string(mat.fType.columns()) + to_string(mat.fType.rows());
  402. if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
  403. fWrittenIntrinsics.insert(name);
  404. String type = this->getTypeName(mat.fType);
  405. const Type& base = mat.fType.componentType();
  406. String transposed = this->getTypeName(base.toCompound(fContext,
  407. mat.fType.rows(),
  408. mat.fType.columns()));
  409. fExtraFunctions.writeText((transposed + " " + name + "(" + type + " m) {\nreturn " +
  410. transposed + "(").c_str());
  411. const char* separator = "";
  412. for (int row = 0; row < mat.fType.rows(); ++row) {
  413. for (int column = 0; column < mat.fType.columns(); ++column) {
  414. fExtraFunctions.writeText(separator);
  415. fExtraFunctions.writeText(("m[" + to_string(column) + "][" + to_string(row) +
  416. "]").c_str());
  417. separator = ", ";
  418. }
  419. }
  420. fExtraFunctions.writeText("); }");
  421. }
  422. this->write(name + "(");
  423. this->writeExpression(mat, kTopLevel_Precedence);
  424. this->write(")");
  425. }
  426. std::unordered_map<StringFragment, GLSLCodeGenerator::FunctionClass>*
  427. GLSLCodeGenerator::fFunctionClasses = nullptr;
  428. void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
  429. #ifdef SKSL_STANDALONE
  430. if (!fFunctionClasses) {
  431. #else
  432. static SkOnce once;
  433. once([] {
  434. #endif
  435. fFunctionClasses = new std::unordered_map<StringFragment, FunctionClass>();
  436. (*fFunctionClasses)["abs"] = FunctionClass::kAbs;
  437. (*fFunctionClasses)["atan"] = FunctionClass::kAtan;
  438. (*fFunctionClasses)["determinant"] = FunctionClass::kDeterminant;
  439. (*fFunctionClasses)["dFdx"] = FunctionClass::kDFdx;
  440. (*fFunctionClasses)["dFdy"] = FunctionClass::kDFdy;
  441. (*fFunctionClasses)["fwidth"] = FunctionClass::kFwidth;
  442. (*fFunctionClasses)["fma"] = FunctionClass::kFMA;
  443. (*fFunctionClasses)["fract"] = FunctionClass::kFract;
  444. (*fFunctionClasses)["inverse"] = FunctionClass::kInverse;
  445. (*fFunctionClasses)["inverseSqrt"] = FunctionClass::kInverseSqrt;
  446. (*fFunctionClasses)["min"] = FunctionClass::kMin;
  447. (*fFunctionClasses)["pow"] = FunctionClass::kPow;
  448. (*fFunctionClasses)["saturate"] = FunctionClass::kSaturate;
  449. (*fFunctionClasses)["texture"] = FunctionClass::kTexture;
  450. (*fFunctionClasses)["transpose"] = FunctionClass::kTranspose;
  451. }
  452. #ifndef SKSL_STANDALONE
  453. );
  454. #endif
  455. const auto found = c.fFunction.fBuiltin ? fFunctionClasses->find(c.fFunction.fName) :
  456. fFunctionClasses->end();
  457. bool isTextureFunctionWithBias = false;
  458. bool nameWritten = false;
  459. if (found != fFunctionClasses->end()) {
  460. switch (found->second) {
  461. case FunctionClass::kAbs: {
  462. if (!fProgram.fSettings.fCaps->emulateAbsIntFunction())
  463. break;
  464. SkASSERT(c.fArguments.size() == 1);
  465. if (c.fArguments[0]->fType != *fContext.fInt_Type)
  466. break;
  467. // abs(int) on Intel OSX is incorrect, so emulate it:
  468. String name = "_absemulation";
  469. this->write(name);
  470. nameWritten = true;
  471. if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
  472. fWrittenIntrinsics.insert(name);
  473. fExtraFunctions.writeText((
  474. "int " + name + "(int x) {\n"
  475. " return x * sign(x);\n"
  476. "}\n"
  477. ).c_str());
  478. }
  479. break;
  480. }
  481. case FunctionClass::kAtan:
  482. if (fProgram.fSettings.fCaps->mustForceNegatedAtanParamToFloat() &&
  483. c.fArguments.size() == 2 &&
  484. c.fArguments[1]->fKind == Expression::kPrefix_Kind) {
  485. const PrefixExpression& p = (PrefixExpression&) *c.fArguments[1];
  486. if (p.fOperator == Token::MINUS) {
  487. this->write("atan(");
  488. this->writeExpression(*c.fArguments[0], kSequence_Precedence);
  489. this->write(", -1.0 * ");
  490. this->writeExpression(*p.fOperand, kMultiplicative_Precedence);
  491. this->write(")");
  492. return;
  493. }
  494. }
  495. break;
  496. case FunctionClass::kDFdy:
  497. if (fProgram.fSettings.fFlipY) {
  498. // Flipping Y also negates the Y derivatives.
  499. this->write("-dFdy");
  500. nameWritten = true;
  501. }
  502. // fallthru
  503. case FunctionClass::kDFdx:
  504. case FunctionClass::kFwidth:
  505. if (!fFoundDerivatives &&
  506. fProgram.fSettings.fCaps->shaderDerivativeExtensionString()) {
  507. SkASSERT(fProgram.fSettings.fCaps->shaderDerivativeSupport());
  508. this->writeExtension(fProgram.fSettings.fCaps->shaderDerivativeExtensionString());
  509. fFoundDerivatives = true;
  510. }
  511. break;
  512. case FunctionClass::kDeterminant:
  513. if (fProgram.fSettings.fCaps->generation() < k150_GrGLSLGeneration) {
  514. SkASSERT(c.fArguments.size() == 1);
  515. this->writeDeterminantHack(*c.fArguments[0]);
  516. return;
  517. }
  518. break;
  519. case FunctionClass::kFMA:
  520. if (!fProgram.fSettings.fCaps->builtinFMASupport()) {
  521. SkASSERT(c.fArguments.size() == 3);
  522. this->write("((");
  523. this->writeExpression(*c.fArguments[0], kSequence_Precedence);
  524. this->write(") * (");
  525. this->writeExpression(*c.fArguments[1], kSequence_Precedence);
  526. this->write(") + (");
  527. this->writeExpression(*c.fArguments[2], kSequence_Precedence);
  528. this->write("))");
  529. return;
  530. }
  531. break;
  532. case FunctionClass::kFract:
  533. if (!fProgram.fSettings.fCaps->canUseFractForNegativeValues()) {
  534. SkASSERT(c.fArguments.size() == 1);
  535. this->write("(0.5 - sign(");
  536. this->writeExpression(*c.fArguments[0], kSequence_Precedence);
  537. this->write(") * (0.5 - fract(abs(");
  538. this->writeExpression(*c.fArguments[0], kSequence_Precedence);
  539. this->write("))))");
  540. return;
  541. }
  542. break;
  543. case FunctionClass::kInverse:
  544. if (fProgram.fSettings.fCaps->generation() < k140_GrGLSLGeneration) {
  545. SkASSERT(c.fArguments.size() == 1);
  546. this->writeInverseHack(*c.fArguments[0]);
  547. return;
  548. }
  549. break;
  550. case FunctionClass::kInverseSqrt:
  551. if (fProgram.fSettings.fCaps->generation() < k130_GrGLSLGeneration) {
  552. SkASSERT(c.fArguments.size() == 1);
  553. this->writeInverseSqrtHack(*c.fArguments[0]);
  554. return;
  555. }
  556. break;
  557. case FunctionClass::kMin:
  558. if (!fProgram.fSettings.fCaps->canUseMinAndAbsTogether()) {
  559. SkASSERT(c.fArguments.size() == 2);
  560. if (is_abs(*c.fArguments[0])) {
  561. this->writeMinAbsHack(*c.fArguments[0], *c.fArguments[1]);
  562. return;
  563. }
  564. if (is_abs(*c.fArguments[1])) {
  565. // note that this violates the GLSL left-to-right evaluation semantics.
  566. // I doubt it will ever end up mattering, but it's worth calling out.
  567. this->writeMinAbsHack(*c.fArguments[1], *c.fArguments[0]);
  568. return;
  569. }
  570. }
  571. break;
  572. case FunctionClass::kPow:
  573. if (!fProgram.fSettings.fCaps->removePowWithConstantExponent()) {
  574. break;
  575. }
  576. // pow(x, y) on some NVIDIA drivers causes crashes if y is a
  577. // constant. It's hard to tell what constitutes "constant" here
  578. // so just replace in all cases.
  579. // Change pow(x, y) into exp2(y * log2(x))
  580. this->write("exp2(");
  581. this->writeExpression(*c.fArguments[1], kMultiplicative_Precedence);
  582. this->write(" * log2(");
  583. this->writeExpression(*c.fArguments[0], kSequence_Precedence);
  584. this->write("))");
  585. return;
  586. case FunctionClass::kSaturate:
  587. SkASSERT(c.fArguments.size() == 1);
  588. this->write("clamp(");
  589. this->writeExpression(*c.fArguments[0], kSequence_Precedence);
  590. this->write(", 0.0, 1.0)");
  591. return;
  592. case FunctionClass::kTexture: {
  593. const char* dim = "";
  594. bool proj = false;
  595. switch (c.fArguments[0]->fType.dimensions()) {
  596. case SpvDim1D:
  597. dim = "1D";
  598. isTextureFunctionWithBias = true;
  599. if (c.fArguments[1]->fType == *fContext.fFloat_Type) {
  600. proj = false;
  601. } else {
  602. SkASSERT(c.fArguments[1]->fType == *fContext.fFloat2_Type);
  603. proj = true;
  604. }
  605. break;
  606. case SpvDim2D:
  607. dim = "2D";
  608. if (c.fArguments[0]->fType != *fContext.fSamplerExternalOES_Type) {
  609. isTextureFunctionWithBias = true;
  610. }
  611. if (c.fArguments[1]->fType == *fContext.fFloat2_Type) {
  612. proj = false;
  613. } else {
  614. SkASSERT(c.fArguments[1]->fType == *fContext.fFloat3_Type);
  615. proj = true;
  616. }
  617. break;
  618. case SpvDim3D:
  619. dim = "3D";
  620. isTextureFunctionWithBias = true;
  621. if (c.fArguments[1]->fType == *fContext.fFloat3_Type) {
  622. proj = false;
  623. } else {
  624. SkASSERT(c.fArguments[1]->fType == *fContext.fFloat4_Type);
  625. proj = true;
  626. }
  627. break;
  628. case SpvDimCube:
  629. dim = "Cube";
  630. isTextureFunctionWithBias = true;
  631. proj = false;
  632. break;
  633. case SpvDimRect:
  634. dim = "Rect";
  635. proj = false;
  636. break;
  637. case SpvDimBuffer:
  638. SkASSERT(false); // doesn't exist
  639. dim = "Buffer";
  640. proj = false;
  641. break;
  642. case SpvDimSubpassData:
  643. SkASSERT(false); // doesn't exist
  644. dim = "SubpassData";
  645. proj = false;
  646. break;
  647. }
  648. this->write("texture");
  649. if (fProgram.fSettings.fCaps->generation() < k130_GrGLSLGeneration) {
  650. this->write(dim);
  651. }
  652. if (proj) {
  653. this->write("Proj");
  654. }
  655. nameWritten = true;
  656. break;
  657. }
  658. case FunctionClass::kTranspose:
  659. if (fProgram.fSettings.fCaps->generation() < k130_GrGLSLGeneration) {
  660. SkASSERT(c.fArguments.size() == 1);
  661. this->writeTransposeHack(*c.fArguments[0]);
  662. return;
  663. }
  664. break;
  665. }
  666. }
  667. if (!nameWritten) {
  668. this->write(c.fFunction.fName);
  669. }
  670. this->write("(");
  671. const char* separator = "";
  672. for (const auto& arg : c.fArguments) {
  673. this->write(separator);
  674. separator = ", ";
  675. this->writeExpression(*arg, kSequence_Precedence);
  676. }
  677. if (fProgram.fSettings.fSharpenTextures && isTextureFunctionWithBias) {
  678. this->write(", -0.5");
  679. }
  680. this->write(")");
  681. }
  682. void GLSLCodeGenerator::writeConstructor(const Constructor& c, Precedence parentPrecedence) {
  683. if (c.fArguments.size() == 1 &&
  684. (this->getTypeName(c.fType) == this->getTypeName(c.fArguments[0]->fType) ||
  685. (c.fType.kind() == Type::kScalar_Kind &&
  686. c.fArguments[0]->fType == *fContext.fFloatLiteral_Type))) {
  687. // in cases like half(float), they're different types as far as SkSL is concerned but the
  688. // same type as far as GLSL is concerned. We avoid a redundant float(float) by just writing
  689. // out the inner expression here.
  690. this->writeExpression(*c.fArguments[0], parentPrecedence);
  691. return;
  692. }
  693. this->writeType(c.fType);
  694. this->write("(");
  695. const char* separator = "";
  696. for (const auto& arg : c.fArguments) {
  697. this->write(separator);
  698. separator = ", ";
  699. this->writeExpression(*arg, kSequence_Precedence);
  700. }
  701. this->write(")");
  702. }
  703. void GLSLCodeGenerator::writeFragCoord() {
  704. if (!fProgram.fSettings.fCaps->canUseFragCoord()) {
  705. if (!fSetupFragCoordWorkaround) {
  706. const char* precision = usesPrecisionModifiers() ? "highp " : "";
  707. fFunctionHeader += precision;
  708. fFunctionHeader += " float sk_FragCoord_InvW = 1. / sk_FragCoord_Workaround.w;\n";
  709. fFunctionHeader += precision;
  710. fFunctionHeader += " vec4 sk_FragCoord_Resolved = "
  711. "vec4(sk_FragCoord_Workaround.xyz * sk_FragCoord_InvW, sk_FragCoord_InvW);\n";
  712. // Ensure that we get exact .5 values for x and y.
  713. fFunctionHeader += " sk_FragCoord_Resolved.xy = floor(sk_FragCoord_Resolved.xy) + "
  714. "vec2(.5);\n";
  715. fSetupFragCoordWorkaround = true;
  716. }
  717. this->write("sk_FragCoord_Resolved");
  718. return;
  719. }
  720. // We only declare "gl_FragCoord" when we're in the case where we want to use layout qualifiers
  721. // to reverse y. Otherwise it isn't necessary and whether the "in" qualifier appears in the
  722. // declaration varies in earlier GLSL specs. So it is simpler to omit it.
  723. if (!fProgram.fSettings.fFlipY) {
  724. this->write("gl_FragCoord");
  725. } else if (const char* extension =
  726. fProgram.fSettings.fCaps->fragCoordConventionsExtensionString()) {
  727. if (!fSetupFragPositionGlobal) {
  728. if (fProgram.fSettings.fCaps->generation() < k150_GrGLSLGeneration) {
  729. this->writeExtension(extension);
  730. }
  731. fGlobals.writeText("layout(origin_upper_left) in vec4 gl_FragCoord;\n");
  732. fSetupFragPositionGlobal = true;
  733. }
  734. this->write("gl_FragCoord");
  735. } else {
  736. if (!fSetupFragPositionLocal) {
  737. fFunctionHeader += usesPrecisionModifiers() ? "highp " : "";
  738. fFunctionHeader += " vec4 sk_FragCoord = vec4(gl_FragCoord.x, " SKSL_RTHEIGHT_NAME
  739. " - gl_FragCoord.y, gl_FragCoord.z, gl_FragCoord.w);\n";
  740. fSetupFragPositionLocal = true;
  741. }
  742. this->write("sk_FragCoord");
  743. }
  744. }
  745. void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) {
  746. switch (ref.fVariable.fModifiers.fLayout.fBuiltin) {
  747. case SK_FRAGCOLOR_BUILTIN:
  748. if (fProgram.fSettings.fCaps->mustDeclareFragmentShaderOutput()) {
  749. this->write("sk_FragColor");
  750. } else {
  751. this->write("gl_FragColor");
  752. }
  753. break;
  754. case SK_FRAGCOORD_BUILTIN:
  755. this->writeFragCoord();
  756. break;
  757. case SK_WIDTH_BUILTIN:
  758. this->write("u_skRTWidth");
  759. break;
  760. case SK_HEIGHT_BUILTIN:
  761. this->write("u_skRTHeight");
  762. break;
  763. case SK_CLOCKWISE_BUILTIN:
  764. this->write(fProgram.fSettings.fFlipY ? "(!gl_FrontFacing)" : "gl_FrontFacing");
  765. break;
  766. case SK_VERTEXID_BUILTIN:
  767. this->write("gl_VertexID");
  768. break;
  769. case SK_INSTANCEID_BUILTIN:
  770. this->write("gl_InstanceID");
  771. break;
  772. case SK_CLIPDISTANCE_BUILTIN:
  773. this->write("gl_ClipDistance");
  774. break;
  775. case SK_IN_BUILTIN:
  776. this->write("gl_in");
  777. break;
  778. case SK_INVOCATIONID_BUILTIN:
  779. this->write("gl_InvocationID");
  780. break;
  781. case SK_LASTFRAGCOLOR_BUILTIN:
  782. this->write(fProgram.fSettings.fCaps->fbFetchColorName());
  783. break;
  784. default:
  785. this->write(ref.fVariable.fName);
  786. }
  787. }
  788. void GLSLCodeGenerator::writeIndexExpression(const IndexExpression& expr) {
  789. this->writeExpression(*expr.fBase, kPostfix_Precedence);
  790. this->write("[");
  791. this->writeExpression(*expr.fIndex, kTopLevel_Precedence);
  792. this->write("]");
  793. }
  794. bool is_sk_position(const FieldAccess& f) {
  795. return "sk_Position" == f.fBase->fType.fields()[f.fFieldIndex].fName;
  796. }
  797. void GLSLCodeGenerator::writeFieldAccess(const FieldAccess& f) {
  798. if (f.fOwnerKind == FieldAccess::kDefault_OwnerKind) {
  799. this->writeExpression(*f.fBase, kPostfix_Precedence);
  800. this->write(".");
  801. }
  802. switch (f.fBase->fType.fields()[f.fFieldIndex].fModifiers.fLayout.fBuiltin) {
  803. case SK_CLIPDISTANCE_BUILTIN:
  804. this->write("gl_ClipDistance");
  805. break;
  806. default:
  807. StringFragment name = f.fBase->fType.fields()[f.fFieldIndex].fName;
  808. if (name == "sk_Position") {
  809. this->write("gl_Position");
  810. } else if (name == "sk_PointSize") {
  811. this->write("gl_PointSize");
  812. } else {
  813. this->write(f.fBase->fType.fields()[f.fFieldIndex].fName);
  814. }
  815. }
  816. }
  817. void GLSLCodeGenerator::writeSwizzle(const Swizzle& swizzle) {
  818. int last = swizzle.fComponents.back();
  819. if (last == SKSL_SWIZZLE_0 || last == SKSL_SWIZZLE_1) {
  820. this->writeType(swizzle.fType);
  821. this->write("(");
  822. }
  823. this->writeExpression(*swizzle.fBase, kPostfix_Precedence);
  824. this->write(".");
  825. for (int c : swizzle.fComponents) {
  826. if (c >= 0) {
  827. this->write(&("x\0y\0z\0w\0"[c * 2]));
  828. }
  829. }
  830. if (last == SKSL_SWIZZLE_0) {
  831. this->write(", 0)");
  832. }
  833. else if (last == SKSL_SWIZZLE_1) {
  834. this->write(", 1)");
  835. }
  836. }
  837. GLSLCodeGenerator::Precedence GLSLCodeGenerator::GetBinaryPrecedence(Token::Kind op) {
  838. switch (op) {
  839. case Token::STAR: // fall through
  840. case Token::SLASH: // fall through
  841. case Token::PERCENT: return GLSLCodeGenerator::kMultiplicative_Precedence;
  842. case Token::PLUS: // fall through
  843. case Token::MINUS: return GLSLCodeGenerator::kAdditive_Precedence;
  844. case Token::SHL: // fall through
  845. case Token::SHR: return GLSLCodeGenerator::kShift_Precedence;
  846. case Token::LT: // fall through
  847. case Token::GT: // fall through
  848. case Token::LTEQ: // fall through
  849. case Token::GTEQ: return GLSLCodeGenerator::kRelational_Precedence;
  850. case Token::EQEQ: // fall through
  851. case Token::NEQ: return GLSLCodeGenerator::kEquality_Precedence;
  852. case Token::BITWISEAND: return GLSLCodeGenerator::kBitwiseAnd_Precedence;
  853. case Token::BITWISEXOR: return GLSLCodeGenerator::kBitwiseXor_Precedence;
  854. case Token::BITWISEOR: return GLSLCodeGenerator::kBitwiseOr_Precedence;
  855. case Token::LOGICALAND: return GLSLCodeGenerator::kLogicalAnd_Precedence;
  856. case Token::LOGICALXOR: return GLSLCodeGenerator::kLogicalXor_Precedence;
  857. case Token::LOGICALOR: return GLSLCodeGenerator::kLogicalOr_Precedence;
  858. case Token::EQ: // fall through
  859. case Token::PLUSEQ: // fall through
  860. case Token::MINUSEQ: // fall through
  861. case Token::STAREQ: // fall through
  862. case Token::SLASHEQ: // fall through
  863. case Token::PERCENTEQ: // fall through
  864. case Token::SHLEQ: // fall through
  865. case Token::SHREQ: // fall through
  866. case Token::LOGICALANDEQ: // fall through
  867. case Token::LOGICALXOREQ: // fall through
  868. case Token::LOGICALOREQ: // fall through
  869. case Token::BITWISEANDEQ: // fall through
  870. case Token::BITWISEXOREQ: // fall through
  871. case Token::BITWISEOREQ: return GLSLCodeGenerator::kAssignment_Precedence;
  872. case Token::COMMA: return GLSLCodeGenerator::kSequence_Precedence;
  873. default: ABORT("unsupported binary operator");
  874. }
  875. }
  876. void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
  877. Precedence parentPrecedence) {
  878. if (fProgram.fSettings.fCaps->unfoldShortCircuitAsTernary() &&
  879. (b.fOperator == Token::LOGICALAND || b.fOperator == Token::LOGICALOR)) {
  880. this->writeShortCircuitWorkaroundExpression(b, parentPrecedence);
  881. return;
  882. }
  883. Precedence precedence = GetBinaryPrecedence(b.fOperator);
  884. if (precedence >= parentPrecedence) {
  885. this->write("(");
  886. }
  887. bool positionWorkaround = fProgramKind == Program::Kind::kVertex_Kind &&
  888. Compiler::IsAssignment(b.fOperator) &&
  889. Expression::kFieldAccess_Kind == b.fLeft->fKind &&
  890. is_sk_position((FieldAccess&) *b.fLeft) &&
  891. !strstr(b.fRight->description().c_str(), "sk_RTAdjust") &&
  892. !fProgram.fSettings.fCaps->canUseFragCoord();
  893. if (positionWorkaround) {
  894. this->write("sk_FragCoord_Workaround = (");
  895. }
  896. this->writeExpression(*b.fLeft, precedence);
  897. this->write(" ");
  898. this->write(Compiler::OperatorName(b.fOperator));
  899. this->write(" ");
  900. this->writeExpression(*b.fRight, precedence);
  901. if (positionWorkaround) {
  902. this->write(")");
  903. }
  904. if (precedence >= parentPrecedence) {
  905. this->write(")");
  906. }
  907. }
  908. void GLSLCodeGenerator::writeShortCircuitWorkaroundExpression(const BinaryExpression& b,
  909. Precedence parentPrecedence) {
  910. if (kTernary_Precedence >= parentPrecedence) {
  911. this->write("(");
  912. }
  913. // Transform:
  914. // a && b => a ? b : false
  915. // a || b => a ? true : b
  916. this->writeExpression(*b.fLeft, kTernary_Precedence);
  917. this->write(" ? ");
  918. if (b.fOperator == Token::LOGICALAND) {
  919. this->writeExpression(*b.fRight, kTernary_Precedence);
  920. } else {
  921. BoolLiteral boolTrue(fContext, -1, true);
  922. this->writeBoolLiteral(boolTrue);
  923. }
  924. this->write(" : ");
  925. if (b.fOperator == Token::LOGICALAND) {
  926. BoolLiteral boolFalse(fContext, -1, false);
  927. this->writeBoolLiteral(boolFalse);
  928. } else {
  929. this->writeExpression(*b.fRight, kTernary_Precedence);
  930. }
  931. if (kTernary_Precedence >= parentPrecedence) {
  932. this->write(")");
  933. }
  934. }
  935. void GLSLCodeGenerator::writeTernaryExpression(const TernaryExpression& t,
  936. Precedence parentPrecedence) {
  937. if (kTernary_Precedence >= parentPrecedence) {
  938. this->write("(");
  939. }
  940. this->writeExpression(*t.fTest, kTernary_Precedence);
  941. this->write(" ? ");
  942. this->writeExpression(*t.fIfTrue, kTernary_Precedence);
  943. this->write(" : ");
  944. this->writeExpression(*t.fIfFalse, kTernary_Precedence);
  945. if (kTernary_Precedence >= parentPrecedence) {
  946. this->write(")");
  947. }
  948. }
  949. void GLSLCodeGenerator::writePrefixExpression(const PrefixExpression& p,
  950. Precedence parentPrecedence) {
  951. if (kPrefix_Precedence >= parentPrecedence) {
  952. this->write("(");
  953. }
  954. this->write(Compiler::OperatorName(p.fOperator));
  955. this->writeExpression(*p.fOperand, kPrefix_Precedence);
  956. if (kPrefix_Precedence >= parentPrecedence) {
  957. this->write(")");
  958. }
  959. }
  960. void GLSLCodeGenerator::writePostfixExpression(const PostfixExpression& p,
  961. Precedence parentPrecedence) {
  962. if (kPostfix_Precedence >= parentPrecedence) {
  963. this->write("(");
  964. }
  965. this->writeExpression(*p.fOperand, kPostfix_Precedence);
  966. this->write(Compiler::OperatorName(p.fOperator));
  967. if (kPostfix_Precedence >= parentPrecedence) {
  968. this->write(")");
  969. }
  970. }
  971. void GLSLCodeGenerator::writeBoolLiteral(const BoolLiteral& b) {
  972. this->write(b.fValue ? "true" : "false");
  973. }
  974. void GLSLCodeGenerator::writeIntLiteral(const IntLiteral& i) {
  975. if (i.fType == *fContext.fUInt_Type) {
  976. this->write(to_string(i.fValue & 0xffffffff) + "u");
  977. } else if (i.fType == *fContext.fUShort_Type) {
  978. this->write(to_string(i.fValue & 0xffff) + "u");
  979. } else if (i.fType == *fContext.fUByte_Type) {
  980. this->write(to_string(i.fValue & 0xff) + "u");
  981. } else {
  982. this->write(to_string((int32_t) i.fValue));
  983. }
  984. }
  985. void GLSLCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
  986. this->write(to_string(f.fValue));
  987. }
  988. void GLSLCodeGenerator::writeSetting(const Setting& s) {
  989. ABORT("internal error; setting was not folded to a constant during compilation\n");
  990. }
  991. void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
  992. if (fProgramKind != Program::kPipelineStage_Kind) {
  993. this->writeTypePrecision(f.fDeclaration.fReturnType);
  994. this->writeType(f.fDeclaration.fReturnType);
  995. this->write(" " + f.fDeclaration.fName + "(");
  996. const char* separator = "";
  997. for (const auto& param : f.fDeclaration.fParameters) {
  998. this->write(separator);
  999. separator = ", ";
  1000. this->writeModifiers(param->fModifiers, false);
  1001. std::vector<int> sizes;
  1002. const Type* type = &param->fType;
  1003. while (type->kind() == Type::kArray_Kind) {
  1004. sizes.push_back(type->columns());
  1005. type = &type->componentType();
  1006. }
  1007. this->writeTypePrecision(*type);
  1008. this->writeType(*type);
  1009. this->write(" " + param->fName);
  1010. for (int s : sizes) {
  1011. if (s <= 0) {
  1012. this->write("[]");
  1013. } else {
  1014. this->write("[" + to_string(s) + "]");
  1015. }
  1016. }
  1017. }
  1018. this->writeLine(") {");
  1019. fIndentation++;
  1020. }
  1021. fFunctionHeader = "";
  1022. OutputStream* oldOut = fOut;
  1023. StringStream buffer;
  1024. fOut = &buffer;
  1025. this->writeStatements(((Block&) *f.fBody).fStatements);
  1026. if (fProgramKind != Program::kPipelineStage_Kind) {
  1027. fIndentation--;
  1028. this->writeLine("}");
  1029. }
  1030. fOut = oldOut;
  1031. this->write(fFunctionHeader);
  1032. this->write(buffer.str());
  1033. }
  1034. void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers,
  1035. bool globalContext) {
  1036. if (modifiers.fFlags & Modifiers::kFlat_Flag) {
  1037. this->write("flat ");
  1038. }
  1039. if (modifiers.fFlags & Modifiers::kNoPerspective_Flag) {
  1040. this->write("noperspective ");
  1041. }
  1042. String layout = modifiers.fLayout.description();
  1043. if (layout.size()) {
  1044. this->write(layout + " ");
  1045. }
  1046. if (modifiers.fFlags & Modifiers::kReadOnly_Flag) {
  1047. this->write("readonly ");
  1048. }
  1049. if (modifiers.fFlags & Modifiers::kWriteOnly_Flag) {
  1050. this->write("writeonly ");
  1051. }
  1052. if (modifiers.fFlags & Modifiers::kCoherent_Flag) {
  1053. this->write("coherent ");
  1054. }
  1055. if (modifiers.fFlags & Modifiers::kVolatile_Flag) {
  1056. this->write("volatile ");
  1057. }
  1058. if (modifiers.fFlags & Modifiers::kRestrict_Flag) {
  1059. this->write("restrict ");
  1060. }
  1061. if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
  1062. (modifiers.fFlags & Modifiers::kOut_Flag)) {
  1063. this->write("inout ");
  1064. } else if (modifiers.fFlags & Modifiers::kIn_Flag) {
  1065. if (globalContext &&
  1066. fProgram.fSettings.fCaps->generation() < GrGLSLGeneration::k130_GrGLSLGeneration) {
  1067. this->write(fProgramKind == Program::kVertex_Kind ? "attribute "
  1068. : "varying ");
  1069. } else {
  1070. this->write("in ");
  1071. }
  1072. } else if (modifiers.fFlags & Modifiers::kOut_Flag) {
  1073. if (globalContext &&
  1074. fProgram.fSettings.fCaps->generation() < GrGLSLGeneration::k130_GrGLSLGeneration) {
  1075. this->write("varying ");
  1076. } else {
  1077. this->write("out ");
  1078. }
  1079. }
  1080. if (modifiers.fFlags & Modifiers::kUniform_Flag) {
  1081. this->write("uniform ");
  1082. }
  1083. if (modifiers.fFlags & Modifiers::kConst_Flag) {
  1084. this->write("const ");
  1085. }
  1086. if (modifiers.fFlags & Modifiers::kPLS_Flag) {
  1087. this->write("__pixel_localEXT ");
  1088. }
  1089. if (modifiers.fFlags & Modifiers::kPLSIn_Flag) {
  1090. this->write("__pixel_local_inEXT ");
  1091. }
  1092. if (modifiers.fFlags & Modifiers::kPLSOut_Flag) {
  1093. this->write("__pixel_local_outEXT ");
  1094. }
  1095. switch (modifiers.fLayout.fFormat) {
  1096. case Layout::Format::kUnspecified:
  1097. break;
  1098. case Layout::Format::kRGBA32F: // fall through
  1099. case Layout::Format::kR32F:
  1100. this->write("highp ");
  1101. break;
  1102. case Layout::Format::kRGBA16F: // fall through
  1103. case Layout::Format::kR16F: // fall through
  1104. case Layout::Format::kLUMINANCE16F: // fall through
  1105. case Layout::Format::kRG16F:
  1106. this->write("mediump ");
  1107. break;
  1108. case Layout::Format::kRGBA8: // fall through
  1109. case Layout::Format::kR8: // fall through
  1110. case Layout::Format::kRGBA8I: // fall through
  1111. case Layout::Format::kR8I:
  1112. this->write("lowp ");
  1113. break;
  1114. }
  1115. }
  1116. void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
  1117. if (intf.fTypeName == "sk_PerVertex") {
  1118. return;
  1119. }
  1120. this->writeModifiers(intf.fVariable.fModifiers, true);
  1121. this->writeLine(intf.fTypeName + " {");
  1122. fIndentation++;
  1123. const Type* structType = &intf.fVariable.fType;
  1124. while (structType->kind() == Type::kArray_Kind) {
  1125. structType = &structType->componentType();
  1126. }
  1127. for (const auto& f : structType->fields()) {
  1128. this->writeModifiers(f.fModifiers, false);
  1129. this->writeTypePrecision(*f.fType);
  1130. this->writeType(*f.fType);
  1131. this->writeLine(" " + f.fName + ";");
  1132. }
  1133. fIndentation--;
  1134. this->write("}");
  1135. if (intf.fInstanceName.size()) {
  1136. this->write(" ");
  1137. this->write(intf.fInstanceName);
  1138. for (const auto& size : intf.fSizes) {
  1139. this->write("[");
  1140. if (size) {
  1141. this->writeExpression(*size, kTopLevel_Precedence);
  1142. }
  1143. this->write("]");
  1144. }
  1145. }
  1146. this->writeLine(";");
  1147. }
  1148. void GLSLCodeGenerator::writeVarInitializer(const Variable& var, const Expression& value) {
  1149. this->writeExpression(value, kTopLevel_Precedence);
  1150. }
  1151. const char* GLSLCodeGenerator::getTypePrecision(const Type& type) {
  1152. if (usesPrecisionModifiers()) {
  1153. switch (type.kind()) {
  1154. case Type::kScalar_Kind:
  1155. if (type == *fContext.fShort_Type || type == *fContext.fUShort_Type ||
  1156. type == *fContext.fByte_Type || type == *fContext.fUByte_Type) {
  1157. if (fProgram.fSettings.fForceHighPrecision ||
  1158. fProgram.fSettings.fCaps->incompleteShortIntPrecision()) {
  1159. return "highp ";
  1160. }
  1161. return "mediump ";
  1162. }
  1163. if (type == *fContext.fHalf_Type) {
  1164. return fProgram.fSettings.fForceHighPrecision ? "highp " : "mediump ";
  1165. }
  1166. if (type == *fContext.fFloat_Type || type == *fContext.fInt_Type ||
  1167. type == *fContext.fUInt_Type) {
  1168. return "highp ";
  1169. }
  1170. return "";
  1171. case Type::kVector_Kind: // fall through
  1172. case Type::kMatrix_Kind:
  1173. return this->getTypePrecision(type.componentType());
  1174. default:
  1175. break;
  1176. }
  1177. }
  1178. return "";
  1179. }
  1180. void GLSLCodeGenerator::writeTypePrecision(const Type& type) {
  1181. this->write(this->getTypePrecision(type));
  1182. }
  1183. void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool global) {
  1184. if (!decl.fVars.size()) {
  1185. return;
  1186. }
  1187. bool wroteType = false;
  1188. for (const auto& stmt : decl.fVars) {
  1189. VarDeclaration& var = (VarDeclaration&) *stmt;
  1190. if (wroteType) {
  1191. this->write(", ");
  1192. } else {
  1193. this->writeModifiers(var.fVar->fModifiers, global);
  1194. this->writeTypePrecision(decl.fBaseType);
  1195. this->writeType(decl.fBaseType);
  1196. this->write(" ");
  1197. wroteType = true;
  1198. }
  1199. this->write(var.fVar->fName);
  1200. for (const auto& size : var.fSizes) {
  1201. this->write("[");
  1202. if (size) {
  1203. this->writeExpression(*size, kTopLevel_Precedence);
  1204. }
  1205. this->write("]");
  1206. }
  1207. if (var.fValue) {
  1208. this->write(" = ");
  1209. this->writeVarInitializer(*var.fVar, *var.fValue);
  1210. }
  1211. if (!fFoundExternalSamplerDecl && var.fVar->fType == *fContext.fSamplerExternalOES_Type) {
  1212. if (fProgram.fSettings.fCaps->externalTextureExtensionString()) {
  1213. this->writeExtension(fProgram.fSettings.fCaps->externalTextureExtensionString());
  1214. }
  1215. if (fProgram.fSettings.fCaps->secondExternalTextureExtensionString()) {
  1216. this->writeExtension(
  1217. fProgram.fSettings.fCaps->secondExternalTextureExtensionString());
  1218. }
  1219. fFoundExternalSamplerDecl = true;
  1220. }
  1221. }
  1222. if (wroteType) {
  1223. this->write(";");
  1224. }
  1225. }
  1226. void GLSLCodeGenerator::writeStatement(const Statement& s) {
  1227. switch (s.fKind) {
  1228. case Statement::kBlock_Kind:
  1229. this->writeBlock((Block&) s);
  1230. break;
  1231. case Statement::kExpression_Kind:
  1232. this->writeExpression(*((ExpressionStatement&) s).fExpression, kTopLevel_Precedence);
  1233. this->write(";");
  1234. break;
  1235. case Statement::kReturn_Kind:
  1236. this->writeReturnStatement((ReturnStatement&) s);
  1237. break;
  1238. case Statement::kVarDeclarations_Kind:
  1239. this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration, false);
  1240. break;
  1241. case Statement::kIf_Kind:
  1242. this->writeIfStatement((IfStatement&) s);
  1243. break;
  1244. case Statement::kFor_Kind:
  1245. this->writeForStatement((ForStatement&) s);
  1246. break;
  1247. case Statement::kWhile_Kind:
  1248. this->writeWhileStatement((WhileStatement&) s);
  1249. break;
  1250. case Statement::kDo_Kind:
  1251. this->writeDoStatement((DoStatement&) s);
  1252. break;
  1253. case Statement::kSwitch_Kind:
  1254. this->writeSwitchStatement((SwitchStatement&) s);
  1255. break;
  1256. case Statement::kBreak_Kind:
  1257. this->write("break;");
  1258. break;
  1259. case Statement::kContinue_Kind:
  1260. this->write("continue;");
  1261. break;
  1262. case Statement::kDiscard_Kind:
  1263. this->write("discard;");
  1264. break;
  1265. case Statement::kNop_Kind:
  1266. this->write(";");
  1267. break;
  1268. default:
  1269. ABORT("unsupported statement: %s", s.description().c_str());
  1270. }
  1271. }
  1272. void GLSLCodeGenerator::writeStatements(const std::vector<std::unique_ptr<Statement>>& statements) {
  1273. for (const auto& s : statements) {
  1274. if (!s->isEmpty()) {
  1275. this->writeStatement(*s);
  1276. this->writeLine();
  1277. }
  1278. }
  1279. }
  1280. void GLSLCodeGenerator::writeBlock(const Block& b) {
  1281. this->writeLine("{");
  1282. fIndentation++;
  1283. this->writeStatements(b.fStatements);
  1284. fIndentation--;
  1285. this->write("}");
  1286. }
  1287. void GLSLCodeGenerator::writeIfStatement(const IfStatement& stmt) {
  1288. this->write("if (");
  1289. this->writeExpression(*stmt.fTest, kTopLevel_Precedence);
  1290. this->write(") ");
  1291. this->writeStatement(*stmt.fIfTrue);
  1292. if (stmt.fIfFalse) {
  1293. this->write(" else ");
  1294. this->writeStatement(*stmt.fIfFalse);
  1295. }
  1296. }
  1297. void GLSLCodeGenerator::writeForStatement(const ForStatement& f) {
  1298. this->write("for (");
  1299. if (f.fInitializer && !f.fInitializer->isEmpty()) {
  1300. this->writeStatement(*f.fInitializer);
  1301. } else {
  1302. this->write("; ");
  1303. }
  1304. if (f.fTest) {
  1305. if (fProgram.fSettings.fCaps->addAndTrueToLoopCondition()) {
  1306. std::unique_ptr<Expression> and_true(new BinaryExpression(
  1307. -1, f.fTest->clone(), Token::LOGICALAND,
  1308. std::unique_ptr<BoolLiteral>(new BoolLiteral(fContext, -1,
  1309. true)),
  1310. *fContext.fBool_Type));
  1311. this->writeExpression(*and_true, kTopLevel_Precedence);
  1312. } else {
  1313. this->writeExpression(*f.fTest, kTopLevel_Precedence);
  1314. }
  1315. }
  1316. this->write("; ");
  1317. if (f.fNext) {
  1318. this->writeExpression(*f.fNext, kTopLevel_Precedence);
  1319. }
  1320. this->write(") ");
  1321. this->writeStatement(*f.fStatement);
  1322. }
  1323. void GLSLCodeGenerator::writeWhileStatement(const WhileStatement& w) {
  1324. this->write("while (");
  1325. this->writeExpression(*w.fTest, kTopLevel_Precedence);
  1326. this->write(") ");
  1327. this->writeStatement(*w.fStatement);
  1328. }
  1329. void GLSLCodeGenerator::writeDoStatement(const DoStatement& d) {
  1330. if (!fProgram.fSettings.fCaps->rewriteDoWhileLoops()) {
  1331. this->write("do ");
  1332. this->writeStatement(*d.fStatement);
  1333. this->write(" while (");
  1334. this->writeExpression(*d.fTest, kTopLevel_Precedence);
  1335. this->write(");");
  1336. return;
  1337. }
  1338. // Otherwise, do the do while loop workaround, to rewrite loops of the form:
  1339. // do {
  1340. // CODE;
  1341. // } while (CONDITION)
  1342. //
  1343. // to loops of the form
  1344. // bool temp = false;
  1345. // while (true) {
  1346. // if (temp) {
  1347. // if (!CONDITION) {
  1348. // break;
  1349. // }
  1350. // }
  1351. // temp = true;
  1352. // CODE;
  1353. // }
  1354. String tmpVar = "_tmpLoopSeenOnce" + to_string(fVarCount++);
  1355. this->write("bool ");
  1356. this->write(tmpVar);
  1357. this->writeLine(" = false;");
  1358. this->writeLine("while (true) {");
  1359. fIndentation++;
  1360. this->write("if (");
  1361. this->write(tmpVar);
  1362. this->writeLine(") {");
  1363. fIndentation++;
  1364. this->write("if (!");
  1365. this->writeExpression(*d.fTest, kPrefix_Precedence);
  1366. this->writeLine(") {");
  1367. fIndentation++;
  1368. this->writeLine("break;");
  1369. fIndentation--;
  1370. this->writeLine("}");
  1371. fIndentation--;
  1372. this->writeLine("}");
  1373. this->write(tmpVar);
  1374. this->writeLine(" = true;");
  1375. this->writeStatement(*d.fStatement);
  1376. this->writeLine();
  1377. fIndentation--;
  1378. this->write("}");
  1379. }
  1380. void GLSLCodeGenerator::writeSwitchStatement(const SwitchStatement& s) {
  1381. this->write("switch (");
  1382. this->writeExpression(*s.fValue, kTopLevel_Precedence);
  1383. this->writeLine(") {");
  1384. fIndentation++;
  1385. for (const auto& c : s.fCases) {
  1386. if (c->fValue) {
  1387. this->write("case ");
  1388. this->writeExpression(*c->fValue, kTopLevel_Precedence);
  1389. this->writeLine(":");
  1390. } else {
  1391. this->writeLine("default:");
  1392. }
  1393. fIndentation++;
  1394. for (const auto& stmt : c->fStatements) {
  1395. this->writeStatement(*stmt);
  1396. this->writeLine();
  1397. }
  1398. fIndentation--;
  1399. }
  1400. fIndentation--;
  1401. this->write("}");
  1402. }
  1403. void GLSLCodeGenerator::writeReturnStatement(const ReturnStatement& r) {
  1404. this->write("return");
  1405. if (r.fExpression) {
  1406. this->write(" ");
  1407. this->writeExpression(*r.fExpression, kTopLevel_Precedence);
  1408. }
  1409. this->write(";");
  1410. }
  1411. void GLSLCodeGenerator::writeHeader() {
  1412. this->write(fProgram.fSettings.fCaps->versionDeclString());
  1413. this->writeLine();
  1414. }
  1415. void GLSLCodeGenerator::writeProgramElement(const ProgramElement& e) {
  1416. switch (e.fKind) {
  1417. case ProgramElement::kExtension_Kind:
  1418. this->writeExtension(((Extension&) e).fName);
  1419. break;
  1420. case ProgramElement::kVar_Kind: {
  1421. VarDeclarations& decl = (VarDeclarations&) e;
  1422. if (decl.fVars.size() > 0) {
  1423. int builtin = ((VarDeclaration&) *decl.fVars[0]).fVar->fModifiers.fLayout.fBuiltin;
  1424. if (builtin == -1) {
  1425. // normal var
  1426. this->writeVarDeclarations(decl, true);
  1427. this->writeLine();
  1428. } else if (builtin == SK_FRAGCOLOR_BUILTIN &&
  1429. fProgram.fSettings.fCaps->mustDeclareFragmentShaderOutput() &&
  1430. ((VarDeclaration&) *decl.fVars[0]).fVar->fWriteCount) {
  1431. if (fProgram.fSettings.fFragColorIsInOut) {
  1432. this->write("inout ");
  1433. } else {
  1434. this->write("out ");
  1435. }
  1436. if (usesPrecisionModifiers()) {
  1437. this->write("mediump ");
  1438. }
  1439. this->writeLine("vec4 sk_FragColor;");
  1440. }
  1441. }
  1442. break;
  1443. }
  1444. case ProgramElement::kInterfaceBlock_Kind:
  1445. this->writeInterfaceBlock((InterfaceBlock&) e);
  1446. break;
  1447. case ProgramElement::kFunction_Kind:
  1448. this->writeFunction((FunctionDefinition&) e);
  1449. break;
  1450. case ProgramElement::kModifiers_Kind: {
  1451. const Modifiers& modifiers = ((ModifiersDeclaration&) e).fModifiers;
  1452. if (!fFoundGSInvocations && modifiers.fLayout.fInvocations >= 0) {
  1453. if (fProgram.fSettings.fCaps->gsInvocationsExtensionString()) {
  1454. this->writeExtension(fProgram.fSettings.fCaps->gsInvocationsExtensionString());
  1455. }
  1456. fFoundGSInvocations = true;
  1457. }
  1458. this->writeModifiers(modifiers, true);
  1459. this->writeLine(";");
  1460. break;
  1461. }
  1462. case ProgramElement::kEnum_Kind:
  1463. break;
  1464. default:
  1465. printf("%s\n", e.description().c_str());
  1466. ABORT("unsupported program element");
  1467. }
  1468. }
  1469. void GLSLCodeGenerator::writeInputVars() {
  1470. if (fProgram.fInputs.fRTWidth) {
  1471. const char* precision = usesPrecisionModifiers() ? "highp " : "";
  1472. fGlobals.writeText("uniform ");
  1473. fGlobals.writeText(precision);
  1474. fGlobals.writeText("float " SKSL_RTWIDTH_NAME ";\n");
  1475. }
  1476. if (fProgram.fInputs.fRTHeight) {
  1477. const char* precision = usesPrecisionModifiers() ? "highp " : "";
  1478. fGlobals.writeText("uniform ");
  1479. fGlobals.writeText(precision);
  1480. fGlobals.writeText("float " SKSL_RTHEIGHT_NAME ";\n");
  1481. }
  1482. }
  1483. bool GLSLCodeGenerator::generateCode() {
  1484. if (fProgramKind != Program::kPipelineStage_Kind) {
  1485. this->writeHeader();
  1486. }
  1487. if (Program::kGeometry_Kind == fProgramKind &&
  1488. fProgram.fSettings.fCaps->geometryShaderExtensionString()) {
  1489. this->writeExtension(fProgram.fSettings.fCaps->geometryShaderExtensionString());
  1490. }
  1491. OutputStream* rawOut = fOut;
  1492. StringStream body;
  1493. fOut = &body;
  1494. for (const auto& e : fProgram) {
  1495. this->writeProgramElement(e);
  1496. }
  1497. fOut = rawOut;
  1498. write_stringstream(fExtensions, *rawOut);
  1499. this->writeInputVars();
  1500. write_stringstream(fGlobals, *rawOut);
  1501. if (!fProgram.fSettings.fCaps->canUseFragCoord()) {
  1502. Layout layout;
  1503. switch (fProgram.fKind) {
  1504. case Program::kVertex_Kind: {
  1505. Modifiers modifiers(layout, Modifiers::kOut_Flag);
  1506. this->writeModifiers(modifiers, true);
  1507. if (this->usesPrecisionModifiers()) {
  1508. this->write("highp ");
  1509. }
  1510. this->write("vec4 sk_FragCoord_Workaround;\n");
  1511. break;
  1512. }
  1513. case Program::kFragment_Kind: {
  1514. Modifiers modifiers(layout, Modifiers::kIn_Flag);
  1515. this->writeModifiers(modifiers, true);
  1516. if (this->usesPrecisionModifiers()) {
  1517. this->write("highp ");
  1518. }
  1519. this->write("vec4 sk_FragCoord_Workaround;\n");
  1520. break;
  1521. }
  1522. default:
  1523. break;
  1524. }
  1525. }
  1526. if (this->usesPrecisionModifiers()) {
  1527. this->writeLine("precision mediump float;");
  1528. }
  1529. write_stringstream(fExtraFunctions, *rawOut);
  1530. write_stringstream(body, *rawOut);
  1531. return true;
  1532. }
  1533. }