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