• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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