• 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 // gl_raii:
7 //   Helper methods for containing GL objects like buffers and textures.
8 
9 #ifndef ANGLE_TESTS_GL_RAII_H_
10 #define ANGLE_TESTS_GL_RAII_H_
11 
12 #include <functional>
13 
14 #include "util/shader_utils.h"
15 
16 namespace angle
17 {
18 
19 // This is a bit of hack to work around a bug in MSVS intellisense, and make it very easy to
20 // use the correct function pointer type without worrying about the various definitions of
21 // GL_APICALL.
22 using GLGen    = decltype(glGenBuffers);
23 using GLDelete = decltype(glDeleteBuffers);
24 
25 class GLWrapper : angle::NonCopyable
26 {
27   public:
GLWrapper(GLGen * genFunc,GLDelete * deleteFunc)28     GLWrapper(GLGen *genFunc, GLDelete *deleteFunc) : mGenFunc(genFunc), mDeleteFunc(deleteFunc) {}
~GLWrapper()29     ~GLWrapper()
30     {
31         if (mHandle)
32         {
33             (*mDeleteFunc)(1, &mHandle);
34         }
35     }
36 
37     // The move-constructor and move-assignment operators are necessary so that the data within a
38     // GLWrapper object can be relocated.
GLWrapper(GLWrapper && rht)39     GLWrapper(GLWrapper &&rht)
40         : mGenFunc(rht.mGenFunc), mDeleteFunc(rht.mDeleteFunc), mHandle(rht.mHandle)
41     {
42         rht.mHandle = 0u;
43     }
44     GLWrapper &operator=(GLWrapper &&rht)
45     {
46         if (this != &rht)
47         {
48             mGenFunc    = rht.mGenFunc;
49             mDeleteFunc = rht.mDeleteFunc;
50             std::swap(mHandle, rht.mHandle);
51         }
52         return *this;
53     }
54 
reset()55     void reset()
56     {
57         if (mHandle != 0u)
58         {
59             (*mDeleteFunc)(1, &mHandle);
60             mHandle = 0u;
61         }
62     }
63 
get()64     GLuint get()
65     {
66         if (!mHandle)
67         {
68             (*mGenFunc)(1, &mHandle);
69         }
70         return mHandle;
71     }
72 
GLuint()73     operator GLuint() { return get(); }
74 
75   private:
76     GLGen *mGenFunc;
77     GLDelete *mDeleteFunc;
78     GLuint mHandle = 0u;
79 };
80 
81 class GLVertexArray : public GLWrapper
82 {
83   public:
GLVertexArray()84     GLVertexArray() : GLWrapper(&glGenVertexArrays, &glDeleteVertexArrays) {}
85 };
86 class GLBuffer : public GLWrapper
87 {
88   public:
GLBuffer()89     GLBuffer() : GLWrapper(&glGenBuffers, &glDeleteBuffers) {}
90 };
91 class GLTexture : public GLWrapper
92 {
93   public:
GLTexture()94     GLTexture() : GLWrapper(&glGenTextures, &glDeleteTextures) {}
95 };
96 class GLFramebuffer : public GLWrapper
97 {
98   public:
GLFramebuffer()99     GLFramebuffer() : GLWrapper(&glGenFramebuffers, &glDeleteFramebuffers) {}
100 };
101 class GLMemoryObject : public GLWrapper
102 {
103   public:
GLMemoryObject()104     GLMemoryObject() : GLWrapper(&glCreateMemoryObjectsEXT, &glDeleteMemoryObjectsEXT) {}
105 };
106 class GLRenderbuffer : public GLWrapper
107 {
108   public:
GLRenderbuffer()109     GLRenderbuffer() : GLWrapper(&glGenRenderbuffers, &glDeleteRenderbuffers) {}
110 };
111 class GLSampler : public GLWrapper
112 {
113   public:
GLSampler()114     GLSampler() : GLWrapper(&glGenSamplers, &glDeleteSamplers) {}
115 };
116 class GLSemaphore : public GLWrapper
117 {
118   public:
GLSemaphore()119     GLSemaphore() : GLWrapper(&glGenSemaphoresEXT, &glDeleteSemaphoresEXT) {}
120 };
121 class GLTransformFeedback : public GLWrapper
122 {
123   public:
GLTransformFeedback()124     GLTransformFeedback() : GLWrapper(&glGenTransformFeedbacks, &glDeleteTransformFeedbacks) {}
125 };
126 class GLProgramPipeline : public GLWrapper
127 {
128   public:
GLProgramPipeline()129     GLProgramPipeline() : GLWrapper(&glGenProgramPipelines, &glDeleteProgramPipelines) {}
130 };
131 class GLQueryEXT : public GLWrapper
132 {
133   public:
GLQueryEXT()134     GLQueryEXT() : GLWrapper(&glGenQueriesEXT, &glDeleteQueriesEXT) {}
135 };
136 
137 class GLShader : angle::NonCopyable
138 {
139   public:
140     GLShader() = delete;
GLShader(GLenum shaderType)141     explicit GLShader(GLenum shaderType) { mHandle = glCreateShader(shaderType); }
142 
~GLShader()143     ~GLShader() { glDeleteShader(mHandle); }
144 
get()145     GLuint get() { return mHandle; }
146 
GLuint()147     operator GLuint() { return get(); }
148 
149   private:
150     GLuint mHandle;
151 };
152 
153 // Prefer ANGLE_GL_PROGRAM for local variables.
154 class GLProgram
155 {
156   public:
GLProgram()157     GLProgram() : mHandle(0) {}
158 
~GLProgram()159     ~GLProgram()
160     {
161         if (mHandle)
162         {
163             glDeleteProgram(mHandle);
164         }
165     }
166 
makeEmpty()167     void makeEmpty() { mHandle = glCreateProgram(); }
168 
makeCompute(const char * computeShader)169     void makeCompute(const char *computeShader) { mHandle = CompileComputeProgram(computeShader); }
170 
makeRaster(const char * vertexShader,const char * fragmentShader)171     void makeRaster(const char *vertexShader, const char *fragmentShader)
172     {
173         mHandle = CompileProgram(vertexShader, fragmentShader);
174     }
175 
makeRaster(const char * vertexShader,const char * geometryShader,const char * fragmentShader)176     void makeRaster(const char *vertexShader,
177                     const char *geometryShader,
178                     const char *fragmentShader)
179     {
180         mHandle = CompileProgramWithGS(vertexShader, geometryShader, fragmentShader);
181     }
182 
makeRasterWithTransformFeedback(const char * vertexShader,const char * fragmentShader,const std::vector<std::string> & tfVaryings,GLenum bufferMode)183     void makeRasterWithTransformFeedback(const char *vertexShader,
184                                          const char *fragmentShader,
185                                          const std::vector<std::string> &tfVaryings,
186                                          GLenum bufferMode)
187     {
188         mHandle = CompileProgramWithTransformFeedback(vertexShader, fragmentShader, tfVaryings,
189                                                       bufferMode);
190     }
191 
makeBinaryOES(const std::vector<uint8_t> & binary,GLenum binaryFormat)192     void makeBinaryOES(const std::vector<uint8_t> &binary, GLenum binaryFormat)
193     {
194         mHandle = LoadBinaryProgramOES(binary, binaryFormat);
195     }
196 
makeBinaryES3(const std::vector<uint8_t> & binary,GLenum binaryFormat)197     void makeBinaryES3(const std::vector<uint8_t> &binary, GLenum binaryFormat)
198     {
199         mHandle = LoadBinaryProgramES3(binary, binaryFormat);
200     }
201 
valid()202     bool valid() const { return mHandle != 0; }
203 
get()204     GLuint get() { return mHandle; }
205 
GLuint()206     operator GLuint() { return get(); }
207 
208   private:
209     GLuint mHandle;
210 };
211 
212 #define ANGLE_GL_EMPTY_PROGRAM(name) \
213     GLProgram name;                  \
214     name.makeEmpty();                \
215     ASSERT_TRUE(name.valid())
216 
217 #define ANGLE_GL_PROGRAM(name, vertex, fragment) \
218     GLProgram name;                              \
219     name.makeRaster(vertex, fragment);           \
220     ASSERT_TRUE(name.valid())
221 
222 #define ANGLE_GL_PROGRAM_WITH_GS(name, vertex, geometry, fragment) \
223     GLProgram name;                                                \
224     name.makeRaster(vertex, geometry, fragment);                   \
225     ASSERT_TRUE(name.valid())
226 
227 #define ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(name, vertex, fragment, tfVaryings, bufferMode) \
228     GLProgram name;                                                                         \
229     name.makeRasterWithTransformFeedback(vertex, fragment, tfVaryings, bufferMode);         \
230     ASSERT_TRUE(name.valid())
231 
232 #define ANGLE_GL_COMPUTE_PROGRAM(name, compute) \
233     GLProgram name;                             \
234     name.makeCompute(compute);                  \
235     ASSERT_TRUE(name.valid())
236 
237 #define ANGLE_GL_BINARY_OES_PROGRAM(name, binary, binaryFormat) \
238     GLProgram name;                                             \
239     name.makeBinaryOES(binary, binaryFormat);                   \
240     ASSERT_TRUE(name.valid())
241 
242 #define ANGLE_GL_BINARY_ES3_PROGRAM(name, binary, binaryFormat) \
243     GLProgram name;                                             \
244     name.makeBinaryES3(binary, binaryFormat);                   \
245     ASSERT_TRUE(name.valid())
246 
247 }  // namespace angle
248 
249 #endif  // ANGLE_TESTS_GL_RAII_H_
250