enthought / enable

Enable: low-level drawing and interaction
Other
91 stars 45 forks source link

pyglet.gl.lib.GLException: (0x1282) when running enable/kiva/examples/kiva/pyglet_gl.py when running python3.11 #1027

Closed homosapien-lcy closed 1 year ago

homosapien-lcy commented 1 year ago

Problem: python3.11 -X faulthandler enable/kiva/examples/kiva/pyglet_gl.py will result in the following error:

2023-04-07 16:08:57.436 Python[12382:221035] ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to /var/folders/2z/kylzj9s92y71cxscmljmpqrh0000gt/T/org.python.python.savedState
Traceback (most recent call last):
  File "/Users/cyliu/Documents/3.11_test_2/enable/kiva/examples/kiva/pyglet_gl.py", line 64, in <module>
    main()
  File "/Users/cyliu/Documents/3.11_test_2/enable/kiva/examples/kiva/pyglet_gl.py", line 56, in main
    win.dispatch_events()
  File "/Users/cyliu/.venvs/py311_test_2/lib/python3.11/site-packages/pyglet/window/cocoa/__init__.py", line 259, in dispatch_events
    self.dispatch_pending_events()
  File "/Users/cyliu/.venvs/py311_test_2/lib/python3.11/site-packages/pyglet/window/cocoa/__init__.py", line 289, in dispatch_pending_events
    EventDispatcher.dispatch_event(self, *event)
  File "/Users/cyliu/.venvs/py311_test_2/lib/python3.11/site-packages/pyglet/event.py", line 387, in dispatch_event
    if getattr(self, event_type)(*args):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cyliu/.venvs/py311_test_2/lib/python3.11/site-packages/pyglet/window/__init__.py", line 817, in on_resize
    gl.glViewport(0, 0, *self.get_framebuffer_size())
  File "/Users/cyliu/.venvs/py311_test_2/lib/python3.11/site-packages/pyglet/gl/lib.py", line 79, in errcheck
    raise GLException(f'(0x{error}): {msg}')
pyglet.gl.lib.GLException: (0x1282): Invalid operation. The specified operation is not allowed in the current state.

How to replicate: python -X faulthandler enable/kiva/examples/kiva/pyglet_gl.py

Environment: MacOS, python3.11

Packages: Package Version


altgraph 0.17.2 autopep8 2.0.1 boto3 1.26.50 botocore 1.29.50 camelot-py 0.10.1 cffi 1.15.1 chardet 5.1.0 charset-normalizer 3.0.1 click 8.1.3 contourpy 1.0.7 cryptography 39.0.0 cycler 0.11.0 Cython 0.29.33 distro 1.8.0 et-xmlfile 1.1.0 fonttools 4.39.0 future 0.18.2 importlib-resources 5.12.0 install 1.3.5 isort 5.12.0 jmespath 1.0.1 kiwisolver 1.4.4 macholib 1.15.2 matplotlib 3.7.1 numpy 1.24.1 opencv-python 4.7.0.68 openpyxl 3.0.10 packaging 23.0 pandas 1.5.2 pdfminer.six 20221105 Pillow 9.3.0 pip 21.2.4 pycodestyle 2.10.0 pycparser 2.21 PyMuPDF 1.21.1 pyparsing 3.0.9 PyPDF2 2.12.1 PyQt5 5.15.9 PyQt5-Qt5 5.15.2 PyQt5-sip 12.11.1 PySide6 6.4.2 PySide6-Addons 6.4.2 PySide6-Essentials 6.4.2 python-dateutil 2.8.2 pytz 2022.7.1 s3transfer 0.6.0 scipy 1.10.1 setuptools 58.0.4 shiboken6 6.4.2 six 1.15.0 tabula-py 2.6.0 tabulate 0.9.0 textract-trp 0.1.3 tomli 2.0.1 traits 6.4.1 typing_extensions 4.4.0 urllib3 1.26.14 vtk 9.2.6 wheel 0.37.0 zipp 3.15.0

homosapien-lcy commented 1 year ago

After some analysis, two errors happened in this demo. "if getattr(self, event_type)(*args):" in dispatch_event (https://github.com/pyglet/pyglet/blob/master/pyglet/event.py#L387). If I change this line to True and skip it:

        # Check instance for an event handler
        try:
            if True:
                return EVENT_HANDLED
        except AttributeError as e:
            event_op = getattr(self, event_type, None)
            if callable(event_op):
                raise e
        except TypeError as exception:
            self._raise_dispatch_exception(event_type, args, getattr(self, event_type), exception)
        else:
            invoked = True

another error will be raised:

2023-04-12 11:30:49.212 Python[4225:88241] ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to /var/folders/2z/kylzj9s92y71cxscmljmpqrh0000gt/T/org.python.python.savedState
Traceback (most recent call last):
  File "/Users/cyliu/Documents/3.11_test/enable/kiva/examples/kiva/pyglet_gl.py", line 64, in <module>
    main()
  File "/Users/cyliu/Documents/3.11_test/enable/kiva/examples/kiva/pyglet_gl.py", line 57, in main
    win.clear()
  File "/Users/cyliu/Documents/3.11_test/pyglet/pyglet/window/__init__.py", line 644, in clear
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
  File "/Users/cyliu/Documents/3.11_test/pyglet/pyglet/gl/lib.py", line 79, in errcheck
    raise GLException(f'(0x{error}): {msg}')
pyglet.gl.lib.GLException: (0x1282): Invalid operation. The specified operation is not allowed in the current state.

And after commenting out "gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)" (https://github.com/pyglet/pyglet/blob/master/pyglet/window/__init__.py#L644 ), the example can be run successfully. So I think the not allowed operations happens in getattr and gl.glClear.

homosapien-lcy commented 1 year ago

Further investigation suggests that the method on_resize from the BaseWindow class (https://github.com/pyglet/pyglet/blob/master/pyglet/window/__init__.py#L259 ) caused the 1st error, evidence is if we add "print(self.on_resize(*args))" to line 387 of event.py (https://github.com/pyglet/pyglet/blob/master/pyglet/event.py#L387 )

        # Check instance for an event handler
        try:
            print(self.on_resize(*args))
            if getattr(self, event_type)(*args):
                return EVENT_HANDLED
        except AttributeError as e:
            event_op = getattr(self, event_type, None)
            if callable(event_op):
                raise e
        except TypeError as exception:
            self._raise_dispatch_exception(event_type, args, getattr(self, event_type), exception)
        else:
            invoked = True

We will get an error fron self.on_resize

2023-04-12 11:57:25.992 Python[4826:102610] ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to /var/folders/2z/kylzj9s92y71cxscmljmpqrh0000gt/T/org.python.python.savedState
Traceback (most recent call last):
  File "/Users/cyliu/Documents/3.11_test/enable/kiva/examples/kiva/pyglet_gl.py", line 64, in <module>
    main()
  File "/Users/cyliu/Documents/3.11_test/enable/kiva/examples/kiva/pyglet_gl.py", line 56, in main
    win.dispatch_events()
  File "/Users/cyliu/Documents/3.11_test/pyglet/pyglet/window/cocoa/__init__.py", line 259, in dispatch_events
    self.dispatch_pending_events()
  File "/Users/cyliu/Documents/3.11_test/pyglet/pyglet/window/cocoa/__init__.py", line 287, in dispatch_pending_events
    EventDispatcher.dispatch_event(self, *event)
  File "/Users/cyliu/Documents/3.11_test/pyglet/pyglet/event.py", line 387, in dispatch_event
    print(self.on_resize(*args))
          ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cyliu/Documents/3.11_test/pyglet/pyglet/window/__init__.py", line 817, in on_resize
    gl.glViewport(0, 0, *self.get_framebuffer_size())
  File "/Users/cyliu/Documents/3.11_test/pyglet/pyglet/gl/lib.py", line 79, in errcheck
    raise GLException(f'(0x{error}): {msg}')
pyglet.gl.lib.GLException: (0x1282): Invalid operation. The specified operation is not allowed in the current state.

Currently, both functions that causing errors involved (glClear and glViewport) are linked from openGL 1.0 (linked in this file https://github.com/pyglet/pyglet/blob/master/pyglet/gl/gl.py ). The error retrieving function that found this error: error = gl.glGetError() (https://github.com/pyglet/pyglet/blob/master/pyglet/gl/lib.py#L68) also comes from openGL 1.0.

corranwebster commented 1 year ago

GL backend has been removed.