From 689028f803dab6b0c7afbe37a12d9d811b6eddef Mon Sep 17 00:00:00 2001 From: Thomas Walker Lynch Date: Fri, 20 Sep 2024 01:22:06 +0000 Subject: [PATCH] arg -> closure --- developer/cc/Card.c | 62 +++++++++++++++++++++++++++++++++++++ developer/cc/Frame.c | 38 +++++++++++------------ developer/cc/global.c | 15 +++++++++ developer/cc/main.c | 71 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 19 deletions(-) create mode 100644 developer/cc/Card.c create mode 100644 developer/cc/global.c create mode 100644 developer/cc/main.c diff --git a/developer/cc/Card.c b/developer/cc/Card.c new file mode 100644 index 0000000..d910a72 --- /dev/null +++ b/developer/cc/Card.c @@ -0,0 +1,62 @@ +/* + Card types + + Currently implements DRM dumb buffer interface only. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +// requires global.c + +//-------------------------------------------------------------------------------- +// Card Abstract Interface + +typedef void (*CaptureCallback) +( + Frame *captured_frame + ,Frame *display_frame + ,CircularQueue *context_window + ,Closure *closure + ); + +typedef struct { + void (*capture)(Frame *capture_frame ,CaptureCallback f ,Closure *closure); + void (*display)(Frame *dipslay_frame); // nonblocking +} Card; + +//-------------------------------------------------------------------------------- +// Instance data for the generic primitive `drm` card. + +typedef struct { + +} CardPrimitiveDRM·CaptureClosure; + +CardPrimitiveDRM·capture(Frame *capture_frame ,CaptureCallback f ,Closure *closure){ + CardPrimitiveDRM·CaptureClosure capture_closure = (CardPrimitiveDRM·CaptureClosure *)closure; + +} + + + +// Frame stream interface +typedef struct { + void (*capture_frame)(Frame *frame ,FrameCallback callback ,void *user_data); +} FrameStream; + +// Example of the frame stream implementation (for capturing frames from some device) +void FrameStreamDRM·capture(Frame *frame ,FrameCallback callback ,void *user_data){ + // Simulate frame capture or retrieval logic here... + + // Once the frame is captured, call the provided callback + Frame *display_frame = NULL; // Allocate or retrieve the display frame as needed + CircularQueue *context_window = NULL; // Optionally pass context + callback(frame, display_frame, context_window, user_data); +} diff --git a/developer/cc/Frame.c b/developer/cc/Frame.c index 106d0ac..c489743 100644 --- a/developer/cc/Frame.c +++ b/developer/cc/Frame.c @@ -128,7 +128,7 @@ bool Frame·write(Frame·Instance *frame ,Index32·Instance i ,const void *pixel // Search for an element where f returns non-null (exist pattern) -void* Frame·exist(Frame·Instance *frame ,Frame·PixelPredicate f ,void *arg) { +void* Frame·exist(Frame·Instance *frame ,Frame·PixelPredicate f ,Closure *closure) { if (!frame || !f) return NULL; Index32·Instance index = Index32·origin; // Start from (0, 0) @@ -137,7 +137,7 @@ void* Frame·exist(Frame·Instance *frame ,Frame·PixelPredicate f ,void *arg) { do{ void *pixel = Frame·access(frame ,index); if( pixel ){ - void *result = f(frame ,pixel ,index ,arg); + void *result = f(frame ,pixel ,index ,closure); if( result ) return result; } }while( Index32·increment(&index ,bound ,frame->pixel_size) ); @@ -147,40 +147,40 @@ void* Frame·exist(Frame·Instance *frame ,Frame·PixelPredicate f ,void *arg) { typedef struct { Frame·PixelPredicate f; // PixelPredicate type for the function - void *arg; // User-provided metadata -} Frame·every_arg_t; + Closure *closure; // User-provided metadata +} Frame·every_closure_t; -void *Frame·every_1(Frame *frame ,void *pixel ,Index32·Instance index ,void *arg0) { - Frame·every_arg_t *ea = (Frame·every_arg_t *)arg0; - ea->f(frame ,pixel ,index ,ea->arg); +void *Frame·every_1(Frame *frame ,void *pixel ,Index32·Instance index ,Closure *closure0) { + Frame·every_closure_t *ea = (Frame·every_closure_t *)closure0; + ea->f(frame ,pixel ,index ,ea->closure); return NULL; // Return NULL for `every` } -void Frame·every(Frame *frame ,Frame·PixelPredicate f ,void *arg) { - Frame·every_arg_t ea = {.f = f ,.arg = arg}; +void Frame·every(Frame *frame ,Frame·PixelPredicate f ,Closure *closure) { + Frame·every_closure_t ea = {.f = f ,.closure = closure}; Frame·exist(frame ,Frame·every_1 ,&ea); } typedef struct { Frame·PixelPredicate f; // PixelPredicate type for the function - void *arg; // User-provided metadata -} Frame·all_arg_t; + Closure *closure; // User-provided metadata +} Frame·all_closure_t; -void *Frame·all_1(Frame *frame ,void *pixel ,Index32·Instance index ,void *arg0) { - Frame·all_arg_t *aa = (Frame·all_arg_t *)arg0; - if( !aa->f(frame ,pixel ,index ,aa->arg) ) return pixel; // If a pixel doesn't satisfy the predicate, return it +void *Frame·all_1(Frame *frame ,void *pixel ,Index32·Instance index ,Closure *closure0) { + Frame·all_closure_t *aa = (Frame·all_closure_t *)closure0; + if( !aa->f(frame ,pixel ,index ,aa->closure) ) return pixel; // If a pixel doesn't satisfy the predicate, return it return NULL; } -bool Frame·all(Frame *frame ,Frame·PixelPredicate f ,void *arg) { - Frame·all_arg_t aa = {.f = f ,.arg = arg}; +bool Frame·all(Frame *frame ,Frame·PixelPredicate f ,Closure *closure) { + Frame·all_closure_t aa = {.f = f ,.closure = closure}; return Frame·exist(frame ,Frame·all_1 ,&aa) == NULL; // If `exist` returns NULL, all elements satisfied the predicate } // Fill the frame with a specific pixel -void *Frame·fill_1(Frame *frame ,void *pixel_in_frame ,Index32·Instance index ,void *arg) { - // `arg` contains the pixel value to fill with - const void *fill_pixel = arg; +void *Frame·fill_1(Frame *frame ,void *pixel_in_frame ,Index32·Instance index ,Closure *closure) { + // `closure` contains the pixel value to fill with + const void *fill_pixel = closure; memcpy(pixel_in_frame ,fill_pixel ,((Frame·Instance *)frame)->pixel_size); return NULL; // Return NULL to indicate that we don't stop the loop (like `Frame·every`) } diff --git a/developer/cc/global.c b/developer/cc/global.c new file mode 100644 index 0000000..a6f4363 --- /dev/null +++ b/developer/cc/global.c @@ -0,0 +1,15 @@ +/* +The center dot separates namespace names from identifiers. + +The `.c` files are included directly into main.c so that the optimizer can have +global purview. C requires forward referencing, so order matters. + +This file comes first among the `.c` file includes, and thus the declarations +and definitions found herein can be used by all others. + +*/ + +typedef struct Closure Closure; + + + diff --git a/developer/cc/main.c b/developer/cc/main.c new file mode 100644 index 0000000..0ebe41b --- /dev/null +++ b/developer/cc/main.c @@ -0,0 +1,71 @@ +/* +A Frame is a 2D array of pixels. + +The main loop consists of: + +1. capture frame +2. transform frame +3. display frame + +The capture frame is what the graphics card would have dip slayed, had we not +interceded. + +This version uses dumb buffers that the program manages. + +*/ + +void main_loop(){ + + + +} + + +int main() { + int fd = open("/dev/dri/card2", O_RDWR | O_CLOEXEC); // Open the DRM device + if (fd < 0) { + perror("Failed to open DRM device"); + return -1; + } + + // Create a dumb buffer + struct drm_mode_create_dumb create_dumb = {0}; + create_dumb.width = 1920; + create_dumb.height = 1080; + create_dumb.bpp = 32; // 32 bits per pixel + + if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb) < 0) { + perror("DRM_IOCTL_MODE_CREATE_DUMB failed"); + close(fd); + return -1; + } + + // Map the dumb buffer + struct drm_mode_map_dumb map_dumb = {0}; + map_dumb.handle = create_dumb.handle; + + if (drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb) < 0) { + perror("DRM_IOCTL_MODE_MAP_DUMB failed"); + close(fd); + return -1; + } + + size_t buffer_size = create_dumb.size; + void* buffer = mmap(NULL, buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map_dumb.offset); + if (buffer == MAP_FAILED) { + perror("mmap failed for dumb buffer"); + close(fd); + return -1; + } + + printf("Dumb buffer created and mapped successfully. Size: %zu bytes\n", buffer_size); + + // Clean up + munmap(buffer, buffer_size); + struct drm_mode_destroy_dumb destroy_dumb = {0}; + destroy_dumb.handle = create_dumb.handle; + drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb); + + close(fd); + return 0; +} -- 2.20.1