blob: 86dcfef7a44b6383dd0b795974f812ccc3921526 [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()) {
halcanary96fcdcc2015-08-27 07:41:13 -070058 return nullptr;
joshualitt6c891102015-05-13 08:51:49 -070059 }
egdanielc1e71012016-01-20 07:53:51 -080060 return builder.finalize();
joshualitt47bb3822014-10-07 16:43:25 -070061}
62
joshualitt47bb3822014-10-07 16:43:25 -070063/////////////////////////////////////////////////////////////////////////////
64
egdaniel0e1853c2016-03-17 11:35:45 -070065GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu,
66 const GrPipeline& pipeline,
67 const GrPrimitiveProcessor& primProc,
Ethan Nicholas38657112017-02-09 17:01:22 -050068 GrProgramDesc* desc)
egdaniel0e1853c2016-03-17 11:35:45 -070069 : INHERITED(pipeline, primProc, desc)
joshualitt30ba4362014-08-21 20:18:45 -070070 , fGpu(gpu)
egdaniel7ea439b2015-12-03 09:20:44 -080071 , fVaryingHandler(this)
72 , fUniformHandler(this) {
joshualitt30ba4362014-08-21 20:18:45 -070073}
74
egdanielfa896322016-01-13 12:19:30 -080075const GrCaps* GrGLProgramBuilder::caps() const {
76 return fGpu->caps();
77}
78
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040079bool GrGLProgramBuilder::compileAndAttachShaders(const char* glsl,
80 int length,
egdaniel574a4c12015-11-02 06:22:44 -080081 GrGLuint programId,
82 GrGLenum type,
Ethan Nicholas941e7e22016-12-12 15:33:30 -050083 SkTDArray<GrGLuint>* shaderIds,
84 const SkSL::Program::Settings& settings,
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040085 const SkSL::Program::Inputs& inputs) {
egdaniel574a4c12015-11-02 06:22:44 -080086 GrGLGpu* gpu = this->gpu();
87 GrGLuint shaderId = GrGLCompileAndAttachShader(gpu->glContext(),
88 programId,
89 type,
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040090 glsl,
91 length,
Ethan Nicholas941e7e22016-12-12 15:33:30 -050092 gpu->stats(),
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040093 settings);
egdaniel574a4c12015-11-02 06:22:44 -080094 if (!shaderId) {
95 return false;
96 }
97
98 *shaderIds->append() = shaderId;
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040099 if (inputs.fFlipY) {
Ethan Nicholas38657112017-02-09 17:01:22 -0500100 GrProgramDesc* d = this->desc();
Robert Phillips7f861922018-01-30 13:13:42 +0000101 d->setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(
102 this->pipeline().proxy()->origin()));
Ethan Nicholas38657112017-02-09 17:01:22 -0500103 d->finalize();
104 }
egdaniel574a4c12015-11-02 06:22:44 -0800105
106 return true;
107}
108
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400109bool GrGLProgramBuilder::compileAndAttachShaders(GrGLSLShaderBuilder& shader,
110 GrGLuint programId,
111 GrGLenum type,
112 SkTDArray<GrGLuint>* shaderIds,
113 const SkSL::Program::Settings& settings,
114 SkSL::Program::Inputs* outInputs) {
115 SkSL::String glsl;
116 std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(gpu()->glContext(), type,
117 shader.fCompilerStrings.begin(),
118 shader.fCompilerStringLengths.begin(),
119 shader.fCompilerStrings.count(),
120 settings,
121 &glsl);
122 *outInputs = program->fInputs;
123 return this->compileAndAttachShaders(glsl.c_str(),
124 glsl.size(),
125 programId,
126 type,
127 shaderIds,
128 settings,
129 *outInputs);
130}
131
joshualitt47bb3822014-10-07 16:43:25 -0700132GrGLProgram* GrGLProgramBuilder::finalize() {
Brian Osman39c08ac2017-07-26 09:36:09 -0400133 TRACE_EVENT0("skia", TRACE_FUNC);
Ryan Macnak38a10ad2017-07-10 10:36:34 -0700134
joshualitt47bb3822014-10-07 16:43:25 -0700135 // verify we can get a program id
136 GrGLuint programID;
137 GL_CALL_RET(programID, CreateProgram());
138 if (0 == programID) {
halcanary96fcdcc2015-08-27 07:41:13 -0700139 return nullptr;
joshualitt30ba4362014-08-21 20:18:45 -0700140 }
141
Ethan Nicholas06d55fb2017-11-08 09:48:50 -0500142 if (this->gpu()->glCaps().programBinarySupport() &&
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500143 this->gpu()->getContext()->contextPriv().getPersistentCache()) {
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400144 GL_CALL(ProgramParameteri(programID, GR_GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GR_GL_TRUE));
145 }
146
egdaniel9f1d4152016-02-10 09:50:38 -0800147 this->finalizeShaders();
148
joshualitt47bb3822014-10-07 16:43:25 -0700149 // compile shaders and bind attributes / uniforms
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400150 const GrPrimitiveProcessor& primProc = this->primitiveProcessor();
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500151 SkSL::Program::Settings settings;
152 settings.fCaps = this->gpu()->glCaps().shaderCaps();
Robert Phillips2890fbf2017-07-26 15:48:41 -0400153 settings.fFlipY = this->pipeline().proxy()->origin() != kTopLeft_GrSurfaceOrigin;
Brian Osman8a83ca42018-02-12 14:32:17 -0500154 settings.fSharpenTextures = this->gpu()->getContext()->contextPriv().sharpenMipmappedTextures();
Brian Salomondc092132018-04-04 10:14:16 -0400155 settings.fFragColorIsInOut = this->fragColorIsInOut();
156
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);
Brian Salomon7c934722018-06-01 14:42:53 -0400196 if (!fs) {
197 this->cleanupProgram(programID, shadersToDelete);
198 return nullptr;
199 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400200 inputs = fs->fInputs;
201 if (inputs.fRTHeight) {
202 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
203 }
204 if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
205 GR_GL_FRAGMENT_SHADER, &shadersToDelete, settings,
206 inputs)) {
207 this->cleanupProgram(programID, shadersToDelete);
208 return nullptr;
209 }
210
211 std::unique_ptr<SkSL::Program> vs = GrSkSLtoGLSL(gpu()->glContext(),
212 GR_GL_VERTEX_SHADER,
213 fVS.fCompilerStrings.begin(),
214 fVS.fCompilerStringLengths.begin(),
215 fVS.fCompilerStrings.count(),
216 settings,
217 &glsl);
Brian Salomon7c934722018-06-01 14:42:53 -0400218 if (!vs || !this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
219 GR_GL_VERTEX_SHADER, &shadersToDelete, settings,
220 inputs)) {
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400221 this->cleanupProgram(programID, shadersToDelete);
222 return nullptr;
223 }
224
225 // NVPR actually requires a vertex shader to compile
226 bool useNvpr = primProc.isPathRendering();
227 if (!useNvpr) {
228 int vaCount = primProc.numAttribs();
229 for (int i = 0; i < vaCount; i++) {
Brian Salomon70132d02018-05-29 15:33:06 -0400230 GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).name()));
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400231 }
232 }
233
234 if (primProc.willUseGeoShader()) {
235 std::unique_ptr<SkSL::Program> gs;
236 gs = GrSkSLtoGLSL(gpu()->glContext(),
237 GR_GL_GEOMETRY_SHADER,
238 fGS.fCompilerStrings.begin(),
239 fGS.fCompilerStringLengths.begin(),
240 fGS.fCompilerStrings.count(),
241 settings,
242 &glsl);
Brian Salomon7c934722018-06-01 14:42:53 -0400243 if (!gs || !this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
244 GR_GL_GEOMETRY_SHADER, &shadersToDelete,
245 settings, inputs)) {
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400246 this->cleanupProgram(programID, shadersToDelete);
247 return nullptr;
248 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400249 }
250 this->bindProgramResourceLocations(programID);
251
252 GL_CALL(LinkProgram(programID));
joshualitt47bb3822014-10-07 16:43:25 -0700253 }
joshualitt30ba4362014-08-21 20:18:45 -0700254 // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
cdalton1acea862015-06-02 13:05:52 -0700255 bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver();
joshualitt30ba4362014-08-21 20:18:45 -0700256#ifdef SK_DEBUG
257 checkLinked = true;
258#endif
259 if (checkLinked) {
Brian Salomone334c592017-05-15 11:00:58 -0400260 if (!this->checkLinkStatus(programID)) {
261 SkDebugf("VS:\n");
262 GrGLPrintShader(fGpu->glContext(), GR_GL_VERTEX_SHADER, fVS.fCompilerStrings.begin(),
263 fVS.fCompilerStringLengths.begin(), fVS.fCompilerStrings.count(),
264 settings);
265 if (primProc.willUseGeoShader()) {
266 SkDebugf("\nGS:\n");
267 GrGLPrintShader(fGpu->glContext(), GR_GL_GEOMETRY_SHADER,
268 fGS.fCompilerStrings.begin(), fGS.fCompilerStringLengths.begin(),
269 fGS.fCompilerStrings.count(), settings);
270 }
271 SkDebugf("\nFS:\n");
272 GrGLPrintShader(fGpu->glContext(), GR_GL_FRAGMENT_SHADER, fFS.fCompilerStrings.begin(),
273 fFS.fCompilerStringLengths.begin(), fFS.fCompilerStrings.count(),
274 settings);
275 SkDEBUGFAIL("");
276 return nullptr;
277 }
joshualittfe1233c2014-10-07 12:16:35 -0700278 }
kkinnunen7aedda52015-06-29 23:01:28 -0700279 this->resolveProgramResourceLocations(programID);
joshualittdb0d3ca2014-10-07 12:42:26 -0700280
joshualitt47bb3822014-10-07 16:43:25 -0700281 this->cleanupShaders(shadersToDelete);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500282 if (!cached && this->gpu()->getContext()->contextPriv().getPersistentCache() &&
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400283 fGpu->glCaps().programBinarySupport()) {
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400284 GrGLsizei length = 0;
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400285 GL_CALL(GetProgramiv(programID, GL_PROGRAM_BINARY_LENGTH, &length));
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500286 if (length > 0) {
287 // store shader in cache
288 sk_sp<SkData> key = SkData::MakeWithoutCopy(desc()->asKey(), desc()->keyLength());
289 GrGLenum binaryFormat;
Mike Klein1d746202018-01-25 17:32:51 -0500290 std::unique_ptr<char[]> binary(new char[length]);
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500291 GL_CALL(GetProgramBinary(programID, length, &length, &binaryFormat, binary.get()));
292 size_t dataLength = sizeof(inputs) + sizeof(binaryFormat) + length;
Mike Klein1d746202018-01-25 17:32:51 -0500293 std::unique_ptr<uint8_t[]> data(new uint8_t[dataLength]);
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500294 size_t offset = 0;
295 memcpy(data.get() + offset, &inputs, sizeof(inputs));
296 offset += sizeof(inputs);
297 memcpy(data.get() + offset, &binaryFormat, sizeof(binaryFormat));
298 offset += sizeof(binaryFormat);
299 memcpy(data.get() + offset, binary.get(), length);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500300 this->gpu()->getContext()->contextPriv().getPersistentCache()->store(
301 *key, *SkData::MakeWithoutCopy(data.get(), dataLength));
Ethan Nicholas12b69ee2017-11-20 12:12:44 -0500302 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400303 }
joshualitt47bb3822014-10-07 16:43:25 -0700304 return this->createProgram(programID);
305}
306
kkinnunen7aedda52015-06-29 23:01:28 -0700307void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) {
egdaniel7ea439b2015-12-03 09:20:44 -0800308 fUniformHandler.bindUniformLocations(programID, fGpu->glCaps());
kkinnunen7aedda52015-06-29 23:01:28 -0700309
egdaniel8dcdedc2015-11-11 06:27:20 -0800310 const GrGLCaps& caps = this->gpu()->glCaps();
311 if (fFS.hasCustomColorOutput() && caps.bindFragDataLocationSupport()) {
312 GL_CALL(BindFragDataLocation(programID, 0,
egdaniel2d721d32015-11-11 13:06:05 -0800313 GrGLSLFragmentShaderBuilder::DeclaredColorOutputName()));
egdaniel8dcdedc2015-11-11 06:27:20 -0800314 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500315 if (fFS.hasSecondaryOutput() && caps.shaderCaps()->mustDeclareFragmentShaderOutput()) {
egdaniel8dcdedc2015-11-11 06:27:20 -0800316 GL_CALL(BindFragDataLocationIndexed(programID, 0, 1,
egdaniel2d721d32015-11-11 13:06:05 -0800317 GrGLSLFragmentShaderBuilder::DeclaredSecondaryColorOutputName()));
egdaniel8dcdedc2015-11-11 06:27:20 -0800318 }
joshualittd8dd47b2015-09-11 11:45:01 -0700319
320 // handle NVPR separable varyings
321 if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() ||
322 !fGpu->glPathRendering()->shouldBindFragmentInputs()) {
323 return;
324 }
egdaniel0eafe792015-11-20 14:01:22 -0800325 int count = fVaryingHandler.fPathProcVaryingInfos.count();
joshualittd8dd47b2015-09-11 11:45:01 -0700326 for (int i = 0; i < count; ++i) {
egdaniel0eafe792015-11-20 14:01:22 -0800327 GL_CALL(BindFragmentInputLocation(programID, i,
328 fVaryingHandler.fPathProcVaryingInfos[i].fVariable.c_str()));
329 fVaryingHandler.fPathProcVaryingInfos[i].fLocation = i;
joshualittd8dd47b2015-09-11 11:45:01 -0700330 }
joshualitt47bb3822014-10-07 16:43:25 -0700331}
332
333bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
334 GrGLint linked = GR_GL_INIT_ZERO;
335 GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
336 if (!linked) {
Brian Salomone334c592017-05-15 11:00:58 -0400337 SkDebugf("Program linking failed.\n");
joshualitt47bb3822014-10-07 16:43:25 -0700338 GrGLint infoLen = GR_GL_INIT_ZERO;
339 GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
340 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
341 if (infoLen > 0) {
342 // retrieve length even though we don't need it to workaround
343 // bug in chrome cmd buffer param validation.
344 GrGLsizei length = GR_GL_INIT_ZERO;
345 GL_CALL(GetProgramInfoLog(programID,
346 infoLen+1,
347 &length,
348 (char*)log.get()));
kkinnunen297aaf92015-02-19 06:32:12 -0800349 SkDebugf("%s", (char*)log.get());
joshualitt47bb3822014-10-07 16:43:25 -0700350 }
joshualitt47bb3822014-10-07 16:43:25 -0700351 GL_CALL(DeleteProgram(programID));
352 programID = 0;
353 }
354 return SkToBool(linked);
355}
356
kkinnunen7aedda52015-06-29 23:01:28 -0700357void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) {
egdaniel7ea439b2015-12-03 09:20:44 -0800358 fUniformHandler.getUniformLocations(programID, fGpu->glCaps());
joshualittd8dd47b2015-09-11 11:45:01 -0700359
360 // handle NVPR separable varyings
361 if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() ||
kkinnunen7bdb05d2016-01-25 00:47:23 -0800362 fGpu->glPathRendering()->shouldBindFragmentInputs()) {
joshualittd8dd47b2015-09-11 11:45:01 -0700363 return;
364 }
egdaniel0eafe792015-11-20 14:01:22 -0800365 int count = fVaryingHandler.fPathProcVaryingInfos.count();
joshualittd8dd47b2015-09-11 11:45:01 -0700366 for (int i = 0; i < count; ++i) {
367 GrGLint location;
egdaniel0eafe792015-11-20 14:01:22 -0800368 GL_CALL_RET(location, GetProgramResourceLocation(
369 programID,
370 GR_GL_FRAGMENT_INPUT,
371 fVaryingHandler.fPathProcVaryingInfos[i].fVariable.c_str()));
372 fVaryingHandler.fPathProcVaryingInfos[i].fLocation = location;
joshualittd8dd47b2015-09-11 11:45:01 -0700373 }
joshualitt30ba4362014-08-21 20:18:45 -0700374}
375
joshualitt47bb3822014-10-07 16:43:25 -0700376void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs) {
377 GL_CALL(DeleteProgram(programID));
egdanielfa896322016-01-13 12:19:30 -0800378 this->cleanupShaders(shaderIDs);
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,
egdaniel7ea439b2015-12-03 09:20:44 -0800388 fUniformHandles,
389 programID,
390 fUniformHandler.fUniforms,
egdaniel09aa1fc2016-04-20 07:09:46 -0700391 fUniformHandler.fSamplers,
Greg Danielbc5d4d72017-05-05 10:28:42 -0400392 fUniformHandler.fTexelBuffers,
egdaniel0eafe792015-11-20 14:01:22 -0800393 fVaryingHandler.fPathProcVaryingInfos,
Robert Phillips369e8b72017-08-01 16:13:04 -0400394 std::move(fGeometryProcessor),
395 std::move(fXferProcessor),
Brian Salomon4d3f5172018-06-07 14:42:52 -0400396 std::move(fFragmentProcessors),
397 fFragmentProcessorCnt);
joshualitt47bb3822014-10-07 16:43:25 -0700398}