1 /* 2 * Copyright 2021 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 skgpu_UniformManager_DEFINED 9 #define skgpu_UniformManager_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/core/SkSpan.h" 13 #include "include/private/SkColorData.h" 14 #include "include/private/base/SkTDArray.h" 15 #include "src/core/SkSLTypeShared.h" 16 #include "src/gpu/graphite/ResourceTypes.h" 17 #include "src/gpu/graphite/Uniform.h" 18 19 class SkM44; 20 class SkMatrix; 21 struct SkPoint; 22 struct SkRect; 23 struct SkV2; 24 struct SkV4; 25 26 namespace skgpu::graphite { 27 28 enum class CType : unsigned; 29 30 class UniformDataBlock; 31 32 class UniformOffsetCalculator { 33 public: 34 UniformOffsetCalculator(Layout layout, uint32_t startingOffset); 35 size()36 size_t size() const { return fOffset; } 37 38 // Calculates the correctly aligned offset to accommodate `count` instances of `type` and 39 // advances the internal offset. Returns the correctly aligned start offset. 40 // 41 // After a call to this method, `size()` will return the offset to the end of `count` instances 42 // of `type` (while the return value equals the aligned start offset). Subsequent calls will 43 // calculate the new start offset starting at `size()`. 44 size_t advanceOffset(SkSLType type, unsigned int count); 45 46 protected: 47 SkSLType getUniformTypeForLayout(SkSLType type); 48 void setLayout(Layout); 49 50 using WriteUniformFn = uint32_t (*)(SkSLType type, 51 CType ctype, 52 void *dest, 53 int n, 54 const void *src); 55 56 WriteUniformFn fWriteUniform; 57 Layout fLayout; // TODO: eventually 'fLayout' will not need to be stored 58 uint32_t fOffset = 0; 59 }; 60 61 class UniformManager : public UniformOffsetCalculator { 62 public: UniformManager(Layout layout)63 UniformManager(Layout layout) : UniformOffsetCalculator(layout, /*startingOffset=*/0) {} 64 65 UniformDataBlock finishUniformDataBlock(); size()66 size_t size() const { return fStorage.size(); } 67 68 void resetWithNewLayout(Layout); 69 void reset(); 70 71 // Write a single instance of `type` from the data block referenced by `src`. 72 void write(SkSLType type, const void* src); 73 74 // Write an array of `type` with `count` elements from the data block referenced by `src`. 75 // Does nothing if `count` is 0. 76 void writeArray(SkSLType type, const void* src, unsigned int count); 77 78 // Copy from `src` using Uniform array-count semantics. 79 void write(const Uniform&, const uint8_t* src); 80 81 void write(const SkM44&); 82 void write(const SkPMColor4f&); 83 void write(const SkRect&); 84 void write(const SkV2&); 85 void write(const SkV4&); 86 void write(const SkPoint&); 87 void write(float f); 88 void write(int); 89 90 void writeArray(SkSpan<const SkColor4f>); 91 void writeArray(SkSpan<const SkPMColor4f>); 92 void writeArray(SkSpan<const float>); 93 94 void writeHalf(const SkMatrix&); 95 void writeHalfArray(SkSpan<const float>); 96 97 // Debug only utilities used for debug assertions and tests. 98 void checkReset() const; 99 void setExpectedUniforms(SkSpan<const Uniform>); 100 void checkExpected(SkSLType, unsigned int count); 101 void doneWithExpectedUniforms(); 102 103 private: 104 // Writes a single element of the given `type` if `count` == 0 (aka Uniform::kNonArray). 105 // Writes an array of `count` elements if `count` > 0, obeying any array layout constraints. 106 // 107 // Do not call this method directly for any new write()/writeArray() overloads. Instead 108 // call the write(SkSLType, const void*) and writeArray(SkSLType, const void*, unsigned int) 109 // overloads which correctly abstract the array vs non-array semantics. 110 void writeInternal(SkSLType type, unsigned int count, const void* src); 111 112 #ifdef SK_DEBUG 113 SkSpan<const Uniform> fExpectedUniforms; 114 int fExpectedUniformIndex = 0; 115 #endif // SK_DEBUG 116 117 SkTDArray<char> fStorage; 118 uint32_t fReqAlignment = 0; 119 }; 120 121 } // namespace skgpu 122 123 #endif // skgpu_UniformManager_DEFINED 124