arg -> closure
authorThomas Walker Lynch <xtujpz@reasoningtechnology.com>
Fri, 20 Sep 2024 01:22:06 +0000 (01:22 +0000)
committerThomas Walker Lynch <xtujpz@reasoningtechnology.com>
Fri, 20 Sep 2024 01:22:06 +0000 (01:22 +0000)
developer/cc/Card.c [new file with mode: 0644]
developer/cc/Frame.c
developer/cc/global.c [new file with mode: 0644]
developer/cc/main.c [new file with mode: 0644]

diff --git a/developer/cc/Card.c b/developer/cc/Card.c
new file mode 100644 (file)
index 0000000..d910a72
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+  Card types
+
+  Currently implements DRM dumb buffer interface only.
+
+*/
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+// 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);
+}
index 106d0ac..c489743 100644 (file)
@@ -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 (file)
index 0000000..a6f4363
--- /dev/null
@@ -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 (file)
index 0000000..0ebe41b
--- /dev/null
@@ -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;
+}