blob: 8fb3589df78c7a196789733c50ca3fb8b31a9370 [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();
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500157 SkSL::Program::Inputs inputs;
joshualitt30ba4362014-08-21 20:18:45 -0700158 SkTDArray<GrGLuint> shadersToDelete;
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400159 bool cached = fGpu->glCaps().programBinarySupport() && nullptr != fCached.get();
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400160 if (cached) {
Ethan Nicholas907204f2017-11-14 14:35:57 -0500161 this->bindProgramResourceLocations(programID);
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400162 // cache hit, just hand the binary to GL
163 const uint8_t* bytes = fCached->bytes();
164 size_t offset = 0;
165 memcpy(&inputs, bytes + offset, sizeof(inputs));
166 offset += sizeof(inputs);
167 int binaryFormat;
168 memcpy(&binaryFormat, bytes + offset, sizeof(binaryFormat));
169 offset += sizeof(binaryFormat);
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400170 GrGLClearErr(this->gpu()->glInterface());
171 GR_GL_CALL_NOERRCHECK(this->gpu()->glInterface(),
172 ProgramBinary(programID, binaryFormat, (void*) (bytes + offset),
173 fCached->size() - offset));
174 if (GR_GL_GET_ERROR(this->gpu()->glInterface()) == GR_GL_NO_ERROR) {
175 if (inputs.fRTHeight) {
176 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
177 }
178 cached = this->checkLinkStatus(programID);
179 } else {
180 cached = false;
181 }
182 }
183 if (!cached) {
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400184 // cache miss, compile shaders
185 if (fFS.fForceHighPrecision) {
186 settings.fForceHighPrecision = true;
egdaniel8dcdedc2015-11-11 06:27:20 -0800187 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400188 SkSL::String glsl;
189 std::unique_ptr<SkSL::Program> fs = GrSkSLtoGLSL(gpu()->glContext(),
190 GR_GL_FRAGMENT_SHADER,
191 fFS.fCompilerStrings.begin(),
192 fFS.fCompilerStringLengths.begin(),
193 fFS.fCompilerStrings.count(),
194 settings,
195 &glsl);
196 inputs = fs->fInputs;
197 if (inputs.fRTHeight) {
198 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
199 }
200 if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
201 GR_GL_FRAGMENT_SHADER, &shadersToDelete, settings,
202 inputs)) {
203 this->cleanupProgram(programID, shadersToDelete);
204 return nullptr;
205 }
206
207 std::unique_ptr<SkSL::Program> vs = GrSkSLtoGLSL(gpu()->glContext(),
208 GR_GL_VERTEX_SHADER,
209 fVS.fCompilerStrings.begin(),
210 fVS.fCompilerStringLengths.begin(),
211 fVS.fCompilerStrings.count(),
212 settings,
213 &glsl);
214 if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
215 GR_GL_VERTEX_SHADER, &shadersToDelete, settings,
216 inputs)) {
217 this->cleanupProgram(programID, shadersToDelete);
218 return nullptr;
219 }
220
221 // NVPR actually requires a vertex shader to compile
222 bool useNvpr = primProc.isPathRendering();
223 if (!useNvpr) {
224 int vaCount = primProc.numAttribs();
225 for (int i = 0; i < vaCount; i++) {
226 GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName));
227 }
228 }
229
230 if (primProc.willUseGeoShader()) {
231 std::unique_ptr<SkSL::Program> gs;
232 gs = GrSkSLtoGLSL(gpu()->glContext(),
233 GR_GL_GEOMETRY_SHADER,
234 fGS.fCompilerStrings.begin(),
235 fGS.fCompilerStringLengths.begin(),
236 fGS.fCompilerStrings.count(),
237 settings,
238 &glsl);
239 if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
240 GR_GL_GEOMETRY_SHADER, &shadersToDelete, settings,
241 inputs)) {
242 this->cleanupProgram(programID, shadersToDelete);
243 return nullptr;
244 }
245
246 }
247 this->bindProgramResourceLocations(programID);
248
249 GL_CALL(LinkProgram(programID));
joshualitt47bb3822014-10-07 16:43:25 -0700250 }
joshualitt30ba4362014-08-21 20:18:45 -0700251 // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
cdalton1acea862015-06-02 13:05:52 -0700252 bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver();
joshualitt30ba4362014-08-21 20:18:45 -0700253#ifdef SK_DEBUG
254 checkLinked = true;
255#endif
256 if (checkLinked) {
Brian Salomone334c592017-05-15 11:00:58 -0400257 if (!this->checkLinkStatus(programID)) {
258 SkDebugf("VS:\n");
259 GrGLPrintShader(fGpu->glContext(), GR_GL_VERTEX_SHADER, fVS.fCompilerStrings.begin(),
260 fVS.fCompilerStringLengths.begin(), fVS.fCompilerStrings.count(),
261 settings);
262 if (primProc.willUseGeoShader()) {
263 SkDebugf("\nGS:\n");
264 GrGLPrintShader(fGpu->glContext(), GR_GL_GEOMETRY_SHADER,
265 fGS.fCompilerStrings.begin(), fGS.fCompilerStringLengths.begin(),
266 fGS.fCompilerStrings.count(), settings);
267 }
268 SkDebugf("\nFS:\n");
269 GrGLPrintShader(fGpu->glContext(), GR_GL_FRAGMENT_SHADER, fFS.fCompilerStrings.begin(),
270 fFS.fCompilerStringLengths.begin(), fFS.fCompilerStrings.count(),
271 settings);
272 SkDEBUGFAIL("");
273 return nullptr;
274 }
joshualittfe1233c2014-10-07 12:16:35 -0700275 }
kkinnunen7aedda52015-06-29 23:01:28 -0700276 this->resolveProgramResourceLocations(programID);
joshualittdb0d3ca2014-10-07 12:42:26 -0700277
joshualitt47bb3822014-10-07 16:43:25 -0700278 this->cleanupShaders(shadersToDelete);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500279 if (!cached && this->gpu()->getContext()->contextPriv().getPersistentCache() &&
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400280 fGpu->glCaps().programBinarySupport()) {
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400281 GrGLsizei length = 0;
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400282 GL_CALL(GetProgramiv(programID, GL_PROGRAM_BINARY_LENGTH, &length));
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500283 if (length > 0) {
284 // store shader in cache
285 sk_sp<SkData> key = SkData::MakeWithoutCopy(desc()->asKey(), desc()->keyLength());
286 GrGLenum binaryFormat;
Mike Klein1d746202018-01-25 17:32:51 -0500287 std::unique_ptr<char[]> binary(new char[length]);
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500288 GL_CALL(GetProgramBinary(programID, length, &length, &binaryFormat, binary.get()));
289 size_t dataLength = sizeof(inputs) + sizeof(binaryFormat) + length;
Mike Klein1d746202018-01-25 17:32:51 -0500290 std::unique_ptr<uint8_t[]> data(new uint8_t[dataLength]);
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500291 size_t offset = 0;
292 memcpy(data.get() + offset, &inputs, sizeof(inputs));
293 offset += sizeof(inputs);
294 memcpy(data.get() + offset, &binaryFormat, sizeof(binaryFormat));
295 offset += sizeof(binaryFormat);
296 memcpy(data.get() + offset, binary.get(), length);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500297 this->gpu()->getContext()->contextPriv().getPersistentCache()->store(
298 *key, *SkData::MakeWithoutCopy(data.get(), dataLength));
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500299 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400300 }
joshualitt47bb3822014-10-07 16:43:25 -0700301 return this->createProgram(programID);
302}
303
kkinnunen7aedda52015-06-29 23:01:28 -0700304void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) {
egdaniel7ea439b2015-12-03 09:20:44 -0800305 fUniformHandler.bindUniformLocations(programID, fGpu->glCaps());
kkinnunen7aedda52015-06-29 23:01:28 -0700306
egdaniel8dcdedc2015-11-11 06:27:20 -0800307 const GrGLCaps& caps = this->gpu()->glCaps();
308 if (fFS.hasCustomColorOutput() && caps.bindFragDataLocationSupport()) {
309 GL_CALL(BindFragDataLocation(programID, 0,
egdaniel2d721d32015-11-11 13:06:05 -0800310 GrGLSLFragmentShaderBuilder::DeclaredColorOutputName()));
egdaniel8dcdedc2015-11-11 06:27:20 -0800311 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500312 if (fFS.hasSecondaryOutput() && caps.shaderCaps()->mustDeclareFragmentShaderOutput()) {
egdaniel8dcdedc2015-11-11 06:27:20 -0800313 GL_CALL(BindFragDataLocationIndexed(programID, 0, 1,
egdaniel2d721d32015-11-11 13:06:05 -0800314 GrGLSLFragmentShaderBuilder::DeclaredSecondaryColorOutputName()));
egdaniel8dcdedc2015-11-11 06:27:20 -0800315 }
joshualittd8dd47b2015-09-11 11:45:01 -0700316
317 // handle NVPR separable varyings
318 if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() ||
319 !fGpu->glPathRendering()->shouldBindFragmentInputs()) {
320 return;
321 }
egdaniel0eafe792015-11-20 14:01:22 -0800322 int count = fVaryingHandler.fPathProcVaryingInfos.count();
joshualittd8dd47b2015-09-11 11:45:01 -0700323 for (int i = 0; i < count; ++i) {
egdaniel0eafe792015-11-20 14:01:22 -0800324 GL_CALL(BindFragmentInputLocation(programID, i,
325 fVaryingHandler.fPathProcVaryingInfos[i].fVariable.c_str()));
326 fVaryingHandler.fPathProcVaryingInfos[i].fLocation = i;
joshualittd8dd47b2015-09-11 11:45:01 -0700327 }
joshualitt47bb3822014-10-07 16:43:25 -0700328}
329
330bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
331 GrGLint linked = GR_GL_INIT_ZERO;
332 GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
333 if (!linked) {
Brian Salomone334c592017-05-15 11:00:58 -0400334 SkDebugf("Program linking failed.\n");
joshualitt47bb3822014-10-07 16:43:25 -0700335 GrGLint infoLen = GR_GL_INIT_ZERO;
336 GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
337 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
338 if (infoLen > 0) {
339 // retrieve length even though we don't need it to workaround
340 // bug in chrome cmd buffer param validation.
341 GrGLsizei length = GR_GL_INIT_ZERO;
342 GL_CALL(GetProgramInfoLog(programID,
343 infoLen+1,
344 &length,
345 (char*)log.get()));
kkinnunen297aaf92015-02-19 06:32:12 -0800346 SkDebugf("%s", (char*)log.get());
joshualitt47bb3822014-10-07 16:43:25 -0700347 }
joshualitt47bb3822014-10-07 16:43:25 -0700348 GL_CALL(DeleteProgram(programID));
349 programID = 0;
350 }
351 return SkToBool(linked);
352}
353
kkinnunen7aedda52015-06-29 23:01:28 -0700354void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) {
egdaniel7ea439b2015-12-03 09:20:44 -0800355 fUniformHandler.getUniformLocations(programID, fGpu->glCaps());
joshualittd8dd47b2015-09-11 11:45:01 -0700356
357 // handle NVPR separable varyings
358 if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() ||
kkinnunen7bdb05d2016-01-25 00:47:23 -0800359 fGpu->glPathRendering()->shouldBindFragmentInputs()) {
joshualittd8dd47b2015-09-11 11:45:01 -0700360 return;
361 }
egdaniel0eafe792015-11-20 14:01:22 -0800362 int count = fVaryingHandler.fPathProcVaryingInfos.count();
joshualittd8dd47b2015-09-11 11:45:01 -0700363 for (int i = 0; i < count; ++i) {
364 GrGLint location;
egdaniel0eafe792015-11-20 14:01:22 -0800365 GL_CALL_RET(location, GetProgramResourceLocation(
366 programID,
367 GR_GL_FRAGMENT_INPUT,
368 fVaryingHandler.fPathProcVaryingInfos[i].fVariable.c_str()));
369 fVaryingHandler.fPathProcVaryingInfos[i].fLocation = location;
joshualittd8dd47b2015-09-11 11:45:01 -0700370 }
joshualitt30ba4362014-08-21 20:18:45 -0700371}
372
joshualitt47bb3822014-10-07 16:43:25 -0700373void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs) {
374 GL_CALL(DeleteProgram(programID));
egdanielfa896322016-01-13 12:19:30 -0800375 this->cleanupShaders(shaderIDs);
376 this->cleanupFragmentProcessors();
joshualitt47bb3822014-10-07 16:43:25 -0700377}
378void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
379 for (int i = 0; i < shaderIDs.count(); ++i) {
380 GL_CALL(DeleteShader(shaderIDs[i]));
381 }
382}
383
384GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
egdaniel7ea439b2015-12-03 09:20:44 -0800385 return new GrGLProgram(fGpu,
Ethan Nicholas38657112017-02-09 17:01:22 -0500386 *this->desc(),
egdaniel7ea439b2015-12-03 09:20:44 -0800387 fUniformHandles,
388 programID,
389 fUniformHandler.fUniforms,
egdaniel09aa1fc2016-04-20 07:09:46 -0700390 fUniformHandler.fSamplers,
Greg Danielbc5d4d72017-05-05 10:28:42 -0400391 fUniformHandler.fTexelBuffers,
egdaniel0eafe792015-11-20 14:01:22 -0800392 fVaryingHandler.fPathProcVaryingInfos,
Robert Phillips369e8b72017-08-01 16:13:04 -0400393 std::move(fGeometryProcessor),
394 std::move(fXferProcessor),
egdaniel09aa1fc2016-04-20 07:09:46 -0700395 fFragmentProcessors);
joshualitt47bb3822014-10-07 16:43:25 -0700396}