Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
PaintParamsKey.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 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
9
15
16using namespace skia_private;
17
18namespace skgpu::graphite {
19
20//--------------------------------------------------------------------------------------------------
21// PaintParamsKeyBuilder
22
23#ifdef SK_DEBUG
24
25void PaintParamsKeyBuilder::checkReset() {
26 SkASSERT(!fLocked);
27 SkASSERT(fData.empty());
28 SkASSERT(fStack.empty());
29}
30
31void PaintParamsKeyBuilder::pushStack(int32_t codeSnippetID) {
32 SkASSERT(fDict->isValidID(codeSnippetID));
33
34 if (!fStack.empty()) {
35 fStack.back().fNumActualChildren++;
36 SkASSERT(fStack.back().fNumActualChildren <= fStack.back().fNumExpectedChildren);
37 }
38
39 const ShaderSnippet* snippet = fDict->getEntry(codeSnippetID);
40 fStack.push_back({codeSnippetID, snippet->fNumChildren});
41}
42
43void PaintParamsKeyBuilder::popStack() {
44 SkASSERT(!fStack.empty());
45 SkASSERT(fStack.back().fNumActualChildren == fStack.back().fNumExpectedChildren);
46 fStack.pop_back();
47}
48
49#endif // SK_DEBUG
50
51//--------------------------------------------------------------------------------------------------
52// PaintParamsKey
53
55 int32_t* newData = arena->makeArrayDefault<int32_t>(fData.size());
56 memcpy(newData, fData.data(), fData.size_bytes());
57 return PaintParamsKey({newData, fData.size()});
58}
59
60
61const ShaderNode* PaintParamsKey::createNode(const ShaderCodeDictionary* dict,
62 int* currentIndex,
63 SkArenaAlloc* arena) const {
64 SkASSERT(*currentIndex < SkTo<int>(fData.size()));
65 const int32_t index = (*currentIndex)++;
66 const int32_t id = fData[index];
67
68 const ShaderSnippet* entry = dict->getEntry(id);
69 if (!entry) {
70 SKGPU_LOG_E("Unknown snippet ID in key: %d", id);
71 return nullptr;
72 }
73
74 const ShaderNode** childArray = arena->makeArray<const ShaderNode*>(entry->fNumChildren);
75 for (int i = 0; i < entry->fNumChildren; ++i) {
76 const ShaderNode* child = this->createNode(dict, currentIndex, arena);
77 if (!child) {
78 return nullptr;
79 }
80 childArray[i] = child;
81 }
82
83 return arena->make<ShaderNode>(entry, SkSpan(childArray, entry->fNumChildren), id, index);
84}
85
87 SkArenaAlloc* arena) const {
88 // TODO: Once the PaintParamsKey creation is organized to represent a single tree starting at
89 // the final blend, there will only be a single root node and this can be simplified.
90 // For now, we don't know how many roots there are, so collect them into a local array before
91 // copying into the arena.
92 const int keySize = SkTo<int>(fData.size());
93
94 // Normal PaintParams creation will have up to 7 roots for the different stages.
96 int currentIndex = 0;
97 while (currentIndex < keySize) {
98 const ShaderNode* root = this->createNode(dict, &currentIndex, arena);
99 if (!root) {
100 return {}; // a bad key
101 }
102 roots.push_back(root);
103 }
104
105 // Copy the accumulated roots into a span stored in the arena
106 const ShaderNode** rootSpan = arena->makeArray<const ShaderNode*>(roots.size());
107 memcpy(rootSpan, roots.data(), roots.size_bytes());
108 return SkSpan(rootSpan, roots.size());
109}
110
111static int key_to_string(SkString* str,
112 const ShaderCodeDictionary* dict,
113 SkSpan<const int32_t> keyData,
114 int currentIndex) {
115 SkASSERT(currentIndex < SkTo<int>(keyData.size()));
116
117 int32_t id = keyData[currentIndex++];
118 auto entry = dict->getEntry(id);
119 if (!entry) {
120 str->append("UnknownCodeSnippetID:");
121 str->appendS32(id);
122 str->append(" ");
123 return currentIndex;
124 }
125
126 std::string_view name = entry->fName;
127 if (skstd::ends_with(name, "Shader")) {
128 name.remove_suffix(6);
129 }
130 str->append(name);
131
132 if (entry->fNumChildren > 0) {
133 str->append(" [ ");
134 for (int i = 0; i < entry->fNumChildren; ++i) {
135 currentIndex = key_to_string(str, dict, keyData, currentIndex);
136 }
137 str->append("]");
138 }
139
140 str->append(" ");
141 return currentIndex;
142}
143
145 SkString str;
146 const int keySize = SkTo<int>(fData.size());
147 for (int currentIndex = 0; currentIndex < keySize; ) {
148 currentIndex = key_to_string(&str, dict, fData, currentIndex);
149 }
150 return str.isEmpty() ? SkString("(empty)") : str;
151}
152
153#ifdef SK_DEBUG
154
155static int dump_node(const ShaderCodeDictionary* dict,
156 SkSpan<const int32_t> keyData,
157 int currentIndex,
158 int indent) {
159 SkASSERT(currentIndex < SkTo<int>(keyData.size()));
160
161 SkDebugf("%*c", 2 * indent, ' ');
162
163 int32_t id = keyData[currentIndex++];
164 auto entry = dict->getEntry(id);
165 if (!entry) {
166 SkDebugf("[%d] unknown block!\n", id);
167 return currentIndex;
168 }
169
170 SkDebugf("[%d] %s\n", id, entry->fStaticFunctionName);
171 for (int i = 0; i < entry->fNumChildren; ++i) {
172 currentIndex = dump_node(dict, keyData, currentIndex, indent + 1);
173 }
174 return currentIndex;
175}
176
177void PaintParamsKey::dump(const ShaderCodeDictionary* dict) const {
178 const int keySize = SkTo<int>(fData.size());
179
180 SkDebugf("--------------------------------------\n");
181 SkDebugf("PaintParamsKey (keySize: %d):\n", keySize);
182
183 int currentIndex = 0;
184 while (currentIndex < keySize) {
185 currentIndex = dump_node(dict, fData, currentIndex, 1);
186 }
187}
188
189#endif // SK_DEBUG
190
191} // namespace skgpu::graphite
#define SKGPU_LOG_E(fmt,...)
Definition Log.h:38
#define SkASSERT(cond)
Definition SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
T * makeArrayDefault(size_t count)
T * makeArray(size_t count)
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
constexpr T * data() const
Definition SkSpan_impl.h:94
constexpr size_t size_bytes() const
Definition SkSpan_impl.h:97
constexpr size_t size() const
Definition SkSpan_impl.h:95
bool isEmpty() const
Definition SkString.h:130
void append(const char text[])
Definition SkString.h:203
void appendS32(int32_t value)
Definition SkString.h:208
SkString toString(const ShaderCodeDictionary *dict) const
PaintParamsKey clone(SkArenaAlloc *) const
SkSpan< const ShaderNode * > getRootNodes(const ShaderCodeDictionary *, SkArenaAlloc *) const
const ShaderSnippet * getEntry(int codeSnippetID) const SK_EXCLUDES(fSpinLock)
bool empty() const
Definition SkTArray.h:194
const char * name
Definition fuchsia.cc:50
static int key_to_string(SkString *str, const ShaderCodeDictionary *dict, SkSpan< const int32_t > keyData, int currentIndex)
constexpr bool ends_with(std::string_view str, std::string_view suffix)
const uintptr_t id