summaryrefslogtreecommitdiff
path: root/src/til_fb.h
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2022-04-28 01:46:10 -0700
committerVito Caputo <vcaputo@pengaru.com>2022-05-01 21:02:41 -0700
commita59229c5513e73348c87bcfc5cc4b39a31012437 (patch)
tree09cbc567f883b8f8677f689f658cd747ca360706 /src/til_fb.h
parent7dec62422b3b00f9a347d37f1e7f89e5bbaba0a9 (diff)
til_fb: introduce a fragment texture source
Idea here is to provide texture sources for obtaining pixel colors at the til_fb_put_pixel/fill drawing API, making it possible for at least overlayable modules to serve as mask/stencil operators where their drawn areas are populated by the contents of another fragment produced dynamically, potentially by other modules altogether. This commit adds a texture=modulename option to the compose module for specifying if a texture should be used when compositing, excepting and defaulting to "none" for disabling texturing. A future commit should expand this compose option to accept a potential list of modules for composing the texture in the same way as the main layers= list functions. Something this all immediately makes clear is the need for a better settings syntax, probably in the form of all module setting specifiers optionally being followed by a squence of settings, with support for escaping to handle nested situations.
Diffstat (limited to 'src/til_fb.h')
-rw-r--r--src/til_fb.h75
1 files changed, 61 insertions, 14 deletions
diff --git a/src/til_fb.h b/src/til_fb.h
index 55e9b6c..3ebede7 100644
--- a/src/til_fb.h
+++ b/src/til_fb.h
@@ -1,26 +1,31 @@
#ifndef _TIL_FB_H
#define _TIL_FB_H
+#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "til_settings.h"
#include "til_setup.h"
+#include "til_util.h"
+
+typedef struct til_fb_fragment_t til_fb_fragment_t;
/* All renderers should target fb_fragment_t, which may or may not represent
* a full-screen mmap. Helpers are provided for subdividing fragments for
* concurrent renderers.
*/
typedef struct til_fb_fragment_t {
- uint32_t *buf; /* pointer to the first pixel in the fragment */
- unsigned x, y; /* absolute coordinates of the upper left corner of this fragment */
- unsigned width, height; /* width and height of this fragment */
- unsigned frame_width; /* width of the frame this fragment is part of */
- unsigned frame_height; /* height of the frame this fragment is part of */
- unsigned stride; /* number of 32-bit words from the end of one row to the start of the next */
- unsigned pitch; /* number of 32-bit words separating y from y + 1, including any padding */
- unsigned number; /* this fragment's number as produced by fragmenting */
- unsigned cleared:1; /* if this fragment has been cleared since last flip */
+ til_fb_fragment_t *texture; /* optional source texture when drawing to this fragment */
+ uint32_t *buf; /* pointer to the first pixel in the fragment */
+ unsigned x, y; /* absolute coordinates of the upper left corner of this fragment */
+ unsigned width, height; /* width and height of this fragment */
+ unsigned frame_width; /* width of the frame this fragment is part of */
+ unsigned frame_height; /* height of the frame this fragment is part of */
+ unsigned stride; /* number of 32-bit words from the end of one row to the start of the next */
+ unsigned pitch; /* number of 32-bit words separating y from y + 1, including any padding */
+ unsigned number; /* this fragment's number as produced by fragmenting */
+ unsigned cleared:1; /* if this fragment has been cleared since last flip */
} til_fb_fragment_t;
/* This is a page handle object for page flip submission/life-cycle.
@@ -70,12 +75,20 @@ static inline int til_fb_fragment_contains(til_fb_fragment_t *fragment, int x, i
}
+/* gets a pixel from the fragment, no bounds checking is performed. */
+static inline uint32_t til_fb_fragment_get_pixel_unchecked(til_fb_fragment_t *fragment, int x, int y)
+{
+ return fragment->buf[(y - fragment->y) * fragment->pitch + x - fragment->x];
+}
+
+
/* puts a pixel into the fragment, no bounds checking is performed. */
static inline void til_fb_fragment_put_pixel_unchecked(til_fb_fragment_t *fragment, int x, int y, uint32_t pixel)
{
- uint32_t *pixels = fragment->buf + (y - fragment->y) * fragment->pitch;
+ if (fragment->texture)
+ pixel = til_fb_fragment_get_pixel_unchecked(fragment->texture, x, y);
- pixels[x - fragment->x] = pixel;
+ fragment->buf[(y - fragment->y) * fragment->pitch + x - fragment->x] = pixel;
}
@@ -91,8 +104,31 @@ static inline int til_fb_fragment_put_pixel_checked(til_fb_fragment_t *fragment,
}
-/* fill a fragment with an arbitrary pixel */
-static inline void til_fb_fragment_fill(til_fb_fragment_t *fragment, uint32_t pixel)
+/* copy a fragment, x,y,width,height are absolute coordinates within the frames, and will be clipped to the overlapping fragment areas */
+static inline void til_fb_fragment_copy(til_fb_fragment_t *dest, int x, int y, int width, int height, til_fb_fragment_t *src)
+{
+ int X = MAX(dest->x, src->x);
+ int Y = MAX(dest->y, src->y);
+ int W = MIN(dest->x + dest->width, src->x + src->width) - X;
+ int H = MIN(dest->y + dest->height, src->y + src->height) - Y;
+
+ assert(W >= 0 && H >= 0);
+
+ /* XXX FIXME TODO */
+ /* XXX FIXME TODO */
+ /* XXX FIXME TODO */
+ /* this is PoC fast and nasty code, optimize this to at least bulk copy rows of pixels */
+ /* XXX FIXME TODO */
+ /* XXX FIXME TODO */
+ /* XXX FIXME TODO */
+ for (int v = 0; v < H; v++) {
+ for (int u = 0; u < W; u++)
+ til_fb_fragment_put_pixel_unchecked(dest, X + u, Y + v, til_fb_fragment_get_pixel_unchecked(src, X + u, Y + v));
+ }
+}
+
+
+static inline void _til_fb_fragment_fill(til_fb_fragment_t *fragment, uint32_t pixel)
{
uint32_t *buf = fragment->buf;
@@ -105,13 +141,24 @@ static inline void til_fb_fragment_fill(til_fb_fragment_t *fragment, uint32_t pi
}
+/* fill a fragment with an arbitrary pixel */
+static inline void til_fb_fragment_fill(til_fb_fragment_t *fragment, uint32_t pixel)
+{
+ if (!fragment->texture)
+ return _til_fb_fragment_fill(fragment, pixel);
+
+ /* when a texture is present, pixel is ignored and instead sourced from fragment->texture->buf[y*pitch+x] */
+ til_fb_fragment_copy(fragment, fragment->x, fragment->y, fragment->width, fragment->height, fragment->texture);
+}
+
+
/* clear a fragment */
static inline void til_fb_fragment_clear(til_fb_fragment_t *fragment)
{
if (fragment->cleared)
return;
- til_fb_fragment_fill(fragment, 0);
+ _til_fb_fragment_fill(fragment, 0);
fragment->cleared = 1;
}
© All Rights Reserved