From 518be23db2605a81f5e0e5e89a76f87a2ce831c2 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Sun, 23 Jun 2024 19:54:35 +0900 Subject: [PATCH] gl_engine: revise the gl portability - guarantee minimum gl version requirement - removed glesv2 dependency - corrected gl ver dependency issue: https://github.com/thorvg/thorvg/issues/2282 --- README.md | 2 +- examples/Example.h | 19 ++++---- examples/meson.build | 4 ++ meson.build | 3 ++ src/renderer/gl_engine/meson.build | 58 +++++++++++------------- src/renderer/gl_engine/tvgGlCommon.h | 9 +++- src/renderer/gl_engine/tvgGlRenderer.cpp | 14 +++++- src/renderer/gl_engine/tvgGlShader.cpp | 2 +- 8 files changed, 63 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 4d6ce6ab..8b17f5e3 100644 --- a/README.md +++ b/README.md @@ -494,7 +494,7 @@ meson setup builddir -Dbindings="capi" ## Dependencies ThorVG offers versatile support for image loading, accommodating both static and external loaders. This flexibility ensures that, even in environments without external libraries, users can still leverage static loaders as a reliable alternative. At its foundation, the ThorVG core library is engineered to function autonomously, free from external dependencies. However, it is important to note that ThorVG also encompasses a range of optional feature extensions, each with its specific set of dependencies. The dependencies associated with these selective features are outlined as follows: -* GL engine: [GLESv2/GLESv3](https://www.khronos.org/opengles/) +* GL engine: [OpenGL v3.3](https://www.khronos.org/opengl/) or [GLES v3.0](https://www.khronos.org/opengles/) * WG engine: [webgpu-native](https://github.com/gfx-rs/wgpu-native) * External PNG support: [libpng](https://github.com/glennrp/libpng) * External JPG support: [turbojpeg](https://github.com/libjpeg-turbo/libjpeg-turbo) diff --git a/examples/Example.h b/examples/Example.h index 4f9ba5a8..a407b6f0 100644 --- a/examples/Example.h +++ b/examples/Example.h @@ -319,19 +319,16 @@ struct GlWindow : Window GlWindow(Example* example, uint32_t width, uint32_t height) : Window(tvg::CanvasEngine::Gl, example, width, height) { +#ifdef THORVG_GL_TARGET_GLES + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); - window = SDL_CreateWindow("ThorVG Example (OpenGLES)", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE); - - if (window == nullptr) { - // try create OpenGLES context failed, create OpenGL context instead - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - window = SDL_CreateWindow("ThorVG Example (OpenGL)", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE); - } - +#else + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); +#endif + window = SDL_CreateWindow("ThorVG Example (OpenGL/ES)", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE); context = SDL_GL_CreateContext(window); } diff --git a/examples/meson.build b/examples/meson.build index 8fc1ed4b..79f7cbc8 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -2,6 +2,10 @@ if (lib_type == 'static') compiler_flags += ['-DTVG_STATIC'] endif +if target_opengles + compiler_flags += '-DTHORVG_GL_TARGET_GLES=1' +endif + examples_dep = [dependency('sdl2')] if (get_option('engines').contains('wg_beta')) diff --git a/meson.build b/meson.build index 7f0b51da..9778d26d 100644 --- a/meson.build +++ b/meson.build @@ -144,6 +144,9 @@ configure_file( headers = [include_directories('inc'), include_directories('.')] +#OpenGL profile: OpenGLES(true) or OpenGL(false), confirmed by gl_engine +target_opengles = false + subdir('inc') subdir('src') subdir('tools') diff --git a/src/renderer/gl_engine/meson.build b/src/renderer/gl_engine/meson.build index 37f65873..7341f82b 100644 --- a/src/renderer/gl_engine/meson.build +++ b/src/renderer/gl_engine/meson.build @@ -21,42 +21,36 @@ source_file = [ 'tvgGlTessellator.h', ] -#find a gl library with fallbacks -gles_dep = meson.get_compiler('cpp').find_library('GLESv3', required: false) - -if not gles_dep.found() - gles_dep = dependency('GLESv3', required: false) -endif - -if not gles_dep.found() - gles_dep = meson.get_compiler('cpp').find_library('GLESv2', required: false) -endif - -if not gles_dep.found() - gles_dep = dependency('GLESv2', required: false) -endif - -link_opengl = false - -if not gles_dep.found() - gles_dep = dependency('GL') - link_opengl = true -endif - -if not gles_dep.found() - gles_dep = meson.get_compiler('cpp').find_library('GL') - link_opengl = true -endif - -if link_opengl - gl_target_define = '-DTHORVG_GL_TARGET_GL=1' +if host_machine.system() == 'darwin' + gl_dep = declare_dependency(link_args: ['-framework', 'OpenGL']) else - gl_target_define = '-DTHORVG_GL_TARGET_GLES=1' + #find a opengl library with fallbacks + gl_dep = dependency('GL', required: false) + + if not gl_dep.found() + gl_dep = meson.get_compiler('cpp').find_library('GL', required: false) + endif + + if not gl_dep.found() + gl_dep = dependency('GLESv3', required: false) + target_opengles = true + endif + + if not gl_dep.found() + gl_dep = meson.get_compiler('cpp').find_library('GLESv3') + target_opengles = true + endif +endif + +if target_opengles + gl_target_profile = '-DTHORVG_GL_TARGET_GLES=1' +else + gl_target_profile = '-DTHORVG_GL_TARGET_GL=1' endif engine_dep += [declare_dependency( - compile_args : gl_target_define, - dependencies : gles_dep, + compile_args : gl_target_profile, + dependencies : gl_dep, include_directories : include_directories('.'), sources : source_file, )] diff --git a/src/renderer/gl_engine/tvgGlCommon.h b/src/renderer/gl_engine/tvgGlCommon.h index d760abe5..55632f3d 100644 --- a/src/renderer/gl_engine/tvgGlCommon.h +++ b/src/renderer/gl_engine/tvgGlCommon.h @@ -26,12 +26,17 @@ #include #if defined (THORVG_GL_TARGET_GLES) #include -#elif defined (THORVG_GL_TARGET_GL) + #define TVG_REQUIRE_GL_MAJOR_VER 3 + #define TVG_REQUIRE_GL_MINOR_VER 0 +#else #if defined(__APPLE__) || defined(__MACH__) #include #else - #include + #define GL_GLEXT_PROTOTYPES 1 + #include #endif + #define TVG_REQUIRE_GL_MAJOR_VER 3 + #define TVG_REQUIRE_GL_MINOR_VER 3 #endif #include "tvgCommon.h" #include "tvgRender.h" diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index fd1b9c4e..27e278dd 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -491,7 +491,7 @@ int GlRenderer::init(uint32_t threads) { if ((initEngineCnt++) > 0) return true; - //TODO: + //TODO: runtime linking? return true; } @@ -517,13 +517,25 @@ int GlRenderer::term() GlRenderer* GlRenderer::gen() { + //TODO: GL minimum version check, should be replaced with the runtime linking in GlRenderer::init() + GLint vMajor, vMinor; + glGetIntegerv(GL_MAJOR_VERSION, &vMajor); + glGetIntegerv(GL_MINOR_VERSION, &vMinor); + if (vMajor < TVG_REQUIRE_GL_MAJOR_VER || (vMajor == TVG_REQUIRE_GL_MAJOR_VER && vMinor < TVG_REQUIRE_GL_MINOR_VER)) { + TVGERR("GL_ENGINE", "OpenGL/ES version is not statisfied. Current: v%d.%d, Required: v%d.%d", vMajor, vMinor, TVG_REQUIRE_GL_MAJOR_VER, TVG_REQUIRE_GL_MINOR_VER); + return nullptr; + } + TVGLOG("GL_ENGINE", "OpenGL/ES version = v%d.%d", vMajor, vMinor); + return new GlRenderer(); } + GlRenderer::GlRenderer() :mGpuBuffer(new GlStageBuffer), mPrograms(), mComposePool() { } + GlRenderer::~GlRenderer() { for (uint32_t i = 0; i < mComposePool.count; i++) { diff --git a/src/renderer/gl_engine/tvgGlShader.cpp b/src/renderer/gl_engine/tvgGlShader.cpp index 6f13e2b5..b2c6c635 100644 --- a/src/renderer/gl_engine/tvgGlShader.cpp +++ b/src/renderer/gl_engine/tvgGlShader.cpp @@ -76,7 +76,7 @@ uint32_t GlShader::complileShader(uint32_t type, char* shaderSrc) // but in general All Desktop GPU should use OpenGL version ( #version 330 core ) #if defined (THORVG_GL_TARGET_GLES) shaderPack[0] ="#version 300 es\n"; -#elif defined (THORVG_GL_TARGET_GL) +#else shaderPack[0] ="#version 330 core\n"; #endif shaderPack[1] = "precision highp float;\n precision mediump int;\n";