From af1f3cb59d06612a69c4a8eb73b95853f2f5b699 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 5e75a3b5..1c672712 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 0ba25a3c..d1cb1b0d 100644 --- a/examples/Example.h +++ b/examples/Example.h @@ -317,19 +317,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 cd664e70..0025577c 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 a5e575e2..6b67af12 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 b2df83f2..0376957a 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -485,7 +485,7 @@ int GlRenderer::init(uint32_t threads) { if ((initEngineCnt++) > 0) return true; - //TODO: + //TODO: runtime linking? return true; } @@ -511,13 +511,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";