blob: 01a65304bb4766920943dcaff60afd636e1c5d58 [file] [log] [blame]
//
// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// gl_raii:
// Helper methods for containing GL objects like buffers and textures.
#ifndef ANGLE_TESTS_GL_RAII_H_
#define ANGLE_TESTS_GL_RAII_H_
#include <functional>
#include "angle_gl.h"
namespace angle
{
// This is a bit of hack to work around a bug in MSVS intellisense, and make it very easy to
// use the correct function pointer type without worrying about the various definitions of
// GL_APICALL.
using GLGen = decltype(glGenBuffers);
using GLDelete = decltype(glDeleteBuffers);
template <GLGen GenF, GLDelete DeleteF>
class GLWrapper
{
public:
GLWrapper() {}
~GLWrapper() { DeleteF(1, &mHandle); }
GLuint get()
{
if (!mHandle)
{
GenF(1, &mHandle);
}
return mHandle;
}
operator GLuint() { return get(); }
private:
GLuint mHandle = 0;
};
using GLBuffer = GLWrapper<glGenBuffers, glDeleteBuffers>;
using GLTexture = GLWrapper<glGenTextures, glDeleteTextures>;
using GLFramebuffer = GLWrapper<glGenFramebuffers, glDeleteFramebuffers>;
using GLRenderbuffer = GLWrapper<glGenRenderbuffers, glDeleteRenderbuffers>;
using GLSampler = GLWrapper<glGenSamplers, glDeleteSamplers>;
// Don't use GLProgram directly, use ANGLE_GL_PROGRAM.
namespace priv
{
class GLProgram
{
public:
GLProgram() : mHandle(0) {}
~GLProgram() { glDeleteProgram(mHandle); }
void makeCompute(const std::string &computeShader)
{
mHandle = CompileComputeProgram(computeShader);
}
void makeRaster(const std::string &vertexShader, const std::string &fragmentShader)
{
mHandle = CompileProgram(vertexShader, fragmentShader);
}
void makeBinaryOES(const std::vector<uint8_t> &binary, GLenum binaryFormat)
{
mHandle = LoadBinaryProgramOES(binary, binaryFormat);
}
void makeBinaryES3(const std::vector<uint8_t> &binary, GLenum binaryFormat)
{
mHandle = LoadBinaryProgramES3(binary, binaryFormat);
}
bool valid() const { return mHandle != 0; }
GLuint get()
{
ASSERT(valid());
return mHandle;
}
operator GLuint() { return get(); }
private:
GLuint mHandle;
};
} // namespace priv
#define ANGLE_GL_PROGRAM(name, vertex, fragment) \
priv::GLProgram name; \
name.makeRaster(vertex, fragment); \
ASSERT_TRUE(name.valid());
#define ANGLE_GL_COMPUTE_PROGRAM(name, compute) \
priv::GLProgram name; \
name.makeCompute(compute); \
ASSERT_TRUE(name.valid());
#define ANGLE_GL_BINARY_OES_PROGRAM(name, binary, binaryFormat) \
priv::GLProgram name; \
name.makeBinaryOES(binary, binaryFormat); \
ASSERT_TRUE(name.valid());
#define ANGLE_GL_BINARY_ES3_PROGRAM(name, binary, binaryFormat) \
priv::GLProgram name; \
name.makeBinaryES3(binary, binaryFormat); \
ASSERT_TRUE(name.valid());
} // namespace angle
#endif // ANGLE_TESTS_GL_RAII_H_