1
0
Fork 0
forked from len0rd/rockbox

LCD core move buf ptr and address look up function viewport struct

I'm currently running up against the limitations of the lcd_draw functions
I want these functions to be able to be used on any size buffer not
just buffers with a stride matching the underlying device

[DONE] allow the framebuffer to be decoupled from the device framebuffer
[DONE need examples] allow for some simple blit like transformations
[DONE] remove the device framebuffer from the plugin api
[DONE}ditto remote framebuffer
[DONE] remove _viewport_get_framebuffer you can call struct *vp = lcd_set_viewport(NULL) and vp->buffer->fb_ptr

while remote lcds may compile (and work in the sim) its not been tested on targets

[FIXED] backdrops need work to be screen agnostic

[FIXED] screen statusbar is not being combined into the main viewport correctly yet

[FIXED] screen elements are displayed incorrectly  after switch to void*

[FIXED] core didn't restore proper viewport on splash etc.

[NEEDS TESTING] remote lcd garbled data

[FIXED] osd lib garbled screen on bmp_part

[FIXED] grey_set_vp needs to return old viewport like lcd_set_viewport

[FIXED] Viewport update now handles viewports with differing buffers/strides by copying to the main buffer

[FIXED] splash on top of WPS leaves old framebuffer data (doesn't redraw)
[UPDATE] refined this a bit more to have clear_viewport set the clean bit and have skin_render do its own screen clear
scrolling viewports no longer trigger wps refresh
also fixed a bug where guisyncyesno was displaying and then disappearing

[ADDED!] New LCD macros that allow you to create properly size frame buffers in you desired size without wasting bytes
(LCD_ and LCD_REMOTE_)
LCD_STRIDE(w, h) same as STRIDE_MAIN
LCD_FBSTRIDE(w, h) returns target specific stride for a buffer W x H
LCD_NBELEMS(w, h) returns the number of fb_data sized elemenst needed for a buffer W x H
LCD_NATIVE_STRIDE(s) conversion between rockbox native vertical and lcd native stride (2bitH)
test_viewports.c has an example of usage

[FIXED!!] 2bit targets don't respect non-native strides
[FIXED] Few define snags

Change-Id: I0d04c3834e464eca84a5a715743a297a0cefd0af
This commit is contained in:
William Wilgus 2020-10-07 02:01:35 -04:00
parent 12f3ed1699
commit 3237ae4a4f
74 changed files with 1595 additions and 967 deletions

View file

@ -62,7 +62,7 @@ void grey_deferred_lcd_update(void);
/* Viewports and framebuffers */
void grey_clear_viewport(void);
void grey_set_viewport(struct viewport *vp);
struct viewport *grey_set_viewport(struct viewport *vp);
void grey_viewport_set_fullscreen(struct viewport *vp,
const enum screen_type screen);
void grey_viewport_set_pos(struct viewport *vp,

View file

@ -765,6 +765,11 @@ static const unsigned char colorindex[4] = {128, 85, 43, 0};
content (b&w and greyscale overlay) to an 8-bit BMP file. */
static void grey_screendump_hook(int fd)
{
fb_data *lcd_fb;
struct viewport *vp_main = rb->lcd_set_viewport(NULL);
rb->viewport_set_fullscreen(vp_main, SCREEN_MAIN);
lcd_fb = vp_main->buffer->fb_ptr;
int i;
int y, gx, gy;
#if LCD_PIXELFORMAT == VERTICAL_PACKING
@ -845,7 +850,7 @@ static void grey_screendump_hook(int fd)
gsrc = _grey_info.values + _GREY_MULUQ(_grey_info.width, gy);
#if LCD_DEPTH == 2
src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_FBWIDTH, y);
src = lcd_fb + _GREY_MULUQ(LCD_FBWIDTH, y);
do
{
@ -876,7 +881,7 @@ static void grey_screendump_hook(int fd)
#if LCD_DEPTH == 1
mask = BIT_N(y & 7);
src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 3);
src = lcd_fb + _GREY_MULUQ(LCD_WIDTH, y >> 3);
do
{
@ -908,7 +913,7 @@ static void grey_screendump_hook(int fd)
#elif LCD_DEPTH == 2
shift = 2 * (y & 3);
src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 2);
src = lcd_fb + _GREY_MULUQ(LCD_WIDTH, y >> 2);
do
{
@ -933,7 +938,7 @@ static void grey_screendump_hook(int fd)
#if LCD_DEPTH == 2
shift = y & 7;
src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 3);
src = lcd_fb + _GREY_MULUQ(LCD_WIDTH, y >> 3);
do
{

View file

@ -154,8 +154,9 @@ static void grey_update_clip_rect(void)
}
/* Set current grey viewport for draw routines */
void grey_set_viewport(struct viewport *vp)
struct viewport *grey_set_viewport(struct viewport *vp)
{
struct viewport *last_vp = _grey_info.vp;
if (vp == NULL)
vp = &_grey_default_vp;
@ -164,6 +165,7 @@ void grey_set_viewport(struct viewport *vp)
_grey_info.vp = vp;
grey_update_clip_rect();
}
return last_vp;
}
/* Set viewport to default settings */

View file

@ -52,6 +52,7 @@ struct osd
OSD_ERASED, /* Erased in preparation for regular drawing */
} status; /* View status */
struct viewport vp; /* Clipping viewport */
struct frame_buffer_t framebuf; /* Holds framebuffer reference */
int lcd_bitmap_stride; /* Stride of LCD bitmap */
void *lcd_bitmap_data; /* Backbuffer framebuffer data */
int back_bitmap_stride; /* Stride of backbuffer bitmap */
@ -68,7 +69,7 @@ struct osd
int height);
void (*lcd_update)(void);
void (*lcd_update_rect)(int x, int y, int width, int height);
void (*lcd_set_viewport)(struct viewport *vp);
struct viewport *(*lcd_set_viewport)(struct viewport *vp);
void (*lcd_set_framebuffer)(void *buf);
void (*lcd_framebuffer_set_pos)(int x, int y, int width, int height);
void (*lcd_bitmap_part)(const void *src, int src_x, int src_y,
@ -227,7 +228,8 @@ static void * _osd_lcd_init_buffers(struct osd *osd, unsigned flags,
osd->back_bitmap_stride = w;
#endif /* end stride type selection */
osd->lcd_bitmap_data = (void *)*rb->lcd_framebuffer;
/* vp is currently initialized to the default framebuffer */
osd->lcd_bitmap_data = osd->vp.buffer->data;
osd->back_bitmap_data = buf;
osd->maxwidth = w;
@ -686,6 +688,25 @@ static void _osd_lcd_update_rect(struct osd *osd,
osd->lcd_update_rect(x, y, width, height);
}
static void _osd_lcd_viewport_set_buffer(void *buffer)
{
if (buffer)
{
native_osd.framebuf.data = buffer;
native_osd.framebuf.elems = native_osd.maxheight * native_osd.maxwidth;
native_osd.framebuf.get_address_fn = NULL; /*Default iterator*/
if (buffer == native_osd.back_bitmap_data)
native_osd.framebuf.stride = (native_osd.back_bitmap_stride);
else
native_osd.framebuf.stride = (native_osd.lcd_bitmap_stride);
rb->viewport_set_buffer(NULL, &native_osd.framebuf, SCREEN_MAIN);
}
else
rb->viewport_set_buffer(NULL, NULL, SCREEN_MAIN);
}
/* Native LCD, public */
bool osd_init(unsigned flags, void *backbuf, size_t backbuf_size,
osd_draw_cb_fn_t draw_cb, int *width, int *height,
@ -696,7 +717,7 @@ bool osd_init(unsigned flags, void *backbuf, size_t backbuf_size,
native_osd.lcd_update = rb->lcd_update;
native_osd.lcd_update_rect = rb->lcd_update_rect;
native_osd.lcd_set_viewport = rb->lcd_set_viewport;
native_osd.lcd_set_framebuffer = (void *)rb->lcd_set_framebuffer;
native_osd.lcd_set_framebuffer = (void *)_osd_lcd_viewport_set_buffer;
#if LCD_DEPTH < 4
native_osd.lcd_framebuffer_set_pos = NULL;
#endif /* LCD_DEPTH < 4 */

View file

@ -34,6 +34,8 @@ void xlcd_fillcircle_screen(struct screen* display, int cx, int cy, int radius);
void xlcd_drawcircle(int cx, int cy, int radius);
void xlcd_drawcircle_screen(struct screen* display, int cx, int cy, int radius);
fb_data* get_framebuffer(struct viewport *vp, size_t *stride); /*CORE*/
#if LCD_DEPTH >= 8
void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height);

View file

@ -26,3 +26,12 @@
#include "xlcd.h"
fb_data* get_framebuffer(struct viewport *vp, size_t *stride)
{
struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
if (vp)
*vp = *vp_main;
if (stride)
*stride = vp_main->buffer->stride;
return vp_main->buffer->fb_ptr;
}

View file

@ -349,6 +349,9 @@ static const fb_data graylut[256] = {
void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height)
{
size_t dst_stride;
fb_data *lcd_fb = get_framebuffer(NULL, &dst_stride);
const unsigned char *src_end;
fb_data *dst;
@ -377,7 +380,7 @@ void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
src += stride * src_y + src_x; /* move starting point */
src_end = src + stride * height;
dst = *rb->lcd_framebuffer + LCD_WIDTH * y + x;
dst = lcd_fb + dst_stride * y + x;
do
{
@ -398,7 +401,7 @@ void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
#endif
src += stride;
dst += LCD_WIDTH;
dst += dst_stride;
}
while (src < src_end);
}
@ -416,6 +419,9 @@ void xlcd_gray_bitmap(const unsigned char *src, int x, int y, int width,
void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height)
{
size_t dst_stride;
fb_data *lcd_fb = get_framebuffer(NULL, &dst_stride);
const unsigned char *src_end;
fb_data *dst;
@ -444,7 +450,7 @@ void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y,
src += 3 * (stride * src_y + src_x); /* move starting point */
src_end = src + 3 * stride * height;
dst = *rb->lcd_framebuffer + LCD_WIDTH * y + x;
dst = lcd_fb + dst_stride * y + x;
do
{
@ -471,7 +477,7 @@ void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y,
while (src_row < row_end);
src += 3 * stride;
dst += LCD_WIDTH;
dst += dst_stride;
}
while (src < src_end);
}

View file

@ -33,6 +33,11 @@ static const unsigned short patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000};
#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
void xlcd_scroll_left(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
int length, oldmode;
if ((unsigned)count >= LCD_WIDTH)
@ -43,8 +48,7 @@ void xlcd_scroll_left(int count)
length = (LCD_WIDTH-count)*LCD_FBHEIGHT;
rb->memmove(*rb->lcd_framebuffer, *rb->lcd_framebuffer + LCD_HEIGHT*count,
length * sizeof(fb_data));
rb->memmove(lcd_fb, lcd_fb + LCD_HEIGHT*count, length * sizeof(fb_data));
oldmode = rb->lcd_get_drawmode();
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
@ -55,6 +59,11 @@ void xlcd_scroll_left(int count)
/* Scroll right */
void xlcd_scroll_right(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
int length, oldmode;
if ((unsigned)count >= LCD_WIDTH)
@ -65,8 +74,8 @@ void xlcd_scroll_right(int count)
length = (LCD_WIDTH-count)*LCD_FBHEIGHT;
rb->memmove(*rb->lcd_framebuffer + LCD_HEIGHT*count,
*rb->lcd_framebuffer, length * sizeof(fb_data));
rb->memmove(lcd_fb + LCD_HEIGHT*count,
lcd_fb, length * sizeof(fb_data));
oldmode = rb->lcd_get_drawmode();
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
@ -77,6 +86,11 @@ void xlcd_scroll_right(int count)
/* Scroll up */
void xlcd_scroll_up(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
int width, length, oldmode;
fb_data *data;
@ -90,7 +104,7 @@ void xlcd_scroll_up(int count)
length = LCD_HEIGHT - count;
width = LCD_WIDTH-1;
data = *rb->lcd_framebuffer;
data = lcd_fb;
do {
rb->memmove(data,data + count,length * sizeof(fb_data));
@ -106,6 +120,11 @@ void xlcd_scroll_up(int count)
/* Scroll down */
void xlcd_scroll_down(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
int width, length, oldmode;
fb_data *data;
@ -119,7 +138,7 @@ void xlcd_scroll_down(int count)
length = LCD_HEIGHT - count;
width = LCD_WIDTH-1;
data = *rb->lcd_framebuffer;
data = lcd_fb;
do {
rb->memmove(data + count, data, length * sizeof(fb_data));
@ -138,6 +157,11 @@ void xlcd_scroll_down(int count)
/* Scroll left */
void xlcd_scroll_left(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
int bitcount=0, oldmode;
int blockcount=0, blocklen;
@ -155,7 +179,7 @@ void xlcd_scroll_left(int count)
if (blockcount)
{
unsigned char *data = *rb->lcd_framebuffer;
unsigned char *data = lcd_fb;
unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT;
do
@ -168,7 +192,7 @@ void xlcd_scroll_left(int count)
if (bitcount)
{
int bx, y;
unsigned char *addr = *rb->lcd_framebuffer + blocklen;
unsigned char *addr = lcd_fb + blocklen;
#if LCD_DEPTH == 2
unsigned fill = (0x55 * (~rb->lcd_get_background() & 3)) << bitcount;
#endif
@ -196,6 +220,11 @@ void xlcd_scroll_left(int count)
/* Scroll right */
void xlcd_scroll_right(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
int bitcount=0, oldmode;
int blockcount=0, blocklen;
@ -213,7 +242,7 @@ void xlcd_scroll_right(int count)
if (blockcount)
{
unsigned char *data = *rb->lcd_framebuffer;
unsigned char *data = lcd_fb;
unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT;
do
@ -226,7 +255,7 @@ void xlcd_scroll_right(int count)
if (bitcount)
{
int bx, y;
unsigned char *addr = *rb->lcd_framebuffer + blockcount;
unsigned char *addr = lcd_fb + blockcount;
#if LCD_DEPTH == 2
unsigned fill = 0x55 * (~rb->lcd_get_background() & 3);
#endif
@ -256,6 +285,11 @@ void xlcd_scroll_right(int count)
/* Scroll left */
void xlcd_scroll_left(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
fb_data *data, *data_end;
int length, oldmode;
@ -265,7 +299,7 @@ void xlcd_scroll_left(int count)
return;
}
data = *rb->lcd_framebuffer;
data = lcd_fb;
data_end = data + LCD_WIDTH*LCD_FBHEIGHT;
length = LCD_WIDTH - count;
@ -285,6 +319,11 @@ void xlcd_scroll_left(int count)
/* Scroll right */
void xlcd_scroll_right(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
fb_data *data, *data_end;
int length, oldmode;
@ -294,7 +333,7 @@ void xlcd_scroll_right(int count)
return;
}
data = *rb->lcd_framebuffer;
data = lcd_fb;
data_end = data + LCD_WIDTH*LCD_FBHEIGHT;
length = LCD_WIDTH - count;
@ -318,6 +357,10 @@ void xlcd_scroll_right(int count)
/* Scroll up */
void xlcd_scroll_up(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
int length, oldmode;
if ((unsigned)count >= LCD_HEIGHT)
@ -328,8 +371,8 @@ void xlcd_scroll_up(int count)
length = LCD_HEIGHT - count;
rb->memmove(*rb->lcd_framebuffer,
*rb->lcd_framebuffer + count * LCD_FBWIDTH,
rb->memmove(lcd_fb,
lcd_fb + count * LCD_FBWIDTH,
length * LCD_FBWIDTH * sizeof(fb_data));
oldmode = rb->lcd_get_drawmode();
@ -341,6 +384,10 @@ void xlcd_scroll_up(int count)
/* Scroll down */
void xlcd_scroll_down(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
int length, oldmode;
if ((unsigned)count >= LCD_HEIGHT)
@ -351,8 +398,8 @@ void xlcd_scroll_down(int count)
length = LCD_HEIGHT - count;
rb->memmove(*rb->lcd_framebuffer + count * LCD_FBWIDTH,
*rb->lcd_framebuffer,
rb->memmove(lcd_fb + count * LCD_FBWIDTH,
lcd_fb,
length * LCD_FBWIDTH * sizeof(fb_data));
oldmode = rb->lcd_get_drawmode();
@ -367,6 +414,10 @@ void xlcd_scroll_down(int count)
/* Scroll up */
void xlcd_scroll_up(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
int bitcount=0, oldmode;
int blockcount=0, blocklen;
@ -388,8 +439,8 @@ void xlcd_scroll_up(int count)
if (blockcount)
{
rb->memmove(*rb->lcd_framebuffer,
*rb->lcd_framebuffer + blockcount * LCD_FBWIDTH,
rb->memmove(lcd_fb,
lcd_fb + blockcount * LCD_FBWIDTH,
blocklen * LCD_FBWIDTH * sizeof(fb_data));
}
if (bitcount)
@ -424,7 +475,7 @@ void xlcd_scroll_up(int count)
: /* inputs */
[wide]"r"(LCD_FBWIDTH),
[rows]"r"(blocklen),
[addr]"a"(*rb->lcd_framebuffer + blocklen * LCD_FBWIDTH),
[addr]"a"(lcd_fb + blocklen * LCD_FBWIDTH),
[cnt] "d"(bitcount),
[bkg] "d"(0x55 * (~rb->lcd_get_background() & 3))
: /* clobbers */
@ -432,7 +483,7 @@ void xlcd_scroll_up(int count)
);
#else /* C version */
int x, by;
unsigned char *addr = *rb->lcd_framebuffer + blocklen * LCD_FBWIDTH;
unsigned char *addr = lcd_fb + blocklen * LCD_FBWIDTH;
#if LCD_DEPTH == 2
unsigned fill = 0x55 * (~rb->lcd_get_background() & 3);
#else
@ -457,7 +508,7 @@ void xlcd_scroll_up(int count)
#if LCD_DEPTH == 2
int x, by;
fb_data *addr = *rb->lcd_framebuffer + blocklen * LCD_FBWIDTH;
fb_data *addr = lcd_fb + blocklen * LCD_FBWIDTH;
unsigned fill, mask;
fill = patterns[rb->lcd_get_background() & 3] << 8;
@ -491,6 +542,10 @@ void xlcd_scroll_up(int count)
/* Scroll up */
void xlcd_scroll_down(int count)
{
/*size_t dst_stride;*/
/*struct viewport *vp_main = NULL;*/
fb_data *lcd_fb = get_framebuffer(NULL, NULL);
int bitcount=0, oldmode;
int blockcount=0, blocklen;
@ -512,8 +567,8 @@ void xlcd_scroll_down(int count)
if (blockcount)
{
rb->memmove(*rb->lcd_framebuffer + blockcount * LCD_FBWIDTH,
*rb->lcd_framebuffer,
rb->memmove(lcd_fb + blockcount * LCD_FBWIDTH,
lcd_fb,
blocklen * LCD_FBWIDTH * sizeof(fb_data));
}
if (bitcount)
@ -548,7 +603,7 @@ void xlcd_scroll_down(int count)
: /* inputs */
[wide]"r"(LCD_WIDTH),
[rows]"r"(blocklen),
[addr]"a"(*rb->lcd_framebuffer + blockcount * LCD_FBWIDTH),
[addr]"a"(lcd_fb + blockcount * LCD_FBWIDTH),
[cnt] "d"(bitcount),
[bkg] "d"((0x55 * (~rb->lcd_get_background() & 3)) << bitcount)
: /* clobbers */
@ -556,7 +611,7 @@ void xlcd_scroll_down(int count)
);
#else /* C version */
int x, by;
unsigned char *addr = *rb->lcd_framebuffer + blockcount * LCD_FBWIDTH;
unsigned char *addr = lcd_fb + blockcount * LCD_FBWIDTH;
#if LCD_DEPTH == 2
unsigned fill = (0x55 * (~rb->lcd_get_background() & 3)) << bitcount;
#else
@ -581,7 +636,7 @@ void xlcd_scroll_down(int count)
#if LCD_DEPTH == 2
int x, by;
fb_data *addr = *rb->lcd_framebuffer + blockcount * LCD_FBWIDTH;
fb_data *addr = lcd_fb + blockcount * LCD_FBWIDTH;
unsigned fill, mask;
fill = patterns[rb->lcd_get_background() & 3] >> (8 - bitcount);