From b11baff09f78a4a383f817ec35208ae8966ab832 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 2 Jan 2017 16:42:08 +0200 Subject: py: Reorganize source directory Separate the Python bindings sources from the test scripts. While at it, remove the unneeded run.sh script. Signed-off-by: Laurent Pinchart --- py/tests/CMakeLists.txt | 7 + py/tests/alpha-test.py | 67 ++++++++++ py/tests/cam.py | 78 ++++++++++++ py/tests/db.py | 72 +++++++++++ py/tests/functest.py | 19 +++ py/tests/gamma.py | 41 ++++++ py/tests/helpers.py | 54 ++++++++ py/tests/iact.py | 43 +++++++ py/tests/kmsmodeview.py | 317 +++++++++++++++++++++++++++++++++++++++++++++ py/tests/test.py | 18 +++ py/tests/trans-test.py | 332 ++++++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 1048 insertions(+) create mode 100644 py/tests/CMakeLists.txt create mode 100755 py/tests/alpha-test.py create mode 100755 py/tests/cam.py create mode 100755 py/tests/db.py create mode 100755 py/tests/functest.py create mode 100755 py/tests/gamma.py create mode 100644 py/tests/helpers.py create mode 100755 py/tests/iact.py create mode 100755 py/tests/kmsmodeview.py create mode 100755 py/tests/test.py create mode 100755 py/tests/trans-test.py (limited to 'py/tests') diff --git a/py/tests/CMakeLists.txt b/py/tests/CMakeLists.txt new file mode 100644 index 0000000..a670ed9 --- /dev/null +++ b/py/tests/CMakeLists.txt @@ -0,0 +1,7 @@ +file(GLOB PY_SRCS "*.py") +add_custom_target(pyextras SOURCES ${PY_SRCS}) + +add_test(NAME pytest COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/functest.py") +set_property(TEST pytest PROPERTY + ENVIRONMENT "PYTHONPATH=." "LD_LIBRARY_PATH=." +) diff --git a/py/tests/alpha-test.py b/py/tests/alpha-test.py new file mode 100755 index 0000000..c6ec8ee --- /dev/null +++ b/py/tests/alpha-test.py @@ -0,0 +1,67 @@ +#!/usr/bin/python3 + +import pykms +from helpers import * +import time + +# This hack makes drm initialize the fbcon, setting up the default connector +card = pykms.Card() +card = 0 + +card = pykms.Card() +res = pykms.ResourceManager(card) +conn = res.reserve_connector() +crtc = res.reserve_crtc(conn) +mode = conn.get_default_mode() + +planes = [] +for p in card.planes: + if p.supports_crtc(crtc) == False: + continue + planes.append(p) + +if len(planes) != 3: + print("Need 3 planes!") + exit(1) + +disable_planes(card) + +w = mode.hdisplay +h = mode.vdisplay + +fbs=[] + +for i in range(len(planes)): + fbs.append(pykms.DumbFramebuffer(card, w, h, "AR24")) + +pykms.draw_rect(fbs[0], 50, 50, 200, 200, pykms.RGB(128, 255, 0, 0)) +pykms.draw_rect(fbs[1], 150, 50, 200, 200, pykms.RGB(128, 0, 255, 0)) +pykms.draw_rect(fbs[2], 50, 150, 200, 200, pykms.RGB(128, 0, 0, 255)) + + +set_props(crtc, { + "trans-key-mode": 0, + "trans-key": 0, + "background": 0, + "alpha_blender": 1, +}) + +for i in range(len(planes)): + plane = planes[i] + fb = fbs[i] + + print("set crtc {}, plane {}, fb {}".format(crtc.id, p.id, fbs[i].id)) + + set_props(plane, { + "FB_ID": fb.id, + "CRTC_ID": crtc.id, + "SRC_W": fb.width << 16, + "SRC_H": fb.height << 16, + "CRTC_W": fb.width, + "CRTC_H": fb.height, + "zorder": i, + }) + + time.sleep(1) + +input("press enter to exit\n") diff --git a/py/tests/cam.py b/py/tests/cam.py new file mode 100755 index 0000000..b44f8f9 --- /dev/null +++ b/py/tests/cam.py @@ -0,0 +1,78 @@ +#!/usr/bin/python3 + +import sys +import selectors +import pykms +from helpers import * + + +w = 640 +h = 480 +fmt = pykms.PixelFormat.YUYV + + +# This hack makes drm initialize the fbcon, setting up the default connector +card = pykms.Card() +card = 0 + +card = pykms.Card() +res = pykms.ResourceManager(card) +conn = res.reserve_connector() +crtc = res.reserve_crtc(conn) +plane = res.reserve_overlay_plane(crtc, fmt) + +mode = conn.get_default_mode() + +NUM_BUFS = 5 + +fbs = [] +for i in range(NUM_BUFS): + fb = pykms.DumbFramebuffer(card, w, h, fmt) + fbs.append(fb) + +vidpath = pykms.VideoDevice.get_capture_devices()[0] + +vid = pykms.VideoDevice(vidpath) +cap = vid.capture_streamer +cap.set_port(0) +cap.set_format(fmt, w, h) +cap.set_queue_size(NUM_BUFS) + +for fb in fbs: + cap.queue(fb) + +cap.stream_on() + + +def readvid(conn, mask): + fb = cap.dequeue() + + if card.has_atomic: + set_props(plane, { + "FB_ID": fb.id, + "CRTC_ID": crtc.id, + "SRC_W": fb.width << 16, + "SRC_H": fb.height << 16, + "CRTC_W": fb.width, + "CRTC_H": fb.height, + }) + else: + crtc.set_plane(plane, fb, 0, 0, fb.width, fb.height, + 0, 0, fb.width, fb.height) + + cap.queue(fb) + +def readkey(conn, mask): + #print("KEY EVENT"); + sys.stdin.readline() + exit(0) + +sel = selectors.DefaultSelector() +sel.register(cap.fd, selectors.EVENT_READ, readvid) +sel.register(sys.stdin, selectors.EVENT_READ, readkey) + +while True: + events = sel.select() + for key, mask in events: + callback = key.data + callback(key.fileobj, mask) diff --git a/py/tests/db.py b/py/tests/db.py new file mode 100755 index 0000000..3ffb716 --- /dev/null +++ b/py/tests/db.py @@ -0,0 +1,72 @@ +#!/usr/bin/python3 + +import sys +import pykms +import selectors +from helpers import * + +bar_width = 20 +bar_speed = 8 + +class FlipHandler(pykms.PageFlipHandlerBase): + def __init__(self): + super().__init__() + self.bar_xpos = 0 + self.front_buf = 0 + self.fb1 = pykms.DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24"); + self.fb2 = pykms.DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24"); + + 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) + + +card = pykms.Card() +res = pykms.ResourceManager(card) +conn = res.reserve_connector() +crtc = res.reserve_crtc(conn) +mode = conn.get_default_mode() + +fliphandler = FlipHandler() + +crtc.set_mode(conn, fliphandler.fb1, mode) + +fliphandler.handle_page_flip(0, 0) + +def readdrm(conn, mask): + #print("EVENT"); + card.call_page_flip_handlers() + +def readkey(conn, mask): + #print("KEY EVENT"); + sys.stdin.readline() + exit(0) + +sel = selectors.DefaultSelector() +sel.register(card.fd, selectors.EVENT_READ, readdrm) +sel.register(sys.stdin, selectors.EVENT_READ, readkey) + +while True: + events = sel.select() + for key, mask in events: + callback = key.data + callback(key.fileobj, mask) diff --git a/py/tests/functest.py b/py/tests/functest.py new file mode 100755 index 0000000..44c29fb --- /dev/null +++ b/py/tests/functest.py @@ -0,0 +1,19 @@ +#!/usr/bin/python3 + +import pykms +from helpers import * + +card = pykms.Card() +res = pykms.ResourceManager(card) +conn = res.reserve_connector() +crtc = res.reserve_crtc(conn) + +mode = conn.get_default_mode() + +fb = pykms.DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24"); +pykms.draw_test_pattern(fb); + +crtc.set_mode(conn, fb, mode) + +print("OK") + diff --git a/py/tests/gamma.py b/py/tests/gamma.py new file mode 100755 index 0000000..a6b68cc --- /dev/null +++ b/py/tests/gamma.py @@ -0,0 +1,41 @@ +#!/usr/bin/python3 + +import pykms +from helpers import * + +# This hack makes drm initialize the fbcon, setting up the default connector +card = pykms.Card() +card = 0 + +card = pykms.Card() +res = pykms.ResourceManager(card) +conn = res.reserve_connector() +crtc = res.reserve_crtc(conn) +mode = conn.get_default_mode() + +fb = pykms.DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24"); +pykms.draw_test_pattern(fb); + +crtc.set_mode(conn, fb, mode) + +len=256 +arr = bytearray(len*2*4) +view = memoryview(arr).cast("H") + +for i in range(len): + g = round(65535 * pow(i / float(len), 1 / 2.2)) + + view[i * 4 + 0] = g + view[i * 4 + 1] = g + view[i * 4 + 2] = g + view[i * 4 + 3] = 0 + +gamma = pykms.Blob(card, arr); + +set_prop(crtc, "GAMMA_LUT", gamma.id) + +input("press enter to remove gamma\n") + +set_prop(crtc, "GAMMA_LUT", 0) + +input("press enter to exit\n") diff --git a/py/tests/helpers.py b/py/tests/helpers.py new file mode 100644 index 0000000..fd67d41 --- /dev/null +++ b/py/tests/helpers.py @@ -0,0 +1,54 @@ +import pykms + +def add_props(areq, ob, map): + for key, value in map.items(): + areq.add(ob, key, value) + +def props(o): + o.refresh_props() + map = o.prop_map + for propid,propval in map.items(): + prop = o.card.get_prop(propid) + print("%-15s %d (%#x)" % (prop.name, propval, propval)) + +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 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") + +red = pykms.RGB(255, 0, 0) +green = pykms.RGB(0, 255, 0) +blue = pykms.RGB(0, 0, 255) +yellow = pykms.RGB(255, 255, 0) +purple = pykms.RGB(255, 0, 255) +white = pykms.RGB(255, 255, 255) +cyan = pykms.RGB(0, 255, 255) + +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") diff --git a/py/tests/iact.py b/py/tests/iact.py new file mode 100755 index 0000000..fecd899 --- /dev/null +++ b/py/tests/iact.py @@ -0,0 +1,43 @@ +#!/usr/bin/python3 -i + +# This is a base script for interactive kms++ python environment + +import pykms +from time import sleep +from math import sin +from math import cos +from helpers import * + +card = pykms.Card() +res = pykms.ResourceManager(card) +conn = res.reserve_connector() +crtc = res.reserve_crtc(conn) + +mode = conn.get_default_mode() + +fb = pykms.DumbFramebuffer(card, 200, 200, "XR24"); +pykms.draw_test_pattern(fb); + +#crtc.set_mode(conn, fb, mode) + +i = 0 +for p in card.planes: + globals()["plane"+str(i)] = p + i=i+1 + +i = 0 +for c in card.crtcs: + globals()["crtc"+str(i)] = c + i=i+1 + +for p in crtc.possible_planes: + if p.plane_type == pykms.PlaneType.Overlay: + plane = p + break + +def set_plane(x, y): + crtc.set_plane(plane, fb, x, y, fb.width, fb.height, 0, 0, fb.width, fb.height) + +set_plane(0, 0) + +# for x in range(0, crtc.width() - fb.width()): set_plane(x, int((sin(x/50) + 1) * 100)); sleep(0.01) diff --git a/py/tests/kmsmodeview.py b/py/tests/kmsmodeview.py new file mode 100755 index 0000000..355db02 --- /dev/null +++ b/py/tests/kmsmodeview.py @@ -0,0 +1,317 @@ +#!/usr/bin/python3 + +import urwid +import pykms + +def exit_on_q(key): + if key in ('q', 'Q'): + raise urwid.ExitMainLoop() + elif key == 'a': + apply_mode() + +alarm_handle = None + +def recalc_info(l, d): + global alarm_handle + + alarm_handle = None + + for w in recalc_list: + w.recalc() + +def div_or_zero(n, d): + if d == 0: + return 0 + else: + return n / d + +class MyIntEdit(urwid.IntEdit): + _metaclass_ = urwid.signals.MetaSignals + signals = ['value_change'] + + def __init__(self, caption, calc=None): + self._myval = 0 + self._disable_change = False + self._calc = calc + self._updlist = None + + super().__init__(caption, 0) + + def set_edit_text(self, text): + global alarm_handle + + super().set_edit_text(text) + newtext = super().get_edit_text() + new_val = int(newtext) if newtext != "" else 0 + if new_val != self._myval: + self._myval = new_val + if not self._disable_change: + urwid.emit_signal(self, 'value_change', self, self._myval) + + if alarm_handle == None: + alarm_handle = loop.set_alarm_in(0, recalc_info) + + if self._updlist != None: + for w in self._updlist: + w.recalc() + + def recalc(self): + self._disable_change = True + self.set_val(self._calc()) + self._disable_change = False + + def set_val(self, val): + self.set_edit_text(str(int(val))) + + def get_val(self): + return self._myval + + def set_updlist(self, list): + self._updlist = list + + def keypress(self, size, key): + if key == '+': + self.set_edit_text(str(self.value() + 1)) + elif key == '-': + self.set_edit_text(str(self.value() - 1)) + else: + return super().keypress(size, key) + +class MyIntText(urwid.Text): + def __init__(self, fmt, calc=None): + super().__init__("") + self._fmt = fmt + self._calc = calc + + def recalc(self): + val = self._calc() + super().set_text(self._fmt.format(val)) + +def khz_to_ps(khz): + if khz == 0: + return 0 + else: + return 1.0 / khz * 1000 * 1000 * 1000 + +def khz_to_us(khz): + if khz == 0: + return 0 + else: + return 1.0 / khz * 1000 + +pclk_khz_widget = MyIntEdit(u"pclk (kHz) ") +pclk_ps_widget = MyIntText(fmt="pclk {:.2f} ps", calc = lambda: khz_to_ps(pclk_khz_widget.get_val())) + +pclk_widgets = [pclk_khz_widget, pclk_ps_widget] + +pclk_columns = urwid.LineBox(urwid.Columns(pclk_widgets), title = "Pixel clock") + +# Horizontal widgets + +hdisp_widget = MyIntEdit(u"hdisp ", calc = lambda: hdisp2_widget.get_val()) +hfp_widget = MyIntEdit(u"hfp ", calc = lambda: hss_widget.get_val() - hdisp_widget.get_val()) +hsw_widget = MyIntEdit(u"hsw ", calc = lambda: hse_widget.get_val() - hss_widget.get_val()) +hbp_widget = MyIntEdit(u"hbp ", calc = lambda: htot_widget.get_val() - hse_widget.get_val()) + +hdisp2_widget = MyIntEdit(u"hdisp ", calc = lambda: hdisp_widget.get_val()) +hss_widget = MyIntEdit(u"hss ", + calc = lambda: hdisp_widget.get_val() + hfp_widget.get_val()) +hse_widget = MyIntEdit(u"hse ", + calc = lambda: hdisp_widget.get_val() + hfp_widget.get_val() + hsw_widget.get_val()) +htot_widget = MyIntEdit(u"htot ", + calc = lambda: hdisp_widget.get_val() + hfp_widget.get_val() + hsw_widget.get_val() + hbp_widget.get_val()) + +hwidgets1 = [hdisp_widget, hfp_widget, hsw_widget, hbp_widget] +hwidgets2 = [hdisp2_widget, hss_widget, hse_widget, htot_widget] + +horiz_pile1 = urwid.Pile(hwidgets1) +horiz_pile2 = urwid.Pile(hwidgets2) + +h_columns = urwid.LineBox(urwid.Columns([(15, horiz_pile1), (15, horiz_pile2)]), title = "Horizontal") + +# Vertical columns + +vdisp_widget = MyIntEdit(u"vdisp ", calc = lambda: vdisp2_widget.get_val()) +vfp_widget = MyIntEdit(u"vfp ", calc = lambda: vss_widget.get_val() - vdisp_widget.get_val()) +vsw_widget = MyIntEdit(u"vsw ", calc = lambda: vse_widget.get_val() - vss_widget.get_val()) +vbp_widget = MyIntEdit(u"vbp ", calc = lambda: vtot_widget.get_val() - vse_widget.get_val()) + +vdisp2_widget = MyIntEdit(u"vdisp ", calc = lambda: vdisp_widget.get_val()) +vss_widget = MyIntEdit(u"vss ", + calc = lambda: vdisp_widget.get_val() + vfp_widget.get_val()) +vse_widget = MyIntEdit(u"vse ", + calc = lambda: vdisp_widget.get_val() + vfp_widget.get_val() + vsw_widget.get_val()) +vtot_widget = MyIntEdit(u"vtot ", + calc = lambda: vdisp_widget.get_val() + vfp_widget.get_val() + vsw_widget.get_val() + vbp_widget.get_val()) + +vwidgets1 = [vdisp_widget, vfp_widget, vsw_widget, vbp_widget] +vwidgets2 = [vdisp2_widget, vss_widget, vse_widget, vtot_widget] + +vert_pile1 = urwid.Pile(vwidgets1) +vert_pile2 = urwid.Pile(vwidgets2) + +v_columns = urwid.LineBox(urwid.Columns([(15, vert_pile1), (15, vert_pile2)]), title = "Vertical") + +# Info widgets + +line_us_widget = MyIntText(fmt="line {:.2f} us", + calc = lambda: khz_to_us(pclk_khz_widget.get_val()) * htot_widget.get_val()) +line_khz_widget = MyIntText(fmt="line {:.2f} kHz", + calc = lambda: div_or_zero(pclk_khz_widget.get_val(), htot_widget.get_val())) + +frame_tot_widget = MyIntText(fmt="tot {} pix", + calc = lambda: htot_widget.get_val() * vtot_widget.get_val()) +frame_us_widget = MyIntText(fmt="frame {:.2f} ms", + calc = lambda: khz_to_us(pclk_khz_widget.get_val()) * htot_widget.get_val() * vtot_widget.get_val() / 1000) +frame_khz_widget = MyIntText(fmt="frame {:.2f} Hz", + calc = lambda: div_or_zero(pclk_khz_widget.get_val() * 1000, htot_widget.get_val() * vtot_widget.get_val())) + +info_box = urwid.LineBox(urwid.Pile([line_us_widget, line_khz_widget, urwid.Divider(), frame_tot_widget, frame_us_widget, frame_khz_widget]), title = "Info") + +# Set update lists + +recalc_list = [ pclk_ps_widget, line_us_widget, line_khz_widget, frame_tot_widget, frame_us_widget, frame_khz_widget ] + +hdisp_widget.set_updlist([hdisp2_widget, hss_widget, hse_widget, htot_widget]) +hfp_widget.set_updlist([hss_widget, hse_widget, htot_widget]) +hsw_widget.set_updlist([hse_widget, htot_widget]) +hbp_widget.set_updlist([htot_widget]) +hdisp2_widget.set_updlist([hdisp_widget, hfp_widget]) +hss_widget.set_updlist([hfp_widget, hsw_widget]) +hse_widget.set_updlist([hsw_widget, hbp_widget]) +htot_widget.set_updlist([hbp_widget]) + +vdisp_widget.set_updlist([vdisp2_widget, vss_widget, vse_widget, vtot_widget]) +vfp_widget.set_updlist([vss_widget, vse_widget, vtot_widget]) +vsw_widget.set_updlist([vse_widget, vtot_widget]) +vbp_widget.set_updlist([vtot_widget]) +vdisp2_widget.set_updlist([vdisp_widget, vfp_widget]) +vss_widget.set_updlist([vfp_widget, vsw_widget]) +vse_widget.set_updlist([vsw_widget, vbp_widget]) +vtot_widget.set_updlist([vbp_widget]) + +# Flags + +fb = None + +DRM_MODE_FLAG_PHSYNC = (1<<0) +DRM_MODE_FLAG_NHSYNC = (1<<1) +DRM_MODE_FLAG_PVSYNC = (1<<2) +DRM_MODE_FLAG_NVSYNC = (1<<3) +DRM_MODE_FLAG_INTERLACE = (1<<4) +DRM_MODE_FLAG_DBLCLK = (1<<12) + +def mode_is_ilace(mode): + return (mode.flags & DRM_MODE_FLAG_INTERLACE) != 0 + +def apply_mode(): + global fb + + mode = pykms.Videomode() + mode.clock = pclk_khz_widget.get_val() + + mode.hdisplay = hdisp2_widget.get_val() + mode.hsync_start = hss_widget.get_val() + mode.hsync_end = hse_widget.get_val() + mode.htotal = htot_widget.get_val() + + mode.vdisplay = vdisp2_widget.get_val() + mode.vsync_start = vss_widget.get_val() + mode.vsync_end = vse_widget.get_val() + mode.vtotal = vtot_widget.get_val() + + if ilace_box.state: + mode.flags |= DRM_MODE_FLAG_INTERLACE + + if dblclk_box.state: + mode.flags |= DRM_MODE_FLAG_DBLCLK + + if hsync_pol.state == True: + mode.flags |= DRM_MODE_FLAG_PHSYNC + elif hsync_pol.state == False: + mode.flags |= DRM_MODE_FLAG_NHSYNC + + if vsync_pol.state == True: + mode.flags |= DRM_MODE_FLAG_PVSYNC + elif vsync_pol.state == False: + mode.flags |= DRM_MODE_FLAG_NVSYNC + + fb = pykms.DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24"); + pykms.draw_test_pattern(fb); + + crtc.set_mode(conn, fb, mode) + +def read_mode(mode): + pclk_khz_widget.set_val(mode.clock) + hdisp2_widget.set_val(mode.hdisplay) + hss_widget.set_val(mode.hsync_start) + hse_widget.set_val(mode.hsync_end) + htot_widget.set_val(mode.htotal) + + vdisp2_widget.set_val(mode.vdisplay) + vss_widget.set_val(mode.vsync_start) + vse_widget.set_val(mode.vsync_end) + vtot_widget.set_val(mode.vtotal) + + ilace_box.set_state(mode_is_ilace(mode)) + dblclk_box.set_state((mode.flags & DRM_MODE_FLAG_DBLCLK) != 0) + + sync = 'mixed' + if (mode.flags & DRM_MODE_FLAG_PHSYNC) != 0: + sync = True + elif (mode.flags & DRM_MODE_FLAG_NHSYNC) != 0: + sync = False + hsync_pol.set_state(sync) + + sync = 'mixed' + if (mode.flags & DRM_MODE_FLAG_PVSYNC) != 0: + sync = True + elif (mode.flags & DRM_MODE_FLAG_NVSYNC) != 0: + sync = False + vsync_pol.set_state(sync) + +def apply_press(w): + apply_mode() + +ilace_box = urwid.CheckBox('interlace') +hsync_pol = urwid.CheckBox('hsync positive', has_mixed=True) +vsync_pol = urwid.CheckBox('vsync positive', has_mixed=True) +dblclk_box = urwid.CheckBox('double clock') + +flags_pile = urwid.LineBox(urwid.Pile([ilace_box, hsync_pol, vsync_pol, dblclk_box]), title = "Flags") + +apply_button = urwid.LineBox(urwid.Padding(urwid.Button('apply', on_press=apply_press))) + +# Main + +def mode_press(w, mode): + read_mode(mode) + +def mode_to_str(mode): + return "{}@{}{}".format(mode.name, mode.vrefresh, "i" if mode_is_ilace(mode) else "") + +mode_buttons = [] + +card = pykms.Card() +conn = card.get_first_connected_connector() +crtc = conn.get_current_crtc() +modes = conn.get_modes() +i = 0 +for m in modes: + mode_buttons.append(urwid.Button(mode_to_str(m), on_press=mode_press, user_data=m)) + i += 1 + +modes_pile = urwid.LineBox(urwid.Pile(mode_buttons), title = "Video modes") + +main_pile = urwid.Pile([modes_pile, pclk_columns, urwid.Columns([ h_columns, v_columns ]), info_box, flags_pile, apply_button]) + +main_columns = urwid.Filler(main_pile, valign='top') + +loop = urwid.MainLoop(main_columns, unhandled_input=exit_on_q, handle_mouse=False) + +# select the first mode +mode_press(None, modes[0]) + +loop.run() + +fb = None diff --git a/py/tests/test.py b/py/tests/test.py new file mode 100755 index 0000000..9c23b5b --- /dev/null +++ b/py/tests/test.py @@ -0,0 +1,18 @@ +#!/usr/bin/python3 + +import pykms +from helpers import * + +card = pykms.Card() +res = pykms.ResourceManager(card) +conn = res.reserve_connector() +crtc = res.reserve_crtc(conn) + +mode = conn.get_default_mode() + +fb = pykms.DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24"); +pykms.draw_test_pattern(fb); + +crtc.set_mode(conn, fb, mode) + +input("press enter to exit\n") diff --git a/py/tests/trans-test.py b/py/tests/trans-test.py new file mode 100755 index 0000000..8c1f964 --- /dev/null +++ b/py/tests/trans-test.py @@ -0,0 +1,332 @@ +#!/usr/bin/python3 + +import pykms +from helpers import * +import time + +# This hack makes drm initialize the fbcon, setting up the default connector +card = pykms.Card() +card = 0 + +card = pykms.Card() +res = pykms.ResourceManager(card) +conn = res.reserve_connector() +crtc = res.reserve_crtc(conn) +mode = conn.get_default_mode() + +planes = [] +for p in card.planes: + if p.supports_crtc(crtc) == False: + continue + planes.append(p) + +disable_planes(card) + +w = mode.hdisplay +h = mode.vdisplay + +fbs=[] + +def test_am5_trans_dest(): + fbs.append(pykms.DumbFramebuffer(card, w, h, "XR24")) + fbs.append(pykms.DumbFramebuffer(card, w, h, "XR24")) + + fb = fbs[0] + pykms.draw_rect(fb, 0, 0, fb.width, fb.height, purple) + pykms.draw_rect(fb, 100, 100, 100, 200, green) + pykms.draw_rect(fb, 300, 100, 100, 200, red) + pykms.draw_rect(fb, 500, 100, 100, 200, white) + + fb = fbs[1] + pykms.draw_rect(fb, 0, 0, fb.width, fb.height, cyan) + pykms.draw_rect(fb, 250, 100, 200, 200, yellow) + + set_props(crtc, { + "trans-key-mode": 1, + "trans-key": purple.rgb888, + "background": 0, + "alpha_blender": 0, + }) + + plane = 0 + + for i in range(0,2): + print("set crtc {}, plane {}, fb {}".format(crtc.id, planes[i].id, fbs[i].id)) + + plane = planes[i] + fb = fbs[i] + set_props(plane, { + "FB_ID": fb.id, + "CRTC_ID": crtc.id, + "SRC_W": fb.width << 16, + "SRC_H": fb.height << 16, + "CRTC_W": fb.width, + "CRTC_H": fb.height, + "zorder": i, + }) + + time.sleep(1) + +def test_am5_trans_src(): + fbs.append(pykms.DumbFramebuffer(card, w, h, "XR24")) + fbs.append(pykms.DumbFramebuffer(card, w, h, "XR24")) + + fb = fbs[0] + pykms.draw_rect(fb, 0, 0, fb.width, fb.height, white) + pykms.draw_rect(fb, 200, 200, 100, 100, red) + pykms.draw_rect(fb, fb.width - 300, 200, 100, 100, green) + + fb = fbs[1] + pykms.draw_rect(fb, 0, 0, fb.width, fb.height, cyan) + pykms.draw_rect(fb, 100, 100, 500, 500, purple) + + set_props(crtc, { + "trans-key-mode": 2, + "trans-key": purple.rgb888, + "background": 0, + "alpha_blender": 0, + }) + + plane = 0 + + for i in range(0,2): + print("set crtc {}, plane {}, fb {}".format(crtc.id, planes[i].id, fbs[i].id)) + + plane = planes[i] + fb = fbs[i] + set_props(plane, { + "FB_ID": fb.id, + "CRTC_ID": crtc.id, + "SRC_W": fb.width << 16, + "SRC_H": fb.height << 16, + "CRTC_W": fb.width, + "CRTC_H": fb.height, + "zorder": 3 if i == 1 else 0, + }) + + time.sleep(1) + +def test_am4_normal_trans_dst(): + fbs.append(pykms.DumbFramebuffer(card, w, h, "XR24")) + fbs.append(pykms.DumbFramebuffer(card, w * 2 // 3, h, "XR24")) + fbs.append(pykms.DumbFramebuffer(card, w * 2 // 3, h, "XR24")) + + fb = fbs[0] + pykms.draw_rect(fb, 0, 0, w, h, purple) + pykms.draw_rect(fb, 100, 50, 50, 200, green) + pykms.draw_rect(fb, 200, 50, 50, 200, red) + pykms.draw_rect(fb, 300, 50, 50, 200, white) + + fb = fbs[1] + pykms.draw_rect(fb, 0, 0, fb.width, fb.height, blue) + + fb = fbs[2] + pykms.draw_rect(fb, 0, 0, fb.width, fb.height, cyan) + + set_props(crtc, { + "trans-key-mode": 1, + "trans-key": purple.rgb888, + "background": 0, + "alpha_blender": 0, + }) + + time.sleep(1) + + plane = planes[0] + fb = fbs[0] + set_props(plane, { + "FB_ID": fb.id, + "CRTC_ID": crtc.id, + "SRC_W": fb.width << 16, + "SRC_H": fb.height << 16, + "CRTC_W": w, + "CRTC_H": h, + }) + + time.sleep(1) + + plane = planes[1] + fb = fbs[1] + set_props(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, + }) + + time.sleep(1) + + plane = planes[2] + fb = fbs[2] + set_props(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": w // 3, + "CRTC_Y": 0, + "CRTC_W": fb.width, + "CRTC_H": fb.height, + }) + +def test_am4_normal_trans_src(): + fbs.append(pykms.DumbFramebuffer(card, w, h, "XR24")) + fbs.append(pykms.DumbFramebuffer(card, w // 2, h, "XR24")) + fbs.append(pykms.DumbFramebuffer(card, w // 2, h, "XR24")) + + fb = fbs[0] + pykms.draw_rect(fb, 0, 0, w, h, pykms.RGB(128, 255, 255)) + pykms.draw_rect(fb, 200, 100, 50, 200, red) + pykms.draw_rect(fb, w - 200 - 50, 100, 50, 200, green) + + fb = fbs[1] + pykms.draw_rect(fb, 0, 0, fb.width, fb.height, blue) + pykms.draw_rect(fb, 100, 100, fb.width - 200, fb.height - 200, purple) + + fb = fbs[2] + pykms.draw_rect(fb, 0, 0, fb.width, fb.height, cyan) + pykms.draw_rect(fb, 100, 100, fb.width - 200, fb.height - 200, purple) + + set_props(crtc, { + "trans-key-mode": 2, + "trans-key": purple.rgb888, + "background": 0, + "alpha_blender": 0, + }) + + time.sleep(1) + + plane = planes[0] + fb = fbs[0] + set_props(plane, { + "FB_ID": fb.id, + "CRTC_ID": crtc.id, + "SRC_W": fb.width << 16, + "SRC_H": fb.height << 16, + "CRTC_W": w, + "CRTC_H": h, + }) + + time.sleep(1) + + plane = planes[1] + fb = fbs[1] + set_props(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, + }) + + time.sleep(1) + + plane = planes[2] + fb = fbs[2] + set_props(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": w - fb.width, + "CRTC_Y": 0, + "CRTC_W": fb.width, + "CRTC_H": fb.height, + }) + +def test_am4_alpha_trans_src(): + fbs.append(pykms.DumbFramebuffer(card, w, h, "XR24")) + fbs.append(pykms.DumbFramebuffer(card, w // 2, h, "XR24")) + fbs.append(pykms.DumbFramebuffer(card, w // 2, h, "XR24")) + + fb = fbs[0] + pykms.draw_rect(fb, 0, 0, w, h, purple) + pykms.draw_rect(fb, 200, 100, 50, 200, red) + pykms.draw_rect(fb, w - 200 - 50, 100, 50, 200, green) + + fb = fbs[1] + pykms.draw_rect(fb, 0, 0, fb.width, fb.height, blue) + pykms.draw_rect(fb, 100, 100, fb.width - 200, fb.height - 200, purple) + + fb = fbs[2] + pykms.draw_rect(fb, 0, 0, fb.width, fb.height, cyan) + pykms.draw_rect(fb, 100, 100, fb.width - 200, fb.height - 200, purple) + + set_props(crtc, { + "trans-key-mode": 1, + "trans-key": purple.rgb888, + "background": 0, + "alpha_blender": 1, + }) + + time.sleep(1) + + plane = planes[0] + fb = fbs[0] + set_props(plane, { + "FB_ID": fb.id, + "CRTC_ID": crtc.id, + "SRC_W": fb.width << 16, + "SRC_H": fb.height << 16, + "CRTC_W": w, + "CRTC_H": h, + }) + + time.sleep(1) + + plane = planes[1] + fb = fbs[1] + set_props(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, + }) + + time.sleep(1) + + plane = planes[2] + fb = fbs[2] + set_props(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": w - fb.width, + "CRTC_Y": 0, + "CRTC_W": fb.width, + "CRTC_H": fb.height, + }) + + + +#test_am5_trans_dest() +test_am5_trans_src() +#test_am4_normal_trans_dst() +#test_am4_normal_trans_src() +#test_am4_alpha_trans_src() + +input("press enter to exit\n") -- cgit v1.2.3