pi3d / pi3d_demos

Demos and support files for pi3d (3D graphics python package for the raspberry pi)
Other
71 stars 33 forks source link

AttributeError: 'NoneType' object has no attribute 'eglChooseConfig' #51

Closed fanlessfan closed 3 years ago

fanlessfan commented 3 years ago

Hello,

I got error below when I try to run the pi3d demo on piCore. I am trying to use raspberry pi 0 w to run the PictureFrame2020.py. it is working but intermittently shutdown because of short memory (512M). So I try the piCore (tinyCore version 12 for raspberry pi 0 http://forum.tinycorelinux.net/index.php/topic,24384.0.html) in order to save memory. I managed to install python3.8 and pip3 install pi3d and pip3 install Pillow. Is there something missing?

python3 Earth.py

Traceback (most recent call last): File "Earth.py", line 11, in import pi3d File "/usr/local/lib/python3.8/site-packages/pi3d/init.py", line 10, in from pi3d.constants import (USE_PYGAME, PIL_OK, File "/usr/local/lib/python3.8/site-packages/pi3d/constants/init.py", line 182, in PLATFORM, bcm, openegl, opengles = _detect_platform_and_load_libraries() File "/usr/local/lib/python3.8/site-packages/pi3d/constants/init.py", line 176, in _detect_platform_and_load_libraries set_egl_function_args(openegl) # function defined in constants/elg.py File "/usr/local/lib/python3.8/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)] AttributeError: 'NoneType' object has no attribute 'eglChooseConfig'

paddywwoof commented 3 years ago

Hi, well done for trying to get this working on a different OS. The platform detection https://github.com/tipam/pi3d/blob/master/pi3d/constants/__init__.py#L82 basically looks to see if a) a line in /proc/modules begins with 'vc4' in which case it's running on RPi 4 with fake KMS b) is libbcm_host.so on there, which means it's running on a RPi c) it looks to see where libEGL and libGLESv2 might be installed.

So your error looks like libEGL wasn't found and egl is still None (libGLESv2 probably wasn't found either but the program never executed line 177) So if I were you I would look to see where those library files are or see if they're not yet installed:

$ sudo find / -name libEGL*

You will also need the libbcm_host.so file to run on the RPi zero. If they're not there, as you've been running on the zero before you could just copy the required files from the SD card you were using and put them in a convenient location but you would then need to hack constants.init.py to load them from your location (if you install them 'properly' then they will be found automatically)

Presumably you've tried running with the lite version of rasperry pi OS?

Paddy

PS for hacking the pi3d source you probably should git clone https://github.com/tipam/pi3d.git and make sure that there is an import demo line and file demo.py in the pi3d_demos directory that points to the location of the cloned repo.

fanlessfan commented 3 years ago

Hi @paddywwoof,

Thank you for your quick response. I copied libraries from rPiOS in another pi0w to this one in /opt/vc/lib as the init.py shows below. But I still got the error which is little different. the file is there, but can't load Could you help?

thx

python3 Earth.py Couldn't load library /opt/vc/lib/libbrcmEGL.so Traceback (most recent call last): File "Earth.py", line 11, in import pi3d File "/usr/local/lib/python3.8/site-packages/pi3d/init.py", line 10, in from pi3d.constants import (USE_PYGAME, PIL_OK, File "/usr/local/lib/python3.8/site-packages/pi3d/constants/init.py", line 182, in PLATFORM, bcm, openegl, opengles = _detect_platform_and_load_libraries() File "/usr/local/lib/python3.8/site-packages/pi3d/constants/init.py", line 176, in _detect_platform_and_load_libraries set_egl_function_args(openegl) # function defined in constants/elg.py File "/usr/local/lib/python3.8/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)] AttributeError: 'NoneType' object has no attribute 'eglChooseConfig'

  elif not acc and os.path.isfile('/opt/vc/lib/libbrcmGLESv2.so'): # raspbian after stretch release
  opengles = _load_library('/opt/vc/lib/libbrcmGLESv2.so')
  openegl = _load_library('/opt/vc/lib/libbrcmEGL.so')

/opt/vc/lib$ ls -l libb* -rw-r--r-- 1 root staff 98612 Jan 6 18:15 libbcm_host.so -rw-r--r-- 1 root staff 202072 Jan 6 18:15 libbrcmEGL.so -rw-r--r-- 1 root staff 105768 Jan 6 18:15 libbrcmGLESv2.so

paddywwoof commented 3 years ago

That does look odd. I'm not sure why ctypes wouldn't be able to load a library. Even odder that you didn't get an error logged for loading GLESv2 Maybe you will get a little more info if it's run not in a try/except block. Could you give this a go:


>>> import ctypes
>>> a = ctypes.CDLL("/opt/vc/lib/libbrcmGLESv2.so") # have to load this first
>>> b = ctypes.CDLL("/opt/vc/lib/libbrcmEGL.so")
>>> b.eglCooseConfig
fanlessfan commented 3 years ago

this time it does have error for GLESv2. And it can't load the lib from the path. I guess it might be the limitation/behaviour of the piCore ( tinyCore for raspberry pi) it's minimum OS running in memory. I just got on this and don't know much about it.

python3 Earth.py Couldn't load library /opt/vc/lib/libbrcmGLESv2.so Couldn't load library /opt/vc/lib/libbrcmEGL.so Traceback (most recent call last): File "Earth.py", line 11, in import pi3d File "/usr/local/lib/python3.8/site-packages/pi3d/init.py", line 10, in from pi3d.constants import (USE_PYGAME, PIL_OK, File "/usr/local/lib/python3.8/site-packages/pi3d/constants/init.py", line 182, in PLATFORM, bcm, openegl, opengles = _detect_platform_and_load_libraries() File "/usr/local/lib/python3.8/site-packages/pi3d/constants/init.py", line 176, in _detect_platform_and_load_libraries set_egl_function_args(openegl) # function defined in constants/elg.py File "/usr/local/lib/python3.8/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)] AttributeError: 'NoneType' object has no attribute 'eglChooseConfig'

and it can't load the library. Traceback (most recent call last): File "testlib.py", line 3, in a = ctypes.CDLL("/opt/vc/lib/libbrcmGLESv2.so") # have to load this first File "/usr/local/lib/python3.8/ctypes/init.py", line 369, in init self._handle = _dlopen(self._name, mode) OSError: libbrcmEGL.so: cannot open shared object file: No such file or directory

paddywwoof commented 3 years ago

Hmm, interesting. From your second error it looks like ctypes.CDLL() isn't opening the relevant file. Looking at the code for ctypes _dlopen() looks to be an alias for _ctypes.LoadLibrary() and your directory listing shows that the file is there so maybe LoadLibrary has some functionality I don't understand or behaves differently. Just as a test could you try this:

$ nano test.c
#include <stdio.h>
void hello() {
  printf("hello world!\n");
}
Ctrl-x
$ gcc -c -fPIC test.c -o test.o
$ gcc test.o -shared -o libtest.so
$ python3
>>> import ctypes
>>> a = ctypes.CDLL("/home/pi/libtest.so") # or wherever it is
>>> a.hello()

You could try putting it in a different directory and see what it does

fanlessfan commented 3 years ago

the libtest.so works. But python3 Earth.py still has errors. I tried to manually load the library in python using types.CDLL. it seems the key error is OSError: /opt/vc/lib/libbrcmEGL.so: undefined symbol: glPointSizePointerOES. You can see all the output below. any idea? Is it possible that we can set an env to let it search the path for the lib.so?

thx

tc@rPi08-wifi:/mnt/mmcblk0p2/libtest$ ls -al total 24 drwxrwxrwx 2 root root 4096 Jan 7 01:15 ./ drwxr-xr-x 7 root root 4096 Jan 7 01:11 ../ -rwxr-xr-x 1 tc staff 7048 Jan 7 01:15 libtest.so -rw-r--r-- 1 tc staff 63 Jan 7 01:14 test.c -rw-r--r-- 1 tc staff 1016 Jan 7 01:14 test.o tc@rPi08-wifi:/mnt/mmcblk0p2/libtest$ python3 Python 3.8.0 (default, Dec 1 2019, 06:34:30) [GCC 9.2.0] on linux Type "help", "copyright", "credits" or "license" for more information.

import ctypes a = ctypes.CDLL("/mnt/mmcblk0p2/libtest/libtest.so") a.hello() hello world! 13

tc@rPi08-wifi:/mnt/mmcblk0p2/pi3d_demos$ python3 Earth.py Couldn't load library /opt/vc/lib/libbrcmGLESv2.so Couldn't load library /opt/vc/lib/libbrcmEGL.so Traceback (most recent call last): File "Earth.py", line 11, in import pi3d File "/usr/local/lib/python3.8/site-packages/pi3d/init.py", line 10, in from pi3d.constants import (USE_PYGAME, PIL_OK, File "/usr/local/lib/python3.8/site-packages/pi3d/constants/init.py", line 182, in PLATFORM, bcm, openegl, opengles = _detect_platform_and_load_libraries() File "/usr/local/lib/python3.8/site-packages/pi3d/constants/init.py", line 176, in _detect_platform_and_load_libraries set_egl_function_args(openegl) # function defined in constants/elg.py File "/usr/local/lib/python3.8/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)] AttributeError: 'NoneType' object has no attribute 'eglChooseConfig' tc@rPi08-wifi:/mnt/mmcblk0p2/pi3d_demos$ ls -l /opt/vc/lib/libbrcmGLESv2.so -rwxr-xr-x 1 root staff 105768 Jan 7 01:19 /opt/vc/lib/libbrcmGLESv2.so tc@rPi08-wifi:/mnt/mmcblk0p2/pi3d_demos$ ls -l /opt/vc/lib/libbrcmEGL.so -rwxr-xr-x 1 root staff 202072 Jan 7 01:19 /opt/vc/lib/libbrcmEGL.so

manual load python3 Python 3.8.0 (default, Dec 1 2019, 06:34:30) [GCC 9.2.0] on linux Type "help", "copyright", "credits" or "license" for more information.

import ctypes a = ctypes.CDLL("/opt/vc/lib/libbrcmGLESv2.so") Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/ctypes/init.py", line 369, in init self._handle = _dlopen(self._name, mode) OSError: libbrcmEGL.so: cannot open shared object file: No such file or directory b = ctypes.CDLL("/opt/vc/lib/libbrcmEGL.so") Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/ctypes/init.py", line 369, in init self._handle = _dlopen(self._name, mode) OSError: libbcm_host.so: cannot open shared object file: No such file or directory c = ctypes.CDLL("/opt/vc/lib/libbcm_host.so") Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/ctypes/init.py", line 369, in init self._handle = _dlopen(self._name, mode) OSError: libvchiq_arm.so: cannot open shared object file: No such file or directory d = ctypes.CDLL("/opt/vc/lib/libvchiq_arm.so") Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/ctypes/init.py", line 369, in init self._handle = _dlopen(self._name, mode) OSError: libvcos.so: cannot open shared object file: No such file or directory e = ctypes.CDLL("/opt/vc/lib/libvcos.so") d = ctypes.CDLL("/opt/vc/lib/libvchiq_arm.so") c = ctypes.CDLL("/opt/vc/lib/libbcm_host.so") d = ctypes.CDLL("/opt/vc/lib/libvcos.so") b = ctypes.CDLL("/opt/vc/lib/libbrcmEGL.so") Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/ctypes/init.py", line 369, in init self._handle = _dlopen(self._name, mode) OSError: /opt/vc/lib/libbrcmEGL.so: undefined symbol: glPointSizePointerOES a = ctypes.CDLL("/opt/vc/lib/libbrcmGLESv2.so") Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/ctypes/init.py", line 369, in init self._handle = _dlopen(self._name, mode) OSError: libbrcmEGL.so: cannot open shared object file: No such file or directory

fanlessfan commented 3 years ago

I also found that glPointSizePointerOES is not defined in /opt/vc/lib/libbrcmEGL.so, but in /opt/vc/lib/libbrcmGLESv2.so. And /opt/vc/lib/libbrcmGLESv2.so needs /opt/vc/lib/libbrcmEGL.so, so none of them can load.

tc@rPi08-wifi:/mnt/mmcblk0p2/pi3d_demos$ nm /opt/vc/lib/libbrcmEGL.so | grep glPointSizePointerOES U glPointSizePointerOES tc@rPi08-wifi:/mnt/mmcblk0p2/pi3d_demos$ nm /opt/vc/lib/libbrcmGLESv2.so | grep glPointSizePointerOES 00011948 T glPointSizePointerOES

https://github.com/malcolmstill/cl-egl/issues/1

very interesting

paddywwoof commented 3 years ago

Hi, yes, loading GLESv2 before EGL applies everywhere and is a quirk we've had to work round since the start of pi3d (hence my comment above). However, in your error listing, the second b = ... EGL.so produces the undefined symbol error so it must have managed to load! So why do you get "No such file or directory" error before?

In your listing did you get no error for e = ..libvcos.so"? Then when you retried the earlier lines did they load without error until you got to b =. In which case what happens if you do

>>> import ctypes
>>> e = ctypes.CDLL("/opt/vc/lib/libvcos.so")
>>> a = ctypes.CDLL("/opt/vc/lib/libbrcmGLESv2.so") # have to load this first
>>> b = ctypes.CDLL("/opt/vc/lib/libbrcmEGL.so")
>>> b.eglCooseConfig

Assuming I misunderstood your error listing and that doesn't work, what happens if you put libbrcmGLESv2.so into /mnt/mmcblk0p2/pi3d_demos and try to ctypes.CDLL() it?

fanlessfan commented 3 years ago

in the output above l successfully load everything until b EGL because the undefined symbol glPointSizePointerOES and I can't load a GLESv2 because "libbrcmEGL.so: cannot open" which means EGL is not loaded. I copied the output to below.

so EGL can't be load because of undefined symbol: glPointSizePointerOES which defined in GLESv2 and GLESv2 can't be load because it depends on EGL. chicken and eggs

the /opt/vc/lib might not setup properly as I just copy them from a working rPiOS on a Pi0W. the problem might be resolved by setup the correct auto search path for the lib.so. when GLESv2 needs EGL it knows where to look at it. Do you know how to?

e = ctypes.CDLL("/opt/vc/lib/libvcos.so") d = ctypes.CDLL("/opt/vc/lib/libvchiq_arm.so") c = ctypes.CDLL("/opt/vc/lib/libbcm_host.so") d = ctypes.CDLL("/opt/vc/lib/libvcos.so") b = ctypes.CDLL("/opt/vc/lib/libbrcmEGL.so") Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/ctypes/init.py", line 369, in init self._handle = _dlopen(self._name, mode) OSError: /opt/vc/lib/libbrcmEGL.so: undefined symbol: glPointSizePointerOES a = ctypes.CDLL("/opt/vc/lib/libbrcmGLESv2.so") Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/ctypes/init.py", line 369, in init self._handle = _dlopen(self._name, mode) OSError: libbrcmEGL.so: cannot open shared object file: No such file or directory

paddywwoof commented 3 years ago

Hi, all of the "no such file or directory" errors have gone! How did you do that? The requirement to load GLESv2 before EGL applies everywhere so I would just ignore that. However the need for EGL from within GLESv2 is now a show stopper. It probably does depend on the linker stuff, which is all a bit horrible, but you might be able to fix with ldconfig https://askubuntu.com/questions/491401/how-do-i-install-a-so-file-newbie https://man7.org/linux/man-pages/man8/ldconfig.8.html let me know how you get on.

fanlessfan commented 3 years ago

Hi, I reconfigured the ld.so.conf and all the load lib errors are gone. Thank you @paddywwoof for the help. But I have new error below. python3 Earth.py

paddywwoof commented 3 years ago

Well, that sounds good, in parts. I suppose you will have to pick your way through the dependencies one by one - you are starting out with an OS that has had every non-essential part stripped out. Have you tried some of the suggestions online? https://stackoverflow.com/questions/42583835/failed-to-open-vchiq-instance

fanlessfan commented 3 years ago

Thank you so much @paddywwoof for the help. It finally works. I fixed the dependencies by re-config the ld.so.conf like below and chmod 777 to /dev/vchiq. my goal is to run the lighweight memory based PictureFrame2020.py on rPi0w, so it won't depend on the mmc once it booted and hope it reduce the memory used by system as currently it's not stable on rPi0w

echo "/opt/vc/lib" >> /etc/ld.so.conf ldconfig

paddywwoof commented 3 years ago

Hi, I'm very impressed that you got it working. If you get better results with piCore tiny core it would be really good if you could write up all the steps so others can do the same.

Paddy

fanlessfan commented 3 years ago

Sure, if it finally have better result than rPiOS. Currently I only have PictureFrame2020.py running without any picture.

fanlessfan commented 3 years ago

Hi @paddywwoof, test the PictureFrame2020.py with pictures, but after running for a while it stoped and have the output of Killed. Is there any log in pi3d or PictureFrame2020.py which shows the reason? I guess it's because of not enough memory. in that case I have to give up rPi0w.

thx

paddywwoof commented 3 years ago

Hmm, when I've tested pi3d on the rPi zero before I've run top at the same time to check memory usage but I don't remember how high it went (I vaguely think it was always reasonably low). top also only measures the memory allocated to the CPU but the GPU memory availability is also critical. What have you allocated to the GPU? Also have you tried running PictureFrame with different image sizes to see if there is a critical dimension that causes the program to fail? Finally, what size monitor are you displaying on? I think large display surfaces might be significant.

fanlessfan commented 3 years ago

I think it's memory related. it happened when I set the GPU memory to 128 and it seems Ok for GPU memory 96 (no kill for the app), but some picture won't show up (black screen). I just use normal 1080P monitor it's 24", but I don't think size matter, but resolution. 512M memory of rPi0w might be the limitation. I don't pay attention to the picture size yet, but I guess it happens when it's more than a threshold.

By the way I got error "glGetError 0x500" always even though the program runs as expected.

thx

fanlessfan commented 3 years ago

Hello @paddywwoof, after a lot of testing, I finally got PictureFrame work on Pi0w with MQTT control. It's stable and runs for days. I have feature request for MQTT and will create another issue. Thank you again for the great work.

paddywwoof commented 3 years ago

Hi, thanks for all the work you've put in. It's only due to all the efforts of users like you that problems get ironed out and improvements added.