Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GrGLProgramBuilder.cpp
Go to the documentation of this file.
1/*
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
9
16#include "src/gpu/Swizzle.h"
31
32#include <memory>
35
36#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
37#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
38
39static void cleanup_shaders(GrGLGpu* gpu, const SkTDArray<GrGLuint>& shaderIDs) {
40 for (int i = 0; i < shaderIDs.size(); ++i) {
41 GR_GL_CALL(gpu->glInterface(), DeleteShader(shaderIDs[i]));
42 }
43}
44
45static void cleanup_program(GrGLGpu* gpu, GrGLuint programID,
46 const SkTDArray<GrGLuint>& shaderIDs) {
47 GR_GL_CALL(gpu->glInterface(), DeleteProgram(programID));
48 cleanup_shaders(gpu, shaderIDs);
49}
50
52 GrDirectContext* dContext,
53 const GrProgramDesc& desc,
54 const GrProgramInfo& programInfo,
55 const GrGLPrecompiledProgram* precompiledProgram) {
56 TRACE_EVENT0_ALWAYS("skia.shaders", "shader_compile");
57 GrAutoLocaleSetter als("C");
58
59 GrGLGpu* glGpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
60
61 // create a builder. This will be handed off to effects so they can use it to add
62 // uniforms, varyings, textures, etc
63 GrGLProgramBuilder builder(glGpu, desc, programInfo);
64
65 auto persistentCache = dContext->priv().getPersistentCache();
66 if (persistentCache && !precompiledProgram) {
68 builder.fCached = persistentCache->load(*key);
69 // the eventual end goal is to completely skip emitAndInstallProcs on a cache hit, but it's
70 // doing necessary setup in addition to generating the SkSL code. Currently we are only able
71 // to skip the SkSL->GLSL step on a cache hit.
72 }
73 if (!builder.emitAndInstallProcs()) {
74 return nullptr;
75 }
76 return builder.finalize(precompiledProgram);
77}
78
79/////////////////////////////////////////////////////////////////////////////
80
81GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu,
82 const GrProgramDesc& desc,
83 const GrProgramInfo& programInfo)
84 : INHERITED(desc, programInfo)
85 , fGpu(gpu)
86 , fVaryingHandler(this)
87 , fUniformHandler(this)
88 , fVertexAttributeCnt(0)
89 , fInstanceAttributeCnt(0)
90 , fVertexStride(0)
91 , fInstanceStride(0) {}
92
94 return fGpu->caps();
95}
96
97bool GrGLProgramBuilder::compileAndAttachShaders(const std::string& glsl,
98 GrGLuint programId,
100 SkTDArray<GrGLuint>* shaderIds,
101 bool shaderWasCached,
103 GrGLGpu* gpu = this->gpu();
105 programId,
106 type,
107 glsl,
108 shaderWasCached,
110 errHandler);
111 if (!shaderId) {
112 return false;
113 }
114
115 *shaderIds->append() = shaderId;
116 return true;
117}
118
119void GrGLProgramBuilder::computeCountsAndStrides(GrGLuint programID,
120 const GrGeometryProcessor& geomProc,
121 bool bindAttribLocations) {
122 fVertexAttributeCnt = geomProc.numVertexAttributes();
123 fInstanceAttributeCnt = geomProc.numInstanceAttributes();
124 fAttributes = std::make_unique<GrGLProgram::Attribute[]>(
125 fVertexAttributeCnt + fInstanceAttributeCnt);
126 auto addAttr = [&](int i, const auto& a) {
127 fAttributes[i].fCPUType = a.cpuType();
128 fAttributes[i].fGPUType = a.gpuType();
129 fAttributes[i].fOffset = *a.offset();
130 fAttributes[i].fLocation = i;
131 if (bindAttribLocations) {
132 GL_CALL(BindAttribLocation(programID, i, a.name()));
133 }
134 };
135 fVertexStride = geomProc.vertexStride();
136 int i = 0;
137 for (auto attr : geomProc.vertexAttributes()) {
138 addAttr(i++, attr);
139 }
140 fInstanceStride = geomProc.instanceStride();
141 for (auto attr : geomProc.instanceAttributes()) {
142 addAttr(i++, attr);
143 }
144 SkASSERT(fInstanceStride == geomProc.instanceStride());
145}
146
147void GrGLProgramBuilder::addInputVars(const SkSL::Program::Interface& interface) {
148 uint8_t useRTFlip = interface.fRTFlipUniform;
149 if (!this->gpu()->glCaps().shaderCaps()->fCanUseFragCoord) {
150 useRTFlip &= ~SkSL::Program::Interface::kRTFlip_FragCoord;
151 }
152
155 }
156}
157
158static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
159static constexpr SkFourByteTag kGLSL_Tag = SkSetFourByteTag('G', 'L', 'S', 'L');
160static constexpr SkFourByteTag kGLPB_Tag = SkSetFourByteTag('G', 'L', 'P', 'B');
161
162void GrGLProgramBuilder::storeShaderInCache(const SkSL::Program::Interface& interface,
163 GrGLuint programID,
164 const std::string shaders[],
165 bool isSkSL,
166 SkSL::ProgramSettings* settings) {
167 if (!this->gpu()->getContext()->priv().getPersistentCache()) {
168 return;
169 }
170 sk_sp<SkData> key = SkData::MakeWithoutCopy(this->desc().asKey(), this->desc().keyLength());
171 SkString description = GrProgramDesc::Describe(fProgramInfo, *fGpu->caps());
172 if (fGpu->glCaps().programBinarySupport()) {
173 // binary cache
174 GrGLsizei length = 0;
175 GL_CALL(GetProgramiv(programID, GL_PROGRAM_BINARY_LENGTH, &length));
176 if (length > 0) {
177 SkBinaryWriteBuffer writer({});
179 writer.writeUInt(kGLPB_Tag);
180
181 writer.writePad32(&interface, sizeof(interface));
182
184 GrGLenum binaryFormat;
185 GL_CALL(GetProgramBinary(programID, length, &length, &binaryFormat, binary.get()));
186
187 writer.writeUInt(binaryFormat);
188 writer.writeInt(length);
189 writer.writePad32(binary.get(), length);
190
191 auto data = writer.snapshotAsData();
192 this->gpu()->getContext()->priv().getPersistentCache()->store(*key, *data, description);
193 }
194 } else {
195 // source cache, plus metadata to allow for a complete precompile
197 meta.fSettings = settings;
199 for (auto attr : this->geometryProcessor().vertexAttributes()) {
200 meta.fAttributeNames.emplace_back(attr.name());
201 }
202 for (auto attr : this->geometryProcessor().instanceAttributes()) {
203 meta.fAttributeNames.emplace_back(attr.name());
204 }
205
207 shaders, &interface, 1, &meta);
208 this->gpu()->getContext()->priv().getPersistentCache()->store(*key, *data, description);
209 }
210}
211
212sk_sp<GrGLProgram> GrGLProgramBuilder::finalize(const GrGLPrecompiledProgram* precompiledProgram) {
213 TRACE_EVENT0("skia.shaders", TRACE_FUNC);
214
215 // verify we can get a program id
216 GrGLuint programID;
217 if (precompiledProgram) {
218 programID = precompiledProgram->fProgramID;
219 } else {
220 GL_CALL_RET(programID, CreateProgram());
221 }
222 if (0 == programID) {
223 return nullptr;
224 }
225
226 if (this->gpu()->glCaps().programBinarySupport() &&
227 this->gpu()->glCaps().programParameterSupport() &&
228 this->gpu()->getContext()->priv().getPersistentCache() &&
229 !precompiledProgram) {
230 GL_CALL(ProgramParameteri(programID, GR_GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GR_GL_TRUE));
231 }
232
233 this->finalizeShaders();
234
235 // compile shaders and bind attributes / uniforms
236 auto errorHandler = this->gpu()->getContext()->priv().getShaderErrorHandler();
237 const GrGeometryProcessor& geomProc = this->geometryProcessor();
239 settings.fSharpenTextures = true;
240 settings.fFragColorIsInOut = this->fragColorIsInOut();
241
242 SkSL::Program::Interface interface;
243 SkTDArray<GrGLuint> shadersToDelete;
244
245 bool cached = fCached.get() != nullptr;
246 bool usedProgramBinaries = false;
247 std::string glsl[kGrShaderTypeCount];
248 const std::string* sksl[kGrShaderTypeCount] = {
251 };
252 std::string cached_sksl[kGrShaderTypeCount];
253 if (precompiledProgram) {
254 // This is very similar to when we get program binaries. We even set that flag, as it's
255 // used to prevent other compile work later, and to force re-querying uniform locations.
256 this->addInputVars(precompiledProgram->fInterface);
257 this->computeCountsAndStrides(programID, geomProc, false);
258 usedProgramBinaries = true;
259 } else if (cached) {
260 TRACE_EVENT0_ALWAYS("skia.shaders", "cache_hit");
261 SkReadBuffer reader(fCached->data(), fCached->size());
263
264 switch (shaderType) {
265 case kGLPB_Tag: {
266 // Program binary cache hit. We may opt not to use this if we don't trust program
267 // binaries on this driver
268 if (!fGpu->glCaps().programBinarySupport()) {
269 cached = false;
270 break;
271 }
272 reader.readPad32(&interface, sizeof(interface));
273 GrGLenum binaryFormat = reader.readUInt();
274 GrGLsizei length = reader.readInt();
275 const void* binary = reader.skip(length);
276 if (!reader.isValid()) {
277 break;
278 }
279 if (length <= 0 || !fGpu->glCaps().programBinaryFormatIsValid(binaryFormat)) {
280 cached = false;
281 break;
282 }
283 GL_CALL(ProgramBinary(programID, binaryFormat, const_cast<void*>(binary), length));
284 // Pass nullptr for the error handler. We don't want to treat this as a compile
285 // failure (we can still recover by compiling the program from source, below).
286 // Clients won't be directly notified, but they can infer this from the trace
287 // events, and from the traffic to the persistent cache.
288 cached = GrGLCheckLinkStatus(fGpu, programID, /*shaderWasCached=*/true,
289 /*errorHandler=*/nullptr, nullptr, nullptr);
290 if (cached) {
291 this->addInputVars(interface);
292 this->computeCountsAndStrides(programID, geomProc, false);
293 }
294 usedProgramBinaries = cached;
295 break;
296 }
297
298 case kGLSL_Tag:
299 // Source cache hit, we don't need to compile the SkSL->GLSL
300 GrPersistentCacheUtils::UnpackCachedShaders(&reader, glsl, &interface, 1);
301 break;
302
303 case kSKSL_Tag:
304 // SkSL cache hit, this should only happen in tools overriding the generated SkSL
306 &reader, cached_sksl, &interface, 1)) {
307 for (int i = 0; i < kGrShaderTypeCount; ++i) {
308 sksl[i] = &cached_sksl[i];
309 }
310 }
311 break;
312
313 default:
314 // We got something invalid, so pretend it wasn't there
315 reader.validate(false);
316 break;
317 }
318 if (!reader.isValid()) {
319 cached = false;
320 }
321 }
322 if (!usedProgramBinaries) {
323 TRACE_EVENT0_ALWAYS("skia.shaders", "cache_miss");
324 // Either a cache miss, or we got something other than binaries from the cache
325
326 /*
327 Fragment Shader
328 */
329 if (glsl[kFragment_GrShaderType].empty()) {
330 // Don't have cached GLSL, need to compile SkSL->GLSL
331 if (fFS.fForceHighPrecision) {
332 settings.fForceHighPrecision = true;
333 }
334 if (!skgpu::SkSLToGLSL(this->gpu()->caps()->shaderCaps(),
337 settings,
339 &interface,
340 errorHandler)) {
341 cleanup_program(fGpu, programID, shadersToDelete);
342 return nullptr;
343 }
344 }
345
346 this->addInputVars(interface);
347 if (!this->compileAndAttachShaders(glsl[kFragment_GrShaderType],
348 programID,
350 &shadersToDelete,
351 cached,
352 errorHandler)) {
353 cleanup_program(fGpu, programID, shadersToDelete);
354 return nullptr;
355 }
356
357 /*
358 Vertex Shader
359 */
360 if (glsl[kVertex_GrShaderType].empty()) {
361 // Don't have cached GLSL, need to compile SkSL->GLSL
362 SkSL::Program::Interface unusedInterface;
363 if (!skgpu::SkSLToGLSL(this->gpu()->caps()->shaderCaps(),
366 settings,
368 &unusedInterface,
369 errorHandler)) {
370 cleanup_program(fGpu, programID, shadersToDelete);
371 return nullptr;
372 }
373 }
374 if (!this->compileAndAttachShaders(glsl[kVertex_GrShaderType],
375 programID,
377 &shadersToDelete,
378 cached,
379 errorHandler)) {
380 cleanup_program(fGpu, programID, shadersToDelete);
381 return nullptr;
382 }
383
384 // This also binds vertex attribute locations.
385 this->computeCountsAndStrides(programID, geomProc, true);
386
387 this->bindProgramResourceLocations(programID);
388
389 {
390 TRACE_EVENT0_ALWAYS("skia.shaders", "driver_link_program");
391 GL_CALL(LinkProgram(programID));
392 if (!GrGLCheckLinkStatus(fGpu, programID, cached, errorHandler, sksl, glsl)) {
393 cleanup_program(fGpu, programID, shadersToDelete);
394 return nullptr;
395 }
396 }
397 }
398 this->resolveProgramResourceLocations(programID, usedProgramBinaries);
399
400 cleanup_shaders(fGpu, shadersToDelete);
401
402 // We can't cache SkSL or GLSL if we were given a precompiled program, but there's not
403 // much point in doing so.
404 if (!cached && !precompiledProgram) {
405 bool isSkSL = false;
406 if (fGpu->getContext()->priv().options().fShaderCacheStrategy ==
408 for (int i = 0; i < kGrShaderTypeCount; ++i) {
409 glsl[i] = SkShaderUtils::PrettyPrint(*sksl[i]);
410 }
411 isSkSL = true;
412 }
413 this->storeShaderInCache(interface, programID, glsl, isSkSL, &settings);
414 }
415 return this->createProgram(programID);
416}
417
418void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) {
419 fUniformHandler.bindUniformLocations(programID, fGpu->glCaps());
420
421 const GrGLCaps& caps = this->gpu()->glCaps();
422 if (caps.bindFragDataLocationSupport()) {
424 GL_CALL(BindFragDataLocation(programID, 0,
425 GrGLSLFragmentShaderBuilder::DeclaredColorOutputName()));
426 if (fFS.hasSecondaryOutput()) {
427 GL_CALL(BindFragDataLocationIndexed(programID, 0, 1,
428 GrGLSLFragmentShaderBuilder::DeclaredSecondaryColorOutputName()));
429 }
430 }
431}
432
433void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID, bool force) {
434 fUniformHandler.getUniformLocations(programID, fGpu->glCaps(), force);
435}
436
437sk_sp<GrGLProgram> GrGLProgramBuilder::createProgram(GrGLuint programID) {
438 return GrGLProgram::Make(fGpu,
440 programID,
441 fUniformHandler.fUniforms,
442 fUniformHandler.fSamplers,
443 std::move(fGPImpl),
444 std::move(fXPImpl),
445 std::move(fFPImpls),
446 std::move(fAttributes),
447 fVertexAttributeCnt,
448 fInstanceAttributeCnt,
449 fVertexStride,
450 fInstanceStride);
451}
452
454 GrGLPrecompiledProgram* precompiledProgram,
455 const SkData& cachedData) {
456 SkReadBuffer reader(cachedData.data(), cachedData.size());
458 if (shaderType != kSKSL_Tag) {
459 // TODO: Support GLSL, and maybe even program binaries, too?
460 return false;
461 }
462
463 GrGLGpu* glGpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
464
465 const GrGLInterface* gl = glGpu->glInterface();
466 auto errorHandler = dContext->priv().getShaderErrorHandler();
467
468 SkSL::ProgramSettings settings;
469 settings.fSharpenTextures = true;
471 meta.fSettings = &settings;
472
473 std::string shaders[kGrShaderTypeCount];
474 SkSL::Program::Interface interface;
475 if (!GrPersistentCacheUtils::UnpackCachedShaders(&reader, shaders, &interface, 1, &meta)) {
476 return false;
477 }
478
479 GrGLuint programID;
480 GR_GL_CALL_RET(gl, programID, CreateProgram());
481 if (0 == programID) {
482 return false;
483 }
484
485 SkTDArray<GrGLuint> shadersToDelete;
486
487 auto compileShader = [&](SkSL::ProgramKind kind, const std::string& sksl, GrGLenum type) {
488 std::string glsl;
489 SkSL::Program::Interface unusedInterface;
490 if (!skgpu::SkSLToGLSL(glGpu->caps()->shaderCaps(),
491 sksl,
492 kind,
493 settings,
494 &glsl,
495 &unusedInterface,
496 errorHandler)) {
497 return false;
498 }
499
500 if (GrGLuint shaderID = GrGLCompileAndAttachShader(glGpu->glContext(),
501 programID,
502 type,
503 glsl,
504 /*shaderWasCached=*/false,
505 glGpu->pipelineBuilder()->stats(),
506 errorHandler)) {
507 shadersToDelete.push_back(shaderID);
508 return true;
509 } else {
510 return false;
511 }
512 };
513
514 if (!compileShader(SkSL::ProgramKind::kFragment,
515 shaders[kFragment_GrShaderType],
517 !compileShader(SkSL::ProgramKind::kVertex,
518 shaders[kVertex_GrShaderType],
520 cleanup_program(glGpu, programID, shadersToDelete);
521 return false;
522 }
523
524 for (int i = 0; i < meta.fAttributeNames.size(); ++i) {
525 GR_GL_CALL(glGpu->glInterface(), BindAttribLocation(programID, i,
526 meta.fAttributeNames[i].c_str()));
527 }
528
529 const GrGLCaps& caps = glGpu->glCaps();
530 if (caps.bindFragDataLocationSupport()) {
532 GR_GL_CALL(glGpu->glInterface(),
533 BindFragDataLocation(programID, 0,
534 GrGLSLFragmentShaderBuilder::DeclaredColorOutputName()));
535
536 if (meta.fHasSecondaryColorOutput) {
537 GR_GL_CALL(glGpu->glInterface(),
538 BindFragDataLocationIndexed(programID, 0, 1,
539 GrGLSLFragmentShaderBuilder::DeclaredSecondaryColorOutputName()));
540 }
541 }
542
543 GR_GL_CALL(glGpu->glInterface(), LinkProgram(programID));
544 GrGLint linked = GR_GL_INIT_ZERO;
545 GR_GL_CALL(glGpu->glInterface(), GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
546 if (!linked) {
547 cleanup_program(glGpu, programID, shadersToDelete);
548 return false;
549 }
550
551 cleanup_shaders(glGpu, shadersToDelete);
552
553 precompiledProgram->fProgramID = programID;
554 precompiledProgram->fInterface = interface;
555 return true;
556}
static constexpr SkFourByteTag kSKSL_Tag
#define GR_GL_LINK_STATUS
#define GR_GL_TRUE
Definition GrGLDefines.h:27
#define GL_PROGRAM_BINARY_LENGTH
#define GR_GL_PROGRAM_BINARY_RETRIEVABLE_HINT
#define GR_GL_FRAGMENT_SHADER
#define GR_GL_VERTEX_SHADER
static void cleanup_program(GrGLGpu *gpu, GrGLuint programID, const SkTDArray< GrGLuint > &shaderIDs)
static constexpr SkFourByteTag kGLSL_Tag
#define GL_CALL(X)
#define GL_CALL_RET(R, X)
static constexpr SkFourByteTag kGLPB_Tag
static void cleanup_shaders(GrGLGpu *gpu, const SkTDArray< GrGLuint > &shaderIDs)
static constexpr SkFourByteTag kSKSL_Tag
bool GrGLCheckLinkStatus(const GrGLGpu *gpu, GrGLuint programID, bool shaderWasCached, GrContextOptions::ShaderErrorHandler *errorHandler, const std::string *sksl[kGrShaderTypeCount], const std::string glsl[kGrShaderTypeCount])
GrGLuint GrGLCompileAndAttachShader(const GrGLContext &glCtx, GrGLuint programId, GrGLenum type, const std::string &glsl, bool shaderWasCached, GrThreadSafePipelineBuilder::Stats *stats, GrContextOptions::ShaderErrorHandler *errorHandler)
unsigned int GrGLuint
Definition GrGLTypes.h:113
int GrGLsizei
Definition GrGLTypes.h:109
int GrGLint
Definition GrGLTypes.h:108
unsigned int GrGLenum
Definition GrGLTypes.h:102
#define GR_GL_INIT_ZERO
Definition GrGLUtil.h:244
#define GR_GL_CALL(IFACE, X)
Definition GrGLUtil.h:381
#define GR_GL_CALL_RET(IFACE, RET, X)
Definition GrGLUtil.h:396
@ kFragment_GrShaderType
@ kVertex_GrShaderType
static const int kGrShaderTypeCount
#define SkASSERT(cond)
Definition SkAssert.h:116
#define INHERITED(method,...)
#define SKSL_RTFLIP_NAME
Definition SkSLProgram.h:19
#define TRACE_EVENT0_ALWAYS(category_group, name)
#define TRACE_FUNC
uint32_t SkFourByteTag
Definition SkTypes.h:166
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
Definition SkTypes.h:167
const GrContextOptions & options() const
GrContextOptions::ShaderErrorHandler * getShaderErrorHandler() const
const GrShaderCaps * shaderCaps() const
Definition GrCaps.h:63
virtual void store(const SkData &, const SkData &)
GrContextOptions::PersistentCache * getPersistentCache()
GrDirectContextPriv priv()
bool programBinarySupport() const
Definition GrGLCaps.h:488
bool bindFragDataLocationSupport() const
Definition GrGLCaps.h:379
const GrGLCaps & glCaps() const
Definition GrGLGpu.h:108
GrThreadSafePipelineBuilder * pipelineBuilder() override
Definition GrGLGpu.cpp:574
const GrGLInterface * glInterface() const
Definition GrGLGpu.h:103
const GrGLContext & glContext() const
Definition GrGLGpu.h:101
const GrCaps * caps() const override
static bool PrecompileProgram(GrDirectContext *, GrGLPrecompiledProgram *, const SkData &)
static sk_sp< GrGLProgram > CreateProgram(GrDirectContext *, const GrProgramDesc &, const GrProgramInfo &, const GrGLPrecompiledProgram *=nullptr)
GrGLGpu * gpu() const
static sk_sp< GrGLProgram > Make(GrGLGpu *, const GrGLSLBuiltinUniformHandles &, GrGLuint programID, const UniformInfoArray &uniforms, const UniformInfoArray &textureSamplers, std::unique_ptr< GrGeometryProcessor::ProgramImpl >, std::unique_ptr< GrXferProcessor::ProgramImpl >, std::vector< std::unique_ptr< GrFragmentProcessor::ProgramImpl > > fps, std::unique_ptr< Attribute[]>, int vertexAttributeCnt, int instanceAttributeCnt, int vertexStride, int instanceStride)
const GrProgramDesc & desc() const
std::vector< std::unique_ptr< GrFragmentProcessor::ProgramImpl > > fFPImpls
std::unique_ptr< GrGeometryProcessor::ProgramImpl > fGPImpl
const GrShaderCaps * shaderCaps() const
GrGLSLVertexBuilder fVS
const GrGeometryProcessor & geometryProcessor() const
std::unique_ptr< GrXferProcessor::ProgramImpl > fXPImpl
GrGLSLBuiltinUniformHandles fUniformHandles
const GrProgramInfo & fProgramInfo
GrGLSLFragmentShaderBuilder fFS
void addRTFlipUniform(const char *name)
size_t instanceStride() const
const GrCaps * caps() const
Definition GrGpu.h:73
GrDirectContext * getContext()
Definition GrGpu.h:67
uint32_t keyLength() const
const uint32_t * asKey() const
static SkString Describe(const GrProgramInfo &, const GrCaps &)
void writeInt(int32_t value) override
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
Definition SkData.h:116
const void * data() const
Definition SkData.h:37
size_t size() const
Definition SkData.h:30
int size() const
Definition SkTDArray.h:138
void push_back(const T &v)
Definition SkTDArray.h:219
T * append()
Definition SkTDArray.h:191
T * get() const
Definition SkRefCnt.h:303
int size() const
Definition SkTArray.h:416
T & emplace_back(Args &&... args)
Definition SkTArray.h:243
struct MyStruct a[10]
EMSCRIPTEN_KEEPALIVE void empty()
FlPixelBufferTexturePrivate * priv
size_t length
sk_sp< SkData > PackCachedShaders(SkFourByteTag shaderType, const std::string shaders[], const SkSL::Program::Interface interfaces[], int numInterfaces, const ShaderMetadata *meta)
bool UnpackCachedShaders(SkReadBuffer *reader, std::string shaders[], SkSL::Program::Interface interfaces[], int numInterfaces, ShaderMetadata *meta)
SkFourByteTag GetType(SkReadBuffer *reader)
std::string PrettyPrint(const std::string &string)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
bool SkSLToGLSL(const SkSL::ShaderCaps *caps, const std::string &sksl, SkSL::ProgramKind programKind, const SkSL::ProgramSettings &settings, std::string *glsl, SkSL::ProgramInterface *outInterface, ShaderErrorHandler *errorHandler)
ShaderCacheStrategy fShaderCacheStrategy
SkSL::Program::Interface fInterface
skia_private::TArray< std::string > fAttributeNames
bool mustDeclareFragmentShaderOutput() const
Definition SkSLUtil.h:43
#define TRACE_EVENT0(category_group, name)