• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "common/utilities.h"
20 #include "libANGLE/angletypes.h"
21 
22 namespace angle
23 {
24 struct FeatureSetBase;
25 struct Format;
26 enum class FormatID;
27 }  // namespace angle
28 
29 namespace gl
30 {
31 struct FormatType;
32 struct InternalFormat;
33 class State;
34 }  // namespace gl
35 
36 namespace egl
37 {
38 class AttributeMap;
39 struct DisplayState;
40 }  // namespace egl
41 
42 namespace rx
43 {
44 class ContextImpl;
45 
46 // The possible rotations of the surface/draw framebuffer, particularly for the Vulkan back-end on
47 // Android.
48 enum class SurfaceRotation
49 {
50     Identity,
51     Rotated90Degrees,
52     Rotated180Degrees,
53     Rotated270Degrees,
54     FlippedIdentity,
55     FlippedRotated90Degrees,
56     FlippedRotated180Degrees,
57     FlippedRotated270Degrees,
58 
59     InvalidEnum,
60     EnumCount = InvalidEnum,
61 };
62 
63 void RotateRectangle(const SurfaceRotation rotation,
64                      const bool flipY,
65                      const int framebufferWidth,
66                      const int framebufferHeight,
67                      const gl::Rectangle &incoming,
68                      gl::Rectangle *outgoing);
69 
70 using MipGenerationFunction = void (*)(size_t sourceWidth,
71                                        size_t sourceHeight,
72                                        size_t sourceDepth,
73                                        const uint8_t *sourceData,
74                                        size_t sourceRowPitch,
75                                        size_t sourceDepthPitch,
76                                        uint8_t *destData,
77                                        size_t destRowPitch,
78                                        size_t destDepthPitch);
79 
80 typedef void (*PixelReadFunction)(const uint8_t *source, uint8_t *dest);
81 typedef void (*PixelWriteFunction)(const uint8_t *source, uint8_t *dest);
82 typedef void (*PixelCopyFunction)(const uint8_t *source, uint8_t *dest);
83 
84 class FastCopyFunctionMap
85 {
86   public:
87     struct Entry
88     {
89         angle::FormatID formatID;
90         PixelCopyFunction func;
91     };
92 
FastCopyFunctionMap()93     constexpr FastCopyFunctionMap() : FastCopyFunctionMap(nullptr, 0) {}
94 
FastCopyFunctionMap(const Entry * data,size_t size)95     constexpr FastCopyFunctionMap(const Entry *data, size_t size) : mSize(size), mData(data) {}
96 
97     bool has(angle::FormatID formatID) const;
98     PixelCopyFunction get(angle::FormatID formatID) const;
99 
100   private:
101     size_t mSize;
102     const Entry *mData;
103 };
104 
105 struct PackPixelsParams
106 {
107     PackPixelsParams();
108     PackPixelsParams(const gl::Rectangle &area,
109                      const angle::Format &destFormat,
110                      GLuint outputPitch,
111                      bool reverseRowOrderIn,
112                      gl::Buffer *packBufferIn,
113                      ptrdiff_t offset);
114 
115     gl::Rectangle area;
116     const angle::Format *destFormat;
117     GLuint outputPitch;
118     gl::Buffer *packBuffer;
119     bool reverseRowOrder;
120     ptrdiff_t offset;
121     SurfaceRotation rotation;
122 };
123 
124 void PackPixels(const PackPixelsParams &params,
125                 const angle::Format &sourceFormat,
126                 int inputPitch,
127                 const uint8_t *source,
128                 uint8_t *destination);
129 
130 using InitializeTextureDataFunction = void (*)(size_t width,
131                                                size_t height,
132                                                size_t depth,
133                                                uint8_t *output,
134                                                size_t outputRowPitch,
135                                                size_t outputDepthPitch);
136 
137 using LoadImageFunction = void (*)(size_t width,
138                                    size_t height,
139                                    size_t depth,
140                                    const uint8_t *input,
141                                    size_t inputRowPitch,
142                                    size_t inputDepthPitch,
143                                    uint8_t *output,
144                                    size_t outputRowPitch,
145                                    size_t outputDepthPitch);
146 
147 struct LoadImageFunctionInfo
148 {
LoadImageFunctionInfoLoadImageFunctionInfo149     LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {}
LoadImageFunctionInfoLoadImageFunctionInfo150     LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion)
151         : loadFunction(loadFunction), requiresConversion(requiresConversion)
152     {}
153 
154     LoadImageFunction loadFunction;
155     bool requiresConversion;
156 };
157 
158 using LoadFunctionMap = LoadImageFunctionInfo (*)(GLenum);
159 
160 bool ShouldUseDebugLayers(const egl::AttributeMap &attribs);
161 bool ShouldUseVirtualizedContexts(const egl::AttributeMap &attribs, bool defaultValue);
162 
163 void CopyImageCHROMIUM(const uint8_t *sourceData,
164                        size_t sourceRowPitch,
165                        size_t sourcePixelBytes,
166                        size_t sourceDepthPitch,
167                        PixelReadFunction pixelReadFunction,
168                        uint8_t *destData,
169                        size_t destRowPitch,
170                        size_t destPixelBytes,
171                        size_t destDepthPitch,
172                        PixelWriteFunction pixelWriteFunction,
173                        GLenum destUnsizedFormat,
174                        GLenum destComponentType,
175                        size_t width,
176                        size_t height,
177                        size_t depth,
178                        bool unpackFlipY,
179                        bool unpackPremultiplyAlpha,
180                        bool unpackUnmultiplyAlpha);
181 
182 // Incomplete textures are 1x1 textures filled with black, used when samplers are incomplete.
183 // This helper class encapsulates handling incomplete textures. Because the GL back-end
184 // can take advantage of the driver's incomplete textures, and because clearing multisample
185 // textures is so difficult, we can keep an instance of this class in the back-end instead
186 // of moving the logic to the Context front-end.
187 
188 // This interface allows us to call-back to init a multisample texture.
189 class MultisampleTextureInitializer
190 {
191   public:
~MultisampleTextureInitializer()192     virtual ~MultisampleTextureInitializer() {}
193     virtual angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
194                                                               gl::Texture *glTexture) = 0;
195 };
196 
197 class IncompleteTextureSet final : angle::NonCopyable
198 {
199   public:
200     IncompleteTextureSet();
201     ~IncompleteTextureSet();
202 
203     void onDestroy(const gl::Context *context);
204 
205     angle::Result getIncompleteTexture(const gl::Context *context,
206                                        gl::TextureType type,
207                                        MultisampleTextureInitializer *multisampleInitializer,
208                                        gl::Texture **textureOut);
209 
210   private:
211     gl::TextureMap mIncompleteTextures;
212 };
213 
214 // Helpers to set a matrix uniform value based on GLSL or HLSL semantics.
215 // The return value indicate if the data was updated or not.
216 template <int cols, int rows>
217 struct SetFloatUniformMatrixGLSL
218 {
219     static void Run(unsigned int arrayElementOffset,
220                     unsigned int elementCount,
221                     GLsizei countIn,
222                     GLboolean transpose,
223                     const GLfloat *value,
224                     uint8_t *targetData);
225 };
226 
227 template <int cols, int rows>
228 struct SetFloatUniformMatrixHLSL
229 {
230     static void Run(unsigned int arrayElementOffset,
231                     unsigned int elementCount,
232                     GLsizei countIn,
233                     GLboolean transpose,
234                     const GLfloat *value,
235                     uint8_t *targetData);
236 };
237 
238 // Helper method to de-tranpose a matrix uniform for an API query.
239 void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose);
240 
241 template <typename NonFloatT>
242 void GetMatrixUniform(GLenum type, NonFloatT *dataOut, const NonFloatT *source, bool transpose);
243 
244 const angle::Format &GetFormatFromFormatType(GLenum format, GLenum type);
245 
246 angle::Result ComputeStartVertex(ContextImpl *contextImpl,
247                                  const gl::IndexRange &indexRange,
248                                  GLint baseVertex,
249                                  GLint *firstVertexOut);
250 
251 angle::Result GetVertexRangeInfo(const gl::Context *context,
252                                  GLint firstVertex,
253                                  GLsizei vertexOrIndexCount,
254                                  gl::DrawElementsType indexTypeOrInvalid,
255                                  const void *indices,
256                                  GLint baseVertex,
257                                  GLint *startVertexOut,
258                                  size_t *vertexCountOut);
259 
260 gl::Rectangle ClipRectToScissor(const gl::State &glState, const gl::Rectangle &rect, bool invertY);
261 
262 // Helper method to intialize a FeatureSet with overrides from the DisplayState
263 void ApplyFeatureOverrides(angle::FeatureSetBase *features, const egl::DisplayState &state);
264 
265 template <typename In>
LineLoopRestartIndexCountHelper(GLsizei indexCount,const uint8_t * srcPtr)266 uint32_t LineLoopRestartIndexCountHelper(GLsizei indexCount, const uint8_t *srcPtr)
267 {
268     constexpr In restartIndex = gl::GetPrimitiveRestartIndexFromType<In>();
269     const In *inIndices       = reinterpret_cast<const In *>(srcPtr);
270     uint32_t numIndices       = 0;
271     // See CopyLineLoopIndicesWithRestart() below for more info on how
272     // numIndices is calculated.
273     GLsizei loopStartIndex = 0;
274     for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
275     {
276         In vertex = inIndices[curIndex];
277         if (vertex != restartIndex)
278         {
279             numIndices++;
280         }
281         else
282         {
283             if (curIndex > loopStartIndex)
284             {
285                 numIndices += 2;
286             }
287             loopStartIndex = curIndex + 1;
288         }
289     }
290     if (indexCount > loopStartIndex)
291     {
292         numIndices++;
293     }
294     return numIndices;
295 }
296 
GetLineLoopWithRestartIndexCount(gl::DrawElementsType glIndexType,GLsizei indexCount,const uint8_t * srcPtr)297 inline uint32_t GetLineLoopWithRestartIndexCount(gl::DrawElementsType glIndexType,
298                                                  GLsizei indexCount,
299                                                  const uint8_t *srcPtr)
300 {
301     switch (glIndexType)
302     {
303         case gl::DrawElementsType::UnsignedByte:
304             return LineLoopRestartIndexCountHelper<uint8_t>(indexCount, srcPtr);
305         case gl::DrawElementsType::UnsignedShort:
306             return LineLoopRestartIndexCountHelper<uint16_t>(indexCount, srcPtr);
307         case gl::DrawElementsType::UnsignedInt:
308             return LineLoopRestartIndexCountHelper<uint32_t>(indexCount, srcPtr);
309         default:
310             UNREACHABLE();
311             return 0;
312     }
313 }
314 
315 // Writes the line-strip vertices for a line loop to outPtr,
316 // where outLimit is calculated as in GetPrimitiveRestartIndexCount.
317 template <typename In, typename Out>
CopyLineLoopIndicesWithRestart(GLsizei indexCount,const uint8_t * srcPtr,uint8_t * outPtr)318 void CopyLineLoopIndicesWithRestart(GLsizei indexCount, const uint8_t *srcPtr, uint8_t *outPtr)
319 {
320     constexpr In restartIndex     = gl::GetPrimitiveRestartIndexFromType<In>();
321     constexpr Out outRestartIndex = gl::GetPrimitiveRestartIndexFromType<Out>();
322     const In *inIndices           = reinterpret_cast<const In *>(srcPtr);
323     Out *outIndices               = reinterpret_cast<Out *>(outPtr);
324     GLsizei loopStartIndex        = 0;
325     for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
326     {
327         In vertex = inIndices[curIndex];
328         if (vertex != restartIndex)
329         {
330             *(outIndices++) = static_cast<Out>(vertex);
331         }
332         else
333         {
334             if (curIndex > loopStartIndex)
335             {
336                 // Emit an extra vertex only if the loop is not empty.
337                 *(outIndices++) = inIndices[loopStartIndex];
338                 // Then restart the strip.
339                 *(outIndices++) = outRestartIndex;
340             }
341             loopStartIndex = curIndex + 1;
342         }
343     }
344     if (indexCount > loopStartIndex)
345     {
346         // Close the last loop if not empty.
347         *(outIndices++) = inIndices[loopStartIndex];
348     }
349 }
350 
351 void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy);
352 }  // namespace rx
353 
354 #endif  // LIBANGLE_RENDERER_RENDERER_UTILS_H_
355