Path: blob/main_old/src/tests/test_utils/gl_raii.h
1693 views
//1// Copyright 2016 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// gl_raii:6// Helper methods for containing GL objects like buffers and textures.78#ifndef ANGLE_TESTS_GL_RAII_H_9#define ANGLE_TESTS_GL_RAII_H_1011#include <functional>1213#include "util/shader_utils.h"1415namespace angle16{1718// This is a bit of hack to work around a bug in MSVS intellisense, and make it very easy to19// use the correct function pointer type without worrying about the various definitions of20// GL_APICALL.21using GLGen = decltype(glGenBuffers);22using GLDelete = decltype(glDeleteBuffers);2324class GLWrapper : angle::NonCopyable25{26public:27GLWrapper(GLGen *genFunc, GLDelete *deleteFunc) : mGenFunc(genFunc), mDeleteFunc(deleteFunc) {}28~GLWrapper()29{30if (mHandle)31{32(*mDeleteFunc)(1, &mHandle);33}34}3536// The move-constructor and move-assignment operators are necessary so that the data within a37// GLWrapper object can be relocated.38GLWrapper(GLWrapper &&rht)39: mGenFunc(rht.mGenFunc), mDeleteFunc(rht.mDeleteFunc), mHandle(rht.mHandle)40{41rht.mHandle = 0u;42}43GLWrapper &operator=(GLWrapper &&rht)44{45if (this != &rht)46{47mGenFunc = rht.mGenFunc;48mDeleteFunc = rht.mDeleteFunc;49std::swap(mHandle, rht.mHandle);50}51return *this;52}5354void reset()55{56if (mHandle != 0u)57{58(*mDeleteFunc)(1, &mHandle);59mHandle = 0u;60}61}6263GLuint get()64{65if (!mHandle)66{67(*mGenFunc)(1, &mHandle);68}69return mHandle;70}7172operator GLuint() { return get(); }7374private:75GLGen *mGenFunc;76GLDelete *mDeleteFunc;77GLuint mHandle = 0u;78};7980class GLVertexArray : public GLWrapper81{82public:83GLVertexArray() : GLWrapper(&glGenVertexArrays, &glDeleteVertexArrays) {}84};85class GLBuffer : public GLWrapper86{87public:88GLBuffer() : GLWrapper(&glGenBuffers, &glDeleteBuffers) {}89};90class GLTexture : public GLWrapper91{92public:93GLTexture() : GLWrapper(&glGenTextures, &glDeleteTextures) {}94};95class GLFramebuffer : public GLWrapper96{97public:98GLFramebuffer() : GLWrapper(&glGenFramebuffers, &glDeleteFramebuffers) {}99};100class GLMemoryObject : public GLWrapper101{102public:103GLMemoryObject() : GLWrapper(&glCreateMemoryObjectsEXT, &glDeleteMemoryObjectsEXT) {}104};105class GLRenderbuffer : public GLWrapper106{107public:108GLRenderbuffer() : GLWrapper(&glGenRenderbuffers, &glDeleteRenderbuffers) {}109};110class GLSampler : public GLWrapper111{112public:113GLSampler() : GLWrapper(&glGenSamplers, &glDeleteSamplers) {}114};115class GLSemaphore : public GLWrapper116{117public:118GLSemaphore() : GLWrapper(&glGenSemaphoresEXT, &glDeleteSemaphoresEXT) {}119};120class GLTransformFeedback : public GLWrapper121{122public:123GLTransformFeedback() : GLWrapper(&glGenTransformFeedbacks, &glDeleteTransformFeedbacks) {}124};125class GLProgramPipeline : public GLWrapper126{127public:128GLProgramPipeline() : GLWrapper(&glGenProgramPipelines, &glDeleteProgramPipelines) {}129};130class GLQueryEXT : public GLWrapper131{132public:133GLQueryEXT() : GLWrapper(&glGenQueriesEXT, &glDeleteQueriesEXT) {}134};135using GLQuery = GLQueryEXT;136137class GLShader : angle::NonCopyable138{139public:140GLShader() = delete;141explicit GLShader(GLenum shaderType) { mHandle = glCreateShader(shaderType); }142143~GLShader() { glDeleteShader(mHandle); }144145GLuint get() { return mHandle; }146147operator GLuint() { return get(); }148149void reset()150{151if (mHandle)152{153glDeleteShader(mHandle);154mHandle = 0;155}156}157158private:159GLuint mHandle;160};161162// Prefer ANGLE_GL_PROGRAM for local variables.163class GLProgram164{165public:166GLProgram() : mHandle(0) {}167168~GLProgram() { reset(); }169170void makeEmpty() { mHandle = glCreateProgram(); }171172void makeCompute(const char *computeShader) { mHandle = CompileComputeProgram(computeShader); }173174void makeRaster(const char *vertexShader, const char *fragmentShader)175{176mHandle = CompileProgram(vertexShader, fragmentShader);177}178179void makeRaster(const char *vertexShader,180const char *geometryShader,181const char *fragmentShader)182{183mHandle = CompileProgramWithGS(vertexShader, geometryShader, fragmentShader);184}185186void makeRaster(const char *vertexShader,187const char *tessControlShader,188const char *tessEvaluateShader,189const char *fragmentShader)190{191mHandle = CompileProgramWithTESS(vertexShader, tessControlShader, tessEvaluateShader,192fragmentShader);193}194195void makeRasterWithTransformFeedback(const char *vertexShader,196const char *fragmentShader,197const std::vector<std::string> &tfVaryings,198GLenum bufferMode)199{200mHandle = CompileProgramWithTransformFeedback(vertexShader, fragmentShader, tfVaryings,201bufferMode);202}203204void makeBinaryOES(const std::vector<uint8_t> &binary, GLenum binaryFormat)205{206mHandle = LoadBinaryProgramOES(binary, binaryFormat);207}208209void makeBinaryES3(const std::vector<uint8_t> &binary, GLenum binaryFormat)210{211mHandle = LoadBinaryProgramES3(binary, binaryFormat);212}213214bool valid() const { return mHandle != 0; }215216GLuint get()217{218if (!mHandle)219{220makeEmpty();221}222return mHandle;223}224225void reset()226{227if (mHandle)228{229glDeleteProgram(mHandle);230mHandle = 0;231}232}233234operator GLuint() { return get(); }235236private:237GLuint mHandle;238};239240#define ANGLE_GL_EMPTY_PROGRAM(name) \241GLProgram name; \242name.makeEmpty(); \243ASSERT_TRUE(name.valid())244245#define ANGLE_GL_PROGRAM(name, vertex, fragment) \246GLProgram name; \247name.makeRaster(vertex, fragment); \248ASSERT_TRUE(name.valid())249250#define ANGLE_GL_PROGRAM_WITH_GS(name, vertex, geometry, fragment) \251GLProgram name; \252name.makeRaster(vertex, geometry, fragment); \253ASSERT_TRUE(name.valid())254255#define ANGLE_GL_PROGRAM_WITH_TESS(name, vertex, tcs, tes, fragment) \256GLProgram name; \257name.makeRaster(vertex, tcs, tes, fragment); \258ASSERT_TRUE(name.valid())259260#define ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(name, vertex, fragment, tfVaryings, bufferMode) \261GLProgram name; \262name.makeRasterWithTransformFeedback(vertex, fragment, tfVaryings, bufferMode); \263ASSERT_TRUE(name.valid())264265#define ANGLE_GL_COMPUTE_PROGRAM(name, compute) \266GLProgram name; \267name.makeCompute(compute); \268ASSERT_TRUE(name.valid())269270#define ANGLE_GL_BINARY_OES_PROGRAM(name, binary, binaryFormat) \271GLProgram name; \272name.makeBinaryOES(binary, binaryFormat); \273ASSERT_TRUE(name.valid())274275#define ANGLE_GL_BINARY_ES3_PROGRAM(name, binary, binaryFormat) \276GLProgram name; \277name.makeBinaryES3(binary, binaryFormat); \278ASSERT_TRUE(name.valid())279280} // namespace angle281282#endif // ANGLE_TESTS_GL_RAII_H_283284285