• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SkUniformData_DEFINED
9 #define SkUniformData_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "include/core/SkSpan.h"
13 #include "src/core/SkUniform.h"
14 #include <vector>
15 
16 /*
17  * TODO: Here is the plan of record for SkUniformData
18  *    allocate them (and their ancillary data (offsets & data)) in an arena - and rm SkRefCnt
19  *    remove the offsets - these should be recomputable as/if needed
20  *    allow a scratch buffer to be used to collect the uniform data when processing a PaintParams
21  *       - this can be reset for each draw and be copied into a cache if it needs to be preserved
22  *    if possible, clear out the cache (and delete the arena) once the DrawPass is created/the
23  *               uniforms are copied into a buffer
24  *       - this will mean we'll get w/in DrawPass reuse but not cross-DrawPass reuse
25  *       - we could also explore getting w/in a Recording (i.e. cross-DrawPass) and w/in a
26  *               Recorder reuse (i.e., cross-Recordings, but single-threaded)
27  *    have the SkUniformData's data layout match what is required by the DrawList so we can just
28  *               copy it into the buffer
29  */
30 
31 class SkUniformData : public SkRefCnt {
32 public:
33 
34     // TODO: should we require a name (e.g., "gradient_uniforms") for each uniform block so
35     // we can better name the Metal FS uniform struct?
36     static sk_sp<SkUniformData> Make(SkSpan<const SkUniform>, size_t dataSize);
37 
~SkUniformData()38     ~SkUniformData() override {
39         // TODO: fOffsets and fData should just be allocated right after UniformData in an arena
40         delete [] fOffsets;
41         delete [] fData;
42     }
43 
count()44     int count() const { return static_cast<unsigned int>(fUniforms.size()); }
uniforms()45     SkSpan<const SkUniform> uniforms() const { return fUniforms; }
offsets()46     uint32_t* offsets() { return fOffsets; }
offsets()47     const uint32_t* offsets() const { return fOffsets; }
offset(int index)48     uint32_t offset(int index) {
49         SkASSERT(index >= 0 && static_cast<size_t>(index) < fUniforms.size());
50         return fOffsets[index];
51     }
data()52     char* data() { return fData; }
data()53     const char* data() const { return fData; }
dataSize()54     size_t dataSize() const { return fDataSize; }
55 
56     bool operator==(const SkUniformData&) const;
57     bool operator!=(const SkUniformData& other) const { return !(*this == other);  }
58 
59 private:
SkUniformData(SkSpan<const SkUniform> uniforms,uint32_t * offsets,char * data,size_t dataSize)60     SkUniformData(SkSpan<const SkUniform> uniforms,
61                   uint32_t* offsets,
62                   char* data,
63                   size_t dataSize)
64             : fUniforms(uniforms)
65             , fOffsets(offsets)
66             , fData(data)
67             , fDataSize(dataSize) {
68     }
69 
70     SkSpan<const SkUniform> fUniforms;
71     uint32_t* fOffsets; // offset of each uniform in 'fData'
72     char* fData;
73     const size_t fDataSize;
74 };
75 
76 class SkUniformBlock {
77 public:
78     SkUniformBlock() = default;
SkUniformBlock(sk_sp<SkUniformData> initial)79     SkUniformBlock(sk_sp<SkUniformData> initial) {
80         fUniformData.push_back(std::move(initial));
81     }
82 
83     void add(sk_sp<SkUniformData>);
84 
empty()85     bool empty() const { return fUniformData.empty(); }
86     size_t totalSize() const;  // TODO: cache this?
87     int count() const;         // TODO: cache this?
88 
89     bool operator==(const SkUniformBlock&) const;
90     bool operator!=(const SkUniformBlock& other) const { return !(*this == other);  }
91     size_t hash() const;
92 
93     using container = std::vector<sk_sp<SkUniformData>>;
94     using iterator = container::iterator;
95     using const_iterator = container::const_iterator;
96 
begin()97     inline iterator begin() noexcept { return fUniformData.begin(); }
cbegin()98     inline const_iterator cbegin() const noexcept { return fUniformData.cbegin(); }
end()99     inline iterator end() noexcept { return fUniformData.end(); }
cend()100     inline const_iterator cend() const noexcept { return fUniformData.cend(); }
101 
102 private:
103     // TODO: SkUniformData should be held uniquely
104     std::vector<sk_sp<SkUniformData>> fUniformData;
105 };
106 
107 #endif // SkUniformData_DEFINED
108