• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #ifndef SkPaintParamsKey_DEFINED
9 #define SkPaintParamsKey_DEFINED
10 
11 #include "include/core/SkTypes.h"
12 #include "include/private/SkTArray.h"
13 #include "src/core/SkBuiltInCodeSnippetID.h"
14 
15 #include <array>
16 #include <limits>
17 #include <vector>
18 
19 enum class SkBackend : uint8_t {
20     kGanesh,
21     kGraphite,
22     kSkVM
23 };
24 class SkPaintParamsKey;
25 class SkShaderCodeDictionary;
26 class SkShaderInfo;
27 
28 class SkPaintParamsKeyBuilder {
29 public:
30     SkPaintParamsKeyBuilder(const SkShaderCodeDictionary*);
31 
32     void beginBlock(int codeSnippetID);
beginBlock(SkBuiltInCodeSnippetID id)33     void beginBlock(SkBuiltInCodeSnippetID id) { this->beginBlock(static_cast<int>(id)); }
34     void endBlock();
35 
36     void addBytes(uint32_t numBytes, const uint8_t* data);
addByte(uint8_t data)37     void addByte(uint8_t data) {
38         this->addBytes(1, &data);
39     }
40 
41 #ifdef SK_DEBUG
byte(int offset)42     uint8_t byte(int offset) const { return fData[offset]; }
43 #endif
44 
45     std::unique_ptr<SkPaintParamsKey> snap();
46 
sizeInBytes()47     int sizeInBytes() const { return fData.count(); }
48 
isValid()49     bool isValid() const { return fIsValid; }
50 
51 private:
52     void makeInvalid();
53 
54     struct StackFrame {
55         int fCodeSnippetID;
56         int fHeaderOffset;
57     };
58 
59     bool fIsValid = true;
60     const SkShaderCodeDictionary* fDict;
61     std::vector<StackFrame> fStack;
62 
63     // TODO: It is probably overkill but we could encode the SkBackend in the first byte of
64     // the key.
65     SkTArray<uint8_t, true> fData;
66 };
67 
68 // This class is a compact representation of the shader needed to implement a given
69 // PaintParams. Its structure is a series of blocks where each block has a
70 // header that consists of 2-bytes:
71 //   a 1-byte code-snippet ID
72 //   a 1-byte number-of-bytes-in-the-block field (incl. the space for the header)
73 // The rest of the data in the block is dependent on the individual code snippet.
74 // If a given block has child blocks, they appear in the key right after their
75 // parent block's header.
76 class SkPaintParamsKey {
77 public:
78     static const int kBlockHeaderSizeInBytes = 2;
79     static const int kBlockSizeOffsetInBytes = 1; // offset to the block size w/in the header
80     static const int kMaxBlockSize = std::numeric_limits<uint8_t>::max();
81 
readCodeSnippetID(int headerOffset)82     std::pair<SkBuiltInCodeSnippetID, uint8_t> readCodeSnippetID(int headerOffset) const {
83         SkASSERT(headerOffset < this->sizeInBytes() - kBlockHeaderSizeInBytes);
84 
85         SkBuiltInCodeSnippetID id = static_cast<SkBuiltInCodeSnippetID>(fData[headerOffset]);
86         uint8_t blockSize = fData[headerOffset+1];
87         SkASSERT(headerOffset + blockSize <= this->sizeInBytes());
88 
89         return { id, blockSize };
90     }
91 
92 #ifdef SK_DEBUG
byte(int offset)93     uint8_t byte(int offset) const {
94         SkASSERT(offset < this->sizeInBytes());
95         return fData[offset];
96     }
97     static int DumpBlock(const SkPaintParamsKey&, int headerOffset);
98     void dump() const;
99 #endif
100     void toShaderInfo(SkShaderCodeDictionary*, SkShaderInfo*) const;
101 
data()102     const void* data() const { return fData.data(); }
sizeInBytes()103     int sizeInBytes() const { return fData.count(); }
104 
105     bool operator==(const SkPaintParamsKey& that) const;
106     bool operator!=(const SkPaintParamsKey& that) const { return !(*this == that); }
107 
108 private:
109     friend class SkPaintParamsKeyBuilder;
110 
111     SkPaintParamsKey(SkTArray<uint8_t, true>&&);
112 
113     static int AddBlockToShaderInfo(SkShaderCodeDictionary*,
114                                     const SkPaintParamsKey&,
115                                     int headerOffset,
116                                     SkShaderInfo*);
117 
118     SkTArray<uint8_t, true> fData;
119 };
120 
121 #endif // SkPaintParamsKey_DEFINED
122