--- /dev/null
+From: =?utf-8?q?Timo_R=C3=B6hling?= <roehling@debian.org>
+Date: Wed, 26 Jan 2022 17:40:16 +0100
+Subject: Replace BlueGL with GLEW
+
+---
+ CMakeLists.txt | 1 -
+ filament/backend/CMakeLists.txt | 10 +-
+ filament/backend/src/opengl/OpenGLDriver.cpp | 4 +-
+ filament/backend/src/opengl/PlatformGLX.cpp | 155 ++++-----------------------
+ filament/backend/src/opengl/PlatformGLX.h | 6 +-
+ filament/backend/src/opengl/gl_headers.h | 3 +-
+ 6 files changed, 36 insertions(+), 143 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index a95c557..5c117c3 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -650,7 +650,6 @@ if (WEBGL)
+ endif()
+
+ if (IS_HOST_PLATFORM)
+- add_subdirectory(${LIBRARIES}/bluegl)
+ add_subdirectory(${LIBRARIES}/filamentapp)
+ add_subdirectory(${LIBRARIES}/imageio)
+
+diff --git a/filament/backend/CMakeLists.txt b/filament/backend/CMakeLists.txt
+index f61faee..7a1ba64 100644
+--- a/filament/backend/CMakeLists.txt
++++ b/filament/backend/CMakeLists.txt
+@@ -285,11 +285,6 @@ endif()
+ target_link_libraries(${TARGET} PUBLIC filament::math)
+ target_link_libraries(${TARGET} PUBLIC filament::utils)
+
+-# Android, iOS, and WebGL do not use bluegl.
+-if(NOT IOS AND NOT ANDROID AND NOT WEBGL)
+- target_link_libraries(${TARGET} PRIVATE bluegl)
+-endif()
+-
+ if (FILAMENT_SUPPORTS_VULKAN)
+ target_link_libraries(${TARGET} PRIVATE bluevk vkmemalloc vkshaders smol-v)
+ endif()
+@@ -299,8 +294,13 @@ if (FILAMENT_SUPPORTS_METAL)
+ endif()
+
+ if (LINUX)
++ find_package(X11 REQUIRED)
++ find_package(GLEW REQUIRED)
++ find_package(OpenGL REQUIRED)
+ target_link_libraries(${TARGET} PUBLIC Threads::Threads)
+ target_link_libraries(${TARGET} PRIVATE dl)
++ target_link_libraries(${TARGET} PRIVATE ${X11_X11_LIB})
++ target_link_libraries(${TARGET} PRIVATE GLEW::GLEW OpenGL::GL)
+ endif()
+
+ # ==================================================================================================
+diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp
+index 9b7135f..5ccf074 100644
+--- a/filament/backend/src/opengl/OpenGLDriver.cpp
++++ b/filament/backend/src/opengl/OpenGLDriver.cpp
+@@ -974,7 +974,7 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo,
+ // This extension only exists on OpenGL ES.
+ gl.bindFramebuffer(GL_FRAMEBUFFER, rt->gl.fbo);
+ if (any(t->usage & TextureUsage::SAMPLEABLE)) {
+- glext::glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER,
++ glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER,
+ attachment, target, t->gl.id, binfo.level, rt->gl.samples);
+ } else {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment,
+@@ -1073,7 +1073,7 @@ void OpenGLDriver::renderBufferStorage(GLuint rbo, GLenum internalformat, uint32
+ auto& gl = mContext;
+ if (gl.ext.EXT_multisampled_render_to_texture ||
+ gl.ext.EXT_multisampled_render_to_texture2) {
+- glext::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, internalformat, width, height);
++ glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, internalformat, width, height);
+ } else
+ #endif
+ {
+diff --git a/filament/backend/src/opengl/PlatformGLX.cpp b/filament/backend/src/opengl/PlatformGLX.cpp
+index b5cb484..665fde3 100644
+--- a/filament/backend/src/opengl/PlatformGLX.cpp
++++ b/filament/backend/src/opengl/PlatformGLX.cpp
+@@ -20,131 +20,35 @@
+ #include <utils/Panic.h>
+
+ #include <X11/Xlib.h>
+-#include <GL/glx.h>
++#include <GL/glew.h>
++#include <GL/glxew.h>
+ #include <GL/glxext.h>
+
+ #include "OpenGLDriverFactory.h"
+
+-#include <dlfcn.h>
+-
+-#define LIBRARY_GLX "libGL.so.1"
+-#define LIBRARY_X11 "libX11.so.6"
+-
+-// Function pointer types for X11 functions
+-typedef Display* (* X11_OPEN_DISPLAY)(const char*);
+-typedef Display* (* X11_CLOSE_DISPLAY)(Display*);
+-
+-// Function pointer types for GLX functions
+-typedef void (* GLX_DESTROY_CONTEXT)(Display*, GLXContext);
+-typedef void (* GLX_SWAP_BUFFERS)(Display* dpy, GLXDrawable drawable);
+-// Stores GLX function pointers and a handle to the system's GLX library
+-struct GLXFunctions {
+- PFNGLXCHOOSEFBCONFIGPROC chooseFbConfig;
+- PFNGLXCREATECONTEXTATTRIBSARBPROC createContext;
+- PFNGLXCREATEPBUFFERPROC createPbuffer;
+- PFNGLXDESTROYPBUFFERPROC destroyPbuffer;
+- PFNGLXMAKECONTEXTCURRENTPROC setCurrentContext;
+-
+- /*
+- When creating a shared GL context, we query the used
+- GLX_FBCONFIG_ID to make sure our display framebuffer
+- attributes match; otherwise making our context current
+- results in a BadMatch
+- https://gist.github.com/roxlu/c282d642c353ce96ef19b6359c741bcb
+- */
+- PFNGLXQUERYCONTEXTPROC queryContext;
+-
+- /*
+- When creating a shared GL context, we select the matching
+- GLXFBConfig that is used by the shared GL context. `getFBConfigs`
+- will return all the available GLXFBConfigs.
+- */
+- PFNGLXGETFBCONFIGSPROC getFbConfigs;
+-
+- /*
+- When creating a shared GL contect, we iterate over the
+- available GLXFBConfigs that are returned by `getFBConfigs`,
+- we use `getFbConfigAttrib` to find the matching
+- `GLX_FBCONFIG_ID`.
+- */
+- PFNGLXGETFBCONFIGATTRIBPROC getFbConfigAttrib;
+-
+- GLX_DESTROY_CONTEXT destroyContext;
+- GLX_SWAP_BUFFERS swapBuffers;
+- void* library;
+-} g_glx;
+-
+-// Stores X11 function pointers and a handle to the system's X11 library
+-struct X11Functions {
+- X11_OPEN_DISPLAY openDisplay;
+- X11_CLOSE_DISPLAY closeDisplay;
+- void* library;
+-} g_x11;
+-
+-static PFNGLXGETPROCADDRESSPROC getProcAddress;
+-
+-static bool loadLibraries() {
+- g_glx.library = dlopen(LIBRARY_GLX, RTLD_LOCAL | RTLD_NOW);
+- if (!g_glx.library) {
+- utils::slog.e << "Could not find library " << LIBRARY_GLX << utils::io::endl;
+- return false;
+- }
+-
+- getProcAddress =
+- (PFNGLXGETPROCADDRESSPROC)dlsym(g_glx.library, "glXGetProcAddressARB");
+-
+- g_glx.chooseFbConfig = (PFNGLXCHOOSEFBCONFIGPROC)
+- getProcAddress((const GLubyte*)"glXChooseFBConfig");
+- g_glx.createContext = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
+- getProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
+- g_glx.createPbuffer = (PFNGLXCREATEPBUFFERPROC)
+- getProcAddress((const GLubyte*)"glXCreatePbuffer");
+- g_glx.destroyPbuffer = (PFNGLXDESTROYPBUFFERPROC)
+- getProcAddress((const GLubyte*)"glXDestroyPbuffer");
+- g_glx.setCurrentContext = (PFNGLXMAKECONTEXTCURRENTPROC)
+- getProcAddress((const GLubyte*)"glXMakeContextCurrent");
+- g_glx.destroyContext = (GLX_DESTROY_CONTEXT)
+- getProcAddress((const GLubyte*)"glXDestroyContext");
+- g_glx.swapBuffers = (GLX_SWAP_BUFFERS)
+- getProcAddress((const GLubyte*)"glXSwapBuffers");
+-
+- g_glx.queryContext = (PFNGLXQUERYCONTEXTPROC)
+- getProcAddress((const GLubyte*)"glXQueryContext");
+- g_glx.getFbConfigs = (PFNGLXGETFBCONFIGSPROC)
+- getProcAddress((const GLubyte*)"glXGetFBConfigs");
+- g_glx.getFbConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)
+- getProcAddress((const GLubyte*)"glXGetFBConfigAttrib");
+-
+- g_x11.library = dlopen(LIBRARY_X11, RTLD_LOCAL | RTLD_NOW);
+- if (!g_x11.library) {
+- utils::slog.e << "Could not find library " << LIBRARY_X11 << utils::io::endl;
+- return false;
+- }
+-
+- g_x11.openDisplay = (X11_OPEN_DISPLAY)dlsym(g_x11.library, "XOpenDisplay");
+- g_x11.closeDisplay = (X11_CLOSE_DISPLAY)dlsym(g_x11.library, "XCloseDisplay");
+- return true;
+-}
+-
+ namespace filament {
+
+ using namespace backend;
+
+ Driver* PlatformGLX::createDriver(void* const sharedGLContext) noexcept {
+- loadLibraries();
+ // Get the display device
+- mGLXDisplay = g_x11.openDisplay(NULL);
++ mGLXDisplay = XOpenDisplay(NULL);
+ if (mGLXDisplay == nullptr) {
+ utils::slog.e << "Failed to open X display. (exiting)." << utils::io::endl;
+ exit(1);
+ }
++ if (glewInit() != GLEW_OK)
++ {
++ utils::slog.e << "Failed to initialize GLEW. (exiting)." << utils::io::endl;
++ exit(1);
++ }
+
+ if (sharedGLContext != nullptr) {
+ int r = -1;
+ int usedFbId = -1;
+ GLXContext sharedCtx = (GLXContext)((void*)sharedGLContext);
+
+- r = g_glx.queryContext(mGLXDisplay, sharedCtx, GLX_FBCONFIG_ID, &usedFbId);
++ r = glXQueryContext(mGLXDisplay, sharedCtx, GLX_FBCONFIG_ID, &usedFbId);
+ if (r != 0) {
+ utils::slog.e << "Failed to get GLX_FBCONFIG_ID from shared GL context."
+ << utils::io::endl;
+@@ -152,7 +56,7 @@ Driver* PlatformGLX::createDriver(void* const sharedGLContext) noexcept {
+ }
+
+ int numConfigs = 0;
+- GLXFBConfig* fbConfigs = g_glx.getFbConfigs(mGLXDisplay, 0, &numConfigs);
++ GLXFBConfig* fbConfigs = glXGetFBConfigs(mGLXDisplay, 0, &numConfigs);
+
+ if (fbConfigs == nullptr) {
+ utils::slog.e << "Failed to get the available GLXFBConfigs." << utils::io::endl;
+@@ -163,7 +67,7 @@ Driver* PlatformGLX::createDriver(void* const sharedGLContext) noexcept {
+ int fbIndex = -1;
+
+ for (int i = 0; i < numConfigs; ++i) {
+- r = g_glx.getFbConfigAttrib(mGLXDisplay, fbConfigs[i], GLX_FBCONFIG_ID, &fbId);
++ r = glXGetFBConfigAttrib(mGLXDisplay, fbConfigs[i], GLX_FBCONFIG_ID, &fbId);
+ if (r != 0) {
+ utils::slog.e << "Failed to get GLX_FBCONFIG_ID for entry " << i << "."
+ << utils::io::endl;
+@@ -192,29 +96,20 @@ Driver* PlatformGLX::createDriver(void* const sharedGLContext) noexcept {
+ };
+
+ int configCount = 0;
+- mGLXConfig = g_glx.chooseFbConfig(mGLXDisplay, DefaultScreen(mGLXDisplay),
++ mGLXConfig = glXChooseFBConfig(mGLXDisplay, DefaultScreen(mGLXDisplay),
+ attribs, &configCount);
+ if (mGLXConfig == nullptr || configCount == 0) {
+ return nullptr;
+ }
+ }
+
+- PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
+- getProcAddress((GLubyte*)"glXCreateContextAttribsARB");
+-
+- if (glXCreateContextAttribs == nullptr) {
+- utils::slog.i << "Unable to retrieve function pointer for `glXCreateContextAttribs()`."
+- << utils::io::endl;
+- return nullptr;
+- }
+-
+ int contextAttribs[] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 1,
+ GL_NONE
+ };
+
+- mGLXContext = g_glx.createContext(mGLXDisplay, mGLXConfig[0],
++ mGLXContext = glXCreateContextAttribsARB(mGLXDisplay, mGLXConfig[0],
+ (GLXContext)sharedGLContext, True, contextAttribs);
+
+ int pbufferAttribs[] = {
+@@ -223,21 +118,17 @@ Driver* PlatformGLX::createDriver(void* const sharedGLContext) noexcept {
+ GL_NONE
+ };
+
+- mDummySurface = g_glx.createPbuffer(mGLXDisplay, mGLXConfig[0], pbufferAttribs);
+- g_glx.setCurrentContext(mGLXDisplay, mDummySurface, mDummySurface, mGLXContext);
+-
+- int result = bluegl::bind();
+- ASSERT_POSTCONDITION(!result, "Unable to load OpenGL entry points.");
++ mDummySurface = glXCreatePbuffer(mGLXDisplay, mGLXConfig[0], pbufferAttribs);
++ glXMakeContextCurrent(mGLXDisplay, mDummySurface, mDummySurface, mGLXContext);
+
+ return OpenGLDriverFactory::create(this, sharedGLContext);
+ }
+
+ void PlatformGLX::terminate() noexcept {
+- g_glx.setCurrentContext(mGLXDisplay, None, None, nullptr);
+- g_glx.destroyPbuffer(mGLXDisplay, mDummySurface);
+- g_glx.destroyContext(mGLXDisplay, mGLXContext);
+- g_x11.closeDisplay(mGLXDisplay);
+- bluegl::unbind();
++ glXMakeContextCurrent(mGLXDisplay, None, None, nullptr);
++ glXDestroyPbuffer(mGLXDisplay, mDummySurface);
++ glXDestroyContext(mGLXDisplay, mGLXContext);
++ XCloseDisplay(mGLXDisplay);
+ }
+
+ Platform::SwapChain* PlatformGLX::createSwapChain(void* nativeWindow, uint64_t& flags) noexcept {
+@@ -255,7 +146,7 @@ Platform::SwapChain* PlatformGLX::createSwapChain(
+ GLX_PBUFFER_HEIGHT, int(height),
+ GL_NONE
+ };
+- GLXPbuffer sur = g_glx.createPbuffer(mGLXDisplay, mGLXConfig[0], pbufferAttribs);
++ GLXPbuffer sur = glXCreatePbuffer(mGLXDisplay, mGLXConfig[0], pbufferAttribs);
+ if (sur) {
+ mPBuffers.push_back(sur);
+ }
+@@ -265,19 +156,19 @@ Platform::SwapChain* PlatformGLX::createSwapChain(
+ void PlatformGLX::destroySwapChain(Platform::SwapChain* swapChain) noexcept {
+ auto it = std::find(mPBuffers.begin(), mPBuffers.end(), (GLXPbuffer)swapChain);
+ if (it != mPBuffers.end()) {
+- g_glx.destroyPbuffer(mGLXDisplay, (GLXPbuffer)swapChain);
++ glXDestroyPbuffer(mGLXDisplay, (GLXPbuffer)swapChain);
+ mPBuffers.erase(it);
+ }
+ }
+
+ void PlatformGLX::makeCurrent(
+ Platform::SwapChain* drawSwapChain, Platform::SwapChain* readSwapChain) noexcept {
+- g_glx.setCurrentContext(mGLXDisplay,
++ glXMakeContextCurrent(mGLXDisplay,
+ (GLXDrawable)drawSwapChain, (GLXDrawable)readSwapChain, mGLXContext);
+ }
+
+ void PlatformGLX::commit(Platform::SwapChain* swapChain) noexcept {
+- g_glx.swapBuffers(mGLXDisplay, (GLXDrawable)swapChain);
++ glXSwapBuffers(mGLXDisplay, (GLXDrawable)swapChain);
+ }
+
+ // TODO Implement GLX fences
+diff --git a/filament/backend/src/opengl/PlatformGLX.h b/filament/backend/src/opengl/PlatformGLX.h
+index 45c3abf..e867c4c 100644
+--- a/filament/backend/src/opengl/PlatformGLX.h
++++ b/filament/backend/src/opengl/PlatformGLX.h
+@@ -19,8 +19,10 @@
+
+ #include <stdint.h>
+
+-#include <bluegl/BlueGL.h>
+-#include <GL/glx.h>
++#include <GL/glew.h>
++#include <GL/glext.h>
++#include <GL/glxew.h>
++#include <GL/glxext.h>
+
+ #include <backend/DriverEnums.h>
+
+diff --git a/filament/backend/src/opengl/gl_headers.h b/filament/backend/src/opengl/gl_headers.h
+index 32ca122..cdbf6fc 100644
+--- a/filament/backend/src/opengl/gl_headers.h
++++ b/filament/backend/src/opengl/gl_headers.h
+@@ -103,7 +103,8 @@
+ #endif
+
+ #else
+- #include <bluegl/BlueGL.h>
++ #include <GL/glew.h>
++ #include <GL/glext.h>
+ #endif
+
+ // This is just to simplify the implementation (i.e. so we don't have to have #ifdefs everywhere)