130ba436f04e61d4505fb854d5fc56079636e0788joshualitt/* 230ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Copyright 2014 Google Inc. 330ba436f04e61d4505fb854d5fc56079636e0788joshualitt * 430ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Use of this source code is governed by a BSD-style license that can be 530ba436f04e61d4505fb854d5fc56079636e0788joshualitt * found in the LICENSE file. 630ba436f04e61d4505fb854d5fc56079636e0788joshualitt */ 730ba436f04e61d4505fb854d5fc56079636e0788joshualitt 899938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon#include "GrShaderVar.h" 994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#include "GrShaderCaps.h" 10cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon#include "GrSwizzle.h" 112d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLShaderBuilder.h" 1277320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman#include "glsl/GrGLSLColorSpaceXformHelper.h" 138dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel#include "glsl/GrGLSLProgramBuilder.h" 1430ba436f04e61d4505fb854d5fc56079636e0788joshualitt 152d721d33aad192cc8a7a1321504b39bdca2a57ceegdanielGrGLSLShaderBuilder::GrGLSLShaderBuilder(GrGLSLProgramBuilder* program) 1630ba436f04e61d4505fb854d5fc56079636e0788joshualitt : fProgramBuilder(program) 178dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel , fInputs(GrGLSLProgramBuilder::kVarsPerBlock) 188dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel , fOutputs(GrGLSLProgramBuilder::kVarsPerBlock) 1943466a1ade066f96823dbc7963767da3973afd91joshualitt , fFeaturesAddedMask(0) 2043466a1ade066f96823dbc7963767da3973afd91joshualitt , fCodeIndex(kCode) 2143466a1ade066f96823dbc7963767da3973afd91joshualitt , fFinalized(false) { 2243466a1ade066f96823dbc7963767da3973afd91joshualitt // We push back some dummy pointers which will later become our header 2343466a1ade066f96823dbc7963767da3973afd91joshualitt for (int i = 0; i <= kCode; i++) { 2443466a1ade066f96823dbc7963767da3973afd91joshualitt fShaderStrings.push_back(); 2596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fCompilerStrings.push_back(nullptr); 2643466a1ade066f96823dbc7963767da3973afd91joshualitt fCompilerStringLengths.push_back(0); 2743466a1ade066f96823dbc7963767da3973afd91joshualitt } 2843466a1ade066f96823dbc7963767da3973afd91joshualitt 2943466a1ade066f96823dbc7963767da3973afd91joshualitt this->main() = "void main() {"; 3030ba436f04e61d4505fb854d5fc56079636e0788joshualitt} 3130ba436f04e61d4505fb854d5fc56079636e0788joshualitt 3299938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomonvoid GrGLSLShaderBuilder::declAppend(const GrShaderVar& var) { 33b2f94d1f4a74f82ea4dd3feb1690ef6d05892afbegdaniel SkString tempDecl; 3494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon var.appendDecl(fProgramBuilder->shaderCaps(), &tempDecl); 35b2f94d1f4a74f82ea4dd3feb1690ef6d05892afbegdaniel this->codeAppendf("%s;", tempDecl.c_str()); 36b2f94d1f4a74f82ea4dd3feb1690ef6d05892afbegdaniel} 37b2f94d1f4a74f82ea4dd3feb1690ef6d05892afbegdaniel 3875864b09e11a1918f202093d042f23ca0b3c8530csmartdaltonvoid GrGLSLShaderBuilder::declareGlobal(const GrShaderVar& v) { 3975864b09e11a1918f202093d042f23ca0b3c8530csmartdalton v.appendDecl(this->getProgramBuilder()->shaderCaps(), &this->definitions()); 4075864b09e11a1918f202093d042f23ca0b3c8530csmartdalton this->definitions().append(";"); 4175864b09e11a1918f202093d042f23ca0b3c8530csmartdalton} 4275864b09e11a1918f202093d042f23ca0b3c8530csmartdalton 432d721d33aad192cc8a7a1321504b39bdca2a57ceegdanielvoid GrGLSLShaderBuilder::emitFunction(GrSLType returnType, 442d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel const char* name, 452d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel int argCnt, 4699938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon const GrShaderVar* args, 472d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel const char* body, 482d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel SkString* outName) { 4943466a1ade066f96823dbc7963767da3973afd91joshualitt this->functions().append(GrGLSLTypeString(returnType)); 5030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fProgramBuilder->nameVariable(outName, '\0', name); 5143466a1ade066f96823dbc7963767da3973afd91joshualitt this->functions().appendf(" %s", outName->c_str()); 5243466a1ade066f96823dbc7963767da3973afd91joshualitt this->functions().append("("); 5330ba436f04e61d4505fb854d5fc56079636e0788joshualitt for (int i = 0; i < argCnt; ++i) { 5494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon args[i].appendDecl(fProgramBuilder->shaderCaps(), &this->functions()); 5530ba436f04e61d4505fb854d5fc56079636e0788joshualitt if (i < argCnt - 1) { 5643466a1ade066f96823dbc7963767da3973afd91joshualitt this->functions().append(", "); 5730ba436f04e61d4505fb854d5fc56079636e0788joshualitt } 5830ba436f04e61d4505fb854d5fc56079636e0788joshualitt } 5943466a1ade066f96823dbc7963767da3973afd91joshualitt this->functions().append(") {\n"); 6043466a1ade066f96823dbc7963767da3973afd91joshualitt this->functions().append(body); 6143466a1ade066f96823dbc7963767da3973afd91joshualitt this->functions().append("}\n\n"); 6230ba436f04e61d4505fb854d5fc56079636e0788joshualitt} 6330ba436f04e61d4505fb854d5fc56079636e0788joshualitt 64101b844d6ba031de5c4e95b43f9292f266799237Brian Salomonstatic inline void append_texture_swizzle(SkString* out, GrSwizzle swizzle) { 65101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon if (swizzle != GrSwizzle::RGBA()) { 66101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon out->appendf(".%s", swizzle.c_str()); 67101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon } 68101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon} 69101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon 702d721d33aad192cc8a7a1321504b39bdca2a57ceegdanielvoid GrGLSLShaderBuilder::appendTextureLookup(SkString* out, 7109aa1fce69b214714171db12c341aebd78dd29eaegdaniel SamplerHandle samplerHandle, 722d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel const char* coordName, 732d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel GrSLType varyingType) const { 7499938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon const GrShaderVar& sampler = fProgramBuilder->samplerVariable(samplerHandle); 75101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon GrSLType samplerType = sampler.getType(); 76990dbc88796f656418bcc4c196df30ed9bef6345egdaniel if (samplerType == kTexture2DRectSampler_GrSLType) { 77e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (varyingType == kVec2f_GrSLType) { 782b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas out->appendf("texture(%s, textureSize(%s) * %s)", 79101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon sampler.c_str(), sampler.c_str(), coordName); 80e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } else { 812b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas out->appendf("texture(%s, vec3(textureSize(%s) * %s.xy, %s.z))", 82101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon sampler.c_str(), sampler.c_str(), coordName, coordName); 83e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 84e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } else { 852b3dab62bccdbf6244aef9103e9e739147af8616Ethan Nicholas out->appendf("texture(%s, %s)", sampler.c_str(), coordName); 86e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 87101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon append_texture_swizzle(out, fProgramBuilder->samplerSwizzle(samplerHandle)); 8830ba436f04e61d4505fb854d5fc56079636e0788joshualitt} 8930ba436f04e61d4505fb854d5fc56079636e0788joshualitt 9009aa1fce69b214714171db12c341aebd78dd29eaegdanielvoid GrGLSLShaderBuilder::appendTextureLookup(SamplerHandle samplerHandle, 912d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel const char* coordName, 9277320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman GrSLType varyingType, 9377320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman GrGLSLColorSpaceXformHelper* colorXformHelper) { 94c624d9d212c4168fc6c202a8535ddff8a3bfb16aBrian Osman if (colorXformHelper && colorXformHelper->isValid()) { 9577320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman // With a color gamut transform, we need to wrap the lookup in another function call 9677320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman SkString lookup; 9777320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman this->appendTextureLookup(&lookup, samplerHandle, coordName, varyingType); 9877320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman this->appendColorGamutXform(lookup.c_str(), colorXformHelper); 9977320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman } else { 10077320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman this->appendTextureLookup(&this->code(), samplerHandle, coordName, varyingType); 10177320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman } 10230ba436f04e61d4505fb854d5fc56079636e0788joshualitt} 10330ba436f04e61d4505fb854d5fc56079636e0788joshualitt 10477320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosmanvoid GrGLSLShaderBuilder::appendTextureLookupAndModulate( 10577320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman const char* modulation, 10677320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman SamplerHandle samplerHandle, 10777320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman const char* coordName, 10877320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman GrSLType varyingType, 10977320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman GrGLSLColorSpaceXformHelper* colorXformHelper) { 11030ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkString lookup; 11109aa1fce69b214714171db12c341aebd78dd29eaegdaniel this->appendTextureLookup(&lookup, samplerHandle, coordName, varyingType); 112c624d9d212c4168fc6c202a8535ddff8a3bfb16aBrian Osman if (colorXformHelper && colorXformHelper->isValid()) { 11377320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman SkString xform; 11477320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman this->appendColorGamutXform(&xform, lookup.c_str(), colorXformHelper); 11577320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(xform)).c_str()); 11677320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman } else { 11777320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); 11877320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman } 11977320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman} 12077320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman 12177320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosmanvoid GrGLSLShaderBuilder::appendColorGamutXform(SkString* out, 12277320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman const char* srcColor, 12377320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman GrGLSLColorSpaceXformHelper* colorXformHelper) { 12477320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman // Our color is (r, g, b, a), but we want to multiply (r, g, b, 1) by our matrix, then 12577320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman // re-insert the original alpha. The supplied srcColor is likely to be of the form 1265192475bd8cb98e8e0c1192ab5ece7b8595701d6brianosman // "texture(...)", and we don't want to evaluate that twice, so wrap everything in a function. 12799938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon static const GrShaderVar gColorGamutXformArgs[] = { 12899938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar("color", kVec4f_GrSLType), 12999938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar("xform", kMat44f_GrSLType), 13077320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman }; 13177320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman SkString functionBody; 1320bd783f951a004ccca175b166f2b30a0fd18a6f6Brian Osman // Gamut xform, clamp to destination gamut. We only support/have premultiplied textures, so we 1330bd783f951a004ccca175b166f2b30a0fd18a6f6Brian Osman // always just clamp to alpha. 1340bd783f951a004ccca175b166f2b30a0fd18a6f6Brian Osman functionBody.append("\tcolor.rgb = clamp((xform * vec4(color.rgb, 1.0)).rgb, 0.0, color.a);\n"); 13577320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman functionBody.append("\treturn color;"); 13677320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman SkString colorGamutXformFuncName; 13777320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman this->emitFunction(kVec4f_GrSLType, 13877320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman "colorGamutXform", 13977320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman SK_ARRAY_COUNT(gColorGamutXformArgs), 14077320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman gColorGamutXformArgs, 14177320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman functionBody.c_str(), 14277320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman &colorGamutXformFuncName); 14377320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman 144c624d9d212c4168fc6c202a8535ddff8a3bfb16aBrian Osman GrGLSLUniformHandler* uniformHandler = fProgramBuilder->uniformHandler(); 14577320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman out->appendf("%s(%s, %s)", colorGamutXformFuncName.c_str(), srcColor, 146c624d9d212c4168fc6c202a8535ddff8a3bfb16aBrian Osman uniformHandler->getUniformCStr(colorXformHelper->gamutXformUniform())); 14777320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman} 14877320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman 14977320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosmanvoid GrGLSLShaderBuilder::appendColorGamutXform(const char* srcColor, 15077320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman GrGLSLColorSpaceXformHelper* colorXformHelper) { 15177320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman SkString xform; 15277320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman this->appendColorGamutXform(&xform, srcColor, colorXformHelper); 15377320dbabcddf05c0a1489eaf1f496729dc8de0ebrianosman this->codeAppend(xform.c_str()); 15430ba436f04e61d4505fb854d5fc56079636e0788joshualitt} 15530ba436f04e61d4505fb854d5fc56079636e0788joshualitt 156f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdaltonvoid GrGLSLShaderBuilder::appendTexelFetch(SkString* out, 15709aa1fce69b214714171db12c341aebd78dd29eaegdaniel SamplerHandle samplerHandle, 158f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton const char* coordExpr) const { 15999938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon const GrShaderVar& sampler = fProgramBuilder->samplerVariable(samplerHandle); 16094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon SkASSERT(fProgramBuilder->shaderCaps()->texelFetchSupport()); 161101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon SkASSERT(GrSLTypeIsCombinedSamplerType(sampler.getType())); 162f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton 163101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon out->appendf("texelFetch(%s, %s)", sampler.c_str(), coordExpr); 164f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton 165101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon append_texture_swizzle(out, fProgramBuilder->samplerSwizzle(samplerHandle)); 166f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton} 167f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton 16809aa1fce69b214714171db12c341aebd78dd29eaegdanielvoid GrGLSLShaderBuilder::appendTexelFetch(SamplerHandle samplerHandle, const char* coordExpr) { 16909aa1fce69b214714171db12c341aebd78dd29eaegdaniel this->appendTexelFetch(&this->code(), samplerHandle, coordExpr); 170f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton} 171f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton 172f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomonvoid GrGLSLShaderBuilder::appendImageStorageLoad(SkString* out, ImageStorageHandle handle, 173f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon const char* coordExpr) { 174f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon const GrShaderVar& imageStorage = fProgramBuilder->imageStorageVariable(handle); 175f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon out->appendf("imageLoad(%s, %s)", imageStorage.c_str(), coordExpr); 176f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon} 177f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon 178f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomonvoid GrGLSLShaderBuilder::appendImageStorageLoad(ImageStorageHandle handle, const char* coordExpr) { 179f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon this->appendImageStorageLoad(&this->code(), handle, coordExpr); 180f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon} 181f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon 18233ad701bc30387127c427fb1e38c781d5de33491cdaltonbool GrGLSLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) { 18333ad701bc30387127c427fb1e38c781d5de33491cdalton if (featureBit & fFeaturesAddedMask) { 18433ad701bc30387127c427fb1e38c781d5de33491cdalton return false; 18530ba436f04e61d4505fb854d5fc56079636e0788joshualitt } 18633ad701bc30387127c427fb1e38c781d5de33491cdalton this->extensions().appendf("#extension %s: require\n", extensionName); 18733ad701bc30387127c427fb1e38c781d5de33491cdalton fFeaturesAddedMask |= featureBit; 18833ad701bc30387127c427fb1e38c781d5de33491cdalton return true; 18930ba436f04e61d4505fb854d5fc56079636e0788joshualitt} 19030ba436f04e61d4505fb854d5fc56079636e0788joshualitt 1912d721d33aad192cc8a7a1321504b39bdca2a57ceegdanielvoid GrGLSLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { 19247bb38283072dc87dc93220cd2f370ca109972ffjoshualitt for (int i = 0; i < vars.count(); ++i) { 19394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon vars[i].appendDecl(fProgramBuilder->shaderCaps(), out); 19447bb38283072dc87dc93220cd2f370ca109972ffjoshualitt out->append(";\n"); 19547bb38283072dc87dc93220cd2f370ca109972ffjoshualitt } 19647bb38283072dc87dc93220cd2f370ca109972ffjoshualitt} 19747bb38283072dc87dc93220cd2f370ca109972ffjoshualitt 1982d721d33aad192cc8a7a1321504b39bdca2a57ceegdanielvoid GrGLSLShaderBuilder::addLayoutQualifier(const char* param, InterfaceQualifier interface) { 19994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon SkASSERT(fProgramBuilder->shaderCaps()->generation() >= k330_GrGLSLGeneration || 20094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon fProgramBuilder->shaderCaps()->mustEnableAdvBlendEqs()); 201e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton fLayoutParams[interface].push_back() = param; 202e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton} 203e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton 2042d721d33aad192cc8a7a1321504b39bdca2a57ceegdanielvoid GrGLSLShaderBuilder::compileAndAppendLayoutQualifiers() { 205e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton static const char* interfaceQualifierNames[] = { 206276cc4113a6440b842c0dacb6d668ee3b45a3b7dcsmartdalton "in", 207e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton "out" 208e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton }; 209e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton 210e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton for (int interface = 0; interface <= kLastInterfaceQualifier; ++interface) { 211e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton const SkTArray<SkString>& params = fLayoutParams[interface]; 212e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton if (params.empty()) { 213e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton continue; 214e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton } 215e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton this->layoutQualifiers().appendf("layout(%s", params[0].c_str()); 216e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton for (int i = 1; i < params.count(); ++i) { 217e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton this->layoutQualifiers().appendf(", %s", params[i].c_str()); 218e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton } 219e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton this->layoutQualifiers().appendf(") %s;\n", interfaceQualifierNames[interface]); 220e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton } 221e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton 222276cc4113a6440b842c0dacb6d668ee3b45a3b7dcsmartdalton GR_STATIC_ASSERT(0 == GrGLSLShaderBuilder::kIn_InterfaceQualifier); 223276cc4113a6440b842c0dacb6d668ee3b45a3b7dcsmartdalton GR_STATIC_ASSERT(1 == GrGLSLShaderBuilder::kOut_InterfaceQualifier); 224e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton GR_STATIC_ASSERT(SK_ARRAY_COUNT(interfaceQualifierNames) == kLastInterfaceQualifier + 1); 225e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton} 226e4017d8ca709bc0b4fc0f95c26eb592a8d5c597bcdalton 2272d721d33aad192cc8a7a1321504b39bdca2a57ceegdanielvoid GrGLSLShaderBuilder::finalize(uint32_t visibility) { 22843466a1ade066f96823dbc7963767da3973afd91joshualitt SkASSERT(!fFinalized); 22994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon this->versionDecl() = fProgramBuilder->shaderCaps()->versionDeclString(); 230574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel this->compileAndAppendLayoutQualifiers(); 231c8a66eb6335b4d92e052ebb37442baaa6c1e386eegdaniel SkASSERT(visibility); 2325e58ceea8569f0d90ff7e3daf5de2def50407212cdalton fProgramBuilder->appendUniformDecls((GrShaderFlags) visibility, &this->uniforms()); 233574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel this->appendDecls(fInputs, &this->inputs()); 234574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel this->appendDecls(fOutputs, &this->outputs()); 235574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel this->onFinalize(); 23643466a1ade066f96823dbc7963767da3973afd91joshualitt // append the 'footer' to code 23743466a1ade066f96823dbc7963767da3973afd91joshualitt this->code().append("}"); 23843466a1ade066f96823dbc7963767da3973afd91joshualitt 23943466a1ade066f96823dbc7963767da3973afd91joshualitt for (int i = 0; i <= fCodeIndex; i++) { 24043466a1ade066f96823dbc7963767da3973afd91joshualitt fCompilerStrings[i] = fShaderStrings[i].c_str(); 24143466a1ade066f96823dbc7963767da3973afd91joshualitt fCompilerStringLengths[i] = (int)fShaderStrings[i].size(); 24243466a1ade066f96823dbc7963767da3973afd91joshualitt } 24343466a1ade066f96823dbc7963767da3973afd91joshualitt 24443466a1ade066f96823dbc7963767da3973afd91joshualitt fFinalized = true; 24543466a1ade066f96823dbc7963767da3973afd91joshualitt} 246