def handle_page_flip_single(self): self.draw_buf ^= 1 self.move_stripe() # one atomic request to flip on all displays/crtcs fb = self.fbs[self.draw_buf] screen_offset = 0 req = pykms.AtomicReq(card) for i in range(0, len(conn_list)): crtc = crtc_list[i] mode = mode_list[i] plane = plane_list[i] req.add( plane, { 'FB_ID': fb.id, 'CRTC_ID': crtc.id, 'SRC_X': screen_offset << 16, 'SRC_Y': 0 << 16, 'SRC_W': mode.hdisplay << 16, 'SRC_H': mode.vdisplay << 16, 'CRTC_X': 0, 'CRTC_Y': 0, 'CRTC_W': mode.hdisplay, 'CRTC_H': mode.vdisplay, 'zpos': 0 }) screen_offset += mode.hdisplay req.commit(0)
def handle_page_flip_separate(self): self.draw_buf ^= 1 self.move_stripe() # ask to flip the first screen fb = self.fbs[self.draw_buf] screen_offset = 0 # add separate atomic request for each display (crtc) for i in range(0, len(conn_list)): req = pykms.AtomicReq(card) crtc = crtc_list[i] mode = mode_list[i] plane = plane_list[i] req.add( plane, { 'FB_ID': fb.id, 'CRTC_ID': crtc.id, 'SRC_X': screen_offset << 16, 'SRC_Y': 0 << 16, 'SRC_W': mode.hdisplay << 16, 'SRC_H': mode.vdisplay << 16, 'CRTC_X': 0, 'CRTC_Y': 0, 'CRTC_W': mode.hdisplay, 'CRTC_H': mode.vdisplay, 'zpos': 0 }) screen_offset += mode.hdisplay req.commit(0)
def __init__(self, state): self.state = state self.cm = state.cm self.contexts = state.contexts self.running = False card = pykms.Card() res = pykms.ResourceManager(card) conn = res.reserve_connector() crtc = res.reserve_crtc(conn) mode = conn.get_default_mode() modeb = mode.to_blob(card) req = pykms.AtomicReq(card) req.add_connector(conn, crtc) req.add_crtc(crtc, modeb) r = req.commit_sync(allow_modeset=True) assert(r == 0) self.card = card self.resman = res self.crtc = crtc self.mode = mode self.bufqueue = [] self.current = None self.next = None self.cam_2_drm = {}
def disable_planes(card): areq = pykms.AtomicReq(card) for p in card.planes: areq.add(p, "FB_ID", 0) areq.add(p, "CRTC_ID", 0) if areq.commit_sync() != 0: print("disabling planes failed")
def set_prop(ob, prop, value): if ob.card.has_atomic: areq = pykms.AtomicReq(ob.card) areq.add(ob, prop, value) if areq.commit_sync() != 0: print("commit failed") else: if ob.set_prop_value(prop, value) != 0: print("setting property failed")
def apply_request(self, drmreq): buffers = drmreq['camreq'].buffers req = pykms.AtomicReq(self.card) for stream, fb in buffers.items(): drmfb = self.cam_2_drm.get(fb, None) self.add_plane(req, stream, drmfb) req.commit()
def set_props(ob, map): if ob.card.has_atomic: areq = pykms.AtomicReq(ob.card) for key, value in map.items(): areq.add(ob, key, value) if areq.commit_sync() != 0: print("commit failed") else: for propid,propval in map.items(): if ob.set_prop_value(propid, propval) != 0: print("setting property failed")
def show_rot_plane(crtc, plane, fb, rot, x_scale, y_scale): crtc_w = int(fb_w * x_scale) crtc_h = int(fb_h * y_scale) if (rot & pykms.Rotation.ROTATE_90) or (rot & pykms.Rotation.ROTATE_270): tmp = crtc_w crtc_w = crtc_h crtc_h = tmp crtc_x = int(mode.hdisplay / 2 - crtc_w / 2) crtc_y = int(mode.vdisplay / 2 - crtc_h / 2) req = pykms.AtomicReq(card) src_x = 0 src_y = 0 src_w = fb_w - src_x src_h = fb_h - src_y print("SRC {},{}-{}x{} DST {},{}-{}x{}".format(src_x, src_y, src_w, src_h, crtc_x, crtc_y, crtc_w, crtc_h)) angle_str = pykms.Rotation(rot & pykms.Rotation.ROTATE_MASK).name reflect_x_str = "REFLECT_X" if rot & pykms.Rotation.REFLECT_X else "" reflect_y_str = "REFLECT_Y" if rot & pykms.Rotation.REFLECT_Y else "" print("{} {} {}".format(angle_str, reflect_x_str, reflect_y_str)) sys.stdout.flush() req.add( plane, { "FB_ID": fb.id, "CRTC_ID": crtc.id, "SRC_X": src_x << 16, "SRC_Y": src_y << 16, "SRC_W": src_w << 16, "SRC_H": src_h << 16, "CRTC_X": crtc_x, "CRTC_Y": crtc_y, "CRTC_W": crtc_w, "CRTC_H": crtc_h, "rotation": rot, "zpos": 2 }) req.commit_sync(allow_modeset=True)
def readvid(conn, mask): global loop_count print("VID EVENT") ifb = src_streamer.dequeue() ofb = dst_streamer.dequeue() req = pykms.AtomicReq(card) req.add_plane(plane1, ifb, crtc, dst=(0, 0, 400, 480)) req.add_plane(plane2, ofb, crtc, dst=(400, 0, 400, 480)) req.commit_sync(allow_modeset=True) time.sleep(1) loop_count += 1 if loop_count >= 10: exit(0) print("loop #", loop_count) src_streamer.queue(ifb) dst_streamer.queue(ofb)
def handle_page_flip(self, frame, time): self.flips += 1 if self.time == 0: self.frames = frame self.time = time time_delta = time - self.time if time_delta >= 5: frame_delta = frame - self.frames print("Frame rate: %f (%u/%u frames in %f s)" % (frame_delta / time_delta, self.flips, frame_delta, time_delta)) self.flips = 0 self.frames = frame self.time = time if self.front_buf == 0: fb = self.fb2 else: fb = self.fb1 self.front_buf = self.front_buf ^ 1 current_xpos = self.bar_xpos old_xpos = (current_xpos + (fb.width - bar_width - bar_speed)) % (fb.width - bar_width) new_xpos = (current_xpos + bar_speed) % (fb.width - bar_width) self.bar_xpos = new_xpos pykms.draw_color_bar(fb, old_xpos, new_xpos, bar_width) if card.has_atomic: ctx = pykms.AtomicReq(card) ctx.add(crtc.primary_plane, "FB_ID", fb.id) ctx.commit() else: crtc.page_flip(fb)
def handle_page_flip(self, frame, time): if self.front_buf == 0: fb = self.fb2 else: fb = self.fb1 self.front_buf = self.front_buf ^ 1 current_xpos = self.bar_xpos; old_xpos = (current_xpos + (fb.width - bar_width - bar_speed)) % (fb.width - bar_width); new_xpos = (current_xpos + bar_speed) % (fb.width - bar_width); self.bar_xpos = new_xpos pykms.draw_color_bar(fb, old_xpos, new_xpos, bar_width) if card.has_atomic: ctx = pykms.AtomicReq(card) ctx.add(crtc.primary_plane, "FB_ID", fb.id) ctx.commit(self) else: crtc.page_flip(fb, self)
import termios, sys, os, tty card = pykms.OmapCard() res = pykms.ResourceManager(card) conn = res.reserve_connector() crtc = res.reserve_crtc(conn) mode = conn.get_default_mode() modeb = mode.to_blob(card) rootplane = res.reserve_primary_plane(crtc, pykms.PixelFormat.XRGB8888) plane = res.reserve_overlay_plane(crtc, pykms.PixelFormat.NV12) card.disable_planes() req = pykms.AtomicReq(card) req.add(conn, "CRTC_ID", crtc.id) req.add(crtc, {"ACTIVE": 1, "MODE_ID": modeb.id}) # This enables the root plane #rootfb = pykms.OmapFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24"); #pykms.draw_test_pattern(rootfb); # #req.add(rootplane, {"FB_ID": rootfb.id, # "CRTC_ID": crtc.id, # "SRC_X": 0 << 16, # "SRC_Y": 0 << 16, # "SRC_W": mode.hdisplay << 16,
def main(argv): if len(argv) > 1: conn_name = argv[1] else: conn_name = '' card = pykms.Card() if not card.has_atomic: raise RuntimeError('This test requires atomic update support') res = pykms.ResourceManager(card) conn = res.reserve_connector(conn_name) crtc = res.reserve_crtc(conn) mode = conn.get_default_mode() flip_handler = FlipHandler(crtc, mode.hdisplay, mode.vdisplay) fb = flip_handler.fb1 pykms.draw_color_bar(fb, fb.width - bar_width - bar_speed, bar_speed, bar_width) mode_blob = mode.to_blob(card) req = pykms.AtomicReq(card) req.add(conn, 'CRTC_ID', crtc.id) req.add(crtc, {'ACTIVE': 1, 'MODE_ID': mode_blob.id}) req.add( crtc.primary_plane, { 'FB_ID': fb.id, 'CRTC_ID': crtc.id, 'SRC_X': 0 << 16, 'SRC_Y': 0 << 16, 'SRC_W': fb.width << 16, 'SRC_H': fb.height << 16, 'CRTC_X': 0, 'CRTC_Y': 0, 'CRTC_W': fb.width, 'CRTC_H': fb.height, }) ret = req.commit(allow_modeset=True) if ret < 0: raise RuntimeError('Atomic mode set failed with %d' % ret) def bye(): # Signal the timeline to complete all pending page flips flip_handler.timeline.signal(100) exit(0) def readdrm(fileobj, mask): for ev in card.read_events(): if ev.type == pykms.DrmEventType.FLIP_COMPLETE: flip_handler.handle_page_flip(ev.seq, ev.time) def readkey(fileobj, mask): sys.stdin.readline() bye() sel = selectors.DefaultSelector() sel.register(card.fd, selectors.EVENT_READ, readdrm) sel.register(sys.stdin, selectors.EVENT_READ, readkey) while True: timeout = Timer.next_timeout() print("--> timeout %s" % repr(timeout)) try: events = sel.select(timeout) except KeyboardInterrupt: bye() for key, mask in events: callback = key.data callback(key.fileobj, mask) Timer.fire()
def handle_page_flip(self, frame, time): if self.time_last == 0: self.frame_last = frame self.time_last = time # Verify that the page flip hasn't completed before the timeline got # signaled. if self.timeline.value < 2 * self.flips - 1: raise RuntimeError( 'Page flip %u for fence %u complete before timeline (%u)!' % (self.flips, 2 * self.flips - 1, self.timeline.value)) self.flips += 1 # Print statistics every 5 seconds. time_delta = time - self.time_last if time_delta >= 5: frame_delta = frame - self.frame_last flips_delta = self.flips - self.flips_last print("Frame rate: %f (%u/%u frames in %f s)" % (frame_delta / time_delta, flips_delta, frame_delta, time_delta)) self.frame_last = frame self.flips_last = self.flips self.time_last = time # Draw the color bar on the back buffer. if self.front_buf == 0: fb = self.fb2 else: fb = self.fb1 self.front_buf = self.front_buf ^ 1 current_xpos = self.bar_xpos old_xpos = (current_xpos + (fb.width - bar_width - bar_speed)) % (fb.width - bar_width) new_xpos = (current_xpos + bar_speed) % (fb.width - bar_width) self.bar_xpos = new_xpos pykms.draw_color_bar(fb, old_xpos, new_xpos, bar_width) # Flip the buffers with an in fence located in the future. The atomic # commit is asynchronous and returns immediately, but the flip should # not complete before the fence gets signaled. print("flipping with fence @%u, timeline is @%u" % (2 * self.flips - 1, self.timeline.value)) fence = self.timeline.create_fence(2 * self.flips - 1) req = pykms.AtomicReq(self.crtc.card) req.add(self.crtc.primary_plane, { 'FB_ID': fb.id, 'IN_FENCE_FD': fence.fd }) req.commit() del fence # Arm a timer to signal the fence in 0.5s. def timeline_signal(timeline): print("signaling timeline @%u" % timeline.value) timeline.signal(2) Timer(0.5, timeline_signal, self.timeline)
def plane_commit(card, crtc, plane, fb, x, y, w, h): req = pykms.AtomicReq(card) req.add_plane(plane, fb, crtc, None, (x, y, w, h)) r = req.commit_sync() assert r == 0, "Plane commit failed: %d" % r
def close(self): req = pykms.AtomicReq(self.card) for s in self.streams: req.add_plane(s['plane'], None, None, dst=(0, 0, 0, 0)) req.commit()