1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // renderer_utils:
7 //   Helper methods pertaining to most or all back-ends.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_RENDERER_UTILS_H_
11 #define LIBANGLE_RENDERER_RENDERER_UTILS_H_
12 
13 #include <cstdint>
14 
15 #include <limits>
16 #include <map>
17 
18 #include "common/angleutils.h"
19 #include "libANGLE/angletypes.h"
20 
21 namespace angle
22 {
23 struct Format;
24 }  // namespace angle
25 
26 namespace gl
27 {
28 struct FormatType;
29 struct InternalFormat;
30 }  // namespace gl
31 
32 namespace egl
33 {
34 class AttributeMap;
35 }  // namespace egl
36 
37 namespace rx
38 {
39 
40 class ResourceSerial
41 {
42   public:
ResourceSerial()43     constexpr ResourceSerial() : mValue(kDirty) {}
ResourceSerial(uintptr_t value)44     explicit constexpr ResourceSerial(uintptr_t value) : mValue(value) {}
45     constexpr bool operator==(ResourceSerial other) const { return mValue == other.mValue; }
46     constexpr bool operator!=(ResourceSerial other) const { return mValue != other.mValue; }
47 
dirty()48     void dirty() { mValue = kDirty; }
clear()49     void clear() { mValue = kEmpty; }
50 
valid()51     constexpr bool valid() const { return mValue != kEmpty && mValue != kDirty; }
empty()52     constexpr bool empty() const { return mValue == kEmpty; }
53 
54   private:
55     constexpr static uintptr_t kDirty = std::numeric_limits<uintptr_t>::max();
56     constexpr static uintptr_t kEmpty = 0;
57 
58     uintptr_t mValue;
59 };
60 
61 class SerialFactory;
62 
63 class Serial final
64 {
65   public:
Serial()66     constexpr Serial() : mValue(kInvalid) {}
67     constexpr Serial(const Serial &other) = default;
68     Serial &operator=(const Serial &other) = default;
69 
70     constexpr bool operator==(const Serial &other) const
71     {
72         return mValue != kInvalid && mValue == other.mValue;
73     }
74     constexpr bool operator!=(const Serial &other) const
75     {
76         return mValue == kInvalid || mValue != other.mValue;
77     }
78     constexpr bool operator>(const Serial &other) const { return mValue > other.mValue; }
79     constexpr bool operator>=(const Serial &other) const { return mValue >= other.mValue; }
80     constexpr bool operator<(const Serial &other) const { return mValue < other.mValue; }
81     constexpr bool operator<=(const Serial &other) const { return mValue <= other.mValue; }
82 
83   private:
84     friend class SerialFactory;
Serial(uint64_t value)85     constexpr explicit Serial(uint64_t value) : mValue(value) {}
86     uint64_t mValue;
87     static constexpr uint64_t kInvalid = 0;
88 };
89 
90 class SerialFactory final : angle::NonCopyable
91 {
92   public:
SerialFactory()93     SerialFactory() : mSerial(1) {}
94 
generate()95     Serial generate()
96     {
97         ASSERT(mSerial != std::numeric_limits<uint64_t>::max());
98         return Serial(mSerial++);
99     }
100 
101   private:
102     uint64_t mSerial;
103 };
104 
105 using MipGenerationFunction = void (*)(size_t sourceWidth,
106                                        size_t sourceHeight,
107                                        size_t sourceDepth,
108                                        const uint8_t *sourceData,
109                                        size_t sourceRowPitch,
110                                        size_t sourceDepthPitch,
111                                        uint8_t *destData,
112                                        size_t destRowPitch,
113                                        size_t destDepthPitch);
114 
115 typedef void (*ColorReadFunction)(const uint8_t *source, uint8_t *dest);
116 typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest);
117 typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest);
118 
119 class FastCopyFunctionMap
120 {
121   public:
122     struct Entry
123     {
124         GLenum format;
125         GLenum type;
126         ColorCopyFunction func;
127     };
128 
FastCopyFunctionMap()129     constexpr FastCopyFunctionMap() : FastCopyFunctionMap(nullptr, 0) {}
130 
FastCopyFunctionMap(const Entry * data,size_t size)131     constexpr FastCopyFunctionMap(const Entry *data, size_t size) : mSize(size), mData(data) {}
132 
133     bool has(const gl::FormatType &formatType) const;
134     ColorCopyFunction get(const gl::FormatType &formatType) const;
135 
136   private:
137     size_t mSize;
138     const Entry *mData;
139 };
140 
141 struct PackPixelsParams
142 {
143     PackPixelsParams();
144     PackPixelsParams(const gl::Rectangle &area,
145                      GLenum format,
146                      GLenum type,
147                      GLuint outputPitch,
148                      const gl::PixelPackState &pack,
149                      gl::Buffer *packBufferIn,
150                      ptrdiff_t offset);
151 
152     gl::Rectangle area;
153     GLenum format;
154     GLenum type;
155     GLuint outputPitch;
156     gl::Buffer *packBuffer;
157     gl::PixelPackState pack;
158     ptrdiff_t offset;
159 };
160 
161 void PackPixels(const PackPixelsParams &params,
162                 const angle::Format &sourceFormat,
163                 int inputPitch,
164                 const uint8_t *source,
165                 uint8_t *destination);
166 
167 ColorWriteFunction GetColorWriteFunction(const gl::FormatType &formatType);
168 ColorCopyFunction GetFastCopyFunction(const FastCopyFunctionMap &fastCopyFunctions,
169                                       const gl::FormatType &formatType);
170 
171 using InitializeTextureDataFunction = void (*)(size_t width,
172                                                size_t height,
173                                                size_t depth,
174                                                uint8_t *output,
175                                                size_t outputRowPitch,
176                                                size_t outputDepthPitch);
177 
178 using LoadImageFunction = void (*)(size_t width,
179                                    size_t height,
180                                    size_t depth,
181                                    const uint8_t *input,
182                                    size_t inputRowPitch,
183                                    size_t inputDepthPitch,
184                                    uint8_t *output,
185                                    size_t outputRowPitch,
186                                    size_t outputDepthPitch);
187 
188 struct LoadImageFunctionInfo
189 {
LoadImageFunctionInfoLoadImageFunctionInfo190     LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {}
LoadImageFunctionInfoLoadImageFunctionInfo191     LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion)
192         : loadFunction(loadFunction), requiresConversion(requiresConversion)
193     {
194     }
195 
196     LoadImageFunction loadFunction;
197     bool requiresConversion;
198 };
199 
200 using LoadFunctionMap = LoadImageFunctionInfo (*)(GLenum);
201 
202 bool ShouldUseDebugLayers(const egl::AttributeMap &attribs);
203 
204 void CopyImageCHROMIUM(const uint8_t *sourceData,
205                        size_t sourceRowPitch,
206                        size_t sourcePixelBytes,
207                        ColorReadFunction readFunction,
208                        uint8_t *destData,
209                        size_t destRowPitch,
210                        size_t destPixelBytes,
211                        ColorWriteFunction colorWriteFunction,
212                        GLenum destUnsizedFormat,
213                        GLenum destComponentType,
214                        size_t width,
215                        size_t height,
216                        bool unpackFlipY,
217                        bool unpackPremultiplyAlpha,
218                        bool unpackUnmultiplyAlpha);
219 
220 // Incomplete textures are 1x1 textures filled with black, used when samplers are incomplete.
221 // This helper class encapsulates handling incomplete textures. Because the GL back-end
222 // can take advantage of the driver's incomplete textures, and because clearing multisample
223 // textures is so difficult, we can keep an instance of this class in the back-end instead
224 // of moving the logic to the Context front-end.
225 
226 // This interface allows us to call-back to init a multisample texture.
227 class MultisampleTextureInitializer
228 {
229   public:
~MultisampleTextureInitializer()230     virtual ~MultisampleTextureInitializer() {}
231     virtual gl::Error initializeMultisampleTextureToBlack(const gl::Context *context,
232                                                           gl::Texture *glTexture) = 0;
233 };
234 
235 class IncompleteTextureSet final : angle::NonCopyable
236 {
237   public:
238     IncompleteTextureSet();
239     ~IncompleteTextureSet();
240 
241     void onDestroy(const gl::Context *context);
242 
243     gl::Error getIncompleteTexture(const gl::Context *context,
244                                    GLenum type,
245                                    MultisampleTextureInitializer *multisampleInitializer,
246                                    gl::Texture **textureOut);
247 
248   private:
249     gl::TextureMap mIncompleteTextures;
250 };
251 
252 }  // namespace rx
253 
254 #endif  // LIBANGLE_RENDERER_RENDERER_UTILS_H_
255