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

OS X with mesalib-glw: import pi3d fails #190

Open
John-P opened this issue Jan 26, 2016 · 44 comments
Open

OS X with mesalib-glw: import pi3d fails #190

John-P opened this issue Jan 26, 2016 · 44 comments

Comments

@John-P
Copy link

John-P commented Jan 26, 2016

Traceback (most recent call last):
  File "3dtest.py", line 1, in <module>
    import pi3d
  File "/usr/local/lib/python2.7/site-packages/pi3d/__init__.py", line 10, in <module>
    from pi3d.constants import *
  File "/usr/local/lib/python2.7/site-packages/pi3d/constants/__init__.py", line 145, in <module>
    PLATFORM, bcm, openegl, opengles = _detect_platform_and_load_libraries()
TypeError: 'NoneType' object is not iterable
@John-P John-P changed the title OS X with mesalib-glw: _detect_platform_and_load_libraries() fails OS X with mesalib-glw: import pi3d fails Jan 26, 2016
@John-P
Copy link
Author

John-P commented Jan 26, 2016

For me the mesa libraries installed via brew are in /usr/local/opt/mesalib-glw/lib/libGLw.1.0.dylib' (I think this is the right one) and needs to be added to def _darwin: in pi3d/pi3d/constants/__init__.py as in def _linux: to import the GL library.

@paddywwoof
Copy link
Collaborator

@John-P Hi, does pi3d run OK on OS X if you change pi3d/constants/init.py?

Did you try the ctypes.util find_library() as in _linux? There is also the PLATFORM constant that needs to be set for the correct drawing surface to be loaded in DisplayOpenGL.py What happens if you change the entry in _PLATFORMS to
'darwin': _linux,

I'm really keen to get this working but it will be tricky without a mac to test it on. If you're willing to try things I would be happy to help in whatever way I can.

@John-P
Copy link
Author

John-P commented Jan 27, 2016

@paddywwoof I'm happy to help get pi3d running on OS X. I'll take another look tonight and change my pi3d/constants/init.py to see if I can get it going.

@John-P
Copy link
Author

John-P commented Feb 2, 2016

OK. So looks like mesa is not needed on OS X (also the brew formula doesn't install the gles libraries) but xquartz is. OpenGL|ES libraries are located at: /opt/X11/lib/libGLESv2.dylib. I have added the following to my pi3d/constants/__init__.py:

def _darwin():
  platform = PLATFORM_OSX
  bcm = None
  opengles = _load_library('/opt/X11/lib/libGLESv2.dylib')
  openegl = _load_library('/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib')

  return platform, bcm, openegl, opengles # opengles now determined by platform

After googling apparently the OS X equivalent of EGL is CGL which I think is part of the OpenGL Library.

When trying to run a simple scene with a camera and a sphere I get this:

python ~/Desktop/3dtest.py
Traceback (most recent call last):
  File "/Users/John/Desktop/3dtest.py", line 5, in <module>
    import pi3d
  File "/usr/local/lib/python2.7/site-packages/pi3d/__init__.py", line 12, in <module>
    from pi3d import Display
  File "/usr/local/lib/python2.7/site-packages/pi3d/Display.py", line 13, in <module>
    from pi3d.util.DisplayOpenGL import DisplayOpenGL
  File "/usr/local/lib/python2.7/site-packages/pi3d/util/DisplayOpenGL.py", line 16, in <module>
    from pyxlib import xlib
  File "/usr/local/lib/python2.7/site-packages/pyxlib/__init__.py", line 2, in <module>
    from .xlib import *
  File "/usr/local/lib/python2.7/site-packages/pyxlib/xlib.py", line 2409, in <module>
    XLoadQueryFont = libX11.XLoadQueryFont
  File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 378, in __getattr__
    func = self.__getitem__(name)
  File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 383, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: dlsym(RTLD_DEFAULT, XLoadQueryFont): symbol not found

Currently stumped

@paddywwoof
Copy link
Collaborator

@John-P That's great stuff. Thanks for struggling on with this.

To translate the error messages: line 2409 in xlib.py is the first line where a function is assigned from the ctypes loaded dll/shared object libX11 which, in turn, should have been loaded in line 7 and 8

x11_name = find_library('X11')
libX11 = CDLL(x11_name) # was explicitly 'libX11.so.6'

So it looks like the xquartz library isn't known as X11 on the mac. Or it might need a hard coded path, presumably it's a .dylib file like the EGL and GLESv2 ones. (There are a few comments about the symlinks being scrambled by os upgrades but not relevant if you've just installed xquarts)

Alternatively if you can get pygame running on the mac (which looks quite an effort http://pygame.org/wiki/macintosh ) then you can set an argument use_pygame=True in Display.create() and the X11 stuff is handled by pygame.

@John-P
Copy link
Author

John-P commented Feb 2, 2016

@paddywwoof Pygame doesn't look too bad to install. Would be nice to get pi3d working with xquartz though. Will investigate and see if find_library('X11') is doing what I expect. It's night here though so off to bed for now.

@superkaii
Copy link

Hi! I'm also highly interested in running pi3d on OS X. I have made the modifications suggested in your conversation so far. Additionally, I modified line 8 in xlib.py to:

x11_name = '/opt/X11/lib/libX11.6.dylib'

This seems to solve the AttributeError: dlsym(RTLD_DEFAULT, XLoadQueryFont): symbol not found error. However, I now get a new error I didn't manage to fix:

Traceback (most recent call last):
  File "Earth.py", line 14, in <module>
    DISPLAY = pi3d.Display.create(x=50, y=50)
  File "/usr/local/lib/python2.7/site-packages/pi3d/Display.py", line 545, in create
    display.opengl.create_display(x, y, w, h, depth=depth, samples=samples, layer=layer, display_config=display_config)
  File "/usr/local/lib/python2.7/site-packages/pi3d/util/DisplayOpenGL.py", line 48, in create_display
    self.display = openegl.eglGetDisplay(EGL_DEFAULT_DISPLAY)
  File "/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 375, in __getattr__
    func = self.__getitem__(name)
  File "/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 380, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: dlsym(0x7fe9a37398a0, eglGetDisplay): symbol not found

@paddywwoof
Copy link
Collaborator

Hi, yes I would really like to get pi3d running on OSX too but I am not allowed to touch my wife's mac on pain of death (or worse). I looks to me like the error message is due to the ctypes shared library openegl not containing the function eglGetDisplay. Looking up at John-P's post that seems to be loaded with /System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib and I would expect it to use libEGL.dylib assuming it's following the same naming convention of linux and windows. Can you search on your system and see if there's a libEGL library anywhere?

@superkaii
Copy link

superkaii commented Nov 11, 2016

Hi! I'm running macOS 10.12.1 and I can not find libEGL anywhere ...
I also searched for a reference on how to install it on google but without any success. However I found this site:
http://nullege.com/codes/search/OpenGL.EGL.eglGetDisplay
which made me wonder if line 48 in util/DisplayOpenGL.py is working on a mac. The line is

self.display = openegl.eglGetDisplay(EGL_DEFAULT_DISPLAY)

but according to the site above, the call may be something like opengl.EGL.eglGetDisplay(EGL_DEFAULT_DISPLAY). Unfortunately, I wasn't able to find the import/definition of openegl so I'm stuck here.
Any ideas?

@paddywwoof
Copy link
Collaborator

Hi, The import definition for openegl is in pi3d/constants/init.py where you added the new function _darwin() as per John-P's post above. But I'm not sure that the required libraries are loaded with xquartz.

If you searched you computer for the file libEGL* and it wasn't there then that probably means you need to get it from somewhere. Did you install the mesalib-gwl brew? It looks from the docs that EGL support isn't included by default so you might need to compile your own. see
http://www.mesa3d.org/egl.html
I don't know how tricky it is to build stuff on mac!

Alternatively you could try a different tack by using ANGLE which seems to be quite actively supported (google etc) - but may have some bits to complete w.r.t. mac.
https://github.com/google/angle/blob/master/doc/DevSetup.md

@superkaii
Copy link

Hi again!
I did try to install mesalib-gwl with brew before, but that did not help with the missing libEGL.
Then I followed your suggestions and build libEGL from ANGLE:

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=`pwd`/depot_tools:"$PATH"
  • Build ANGLE
export GYP_GENERATORS="ninja"
git clone https://chromium.googlesource.com/angle/angle
cd angle
python scripts/bootstrap.py
gclient sync
git checkout master
ninja -C out/Release

The build ran without a problem and I got libEGL.dylib and libGLESv2.dylib.
Using these libs, I have a new error:

Traceback (most recent call last):
  File "Earth.py", line 14, in <module>
    DISPLAY = pi3d.Display.create(x=50, y=50)
  File "/usr/local/lib/python2.7/site-packages/pi3d/Display.py", line 545, in create
    display.opengl.create_display(x, y, w, h, depth=depth, samples=samples, layer=layer, display_config=display_config)
  File "/usr/local/lib/python2.7/site-packages/pi3d/util/DisplayOpenGL.py", line 79, in create_display
    assert self.context != EGL_NO_CONTEXT
AssertionError

@superkaii
Copy link

btw. all of my results are also true for OS X 10.11.6.

@paddywwoof
Copy link
Collaborator

paddywwoof commented Nov 14, 2016

Hi, well that's good news in some ways as python seems to be loading the libEGL library and managing to find the various functions called down to line 79. However one or other of them is not managing to come up with the goods. I don't know if it's relevant but I had similar symptoms trying to get pi3d working with windows, specifically on some set-ups, especially when using 64 bit python. If you look in pi3d/constants/__init__() you will see a section inside the _windows() function that attempts to fix the return and argument types for the various libEGL and libGLESv2 functions. After doing the ones listed I managed to get pi3d working with 64bit python on my windows10 laptop, however it still didn't get it working for @Shando. I've just checked it here on linux and it seems happy to have most of the lines moved from _windows() down to a position where they are run for all OSs i.e.

def _detect_platform_and_load_libraries():
  import platform

  platform_name = platform.system().lower()
  loader = _PLATFORMS.get(platform_name, None)
  if not loader:
    raise Exception("Couldn't understand platform %s" % platform_name)
  platform, bcm, openegl, opengles = loader()
  openegl.eglGetDisplay.restype = c_void_p
  openegl.eglInitialize.argtypes = [c_void_p, POINTER(c_int32), POINTER(c_int32)]
  openegl.eglChooseConfig.argtypes = [c_void_p, c_void_p, c_void_p, c_int32, POINTER(c_int32)]
  openegl.eglCreateContext.argtypes = [c_void_p, c_void_p, c_int32, c_void_p]
  openegl.eglCreateContext.restype = c_void_p
  openegl.eglCreateWindowSurface.argtypes = [c_void_p, c_void_p, c_void_p, c_int32]
  openegl.eglCreateWindowSurface.restype = c_void_p
  openegl.eglMakeCurrent.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p]
  openegl.eglSwapBuffers.argtypes = [c_void_p, c_void_p]

  opengles.glUniformMatrix4fv.argtypes = [c_int32, c_int32, c_int32, c_void_p]

  return platform, bcm, openegl, opengles

So that would also happen for _darwin() too. However I'm not aware of issues with 32 and 64 bit setups on linux and I would have thought OSX is a lot nearer to that than it is to windows.

Also, I will attach the script I used when trying to debug what wasn't working while trying to get pi3d working on windows just in case you can glean a bit more info using it.
test_egl.txt

@superkaii
Copy link

Hi! I don't have much time in the next view days, but I made the modifications to def _detect_platform_and_load_libraries(): (also had to add from ctypes import POINTER, c_void_p, c_int32, c_uint, c_float inside the function) which now results in these error messages:

  • not using pygame
python Earth.py 
Using hard coded path to libX11!
/opt/X11/lib/libX11.6.dylib
[1]    1888 trace trap  python Earth.py
  • using pygame:
python Earth.py
Using hard coded path to libX11!
/opt/X11/lib/libX11.6.dylib
2016-11-15 11:09:01.597 Python[2059:615784] 11:09:01.597 WARNING:  140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API's in AudioComponent.h.
Traceback (most recent call last):
  File "Earth.py", line 13, in <module>
    DISPLAY = pi3d.Display.create(x=50, y=50, use_pygame=True)
  File "/usr/local/lib/python2.7/site-packages/pi3d/Display.py", line 545, in create
    display.opengl.create_display(x, y, w, h, depth=depth, samples=samples, layer=layer, display_config=display_config)
  File "/usr/local/lib/python2.7/site-packages/pi3d/util/DisplayOpenGL.py", line 81, in create_display
    self.create_surface(x, y, w, h, layer)
  File "/usr/local/lib/python2.7/site-packages/pi3d/util/DisplayOpenGL.py", line 159, in create_surface
    self.window = pygame.display.get_wm_info()["window"]
KeyError: 'window'

I also ran your test_egl.txt script:

python test_egl.py        
Using hard coded path to libX11!
/opt/X11/lib/libX11.6.dylib
2016-11-15 11:10:14.024 Python[2093:622821] 11:10:14.023 WARNING:  140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API's in AudioComponent.h.
For ref
  EGL_FALSE=0x0000
  EGL_BAD_DISPLAY=0x3008
  EGL_BAD_ATTRIBUTE=0x3004
  EGL_NOT_INITIALIZED=0x3001
  EGL_BAD_PARAMETER=0x300C
  EGL_WINDOW_BIT=0x0004

1 0
2 0
3 0
4 0
5 0
6 0
got to #6/6 in a_list with display False
Traceback (most recent call last):
  File "test_egl.py", line 125, in <module>
    assert r == EGL_TRUE             #<<<<<<<<<<<<<<<<<<<<<<
AssertionError

@Cabalist
Copy link

Cabalist commented Jan 27, 2020

I'm using Python 3.7.5 and macOS 10.15.2 with pi3d 2.34

I'm using xquartz 2.7.11 installed with brew.

On import of pi3d I get this:

>>> import pi3d
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/work/.virtualenvs/xxx/lib/python3.7/site-packages/pi3d/__init__.py", line 10, in <module>
    from pi3d.constants import *
  File "/Users/work/.virtualenvs/xxx/lib/python3.7/site-packages/pi3d/constants/__init__.py", line 29, in <module>
    from pi3d.constants.egl import *
  File "/Users/work/.virtualenvs/xxx/lib/python3.7/site-packages/pi3d/constants/egl.py", line 6, in <module>
    from pyxlib.x import Window
  File "/Users/work/.virtualenvs/xxx/lib/python3.7/site-packages/pyxlib/__init__.py", line 2, in <module>
    from .xlib import *
  File "/Users/work/.virtualenvs/xxx/lib/python3.7/site-packages/pyxlib/xlib.py", line 2407, in <module>
    XLoadQueryFont = libX11.XLoadQueryFont
  File "/Users/work/.pyenv/versions/3.7.5/lib/python3.7/ctypes/__init__.py", line 377, in __getattr__
    func = self.__getitem__(name)
  File "/Users/work/.pyenv/versions/3.7.5/lib/python3.7/ctypes/__init__.py", line 382, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: dlsym(RTLD_DEFAULT, XLoadQueryFont): symbol not found

Since it is now 2020 I'd be happy to pick up the thread on this if someone is willing to offer some advice.

@paddywwoof
Copy link
Collaborator

paddywwoof commented Jan 27, 2020

Ryan, it would be great to get pi3d working on mac and your offer of help is great but it might be quite hard to work through the issues remotely. That error indicates that the first function to be used from the ctypes loaded library X11 isn't there. On my linux laptop (or raspberry pi with X11 installed)

$ python3
>>> import ctypes
>>> from ctypes.util import find_library
>>> x11_name = find_library('X11')
>>> x11_name
'libX11.so.6'
>>> libX11 = ctypes.CDLL(x11_name)
>>> libX11.XLoadQueryFont
<_FuncPtr object at 0x7f1ef9f62818>

See what you get on the mac with xquartz. You could try searching your machine for files with libX11 in their name. If you compile xquartz then the shared objects might have been created but not registered (don't really know that stuff works on darwin).

Paddy

PS, I am gradually working up a version of pi3d wrapping a Rust implementation here https://github.com/paddywwoof/rust_pi3d.git That system uses the slightly abstracted sdl2 and gl libraries and, hopefully, will just work on more OSs...

@Cabalist
Copy link

Cabalist commented Jan 28, 2020

Ah. I didn't realize this was more of a feature request then a bug report.

On my system I've got ibX11.6.dylib located at /opt/X11/lib/libX11.6.dylib

find_library('X11') returns None unless I run:
export DYLD_FALLBACK_LIBRARY_PATH="/opt/X11/lib:/usr/local/lib:/usr/lib"
then I get this:

>>> import ctypes
>>> from ctypes.util import find_library
>>> x11_name = find_library('X11')
>>> x11_name
'/opt/X11/lib/libX11.dylib'
>>> libX11 = ctypes.CDLL(x11_name)
>>> libX11.XLoadQueryFont
<_FuncPtr object at 0x1092b66d0>

At this point the error is now:

>>> import pi3d
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/work/.virtualenvs/Gakken-Eye-Tracker/lib/python3.7/site-packages/pi3d/__init__.py", line 10, in <module>
    from pi3d.constants import *
  File "/Users/work/.virtualenvs/Gakken-Eye-Tracker/lib/python3.7/site-packages/pi3d/constants/__init__.py", line 182, in <module>
    PLATFORM, bcm, openegl, opengles = _detect_platform_and_load_libraries()
  File "/Users/work/.virtualenvs/Gakken-Eye-Tracker/lib/python3.7/site-packages/pi3d/constants/__init__.py", line 175, in _detect_platform_and_load_libraries
    platform, bcm, openegl, opengles = loader()
TypeError: cannot unpack non-iterable NoneType object

This is caused by the loader in my case being _darwin() and the entirety of that code is:

def _darwin():
pass

Uh oh... :)

@paddywwoof
Copy link
Collaborator

Well that's actually progress. The function should have darwin specific code but if the required dylibs can be loaded on the basis of it being X11 there might not need to be anything in there. Ie it could just
return _linux()
Could you try loading EGL and GLESv2 in a python terminal as you did with X11 to see if the dylibs are available?

@Cabalist
Copy link

Cabalist commented Jan 28, 2020

That would be nice!

find_library('GLESv2') works and can be loaded by CDLL but find_library('EGL') returns None. Which library filename am I looking for here?

>>> find_library('GLESv2')
'/opt/X11/lib/libGLESv2.dylib'

>>> find_library('EGL')
>>>

@paddywwoof
Copy link
Collaborator

paddywwoof commented Jan 28, 2020

it's libEGL.dylib but googling that sounds like it might not be generally used on mac. Someone suggests downloading from https://moltengl.com/downloads/ (2nd link GLES2 etc) it should then be found by find_library if you put it somewhere on the sys.path i.e. in the current directory you run python from.

The alternative route might be to use GLX if that's available (check find_library('GLX') etc) If this library is there then you would need to add the argument use_glx=True to the Display.create() fn

Further thoughts scanning back through this thread. You could try using libGL.dylib something along the lines of (though I haven't been able to see what functions are supposed to be in libGL.dylib)

def _darwin():
  from ctypes.util import find_library
  platform = PLATFORM_OSX
  bcm = None
  opengles = _load_library(find_library("GLESv2"))
  openegl = _load_library(find_library("GL"))

  return platform, bcm, openegl, opengles # opengles now determined by platform

@Cabalist
Copy link

Well it seems I don't have GLX either.

Replacing _darwin() with the code you provide got me this:

>>> import pi3d
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/work/.virtualenvs/Gakken-Eye-Tracker/lib/python3.7/site-packages/pi3d/__init__.py", line 10, in <module>
    from pi3d.constants import *
  File "/Users/work/.virtualenvs/Gakken-Eye-Tracker/lib/python3.7/site-packages/pi3d/constants/__init__.py", line 188, in <module>
    PLATFORM, bcm, openegl, opengles = _detect_platform_and_load_libraries()
  File "/Users/work/.virtualenvs/Gakken-Eye-Tracker/lib/python3.7/site-packages/pi3d/constants/__init__.py", line 182, in _detect_platform_and_load_libraries
    set_egl_function_args(openegl) # function defined in constants/elg.py
  File "/Users/work/.virtualenvs/Gakken-Eye-Tracker/lib/python3.7/site-packages/pi3d/constants/egl.py", line 160, in set_egl_function_args
    egl.eglChooseConfig.argtypes = [EGLDisplay, POINTER(EGLint), c_void_p, EGLint, POINTER(EGLint)]
  File "/Users/work/.pyenv/versions/3.7.5/lib/python3.7/ctypes/__init__.py", line 377, in __getattr__
    func = self.__getitem__(name)
  File "/Users/work/.pyenv/versions/3.7.5/lib/python3.7/ctypes/__init__.py", line 382, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: dlsym(0x7fa713e056c0, eglChooseConfig): symbol not found

@Cabalist
Copy link

Cabalist commented Jan 28, 2020

I think I may have done it. I changed

def _darwin():
  pass

to

def _darwin():
  return _linux()

I then installed moltengl's library and putting them in my path ('/usr/local/lib`)

However this got me this error on running import pi3d:
“libEGL.dylib” cannot be opened because the developer cannot be verified.

Screen Shot 2020-01-28 at 3 49 22 PM

I then when to System Preferences > Security & Privacy and clicked on "Allow Anyway" in General

It now imports fine!

I am getting other errors though. To narrow these down could I ask what the "hello world" is for this code?

EDIT:
I had to mkdir /tmp/.X11-unix and then tried to run RunTests.py in the pi3d_demos. It runs but I see nothing on the screen. :?

@paddywwoof
Copy link
Collaborator

Hi, that all sounds quite hopeful, some kind of progress anyway. I doubted that the GL dylib would have all the EGL functions - doesn't on this linux either.

When you say nothing on the screen, do you not even get an X11 window popping up? Can you test whether xquartz is working on its own?

The minimal 'hello world' might be something like

import pi3d
disp = pi3d.Display.create(w=200, h=150, window_title="hello world")
for _i in range(1000):
    disp.loop_running()
disp.destroy()

Which should produce a window with just background. The next step would be rendering a simple shape:

import pi3d
disp = pi3d.Display.create(w=200, h=150)
ball = pi3d.Sphere(z=5.0)
for _i in range(1000):
    disp.loop_running()
    ball.draw()
disp.destroy()

And then add keyboard functionality, and after that textures as in pi3d_demos/Minimal.py

@Cabalist
Copy link

Cabalist commented Jan 29, 2020

For the first block of code I see Xquartz open in my dock but I don't see any windows open. After roughly 2 seconds I see:

[1] 57576 segmentation fault python helloworldtest.py

I stuck some print statements in and it appears that the pi3d.Display.create() call seems to be causing the segmentation fault. There is no stack trace.

The crash it causes also causes a bunch of my windows to flash black for a second. Most notably the intellij IDE. :)

EDIT: Using a debugger I'm unable to get past this call here:

self.context = openegl.eglCreateContext(self.display, self.config,
EGL_NO_CONTEXT, context_attribs)
This looks like it calls something in a library and pdb can't see in there

EDIT2: xman and xlogo work fine. Xquartz seems to be working as expected.

@paddywwoof
Copy link
Collaborator

Thanks for soldiering on with this... Hard to figure out problems with the dylib function calls. No debugging or error messages, at best they just don't do anything, at worst stray outside their allocated memory and seg fault! The eglCreateContext caused issues trying to get pi3d running on gentoo64 on the Raspberry Pi, I just couldn't get EGL to provide a context with (SURFACE_TYPE & 4) != 0 you can see what contexts are being offered by running the code below. I would be interested to see what you get.

from ctypes import (c_int, byref, Structure, CDLL, POINTER)
from ctypes.util import find_library

egl_name = find_library("EGL")
egl = CDLL(egl_name)

EGL_BUFFER_SIZE = 0x3020
EGL_ALPHA_SIZE = 0x3021
EGL_BLUE_SIZE = 0x3022
EGL_GREEN_SIZE = 0x3023
EGL_RED_SIZE = 0x3024
EGL_DEPTH_SIZE = 0x3025
EGL_STENCIL_SIZE = 0x3026
EGL_SAMPLES = 0x3031
EGL_SURFACE_TYPE = 0x3033
EGL_DEFAULT_DISPLAY = 0

EGLint = c_int

class _EGLDisplay(Structure): ###### EDIT needs this definition to work on gentoo64 is that significant (not needed on laptop 64)
    __slots__ = [
    ]
_EGLDisplay._fields_ = [
    ('_opaque_struct', EGLint)
]
EGLDisplay = POINTER(_EGLDisplay) #######

class _EGLConfig(Structure):
    __slots__ = [
    ]
_EGLConfig._fields_ = [
    ('_opaque_struct', EGLint)
]
EGLConfig = POINTER(_EGLConfig)

egl.eglGetDisplay.restype = EGLDisplay ####### EDIT needs this on gentoo64

display = egl.eglGetDisplay(EGL_DEFAULT_DISPLAY)
r = egl.eglInitialize(display, None, None)
attrib_dict = {EGL_RED_SIZE:"RED_SIZE",
			   EGL_GREEN_SIZE:"GREEN_SIZE",
			   EGL_BLUE_SIZE:"BLUE_SIZE",
			   EGL_DEPTH_SIZE:"DEPTH_SIZE",
			   EGL_ALPHA_SIZE:"ALPHA_SIZE",
			   EGL_BUFFER_SIZE:"BUFFER_SIZE",
			   EGL_SAMPLES:"SAMPLES",
			   EGL_STENCIL_SIZE:"STENCIL_SIZE",
			   EGL_SURFACE_TYPE:"SURFACE_TYPE"}
numconfig = EGLint(0)
poss_configs = (EGLConfig * 50)(*(EGLConfig() for _ in range(50)))
r = egl.eglGetConfigs(display, byref(poss_configs), EGLint(len(poss_configs)), byref(numconfig))
attr_val = EGLint()
for i in range(numconfig.value):
  print(i, "- ", end="")
  for attr in attrib_dict:
    r = egl.eglGetConfigAttrib(display, poss_configs[i], attr, byref(attr_val))
    print("{}={}, ".format(attrib_dict[attr], attr_val.value), end="")
  print("")

@Cabalist
Copy link

Output of that script is:

0 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=4,
1 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=1,
2 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=5,
3 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=4,
4 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=1,
5 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=5,
6 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=4,
7 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=1,
8 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=5,
9 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=4,
10 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=1,
11 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=5,
12 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=4,
13 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=1,
14 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=5,

@paddywwoof
Copy link
Collaborator

Well most of those look usable so I feel it ought to work. number 11 matches the config asked for so maybe try adding at the end

EGL_NO_CONTEXT = 0
context = egl.eglCreateContext(display, poss_configs[11], EGL_NO_CONTEXT, None)
print(context)

which differs from DisplayOpenGL.py is that it doesn't try to specify the the client context. It seems to work OK for me here if I pass NULL (represented by None in python)

Paddy

@Cabalist
Copy link

hmm... looks like it is having an issue finding the right library files.

0 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=4,
1 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=1,
2 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=5,
3 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=4,
4 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=1,
5 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=5,
6 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=4,
7 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=1,
8 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=4, STENCIL_SIZE=8, SURFACE_TYPE=5,
9 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=4,
10 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=1,
11 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=5,
12 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=4,
13 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=1,
14 - RED_SIZE=8, GREEN_SIZE=8, BLUE_SIZE=8, DEPTH_SIZE=24, ALPHA_SIZE=8, BUFFER_SIZE=32, SAMPLES=0, STENCIL_SIZE=8, SURFACE_TYPE=5,
(Error) failed to load library 'libGLESv1_CM.dylib'
1

egl_name here is /usr/local/lib/libEGL.dylib.

libGLESv1_CM.dylib is located in /opt/X11/lib which is first in my DYLD_FALLBACK_LIBRARY_PATH

There must be a path that this is using that is separate from DYLD_FALLBACK_LIBRARY_PATH that could help.

@paddywwoof
Copy link
Collaborator

paddywwoof commented Jan 30, 2020 via email

@Cabalist
Copy link

I might need a little handholding there. Where would you like me to put that?

@paddywwoof
Copy link
Collaborator

Sorry! Where the code has egl_name = find_library... You can put ='/usr/local... Or whichever version you want it to use (assuming it's found the wrong one) but not sure why it's looking for GLESv1 at all!

@Cabalist
Copy link

Cabalist commented Jan 30, 2020

Maybe I've lost the thread here.

The egl_name (/usr/local/lib/libEGL.dylib) looks correct to me. That file exists and appears to load fine. However I am getting an error that it can't load the library libGLESv1_CM.dylib when the script calls context = egl.eglCreateContext(display, poss_configs[11], EGL_NO_CONTEXT, None)

This file (libGLESv1_CM.dylib) is in my /opt/X11/lib directory. If the script is looking for the library and can't find it I could possibly point it to where it is.

I believe libGLESv1_CM is a different library than I would assume egl_name is looking for. And I think I can't just drop that path in the place of egl_name in egl = CDLL(egl_name) When I do I get:

Traceback (most recent call last):
  File "/Users/work/PycharmProjects/Gakken-Eye-Tracker/test.py", line 43, in <module>
    egl.eglGetDisplay.restype = EGLDisplay  ####### EDIT needs this on gentoo64
  File "/Users/work/.pyenv/versions/3.7.5/lib/python3.7/ctypes/__init__.py", line 377, in __getattr__
    func = self.__getitem__(name)
  File "/Users/work/.pyenv/versions/3.7.5/lib/python3.7/ctypes/__init__.py", line 382, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: dlsym(0x7f893b4057a0, eglGetDisplay): symbol not found

I don't have a libEGL.dylib in /opt/X11/lib

@paddywwoof
Copy link
Collaborator

paddywwoof commented Jan 30, 2020

Ryan, yes you're right, you can't tweak where libEGL functions try to load other dynamically loaded libraries apart from by setting system paths. Which seem to be already set up correctly. Or maybe copying files into different directories. Not sure how to get it to load correctly. What happens if you try find_library('GLESv1')?

@Cabalist
Copy link

Cabalist commented Jan 30, 2020

find_library('GLESv1') returns None
find_library('GLESv2') returns /opt/X11/lib/libGLESv2.dylib

$ ls -al /opt/X11/lib/libGLESv*

-rwxr-xr-x  1 root  wheel   78672 Oct 29  2016 /opt/X11/lib/libGLESv1_CM.1.dylib
lrwxr-xr-x  1 work  wheel      20 Jan 16 11:38 /opt/X11/lib/libGLESv1_CM.dylib -> libGLESv1_CM.1.dylib
-rwxr-xr-x  1 root  wheel  128000 Oct 29  2016 /opt/X11/lib/libGLESv2.2.dylib
lrwxr-xr-x  1 work  wheel      17 Jan 16 11:38 /opt/X11/lib/libGLESv2.dylib -> libGLESv2.2.dylib

@helgeerbe
Copy link
Contributor

Well, this discussion is maybe a little bit outdated. I tried to run picframe on my new apple silicon MacBook.

I'm using XQuartz as my x11 server (installed through homebrew). I filled the placeholder for _darwin().

def _darwin():
  platform = PLATFORM_OSX
  bcm = None
  opengles = _load_library('/Applications/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Libraries/libGLESv2.dylib')
  openegl = _load_library('/Applications/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Libraries/libEGL.dylib')
  return platform, bcm, openegl, opengles # opengles now determined by platform

Everything seems to be fine until I receive a segmentation fault at line 325 `DisplayOpenGL.py

self.surface = openegl.eglCreateWindowSurface(self.display, self.config, self.window, 0)

@paddywwoof
Copy link
Collaborator

Hi, great that you're trying to get pi3d running on mac, as you can see, despite this being theoretically possible, I've not managed it in the past (in large part because I don't have a mac myself!)

I will do a bit more digging but getting a seg fault with that function call makes me think that one or more of the arguments are the wrong type (possibly 32 or 64 bits, I think the new mac has at last abandoned any support for 32 bit applications). display and config have ctypes types defined as ctypes.POINTER so, hopefully, they're the right type but might be being set to a wrong value. window is defined as type ctypes.c_ulong which might be 32/64 bits but it would be odd for the code to work OK on 64 bit linux. And the 0 should be OK (but you never know)

@helgeerbe
Copy link
Contributor

I tried to use glx.

In glx.py

glx_name = find_library('GLX')
# glx_name = "/opt/homebrew/lib/libxcb-glx.dylib"
glx_name = "/opt/X11/lib/libGL.dylib"
libGLX = CDLL(glx_name)

I'm not sure, if I load the correct library. libxcb-glx.dylibdoes not work. But libGL.dylibseems to work.

But I get No matching FB config found in DisplayOpenGL.py

else: # work on basis it's X11
      # Set some WM info
      self.root = xlib.XRootWindowOfScreen(self.screen)
      if self.use_glx: # For drawing on X window with transparent background
        numfbconfigs = c_int()
        VisData = c_ints((
          glx.GLX_RENDER_TYPE, glx.GLX_RGBA_BIT,
          glx.GLX_DRAWABLE_TYPE, glx.GLX_WINDOW_BIT,
          glx.GLX_DOUBLEBUFFER, True,
          glx.GLX_RED_SIZE, 8,
          glx.GLX_GREEN_SIZE, 8,
          glx.GLX_BLUE_SIZE, 8,
          glx.GLX_ALPHA_SIZE, 8,
          glx.GLX_DEPTH_SIZE, 16,
          0))
        glx_screen = xlib.XDefaultScreen(self.d)
        fbconfigs = glx.glXChooseFBConfig(self.d, glx_screen, VisData, byref(numfbconfigs))
        fbconfig = 0

fbconfigsin line 234 seem to be Null.

@helgeerbe
Copy link
Contributor

I implemented fbconfigs = glx.glXGetFBConfigs( self.d, glx_screen, byref(numfbconfigs)) and got numfbconfigs=0. So not frame buffer configs at all.

glXQueryExtensionreturns True.

At the moment I have no idea. Maybe the display or screen? How can I test that?

@helgeerbe
Copy link
Contributor

image

OK, seems to work now.

  • egl is not working, so I have to use glx=true
  • load all libraries from the same source (actual /opt/homebrew/lib)
    • I had a mixture with /opt/X11/lib this didn't work
    • have to check if loading all libs from /opt/X11/lib might work as well
  • Even when not using egl you have to provide a dummy lib which has eglChooseConfig
    • openegl = _load_library('/Applications/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Libraries/libEGL.dylib')
  • The libs
    • openegl = _load_library('/Applications/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Libraries/libEGL.dylib')
    • opengles = _load_library('/opt/homebrew/lib/libGLESv2.2.dylib')
    • glx_name = "/opt/homebrew/lib/libGL.dylib"
    • x11_name = "/opt/homebrew/lib/libX11.dylib"
    • xrender_name = '/opt/homebrew/lib/libXrender.dylib'
  • X11 Server is XQuartz

@paddywwoof
Copy link
Collaborator

@helgeerbe fantastic work getting that running. I'd like to know what it is that makes it work with glx but not egl you had a similar issue getting pi3d running on your linux VM initially. The (non-obvious) glx dependency on egl cropped up before - was that when you were trying to get your linux VM working?

@helgeerbe
Copy link
Contributor

On my VM (windows host intel based) I enabled 3d hardware acceleration. With that setting egl was not working. Only glx.
When I disabled 3d hardware acceleration. Egl and glx worked both.

But on my new Mac with apple silicon (arm). I couldn't find any egl library. I used the library, which comes with chrome. As far as I know mesa supports only glx on Mac for arms. But pi3d is testing if some functions are available in the egl lib. Even if you don't want to use is.

I will do some further testing.

@helgeerbe
Copy link
Contributor

I will fork pi3d and do some cleanup in my code changes. So you can see, what I have done for MacOS on AppleSilicon.

What I really don't know, if EGL is available on macOS on intel systems or if there will ever be a port on apple silicon.

So I will prepare the code, that on macOS egl is ignored, if now library could be found.

@paddywwoof
Copy link
Collaborator

That would be great. I can't see anywhere in the pi3d code where any functions in libEGL.so get called if use_glx=True however it does look like the ctypes load_library still happens. This is done in pi3d.init so that's before the call to Display.create() when the glx choice is made. Maybe the library loading could be put inside a try/catch and managed later depending on the use_glx flag. Alternatively the libraries could be loaded as part of DisplayOpenGL.py

Is the the OS on mac not darwin anymore?

@helgeerbe
Copy link
Contributor

Hi @paddywwoof. I created a #252 pull request. At the end, it were only a couple of code lines, which have to be added.
Your are right, I set openegl = None and simply skip its initialization. In DisplayOpenGL.py I just added an assert that openegl must not be None, if use_glx == False. Maybe you have a more elegant approach in mind.

And yes, macOS is still Darwin.

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

5 participants