Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion rope/qt/widgets/preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import numpy as np
from PySide6.QtCore import Qt, QTimer, Signal, Slot
from PySide6.QtGui import QColor, QImage, QPainter
from PySide6.QtOpenGLWidgets import QOpenGLWidget
from PySide6.QtWidgets import QLabel

Expand Down Expand Up @@ -249,8 +250,42 @@ def _recompute_scale(self):
self._scale = (1.0, widget_aspect / image_aspect)

def paintGL(self):
if not _OPENGL_AVAILABLE:
if not _OPENGL_AVAILABLE or self._program == 0:
# QPainter fallback for platforms where OpenGL shader init failed or PyOpenGL is missing
t0 = time.perf_counter()
painter = QPainter(self)
painter.fillRect(self.rect(), QColor(0, 0, 0))
frame = self._pending_cpu
if frame is None and self._pending_cuda is not None:
try:
frame = self._pending_cuda.detach().cpu().numpy()
except Exception:
frame = None
if frame is None and self._last_frame_source is not None:
if isinstance(self._last_frame_source, np.ndarray):
frame = self._last_frame_source
elif _TORCH_AVAILABLE and isinstance(self._last_frame_source, torch.Tensor):
try:
frame = self._last_frame_source.detach().cpu().numpy()
except Exception:
frame = None
if frame is not None and isinstance(frame, np.ndarray) and frame.ndim == 3:
h, w, c = frame.shape
if not frame.flags["C_CONTIGUOUS"]:
frame = np.ascontiguousarray(frame)
qimg = QImage(frame.data, w, h, w * c, QImage.Format.Format_RGB888)
scaled = qimg.scaled(self.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
x = (self.width() - scaled.width()) // 2
y = (self.height() - scaled.height()) // 2
painter.drawImage(x, y, scaled)
self._tex_w, self._tex_h = w, h
self._last_path = "qpainter-fallback"
painter.end()
self._pending_cpu = None
self._pending_cuda = None
self._last_paint_ms = (time.perf_counter() - t0) * 1000.0
return

t0 = time.perf_counter()
# Record paint timeline at the start so a stalled paint still
# registers an interval boundary (avoids fps spikes after long
Expand Down