diff options
author | William Wilgus <wilgus.william@gmail.com> | 2020-10-07 02:01:35 -0400 |
---|---|---|
committer | William Wilgus <wilgus.william@gmail.com> | 2020-10-26 12:28:48 -0400 |
commit | 3237ae4a4ff9296a377ff9194a11038da161208f (patch) | |
tree | af4338c78467b9b0845d76c39da1fbe10f25e23e /firmware/drivers/lcd-color-common.c | |
parent | 12f3ed1699d6bef25bed90ba95cbcc1a6bb4934a (diff) | |
download | rockbox-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/drivers/lcd-color-common.c')
-rw-r--r-- | firmware/drivers/lcd-color-common.c | 95 |
1 files changed, 61 insertions, 34 deletions
diff --git a/firmware/drivers/lcd-color-common.c b/firmware/drivers/lcd-color-common.c index c8bfd2d6b3..60e95a25ca 100644 --- a/firmware/drivers/lcd-color-common.c +++ b/firmware/drivers/lcd-color-common.c | |||
@@ -36,13 +36,23 @@ enum fill_opt { | |||
36 | }; | 36 | }; |
37 | 37 | ||
38 | /*** globals ***/ | 38 | /*** globals ***/ |
39 | fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] | 39 | static fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] |
40 | IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16); | 40 | IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16); |
41 | fb_data *lcd_framebuffer = &lcd_static_framebuffer[0][0]; | 41 | |
42 | static void *lcd_frameaddress_default(int x, int y); | ||
42 | 43 | ||
43 | static fb_data* lcd_backdrop = NULL; | 44 | static fb_data* lcd_backdrop = NULL; |
44 | static long lcd_backdrop_offset IDATA_ATTR = 0; | 45 | static long lcd_backdrop_offset IDATA_ATTR = 0; |
45 | 46 | ||
47 | /* shouldn't be changed unless you want system-wide framebuffer changes! */ | ||
48 | struct frame_buffer_t lcd_framebuffer_default = | ||
49 | { | ||
50 | .fb_ptr = &lcd_static_framebuffer[0][0], | ||
51 | .get_address_fn = &lcd_frameaddress_default, | ||
52 | .stride = STRIDE_MAIN(LCD_WIDTH, LCD_HEIGHT), | ||
53 | .elems = (LCD_FBWIDTH*LCD_FBHEIGHT), | ||
54 | }; | ||
55 | |||
46 | static struct viewport default_vp = | 56 | static struct viewport default_vp = |
47 | { | 57 | { |
48 | .x = 0, | 58 | .x = 0, |
@@ -51,15 +61,32 @@ static struct viewport default_vp = | |||
51 | .height = LCD_HEIGHT, | 61 | .height = LCD_HEIGHT, |
52 | .font = FONT_SYSFIXED, | 62 | .font = FONT_SYSFIXED, |
53 | .drawmode = DRMODE_SOLID, | 63 | .drawmode = DRMODE_SOLID, |
54 | .fg_pattern = LCD_DEFAULT_FG, | 64 | .buffer = NULL, |
55 | .bg_pattern = LCD_DEFAULT_BG, | 65 | .fg_pattern = LCD_DEFAULT_FG, |
66 | .bg_pattern = LCD_DEFAULT_BG, | ||
56 | }; | 67 | }; |
57 | 68 | ||
58 | static struct viewport* current_vp IDATA_ATTR = &default_vp; | 69 | struct viewport* lcd_current_viewport IDATA_ATTR; |
70 | |||
71 | static void *lcd_frameaddress_default(int x, int y) | ||
72 | { | ||
73 | /* the default expects a buffer the same size as the screen */ | ||
74 | struct frame_buffer_t *fb = lcd_current_viewport->buffer; | ||
75 | |||
76 | #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE | ||
77 | size_t element = (x * LCD_NATIVE_STRIDE(fb->stride)) + y; | ||
78 | #else | ||
79 | size_t element = (y * LCD_NATIVE_STRIDE(fb->stride)) + x; | ||
80 | #endif | ||
81 | return fb->fb_ptr + element;/*(element % fb->elems);*/ | ||
82 | } | ||
59 | 83 | ||
60 | /* LCD init */ | 84 | /* LCD init */ |
61 | void lcd_init(void) | 85 | void lcd_init(void) |
62 | { | 86 | { |
87 | /* Initialize the viewport */ | ||
88 | lcd_set_viewport(NULL); | ||
89 | |||
63 | lcd_clear_display(); | 90 | lcd_clear_display(); |
64 | 91 | ||
65 | /* Call device specific init */ | 92 | /* Call device specific init */ |
@@ -70,77 +97,77 @@ void lcd_init(void) | |||
70 | /* Clear the whole display */ | 97 | /* Clear the whole display */ |
71 | void lcd_clear_display(void) | 98 | void lcd_clear_display(void) |
72 | { | 99 | { |
73 | struct viewport* old_vp = current_vp; | 100 | struct viewport* old_vp = lcd_current_viewport; |
74 | 101 | ||
75 | current_vp = &default_vp; | 102 | lcd_current_viewport = &default_vp; |
76 | 103 | ||
77 | lcd_clear_viewport(); | 104 | lcd_clear_viewport(); |
78 | 105 | ||
79 | current_vp = old_vp; | 106 | lcd_current_viewport = old_vp; |
80 | } | 107 | } |
81 | 108 | ||
82 | /*** parameter handling ***/ | 109 | /*** parameter handling ***/ |
83 | 110 | ||
84 | void lcd_set_drawmode(int mode) | 111 | void lcd_set_drawmode(int mode) |
85 | { | 112 | { |
86 | current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); | 113 | lcd_current_viewport->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); |
87 | } | 114 | } |
88 | 115 | ||
89 | int lcd_get_drawmode(void) | 116 | int lcd_get_drawmode(void) |
90 | { | 117 | { |
91 | return current_vp->drawmode; | 118 | return lcd_current_viewport->drawmode; |
92 | } | 119 | } |
93 | 120 | ||
94 | void lcd_set_foreground(unsigned color) | 121 | void lcd_set_foreground(unsigned color) |
95 | { | 122 | { |
96 | current_vp->fg_pattern = color; | 123 | lcd_current_viewport->fg_pattern = color; |
97 | } | 124 | } |
98 | 125 | ||
99 | unsigned lcd_get_foreground(void) | 126 | unsigned lcd_get_foreground(void) |
100 | { | 127 | { |
101 | return current_vp->fg_pattern; | 128 | return lcd_current_viewport->fg_pattern; |
102 | } | 129 | } |
103 | 130 | ||
104 | void lcd_set_background(unsigned color) | 131 | void lcd_set_background(unsigned color) |
105 | { | 132 | { |
106 | current_vp->bg_pattern = color; | 133 | lcd_current_viewport->bg_pattern = color; |
107 | } | 134 | } |
108 | 135 | ||
109 | unsigned lcd_get_background(void) | 136 | unsigned lcd_get_background(void) |
110 | { | 137 | { |
111 | return current_vp->bg_pattern; | 138 | return lcd_current_viewport->bg_pattern; |
112 | } | 139 | } |
113 | 140 | ||
114 | void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color) | 141 | void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color) |
115 | { | 142 | { |
116 | lcd_set_drawmode(mode); | 143 | lcd_set_drawmode(mode); |
117 | current_vp->fg_pattern = fg_color; | 144 | lcd_current_viewport->fg_pattern = fg_color; |
118 | current_vp->bg_pattern = bg_color; | 145 | lcd_current_viewport->bg_pattern = bg_color; |
119 | } | 146 | } |
120 | 147 | ||
121 | int lcd_getwidth(void) | 148 | int lcd_getwidth(void) |
122 | { | 149 | { |
123 | return current_vp->width; | 150 | return lcd_current_viewport->width; |
124 | } | 151 | } |
125 | 152 | ||
126 | int lcd_getheight(void) | 153 | int lcd_getheight(void) |
127 | { | 154 | { |
128 | return current_vp->height; | 155 | return lcd_current_viewport->height; |
129 | } | 156 | } |
130 | 157 | ||
131 | void lcd_setfont(int newfont) | 158 | void lcd_setfont(int newfont) |
132 | { | 159 | { |
133 | current_vp->font = newfont; | 160 | lcd_current_viewport->font = newfont; |
134 | } | 161 | } |
135 | 162 | ||
136 | int lcd_getfont(void) | 163 | int lcd_getfont(void) |
137 | { | 164 | { |
138 | return current_vp->font; | 165 | return lcd_current_viewport->font; |
139 | } | 166 | } |
140 | 167 | ||
141 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) | 168 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) |
142 | { | 169 | { |
143 | return font_getstringsize(str, w, h, current_vp->font); | 170 | return font_getstringsize(str, w, h, lcd_current_viewport->font); |
144 | } | 171 | } |
145 | 172 | ||
146 | void lcd_set_backdrop(fb_data* backdrop) | 173 | void lcd_set_backdrop(fb_data* backdrop) |
@@ -148,7 +175,7 @@ void lcd_set_backdrop(fb_data* backdrop) | |||
148 | lcd_backdrop = backdrop; | 175 | lcd_backdrop = backdrop; |
149 | if (backdrop) | 176 | if (backdrop) |
150 | { | 177 | { |
151 | lcd_backdrop_offset = (intptr_t)backdrop - (intptr_t)lcd_framebuffer; | 178 | lcd_backdrop_offset = (intptr_t)backdrop - (intptr_t)FBADDR(0,0); |
152 | lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop; | 179 | lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop; |
153 | } | 180 | } |
154 | else | 181 | else |
@@ -166,14 +193,14 @@ fb_data* lcd_get_backdrop(void) | |||
166 | /* Set a single pixel */ | 193 | /* Set a single pixel */ |
167 | void lcd_drawpixel(int x, int y) | 194 | void lcd_drawpixel(int x, int y) |
168 | { | 195 | { |
169 | if ( ((unsigned)x < (unsigned)current_vp->width) | 196 | if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) |
170 | && ((unsigned)y < (unsigned)current_vp->height) | 197 | && ((unsigned)y < (unsigned)lcd_current_viewport->height) |
171 | #if defined(HAVE_VIEWPORT_CLIP) | 198 | #if defined(HAVE_VIEWPORT_CLIP) |
172 | && ((unsigned)x < (unsigned)LCD_WIDTH) | 199 | && ((unsigned)x < (unsigned)LCD_WIDTH) |
173 | && ((unsigned)y < (unsigned)LCD_HEIGHT) | 200 | && ((unsigned)y < (unsigned)LCD_HEIGHT) |
174 | #endif | 201 | #endif |
175 | ) | 202 | ) |
176 | lcd_fastpixelfuncs[current_vp->drawmode](FBADDR(current_vp->x+x, current_vp->y+y)); | 203 | lcd_fastpixelfuncs[lcd_current_viewport->drawmode](FBADDR(lcd_current_viewport->x+x, lcd_current_viewport->y+y)); |
177 | } | 204 | } |
178 | 205 | ||
179 | /* Draw a line */ | 206 | /* Draw a line */ |
@@ -185,7 +212,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
185 | int d, dinc1, dinc2; | 212 | int d, dinc1, dinc2; |
186 | int x, xinc1, xinc2; | 213 | int x, xinc1, xinc2; |
187 | int y, yinc1, yinc2; | 214 | int y, yinc1, yinc2; |
188 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; | 215 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; |
189 | 216 | ||
190 | deltay = abs(y2 - y1); | 217 | deltay = abs(y2 - y1); |
191 | if (deltay == 0) | 218 | if (deltay == 0) |
@@ -241,14 +268,14 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
241 | 268 | ||
242 | for (i = 0; i < numpixels; i++) | 269 | for (i = 0; i < numpixels; i++) |
243 | { | 270 | { |
244 | if ( ((unsigned)x < (unsigned)current_vp->width) | 271 | if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) |
245 | && ((unsigned)y < (unsigned)current_vp->height) | 272 | && ((unsigned)y < (unsigned)lcd_current_viewport->height) |
246 | #if defined(HAVE_VIEWPORT_CLIP) | 273 | #if defined(HAVE_VIEWPORT_CLIP) |
247 | && ((unsigned)x < (unsigned)LCD_WIDTH) | 274 | && ((unsigned)x < (unsigned)LCD_WIDTH) |
248 | && ((unsigned)y < (unsigned)LCD_HEIGHT) | 275 | && ((unsigned)y < (unsigned)LCD_HEIGHT) |
249 | #endif | 276 | #endif |
250 | ) | 277 | ) |
251 | pfunc(FBADDR(x + current_vp->x, y + current_vp->y)); | 278 | pfunc(FBADDR(x + lcd_current_viewport->x, y + lcd_current_viewport->y)); |
252 | 279 | ||
253 | if (d < 0) | 280 | if (d < 0) |
254 | { | 281 | { |
@@ -307,9 +334,9 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, | |||
307 | void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, | 334 | void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, |
308 | int x, int y, int width, int height) | 335 | int x, int y, int width, int height) |
309 | { | 336 | { |
310 | int bitmap_stride = STRIDE_MAIN(bm->width, bm->height); | 337 | int bitmap_stride = LCD_FBSTRIDE(bm->width, bm->height); |
311 | if (bm->format == FORMAT_MONO) | 338 | if (bm->format == FORMAT_MONO) |
312 | lcd_mono_bitmap_part(bm->data, src_x, src_y, bitmap_stride, x, y, width, height); | 339 | lcd_mono_bitmap_part(bm->data, src_x, src_y, bm->width, x, y, width, height); |
313 | else if (bm->alpha_offset > 0) | 340 | else if (bm->alpha_offset > 0) |
314 | lcd_alpha_bitmap_part_mix((fb_data*)bm->data, bm->data+bm->alpha_offset, | 341 | lcd_alpha_bitmap_part_mix((fb_data*)bm->data, bm->data+bm->alpha_offset, |
315 | src_x, src_y, x, y, width, height, | 342 | src_x, src_y, x, y, width, height, |
@@ -554,7 +581,7 @@ void lcd_blit_yuv(unsigned char * const src[3], | |||
554 | void lcd_gradient_fillrect_part(int x, int y, int width, int height, | 581 | void lcd_gradient_fillrect_part(int x, int y, int width, int height, |
555 | unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip) | 582 | unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip) |
556 | { | 583 | { |
557 | int old_pattern = current_vp->fg_pattern; | 584 | int old_pattern = lcd_current_viewport->fg_pattern; |
558 | int step_mul, i; | 585 | int step_mul, i; |
559 | int x1, x2; | 586 | int x1, x2; |
560 | x1 = x; | 587 | x1 = x; |
@@ -581,14 +608,14 @@ void lcd_gradient_fillrect_part(int x, int y, int width, int height, | |||
581 | } | 608 | } |
582 | 609 | ||
583 | for(i = y; i < y + height; i++) { | 610 | for(i = y; i < y + height; i++) { |
584 | current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); | 611 | lcd_current_viewport->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); |
585 | lcd_hline(x1, x2, i); | 612 | lcd_hline(x1, x2, i); |
586 | h_r -= rstep; | 613 | h_r -= rstep; |
587 | h_g -= gstep; | 614 | h_g -= gstep; |
588 | h_b -= bstep; | 615 | h_b -= bstep; |
589 | } | 616 | } |
590 | 617 | ||
591 | current_vp->fg_pattern = old_pattern; | 618 | lcd_current_viewport->fg_pattern = old_pattern; |
592 | } | 619 | } |
593 | 620 | ||
594 | /* Fill a rectangle with a gradient. The gradient's color will fade from | 621 | /* Fill a rectangle with a gradient. The gradient's color will fade from |