| /* |
| * 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 |