Skip to content

Commit

Permalink
Implement ModernGlVideoDriver.screenshot
Browse files Browse the repository at this point in the history
  • Loading branch information
JesseTG committed May 22, 2024
1 parent d7a74c8 commit 0156e75
Showing 1 changed file with 39 additions and 7 deletions.
46 changes: 39 additions & 7 deletions src/libretro/drivers/video/opengl/moderngl.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
retro_hw_render_interface,
)

from ..driver import FrameBufferSpecial, VideoDriver, VideoDriverInitArgs
from ..driver import FrameBufferSpecial, VideoDriver, VideoDriverInitArgs, Screenshot

_CONTEXTS = frozenset((HardwareContext.NONE, HardwareContext.OPENGL_CORE, HardwareContext.OPENGL))

Expand Down Expand Up @@ -154,6 +154,9 @@ def __init__(
self._vao: VertexArray | None = None
self._vbo: Buffer | None = None
self._has_debug: bool | None = None
self._last_width: int | None = None
self._last_height: int | None = None
self._rotation: Rotation = Rotation.NONE

# Framebuffer, color, and depth attachments for the "default" framebuffer
# (equivalent to what a window would provide)
Expand Down Expand Up @@ -270,6 +273,8 @@ def refresh(
self._window.swap_buffers()

self._context.finish()
self._last_width = width
self._last_height = height

@property
@override
Expand Down Expand Up @@ -483,16 +488,43 @@ def system_av_info(self, av_info: retro_system_av_info) -> None:

self._system_av_info = deepcopy(av_info)

@property
@override
def screenshot(self) -> memoryview | None:
geometry = self._system_av_info.geometry
def screenshot(self) -> Screenshot | None:
if self._system_av_info is None:
return None

size = (self._last_width, self._last_height)
if self._window:
data = self._window.fbo.read(viewport=(geometry.base_width, geometry.base_height))
frame = self._window.fbo.read(size, 4)
else:
data = self._fbo.read(viewport=(geometry.base_width, geometry.base_height))
frame = self._fbo.read(size, 4)

return memoryview(data) if data else None
if frame is None:
return None

if not self._callback or not self._callback.bottom_left_origin:
# If we're using software rendering or the origin is at the bottom-left...
bytes_per_row = self._last_width * self._pixel_format.bytes_per_pixel
reversed_frame = array("B", frame)
reversed_frame_view = memoryview(reversed_frame)
frame_view = memoryview(frame)
frame_len = len(frame)
for i in range(self._last_height):
# For each row...
start = i * bytes_per_row
end = start + bytes_per_row
reversed_frame_view[start:end] = frame_view[frame_len - end:frame_len - start]
# ...copy row number (height - i) to row i

frame = reversed_frame_view

return Screenshot(
memoryview(frame),
self._last_width,
self._last_height,
self._rotation,
self._pixel_format
)

@property
@override
Expand Down

0 comments on commit 0156e75

Please sign in to comment.