diff --git a/CMakeLists.txt b/CMakeLists.txt index 88d3682e..50ad511a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,8 @@ set(SOURCE_FILES MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp MobileGL/MG_Util/ShaderTranspiler/SpvcSession.cpp + MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp + MobileGL/MG_Impl/GLXImpl/Exporting/Definitions.cpp MobileGL/MG_Impl/GLXImpl/LookUp/LookUp.cpp @@ -160,8 +162,12 @@ if (ANDROID) log) endif() +if (NOT ANDROID) + set(BUILD_TEST ON CACHE BOOL "Build the tests") set(BUILD_BENCHMARK ON CACHE BOOL "Build the benchmarks") add_subdirectory(MobileGL/MG_Test) add_subdirectory(MobileGL/MG_Benchmark) + +endif() \ No newline at end of file diff --git a/MobileGL/Defines.h b/MobileGL/Defines.h index ad70346f..48272aaf 100644 --- a/MobileGL/Defines.h +++ b/MobileGL/Defines.h @@ -2,6 +2,7 @@ // ============== Platform-specific definitions and macros ============== // #ifdef __ANDROID__ +#undef __ANDROID_API__ #define __ANDROID_API__ 26 // force Android API level to 26 for compatibility #endif diff --git a/MobileGL/Init.cpp b/MobileGL/Init.cpp index 64a6d8a7..21f66623 100644 --- a/MobileGL/Init.cpp +++ b/MobileGL/Init.cpp @@ -1,12 +1,18 @@ #include "Includes.h" #include +#include namespace MobileGL { void MG_Initialize() { MG_Util::Debug::InitFile(); - MGLOG_I("MobileGL Initializing..."); + MGLOG_I("Initializing MobileGL..."); + MG_State::Init(); + MGLOG_D("MobileGL State initialized"); MG_Backend::Init(); + MGLOG_D("MobileGL Backend initialized"); glslang::InitializeProcess(); + MGLOG_D("glslang initialized"); + MGLOG_I("MobileGL Initialized"); } void MG_Destroy() { diff --git a/MobileGL/MG_Backend/Backends.h b/MobileGL/MG_Backend/Backends.h index dd79f7d4..a6ed6eb0 100644 --- a/MobileGL/MG_Backend/Backends.h +++ b/MobileGL/MG_Backend/Backends.h @@ -6,7 +6,7 @@ namespace MobileGL { namespace MG_Backend { namespace Unknown { - const RendererInfo RendererInfoUnknown = { + inline RendererInfo RendererInfoUnknown = { .RendererName = "", // Renderer Name .BackendName = "", // Backend Name .ExtraVendor = ", ", // Extra vendor @@ -28,7 +28,7 @@ namespace MobileGL { Metal }; - const RendererInfo RendererInfoVulkan = { + inline RendererInfo RendererInfoVulkan = { .RendererName = "MG-DE-Vulkan", // Renderer Name .BackendName = "Diligent Engine (Vulkan)", // Backend Name .ExtraVendor = Nullopt, // Extra vendor @@ -44,7 +44,7 @@ namespace MobileGL { .BackendCapability = {} // Backend Capability }; - const RendererInfo RendererInfoMetal = { + inline RendererInfo RendererInfoMetal = { .RendererName = "MG-DE-Metal", // Renderer Name .BackendName = "Diligent Engine (Metal)", // Backend Name .ExtraVendor = Nullopt, // Extra vendor @@ -62,7 +62,7 @@ namespace MobileGL { } // namespace Diligent namespace DirectGLES { - const RendererInfo RendererInfo = { + inline RendererInfo RendererInfo = { .RendererName = "Espryt", // Renderer Name .BackendName = "Direct (OpenGL ES)", // Backend Name .ExtraVendor = Nullopt, // Extra vendor diff --git a/MobileGL/MG_Backend/Init.cpp b/MobileGL/MG_Backend/Init.cpp index 7b47d862..1aeb25ae 100644 --- a/MobileGL/MG_Backend/Init.cpp +++ b/MobileGL/MG_Backend/Init.cpp @@ -1,5 +1,7 @@ #include "Backends.h" #include +#include +#include namespace MobileGL { namespace MG_Config { @@ -7,25 +9,68 @@ namespace MobileGL { } namespace MG_Backend { + static RendererInfo RendererInfo; + + void LogBackendInfo() { + if (MG_Config::RendererInfoPtr) { + MGLOG_I("MobileGL Backend Info:"); + MGLOG_I(" Renderer Name: %s", MG_Config::RendererInfoPtr->RendererName.c_str()); + MGLOG_I(" Backend Name: %s", MG_Config::RendererInfoPtr->BackendName.c_str()); + if (MG_Config::RendererInfoPtr->ExtraVendor) { + MGLOG_I(" Extra Vendor Info: %s", MG_Config::RendererInfoPtr->ExtraVendor->c_str()); + } + MGLOG_I(" Target OpenGL Version: %d.%d", + MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLVersion.Major, + MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLVersion.Minor); + MGLOG_I(" Target GLSL Version: %d.%d", + MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLSLVersion.Major, + MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLSLVersion.Minor); + MGLOG_I(" OpenGL Extensions:"); + for (const auto& ext : MG_Config::RendererInfoPtr->RendererGLInfo.Extensions) { + MGLOG_I(" - %s", MG_Util::ConvertetGLExtToString(ext).c_str()); + } + } else { + MGLOG_W(" No renderer info available"); + } + } + + void InitSpecificBackendLibs() { +#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_DILIGENT + // Nothing to do + MGLOG_D("Diligent Engine backend loaded"); +#elif MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES + MG_Util::BackendLoader::GLES::Init(); + MGLOG_D("DirectGLES backend loaded, GLES version: %d.%d", MG_External::GLES::Caps::GLESVersion.Major, + MG_External::GLES::Caps::GLESVersion.Minor); +#else + MGLOG_W("Unknown backend, skipping backend initialization"); +#endif + } + void Init() { MGLOG_D("Initializing MobileGL Backend..."); #if MOBILEGL_BACKEND == MOBILEGL_BACKEND_DILIGENT switch (MG_Config::Backend::Diligent::SpecificBackend) { case MG_Backend::Diligent::SpecificBackendType::Vulkan: - MG_Config::RendererInfoPtr = (RendererInfo*)&MG_Backend::Diligent::RendererInfoVulkan; + RendererInfo = MG_Backend::Diligent::RendererInfoVulkan; break; case MG_Backend::Diligent::SpecificBackendType::Metal: - MG_Config::RendererInfoPtr = (RendererInfo*)&MG_Backend::Diligent::RendererInfoMetal; + RendererInfo = MG_Backend::Diligent::RendererInfoMetal; break; default: throw RuntimeError("Unsupported renderer type"); } #elif MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Config::RendererInfoPtr = (RendererInfo*)&MG_Backend::DirectGLES::RendererInfo; + RendererInfo = MG_Backend::DirectGLES::RendererInfo; #else - MG_Config::RendererInfoPtr = (RendererInfo*)&RendererInfoUnknown; + RendererInfo = RendererInfoUnknown; #endif + + MG_Config::RendererInfoPtr = &RendererInfo; + + InitSpecificBackendLibs(); + LogBackendInfo(); } } // namespace MG_Backend } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.cpp b/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.cpp new file mode 100644 index 00000000..2b2aa6cd --- /dev/null +++ b/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.cpp @@ -0,0 +1,117 @@ +#include "EGLWrapper.h" + +namespace MobileGL { + namespace MG_Impl::EGLImpl { + // TODO: implement complete EGL functionality + + EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, + const EGLint* attrib_list) { + return (EGLSurface)1; + } + + EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, + EGLint* num_config) { + *num_config = 1; + return EGL_TRUE; + } + + EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx, const EGLint* attrib_list) { + return (EGLContext)1; + } + + EGLBoolean Initialize(EGLDisplay dpy, EGLint* major, EGLint* minor) { + if (major) *major = 1; + if (minor) *minor = 5; + return EGL_TRUE; + } + + EGLDisplay GetDisplay(NativeDisplayType display) { + return (EGLDisplay)1; + } + + EGLint GetError() { + return EGL_SUCCESS; + } + + EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { + return EGL_TRUE; + } + + EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx) { + return EGL_TRUE; + } + + EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface) { + return EGL_TRUE; + } + + EGLBoolean Terminate(EGLDisplay dpy) { + return EGL_TRUE; + } + + EGLBoolean ReleaseThread(void) { + return EGL_TRUE; + } + + EGLContext GetCurrentContext(void) { + return (EGLContext)1; + } + + EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) { + if (attribute == EGL_NATIVE_VISUAL_ID) { +#if defined(ANDROID) + *value = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; + return EGL_TRUE; +#elif defined(__linux__) + *value = 0; + return EGL_TRUE; +#elif defined(_WIN32) + *value = 0; + return EGL_TRUE; +#else + *value = 0; + return EGL_FALSE; +#endif + } + return EGL_TRUE; + } + + EGLBoolean BindAPI(EGLenum api) { + return EGL_TRUE; + } + + EGLSurface GetCurrentSurface(EGLint readdraw) { + return (EGLSurface)1; + } + + EGLBoolean QuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint* value) { + return EGL_TRUE; + } + + EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval) { + return EGL_TRUE; + } + + EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface draw) { + return EGL_TRUE; + } + + EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) { + return (EGLSurface)1; + } + + __eglMustCastToProperFunctionPointerType GetProcAddress(const char* name) { + MGLOG_D("eglGetProcAddress(%s)", name); +#if !defined(WIN32) && !defined(__APPLE__) + void* proc = dlsym(RTLD_DEFAULT, (const char*)name); +#else + void* proc = NULL; +#endif + if (!proc) { + MGLOG_W("Failed to get function: %s", (const char*)name); + return nullptr; + } + return (__eglMustCastToProperFunctionPointerType)proc; + } + } // namespace MG_Impl::EGLImpl +} // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.h b/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.h new file mode 100644 index 00000000..3f3cae4f --- /dev/null +++ b/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.h @@ -0,0 +1,2 @@ +#pragma once +#include \ No newline at end of file diff --git a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp index 4c479e55..e7687982 100644 --- a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp +++ b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp @@ -1,8 +1,8 @@ #include "GL_Getter.h" #include #include -#include #include +#include #include namespace MobileGL { diff --git a/MobileGL/MG_State/GLState/Core.cpp b/MobileGL/MG_State/GLState/Core.cpp index 8480cc12..991639f5 100644 --- a/MobileGL/MG_State/GLState/Core.cpp +++ b/MobileGL/MG_State/GLState/Core.cpp @@ -2,6 +2,11 @@ namespace MobileGL { namespace MG_State { + void Init() { + MGLOG_D("Initializing MobileGL State..."); + pGLContext = new MG_State::GLState::GLContext(); + } + namespace GLState { // Error void GLContext::RecordError(ErrorCode code, SharedPtr info) { diff --git a/MobileGL/MG_State/GLState/Core.h b/MobileGL/MG_State/GLState/Core.h index efc0fb49..3facafea 100644 --- a/MobileGL/MG_State/GLState/Core.h +++ b/MobileGL/MG_State/GLState/Core.h @@ -11,6 +11,8 @@ namespace MobileGL { namespace MG_State { + void Init(); + namespace GLState { class GLContext { public: diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp index bfbc90a4..4b94d4c4 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp @@ -1,6 +1,7 @@ #include "Loader.h" #define GL_FUNC_DECL(name) name##_PTR name; +#define EGL_FUNC_DECL(name) name##_PTR name; namespace MobileGL { namespace MG_External { @@ -379,21 +380,61 @@ namespace MobileGL { GL_FUNC_DECL(glBruh) } // namespace GLES + + namespace EGL { + EGL_FUNC_DECL(eglBindAPI) + EGL_FUNC_DECL(eglBindTexImage) + EGL_FUNC_DECL(eglChooseConfig) + EGL_FUNC_DECL(eglCopyBuffers) + EGL_FUNC_DECL(eglCreateContext) + EGL_FUNC_DECL(eglCreatePbufferFromClientBuffer) + EGL_FUNC_DECL(eglCreatePbufferSurface) + EGL_FUNC_DECL(eglCreatePixmapSurface) + EGL_FUNC_DECL(eglCreatePlatformWindowSurface) + EGL_FUNC_DECL(eglCreateWindowSurface) + EGL_FUNC_DECL(eglDestroyContext) + EGL_FUNC_DECL(eglDestroySurface) + EGL_FUNC_DECL(eglGetConfigAttrib) + EGL_FUNC_DECL(eglGetConfigs) + EGL_FUNC_DECL(eglGetCurrentContext) + EGL_FUNC_DECL(eglGetCurrentDisplay) + EGL_FUNC_DECL(eglGetCurrentSurface) + EGL_FUNC_DECL(eglGetDisplay) + EGL_FUNC_DECL(eglGetPlatformDisplay) + EGL_FUNC_DECL(eglGetError) + EGL_FUNC_DECL(eglGetProcAddress) + EGL_FUNC_DECL(eglInitialize) + EGL_FUNC_DECL(eglMakeCurrent) + EGL_FUNC_DECL(eglQueryAPI) + EGL_FUNC_DECL(eglQueryContext) + EGL_FUNC_DECL(eglQueryString) + EGL_FUNC_DECL(eglQuerySurface) + EGL_FUNC_DECL(eglReleaseTexImage) + EGL_FUNC_DECL(eglReleaseThread) + EGL_FUNC_DECL(eglSurfaceAttrib) + EGL_FUNC_DECL(eglSwapBuffers) + EGL_FUNC_DECL(eglSwapBuffersWithDamageEXT) + EGL_FUNC_DECL(eglSwapInterval) + EGL_FUNC_DECL(eglTerminate) + EGL_FUNC_DECL(eglUnlockSurfaceKHR) + EGL_FUNC_DECL(eglWaitClient) + EGL_FUNC_DECL(eglWaitGL) + EGL_FUNC_DECL(eglWaitNative) + } // namespace EGL } // namespace MG_External #undef GL_FUNC_DECL +#undef EGL_FUNC_DECL namespace MG_Util { - namespace BackendLoader { - void Init() { - GLES::LoadLibs(); - GLES::InitEGL(); - GLES::InitGLES(); - GLES::DestroyTempEGLCtx(); - } - } // namespace BackendLoader - namespace BackendLoader::GLES { + void Init() { + LoadLibs(); + InitEGL(); + InitGLES(); + DestroyTempEGLCtx(); + } + void *libGLES = nullptr, *libEGL = nullptr; static const char* LibPathPrefixes[] = {"", "/opt/vc/lib/", "/usr/local/lib/", "/usr/lib/", nullptr}; @@ -818,25 +859,25 @@ namespace MobileGL { static EGLSurface eglSurface = EGL_NO_SURFACE; static EGLContext eglContext = EGL_NO_CONTEXT; -#define LOAD_EGL(name) \ +#define INIT_EGL_FUNC(name) \ if (libEGL != NULL) { \ MG_External::EGL::name = (MG_External::EGL::name##_PTR)ProcAddress(libEGL, #name); \ } void InitEGL() { - LOAD_EGL(eglGetProcAddress) - LOAD_EGL(eglBindAPI) - LOAD_EGL(eglInitialize) - LOAD_EGL(eglGetDisplay) - LOAD_EGL(eglCreatePbufferSurface) - LOAD_EGL(eglDestroySurface) - LOAD_EGL(eglDestroyContext) - LOAD_EGL(eglMakeCurrent) - LOAD_EGL(eglChooseConfig) - LOAD_EGL(eglCreateContext) - LOAD_EGL(eglQueryString) - LOAD_EGL(eglTerminate) - LOAD_EGL(eglGetError) + INIT_EGL_FUNC(eglGetProcAddress) + INIT_EGL_FUNC(eglBindAPI) + INIT_EGL_FUNC(eglInitialize) + INIT_EGL_FUNC(eglGetDisplay) + INIT_EGL_FUNC(eglCreatePbufferSurface) + INIT_EGL_FUNC(eglDestroySurface) + INIT_EGL_FUNC(eglDestroyContext) + INIT_EGL_FUNC(eglMakeCurrent) + INIT_EGL_FUNC(eglChooseConfig) + INIT_EGL_FUNC(eglCreateContext) + INIT_EGL_FUNC(eglQueryString) + INIT_EGL_FUNC(eglTerminate) + INIT_EGL_FUNC(eglGetError) EGLint configAttribs[] = {EGL_RED_SIZE, 8, @@ -917,10 +958,10 @@ namespace MobileGL { } void DestroyTempEGLCtx() { - LOAD_EGL(eglDestroySurface) - LOAD_EGL(eglDestroyContext) - LOAD_EGL(eglMakeCurrent) - LOAD_EGL(eglTerminate) + INIT_EGL_FUNC(eglDestroySurface) + INIT_EGL_FUNC(eglDestroyContext) + INIT_EGL_FUNC(eglMakeCurrent) + INIT_EGL_FUNC(eglTerminate) MG_External::EGL::eglMakeCurrent(eglDisplay, 0, 0, EGL_NO_CONTEXT); MG_External::EGL::eglDestroySurface(eglDisplay, eglSurface); diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h index 8b8364b2..b5f1a929 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h @@ -927,9 +927,8 @@ namespace MobileGL { namespace MG_Util { namespace BackendLoader { - void Init(); - namespace GLES { + void Init(); extern void *libGLES, *libEGL; void* ProcAddress(void* lib, const char* name);