Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable atomic commits for DRM rendering #764

Closed
wants to merge 3 commits into from
Closed
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
29 changes: 15 additions & 14 deletions picamera2/previews/drm_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ def set_overlay(self, overlay):
raise RuntimeError("Preview must be configured before setting an overlay")
if self.picam2.camera_config['buffer_count'] < 2:
raise RuntimeError("Need at least buffer_count=2 to set overlay")

if overlay is None:
self.overlay_new_fb = None
else:
Expand All @@ -107,11 +106,14 @@ def set_overlay(self, overlay):
mm.write(np.ascontiguousarray(overlay).data)
self.overlay_new_fb = new_fb

if self.picam2.display_stream_name is not None:
with self.lock:
self.render_drm(self.picam2, None)
# if self.picam2.display_stream_name is not None:
# with self.lock:
# self.render_drm(self.picam2, None)

def render_drm(self, picam2, completed_request):
# Use an atomic commit to render
ctx = pykms.AtomicReq(self.card)

if completed_request is not None:
self.display_stream_name = completed_request.config['display']
stream = completed_request.stream_map[self.display_stream_name]
Expand Down Expand Up @@ -159,7 +161,6 @@ def render_drm(self, picam2, completed_request):
self.overlay_plane.set_prop("pixel blend mode", 1)
except RuntimeError:
pass

if completed_request is not None:
fb = completed_request.request.buffers[stream]

Expand Down Expand Up @@ -191,23 +192,23 @@ def render_drm(self, picam2, completed_request):
else:
drmfb = pykms.DmabufFramebuffer(self.card, width, height, fmt, [fd], [stride], [0])
self.drmfbs[fb] = drmfb

drmfb = self.drmfbs[fb]
self.crtc.set_plane(self.plane, drmfb, x, y, w, h, 0, 0, width, height)
# An "atomic commit" would probably be better, but I can't get this to work...
# ctx = pykms.AtomicReq(self.card)
# ctx.add(self.plane, {"FB_ID": drmfb.id, "CRTC_ID": self.crtc.id,
# "SRC_W": width << 16, "SRC_H": height << 16,
# "CRTC_X": x, "CRTC_Y": y, "CRTC_W": w, "CRTC_H": h})
# ctx.commit()
ctx.add(self.plane, {"FB_ID": drmfb.id, "CRTC_ID": self.crtc.id,
"SRC_W": width << 16, "SRC_H": height << 16,
"CRTC_X": x, "CRTC_Y": y, "CRTC_W": w, "CRTC_H": h})

# Render an overlay if present
overlay_new_fb = self.overlay_new_fb
if overlay_new_fb != self.overlay_fb:
overlay_old_fb = self.overlay_fb # Must hang on to this momentarily to avoid a "wink"
self.overlay_fb = overlay_new_fb
if self.overlay_fb is not None:
width, height = self.overlay_fb.width, self.overlay_fb.height
self.crtc.set_plane(self.overlay_plane, self.overlay_fb, x, y, w, h, 0, 0, width, height)
ctx.add(self.overlay_plane, {"FB_ID": self.overlay_fb.id, "CRTC_ID": self.crtc.id,
"SRC_W": width << 16, "SRC_H": height << 16,
"CRTC_X": x, "CRTC_Y": y, "CRTC_W": w, "CRTC_H": h})

ctx.commit_sync()
overlay_old_fb = None # noqa The new one has been sent so it's safe to let this go now
old_drmfbs = None # noqa Can chuck these away now too

Expand Down