From 53cc747fd2bdd774bc6f27f8aca5749c664b5cc7 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Sun, 24 Nov 2019 01:19:06 -0800 Subject: fb: add pitch to fb_fragment_t The put_pixel helpers really needed reworking to properly handle subframe fragments modules like montage will utilize. I had the stride present as it's convenient for a number of modules that maintain a buf pointer as they progress down a row, but the pitch is more applicable to put_pixel for scaling the y coordinate. Now there's both pitch and stride so everyone's happy with what's most convenient for their needs. --- src/drm_fb.c | 1 + src/fb.c | 9 ++++----- src/fb.h | 12 ++++++++---- src/sdl_fb.c | 1 + 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/drm_fb.c b/src/drm_fb.c index 3d0f6ba..cfaae29 100644 --- a/src/drm_fb.c +++ b/src/drm_fb.c @@ -455,6 +455,7 @@ static void * drm_fb_page_alloc(void *context, fb_page_t *res_page) res_page->fragment.height = c->mode->vdisplay; res_page->fragment.frame_height = c->mode->vdisplay; res_page->fragment.stride = create_dumb.pitch - (c->mode->hdisplay * 4); + res_page->fragment.pitch = create_dumb.pitch; return p; } diff --git a/src/fb.c b/src/fb.c index 7485800..a20fdd3 100644 --- a/src/fb.c +++ b/src/fb.c @@ -319,9 +319,7 @@ int fb_fragment_slice_single(const fb_fragment_t *fragment, unsigned n_fragments if (yoff >= fragment->height) return 0; - pitch = (fragment->width * 4) + fragment->stride; - - res_fragment->buf = ((void *)fragment->buf) + yoff * pitch; + res_fragment->buf = ((void *)fragment->buf) + yoff * fragment->pitch; res_fragment->x = fragment->x; res_fragment->y = yoff; res_fragment->width = fragment->width; @@ -329,6 +327,7 @@ int fb_fragment_slice_single(const fb_fragment_t *fragment, unsigned n_fragments res_fragment->frame_width = fragment->frame_width; res_fragment->frame_height = fragment->frame_height; res_fragment->stride = fragment->stride; + res_fragment->pitch = fragment->pitch; return 1; } @@ -337,7 +336,6 @@ int fb_fragment_slice_single(const fb_fragment_t *fragment, unsigned n_fragments int fb_fragment_tile_single(const fb_fragment_t *fragment, unsigned tile_size, unsigned num, fb_fragment_t *res_fragment) { unsigned w = fragment->width / tile_size, h = fragment->height / tile_size; - unsigned pitch = (fragment->width * 4) + fragment->stride; unsigned x, y, xoff, yoff; if (w * tile_size < fragment->width) @@ -355,7 +353,7 @@ int fb_fragment_tile_single(const fb_fragment_t *fragment, unsigned tile_size, u xoff = x * tile_size; yoff = y * tile_size; - res_fragment->buf = (void *)fragment->buf + (yoff * pitch) + (xoff * 4); + res_fragment->buf = (void *)fragment->buf + (yoff * fragment->pitch) + (xoff * 4); res_fragment->x = fragment->x + xoff; res_fragment->y = fragment->y + yoff; res_fragment->width = MIN(fragment->width - xoff, tile_size); @@ -363,6 +361,7 @@ int fb_fragment_tile_single(const fb_fragment_t *fragment, unsigned tile_size, u res_fragment->frame_width = fragment->frame_width; res_fragment->frame_height = fragment->frame_height; res_fragment->stride = fragment->stride + ((fragment->width - res_fragment->width) * 4); + res_fragment->pitch = fragment->pitch; return 1; } diff --git a/src/fb.h b/src/fb.h index f9d0b77..dfd4550 100644 --- a/src/fb.h +++ b/src/fb.h @@ -17,6 +17,7 @@ typedef struct fb_fragment_t { 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 bytes from the end of one row to the start of the next */ + unsigned pitch; /* number of bytes separating y from y + 1, including any padding */ } fb_fragment_t; /* This is a page handle object for page flip submission/life-cycle. @@ -67,10 +68,9 @@ static inline int fb_fragment_contains(fb_fragment_t *fragment, int x, int y) /* puts a pixel into the fragment, no bounds checking is performed. */ static inline void fb_fragment_put_pixel_unchecked(fb_fragment_t *fragment, int x, int y, uint32_t pixel) { - uint32_t *pixels = fragment->buf; + uint32_t *pixels = ((void *)fragment->buf) + (y - fragment->y) * fragment->pitch; - /* FIXME this assumes stride is aligned to 4 */ - pixels[((y - fragment->y) * (fragment->width + (fragment->stride >> 2))) + (x - fragment->x)] = pixel; + pixels[x - fragment->x] = pixel; } @@ -89,7 +89,11 @@ static inline int fb_fragment_put_pixel_checked(fb_fragment_t *fragment, int x, /* zero a fragment */ static inline void fb_fragment_zero(fb_fragment_t *fragment) { - memset(fragment->buf, 0, ((fragment->width << 2) + fragment->stride) * fragment->height); + void *buf = fragment->buf; + + /* TODO: there should be a fast-path for non-divided fragments where there's no stride to skip */ + for (int y = 0; y < fragment->height; y++, buf += fragment->pitch) + memset(buf, 0, fragment->pitch - fragment->stride); } #endif diff --git a/src/sdl_fb.c b/src/sdl_fb.c index 8d0241b..a3eb0d1 100644 --- a/src/sdl_fb.c +++ b/src/sdl_fb.c @@ -195,6 +195,7 @@ static void * sdl_fb_page_alloc(void *context, fb_page_t *res_page) res_page->fragment.height = c->height; res_page->fragment.frame_height = c->height; res_page->fragment.stride = p->surface->pitch - (c->width * 4); + res_page->fragment.pitch = p->surface->pitch; return p; } -- cgit v1.2.3