• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 struct ShaderMetadata {
24     SkSL::Program::Settings* fSettings = nullptr;
25     SkTArray<SkSL::String> fAttributeNames;
26     bool fHasCustomColorOutput = false;
27     bool fHasSecondaryColorOutput = false;
28 };
29 
30 static inline sk_sp<SkData> PackCachedShaders(SkFourByteTag shaderType,
31                                               const SkSL::String shaders[],
32                                               const SkSL::Program::Inputs inputs[],
33                                               int numInputs,
34                                               const ShaderMetadata* meta = nullptr) {
35     // For consistency (so tools can blindly pack and unpack cached shaders), we always write
36     // kGrShaderTypeCount inputs. If the backend gives us fewer, we just replicate the last one.
37     SkASSERT(numInputs >= 1 && numInputs <= kGrShaderTypeCount);
38 
39     SkWriter32 writer;
40     writer.write32(shaderType);
41     for (int i = 0; i < kGrShaderTypeCount; ++i) {
42         writer.writeString(shaders[i].c_str(), shaders[i].size());
43         writer.writePad(&inputs[std::min(i, numInputs - 1)], sizeof(SkSL::Program::Inputs));
44     }
45     writer.writeBool(SkToBool(meta));
46     if (meta) {
47         writer.writeBool(SkToBool(meta->fSettings));
48         if (meta->fSettings) {
49             writer.writeBool(meta->fSettings->fFlipY);
50             writer.writeBool(meta->fSettings->fFragColorIsInOut);
51             writer.writeBool(meta->fSettings->fForceHighPrecision);
52         }
53 
54         writer.writeInt(meta->fAttributeNames.count());
55         for (const auto& attr : meta->fAttributeNames) {
56             writer.writeString(attr.c_str(), attr.size());
57         }
58 
59         writer.writeBool(meta->fHasCustomColorOutput);
60         writer.writeBool(meta->fHasSecondaryColorOutput);
61     }
62     return writer.snapshotAsData();
63 }
64 
65 static inline void UnpackCachedShaders(SkReader32* reader,
66                                        SkSL::String shaders[],
67                                        SkSL::Program::Inputs inputs[],
68                                        int numInputs,
69                                        ShaderMetadata* meta = nullptr) {
70     for (int i = 0; i < kGrShaderTypeCount; ++i) {
71         size_t stringLen = 0;
72         const char* string = reader->readString(&stringLen);
73         shaders[i] = SkSL::String(string, stringLen);
74 
75         // GL, for example, only wants one set of Inputs
76         if (i < numInputs) {
77             reader->read(&inputs[i], sizeof(inputs[i]));
78         } else {
79             reader->skip(sizeof(SkSL::Program::Inputs));
80         }
81     }
82     if (reader->readBool() && meta) {
83         SkASSERT(meta->fSettings != nullptr);
84 
85         if (reader->readBool()) {
86             meta->fSettings->fFlipY              = reader->readBool();
87             meta->fSettings->fFragColorIsInOut   = reader->readBool();
88             meta->fSettings->fForceHighPrecision = reader->readBool();
89         }
90 
91         meta->fAttributeNames.resize(reader->readInt());
92         for (int i = 0; i < meta->fAttributeNames.count(); ++i) {
93             size_t stringLen = 0;
94             const char* string = reader->readString(&stringLen);
95             meta->fAttributeNames[i] = SkSL::String(string, stringLen);
96         }
97 
98         meta->fHasCustomColorOutput    = reader->readBool();
99         meta->fHasSecondaryColorOutput = reader->readBool();
100     }
101 }
102 
103 }
104 
105 #endif
106