summaryrefslogtreecommitdiffstats
path: root/firmware/export/lcd.h
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2020-10-07 02:01:35 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2020-10-26 12:28:48 -0400
commit3237ae4a4ff9296a377ff9194a11038da161208f (patch)
treeaf4338c78467b9b0845d76c39da1fbe10f25e23e /firmware/export/lcd.h
parent12f3ed1699d6bef25bed90ba95cbcc1a6bb4934a (diff)
downloadrockbox-3237ae4a4ff9296a377ff9194a11038da161208f.tar.gz
rockbox-3237ae4a4ff9296a377ff9194a11038da161208f.zip
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
Diffstat (limited to 'firmware/export/lcd.h')
-rw-r--r--firmware/export/lcd.h271
1 files changed, 170 insertions, 101 deletions
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index ae06307dca..af734da913 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -23,30 +23,11 @@
#define __LCD_H__
#include <stdbool.h>
+#include <stddef.h>
#include "cpu.h"
#include "config.h"
#include "events.h"
-#define VP_FLAG_ALIGN_RIGHT 0x01
-#define VP_FLAG_ALIGN_CENTER 0x02
-
-#define VP_FLAG_ALIGNMENT_MASK \
- (VP_FLAG_ALIGN_RIGHT|VP_FLAG_ALIGN_CENTER)
-
-#define VP_IS_RTL(vp) (((vp)->flags & VP_FLAG_ALIGNMENT_MASK) == VP_FLAG_ALIGN_RIGHT)
-
-struct viewport {
- int x;
- int y;
- int width;
- int height;
- int flags;
- int font;
- int drawmode;
- /* needed for even for mono displays to support greylib */
- unsigned fg_pattern;
- unsigned bg_pattern;
-};
/* Frame buffer stride
*
@@ -101,7 +82,7 @@ enum screen_type {
struct scrollinfo;
-#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
+#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
#define STRIDE_MAIN(w, h) (h)
#else
#define STRIDE_MAIN(w, h) (w)
@@ -115,46 +96,105 @@ struct scrollinfo;
#if LCD_DEPTH <=8
#if (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) \
|| (LCD_PIXELFORMAT == HORIZONTAL_INTERLEAVED)
-typedef unsigned short fb_data;
+ typedef unsigned short fb_data;
#define FB_DATA_SZ 2
#else
-typedef unsigned char fb_data;
+ typedef unsigned char fb_data;
#define FB_DATA_SZ 1
#endif
#elif LCD_DEPTH <= 16
-typedef unsigned short fb_data;
+ typedef unsigned short fb_data;
#define FB_DATA_SZ 2
#elif LCD_DEPTH <= 24
-struct _fb_pixel {
- unsigned char b, g, r;
-};
-typedef struct _fb_pixel fb_data;
+ struct _fb_pixel {
+ unsigned char b, g, r;
+ };
+ typedef struct _fb_pixel fb_data;
#define FB_DATA_SZ 3
#else /* LCD_DEPTH > 24 */
#if (LCD_PIXELFORMAT == XRGB8888)
-struct _fb_pixel {
- unsigned char b, g, r, x;
-};
-typedef struct _fb_pixel fb_data;
+ struct _fb_pixel {
+ unsigned char b, g, r, x;
+ };
+ typedef struct _fb_pixel fb_data;
#else
-typedef unsigned long fb_data;
+ typedef unsigned long fb_data;
#endif
#define FB_DATA_SZ 4
#endif /* LCD_DEPTH */
+#ifdef HAVE_REMOTE_LCD
+#if LCD_REMOTE_DEPTH <= 8
+#if (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED) \
+ || (LCD_REMOTE_PIXELFORMAT == HORIZONTAL_INTERLEAVED)
+ typedef unsigned short fb_remote_data;
+#define FB_RDATA_SZ 2
+#else
+ typedef unsigned char fb_remote_data;
+#define FB_RDATA_SZ 1
+#endif
+#elif LCD_DEPTH <= 16
+ typedef unsigned short fb_remote_data;
+#define FB_RDATA_SZ 2
+#else
+ typedef unsigned long fb_remote_data;
+#define FB_RDATA_SZ 4
+#endif
+#endif
+
#if defined(HAVE_LCD_MODES)
-void lcd_set_mode(int mode);
+ void lcd_set_mode(int mode);
#define LCD_MODE_RGB565 0x00000001
#define LCD_MODE_YUV 0x00000002
#define LCD_MODE_PAL256 0x00000004
#if HAVE_LCD_MODES & LCD_MODE_PAL256
- void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
+ void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
int width, int height);
- void lcd_pal256_update_pal(fb_data *palette);
+ void lcd_pal256_update_pal(fb_data *palette);
#endif
#endif
+struct frame_buffer_t {
+ union
+ {
+ void *data;
+ char *ch_ptr;
+ fb_data *fb_ptr;
+#ifdef HAVE_REMOTE_LCD
+ fb_remote_data *fb_remote_ptr;
+#endif
+ };
+ void *(*get_address_fn)(int x, int y);
+ ptrdiff_t stride;
+ size_t elems;
+};
+
+#define VP_FLAG_ALIGN_RIGHT 0x01
+#define VP_FLAG_ALIGN_CENTER 0x02
+
+#define VP_FLAG_ALIGNMENT_MASK \
+ (VP_FLAG_ALIGN_RIGHT|VP_FLAG_ALIGN_CENTER)
+
+#define VP_IS_RTL(vp) (((vp)->flags & VP_FLAG_ALIGNMENT_MASK) == VP_FLAG_ALIGN_RIGHT)
+
+#define VP_FLAG_VP_DIRTY 0x4000
+#define VP_FLAG_CLEAR_FLAG 0x8000
+#define VP_FLAG_VP_SET_CLEAN (VP_FLAG_CLEAR_FLAG | VP_FLAG_VP_DIRTY)
+
+struct viewport {
+ int x;
+ int y;
+ int width;
+ int height;
+ int flags;
+ int font;
+ int drawmode;
+ struct frame_buffer_t *buffer;
+ /* needed for even for mono displays to support greylib */
+ unsigned fg_pattern;
+ unsigned bg_pattern;
+};
/* common functions */
extern void lcd_write_command(int byte);
@@ -171,7 +211,10 @@ extern int lcd_getwidth(void);
extern int lcd_getheight(void);
extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
-extern void lcd_set_viewport(struct viewport* vp);
+extern struct viewport* lcd_init_viewport(struct viewport* vp);
+extern struct viewport* lcd_set_viewport(struct viewport* vp);
+extern struct viewport* lcd_set_viewport_ex(struct viewport* vp, int flags);
+
extern void lcd_update(void);
extern void lcd_update_viewport(void);
extern void lcd_update_viewport_rect(int x, int y, int width, int height);
@@ -193,15 +236,15 @@ extern bool lcd_putsxy_scroll_func(int x, int y, const unsigned char *string,
#if defined(HAVE_LCD_COLOR)
#if MEMORYSIZE > 2
#define LCD_YUV_DITHER 0x1
-extern void lcd_yuv_set_options(unsigned options);
-extern void lcd_blit_yuv(unsigned char * const src[3],
+ extern void lcd_yuv_set_options(unsigned options);
+ extern void lcd_blit_yuv(unsigned char * const src[3],
int src_x, int src_y, int stride,
int x, int y, int width, int height);
#endif /* MEMORYSIZE > 2 */
#else
-extern void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
+ extern void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
int bheight, int stride);
-extern void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
+ extern void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
int bx, int by, int bwidth, int bheight,
int stride);
#endif
@@ -211,9 +254,9 @@ extern void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
extern void lcd_update_rect(int x, int y, int width, int height);
#ifdef HAVE_REMOTE_LCD
-extern void lcd_remote_update(void);
-/* update a fraction of the screen */
-extern void lcd_remote_update_rect(int x, int y, int width, int height);
+ extern void lcd_remote_update(void);
+ /* update a fraction of the screen */
+ extern void lcd_remote_update_rect(int x, int y, int width, int height);
#endif /* HAVE_REMOTE_LCD */
/* Bitmap formats */
@@ -239,13 +282,13 @@ enum
typedef void lcd_pixelfunc_type(int x, int y);
typedef void lcd_blockfunc_type(fb_data *address, unsigned mask, unsigned bits);
#if LCD_DEPTH >= 8
-typedef void lcd_fastpixelfunc_type(fb_data *address);
+ typedef void lcd_fastpixelfunc_type(fb_data *address);
#endif
#if defined(HAVE_LCD_COLOR) && defined(LCD_REMOTE_DEPTH) && \
LCD_REMOTE_DEPTH > 1
/* Just return color for screens use */
-static inline unsigned lcd_color_to_native(unsigned color)
+ static inline unsigned lcd_color_to_native(unsigned color)
{ return color; }
#define SCREEN_COLOR_TO_NATIVE(screen, color) (screen)->color_to_native(color)
#else
@@ -286,7 +329,7 @@ static inline unsigned lcd_color_to_native(unsigned color)
(((b) >> 3) << 8) )
/* swap color once - not currenly used in static inits */
#define _SWAPUNPACK(x, _unp_) \
- ({ typeof (x) _x_ = swap16(x); _unp_(_x_); })
+ ({ typeof (x) _x_ = swap16(x); _unp_(_x_); })
#define RGB_UNPACK_RED(x) _SWAPUNPACK((x), _RGB_UNPACK_RED)
#define RGB_UNPACK_GREEN(x) _SWAPUNPACK((x), _RGB_UNPACK_GREEN)
#define RGB_UNPACK_BLUE(x) _SWAPUNPACK((x), _RGB_UNPACK_BLUE)
@@ -374,16 +417,16 @@ static inline unsigned lcd_color_to_native(unsigned color)
* format, so it's the reverse of FB_SCALARPACK_LCD
*/
#if LCD_DEPTH >= 24
-static inline fb_data scalar_to_fb(unsigned p)
-{
- union { fb_data st; unsigned sc; } convert;
- convert.sc = p; return convert.st;
-}
-static inline unsigned fb_to_scalar(fb_data p)
-{
- union { fb_data st; unsigned sc; } convert;
- convert.st = p; return convert.sc;
-}
+ static inline fb_data scalar_to_fb(unsigned p)
+ {
+ union { fb_data st; unsigned sc; } convert;
+ convert.sc = p; return convert.st;
+ }
+ static inline unsigned fb_to_scalar(fb_data p)
+ {
+ union { fb_data st; unsigned sc; } convert;
+ convert.st = p; return convert.sc;
+ }
#define FB_RGBPACK(r_, g_, b_) ((fb_data){.r = r_, .g = g_, .b = b_})
#define FB_RGBPACK_LCD(r_, g_, b_) FB_RGBPACK(r_, g_, b_)
#define FB_UNPACK_RED(fb) ((fb).r)
@@ -411,17 +454,28 @@ static inline unsigned fb_to_scalar(fb_data p)
/* Frame buffer dimensions */
#if LCD_DEPTH == 1
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
-#define LCD_FBWIDTH ((LCD_WIDTH+7)/8)
+#define LCD_FBSTRIDE(w, h) ((w+7)/8)
+#define LCD_FBWIDTH LCD_FBSTRIDE(LCD_WIDTH, LCD_HEIGHT)
+#define LCD_NBELEMS(w, h) (((h*LCD_FBSTRIDE(w, h)) + w) / sizeof(fb_data))
#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
-#define LCD_FBHEIGHT ((LCD_HEIGHT+7)/8)
+#define LCD_FBSTRIDE(w, h) ((h+7)/8)
+#define LCD_FBHEIGHT LCD_FBSTRIDE(LCD_WIDTH, LCD_HEIGHT)
+#define LCD_NBELEMS(w, h) (((w*LCD_FBSTRIDE(w, h)) + h) / sizeof(fb_data))
#endif /* LCD_PIXELFORMAT */
#elif LCD_DEPTH == 2
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
-#define LCD_FBWIDTH ((LCD_WIDTH+3)/4)
+#define LCD_FBSTRIDE(w, h) ((w+3)>>2)
+#define LCD_NATIVE_STRIDE(s) LCD_FBSTRIDE(s, s)
+#define LCD_FBWIDTH LCD_FBSTRIDE(LCD_WIDTH, LCD_HEIGHT)
+#define LCD_NBELEMS(w, h) (((h*LCD_FBSTRIDE(w, h)) + w) / sizeof(fb_data))
#elif LCD_PIXELFORMAT == VERTICAL_PACKING
-#define LCD_FBHEIGHT ((LCD_HEIGHT+3)/4)
+#define LCD_FBSTRIDE(w, h) ((h+3)/4)
+#define LCD_FBHEIGHT LCD_FBSTRIDE(LCD_WIDTH, LCD_HEIGHT)
+#define LCD_NBELEMS(w, h) (((w*LCD_FBSTRIDE(w, h)) + h) / sizeof(fb_data))
#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
-#define LCD_FBHEIGHT ((LCD_HEIGHT+7)/8)
+#define LCD_FBSTRIDE(w, h) ((h+7)/8)
+#define LCD_FBHEIGHT LCD_FBSTRIDE(LCD_WIDTH, LCD_HEIGHT)
+#define LCD_NBELEMS(w, h) (((w*LCD_FBSTRIDE(w, h)) + h) / sizeof(fb_data))
#endif /* LCD_PIXELFORMAT */
#endif /* LCD_DEPTH */
/* Set defaults if not defined different yet. The defaults apply to both
@@ -432,13 +486,29 @@ static inline unsigned fb_to_scalar(fb_data p)
#ifndef LCD_FBHEIGHT
#define LCD_FBHEIGHT LCD_HEIGHT
#endif
-/* The actual framebuffer */
-extern fb_data *lcd_framebuffer;
+
+#ifndef LCD_NATIVE_STRIDE
+/* 2-bit Horz is the only display that actually defines this */
+#define LCD_NATIVE_STRIDE(s) (s)
+#endif
+
+#ifndef LCD_NBELEMS
#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
-#define FBADDR(x, y) (lcd_framebuffer + ((x) * LCD_FBHEIGHT) + (y))
+#define LCD_NBELEMS(w, h) ((w*STRIDE_MAIN(w, h)) + h)
#else
-#define FBADDR(x, y) (lcd_framebuffer + ((y) * LCD_FBWIDTH) + (x))
+#define LCD_NBELEMS(w, h) ((h*STRIDE_MAIN(w, h)) + w)
#endif
+#define LCD_FBSTRIDE(w, h) STRIDE_MAIN(w, h)
+#endif
+
+#ifndef LCD_STRIDE
+ #define LCD_STRIDE(w, h) STRIDE_MAIN(w, h)
+#endif
+
+extern struct viewport* lcd_current_viewport;
+
+#define FBADDR(x,y) ((fb_data*) lcd_current_viewport->buffer->get_address_fn(x, y))
+
#define FRAMEBUFFER_SIZE (sizeof(fb_data)*LCD_FBWIDTH*LCD_FBHEIGHT)
/** Port-specific functions. Enable in port config file. **/
@@ -499,7 +569,7 @@ struct bitmap {
extern void lcd_set_invert_display(bool yesno);
#ifdef HAVE_BACKLIGHT_INVERSION
-extern void lcd_set_backlight_inversion(bool yesno);
+ extern void lcd_set_backlight_inversion(bool yesno);
#endif /* HAVE_BACKLIGHT_INVERSION */
extern void lcd_set_flip(bool yesno);
@@ -510,13 +580,13 @@ extern int lcd_getfont(void);
/* low level drawing function pointer arrays */
#if LCD_DEPTH >= 8
-extern lcd_fastpixelfunc_type* const *lcd_fastpixelfuncs;
+ extern lcd_fastpixelfunc_type* const *lcd_fastpixelfuncs;
#elif LCD_DEPTH > 1
-extern lcd_pixelfunc_type* const *lcd_pixelfuncs;
-extern lcd_blockfunc_type* const *lcd_blockfuncs;
+ extern lcd_pixelfunc_type* const *lcd_pixelfuncs;
+ extern lcd_blockfunc_type* const *lcd_blockfuncs;
#else /* LCD_DEPTH == 1*/
-extern lcd_pixelfunc_type* const lcd_pixelfuncs[8];
-extern lcd_blockfunc_type* const lcd_blockfuncs[8];
+ extern lcd_pixelfunc_type* const lcd_pixelfuncs[8];
+ extern lcd_blockfunc_type* const lcd_blockfuncs[8];
#endif /* LCD_DEPTH */
extern void lcd_drawpixel(int x, int y);
@@ -526,45 +596,44 @@ extern void lcd_vline(int x, int y1, int y2);
extern void lcd_drawrect(int x, int y, int width, int height);
extern void lcd_fillrect(int x, int y, int width, int height);
extern void lcd_gradient_fillrect(int x, int y, int width, int height,
- unsigned start_rgb, unsigned end_rgb);
+ unsigned start_rgb, unsigned end_rgb);
extern void lcd_gradient_fillrect_part(int x, int y, int width, int height,
- unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip);
+ unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip);
extern void lcd_draw_border_viewport(void);
extern void lcd_fill_viewport(void);
extern void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
int stride, int x, int y, int width, int height);
extern void lcd_bitmap(const fb_data *src, int x, int y, int width,
int height);
-extern void lcd_set_framebuffer(fb_data *fb);
extern void lcd_scroll_step(int pixels);
#if LCD_DEPTH > 1
-extern void lcd_set_foreground(unsigned foreground);
-extern unsigned lcd_get_foreground(void);
-extern void lcd_set_background(unsigned background);
-extern unsigned lcd_get_background(void);
+ extern void lcd_set_foreground(unsigned foreground);
+ extern unsigned lcd_get_foreground(void);
+ extern void lcd_set_background(unsigned background);
+ extern unsigned lcd_get_background(void);
#ifdef HAVE_LCD_COLOR
-extern void lcd_set_selector_start(unsigned selector);
-extern void lcd_set_selector_end(unsigned selector);
-extern void lcd_set_selector_text(unsigned selector_text);
+ extern void lcd_set_selector_start(unsigned selector);
+ extern void lcd_set_selector_end(unsigned selector);
+ extern void lcd_set_selector_text(unsigned selector_text);
#endif
-extern void lcd_set_drawinfo(int mode, unsigned foreground,
- unsigned background);
-void lcd_set_backdrop(fb_data* backdrop);
-
-fb_data* lcd_get_backdrop(void);
-
-extern void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
- int stride, int x, int y, int width, int height);
-extern void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width,
- int height);
-extern void lcd_bitmap_transparent_part(const fb_data *src,
- int src_x, int src_y,
- int stride, int x, int y, int width,
- int height);
-extern void lcd_bitmap_transparent(const fb_data *src, int x, int y,
- int width, int height);
+ extern void lcd_set_drawinfo(int mode, unsigned foreground,
+ unsigned background);
+ void lcd_set_backdrop(fb_data* backdrop);
+
+ fb_data* lcd_get_backdrop(void);
+
+ extern void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
+ int stride, int x, int y, int width, int height);
+ extern void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width,
+ int height);
+ extern void lcd_bitmap_transparent_part(const fb_data *src,
+ int src_x, int src_y,
+ int stride, int x, int y, int width,
+ int height);
+ extern void lcd_bitmap_transparent(const fb_data *src, int x, int y,
+ int width, int height);
#else /* LCD_DEPTH == 1 */
#define lcd_mono_bitmap lcd_bitmap
#define lcd_mono_bitmap_part lcd_bitmap_part
@@ -577,10 +646,10 @@ extern void lcd_nine_segment_bmp(const struct bitmap* bm, int x, int y,
/* TODO: Impement this for remote displays if ever needed */
#if defined(LCD_DPI) && (LCD_DPI > 0)
-/* returns the pixel density of the display */
-static inline int lcd_get_dpi(void) { return LCD_DPI; }
+ /* returns the pixel density of the display */
+ static inline int lcd_get_dpi(void) { return LCD_DPI; }
#else
-extern int lcd_get_dpi(void);
+ extern int lcd_get_dpi(void);
#endif /* LCD_DPI */
#endif /* __LCD_H__ */