[Feat|Perf] (*/BufferState): Improve dirty mark for Buffer.

This commit is contained in:
BZLZHH
2026-02-02 02:25:41 +08:00
parent 91650e29c5
commit 0cf9d9223d
41 changed files with 908 additions and 678 deletions
@@ -88,7 +88,7 @@ namespace MobileGL {
return MG_External::EGL::eglQuerySurface(display, surface, attribute, value);
}
char const * QueryString(EGLDisplay display, EGLint name) {
char const* QueryString(EGLDisplay display, EGLint name) {
return MG_External::EGL::eglQueryString(display, name);
}
@@ -122,7 +122,7 @@ namespace MobileGL {
}
EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap,
const EGLint* attrib_list) {
const EGLint* attrib_list) {
return MG_External::EGL::eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
}
@@ -170,51 +170,45 @@ namespace MobileGL {
return (__eglMustCastToProperFunctionPointerType)proc;
}
EGLSync CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib * attrib_list) {
EGLSync CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list) {
return MG_External::EGL::eglCreateSync(dpy, type, attrib_list);
}
EGLBoolean DestroySync(EGLDisplay dpy, EGLSync sync) {
return MG_External::EGL::eglDestroySync(dpy, sync);
}
EGLint ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) {
return MG_External::EGL::eglClientWaitSync(dpy, sync, flags, timeout);
}
EGLBoolean GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib * value) {
EGLBoolean GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value) {
return MG_External::EGL::eglGetSyncAttrib(dpy, sync, attribute, value);
}
EGLImage CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list) {
EGLImage CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer,
const EGLAttrib* attrib_list) {
return MG_External::EGL::eglCreateImage(dpy, ctx, target, buffer, attrib_list);
}
EGLBoolean DestroyImage(EGLDisplay dpy, EGLImage image) {
return MG_External::EGL::eglDestroyImage(dpy, image);
}
EGLDisplay GetPlatformDisplay(EGLenum platform, void * native_display, const EGLAttrib * attrib_list) {
EGLDisplay GetPlatformDisplay(EGLenum platform, void* native_display, const EGLAttrib* attrib_list) {
return MG_External::EGL::eglGetPlatformDisplay(platform, native_display, attrib_list);
}
EGLSurface CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list) {
EGLSurface CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void* native_window,
const EGLAttrib* attrib_list) {
return MG_External::EGL::eglCreatePlatformWindowSurface(dpy, config, native_window, attrib_list);
}
EGLSurface CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLAttrib * attrib_list) {
EGLSurface CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void* native_pixmap,
const EGLAttrib* attrib_list) {
return MG_External::EGL::eglCreatePlatformPixmapSurface(dpy, config, native_pixmap, attrib_list);
}
EGLBoolean WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) {
return MG_External::EGL::eglWaitSync(dpy, sync, flags);
}
@@ -98,7 +98,7 @@ namespace MobileGL {
return EGL_TRUE;
}
char const * QueryString(EGLDisplay display, EGLint name) {
char const* QueryString(EGLDisplay display, EGLint name) {
return "";
}
@@ -132,7 +132,7 @@ namespace MobileGL {
}
EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap,
const EGLint* attrib_list) {
const EGLint* attrib_list) {
return (EGLSurface)1;
}
@@ -29,7 +29,7 @@ namespace MobileGL {
EGLBoolean BindAPI(EGLenum api);
EGLSurface GetCurrentSurface(EGLint readdraw);
EGLBoolean QuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint* value);
char const * QueryString(EGLDisplay display, EGLint name);
char const* QueryString(EGLDisplay display, EGLint name);
EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval);
EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface draw);
EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list);
@@ -39,7 +39,7 @@ namespace MobileGL {
EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
EGLConfig config, const EGLint* attrib_list);
EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap,
const EGLint* attrib_list);
const EGLint* attrib_list);
EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config);
EGLDisplay GetCurrentDisplay(void);
EGLenum QueryAPI(void);
@@ -49,15 +49,18 @@ namespace MobileGL {
EGLBoolean WaitGL(void);
EGLBoolean WaitNative(EGLint engine);
__eglMustCastToProperFunctionPointerType GetProcAddress(const char* name);
EGLSync CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib * attrib_list);
EGLSync CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list);
EGLBoolean DestroySync(EGLDisplay dpy, EGLSync sync);
EGLint ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
EGLBoolean GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib * value);
EGLImage CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list);
EGLBoolean GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value);
EGLImage CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer,
const EGLAttrib* attrib_list);
EGLBoolean DestroyImage(EGLDisplay dpy, EGLImage image);
EGLDisplay GetPlatformDisplay(EGLenum platform, void * native_display, const EGLAttrib * attrib_list);
EGLSurface CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list);
EGLSurface CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLAttrib * attrib_list);
EGLDisplay GetPlatformDisplay(EGLenum platform, void* native_display, const EGLAttrib* attrib_list);
EGLSurface CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void* native_window,
const EGLAttrib* attrib_list);
EGLSurface CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void* native_pixmap,
const EGLAttrib* attrib_list);
EGLBoolean WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags);
} // namespace MG_Impl::EGLImpl
} // namespace MobileGL
+2 -2
View File
@@ -525,8 +525,7 @@ namespace MobileGL {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(bufferTarget, pointIndex);
point.Bind(bufferObject);
point.SetRange(Range1D(0, bufferObject->GetSize()));
MGLOG_D("%s: set range (0, %d)", __func__,
bufferObject->GetSize());
MGLOG_D("%s: set range (0, %d)", __func__, bufferObject->GetSize());
}
void BindBufferRange_State(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
@@ -575,6 +574,7 @@ namespace MobileGL {
return MapBuffer_State(target, access);
}
// FIXME: this should be a "backend" function
void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset,
GLsizeiptr size) {
CopyBufferSubData_State(readTarget, writeTarget, readOffset, writeOffset, size);
+12 -6
View File
@@ -12,16 +12,22 @@
namespace MobileGL {
namespace MG_Impl::GLImpl {
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */
void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride);
void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount,
GLsizei stride);
void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride);
void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices, GLint basevertex);
void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
const void* indices, GLint basevertex);
void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices);
void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
void DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLint basevertex);
void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLuint baseinstance);
void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLint basevertex, GLuint baseinstance);
void DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLint basevertex);
void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLuint baseinstance);
void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount);
void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect);
void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount,
GLuint baseinstance);
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
void DrawArraysIndirect(GLenum mode, const void* indirect);
void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex);
@@ -516,15 +516,15 @@ namespace MobileGL {
void Uniform_State(MG_State::GLState::ProgramObject& programObject, GLuint location, T* value,
SizeT byteOffsetInsideUniform = 0) {
if (!programObject.IsUniformOpaqueAtLocation(location)) {
MGLOG_D("%s: program = %d, location = %d, maxLocation = %d", __func__,
programObject.GetExternalIndex(), location, programObject.GetMaxUniformLocation());
MGLOG_D("%s: program = %d, location = %d, maxLocation = %d", __func__, programObject.GetExternalIndex(),
location, programObject.GetMaxUniformLocation());
auto size = programObject.GetUniformSizesInBytes(location);
auto offset = programObject.GetUniformOffset(location);
MOBILEGL_ASSERT(size >= ItemCount * sizeof(T),
"Uniform size mismatch, expected at least %zu bytes, got %zu bytes.",
ItemCount * sizeof(T), size);
MGLOG_D("%s: program = %d, location = %d, byteOffset = %d", __func__,
programObject.GetExternalIndex(), location, offset + byteOffsetInsideUniform);
MGLOG_D("%s: program = %d, location = %d, byteOffset = %d", __func__, programObject.GetExternalIndex(),
location, offset + byteOffsetInsideUniform);
Memcpy((char*)programObject.MapUBO() + offset + byteOffsetInsideUniform, value, ItemCount * sizeof(T));
} else {
auto* ttype = programObject.GetUniformTType(location);
+25 -24
View File
@@ -63,8 +63,7 @@ namespace MobileGL {
// TextureInternalFormat textureInternalFormat =
// MG_Util::ConvertGLEnumToTextureInternalFormat(format);
MGLOG_D("TexSubImage2D_State: target = %s, level = %d, (%d, %d), format = %s, pixels = %p",
MG_Util::ConvertGLEnumToString(target).c_str(), level,
width, height,
MG_Util::ConvertGLEnumToString(target).c_str(), level, width, height,
MG_Util::ConvertTextureInputFormatToString(textureInputFormat).c_str(), pixels);
// ===================== Error Checking ==============================
if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) return;
@@ -502,14 +501,18 @@ namespace MobileGL {
GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) {
MGLOG_D(
"%s called with target: %s, level: %d, internalformat: %s, width: %d, height: %d, depth: %d, "
"border: %d, format: %s, type: %s (%u), pixels: %p", __func__,
MG_Util::ConvertTextureUploadTargetToString(MG_Util::ConvertGLEnumToTextureUploadTarget(target)).c_str(),
"border: %d, format: %s, type: %s (%u), pixels: %p",
__func__,
MG_Util::ConvertTextureUploadTargetToString(MG_Util::ConvertGLEnumToTextureUploadTarget(target))
.c_str(),
level,
MG_Util::ConvertTextureInternalFormatToString(
MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat)).c_str(),
MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat))
.c_str(),
width, height, depth, border,
MG_Util::ConvertTextureInputFormatToString(MG_Util::ConvertGLEnumToTextureInputFormat(format)).c_str(),
MG_Util::ConvertTexturePixelDataTypeToString(MG_Util::ConvertGLEnumToTexturePixelDataType(type)).c_str(),
MG_Util::ConvertTexturePixelDataTypeToString(MG_Util::ConvertGLEnumToTexturePixelDataType(type))
.c_str(),
type, pixels);
// ======================= Converting ================================
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
@@ -580,13 +583,13 @@ namespace MobileGL {
reinterpret_cast<SizeT>(pixels);
}
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get()),
"Texture object here should always be an object with mipmap");
auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
// Allocate in TextureObject
textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, depth}, internalBytes});
textureMipmapObject->AllocateStorage(textureUploadingTarget, level,
{{width, height, depth}, internalBytes});
if (!originalPixels) {
MGLOG_D("%s: No input pixel and no PBO bound, no pixel transfer", __func__);
@@ -601,8 +604,8 @@ namespace MobileGL {
if (processedPixels && imageSize > 0) {
if (imageSize != internalBytes) {
MGLOG_W("%s: Processed pixel data size (%zu) does not match expected size (%zu). "
"This may indicate an alignment or processing issue.", __func__,
imageSize, internalBytes);
"This may indicate an alignment or processing issue.",
__func__, imageSize, internalBytes);
}
const SizeT copySize = std::min(imageSize, internalBytes);
@@ -623,20 +626,16 @@ namespace MobileGL {
TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format);
TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type);
TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
MGLOG_D(
"%s called with target: %s (%s), level: %d, internalformat: %s (%s), width: %d, height: %d, "
"border: %d, format: %s (%s), type: %s (%s), pixels: %p", __func__,
MG_Util::ConvertTextureUploadTargetToString(textureUploadingTarget).c_str(),
MG_Util::ConvertGLEnumToString(target).c_str(),
level,
MGLOG_D("%s called with target: %s (%s), level: %d, internalformat: %s (%s), width: %d, height: %d, "
"border: %d, format: %s (%s), type: %s (%s), pixels: %p",
__func__, MG_Util::ConvertTextureUploadTargetToString(textureUploadingTarget).c_str(),
MG_Util::ConvertGLEnumToString(target).c_str(), level,
MG_Util::ConvertTextureInternalFormatToString(textureInternalFormat).c_str(),
MG_Util::ConvertGLEnumToString(internalformat).c_str(),
width, height, border,
MG_Util::ConvertGLEnumToString(internalformat).c_str(), width, height, border,
MG_Util::ConvertTextureInputFormatToString(textureInputFormat).c_str(),
MG_Util::ConvertGLEnumToString(format).c_str(),
MG_Util::ConvertTexturePixelDataTypeToString(texturePixelDataType).c_str(),
MG_Util::ConvertGLEnumToString(type).c_str(),
pixels);
MG_Util::ConvertGLEnumToString(type).c_str(), pixels);
// ===================== Error Checking ==============================
if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) return;
if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) return;
@@ -661,7 +660,8 @@ namespace MobileGL {
// indicated by type.
// ======================= Processing ================================
textureInternalFormat = MG_Util::ConvertInternalFormatToSized(textureInternalFormat, textureInputFormat, texturePixelDataType);
textureInternalFormat =
MG_Util::ConvertInternalFormatToSized(textureInternalFormat, textureInputFormat, texturePixelDataType);
SharedPtr<MG_State::GLState::ITextureObject> textureObject = nullptr;
Bool isProxy = TextureImpl::IsProxyTextureTarget(textureUploadingTarget);
if (isProxy) {
@@ -1227,11 +1227,12 @@ namespace MobileGL {
}
void CopyTexImage2D_State(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width,
GLsizei height, GLint border) {
GLsizei height, GLint border) {
GLenum outInternalFormat, format, type;
MG_Util::TextureFormatProcessor::NormalizePixelFormat(internalformat, 0, &outInternalFormat, &format, &type);
MG_Util::TextureFormatProcessor::NormalizePixelFormat(internalformat, 0, &outInternalFormat, &format,
&type);
const auto pixelUnpackBufferObject =
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
TexImage2D_State(target, level, outInternalFormat, width, height, border, format, type, nullptr);
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).Bind(pixelUnpackBufferObject);
}
+4 -4
View File
@@ -20,10 +20,10 @@ namespace MobileGL {
const GLvoid* pixels);
void TexParameterf(GLenum target, GLenum pname, GLfloat param);
void TexParameteri(GLenum target, GLenum pname, GLint param);
void TexParameterfv(GLenum target, GLenum pname, const GLfloat * params);
void TexParameteriv(GLenum target, GLenum pname, const GLint * params);
void TexParameterIiv(GLenum target, GLenum pname, const GLint * params);
void TexParameterIuiv(GLenum target, GLenum pname, const GLuint * params);
void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
void TexParameteriv(GLenum target, GLenum pname, const GLint* params);
void TexParameterIiv(GLenum target, GLenum pname, const GLint* params);
void TexParameterIuiv(GLenum target, GLenum pname, const GLuint* params);
void TexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth, GLboolean fixedsamplelocations);
@@ -170,7 +170,8 @@ namespace MobileGL::MG_Impl::GLImpl {
}
return true;
}
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format, TextureInternalFormat internalFormat,
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format,
TextureInternalFormat internalFormat,
TexturePixelDataType type) {
if (type == TexturePixelDataType::UnsignedByte332 || type == TexturePixelDataType::UnsignedByte233Rev ||
type == TexturePixelDataType::UnsignedShort565 || type == TexturePixelDataType::UnsignedShort565Rev ||
@@ -178,7 +179,8 @@ namespace MobileGL::MG_Impl::GLImpl {
if (format != TextureInputFormat::RGB) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInternalFormatCompatibleWithInput",
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"ValidateTextureInternalFormatCompatibleWithInput",
"Invalid format for the given type"));
return false;
}
@@ -193,7 +195,8 @@ namespace MobileGL::MG_Impl::GLImpl {
if (format != TextureInputFormat::RGBA && format != TextureInputFormat::BGRA) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInternalFormatCompatibleWithInput",
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"ValidateTextureInternalFormatCompatibleWithInput",
"Invalid format for the given type"));
return false;
}
@@ -206,7 +209,8 @@ namespace MobileGL::MG_Impl::GLImpl {
if (format != TextureInputFormat::DepthComponent) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInternalFormatCompatibleWithInput",
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"ValidateTextureInternalFormatCompatibleWithInput",
"Invalid format for depth component internal format"));
return false;
}
+2 -1
View File
@@ -23,7 +23,8 @@ namespace MobileGL::MG_Impl::GLImpl {
Bool ValidateTextureSizeRange(SizeT width, SizeT height, SizeT depth);
Bool ValidateTextureInternalFormat(TextureInternalFormat format);
Bool ValidateTextureBorderNumber(Int border);
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format, TextureInternalFormat internalFormat,
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format,
TextureInternalFormat internalFormat,
TexturePixelDataType type);
Bool ValidateTextureLevelWithUploadTarget(TextureUploadTarget target, Int level);
Bool ValidateTextureObject(SharedPtr<MG_State::GLState::ITextureObject> textureObject);
+3 -3
View File
@@ -7,9 +7,9 @@
// End of Source File Header
#include "GetProcAddress.h"
#define GETPROC(name, var) \
if (strcmp(#name, var) == 0) { \
return (void*)name; \
#define GETPROC(name, var) \
if (strcmp(#name, var) == 0) { \
return (void*)name; \
}
namespace MobileGL {