Add rudimentary multi-connector support to fbmirror as well
This commit is contained in:
parent
2442bee476
commit
9bd7813dc3
2 changed files with 31 additions and 4 deletions
|
|
@ -34,12 +34,31 @@ with open("/sys/class/graphics/fb0/stride") as f:
|
||||||
|
|
||||||
linux_framebuffer = np.memmap('/dev/fb0',mode='r', shape=(screeny, stride // bytes_per_pixel), dtype=dtype)
|
linux_framebuffer = np.memmap('/dev/fb0',mode='r', shape=(screeny, stride // bytes_per_pixel), dtype=dtype)
|
||||||
|
|
||||||
|
def make_pixelmap_multilane(width, height, n_addr_lines, n_lanes):
|
||||||
|
calc_height = n_lanes << n_addr_lines
|
||||||
|
if height != calc_height:
|
||||||
|
raise RuntimeError(f"Calculated height {calc_height} does not match requested height {height}")
|
||||||
|
n_addr = 1 << n_addr_lines
|
||||||
|
|
||||||
|
m = []
|
||||||
|
for addr in range(n_addr):
|
||||||
|
for x in range(width):
|
||||||
|
for lane in range(n_lanes):
|
||||||
|
y = addr + lane * n_addr
|
||||||
|
m.append(x + width * y)
|
||||||
|
print(m)
|
||||||
|
return m
|
||||||
|
|
||||||
@click.command
|
@click.command
|
||||||
@click.option("--x-offset", "xoffset", type=int, help="The x offset of top left corner of the region to mirror", default=0)
|
@click.option("--x-offset", "xoffset", type=int, help="The x offset of top left corner of the region to mirror", default=0)
|
||||||
@click.option("--y-offset", "yoffset", type=int, help="The y offset of top left corner of the region to mirror", default=0)
|
@click.option("--y-offset", "yoffset", type=int, help="The y offset of top left corner of the region to mirror", default=0)
|
||||||
@piomatter_click.standard_options
|
@piomatter_click.standard_options(n_lanes=2, n_temporal_planes=4)
|
||||||
def main(xoffset, yoffset, width, height, serpentine, rotation, pinout, n_planes, n_addr_lines):
|
def main(xoffset, yoffset, width, height, serpentine, rotation, pinout, n_planes, n_temporal_planes, n_addr_lines, n_lanes):
|
||||||
geometry = piomatter.Geometry(width=width, height=height, n_planes=n_planes, n_addr_lines=n_addr_lines, rotation=rotation)
|
if n_lanes != 2:
|
||||||
|
pixelmap = make_pixelmap_multilane(width, height, n_addr_lines, n_lanes)
|
||||||
|
geometry = piomatter.Geometry(width=width, height=height, n_planes=n_planes, n_addr_lines=n_addr_lines, n_temporal_planes=n_temporal_planes, n_lanes=n_lanes, map=pixelmap)
|
||||||
|
else:
|
||||||
|
geometry = piomatter.Geometry(width=width, height=height, n_planes=n_planes, n_addr_lines=n_addr_lines, n_temporal_planes=n_temporal_planes, rotation=rotation)
|
||||||
framebuffer = np.zeros(shape=(geometry.height, geometry.width), dtype=dtype)
|
framebuffer = np.zeros(shape=(geometry.height, geometry.width), dtype=dtype)
|
||||||
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB565, pinout=pinout, framebuffer=framebuffer, geometry=geometry)
|
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB565, pinout=pinout, framebuffer=framebuffer, geometry=geometry)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,11 @@ class PybindEnumChoice(click.Choice):
|
||||||
r = getattr(self.enum, value)
|
r = getattr(self.enum, value)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
def validate_temporal_planes(ctx, param, value):
|
||||||
|
if value not in (0, 2, 4):
|
||||||
|
raise click.BadParameter("must be 0, 2, or 4")
|
||||||
|
return value
|
||||||
|
|
||||||
def standard_options(
|
def standard_options(
|
||||||
f: click.decorators.FC | None = None,
|
f: click.decorators.FC | None = None,
|
||||||
*,
|
*,
|
||||||
|
|
@ -35,6 +40,7 @@ def standard_options(
|
||||||
rotation=piomatter.Orientation.Normal,
|
rotation=piomatter.Orientation.Normal,
|
||||||
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
|
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
|
||||||
n_planes=10,
|
n_planes=10,
|
||||||
|
n_temporal_planes=None,
|
||||||
n_addr_lines=4,
|
n_addr_lines=4,
|
||||||
n_lanes=None,
|
n_lanes=None,
|
||||||
) -> Callable[[], None]:
|
) -> Callable[[], None]:
|
||||||
|
|
@ -75,7 +81,9 @@ def standard_options(
|
||||||
help="The overall orientation (rotation) of the panels"
|
help="The overall orientation (rotation) of the panels"
|
||||||
)(f)
|
)(f)
|
||||||
if n_planes is not None:
|
if n_planes is not None:
|
||||||
f = click.option("--num-planes", "n_planes", default=n_planes, help="The number of bit planes (color depth. Lower values can improve refresh rate in frames per second")(f)
|
f = click.option("--num-planes", "n_planes", default=n_planes, help="The number of bit planes (color depth). Lower values can improve refresh rate in frames per second")(f)
|
||||||
|
if n_temporal_planes is not None:
|
||||||
|
f = click.option("--num-temporal-planes", "n_temporal_planes", default=n_temporal_planes, callback=validate_temporal_planes, help="The number of temporal bit-planes. May be 0, 2, or 4. Nonzero values improve frame rate but can cause some shimmer")(f)
|
||||||
if n_addr_lines is not None:
|
if n_addr_lines is not None:
|
||||||
f = click.option("--num-address-lines", "n_addr_lines", default=n_addr_lines, help="The number of address lines used by the panels")(f)
|
f = click.option("--num-address-lines", "n_addr_lines", default=n_addr_lines, help="The number of address lines used by the panels")(f)
|
||||||
if n_lanes is not None:
|
if n_lanes is not None:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue