1 /*
2 * Copyright 2019 Google LLC.
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
8 #ifndef GrPersistentCacheEntry_DEFINED
9 #define GrPersistentCacheEntry_DEFINED
10
11 #include "include/core/SkData.h"
12 #include "include/private/GrTypesPriv.h"
13 #include "src/core/SkReader32.h"
14 #include "src/core/SkWriter32.h"
15 #include "src/sksl/SkSLString.h"
16 #include "src/sksl/ir/SkSLProgram.h"
17
18 // The GrPersistentCache stores opaque blobs, as far as clients are concerned. It's helpful to
19 // inspect certain kinds of cached data within our tools, so for those cases (GLSL, SPIR-V), we
20 // put the serialization logic here, to be shared by the backend code and the tool code.
21 namespace GrPersistentCacheUtils {
22
PackCachedShaders(SkFourByteTag shaderType,const SkSL::String shaders[],const SkSL::Program::Inputs inputs[],int numInputs)23 static inline sk_sp<SkData> PackCachedShaders(SkFourByteTag shaderType,
24 const SkSL::String shaders[],
25 const SkSL::Program::Inputs inputs[],
26 int numInputs) {
27 // For consistency (so tools can blindly pack and unpack cached shaders), we always write
28 // kGrShaderTypeCount inputs. If the backend gives us fewer, we just replicate the last one.
29 SkASSERT(numInputs >= 1 && numInputs <= kGrShaderTypeCount);
30
31 SkWriter32 writer;
32 writer.write32(shaderType);
33 for (int i = 0; i < kGrShaderTypeCount; ++i) {
34 writer.writeString(shaders[i].c_str(), shaders[i].size());
35 writer.writePad(&inputs[SkTMin(i, numInputs - 1)], sizeof(SkSL::Program::Inputs));
36 }
37 return writer.snapshotAsData();
38 }
39
UnpackCachedShaders(const SkData * data,SkSL::String shaders[],SkSL::Program::Inputs inputs[],int numInputs)40 static inline SkFourByteTag UnpackCachedShaders(const SkData* data,
41 SkSL::String shaders[],
42 SkSL::Program::Inputs inputs[],
43 int numInputs) {
44 SkReader32 reader(data->data(), data->size());
45 SkFourByteTag shaderType = reader.readU32();
46 for (int i = 0; i < kGrShaderTypeCount; ++i) {
47 size_t stringLen = 0;
48 const char* string = reader.readString(&stringLen);
49 shaders[i] = SkSL::String(string, stringLen);
50
51 // GL, for example, only wants one set of Inputs
52 if (i < numInputs) {
53 reader.read(&inputs[i], sizeof(inputs[i]));
54 } else {
55 reader.skip(sizeof(SkSL::Program::Inputs));
56 }
57 }
58 return shaderType;
59 }
60
61 }
62
63 #endif
64