blob: 4ffc1ecf225ca0237e1a6e139b814c40d523b62b [file] [log] [blame]
joshualitt30ba4362014-08-21 20:18:45 -07001/*
2 * Copyright 2014 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
joshualitt47bb3822014-10-07 16:43:25 -07008#include "GrGLProgramBuilder.h"
joshualitt8072caa2015-02-12 14:20:52 -08009
bsalomon6f7f2012015-03-16 14:00:52 -070010#include "GrAutoLocaleSetter.h"
Robert Phillips9bee2e52017-05-29 12:37:20 -040011#include "GrContext.h"
Robert Phillips6be756b2018-01-16 15:07:54 -050012#include "GrContextPriv.h"
joshualitt47bb3822014-10-07 16:43:25 -070013#include "GrCoordTransform.h"
joshualitt30ba4362014-08-21 20:18:45 -070014#include "GrGLProgramBuilder.h"
egdaniel5d8f69f2016-09-07 07:24:12 -070015#include "GrProgramDesc.h"
Brian Salomon94efbf52016-11-29 13:43:05 -050016#include "GrShaderCaps.h"
bsalomon7f9b2e42016-01-12 13:29:26 -080017#include "GrSwizzle.h"
Hal Canary95e3c052017-01-11 12:44:43 -050018#include "SkAutoMalloc.h"
Derek Sollenberger488f0d62017-03-03 15:48:33 -050019#include "SkATrace.h"
joshualitt30ba4362014-08-21 20:18:45 -070020#include "SkTraceEvent.h"
joshualitte7afc2d2015-09-11 10:44:13 -070021#include "gl/GrGLGpu.h"
joshualitte7afc2d2015-09-11 10:44:13 -070022#include "gl/GrGLProgram.h"
egdaniel574a4c12015-11-02 06:22:44 -080023#include "gl/builders/GrGLShaderStringBuilder.h"
egdaniel64c47282015-11-13 06:54:19 -080024#include "glsl/GrGLSLFragmentProcessor.h"
egdaniele659a582015-11-13 09:55:43 -080025#include "glsl/GrGLSLGeometryProcessor.h"
egdaniel018fb622015-10-28 07:26:40 -070026#include "glsl/GrGLSLProgramDataManager.h"
egdanielfa4cc8b2015-11-13 08:34:52 -080027#include "glsl/GrGLSLXferProcessor.h"
joshualitt30ba4362014-08-21 20:18:45 -070028
joshualitt30ba4362014-08-21 20:18:45 -070029#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
30#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
31
egdaniel0e1853c2016-03-17 11:35:45 -070032GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrPipeline& pipeline,
33 const GrPrimitiveProcessor& primProc,
Ethan Nicholas38657112017-02-09 17:01:22 -050034 GrProgramDesc* desc,
egdaniel0e1853c2016-03-17 11:35:45 -070035 GrGLGpu* gpu) {
Robert Phillips6be756b2018-01-16 15:07:54 -050036#ifdef SK_DEBUG
37 GrResourceProvider* resourceProvider = gpu->getContext()->contextPriv().resourceProvider();
38
39 SkASSERT(!pipeline.isBad() && primProc.instantiate(resourceProvider));
40#endif
Robert Phillipsa91e0b72017-05-01 13:12:20 -040041
Derek Sollenberger488f0d62017-03-03 15:48:33 -050042 ATRACE_ANDROID_FRAMEWORK("Shader Compile");
bsalomon3318ee72015-03-16 11:56:29 -070043 GrAutoLocaleSetter als("C");
44
joshualitt47bb3822014-10-07 16:43:25 -070045 // create a builder. This will be handed off to effects so they can use it to add
46 // uniforms, varyings, textures, etc
egdaniel0e1853c2016-03-17 11:35:45 -070047 GrGLProgramBuilder builder(gpu, pipeline, primProc, desc);
joshualitt47bb3822014-10-07 16:43:25 -070048
Robert Phillips0c4b7b12018-03-06 08:20:37 -050049 auto persistentCache = gpu->getContext()->contextPriv().getPersistentCache();
50 if (persistentCache && gpu->glCaps().programBinarySupport()) {
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040051 sk_sp<SkData> key = SkData::MakeWithoutCopy(desc->asKey(), desc->keyLength());
Robert Phillips0c4b7b12018-03-06 08:20:37 -050052 builder.fCached = persistentCache->load(*key);
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040053 // the eventual end goal is to completely skip emitAndInstallProcs on a cache hit, but it's
54 // doing necessary setup in addition to generating the SkSL code. Currently we are only able
55 // to skip the SkSL->GLSL step on a cache hit.
56 }
Ethan Nicholas2983f402017-05-08 09:36:08 -040057 if (!builder.emitAndInstallProcs()) {
egdanielc1e71012016-01-20 07:53:51 -080058 builder.cleanupFragmentProcessors();
halcanary96fcdcc2015-08-27 07:41:13 -070059 return nullptr;
joshualitt6c891102015-05-13 08:51:49 -070060 }
egdanielc1e71012016-01-20 07:53:51 -080061 return builder.finalize();
joshualitt47bb3822014-10-07 16:43:25 -070062}
63
joshualitt47bb3822014-10-07 16:43:25 -070064/////////////////////////////////////////////////////////////////////////////
65
egdaniel0e1853c2016-03-17 11:35:45 -070066GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu,
67 const GrPipeline& pipeline,
68 const GrPrimitiveProcessor& primProc,
Ethan Nicholas38657112017-02-09 17:01:22 -050069 GrProgramDesc* desc)
egdaniel0e1853c2016-03-17 11:35:45 -070070 : INHERITED(pipeline, primProc, desc)
joshualitt30ba4362014-08-21 20:18:45 -070071 , fGpu(gpu)
egdaniel7ea439b2015-12-03 09:20:44 -080072 , fVaryingHandler(this)
73 , fUniformHandler(this) {
joshualitt30ba4362014-08-21 20:18:45 -070074}
75
egdanielfa896322016-01-13 12:19:30 -080076const GrCaps* GrGLProgramBuilder::caps() const {
77 return fGpu->caps();
78}
79
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040080bool GrGLProgramBuilder::compileAndAttachShaders(const char* glsl,
81 int length,
egdaniel574a4c12015-11-02 06:22:44 -080082 GrGLuint programId,
83 GrGLenum type,
Ethan Nicholas941e7e22016-12-12 15:33:30 -050084 SkTDArray<GrGLuint>* shaderIds,
85 const SkSL::Program::Settings& settings,
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040086 const SkSL::Program::Inputs& inputs) {
egdaniel574a4c12015-11-02 06:22:44 -080087 GrGLGpu* gpu = this->gpu();
88 GrGLuint shaderId = GrGLCompileAndAttachShader(gpu->glContext(),
89 programId,
90 type,
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040091 glsl,
92 length,
Ethan Nicholas941e7e22016-12-12 15:33:30 -050093 gpu->stats(),
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040094 settings);
egdaniel574a4c12015-11-02 06:22:44 -080095 if (!shaderId) {
96 return false;
97 }
98
99 *shaderIds->append() = shaderId;
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400100 if (inputs.fFlipY) {
Ethan Nicholas38657112017-02-09 17:01:22 -0500101 GrProgramDesc* d = this->desc();
Robert Phillips7f861922018-01-30 13:13:42 +0000102 d->setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(
103 this->pipeline().proxy()->origin()));
Ethan Nicholas38657112017-02-09 17:01:22 -0500104 d->finalize();
105 }
egdaniel574a4c12015-11-02 06:22:44 -0800106
107 return true;
108}
109
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400110bool GrGLProgramBuilder::compileAndAttachShaders(GrGLSLShaderBuilder& shader,
111 GrGLuint programId,
112 GrGLenum type,
113 SkTDArray<GrGLuint>* shaderIds,
114 const SkSL::Program::Settings& settings,
115 SkSL::Program::Inputs* outInputs) {
116 SkSL::String glsl;
117 std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(gpu()->glContext(), type,
118 shader.fCompilerStrings.begin(),
119 shader.fCompilerStringLengths.begin(),
120 shader.fCompilerStrings.count(),
121 settings,
122 &glsl);
123 *outInputs = program->fInputs;
124 return this->compileAndAttachShaders(glsl.c_str(),
125 glsl.size(),
126 programId,
127 type,
128 shaderIds,
129 settings,
130 *outInputs);
131}
132
joshualitt47bb3822014-10-07 16:43:25 -0700133GrGLProgram* GrGLProgramBuilder::finalize() {
Brian Osman39c08ac2017-07-26 09:36:09 -0400134 TRACE_EVENT0("skia", TRACE_FUNC);
Ryan Macnak38a10ad2017-07-10 10:36:34 -0700135
joshualitt47bb3822014-10-07 16:43:25 -0700136 // verify we can get a program id
137 GrGLuint programID;
138 GL_CALL_RET(programID, CreateProgram());
139 if (0 == programID) {
egdanielfa896322016-01-13 12:19:30 -0800140 this->cleanupFragmentProcessors();
halcanary96fcdcc2015-08-27 07:41:13 -0700141 return nullptr;
joshualitt30ba4362014-08-21 20:18:45 -0700142 }
143
Ethan Nicholas06d55fb2017-11-08 09:48:50 -0500144 if (this->gpu()->glCaps().programBinarySupport() &&
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500145 this->gpu()->getContext()->contextPriv().getPersistentCache()) {
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400146 GL_CALL(ProgramParameteri(programID, GR_GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GR_GL_TRUE));
147 }
148
egdaniel9f1d4152016-02-10 09:50:38 -0800149 this->finalizeShaders();
150
joshualitt47bb3822014-10-07 16:43:25 -0700151 // compile shaders and bind attributes / uniforms
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400152 const GrPrimitiveProcessor& primProc = this->primitiveProcessor();
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500153 SkSL::Program::Settings settings;
154 settings.fCaps = this->gpu()->glCaps().shaderCaps();
Robert Phillips2890fbf2017-07-26 15:48:41 -0400155 settings.fFlipY = this->pipeline().proxy()->origin() != kTopLeft_GrSurfaceOrigin;
Brian Osman8a83ca42018-02-12 14:32:17 -0500156 settings.fSharpenTextures = this->gpu()->getContext()->contextPriv().sharpenMipmappedTextures();
Brian Salomondc092132018-04-04 10:14:16 -0400157 settings.fFragColorIsInOut = this->fragColorIsInOut();
158
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500159 SkSL::Program::Inputs inputs;
joshualitt30ba4362014-08-21 20:18:45 -0700160 SkTDArray<GrGLuint> shadersToDelete;
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400161 bool cached = fGpu->glCaps().programBinarySupport() && nullptr != fCached.get();
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400162 if (cached) {
Ethan Nicholas907204f2017-11-14 14:35:57 -0500163 this->bindProgramResourceLocations(programID);
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400164 // cache hit, just hand the binary to GL
165 const uint8_t* bytes = fCached->bytes();
166 size_t offset = 0;
167 memcpy(&inputs, bytes + offset, sizeof(inputs));
168 offset += sizeof(inputs);
169 int binaryFormat;
170 memcpy(&binaryFormat, bytes + offset, sizeof(binaryFormat));
171 offset += sizeof(binaryFormat);
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400172 GrGLClearErr(this->gpu()->glInterface());
173 GR_GL_CALL_NOERRCHECK(this->gpu()->glInterface(),
174 ProgramBinary(programID, binaryFormat, (void*) (bytes + offset),
175 fCached->size() - offset));
176 if (GR_GL_GET_ERROR(this->gpu()->glInterface()) == GR_GL_NO_ERROR) {
177 if (inputs.fRTHeight) {
178 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
179 }
180 cached = this->checkLinkStatus(programID);
181 } else {
182 cached = false;
183 }
184 }
185 if (!cached) {
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400186 // cache miss, compile shaders
187 if (fFS.fForceHighPrecision) {
188 settings.fForceHighPrecision = true;
egdaniel8dcdedc2015-11-11 06:27:20 -0800189 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400190 SkSL::String glsl;
191 std::unique_ptr<SkSL::Program> fs = GrSkSLtoGLSL(gpu()->glContext(),
192 GR_GL_FRAGMENT_SHADER,
193 fFS.fCompilerStrings.begin(),
194 fFS.fCompilerStringLengths.begin(),
195 fFS.fCompilerStrings.count(),
196 settings,
197 &glsl);
198 inputs = fs->fInputs;
199 if (inputs.fRTHeight) {
200 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
201 }
202 if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
203 GR_GL_FRAGMENT_SHADER, &shadersToDelete, settings,
204 inputs)) {
205 this->cleanupProgram(programID, shadersToDelete);
206 return nullptr;
207 }
208
209 std::unique_ptr<SkSL::Program> vs = GrSkSLtoGLSL(gpu()->glContext(),
210 GR_GL_VERTEX_SHADER,
211 fVS.fCompilerStrings.begin(),
212 fVS.fCompilerStringLengths.begin(),
213 fVS.fCompilerStrings.count(),
214 settings,
215 &glsl);
216 if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
217 GR_GL_VERTEX_SHADER, &shadersToDelete, settings,
218 inputs)) {
219 this->cleanupProgram(programID, shadersToDelete);
220 return nullptr;
221 }
222
223 // NVPR actually requires a vertex shader to compile
224 bool useNvpr = primProc.isPathRendering();
225 if (!useNvpr) {
226 int vaCount = primProc.numAttribs();
227 for (int i = 0; i < vaCount; i++) {
Brian Salomon70132d02018-05-29 15:33:06 -0400228 GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).name()));
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400229 }
230 }
231
232 if (primProc.willUseGeoShader()) {
233 std::unique_ptr<SkSL::Program> gs;
234 gs = GrSkSLtoGLSL(gpu()->glContext(),
235 GR_GL_GEOMETRY_SHADER,
236 fGS.fCompilerStrings.begin(),
237 fGS.fCompilerStringLengths.begin(),
238 fGS.fCompilerStrings.count(),
239 settings,
240 &glsl);
241 if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
242 GR_GL_GEOMETRY_SHADER, &shadersToDelete, settings,
243 inputs)) {
244 this->cleanupProgram(programID, shadersToDelete);
245 return nullptr;
246 }
247
248 }
249 this->bindProgramResourceLocations(programID);
250
251 GL_CALL(LinkProgram(programID));
joshualitt47bb3822014-10-07 16:43:25 -0700252 }
joshualitt30ba4362014-08-21 20:18:45 -0700253 // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
cdalton1acea862015-06-02 13:05:52 -0700254 bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver();
joshualitt30ba4362014-08-21 20:18:45 -0700255#ifdef SK_DEBUG
256 checkLinked = true;
257#endif
258 if (checkLinked) {
Brian Salomone334c592017-05-15 11:00:58 -0400259 if (!this->checkLinkStatus(programID)) {
260 SkDebugf("VS:\n");
261 GrGLPrintShader(fGpu->glContext(), GR_GL_VERTEX_SHADER, fVS.fCompilerStrings.begin(),
262 fVS.fCompilerStringLengths.begin(), fVS.fCompilerStrings.count(),
263 settings);
264 if (primProc.willUseGeoShader()) {
265 SkDebugf("\nGS:\n");
266 GrGLPrintShader(fGpu->glContext(), GR_GL_GEOMETRY_SHADER,
267 fGS.fCompilerStrings.begin(), fGS.fCompilerStringLengths.begin(),
268 fGS.fCompilerStrings.count(), settings);
269 }
270 SkDebugf("\nFS:\n");
271 GrGLPrintShader(fGpu->glContext(), GR_GL_FRAGMENT_SHADER, fFS.fCompilerStrings.begin(),
272 fFS.fCompilerStringLengths.begin(), fFS.fCompilerStrings.count(),
273 settings);
274 SkDEBUGFAIL("");
275 return nullptr;
276 }
joshualittfe1233c2014-10-07 12:16:35 -0700277 }
kkinnunen7aedda52015-06-29 23:01:28 -0700278 this->resolveProgramResourceLocations(programID);
joshualittdb0d3ca2014-10-07 12:42:26 -0700279
joshualitt47bb3822014-10-07 16:43:25 -0700280 this->cleanupShaders(shadersToDelete);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500281 if (!cached && this->gpu()->getContext()->contextPriv().getPersistentCache() &&
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400282 fGpu->glCaps().programBinarySupport()) {
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400283 GrGLsizei length = 0;
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400284 GL_CALL(GetProgramiv(programID, GL_PROGRAM_BINARY_LENGTH, &length));
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500285 if (length > 0) {
286 // store shader in cache
287 sk_sp<SkData> key = SkData::MakeWithoutCopy(desc()->asKey(), desc()->keyLength());
288 GrGLenum binaryFormat;
Mike Klein1d746202018-01-25 17:32:51 -0500289 std::unique_ptr<char[]> binary(new char[length]);
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500290 GL_CALL(GetProgramBinary(programID, length, &length, &binaryFormat, binary.get()));
291 size_t dataLength = sizeof(inputs) + sizeof(binaryFormat) + length;
Mike Klein1d746202018-01-25 17:32:51 -0500292 std::unique_ptr<uint8_t[]> data(new uint8_t[dataLength]);
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500293 size_t offset = 0;
294 memcpy(data.get() + offset, &inputs, sizeof(inputs));
295 offset += sizeof(inputs);
296 memcpy(data.get() + offset, &binaryFormat, sizeof(binaryFormat));
297 offset += sizeof(binaryFormat);
298 memcpy(data.get() + offset, binary.get(), length);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500299 this->gpu()->getContext()->contextPriv().getPersistentCache()->store(
300 *key, *SkData::MakeWithoutCopy(data.get(), dataLength));
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500301 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400302 }
joshualitt47bb3822014-10-07 16:43:25 -0700303 return this->createProgram(programID);
304}
305
kkinnunen7aedda52015-06-29 23:01:28 -0700306void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) {
egdaniel7ea439b2015-12-03 09:20:44 -0800307 fUniformHandler.bindUniformLocations(programID, fGpu->glCaps());
kkinnunen7aedda52015-06-29 23:01:28 -0700308
egdaniel8dcdedc2015-11-11 06:27:20 -0800309 const GrGLCaps& caps = this->gpu()->glCaps();
310 if (fFS.hasCustomColorOutput() && caps.bindFragDataLocationSupport()) {
311 GL_CALL(BindFragDataLocation(programID, 0,
egdaniel2d721d32015-11-11 13:06:05 -0800312 GrGLSLFragmentShaderBuilder::DeclaredColorOutputName()));
egdaniel8dcdedc2015-11-11 06:27:20 -0800313 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500314 if (fFS.hasSecondaryOutput() && caps.shaderCaps()->mustDeclareFragmentShaderOutput()) {
egdaniel8dcdedc2015-11-11 06:27:20 -0800315 GL_CALL(BindFragDataLocationIndexed(programID, 0, 1,
egdaniel2d721d32015-11-11 13:06:05 -0800316 GrGLSLFragmentShaderBuilder::DeclaredSecondaryColorOutputName()));
egdaniel8dcdedc2015-11-11 06:27:20 -0800317 }
joshualittd8dd47b2015-09-11 11:45:01 -0700318
319 // handle NVPR separable varyings
320 if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() ||
321 !fGpu->glPathRendering()->shouldBindFragmentInputs()) {
322 return;
323 }
egdaniel0eafe792015-11-20 14:01:22 -0800324 int count = fVaryingHandler.fPathProcVaryingInfos.count();
joshualittd8dd47b2015-09-11 11:45:01 -0700325 for (int i = 0; i < count; ++i) {
egdaniel0eafe792015-11-20 14:01:22 -0800326 GL_CALL(BindFragmentInputLocation(programID, i,
327 fVaryingHandler.fPathProcVaryingInfos[i].fVariable.c_str()));
328 fVaryingHandler.fPathProcVaryingInfos[i].fLocation = i;
joshualittd8dd47b2015-09-11 11:45:01 -0700329 }
joshualitt47bb3822014-10-07 16:43:25 -0700330}
331
332bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
333 GrGLint linked = GR_GL_INIT_ZERO;
334 GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
335 if (!linked) {
Brian Salomone334c592017-05-15 11:00:58 -0400336 SkDebugf("Program linking failed.\n");
joshualitt47bb3822014-10-07 16:43:25 -0700337 GrGLint infoLen = GR_GL_INIT_ZERO;
338 GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
339 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
340 if (infoLen > 0) {
341 // retrieve length even though we don't need it to workaround
342 // bug in chrome cmd buffer param validation.
343 GrGLsizei length = GR_GL_INIT_ZERO;
344 GL_CALL(GetProgramInfoLog(programID,
345 infoLen+1,
346 &length,
347 (char*)log.get()));
kkinnunen297aaf92015-02-19 06:32:12 -0800348 SkDebugf("%s", (char*)log.get());
joshualitt47bb3822014-10-07 16:43:25 -0700349 }
joshualitt47bb3822014-10-07 16:43:25 -0700350 GL_CALL(DeleteProgram(programID));
351 programID = 0;
352 }
353 return SkToBool(linked);
354}
355
kkinnunen7aedda52015-06-29 23:01:28 -0700356void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) {
egdaniel7ea439b2015-12-03 09:20:44 -0800357 fUniformHandler.getUniformLocations(programID, fGpu->glCaps());
joshualittd8dd47b2015-09-11 11:45:01 -0700358
359 // handle NVPR separable varyings
360 if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() ||
kkinnunen7bdb05d2016-01-25 00:47:23 -0800361 fGpu->glPathRendering()->shouldBindFragmentInputs()) {
joshualittd8dd47b2015-09-11 11:45:01 -0700362 return;
363 }
egdaniel0eafe792015-11-20 14:01:22 -0800364 int count = fVaryingHandler.fPathProcVaryingInfos.count();
joshualittd8dd47b2015-09-11 11:45:01 -0700365 for (int i = 0; i < count; ++i) {
366 GrGLint location;
egdaniel0eafe792015-11-20 14:01:22 -0800367 GL_CALL_RET(location, GetProgramResourceLocation(
368 programID,
369 GR_GL_FRAGMENT_INPUT,
370 fVaryingHandler.fPathProcVaryingInfos[i].fVariable.c_str()));
371 fVaryingHandler.fPathProcVaryingInfos[i].fLocation = location;
joshualittd8dd47b2015-09-11 11:45:01 -0700372 }
joshualitt30ba4362014-08-21 20:18:45 -0700373}
374
joshualitt47bb3822014-10-07 16:43:25 -0700375void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs) {
376 GL_CALL(DeleteProgram(programID));
egdanielfa896322016-01-13 12:19:30 -0800377 this->cleanupShaders(shaderIDs);
378 this->cleanupFragmentProcessors();
joshualitt47bb3822014-10-07 16:43:25 -0700379}
380void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
381 for (int i = 0; i < shaderIDs.count(); ++i) {
382 GL_CALL(DeleteShader(shaderIDs[i]));
383 }
384}
385
386GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
egdaniel7ea439b2015-12-03 09:20:44 -0800387 return new GrGLProgram(fGpu,
Ethan Nicholas38657112017-02-09 17:01:22 -0500388 *this->desc(),
egdaniel7ea439b2015-12-03 09:20:44 -0800389 fUniformHandles,
390 programID,
391 fUniformHandler.fUniforms,
egdaniel09aa1fc2016-04-20 07:09:46 -0700392 fUniformHandler.fSamplers,
Greg Danielbc5d4d72017-05-05 10:28:42 -0400393 fUniformHandler.fTexelBuffers,
egdaniel0eafe792015-11-20 14:01:22 -0800394 fVaryingHandler.fPathProcVaryingInfos,
Robert Phillips369e8b72017-08-01 16:13:04 -0400395 std::move(fGeometryProcessor),
396 std::move(fXferProcessor),
egdaniel09aa1fc2016-04-20 07:09:46 -0700397 fFragmentProcessors);
joshualitt47bb3822014-10-07 16:43:25 -0700398}