Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression to access to glInitFramebufferObjectARB in v3.1.6 #88

Open
vallsv opened this issue Dec 14, 2022 · 4 comments
Open

Regression to access to glInitFramebufferObjectARB in v3.1.6 #88

vallsv opened this issue Dec 14, 2022 · 4 comments

Comments

@vallsv
Copy link

vallsv commented Dec 14, 2022

Hi,

I have a problem with some of my machine with project using PyOpenGL.

It looks like, with exact same env, the capability glInitFramebufferObjectARB

  • Is available with pyopenhl 3.1.5
  • Is NOT available with pyopengl 3.1.6

Do you think it's a regression?

Do you think there is a wrong use on my script?

How can i help you to find the problem?

With 3.1.5

In [1]: import pygame as pg
In [2]: pg.init()
In [3]: import OpenGL.GL
In [5]: from pygame.locals import *
   ...: from OpenGL.GL import *
   ...: from OpenGL.GLU import *
In [6]: pg.display.set_mode((50, 50), DOUBLEBUF|OPENGL)
In [9]: OpenGL.GL.glGetString(OpenGL.GL.GL_VERSION)
Out[9]: b'3.0 Mesa 18.3.6'
In [10]: from OpenGL.GL.ARB.framebuffer_object import glInitFramebufferObjectARB
In [11]: glInitFramebufferObjectARB()
Out[11]: True
In [12]: OpenGL.__version__
Out[12]: '3.1.5'

With 3.1.6

In [1]: import pygame as pg
In [2]: from pygame.locals import *
   ...: from OpenGL.GL import *
   ...: from OpenGL.GLU import *
In [3]: pg.display.set_mode((50, 50), DOUBLEBUF|OPENGL)
In [4]: OpenGL.GL.glGetString(OpenGL.GL.GL_VERSION)
Out[4]: b'3.0 Mesa 18.3.6'
In [5]: from OpenGL.GL.ARB.framebuffer_object import glInitFramebufferObjectARB
In [6]: glInitFramebufferObjectARB()
Out[6]: False
In [7]: OpenGL.__version__
Out[7]: '3.1.6'
@vallsv
Copy link
Author

vallsv commented Dec 15, 2022

If i launch my application with the env PYOPENGL_PLATFORM=linux it works well.

Here is my env

WAYLAND_DISPLAY=wayland-0
DISPLAY=:0
XDG_SESSION_TYPE=wayland

@mcfletch
Copy link
Owner

mcfletch commented Jan 5, 2023

So this seems like a side-effect from enhancing support for wayland. Specifically it looks like the code that checks to see whether we are using wayland is passing (i.e. it says "this is a wayland environment") but pygame is AFAICT using x-wayland to run.

If you try to make pygame use wayland (with SDL_VIDEODRIVER=wayland) it bombs out claiming there's no wayland available (possibly because an underlying library wasn't compiled for wayland). Under the covers what's likely happening here is that the call to isContextValid() is failing because it's checking for an EGL context, and the pygame context is a glX context. The older version, being less "smart" was just saying "oh, this is linux, great, use X" and so ignoring the wayland setup.

Not really sure what the correct solution is here, options:

  • demand the user specify the egl/glx platform (blah)
  • create a probe that loads egl and glx and tests for either context being valid, switching to using that platform plugin after the first context is created (does this run into cases where people want to use both egl and glx? I think that rather unlikely, but who knows).
  • Is there really any "right" answer until the user says "hey, I'm going to use X here" and is there some way to see that has occurred (like an XIsInitialised()). Find something inside the glX setup that any X-using program would do that lets us detect that "even though this is wayland, we are using glx, not egl"
  • specifically hack around with detecting Pygame to switch to glX platform?
  • ignore wayland presence and always use glx on linux

For instance, this patch "fixes" the immediate issue (but with a huge run-time cost, so not likely to land)

diff --git a/OpenGL/extensions.py b/OpenGL/extensions.py
index d4af5b68..a3e8c408 100644
--- a/OpenGL/extensions.py
+++ b/OpenGL/extensions.py
@@ -193,6 +193,8 @@ class _GLQuerier( ExtensionQuerier ):
             else:
                 break
         return extensions
+
+
 GLQuerier = _GLQuerier()
 class _GLUQuerier( ExtensionQuerier ):
     prefix = as_8_bit('GLU_')
diff --git a/OpenGL/platform/egl.py b/OpenGL/platform/egl.py
index e74f3dd8..0edfbbf6 100644
--- a/OpenGL/platform/egl.py
+++ b/OpenGL/platform/egl.py
@@ -64,6 +64,12 @@ class EGLPlatform( baseplatform.BasePlatform ):
             return None
     @baseplatform.lazy_property
     def OpenGL(self): return self.GL
+    @baseplatform.lazy_property
+    def GLX(self):
+        try:
+            return ctypesloader.loadLibrary(ctypes.cdll, "GLX", mode=ctypes.RTLD_GLOBAL)
+        except OSError as err:
+            return self.GL
     
     @baseplatform.lazy_property
     def EGL(self):
@@ -103,4 +109,6 @@ class EGLPlatform( baseplatform.BasePlatform ):
     DEFAULT_FUNCTION_TYPE = staticmethod( ctypes.CFUNCTYPE )
     @baseplatform.lazy_property
     def GetCurrentContext( self ):
-        return self.EGL.eglGetCurrentContext
+        def either(*args):
+            return self.EGL.eglGetCurrentContext(*args) or self.GLX.glXGetCurrentContext(*args)
+        return either
diff --git a/OpenGL/platform/glx.py b/OpenGL/platform/glx.py
index c67e9cf6..33b515be 100644
--- a/OpenGL/platform/glx.py
+++ b/OpenGL/platform/glx.py
@@ -40,7 +40,6 @@ class GLXPlatform(baseplatform.BasePlatform):
         except OSError:
             return None
 
-    # GLX doesn't seem to have its own loadable module?
     @baseplatform.lazy_property
     def GLX(self):
         try:

@t20100
Copy link
Contributor

t20100 commented Jan 5, 2023

The same issue is there with PyQt|PySide depending on the Qt Platform Abstraction in use.

No matter of the default detection mechanism, wouldn't it make sense/be possible to have an way to set the platform programmatically?

For instance, with PyQt|PySide, it is possible to retrieve the platform at runtime with QGuiApplication.platformName, and that could be used to set it in pyopengl.

@mcfletch
Copy link
Owner

mcfletch commented Jan 6, 2023

Sure, having it be a thing you can set via code is fine. But it has to be set basically at import-time to avoid funky issues, so you wind up with a thin wrapper around setting the PYOPENGL_PLATFORM environment variable before import. Just added a function OpenGl.setPlatform('glx') which is just that, but it's meh IMO.

What I was looking for was a way to properly select the platform automatically. The primary concern being that I don't want to load e.g. a whole X-windows client library just to see if the process is running an X window, same issue with Qt/Gtk/etc. Way too heavy-weight to use for 'guess which approach to use'. Secondary concern is that the software doesn't have to start the X/Wayland connection immediately; and in theory at any moment it could make a choice to do X vs. Wayland... so until we see an actual rendering context there really isn't a right guess as to which type of context it is AFAICS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants