| /* | |
| * Copyright 2021 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef skgpu_UniformManager_DEFINED | |
| #define skgpu_UniformManager_DEFINED | |
| #include "include/core/SkRefCnt.h" | |
| #include "include/core/SkSpan.h" | |
| #include "include/private/SkColorData.h" | |
| #include "include/private/base/SkTDArray.h" | |
| #include "src/core/SkSLTypeShared.h" | |
| #include "src/gpu/graphite/ResourceTypes.h" | |
| #include "src/gpu/graphite/Uniform.h" | |
| class SkM44; | |
| class SkMatrix; | |
| struct SkPoint; | |
| struct SkRect; | |
| struct SkV2; | |
| struct SkV4; | |
| namespace skgpu::graphite { | |
| enum class CType : unsigned; | |
| class UniformDataBlock; | |
| class UniformOffsetCalculator { | |
| public: | |
| UniformOffsetCalculator(Layout layout, uint32_t startingOffset); | |
| size_t size() const { return fOffset; } | |
| // Calculates the correctly aligned offset to accommodate `count` instances of `type` and | |
| // advances the internal offset. Returns the correctly aligned start offset. | |
| // | |
| // After a call to this method, `size()` will return the offset to the end of `count` instances | |
| // of `type` (while the return value equals the aligned start offset). Subsequent calls will | |
| // calculate the new start offset starting at `size()`. | |
| size_t advanceOffset(SkSLType type, unsigned int count); | |
| protected: | |
| SkSLType getUniformTypeForLayout(SkSLType type); | |
| void setLayout(Layout); | |
| using WriteUniformFn = uint32_t (*)(SkSLType type, | |
| CType ctype, | |
| void *dest, | |
| int n, | |
| const void *src); | |
| WriteUniformFn fWriteUniform; | |
| Layout fLayout; // TODO: eventually 'fLayout' will not need to be stored | |
| uint32_t fOffset = 0; | |
| }; | |
| class UniformManager : public UniformOffsetCalculator { | |
| public: | |
| UniformManager(Layout layout) : UniformOffsetCalculator(layout, /*startingOffset=*/0) {} | |
| UniformDataBlock finishUniformDataBlock(); | |
| size_t size() const { return fStorage.size(); } | |
| void resetWithNewLayout(Layout); | |
| void reset(); | |
| // Write a single instance of `type` from the data block referenced by `src`. | |
| void write(SkSLType type, const void* src); | |
| // Write an array of `type` with `count` elements from the data block referenced by `src`. | |
| // Does nothing if `count` is 0. | |
| void writeArray(SkSLType type, const void* src, unsigned int count); | |
| // Copy from `src` using Uniform array-count semantics. | |
| void write(const Uniform&, const uint8_t* src); | |
| void write(const SkM44&); | |
| void write(const SkPMColor4f&); | |
| void write(const SkRect&); | |
| void write(const SkV2&); | |
| void write(const SkV4&); | |
| void write(const SkPoint&); | |
| void write(float f); | |
| void write(int); | |
| void writeArray(SkSpan<const SkColor4f>); | |
| void writeArray(SkSpan<const SkPMColor4f>); | |
| void writeArray(SkSpan<const float>); | |
| void writeHalf(const SkMatrix&); | |
| void writeHalfArray(SkSpan<const float>); | |
| // Debug only utilities used for debug assertions and tests. | |
| void checkReset() const; | |
| void setExpectedUniforms(SkSpan<const Uniform>); | |
| void checkExpected(SkSLType, unsigned int count); | |
| void doneWithExpectedUniforms(); | |
| private: | |
| // Writes a single element of the given `type` if `count` == 0 (aka Uniform::kNonArray). | |
| // Writes an array of `count` elements if `count` > 0, obeying any array layout constraints. | |
| // | |
| // Do not call this method directly for any new write()/writeArray() overloads. Instead | |
| // call the write(SkSLType, const void*) and writeArray(SkSLType, const void*, unsigned int) | |
| // overloads which correctly abstract the array vs non-array semantics. | |
| void writeInternal(SkSLType type, unsigned int count, const void* src); | |
| #ifdef SK_DEBUG | |
| SkSpan<const Uniform> fExpectedUniforms; | |
| int fExpectedUniformIndex = 0; | |
| #endif // SK_DEBUG | |
| SkTDArray<char> fStorage; | |
| uint32_t fReqAlignment = 0; | |
| }; | |
| } // namespace skgpu | |
| #endif // skgpu_UniformManager_DEFINED |