mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
153 lines
4.3 KiB
C++
153 lines
4.3 KiB
C++
#include "glproc.hpp"
|
|
|
|
#if defined(__has_include)
|
|
#if __has_include(<GLES3/gl3.h>)
|
|
#include <GLES3/gl3.h>
|
|
#elif __has_include(<GLES3/gl32.h>)
|
|
#include <GLES3/gl32.h>
|
|
#else
|
|
#error "OpenGL ES 3 headers are required"
|
|
#endif
|
|
#else
|
|
#include <GLES3/gl3.h>
|
|
#endif
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <dlfcn.h>
|
|
|
|
void *_libGlHandle = nullptr;
|
|
|
|
namespace {
|
|
|
|
void *LookupSymbol(const char *procName);
|
|
|
|
void *GetMobileGlHandle() {
|
|
if (_libGlHandle != nullptr) {
|
|
return _libGlHandle;
|
|
}
|
|
|
|
const char *library = std::getenv("MOBILEGL_TRACE_LIBRARY");
|
|
if (library != nullptr && library[0] != '\0') {
|
|
_libGlHandle = dlopen(library, RTLD_NOW | RTLD_GLOBAL | RTLD_NOLOAD);
|
|
if (_libGlHandle == nullptr) {
|
|
_libGlHandle = dlopen(library, RTLD_NOW | RTLD_GLOBAL);
|
|
}
|
|
}
|
|
if (_libGlHandle == nullptr) {
|
|
_libGlHandle = dlopen("libMobileGL.so", RTLD_NOW | RTLD_GLOBAL | RTLD_NOLOAD);
|
|
}
|
|
if (_libGlHandle == nullptr) {
|
|
_libGlHandle = dlopen("libMobileGL.so", RTLD_NOW | RTLD_GLOBAL);
|
|
}
|
|
return _libGlHandle;
|
|
}
|
|
|
|
using GlReadBuffer = void (*)(GLenum mode);
|
|
using GlReadPixels = void (*)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
|
void *pixels);
|
|
using GlGetIntegerv = void (*)(GLenum pname, GLint *data);
|
|
using GlGetError = GLenum (*)();
|
|
GlReadBuffer gRealGlReadBuffer = nullptr;
|
|
GlReadPixels gRealGlReadPixels = nullptr;
|
|
GlGetIntegerv gRealGlGetIntegerv = nullptr;
|
|
GlGetError gRealGlGetError = nullptr;
|
|
int gSuppressInvalidEnumCount = 0;
|
|
|
|
void MobileGLTraceReadBuffer(GLenum mode) {
|
|
if (mode == GL_BACK) {
|
|
++gSuppressInvalidEnumCount;
|
|
return;
|
|
}
|
|
if (gRealGlReadBuffer == nullptr) {
|
|
gRealGlReadBuffer = reinterpret_cast<GlReadBuffer>(LookupSymbol("glReadBuffer"));
|
|
}
|
|
if (gRealGlReadBuffer != nullptr) {
|
|
gRealGlReadBuffer(mode);
|
|
}
|
|
}
|
|
|
|
void MobileGLTraceReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
|
void *pixels) {
|
|
if (gRealGlReadPixels == nullptr) {
|
|
gRealGlReadPixels = reinterpret_cast<GlReadPixels>(LookupSymbol("glReadPixels"));
|
|
}
|
|
if (gRealGlReadPixels != nullptr) {
|
|
gRealGlReadPixels(x, y, width, height, format, type, pixels);
|
|
}
|
|
}
|
|
|
|
void MobileGLTraceGetIntegerv(GLenum pname, GLint *data) {
|
|
if (pname == GL_READ_BUFFER) {
|
|
if (data != nullptr) {
|
|
*data = GL_BACK;
|
|
}
|
|
++gSuppressInvalidEnumCount;
|
|
return;
|
|
}
|
|
if (gRealGlGetIntegerv == nullptr) {
|
|
gRealGlGetIntegerv = reinterpret_cast<GlGetIntegerv>(LookupSymbol("glGetIntegerv"));
|
|
}
|
|
if (gRealGlGetIntegerv != nullptr) {
|
|
gRealGlGetIntegerv(pname, data);
|
|
}
|
|
}
|
|
|
|
GLenum MobileGLTraceGetError() {
|
|
if (gRealGlGetError == nullptr) {
|
|
gRealGlGetError = reinterpret_cast<GlGetError>(LookupSymbol("glGetError"));
|
|
}
|
|
if (gRealGlGetError == nullptr) {
|
|
return GL_NO_ERROR;
|
|
}
|
|
GLenum error = gRealGlGetError();
|
|
if (error == GL_INVALID_ENUM && gSuppressInvalidEnumCount > 0) {
|
|
--gSuppressInvalidEnumCount;
|
|
return GL_NO_ERROR;
|
|
}
|
|
return error;
|
|
}
|
|
|
|
void *LookupSymbol(const char *procName) {
|
|
void *mobileGl = GetMobileGlHandle();
|
|
if (mobileGl != nullptr) {
|
|
void *proc = dlsym(mobileGl, procName);
|
|
if (proc != nullptr) {
|
|
return proc;
|
|
}
|
|
}
|
|
|
|
return dlsym(RTLD_DEFAULT, procName);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void *_getPublicProcAddress(const char *procName) {
|
|
if (strcmp(procName, "glReadPixels") == 0) {
|
|
return reinterpret_cast<void *>(&MobileGLTraceReadPixels);
|
|
}
|
|
if (strcmp(procName, "glReadBuffer") == 0) {
|
|
return reinterpret_cast<void *>(&MobileGLTraceReadBuffer);
|
|
}
|
|
if (strcmp(procName, "glGetIntegerv") == 0) {
|
|
return reinterpret_cast<void *>(&MobileGLTraceGetIntegerv);
|
|
}
|
|
if (strcmp(procName, "glGetError") == 0) {
|
|
return reinterpret_cast<void *>(&MobileGLTraceGetError);
|
|
}
|
|
return LookupSymbol(procName);
|
|
}
|
|
|
|
void *_getPrivateProcAddress(const char *procName) {
|
|
void *proc = LookupSymbol(procName);
|
|
if (proc != nullptr) {
|
|
return proc;
|
|
}
|
|
|
|
if (_eglGetProcAddress != nullptr) {
|
|
return reinterpret_cast<void *>(_eglGetProcAddress(procName));
|
|
}
|
|
|
|
return nullptr;
|
|
}
|