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