summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg White <gwhite@rockbox.org>2007-01-04 11:43:33 +0000
committerGreg White <gwhite@rockbox.org>2007-01-04 11:43:33 +0000
commit9d0faed29ce2293ce35ed8ba0dcba779b50f50a8 (patch)
treebcbb4cd78b863ded1d84bae94b7cccc81ddfe5be
parentdd7b75bd2c716f888b49ff50afc1f621157f394b (diff)
downloadrockbox-9d0faed29ce2293ce35ed8ba0dcba779b50f50a8.tar.gz
rockbox-9d0faed29ce2293ce35ed8ba0dcba779b50f50a8.zip
Use DMA for Blit to screen/clear
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11906 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/lcd-16bit.c68
-rw-r--r--firmware/export/lcd.h6
-rw-r--r--firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c294
3 files changed, 217 insertions, 151 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 6e5c31c0a5..949f80ffbc 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -33,6 +33,11 @@
33#include "font.h" 33#include "font.h"
34#include "rbunicode.h" 34#include "rbunicode.h"
35#include "bidi.h" 35#include "bidi.h"
36#if defined(TOSHIBA_GIGABEAT_F)
37#define NON_GB_STATIC
38#else
39#define NON_GB_STATIC static
40#endif
36 41
37#define SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32) 42#define SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32)
38 43
@@ -45,11 +50,12 @@ enum fill_opt {
45/*** globals ***/ 50/*** globals ***/
46fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH] IRAM_LCDFRAMEBUFFER __attribute__ ((aligned (16))); 51fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH] IRAM_LCDFRAMEBUFFER __attribute__ ((aligned (16)));
47 52
53
48static fb_data* lcd_backdrop = NULL; 54static fb_data* lcd_backdrop = NULL;
49static long lcd_backdrop_offset IDATA_ATTR = 0; 55static long lcd_backdrop_offset IDATA_ATTR = 0;
50 56
51static unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG; 57NON_GB_STATIC unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG;
52static unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG; 58NON_GB_STATIC unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG;
53static int drawmode = DRMODE_SOLID; 59static int drawmode = DRMODE_SOLID;
54static int xmargin = 0; 60static int xmargin = 0;
55static int ymargin = 0; 61static int ymargin = 0;
@@ -75,9 +81,12 @@ static const char scroll_tick_table[16] = {
75/* LCD init */ 81/* LCD init */
76void lcd_init(void) 82void lcd_init(void)
77{ 83{
78 lcd_clear_display(); 84 lcd_clear_display();
79 /* Call device specific init */ 85
80 lcd_init_device(); 86 /* Call device specific init */
87 lcd_init_device();
88
89
81 create_thread(scroll_thread, scroll_stack, 90 create_thread(scroll_thread, scroll_stack,
82 sizeof(scroll_stack), scroll_name 91 sizeof(scroll_stack), scroll_name
83 IF_PRIO(, PRIORITY_USER_INTERFACE)); 92 IF_PRIO(, PRIORITY_USER_INTERFACE));
@@ -95,20 +104,24 @@ int lcd_get_drawmode(void)
95 return drawmode; 104 return drawmode;
96} 105}
97 106
107#if !defined(TOSHIBA_GIGABEAT_F)
98void lcd_set_foreground(unsigned color) 108void lcd_set_foreground(unsigned color)
99{ 109{
100 fg_pattern = color; 110 fg_pattern = color;
101} 111}
112#endif
102 113
103unsigned lcd_get_foreground(void) 114unsigned lcd_get_foreground(void)
104{ 115{
105 return fg_pattern; 116 return fg_pattern;
106} 117}
107 118
119#if !defined(TOSHIBA_GIGABEAT_F)
108void lcd_set_background(unsigned color) 120void lcd_set_background(unsigned color)
109{ 121{
110 bg_pattern = color; 122 bg_pattern = color;
111} 123}
124#endif
112 125
113unsigned lcd_get_background(void) 126unsigned lcd_get_background(void)
114{ 127{
@@ -201,12 +214,13 @@ void lcd_set_backdrop(fb_data* backdrop)
201 { 214 {
202 lcd_backdrop_offset = (long)backdrop - (long)&lcd_framebuffer[0][0]; 215 lcd_backdrop_offset = (long)backdrop - (long)&lcd_framebuffer[0][0];
203 lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop; 216 lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop;
204 } 217 }
205 else 218 else
206 { 219 {
207 lcd_backdrop_offset = 0; 220 lcd_backdrop_offset = 0;
208 lcd_fastpixelfuncs = lcd_fastpixelfuncs_bgcolor; 221 lcd_fastpixelfuncs = lcd_fastpixelfuncs_bgcolor;
209 } 222 }
223 lcd_device_prepare_backdrop(backdrop);
210} 224}
211 225
212fb_data* lcd_get_backdrop(void) 226fb_data* lcd_get_backdrop(void)
@@ -217,10 +231,11 @@ fb_data* lcd_get_backdrop(void)
217/*** drawing functions ***/ 231/*** drawing functions ***/
218 232
219/* Clear the whole display */ 233/* Clear the whole display */
234#if !defined(TOSHIBA_GIGABEAT_F)
220void lcd_clear_display(void) 235void lcd_clear_display(void)
221{ 236{
222 fb_data *dst = LCDADDR(0, 0); 237 fb_data *dst = LCDADDR(0, 0);
223 238
224 if (drawmode & DRMODE_INVERSEVID) 239 if (drawmode & DRMODE_INVERSEVID)
225 { 240 {
226 memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT); 241 memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT);
@@ -234,6 +249,7 @@ void lcd_clear_display(void)
234 } 249 }
235 scrolling_lines = 0; 250 scrolling_lines = 0;
236} 251}
252#endif
237 253
238/* Set a single pixel */ 254/* Set a single pixel */
239void lcd_drawpixel(int x, int y) 255void lcd_drawpixel(int x, int y)
@@ -329,17 +345,17 @@ void lcd_hline(int x1, int x2, int y)
329 x1 = x2; 345 x1 = x2;
330 x2 = x; 346 x2 = x;
331 } 347 }
332 348
333 /* nothing to draw? */ 349 /* nothing to draw? */
334 if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) 350 if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0))
335 return; 351 return;
336 352
337 /* clipping */ 353 /* clipping */
338 if (x1 < 0) 354 if (x1 < 0)
339 x1 = 0; 355 x1 = 0;
340 if (x2 >= LCD_WIDTH) 356 if (x2 >= LCD_WIDTH)
341 x2 = LCD_WIDTH-1; 357 x2 = LCD_WIDTH-1;
342 358
343 if (drawmode & DRMODE_INVERSEVID) 359 if (drawmode & DRMODE_INVERSEVID)
344 { 360 {
345 if (drawmode & DRMODE_BG) 361 if (drawmode & DRMODE_BG)
@@ -363,7 +379,7 @@ void lcd_hline(int x1, int x2, int y)
363 } 379 }
364 dst = LCDADDR(x1, y); 380 dst = LCDADDR(x1, y);
365 width = x2 - x1 + 1; 381 width = x2 - x1 + 1;
366 382
367 switch (fillopt) 383 switch (fillopt)
368 { 384 {
369 case OPT_SET: 385 case OPT_SET:
@@ -401,14 +417,14 @@ void lcd_vline(int x, int y1, int y2)
401 417
402 /* nothing to draw? */ 418 /* nothing to draw? */
403 if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) 419 if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0))
404 return; 420 return;
405 421
406 /* clipping */ 422 /* clipping */
407 if (y1 < 0) 423 if (y1 < 0)
408 y1 = 0; 424 y1 = 0;
409 if (y2 >= LCD_HEIGHT) 425 if (y2 >= LCD_HEIGHT)
410 y2 = LCD_HEIGHT-1; 426 y2 = LCD_HEIGHT-1;
411 427
412 dst = LCDADDR(x, y1); 428 dst = LCDADDR(x, y1);
413 dst_end = dst + (y2 - y1) * LCD_WIDTH; 429 dst_end = dst + (y2 - y1) * LCD_WIDTH;
414 430
@@ -463,7 +479,7 @@ void lcd_fillrect(int x, int y, int width, int height)
463 width = LCD_WIDTH - x; 479 width = LCD_WIDTH - x;
464 if (y + height > LCD_HEIGHT) 480 if (y + height > LCD_HEIGHT)
465 height = LCD_HEIGHT - y; 481 height = LCD_HEIGHT - y;
466 482
467 if (drawmode & DRMODE_INVERSEVID) 483 if (drawmode & DRMODE_INVERSEVID)
468 { 484 {
469 if (drawmode & DRMODE_BG) 485 if (drawmode & DRMODE_BG)
@@ -544,7 +560,7 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
544 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 560 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
545 || (x + width <= 0) || (y + height <= 0)) 561 || (x + width <= 0) || (y + height <= 0))
546 return; 562 return;
547 563
548 /* clipping */ 564 /* clipping */
549 if (x < 0) 565 if (x < 0)
550 { 566 {
@@ -577,7 +593,7 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
577 unsigned data = *src_col >> src_y; 593 unsigned data = *src_col >> src_y;
578 fb_data *dst_col = dst++; 594 fb_data *dst_col = dst++;
579 int numbits = 8 - src_y; 595 int numbits = 8 - src_y;
580 596
581 dst_end = dst_col + height * LCD_WIDTH; 597 dst_end = dst_col + height * LCD_WIDTH;
582 do 598 do
583 { 599 {
@@ -620,7 +636,7 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
620 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 636 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
621 || (x + width <= 0) || (y + height <= 0)) 637 || (x + width <= 0) || (y + height <= 0))
622 return; 638 return;
623 639
624 /* clipping */ 640 /* clipping */
625 if (x < 0) 641 if (x < 0)
626 { 642 {
@@ -672,7 +688,7 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
672 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 688 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
673 || (x + width <= 0) || (y + height <= 0)) 689 || (x + width <= 0) || (y + height <= 0))
674 return; 690 return;
675 691
676 /* clipping */ 692 /* clipping */
677 if (x < 0) 693 if (x < 0)
678 { 694 {
@@ -742,7 +758,7 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
742 bits = font_get_bits(pf, ch); 758 bits = font_get_bits(pf, ch);
743 759
744 lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); 760 lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height);
745 761
746 x += width - ofs; 762 x += width - ofs;
747 ofs = 0; 763 ofs = 0;
748 } 764 }
@@ -850,8 +866,8 @@ void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style)
850void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, int offset) 866void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, int offset)
851{ 867{
852 lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset); 868 lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset);
853} 869}
854 870
855void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, 871void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
856 int style, int offset) 872 int style, int offset)
857{ 873{
@@ -963,7 +979,7 @@ static void scroll_thread(void)
963 } 979 }
964 980
965 lastmode = drawmode; 981 lastmode = drawmode;
966 drawmode = s->invert ? 982 drawmode = s->invert ?
967 (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; 983 (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
968 lcd_putsxyofs(xpos, ypos, s->offset, s->line); 984 lcd_putsxyofs(xpos, ypos, s->offset, s->line);
969 drawmode = lastmode; 985 drawmode = lastmode;
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 3e1ea4430b..fc0562419c 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -345,6 +345,12 @@ extern unsigned lcd_get_background(void);
345extern void lcd_set_drawinfo(int mode, unsigned foreground, 345extern void lcd_set_drawinfo(int mode, unsigned foreground,
346 unsigned background); 346 unsigned background);
347void lcd_set_backdrop(fb_data* backdrop); 347void lcd_set_backdrop(fb_data* backdrop);
348#if !defined(TOSHIBA_GIGABEAT_F)
349#define lcd_device_prepare_backdrop(x) ;
350#else
351void lcd_device_prepare_backdrop(fb_data* backdrop);
352#endif
353
348fb_data* lcd_get_backdrop(void); 354fb_data* lcd_get_backdrop(void);
349 355
350extern void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, 356extern void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
diff --git a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
index df5be43551..754ee6dec4 100644
--- a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
+++ b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
@@ -4,19 +4,42 @@
4#include "lcd.h" 4#include "lcd.h"
5#include "kernel.h" 5#include "kernel.h"
6#include "system.h" 6#include "system.h"
7 7#include "mmu-meg-fx.h"
8void lcd_init_device(void); 8#include <stdlib.h>
9void lcd_update_rec(int, int, int, int); 9#include "memory.h"
10void lcd_update(void); 10#include "lcd-target.h"
11 11
12bool usedmablit = false; 12/*
13** We prepare foreground and background fills ahead of time - DMA fills in 16 byte groups
14*/
15unsigned long fg_pattern_blit[4];
16unsigned long bg_pattern_blit[4];
17
18volatile bool use_dma_blit = false;
19volatile bool lcd_on = true;
20volatile bool lcd_poweroff = true;
21/*
22** These are imported from lcd-16bit.c
23*/
24extern unsigned fg_pattern;
25extern unsigned bg_pattern;
26
27extern volatile bool lcd_on;
13 28
14/* LCD init */ 29/* LCD init */
15void lcd_init_device(void) 30void lcd_init_device(void)
16{ 31{
32 memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2);
33 memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2);
34 clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit));
35 clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit));
36
17 /* Switch from 555I mode to 565 mode */ 37 /* Switch from 555I mode to 565 mode */
18 LCDCON5 |= 1 << 11; 38 LCDCON5 |= 1 << 11;
19 39
40#if !defined(BOOTLOADER)
41 use_dma_blit = true;
42#endif
20} 43}
21 44
22/* Update a fraction of the display. */ 45/* Update a fraction of the display. */
@@ -24,35 +47,159 @@ void lcd_update_rect(int x, int y, int width, int height)
24{ 47{
25 (void)x; 48 (void)x;
26 (void)width; 49 (void)width;
27 50 (void)y;
28 if (usedmablit) 51 (void)height;
52
53 if(!lcd_on)
54 {
55 yield();
56 return;
57 }
58 if (use_dma_blit)
29 { 59 {
30 /* Spin waiting for DMA to become available */ 60 /* Wait for this controller to stop pending transfer */
31 //while (DSTAT0 & (1<<20)) ; 61 while((DSTAT1 & 0x000fffff))
32 if (DSTAT0 & (1<<20)) return; 62 yield();
33 63
64 /* Flush DCache */
65 invalidate_dcache_range((void *)(((int) &lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH)), (height * sizeof(fb_data) * LCD_WIDTH));
66
34 /* set DMA dest */ 67 /* set DMA dest */
35 DIDST0 = (int) FRAME + y * sizeof(fb_data) * LCD_WIDTH; 68 DIDST1 = ((int) FRAME) + (y * sizeof(fb_data) * LCD_WIDTH);
36 69
37 /* FRAME on AHB buf, increment */ 70 /* FRAME on AHB buf, increment */
38 DIDSTC0 = 0; 71 DIDSTC1 = 0;
39 DCON0 = (((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((height * sizeof(fb_data) * LCD_WIDTH) >> 4)); 72 /* Handshake on AHB, Burst transfer, Whole service, Don't reload, transfer 32-bits */
73 DCON1 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((height * sizeof(fb_data) * LCD_WIDTH) >> 4);
40 74
41 /* set DMA source and options */ 75 /* set DMA source */
42 DISRC0 = (int) &lcd_framebuffer + (y * sizeof(fb_data) * LCD_WIDTH) + 0x30000000; 76 DISRC1 = ((int) &lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH) + 0x30000000;
43 DISRCC0 = 0x00; /* memory is on AHB bus, increment addresses */ 77 /* memory is on AHB bus, increment addresses */
78 DISRCC1 = 0x00;
44 79
45 /* Activate the channel */ 80 /* Activate the channel */
46 DMASKTRIG0 = 0x2; 81 DMASKTRIG1 = 0x2;
82
47 /* Start DMA */ 83 /* Start DMA */
48 DMASKTRIG0 |= 0x1; 84 DMASKTRIG1 |= 0x1;
85
86 /* Wait for transfer to complete */
87 while((DSTAT1 & 0x000fffff))
88 yield();
89 }
90 else
91 memcpy(((char*)FRAME) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH)));
92}
93
94
95void lcd_enable(bool state)
96{
97 if(state) {
98 if(lcd_poweroff) {
99 if(!lcd_on)
100 memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2);
101 lcd_on = true;
102 LCDCON1 |= 1;
103 }
104 }
105 else {
106 if(lcd_poweroff) {
107 lcd_on = false;
108 LCDCON1 &= ~1;
109 }
110 }
111}
112
113void lcd_set_foreground(unsigned color)
114{
115 fg_pattern = color;
116
117 memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2);
118 clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit));
119}
120
121void lcd_set_background(unsigned color)
122{
123 bg_pattern = color;
124 memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2);
125 clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit));
126}
127
128void lcd_device_prepare_backdrop(fb_data* backdrop)
129{
130 clean_dcache_range((void *)backdrop, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH));
131}
132
133void lcd_clear_display_dma(void)
134{
135 void *src;
136 bool inc = false;
137
138 if (lcd_get_drawmode() & DRMODE_INVERSEVID)
139 src = fg_pattern_blit;
140 else
141 {
142 fb_data* lcd_backdrop = lcd_get_backdrop();
143
144 if (!lcd_backdrop)
145 src = bg_pattern_blit;
146 else
147 {
148 src = lcd_backdrop;
149 inc = true;
150 }
151 }
152 /* Wait for any pending transfer to complete */
153 while((DSTAT3 & 0x000fffff))
154 yield();
155 DMASKTRIG3 |= 0x4; /* Stop controller */
156 DIDST3 = ((int) lcd_framebuffer) + 0x30000000; /* set DMA dest, physical address */
157 DIDSTC3 = 0; /* Dest on AHB, increment */
158
159 DISRC3 = ((int) src) + 0x30000000; /* Set source, in physical space */
160 DISRCC3 = inc ? 0x00 : 0x01; /* memory is on AHB bus, increment addresses based on backdrop */
161
162 /* Handshake on AHB, Burst mode, whole service mode, no reload, move 32-bits */
163 DCON3 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH) >> 4);
164
165 /* Dump DCache for dest, we are about to overwrite it with DMA */
166 dump_dcache_range((void *)lcd_framebuffer, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH));
167 /* Activate the channel */
168 DMASKTRIG3 = 2;
169 /* Start DMA */
170 DMASKTRIG3 |= 1;
171
172 /* Wait for transfer to complete */
173 while((DSTAT3 & 0x000fffff))
174 yield();
175}
176
177void lcd_clear_display(void)
178{
179 if(use_dma_blit)
180 {
181 lcd_clear_display_dma();
182 return;
183 }
184
185 fb_data *dst = &lcd_framebuffer[0][0];
186
187 if (lcd_get_drawmode() & DRMODE_INVERSEVID)
188 {
189 memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT);
49 } 190 }
50 else 191 else
51 { 192 {
52 memcpy((void*)FRAME, &lcd_framebuffer, sizeof(lcd_framebuffer)); 193 fb_data* lcd_backdrop = lcd_get_backdrop();
194 if (!lcd_backdrop)
195 memset16(dst, bg_pattern, LCD_WIDTH*LCD_HEIGHT);
196 else
197 memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer));
53 } 198 }
199 lcd_stop_scroll();
54} 200}
55 201
202
56/* Update the display. 203/* Update the display.
57 This must be called after all other LCD functions that change the display. */ 204 This must be called after all other LCD functions that change the display. */
58void lcd_update(void) 205void lcd_update(void)
@@ -164,7 +311,6 @@ void lcd_yuv_blit(unsigned char * const src[3],
164} 311}
165 312
166 313
167
168void lcd_set_contrast(int val) { 314void lcd_set_contrast(int val) {
169 (void) val; 315 (void) val;
170 // TODO: 316 // TODO:
@@ -192,105 +338,3 @@ void lcd_set_flip(bool yesno) {
192 // TODO: 338 // TODO:
193} 339}
194 340
195
196
197
198
199
200
201
202
203
204
205
206
207#if 0
208/* Performance function to blit a YUV bitmap directly to the LCD */
209void lcd_yuv_blit(unsigned char * const src[3],
210 int src_x, int src_y, int stride,
211 int x, int y, int width, int height)
212{
213 fb_data *dst, *dst_end;
214
215 width = (width + 1) & ~1;
216
217 dst = (fb_data*)FRAME + LCD_WIDTH * y + x;
218 dst_end = dst + LCD_WIDTH * height;
219
220 do
221 {
222 fb_data *dst_row = dst;
223 fb_data *row_end = dst_row + width;
224 const unsigned char *ysrc = src[0] + stride * src_y + src_x;
225 int y, u, v;
226 int red, green, blue;
227 unsigned rbits, gbits, bbits;
228
229 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
230 const unsigned char *usrc = src[1] + (stride/CSUB_X) * (src_y/CSUB_Y)
231 + (src_x/CSUB_X);
232 const unsigned char *vsrc = src[2] + (stride/CSUB_X) * (src_y/CSUB_Y)
233 + (src_x/CSUB_X);
234 int xphase = src_x % CSUB_X;
235 int rc, gc, bc;
236
237 u = *usrc++ - 128;
238 v = *vsrc++ - 128;
239 rc = RVFAC * v + ROUNDOFFS;
240 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
241 bc = BUFAC * u + ROUNDOFFS;
242
243 do
244 {
245 y = *ysrc++;
246 red = RYFAC * y + rc;
247 green = GYFAC * y + gc;
248 blue = BYFAC * y + bc;
249
250 if ((unsigned)red > (RYFAC*255+ROUNDOFFS))
251 {
252 if (red < 0)
253 red = 0;
254 else
255 red = (RYFAC*255+ROUNDOFFS);
256 }
257 if ((unsigned)green > (GYFAC*255+ROUNDOFFS))
258 {
259 if (green < 0)
260 green = 0;
261 else
262 green = (GYFAC*255+ROUNDOFFS);
263 }
264 if ((unsigned)blue > (BYFAC*255+ROUNDOFFS))
265 {
266 if (blue < 0)
267 blue = 0;
268 else
269 blue = (BYFAC*255+ROUNDOFFS);
270 }
271 rbits = ((unsigned)red) >> 16 ;
272 gbits = ((unsigned)green) >> 16 ;
273 bbits = ((unsigned)blue) >> 16 ;
274 *dst_row++ = (rbits << 11) | (gbits << 5) | bbits;
275
276 if (++xphase >= CSUB_X)
277 {
278 u = *usrc++ - 128;
279 v = *vsrc++ - 128;
280 rc = RVFAC * v + ROUNDOFFS;
281 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
282 bc = BUFAC * u + ROUNDOFFS;
283 xphase = 0;
284 }
285 }
286 while (dst_row < row_end);
287
288 src_y++;
289 dst += LCD_WIDTH;
290 }
291 while (dst < dst_end);
292}
293#endif
294
295
296