Skip to content

Commit 35154f3

Browse files
Don't try to serialise GL function calls
The Qt OpenGL widget does the neccessary context serialisation. Signed-off-by: Jim Easterbrook <jim@jim-easterbrook.me.uk>
1 parent 769f11e commit 35154f3

File tree

1 file changed

+41
-104
lines changed

1 file changed

+41
-104
lines changed

src/pyctools/components/qt/qtdisplay.py

Lines changed: 41 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
__docformat__ = 'restructuredtext en'
2121

2222
from collections import deque
23-
from contextlib import contextmanager
24-
import threading
2523
import time
2624

2725
import numpy
@@ -32,75 +30,17 @@
3230
from pyctools.core.qt import (LowEventPriority, qt_version_info, qt_package,
3331
QtCore, QtEventLoop, QtGui, QtSlot, QtWidgets)
3432

35-
if qt_package == 'PyQt5':
36-
from PyQt5.QtWidgets import QOpenGLWidget
37-
elif qt_package == 'PyQt6':
33+
if qt_package == 'PyQt6':
3834
from PyQt6.QtOpenGLWidgets import QOpenGLWidget
39-
elif qt_package == 'PySide2':
40-
from PySide2.QtWidgets import QOpenGLWidget
4135
elif qt_package == 'PySide6':
4236
from PySide6.QtOpenGLWidgets import QOpenGLWidget
4337
else:
44-
raise ImportError(f'Unrecognised qt_package value "{qt_package}"')
38+
QOpenGLWidget = QtWidgets.QOpenGLWidget
4539

4640
if qt_version_info < (5, 4):
4741
raise ImportError('Qt version 5.4 or higher required')
4842

4943

50-
# single context lock to serialise OpenGL operations across multiple
51-
# windows
52-
ctx_lock = threading.RLock()
53-
54-
@contextmanager
55-
def context():
56-
ctx_lock.acquire()
57-
yield
58-
ctx_lock.release()
59-
60-
class RenderingThread(QtCore.QObject):
61-
next_frame_event = QtCore.QEvent.registerEventType()
62-
63-
def __init__(self, widget, **kwds):
64-
super(RenderingThread, self).__init__(**kwds)
65-
self.widget = widget
66-
self.running = False
67-
68-
def next_frame(self):
69-
self.widget.makeCurrent()
70-
self.widget.paintGL()
71-
# swapBuffers should block until frame interval, depending on hardware
72-
self.widget.swapBuffers()
73-
now = time.time()
74-
self.clock += 1.0 / 75.0
75-
while now < self.clock:
76-
# swapBuffers didn't block, so do our own free running at 75Hz
77-
time.sleep(self.clock - now)
78-
now = time.time()
79-
self.widget.done_swap(now)
80-
# schedule next frame, after processing other events
81-
QtCore.QCoreApplication.postEvent(
82-
self, QtCore.QEvent(self.next_frame_event), LowEventPriority)
83-
84-
def event(self, event):
85-
if event.type() == self.next_frame_event:
86-
event.accept()
87-
self.next_frame()
88-
return True
89-
return super(RenderingThread, self).event(event)
90-
91-
@QtSlot(object)
92-
def resize(self, event):
93-
# resize event is always sent when window first becomes visible
94-
if not self.running:
95-
self.widget.makeCurrent()
96-
self.widget.glInit()
97-
self.clock = time.time()
98-
self.widget.resizeEvent(event)
99-
if not self.running:
100-
self.running = True
101-
self.next_frame()
102-
103-
10444
class GLDisplay(QOpenGLWidget):
10545
def __init__(self, logger, *arg, **kwds):
10646
super(GLDisplay, self).__init__(*arg, **kwds)
@@ -187,57 +127,54 @@ def step(self):
187127
self.show_black = False
188128

189129
def initializeGL(self):
190-
with context():
191-
GL.glClear(GL.GL_COLOR_BUFFER_BIT)
192-
GL.glDisable(GL.GL_DEPTH_TEST)
193-
GL.glEnable(GL.GL_TEXTURE_2D)
194-
texture = GL.glGenTextures(1)
195-
GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1)
196-
GL.glBindTexture(GL.GL_TEXTURE_2D, texture)
197-
GL.glDisable(GL.GL_TEXTURE_2D)
130+
GL.glClear(GL.GL_COLOR_BUFFER_BIT)
131+
GL.glDisable(GL.GL_DEPTH_TEST)
132+
GL.glEnable(GL.GL_TEXTURE_2D)
133+
texture = GL.glGenTextures(1)
134+
GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1)
135+
GL.glBindTexture(GL.GL_TEXTURE_2D, texture)
136+
GL.glDisable(GL.GL_TEXTURE_2D)
198137

199138
def resizeGL(self, w, h):
200-
with context():
201-
GL.glViewport(0, 0, w, h)
202-
GL.glMatrixMode(GL.GL_PROJECTION)
203-
GL.glLoadIdentity()
204-
GL.glOrtho(0, 1, 0, 1, -1, 1)
205-
GL.glMatrixMode(GL.GL_MODELVIEW)
206-
GL.glLoadIdentity()
139+
GL.glViewport(0, 0, w, h)
140+
GL.glMatrixMode(GL.GL_PROJECTION)
141+
GL.glLoadIdentity()
142+
GL.glOrtho(0, 1, 0, 1, -1, 1)
143+
GL.glMatrixMode(GL.GL_MODELVIEW)
144+
GL.glLoadIdentity()
207145

208146
def paintGL(self):
209147
if self.show_black:
210148
image = self.black_image
211149
else:
212150
image = self.numpy_image
213151
ylen, xlen, bpc = image.shape
214-
with context():
215-
GL.glEnable(GL.GL_TEXTURE_2D)
216-
GL.glClear(GL.GL_COLOR_BUFFER_BIT)
217-
GL.glDisable(GL.GL_DEPTH_TEST)
218-
GL.glTexParameterf(
219-
GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR)
220-
GL.glTexParameterf(
221-
GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)
222-
if bpc == 3:
223-
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, xlen, ylen,
224-
0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, image)
225-
elif bpc == 1:
226-
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, xlen, ylen,
227-
0, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE, image)
228-
else:
229-
return
230-
GL.glBegin(GL.GL_QUADS)
231-
GL.glTexCoord2i(0, 0)
232-
GL.glVertex2i(0, 1)
233-
GL.glTexCoord2i(0, 1)
234-
GL.glVertex2i(0, 0)
235-
GL.glTexCoord2i(1, 1)
236-
GL.glVertex2i(1, 0)
237-
GL.glTexCoord2i(1, 0)
238-
GL.glVertex2i(1, 1)
239-
GL.glEnd()
240-
GL.glDisable(GL.GL_TEXTURE_2D)
152+
GL.glEnable(GL.GL_TEXTURE_2D)
153+
GL.glClear(GL.GL_COLOR_BUFFER_BIT)
154+
GL.glDisable(GL.GL_DEPTH_TEST)
155+
GL.glTexParameterf(
156+
GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR)
157+
GL.glTexParameterf(
158+
GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)
159+
if bpc == 3:
160+
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, xlen, ylen,
161+
0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, image)
162+
elif bpc == 1:
163+
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, xlen, ylen,
164+
0, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE, image)
165+
else:
166+
return
167+
GL.glBegin(GL.GL_QUADS)
168+
GL.glTexCoord2i(0, 0)
169+
GL.glVertex2i(0, 1)
170+
GL.glTexCoord2i(0, 1)
171+
GL.glVertex2i(0, 0)
172+
GL.glTexCoord2i(1, 1)
173+
GL.glVertex2i(1, 0)
174+
GL.glTexCoord2i(1, 0)
175+
GL.glVertex2i(1, 1)
176+
GL.glEnd()
177+
GL.glDisable(GL.GL_TEXTURE_2D)
241178

242179
def startup(self):
243180
pass

0 commit comments

Comments
 (0)