From c7cbf14e30063e0bb39fda2420332e9a68bf2f2f Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Sat, 1 Apr 2023 10:10:03 -0500 Subject: [PATCH] libglvnd: Fixes and refinements to 1.6.0 based on upstream --- sys-libs/libglvnd/libglvnd-1.6.0.recipe | 49 +- .../libglvnd/patches/libglvnd-1.6.0.patchset | 1204 ++++++++++------- 2 files changed, 780 insertions(+), 473 deletions(-) diff --git a/sys-libs/libglvnd/libglvnd-1.6.0.recipe b/sys-libs/libglvnd/libglvnd-1.6.0.recipe index fc019fd3b..e2cf39a27 100644 --- a/sys-libs/libglvnd/libglvnd-1.6.0.recipe +++ b/sys-libs/libglvnd/libglvnd-1.6.0.recipe @@ -1,12 +1,13 @@ SUMMARY="GL Vendor-Neutral Dispatch Library" DESCRIPTION="libglvnd translates Haiku's OpenGL kit to a modern EGL-based graphics rendering \ pipeline." -HOMEPAGE="http://github.com/NVIDIA/libglvnd" +HOMEPAGE="http://gitlab.freedesktop.org/glvnd/libglvnd" COPYRIGHT="2013, NVIDIA CORPORATION" LICENSE="MIT" -REVISION="1" -SOURCE_URI="https://github.com/NVIDIA/libglvnd/archive/refs/tags/v$portVersion.tar.gz" -CHECKSUM_SHA256="e31dd71441604cf7467397e740af8070caa84133b5ed71241d3d5ca84c950baf" +REVISION="4" +SOURCE_URI="https://gitlab.freedesktop.org/glvnd/libglvnd/-/archive/v$portVersion/libglvnd-v$portVersion.tar.gz" +SOURCE_DIR="libglvnd-v$portVersion" +CHECKSUM_SHA256="efc756ffd24b24059e1c53677a9d57b4b237b00a01c54a6f1611e1e51661d70c" PATCHES="libglvnd-$portVersion.patchset" ARCHITECTURES="?all" @@ -15,7 +16,7 @@ SECONDARY_ARCHITECTURES="?x86_gcc2 ?x86" PROVIDES=" libglvnd$secondaryArchSuffix = $portVersion lib:libGL$secondaryArchSuffix - lib:libegl$secondaryArchSuffix + lib:libEGL$secondaryArchSuffix lib:libglesv1_cm$secondaryArchSuffix lib:libglesv2$secondaryArchSuffix lib:libgldispatch$secondaryArchSuffix @@ -23,12 +24,16 @@ PROVIDES=" " REQUIRES=" haiku$secondaryArchSuffix - lib:libEGL${secondaryArchSuffix} " PROVIDES_devel=" libglvnd${secondaryArchSuffix}_devel = $portVersion devel:libGL$secondaryArchSuffix + devel:libEGL$secondaryArchSuffix + devel:libglesv1_cm$secondaryArchSuffix + devel:libglesv2$secondaryArchSuffix + devel:libgldispatch$secondaryArchSuffix + devel:libopengl$secondaryArchSuffix " REQUIRES_devel=" libglvnd$secondaryArchSuffix == $portVersion base @@ -36,7 +41,6 @@ REQUIRES_devel=" BUILD_REQUIRES=" haiku${secondaryArchSuffix}_devel - devel:libEGL$secondaryArchSuffix " BUILD_PREREQUIRES=" cmd:awk @@ -45,15 +49,16 @@ BUILD_PREREQUIRES=" cmd:meson cmd:ninja cmd:sed + cmd:python3 " BUILD() { meson --buildtype=release \ --prefix=$prefix --libdir=$libDir --datadir=$dataDir --bindir=$binDir\ - --includedir=$includeDir --sysconfdir=$settingsDir --sbindir=$binDir \ + --includedir=$includeDir/os/opengl --sysconfdir=$settingsDir --sbindir=$binDir \ --libexecdir=$libDir --localedir=$dataDir/locale \ - -Dhgl=true ./build + ./build ninja -C build } @@ -61,10 +66,34 @@ INSTALL() { ninja -C build install - prepareInstalledDevelLibs libGL + # Fix a few misc header installation location + mv $includeDir/os/opengl/OpenGLKit.h $includeDir/os/OpenGLKit.h + mv $includeDir/os/opengl/opengl/GLView.h $includeDir/os/opengl/GLView.h + rm -rf $includeDir/os/opengl/opengl + + prepareInstalledDevelLibs libGL libEGL libOpenGL libGLESv1_CM libGLESv2 libGLdispatch fixPkgconfig + # Fix OpenGL kit location + sed -i 's/develop\/headers$/develop\/headers\/os\/opengl/' $installDestDir$developLibDir/pkgconfig/opengl.pc + sed -i 's/develop\/headers$/develop\/headers\/os\/opengl/' $installDestDir$developLibDir/pkgconfig/egl.pc + sed -i 's/develop\/headers$/develop\/headers\/os\/opengl/' $installDestDir$developLibDir/pkgconfig/gl.pc + sed -i 's/develop\/headers$/develop\/headers\/os\/opengl/' $installDestDir$developLibDir/pkgconfig/glesv1_cm.pc + sed -i 's/develop\/headers$/develop\/headers\/os\/opengl/' $installDestDir$developLibDir/pkgconfig/glesv2.pc + sed -i 's/develop\/headers$/develop\/headers\/os\/opengl/' $installDestDir$developLibDir/pkgconfig/libglvnd.pc + + # Toss ports a few bones + # XXX: Is this a good idea? it's more standard, but anything not using pkgconfig should be punished? + #for i in KHR GLES GLES2 GLES3 EGL GL; do + # ln -s $includeDir/os/opengl/$i $includeDir/$i + #done + # devel package packageEntries devel \ $developDir } + +TEST() +{ + ninja -C build test +} diff --git a/sys-libs/libglvnd/patches/libglvnd-1.6.0.patchset b/sys-libs/libglvnd/patches/libglvnd-1.6.0.patchset index 419cc52c3..b48412656 100644 --- a/sys-libs/libglvnd/patches/libglvnd-1.6.0.patchset +++ b/sys-libs/libglvnd/patches/libglvnd-1.6.0.patchset @@ -1,158 +1,191 @@ -From b06009c36706f9cdfd823eaf3dc69488794c8e1d Mon Sep 17 00:00:00 2001 +From 112a6f5ad0579e6e7cda45c780e5f8b12b5fc32a Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Sun, 11 Dec 2022 02:25:51 +0000 +Subject: [PATCH 1/6] meson.build: error out on unsupported OSes + +This is a requirement for WrapDB. Also prevents the build from wasting +time by failing early. + +Signed-off-by: Rosen Penev +--- + meson.build | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/meson.build b/meson.build +index a87548e..8144a22 100644 +--- a/meson.build ++++ b/meson.build +@@ -29,6 +29,10 @@ project( + default_options : ['c_std=gnu99'] + ) + ++if host_machine.system() in ['darwin', 'windows'] ++ error('Host OS: @0@ is unsupported.'.format(host_machine.system())) ++endif ++ + dep_null = dependency('', required : false) + cc = meson.get_compiler('c') + prog_py = import('python').find_installation() +-- +2.37.3 + +From 5013d3528822b230f8c0cdc32029bf9cf92bb97e Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 10 Mar 2023 15:13:16 +0100 +Subject: [PATCH 2/6] Update bin/symbols-check.py from mesa/mesa@9d42e31b + +Fixes https://gitlab.freedesktop.org/glvnd/libglvnd/-/issues/224 + +Signed-off-by: Pino Toscano +--- + bin/symbols-check.py | 32 ++++++++++++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +diff --git a/bin/symbols-check.py b/bin/symbols-check.py +index 5ebeb86..6049cbe 100644 +--- a/bin/symbols-check.py ++++ b/bin/symbols-check.py +@@ -13,6 +13,34 @@ PLATFORM_SYMBOLS = [ + '__cxa_guard_abort', + '__cxa_guard_acquire', + '__cxa_guard_release', ++ '__cxa_allocate_dependent_exception', ++ '__cxa_allocate_exception', ++ '__cxa_begin_catch', ++ '__cxa_call_unexpected', ++ '__cxa_current_exception_type', ++ '__cxa_current_primary_exception', ++ '__cxa_decrement_exception_refcount', ++ '__cxa_deleted_virtual', ++ '__cxa_demangle', ++ '__cxa_end_catch', ++ '__cxa_free_dependent_exception', ++ '__cxa_free_exception', ++ '__cxa_get_exception_ptr', ++ '__cxa_get_globals', ++ '__cxa_get_globals_fast', ++ '__cxa_increment_exception_refcount', ++ '__cxa_new_handler', ++ '__cxa_pure_virtual', ++ '__cxa_rethrow', ++ '__cxa_rethrow_primary_exception', ++ '__cxa_terminate_handler', ++ '__cxa_throw', ++ '__cxa_uncaught_exception', ++ '__cxa_uncaught_exceptions', ++ '__cxa_unexpected_handler', ++ '__dynamic_cast', ++ '__emutls_get_address', ++ '__gxx_personality_v0', + '__end__', + '__odr_asan._glapi_Context', + '__odr_asan._glapi_Dispatch', +@@ -40,7 +68,7 @@ def get_symbols_nm(nm, lib): + if len(fields) == 2 or fields[1] == 'U': + continue + symbol_name = fields[0] +- if platform_name == 'Linux': ++ if platform_name == 'Linux' or platform_name == 'GNU' or platform_name.startswith('GNU/'): + if symbol_name in PLATFORM_SYMBOLS: + continue + elif platform_name == 'Darwin': +@@ -73,7 +101,7 @@ def get_symbols_dumpbin(dumpbin, lib): + continue + symbol_name = fields[3] + # De-mangle symbols +- if symbol_name[0] == '_': ++ if symbol_name[0] == '_' and '@' in symbol_name: + symbol_name = symbol_name[1:].split('@')[0] + symbols.append(symbol_name) + return symbols +-- +2.37.3 + +From 2795b8f09c229a58134c34ecb83001ff72254a53 Mon Sep 17 00:00:00 2001 From: X512 Date: Sat, 21 May 2022 12:20:22 +0900 -Subject: [PATCH 1/2] HGL: add Haiku libGL.so implementation based on EGL +Subject: [PATCH 3/6] HGL: add Haiku libGL.so implementation based on EGL --- - include/meson.build | 11 +- - include/opengl/GLRenderer.h | 73 ++++++ - include/opengl/GLView.h | 192 +++++++++++++++ - include/opengl/OpenGLKit.h | 10 + - include/opengl/README | 27 +++ - meson.build | 2 +- + include/HGL/OpenGLKit.h | 10 + + include/HGL/README | 21 ++ + include/HGL/opengl/GLView.h | 196 ++++++++++++ + include/Makefile.am | 6 +- + include/meson.build | 13 +- + meson.build | 6 + meson_options.txt | 6 + - src/EGL/meson.build | 4 +- + src/EGL/meson.build | 19 +- src/HGL/.gitignore | 2 + - src/HGL/BitmapHook.h | 13 + - src/HGL/GLView.cpp | 462 ++++++++++++++++++++++++++++++++++++ - src/HGL/libgl.c | 59 +++++ - src/HGL/meson.build | 53 +++++ + src/HGL/BitmapHook.h | 17 ++ + src/HGL/GLView.cpp | 580 ++++++++++++++++++++++++++++++++++++ + src/HGL/libgl.c | 59 ++++ + src/HGL/meson.build | 53 ++++ src/meson.build | 4 + - 14 files changed, 913 insertions(+), 5 deletions(-) - create mode 100644 include/opengl/GLRenderer.h - create mode 100644 include/opengl/GLView.h - create mode 100644 include/opengl/OpenGLKit.h - create mode 100644 include/opengl/README + 14 files changed, 987 insertions(+), 5 deletions(-) + create mode 100644 include/HGL/OpenGLKit.h + create mode 100644 include/HGL/README + create mode 100644 include/HGL/opengl/GLView.h create mode 100644 src/HGL/.gitignore create mode 100644 src/HGL/BitmapHook.h create mode 100644 src/HGL/GLView.cpp create mode 100644 src/HGL/libgl.c create mode 100644 src/HGL/meson.build -diff --git a/include/meson.build b/include/meson.build -index 5efb90d..d0e8a2f 100644 ---- a/include/meson.build -+++ b/include/meson.build -@@ -22,6 +22,7 @@ - # MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - - inc_include = include_directories('.') -+inc_include_opengl = include_directories('opengl') - - install_headers( - 'glvnd/GLdispatchABI.h', -@@ -54,6 +55,15 @@ if with_glx and _headers - ) - endif - -+if get_option('hgl') and _headers -+ install_headers( -+ 'opengl/OpenGLKit.h', -+ 'opengl/GLView.h', -+ 'opengl/GLRenderer.h', -+ subdir : 'opengl', -+ ) -+endif -+ - if get_option('gles1') and _headers - install_headers( - 'GLES/egl.h', -@@ -89,4 +99,3 @@ if get_option('egl') and _headers - subdir : 'EGL', - ) - endif -- -diff --git a/include/opengl/GLRenderer.h b/include/opengl/GLRenderer.h +diff --git a/include/HGL/OpenGLKit.h b/include/HGL/OpenGLKit.h new file mode 100644 -index 0000000..5c9c4da +index 0000000..71d9830 --- /dev/null -+++ b/include/opengl/GLRenderer.h -@@ -0,0 +1,73 @@ ++++ b/include/HGL/OpenGLKit.h +@@ -0,0 +1,10 @@ +/* -+ * Copyright 2006, Philippe Houdoin. All rights reserved. -+ * Distributed under the terms of the MIT License. -+ -+ * This header defines BGLRenderer, the base class making up -+ * the Haiku GL renderer add-ons (essentially selfcontained C++ -+ * shared libraries that do the actual rendering such as -+ * libswpipe.so and libswrast.so) ++ * Master include file for the Haiku OpenGL Kit. + */ -+#ifndef GLRENDERER_H -+#define GLRENDERER_H + -+ -+#include ++#include +#include + -+ -+class BGLDispatcher; -+class GLRendererRoster; -+ -+typedef unsigned long renderer_id; -+ -+class _EXPORT BGLRenderer -+{ -+ // Private unimplemented copy constructors -+ BGLRenderer(const BGLRenderer &); -+ BGLRenderer & operator=(const BGLRenderer &); -+ -+public: -+ BGLRenderer(BGLView *view, ulong bgl_options); -+ virtual ~BGLRenderer(); -+ -+ void Acquire(); -+ void Release(); -+ -+ virtual void LockGL(); -+ virtual void UnlockGL(); -+ -+ virtual void SwapBuffers(bool VSync = false); -+ virtual void Draw(BRect updateRect); -+ virtual status_t CopyPixelsOut(BPoint source, BBitmap *dest); -+ virtual status_t CopyPixelsIn(BBitmap *source, BPoint dest); -+ -+ virtual void FrameResized(float width, float height); -+ -+ virtual void DirectConnected(direct_buffer_info *info); -+ virtual void EnableDirectMode(bool enabled); -+ -+ inline int32 ReferenceCount() const { return fRefCount; }; -+ inline ulong Options() const { return fOptions; }; -+ inline BGLView* GLView() { return fView; }; -+ -+private: -+ friend class GLRendererRoster; -+ -+ virtual status_t _Reserved_Renderer_0(int32, void *); -+ virtual status_t _Reserved_Renderer_1(int32, void *); -+ virtual status_t _Reserved_Renderer_2(int32, void *); -+ virtual status_t _Reserved_Renderer_3(int32, void *); -+ virtual status_t _Reserved_Renderer_4(int32, void *); -+ -+ int32 fRefCount; // How much we're still useful -+ BGLView* fView; // Never forget who is the boss! -+ ulong fOptions; // Keep that tune in memory -+ -+ GLRendererRoster* fOwningRoster; -+ renderer_id fID; -+}; -+ -+extern "C" _EXPORT BGLRenderer* instantiate_gl_renderer(BGLView *view, ulong options); -+ -+ -+#endif // GLRENDERER_H -diff --git a/include/opengl/GLView.h b/include/opengl/GLView.h ++// Projects needing GL/glu.h and GL/glut.h should now ++// include these headers independently as glu and glut ++// are no longer core parts of mesa +diff --git a/include/HGL/README b/include/HGL/README new file mode 100644 -index 0000000..cf5e2ec +index 0000000..b452c18 --- /dev/null -+++ b/include/opengl/GLView.h -@@ -0,0 +1,192 @@ ++++ b/include/HGL/README +@@ -0,0 +1,21 @@ ++These headers make up the Haiku OpenGL kit. ++ ++Headers in this directory preserve some BeOS™ compatibility ++compatibility, so changes should be mentioned to the Haiku ++project mailing list. ++ ++Haiku Website: http://haiku-os.org ++BeOS OpenGL API Docs: https://www.haiku-os.org/legacy-docs/bebook/TheOpenGLKit_Overview.html ++ ++Normal Haiku OpenGL layout: ++ ++ * headers/os/OpenGLKit.h ++ * headers/os/opengl/GLView.h ++ * headers/os/opengl/GL/gl.h ++ * headers/os/opengl/GL/glext.h ++ * headers/os/opengl/GL/osmesa.h (needed?) ++ ++Extras: ++ ++ * headers/os/opengl/GL/glu.h ++ * headers/os/opengl/GL/glut.h +diff --git a/include/HGL/opengl/GLView.h b/include/HGL/opengl/GLView.h +new file mode 100644 +index 0000000..5649115 +--- /dev/null ++++ b/include/HGL/opengl/GLView.h +@@ -0,0 +1,196 @@ +/* -+ * Copyright 2008-2013, Haiku, Inc. All Rights Reserved. ++ * Copyright 2008-2023, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * This header defines BGLView, the base class making up -+ * the Haiku GL Kit. ++ * the Haiku OpenGL Kit. + * + */ +#ifndef BGLVIEW_H @@ -175,6 +208,7 @@ index 0000000..cf5e2ec +#define BGL_STENCIL 512 +#define BGL_SHARE_CONTEXT 1024 + ++ +#ifdef __cplusplus + +#include @@ -238,6 +272,7 @@ index 0000000..cf5e2ec + virtual void GetPreferredSize(float* width, float* height); + +private: ++ class Display; + struct Renderer; + + virtual void _ReservedGLView1(); @@ -252,6 +287,8 @@ index 0000000..cf5e2ec + BGLView(const BGLView &); + BGLView &operator=(const BGLView &); + ++ static Display sDisplay; ++ + void _DitherFront(); + bool _ConfirmDither(); + void _Draw(BRect rect); @@ -339,70 +376,82 @@ index 0000000..cf5e2ec +#endif // __cplusplus + +#endif // BGLVIEW_H -diff --git a/include/opengl/OpenGLKit.h b/include/opengl/OpenGLKit.h -new file mode 100644 -index 0000000..71d9830 ---- /dev/null -+++ b/include/opengl/OpenGLKit.h -@@ -0,0 +1,10 @@ -+/* -+ * Master include file for the Haiku OpenGL Kit. -+ */ +diff --git a/include/Makefile.am b/include/Makefile.am +index 800ed55..49ffb8b 100644 +--- a/include/Makefile.am ++++ b/include/Makefile.am +@@ -44,6 +44,10 @@ EGL_HEADER_FILES = \ + EGL/eglext.h \ + EGL/eglplatform.h + ++HGL_HEADER_FILES = \ ++ HGL/OpenGLKit.h \ ++ HGL/opengl/GLView.h + -+#include -+#include + if ENABLE_GL_HEADERS + nobase_include_HEADERS += $(GL_HEADER_FILES) + else +@@ -76,4 +80,4 @@ else + noinst_HEADERS += $(EGL_HEADER_FILES) + endif + +-EXTRA_DIST = meson.build +\ No newline at end of file ++EXTRA_DIST = meson.build $(HGL_HEADER_FILES) +diff --git a/include/meson.build b/include/meson.build +index 5efb90d..408e83a 100644 +--- a/include/meson.build ++++ b/include/meson.build +@@ -22,6 +22,7 @@ + # MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + + inc_include = include_directories('.') ++inc_include_hgl = include_directories('HGL/opengl') + + install_headers( + 'glvnd/GLdispatchABI.h', +@@ -54,6 +55,17 @@ if with_glx and _headers + ) + endif + ++if with_hgl and _headers ++ install_headers( ++ 'HGL/opengl/GLView.h', ++ subdir : 'opengl', ++ ) ++ install_headers( ++ 'HGL/OpenGLKit.h', ++ subdir : '', ++ ) ++endif + -+// Projects needing GL/glu.h and GL/glut.h should now -+// include these headers independently as glu and glut -+// are no longer core parts of mesa -diff --git a/include/opengl/README b/include/opengl/README -new file mode 100644 -index 0000000..da5e5b6 ---- /dev/null -+++ b/include/opengl/README -@@ -0,0 +1,27 @@ -+These headers make up the Haiku Op*nGL kit. -+ -+Headers in this directory preserve some BeOS™ compatibility -+compatibility, so changes should be mentioned to the Haiku -+project mailing list. -+ -+http://haiku-os.org -+ -+Normal Haiku Op*enGL layout: -+ -+ * headers/os/OpenGLKit.h -+ * headers/os/opengl/GLView.h -+ * headers/os/opengl/GLRenderer.h -+ * headers/os/opengl/GL/gl.h -+ * headers/os/opengl/GL/glext.h -+ * headers/os/opengl/GL/osmesa.h (needed?) -+ -+Extras: -+ -+ * headers/os/opengl/GL/glu.h -+ * headers/os/opengl/GL/glut.h -+ -+OpenGL™ is a trademark of SGI. The usage of this trademark -+in the Haiku GL Kit is not a sign of any certification or -+endorsement by SGI or its affiliates. Usage is purely to -+allow legacy compatibility with the BeOS™ and its 3D GL -+rendering subsystem. + if get_option('gles1') and _headers + install_headers( + 'GLES/egl.h', +@@ -89,4 +101,3 @@ if get_option('egl') and _headers + subdir : 'EGL', + ) + endif +- diff --git a/meson.build b/meson.build -index 8144a22..86fc92f 100644 +index 8144a22..ab16ffb 100644 --- a/meson.build +++ b/meson.build -@@ -23,7 +23,7 @@ +@@ -110,6 +110,12 @@ elif not get_option('glx').disabled() and dep_x11.found() + with_glx = true + endif - project( - 'glvnd', -- 'c', -+ 'c', 'cpp', - version : '1.6.0', - meson_version : '>= 0.48', - default_options : ['c_std=gnu99'] ++with_hgl = false ++if get_option('hgl') and host_machine.system() in ['haiku'] ++ add_languages('cpp') ++ with_hgl = true ++endif ++ + if cc.compiles('typeof(int *);', name : 'typeof') + add_project_arguments('-DHAVE_TYPEOF', language : ['c']) + endif diff --git a/meson_options.txt b/meson_options.txt -index 43198f6..bd34f81 100644 +index 43198f6..2b2727a 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -42,6 +42,12 @@ option( @@ -412,24 +461,46 @@ index 43198f6..bd34f81 100644 +option( + 'hgl', + type : 'boolean', -+ value : false, -+ description : 'Support the HGL platform.' ++ value : true, ++ description : 'Support the Haiku GL platform.' +) option( 'gles1', type : 'boolean', diff --git a/src/EGL/meson.build b/src/EGL/meson.build -index 9d109b1..f4db258 100644 +index 9d109b1..c90f0ca 100644 --- a/src/EGL/meson.build +++ b/src/EGL/meson.build -@@ -39,9 +39,7 @@ libEGL = shared_library( +@@ -29,6 +29,21 @@ libegl_dispatch_stubs = static_library( + gnu_symbol_visibility : 'hidden', + ) + ++if host_machine.system() in ['haiku'] ++ # A booted Haiku system has a rigid directory structure. ++ # non-packaged prefixes are like local where the user can modify the contents. ++ # Anything missing "non-packaged" is read-only and populated by our software packages. ++ # Anything in system is system installed software, anything in home is user installed ++ egl_vendor_config_dirs = '/boot/home/config/non-packaged/add-ons/opengl/egl_vendor.d' ++ egl_vendor_config_dirs += ':/boot/home/config/add-ons/opengl/egl_vendor.d' ++ egl_vendor_config_dirs += ':/boot/system/non-packaged/add-ons/opengl/egl_vendor.d' ++ egl_vendor_config_dirs += ':/boot/system/add-ons/opengl/egl_vendor.d' ++else ++ egl_vendor_config_dirs = '@0@/glvnd/egl_vendor.d:@1@/glvnd/egl_vendor.d'.format( ++ join_paths(get_option('prefix'),get_option('sysconfdir')), ++ join_paths(get_option('prefix'),get_option('datadir'))) ++endif ++ + libEGL = shared_library( + 'EGL', + [ +@@ -39,9 +54,7 @@ libEGL = shared_library( 'libeglerror.c', ], c_args : [ - '-DDEFAULT_EGL_VENDOR_CONFIG_DIRS="@0@/glvnd/egl_vendor.d:@1@/glvnd/egl_vendor.d"'.format( - join_paths(get_option('prefix'), get_option('sysconfdir')), - join_paths(get_option('prefix'), get_option('datadir'))), -+ '-DDEFAULT_EGL_VENDOR_CONFIG_DIRS="/boot/home/config/non-packaged/add-ons/opengl/egl_vendor.d:/boot/home/config/add-ons/opengl/egl_vendor.d:/boot/system/non-packaged/add-ons/opengl/egl_vendor.d:/boot/system/add-ons/opengl/egl_vendor.d"' ++ '-DDEFAULT_EGL_VENDOR_CONFIG_DIRS="@0@"'.format(egl_vendor_config_dirs) ], include_directories : inc_include, link_args : '-Wl,-Bsymbolic', @@ -443,15 +514,19 @@ index 0000000..84a797f +g_libglglxwrapper.c diff --git a/src/HGL/BitmapHook.h b/src/HGL/BitmapHook.h new file mode 100644 -index 0000000..b5d976f +index 0000000..5a9ec53 --- /dev/null +++ b/src/HGL/BitmapHook.h -@@ -0,0 +1,13 @@ +@@ -0,0 +1,17 @@ ++/* ++ * Copyright 2006-2023, Haiku. All rights reserved. ++ * Distributed under the terms of the MIT License. ++ */ ++ +#pragma once + +#include + -+ +class BBitmap; + +class BitmapHook { @@ -462,19 +537,20 @@ index 0000000..b5d976f +}; diff --git a/src/HGL/GLView.cpp b/src/HGL/GLView.cpp new file mode 100644 -index 0000000..721b099 +index 0000000..9b99853 --- /dev/null +++ b/src/HGL/GLView.cpp -@@ -0,0 +1,462 @@ +@@ -0,0 +1,580 @@ +/* -+ * Copyright 2006-2022, Haiku. All rights reserved. ++ * Copyright 2006-2023, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: -+ * Jérôme Duval, korli@users.berlios.de -+ * Philippe Houdoin, philippe.houdoin@free.fr -+ * Stefano Ceccherini, burton666@libero.it -+ * X512, danger_mail@list.ru ++ * Jérôme Duval, korli@users.berlios.de ++ * Philippe Houdoin, philippe.houdoin@free.fr ++ * Stefano Ceccherini, burton666@libero.it ++ * X512, danger_mail@list.ru ++ * Alexander von Gluck IV, kallisti5@unixzen.com + */ + +#include @@ -491,6 +567,7 @@ index 0000000..721b099 +#include + +#include ++#include + +#include +#include @@ -501,324 +578,419 @@ index 0000000..721b099 + + +struct glview_direct_info { -+ direct_buffer_info* direct_info; -+ bool direct_connected; -+ bool enable_direct_mode; ++ direct_buffer_info* direct_info; ++ bool direct_connected; ++ bool enable_direct_mode; + -+ glview_direct_info(); -+ ~glview_direct_info(); ++ glview_direct_info(); ++ ~glview_direct_info(); +}; + -+ +#define LIBEGL_HOOK_LIST(REQUIRED) \ -+ REQUIRED(PFNEGLGETPROCADDRESSPROC, eglGetProcAddress) \ -+ REQUIRED(PFNEGLGETDISPLAYPROC, eglGetDisplay) \ -+ REQUIRED(PFNEGLINITIALIZEPROC, eglInitialize) \ -+ REQUIRED(PFNEGLCHOOSECONFIGPROC, eglChooseConfig) \ -+ REQUIRED(PFNEGLBINDAPIPROC, eglBindAPI) \ -+ REQUIRED(PFNEGLCREATECONTEXTPROC, eglCreateContext) \ -+ REQUIRED(PFNEGLDESTROYCONTEXTPROC, eglDestroyContext) \ -+ REQUIRED(PFNEGLMAKECURRENTPROC, eglMakeCurrent) \ -+ REQUIRED(PFNEGLTERMINATEPROC, eglTerminate) \ -+ REQUIRED(PFNEGLSWAPBUFFERSPROC, eglSwapBuffers) \ -+ REQUIRED(PFNEGLCREATEWINDOWSURFACEPROC, eglCreateWindowSurface) \ -+ REQUIRED(PFNEGLCREATEPBUFFERSURFACEPROC, eglCreatePbufferSurface) \ -+ REQUIRED(PFNEGLDESTROYSURFACEPROC, eglDestroySurface) \ -+ REQUIRED(PFNEGLGETCURRENTCONTEXTPROC, eglGetCurrentContext) \ ++ REQUIRED(PFNEGLGETPROCADDRESSPROC, eglGetProcAddress) \ ++ REQUIRED(PFNEGLGETDISPLAYPROC, eglGetDisplay) \ ++ REQUIRED(PFNEGLINITIALIZEPROC, eglInitialize) \ ++ REQUIRED(PFNEGLCHOOSECONFIGPROC, eglChooseConfig) \ ++ REQUIRED(PFNEGLBINDAPIPROC, eglBindAPI) \ ++ REQUIRED(PFNEGLCREATECONTEXTPROC, eglCreateContext) \ ++ REQUIRED(PFNEGLDESTROYCONTEXTPROC, eglDestroyContext) \ ++ REQUIRED(PFNEGLMAKECURRENTPROC, eglMakeCurrent) \ ++ REQUIRED(PFNEGLTERMINATEPROC, eglTerminate) \ ++ REQUIRED(PFNEGLSWAPBUFFERSPROC, eglSwapBuffers) \ ++ REQUIRED(PFNEGLCREATEWINDOWSURFACEPROC, eglCreateWindowSurface) \ ++ REQUIRED(PFNEGLCREATEPBUFFERSURFACEPROC, eglCreatePbufferSurface) \ ++ REQUIRED(PFNEGLDESTROYSURFACEPROC, eglDestroySurface) \ ++ REQUIRED(PFNEGLGETCURRENTCONTEXTPROC, eglGetCurrentContext) \ ++ REQUIRED(PFNEGLGETCURRENTDISPLAYPROC, eglGetCurrentDisplay) ++ ++ ++class BGLView::Display : public BReferenceable { ++public: ++#define DISPATCH_TABLE_ENTRY(x, y) x y {}; ++ LIBEGL_HOOK_LIST(DISPATCH_TABLE_ENTRY) ++#undef DISPATCH_TABLE_ENTRY ++ ++ EGLDisplay eglDpy {}; ++ EGLConfig eglCfg {}; ++ ++private: ++ status_t Init(); ++ ++ pthread_mutex_t fLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; ++ status_t fStatus = B_NO_INIT; ++ void *libEgl {}; ++ ++protected: ++ virtual void FirstReferenceAcquired(); ++ virtual void LastReferenceReleased(); ++ ++public: ++ Display(); ++ virtual ~Display() = default; ++ ++ status_t InitCheck(); ++}; + + +struct BGLView::Renderer { -+ BGLView *view; ++ BGLView *view; + -+ void *libEgl{}; ++ BReference display; + -+#define DISPATCH_TABLE_ENTRY(x, y) x y{}; -+ LIBEGL_HOOK_LIST(DISPATCH_TABLE_ENTRY) -+#undef DISPATCH_TABLE_ENTRY ++ EGLContext eglCtx = EGL_NO_CONTEXT; ++ EGLSurface eglSurf = EGL_NO_SURFACE; ++ uint32_t width = 0; ++ uint32_t height = 0; + -+ EGLDisplay eglDpy{}; -+ EGLConfig eglCfg{}; -+ EGLContext eglCtx = EGL_NO_CONTEXT; -+ EGLSurface eglSurf = EGL_NO_SURFACE; -+ uint32_t width = 0; -+ uint32_t height = 0; ++ class BitmapHook: public ::BitmapHook { ++ private: ++ inline Renderer *Base() {return (Renderer*)((char*)this - offsetof(Renderer, fBmpHook));} + -+ class BitmapHook: public ::BitmapHook { -+ private: -+ inline Renderer *Base() {return (Renderer*)((char*)this - offsetof(Renderer, fBmpHook));} ++ public: ++ virtual ~BitmapHook() {}; ++ void GetSize(uint32_t &width, uint32_t &height) override; ++ BBitmap *SetBitmap(BBitmap *bmp) override; ++ } fBmpHook; ++ pthread_mutex_t fLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; ++ ObjectDeleter fBitmap; + -+ public: -+ virtual ~BitmapHook() {}; -+ void GetSize(uint32_t &width, uint32_t &height) override; -+ BBitmap *SetBitmap(BBitmap *bmp) override; -+ } fBmpHook; -+ pthread_mutex_t fLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; -+ ObjectDeleter fBitmap; -+ -+ ~Renderer(); -+ status_t Init(); -+ void SwapBuffers(); ++ ~Renderer(); ++ status_t Init(); ++ void SwapBuffers(); +}; + + ++BGLView::Display BGLView::sDisplay; ++ ++ ++BGLView::Display::Display() ++{ ++ fReferenceCount = 0; ++} ++ ++status_t BGLView::Display::InitCheck() ++{ ++ PthreadMutexLocker lock(&fLock); ++ return fStatus; ++} ++ ++void BGLView::Display::FirstReferenceAcquired() ++{ ++ PthreadMutexLocker lock(&fLock); ++ fStatus = Init(); ++} ++ ++void BGLView::Display::LastReferenceReleased() ++{ ++ PthreadMutexLocker lock(&fLock); ++ ++ if (fStatus < B_OK) ++ return; ++ ++ fStatus = B_NO_INIT; ++ ++ if (eglDpy == eglGetCurrentDisplay()) ++ eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); ++ ++ eglTerminate(eglDpy); eglDpy = NULL; ++ dlclose(libEgl); libEgl = NULL; ++} ++ ++status_t BGLView::Display::Init() ++{ ++ libEgl = dlopen("libEGL.so.1", RTLD_LOCAL); ++ if (libEgl == NULL) { ++ fprintf(stderr, "[!] libEGL.so.1 not found\n"); ++ return B_ERROR; ++ } ++ ++#define DISPATCH_TABLE_ENTRY(x, y) \ ++ *(void**)&y = dlsym(libEgl, #y); \ ++ if (y == NULL) { \ ++ fprintf(stderr, "[!] libEGL symbol " #y " not found\n"); \ ++ return B_ERROR; \ ++ } ++ LIBEGL_HOOK_LIST(DISPATCH_TABLE_ENTRY) ++#undef DISPATCH_TABLE_ENTRY ++ ++ eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); ++ if (eglDpy == EGL_NO_DISPLAY) { ++ fprintf(stderr, "[!] eglGetDisplay failed to obtain EGL_DEFAULT_DISPLAY\n"); ++ return B_ERROR; ++ } ++ ++ EGLint major, minor; ++ EGLBoolean result = eglInitialize(eglDpy, &major, &minor); ++ if (result != EGL_TRUE) { ++ fprintf(stderr, "[!] eglInitialize failed for EGL_DEFAULT_DISPLAY\n"); ++ return B_ERROR; ++ } ++ ++ EGLint numConfigs; ++ static const EGLint configAttribs[] = { ++ EGL_SURFACE_TYPE, EGL_WINDOW_BIT, ++ EGL_BLUE_SIZE, 8, ++ EGL_GREEN_SIZE, 8, ++ EGL_RED_SIZE, 8, ++ EGL_DEPTH_SIZE, 8, ++ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, ++ EGL_NONE ++ }; ++ result = eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs); ++ if (result != EGL_TRUE || numConfigs <= 0) { ++ fprintf(stderr, "[!] eglChooseDisplay failed\n"); ++ return B_ERROR; ++ } ++ ++ return B_OK; ++} ++ +void BGLView::Renderer::BitmapHook::GetSize(uint32_t &width, uint32_t &height) +{ -+ PthreadMutexLocker lock(&Base()->fLock); -+ width = Base()->width; -+ height = Base()->height; ++ PthreadMutexLocker lock(&Base()->fLock); ++ width = Base()->width; ++ height = Base()->height; +} + +BBitmap *BGLView::Renderer::BitmapHook::SetBitmap(BBitmap *bmp) +{ -+ PthreadMutexLocker lock(&Base()->fLock); -+ BBitmap* oldBmp = Base()->fBitmap.Detach(); -+ Base()->fBitmap.SetTo(bmp); -+ BMessenger(Base()->view).SendMessage(B_INVALIDATE); -+ return oldBmp; ++ PthreadMutexLocker lock(&Base()->fLock); ++ BBitmap* oldBmp = Base()->fBitmap.Detach(); ++ Base()->fBitmap.SetTo(bmp); ++ BMessenger(Base()->view).SendMessage(B_INVALIDATE); ++ return oldBmp; +} + -+ +status_t BGLView::Renderer::Init() +{ -+ libEgl = dlopen("libEGL.so", RTLD_LOCAL); -+ if (libEgl == NULL) { -+ fprintf(stderr, "[!] libEGL.so not found\n"); -+ return B_ERROR; -+ } ++ display = &BGLView::sDisplay; ++ if (display->InitCheck() < B_OK) ++ return display->InitCheck(); + -+#define DISPATCH_TABLE_ENTRY(x, y) *(void**)&y = dlsym(libEgl, #y); if (y == NULL) {fprintf(stderr, "[!] libEGL symbol " #y " not found\n"); return B_ERROR;} -+ LIBEGL_HOOK_LIST(DISPATCH_TABLE_ENTRY) -+#undef DISPATCH_TABLE_ENTRY ++ EGLContext shareCtx = EGL_NO_CONTEXT; ++ if ((view->fOptions & BGL_SHARE_CONTEXT) != 0) { ++ shareCtx = display->eglGetCurrentContext(); ++ } + -+ eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); ++ EGLBoolean result = display->eglBindAPI(EGL_OPENGL_API); ++ if (result != EGL_TRUE) { ++ fprintf(stderr, "[!] eglBindAPI failed\n"); ++ return B_ERROR; ++ } + -+ EGLint major, minor; -+ eglInitialize(eglDpy, &major, &minor); ++ eglCtx = display->eglCreateContext(display->eglDpy, display->eglCfg, shareCtx, NULL); ++ if (eglCtx == NULL) { ++ fprintf(stderr, "[!] eglCreateContext failed\n"); ++ return B_ERROR; ++ } + -+ EGLint numConfigs; -+ EGLint configAttribs[] = { -+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, -+ EGL_BLUE_SIZE, 8, -+ EGL_GREEN_SIZE, 8, -+ EGL_RED_SIZE, 8, -+ EGL_DEPTH_SIZE, 8, -+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, -+ EGL_NONE -+ }; -+ eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs); ++ BRect viewFrame = view->Frame(); ++ width = (uint32_t)viewFrame.Width() + 1; ++ height = (uint32_t)viewFrame.Height() + 1; + -+ eglBindAPI(EGL_OPENGL_API); ++ eglSurf = display->eglCreateWindowSurface(display->eglDpy, display->eglCfg, ++ (EGLNativeWindowType)&fBmpHook, NULL); ++ if (eglSurf == NULL) { ++ fprintf(stderr, "[!] eglCreateWindowSurface failed\n"); ++ return B_ERROR; ++ } + -+ EGLContext shareCtx = EGL_NO_CONTEXT; -+ if ((view->fOptions & BGL_SHARE_CONTEXT) != 0) { -+ shareCtx = eglGetCurrentContext(); -+ } -+ eglCtx = eglCreateContext(eglDpy, eglCfg, shareCtx, NULL); -+ -+ BRect viewFrame = view->Frame(); -+ width = (uint32_t)viewFrame.Width() + 1; -+ height = (uint32_t)viewFrame.Height() + 1; -+ -+ eglSurf = eglCreateWindowSurface(eglDpy, eglCfg, (EGLNativeWindowType)&fBmpHook, NULL); -+ -+ return B_OK; ++ return B_OK; +} + +BGLView::Renderer::~Renderer() +{ -+ if (libEgl == NULL) -+ return; -+ eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ if (eglSurf != EGL_NO_SURFACE) {eglDestroySurface(eglDpy, eglSurf); eglSurf = EGL_NO_SURFACE;} -+ if (eglCtx != EGL_NO_CONTEXT) {eglDestroyContext(eglDpy, eglCtx); eglCtx = EGL_NO_CONTEXT;} -+ eglTerminate(eglDpy); -+ dlclose(libEgl); ++ if (display->InitCheck() < B_OK) ++ return; ++ ++ if (display->eglDpy == display->eglGetCurrentDisplay() ++ && eglCtx == display->eglGetCurrentContext()) ++ display->eglMakeCurrent(display->eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); ++ ++ if (eglSurf != EGL_NO_SURFACE) { ++ display->eglDestroySurface(display->eglDpy, eglSurf); ++ eglSurf = EGL_NO_SURFACE; ++ } ++ ++ if (eglCtx != EGL_NO_CONTEXT) { ++ display->eglDestroyContext(display->eglDpy, eglCtx); ++ eglCtx = EGL_NO_CONTEXT; ++ } +} + +void BGLView::Renderer::SwapBuffers() +{ -+ eglSwapBuffers(eglDpy, eglSurf); ++ display->eglSwapBuffers(display->eglDpy, eglSurf); +} + -+ +// #pragma mark - + +BGLView::BGLView(BRect rect, const char* name, ulong resizingMode, ulong mode, -+ ulong options) -+ : -+ BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS), -+ fGc(NULL), -+ fOptions(options), -+ fDrawLock("BGLView draw lock"), -+ fDisplayLock("BGLView display lock"), -+ fClipInfo(NULL), -+ fRenderer(new Renderer{.view = this}) ++ ulong options) ++ : ++ BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS), ++ fGc(NULL), ++ fOptions(options), ++ fDrawLock("BGLView draw lock"), ++ fDisplayLock("BGLView display lock"), ++ fClipInfo(NULL), ++ fRenderer(new Renderer{.view = this}) +{ -+ if (fRenderer->Init() < B_OK) { -+ delete fRenderer; -+ fRenderer = NULL; -+ } ++ if (fRenderer->Init() < B_OK) { ++ delete fRenderer; ++ fRenderer = NULL; ++ } +} + -+ +// BeOS compatibility: contrary to others BView's contructors, +// BGLView one wants a non-const name argument. +BGLView::BGLView(BRect rect, char* name, ulong resizingMode, ulong mode, -+ ulong options) -+ : -+ BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS), -+ fGc(NULL), -+ fOptions(options), -+ fDrawLock("BGLView draw lock"), -+ fDisplayLock("BGLView display lock"), -+ fClipInfo(NULL), -+ fRenderer(new Renderer{.view = this}) ++ ulong options) ++ : ++ BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS), ++ fGc(NULL), ++ fOptions(options), ++ fDrawLock("BGLView draw lock"), ++ fDisplayLock("BGLView display lock"), ++ fClipInfo(NULL), ++ fRenderer(new Renderer{.view = this}) +{ -+ if (fRenderer->Init() < B_OK) { -+ delete fRenderer; -+ fRenderer = NULL; -+ } ++ if (fRenderer->Init() < B_OK) { ++ delete fRenderer; ++ fRenderer = NULL; ++ } +} + -+ +BGLView::~BGLView() +{ -+ delete fRenderer; -+ delete fClipInfo; ++ delete fRenderer; ++ delete fClipInfo; +} + -+ +void +BGLView::LockGL() +{ -+ fDisplayLock.Lock(); -+ if (fDisplayLock.CountLocks() == 1) { -+ fRenderer->eglMakeCurrent(fRenderer->eglDpy, fRenderer->eglSurf, fRenderer->eglSurf, fRenderer->eglCtx); -+ } ++ fDisplayLock.Lock(); ++ if (fDisplayLock.CountLocks() == 1) { ++ fRenderer->display->eglMakeCurrent(fRenderer->display->eglDpy, fRenderer->eglSurf, ++ fRenderer->eglSurf, fRenderer->eglCtx); ++ } +} + -+ +void +BGLView::UnlockGL() +{ -+ thread_id lockerThread = fDisplayLock.LockingThread(); -+ thread_id callerThread = find_thread(NULL); ++ thread_id lockerThread = fDisplayLock.LockingThread(); ++ thread_id callerThread = find_thread(NULL); + -+ if (lockerThread != B_ERROR && lockerThread != callerThread) { -+ printf("UnlockGL is called from wrong thread, lockerThread: %d, callerThread: %d\n", -+ (int)lockerThread, (int)callerThread); -+ } ++ if (lockerThread != B_ERROR && lockerThread != callerThread) { ++ printf("UnlockGL is called from wrong thread, lockerThread: %d, callerThread: %d\n", ++ (int)lockerThread, (int)callerThread); ++ } + -+ if (fDisplayLock.CountLocks() == 1) { -+ fRenderer->eglMakeCurrent(fRenderer->eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ } -+ fDisplayLock.Unlock(); ++ if (fDisplayLock.CountLocks() == 1) { ++ fRenderer->display->eglMakeCurrent(fRenderer->display->eglDpy, EGL_NO_SURFACE, ++ EGL_NO_SURFACE, EGL_NO_CONTEXT); ++ } ++ fDisplayLock.Unlock(); +} + -+ +void +BGLView::SwapBuffers() +{ -+ SwapBuffers(false); ++ SwapBuffers(false); +} + -+ +void +BGLView::SwapBuffers(bool vSync) +{ -+ _LockDraw(); -+ fRenderer->SwapBuffers(); -+ _UnlockDraw(); ++ _LockDraw(); ++ fRenderer->SwapBuffers(); ++ _UnlockDraw(); +} + + +BView* +BGLView::EmbeddedView() +{ -+ return NULL; ++ return NULL; +} + -+ +void* +BGLView::GetGLProcAddress(const char* procName) +{ -+ return (void*)fRenderer->eglGetProcAddress(procName); ++ return (void*)fRenderer->display->eglGetProcAddress(procName); +} + -+ +status_t +BGLView::CopyPixelsOut(BPoint source, BBitmap* dest) +{ -+ if (!dest || !dest->Bounds().IsValid()) -+ return B_BAD_VALUE; ++ if (!dest || !dest->Bounds().IsValid()) ++ return B_BAD_VALUE; + -+ return ENOSYS; ++ return ENOSYS; +} + -+ +status_t +BGLView::CopyPixelsIn(BBitmap* source, BPoint dest) +{ -+ if (!source || !source->Bounds().IsValid()) -+ return B_BAD_VALUE; ++ if (!source || !source->Bounds().IsValid()) ++ return B_BAD_VALUE; + -+ return ENOSYS; ++ return ENOSYS; +} + -+ -+/*! Mesa's GLenum is not ulong but uint, so we can't use GLenum -+ without breaking this method signature. -+ Instead, we have to use the effective BeOS's SGI OpenGL GLenum type: -+ unsigned long. ++/*! Mesa's GLenum is not ulong but uint, so we can't use GLenum ++ without breaking this method signature. ++ Instead, we have to use the effective BeOS's SGI OpenGL GLenum type: ++ unsigned long. + */ +void +BGLView::ErrorCallback(unsigned long errorCode) +{ -+ char msg[32]; -+ sprintf(msg, "GL: Error code $%04lx.", errorCode); -+ // TODO: under BeOS R5, it call debugger(msg); -+ fprintf(stderr, "%s\n", msg); ++ char msg[32]; ++ sprintf(msg, "GL: Error code $%04lx.", errorCode); ++ // TODO: under BeOS R5, it call debugger(msg); ++ fprintf(stderr, "%s\n", msg); +} + -+ +void +BGLView::Draw(BRect updateRect) +{ -+ BRegion region(updateRect); -+ PthreadMutexLocker lock(&fRenderer->fLock); -+ if (fRenderer->fBitmap.IsSet()) { -+ DrawBitmap(fRenderer->fBitmap.Get(), B_ORIGIN); -+ region.Exclude(fRenderer->fBitmap->Bounds()); -+ } -+ FillRegion(®ion, B_SOLID_LOW); ++ BRegion region(updateRect); ++ PthreadMutexLocker lock(&fRenderer->fLock); ++ if (fRenderer->fBitmap.IsSet()) { ++ DrawBitmap(fRenderer->fBitmap.Get(), B_ORIGIN); ++ region.Exclude(fRenderer->fBitmap->Bounds()); ++ } ++ FillRegion(®ion, B_SOLID_LOW); +} + -+ +void +BGLView::AttachedToWindow() +{ -+ BView::AttachedToWindow(); ++ BView::AttachedToWindow(); + -+ { -+ PthreadMutexLocker lock(&fRenderer->fLock); -+ fRenderer->width = Bounds().IntegerWidth() + 1; -+ fRenderer->height = Bounds().IntegerHeight() + 1; -+ } ++ { ++ PthreadMutexLocker lock(&fRenderer->fLock); ++ fRenderer->width = Bounds().IntegerWidth() + 1; ++ fRenderer->height = Bounds().IntegerHeight() + 1; ++ } + -+ // Set default OpenGL viewport: -+ LockGL(); -+ glViewport(0, 0, Bounds().IntegerWidth() + 1, Bounds().IntegerHeight() + 1); -+ UnlockGL(); ++ // Set default OpenGL viewport: ++ LockGL(); ++ glViewport(0, 0, Bounds().IntegerWidth() + 1, Bounds().IntegerHeight() + 1); ++ UnlockGL(); +} + -+ +void BGLView::GetPreferredSize(float* _width, float* _height) +{ -+ if (_width) *_width = 0; -+ if (_height) *_height = 0; ++ if (_width) ++ *_width = 0; ++ if (_height) ++ *_height = 0; +} + -+ +void +BGLView::DirectConnected(direct_buffer_info* info) +{ @@ -830,53 +1002,79 @@ index 0000000..721b099 +{ +} + -+ -+void BGLView::FrameResized(float width, float height) { -+ BView::FrameResized(width, height); -+ PthreadMutexLocker lock(&fRenderer->fLock); -+ fRenderer->width = (uint32_t)width + 1; -+ fRenderer->height = (uint32_t)height + 1; ++void BGLView::FrameResized(float width, float height) ++{ ++ BView::FrameResized(width, height); ++ PthreadMutexLocker lock(&fRenderer->fLock); ++ fRenderer->width = (uint32_t)width + 1; ++ fRenderer->height = (uint32_t)height + 1; +} + + +// forward to base class -+void BGLView::AllAttached() {BView::AllAttached();} -+void BGLView::DetachedFromWindow() {BView::DetachedFromWindow();} -+void BGLView::AllDetached() {BView::AllDetached();} -+status_t BGLView::Perform(perform_code d, void* arg) {return BView::Perform(d, arg);} -+status_t BGLView::Archive(BMessage* data, bool deep) const {return BView::Archive(data, deep);} -+void BGLView::MessageReceived(BMessage* msg) {BView::MessageReceived(msg);} -+void BGLView::SetResizingMode(uint32 mode) {BView::SetResizingMode(mode);} -+void BGLView::Show() {BView::Show();} -+void BGLView::Hide() {BView::Hide();} -+BHandler* BGLView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, int32 form, const char* property) -+{return BView::ResolveSpecifier(msg, index, specifier, form, property);} -+status_t BGLView::GetSupportedSuites(BMessage* data) {return BView::GetSupportedSuites(data);} -+ -+ -+void -+BGLView::_LockDraw() -+{ -+ if (!fClipInfo || !fClipInfo->enable_direct_mode) -+ return; -+ -+ fDrawLock.Lock(); ++void BGLView::AllAttached() { ++ BView::AllAttached(); +} + -+ -+void -+BGLView::_UnlockDraw() -+{ -+ if (!fClipInfo || !fClipInfo->enable_direct_mode) -+ return; -+ -+ fDrawLock.Unlock(); ++void BGLView::DetachedFromWindow() { ++ BView::DetachedFromWindow(); +} + ++void BGLView::AllDetached() { ++ BView::AllDetached(); ++} ++ ++status_t BGLView::Perform(perform_code d, void* arg) { ++ return BView::Perform(d, arg); ++} ++ ++status_t BGLView::Archive(BMessage* data, bool deep) const { ++ return BView::Archive(data, deep); ++} ++ ++void BGLView::MessageReceived(BMessage* msg) { ++ BView::MessageReceived(msg); ++} ++ ++void BGLView::SetResizingMode(uint32 mode) { ++ BView::SetResizingMode(mode); ++} ++ ++void BGLView::Show() { ++ BView::Show(); ++} ++ ++void BGLView::Hide() { ++ BView::Hide(); ++} ++ ++BHandler* BGLView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, ++ int32 form, const char* property) { ++ return BView::ResolveSpecifier(msg, index, specifier, form, property); ++} ++ ++status_t BGLView::GetSupportedSuites(BMessage* data) { ++ return BView::GetSupportedSuites(data); ++} ++ ++void BGLView::_LockDraw() ++{ ++ if (!fClipInfo || !fClipInfo->enable_direct_mode) ++ return; ++ ++ fDrawLock.Lock(); ++} ++ ++void BGLView::_UnlockDraw() ++{ ++ if (!fClipInfo || !fClipInfo->enable_direct_mode) ++ return; ++ ++ fDrawLock.Unlock(); ++} + +//---- virtual reserved methods ---------- + -+ +void BGLView::_ReservedGLView1() {} +void BGLView::_ReservedGLView2() {} +void BGLView::_ReservedGLView3() {} @@ -886,47 +1084,42 @@ index 0000000..721b099 +void BGLView::_ReservedGLView7() {} +void BGLView::_ReservedGLView8() {} + -+ +// #pragma mark - + -+ -+ +const char* color_space_name(color_space space) +{ -+#define C2N(a) case a: return #a ++#define C2N(a) case a: return #a + -+ switch (space) { -+ C2N(B_RGB24); -+ C2N(B_RGB32); -+ C2N(B_RGBA32); -+ C2N(B_RGB32_BIG); -+ C2N(B_RGBA32_BIG); -+ C2N(B_GRAY8); -+ C2N(B_GRAY1); -+ C2N(B_RGB16); -+ C2N(B_RGB15); -+ C2N(B_RGBA15); -+ C2N(B_CMAP8); -+ default: -+ return "Unknown!"; -+ }; ++ switch (space) { ++ C2N(B_RGB24); ++ C2N(B_RGB32); ++ C2N(B_RGBA32); ++ C2N(B_RGB32_BIG); ++ C2N(B_RGBA32_BIG); ++ C2N(B_GRAY8); ++ C2N(B_GRAY1); ++ C2N(B_RGB16); ++ C2N(B_RGB15); ++ C2N(B_RGBA15); ++ C2N(B_CMAP8); ++ default: ++ return "Unknown!"; ++ }; + +#undef C2N +}; + -+ +glview_direct_info::glview_direct_info() +{ -+ // TODO: See direct_window_data() in app_server's ServerWindow.cpp -+ direct_info = (direct_buffer_info*)calloc(1, DIRECT_BUFFER_INFO_AREA_SIZE); -+ direct_connected = false; -+ enable_direct_mode = false; ++ // TODO: See direct_window_data() in app_server's ServerWindow.cpp ++ direct_info = (direct_buffer_info*)calloc(1, DIRECT_BUFFER_INFO_AREA_SIZE); ++ direct_connected = false; ++ enable_direct_mode = false; +} + -+ +glview_direct_info::~glview_direct_info() +{ -+ free(direct_info); ++ free(direct_info); +} diff --git a/src/HGL/libgl.c b/src/HGL/libgl.c new file mode 100644 @@ -995,7 +1188,7 @@ index 0000000..e13571d +} diff --git a/src/HGL/meson.build b/src/HGL/meson.build new file mode 100644 -index 0000000..993e890 +index 0000000..601fab7 --- /dev/null +++ b/src/HGL/meson.build @@ -0,0 +1,53 @@ @@ -1033,7 +1226,7 @@ index 0000000..993e890 + ], + include_directories : [ + inc_include, -+ inc_include_opengl, ++ inc_include_hgl, + '/boot/system/develop/headers/private/shared' + ], + link_args : '-Wl,-Bsymbolic', @@ -1053,14 +1246,14 @@ index 0000000..993e890 + version : '1.2', +) diff --git a/src/meson.build b/src/meson.build -index bedb18c..6ff7fcd 100644 +index bedb18c..db489ae 100644 --- a/src/meson.build +++ b/src/meson.build @@ -35,6 +35,10 @@ if with_glx subdir('GL') endif -+if get_option('hgl') ++if with_hgl + subdir('HGL') +endif + @@ -1070,10 +1263,95 @@ index bedb18c..6ff7fcd 100644 -- 2.37.3 -From 3dfe88c61f03d72af5e98fcebf5c859cea2d2853 Mon Sep 17 00:00:00 2001 +From 51138d2b5af83bd0209e926123ae377bcb69c2cd Mon Sep 17 00:00:00 2001 +From: Alexander von Gluck IV +Date: Tue, 28 Mar 2023 20:54:14 -0500 +Subject: [PATCH 4/6] symbols-check: Add Haiku platform symbols + +--- + bin/symbols-check.py | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/bin/symbols-check.py b/bin/symbols-check.py +index 6049cbe..947105f 100644 +--- a/bin/symbols-check.py ++++ b/bin/symbols-check.py +@@ -52,8 +52,11 @@ PLATFORM_SYMBOLS = [ + '_fbss', + '_fdata', + '_ftext', ++ '_gSharedObjectHaikuABI', ++ '_gSharedObjectHaikuVersion', + ] + ++ + def get_symbols_nm(nm, lib): + ''' + List all the (non platform-specific) symbols exported by the library +@@ -68,7 +71,7 @@ def get_symbols_nm(nm, lib): + if len(fields) == 2 or fields[1] == 'U': + continue + symbol_name = fields[0] +- if platform_name == 'Linux' or platform_name == 'GNU' or platform_name.startswith('GNU/'): ++ if platform_name in ['Linux', 'GNU', 'Haiku'] or platform_name.startswith('GNU/'): + if symbol_name in PLATFORM_SYMBOLS: + continue + elif platform_name == 'Darwin': +-- +2.37.3 + +From 249b2cefed2aa76e16ffef8ea8d1cef9a5cbc42b Mon Sep 17 00:00:00 2001 +From: Alexander von Gluck IV +Date: Wed, 29 Mar 2023 07:20:39 -0500 +Subject: [PATCH 5/6] tests/egl: Fix LIBRARY_PATH on Haiku + +--- + tests/eglenv.sh | 10 ++++++++-- + tests/meson.build | 6 +++++- + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/tests/eglenv.sh b/tests/eglenv.sh +index 8237ce5..3b1c026 100644 +--- a/tests/eglenv.sh ++++ b/tests/eglenv.sh +@@ -3,5 +3,11 @@ + __EGL_VENDOR_LIBRARY_DIRS=$TOP_SRCDIR/tests/json + export __EGL_VENDOR_LIBRARY_DIRS + +-LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TOP_BUILDDIR/tests/dummy/.libs +-export LD_LIBRARY_PATH ++PLATFORM=$(uname -s) ++if test $PLATFORM -eq "Haiku"; then ++ LIBRARY_PATH=$LIBRARY_PATH:$TOP_BUILDDIR/tests/dummy/.libs ++ export LIBRARY_PATH ++else ++ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TOP_BUILDDIR/tests/dummy/.libs ++ export LD_LIBRARY_PATH ++fi +diff --git a/tests/meson.build b/tests/meson.build +index 3be62b7..521834c 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -60,7 +60,11 @@ test( + suite : ['gldispatch'], + ) + +-_env_ld = 'LD_LIBRARY_PATH=@0@/'.format(dummy_build_dir) ++if host_machine.system() in ['haiku'] ++ _env_ld = 'LIBRARY_PATH=@0@:/boot/system/lib'.format(dummy_build_dir) ++else ++ _env_ld = 'LD_LIBRARY_PATH=@0@'.format(dummy_build_dir) ++endif + + if with_glx + env_glx = [ +-- +2.37.3 + +From 782351619d8d804ccbd8aad43bf04f831048dd3e Mon Sep 17 00:00:00 2001 From: X512 Date: Wed, 25 Jan 2023 03:40:07 +0900 -Subject: [PATCH 2/2] fix crash on library unload +Subject: [PATCH 6/6] fix crash on library unload --- src/EGL/libeglcurrent.c | 2 ++