Skip to content

Commit

Permalink
Add begin/end_cpu_access
Browse files Browse the repository at this point in the history
  • Loading branch information
tomba committed Aug 30, 2024
1 parent 59b5d9c commit df45d3f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
62 changes: 62 additions & 0 deletions kms/framebuffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from typing import TYPE_CHECKING

import pixutils.ioctl

import kms
import kms.uapi

Expand Down Expand Up @@ -51,6 +53,12 @@ def clear(self):
ptr = ptrtype.from_buffer(self.map(idx))
ctypes.memset(ptr, 0, self.size(idx))

def begin_cpu_access(self, access: str):
raise NotImplementedError()

def end_cpu_access(self):
raise NotImplementedError()


class DumbFramebuffer(Framebuffer):
def __init__(self, card: Card, width: int, height: int, format: kms.PixelFormat) -> None:
Expand Down Expand Up @@ -146,12 +154,33 @@ def fd(self, plane_idx):

return p.prime_fd

def begin_cpu_access(self, access: str):
pass

def end_cpu_access(self):
pass


class DmabufFramebuffer(Framebuffer):
class struct_dma_buf_sync(ctypes.Structure):
__slots__ = ['flags']
_fields_ = [('flags', ctypes.c_uint64)]

DMA_BUF_BASE = 'b'
DMA_BUF_IOCTL_SYNC = pixutils.ioctl.IOW(DMA_BUF_BASE, 0, struct_dma_buf_sync)

DMA_BUF_SYNC_READ = 1 << 0
DMA_BUF_SYNC_WRITE = 2 << 0
DMA_BUF_SYNC_RW = DMA_BUF_SYNC_READ | DMA_BUF_SYNC_WRITE
DMA_BUF_SYNC_START = 0 << 2
DMA_BUF_SYNC_END = 1 << 2

def __init__(self, card: Card, width: int, height: int, format: kms.PixelFormat,
fds: list[int], pitches: list[int], offsets: list[int]) -> None:
planes = []

self._sync_flags = 0

for idx in range(len(format.planes)):
args = kms.uapi.drm_prime_handle(fd=fds[idx])
fcntl.ioctl(card.fd, kms.uapi.DRM_IOCTL_PRIME_FD_TO_HANDLE, args, True)
Expand Down Expand Up @@ -213,3 +242,36 @@ def fd(self, plane_idx):
p = self.planes[plane_idx]

return p.prime_fd

def begin_cpu_access(self, access: str):
if self._sync_flags != 0:
raise RuntimeError("begin_cpu sync already started")

if access == 'r':
self._sync_flags = DmabufFramebuffer.DMA_BUF_SYNC_READ
elif access == 'w':
self._sync_flags = DmabufFramebuffer.DMA_BUF_SYNC_WRITE
elif access == 'rw':
self._sync_flags = DmabufFramebuffer.DMA_BUF_SYNC_RW
else:
raise RuntimeError('Bad access type "{access}"')

dbs = DmabufFramebuffer.struct_dma_buf_sync()
# pylint: disable=attribute-defined-outside-init
dbs.flags = DmabufFramebuffer.DMA_BUF_SYNC_START | self._sync_flags

for p in self.planes:
fcntl.ioctl(p.prime_fd, DmabufFramebuffer.DMA_BUF_IOCTL_SYNC, dbs, False)

def end_cpu_access(self):
if self._sync_flags == 0:
raise RuntimeError("begin_cpu sync not started")

dbs = DmabufFramebuffer.struct_dma_buf_sync()
# pylint: disable=attribute-defined-outside-init
dbs.flags = DmabufFramebuffer.DMA_BUF_SYNC_END | self._sync_flags

for p in self.planes:
fcntl.ioctl(p.prime_fd, DmabufFramebuffer.DMA_BUF_IOCTL_SYNC, dbs, False)

self._sync_flags = 0
2 changes: 2 additions & 0 deletions utils/kmstest.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ def main():
fb = kms.DumbFramebuffer(card, width, height, fmt)

ts1 = time.perf_counter()
fb.begin_cpu_access('w')
draw_test_pattern(fb)
fb.end_cpu_access()
ts2 = time.perf_counter()
print(f'Drawing took {(ts2 - ts1) * 1000:.4f} ms')

Expand Down

0 comments on commit df45d3f

Please sign in to comment.