summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-16bit.c
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-11-28 10:05:45 +0000
committerJens Arnold <amiconn@rockbox.org>2005-11-28 10:05:45 +0000
commit1d6eeea1e196b6d7beefab70a6ee664340ab7bef (patch)
treeaf9accecfd30ea4fab25e56c11ec243922229ba1 /firmware/drivers/lcd-16bit.c
parentee76cc3716267720025bab498aa9b8a136f89218 (diff)
downloadrockbox-1d6eeea1e196b6d7beefab70a6ee664340ab7bef.tar.gz
rockbox-1d6eeea1e196b6d7beefab70a6ee664340ab7bef.zip
16bit LCD driver: faster drawing routines.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8098 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-16bit.c')
-rw-r--r--firmware/drivers/lcd-16bit.c123
1 files changed, 76 insertions, 47 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 7629c889e9..a4ae6cd553 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -145,32 +145,33 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h)
145 145
146/*** low-level drawing functions ***/ 146/*** low-level drawing functions ***/
147 147
148static void setpixel(int x, int y) ICODE_ATTR; 148#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)])
149static void setpixel(int x, int y) 149
150static void setpixel(fb_data *address) ICODE_ATTR;
151static void setpixel(fb_data *address)
150{ 152{
151 lcd_framebuffer[y][x] = fg_pattern; 153 *address = fg_pattern;
152} 154}
153 155
154static void clearpixel(int x, int y) ICODE_ATTR; 156static void clearpixel(fb_data *address) ICODE_ATTR;
155static void clearpixel(int x, int y) 157static void clearpixel(fb_data *address)
156{ 158{
157 lcd_framebuffer[y][x] = bg_pattern; 159 *address = bg_pattern;
158} 160}
159 161
160static void flippixel(int x, int y) ICODE_ATTR; 162static void flippixel(fb_data *address) ICODE_ATTR;
161static void flippixel(int x, int y) 163static void flippixel(fb_data *address)
162{ 164{
163 lcd_framebuffer[y][x] = ~lcd_framebuffer[y][x]; 165 *address = ~(*address);
164} 166}
165 167
166static void nopixel(int x, int y) ICODE_ATTR; 168static void nopixel(fb_data *address) ICODE_ATTR;
167static void nopixel(int x, int y) 169static void nopixel(fb_data *address)
168{ 170{
169 (void)x; 171 (void)address;
170 (void)y;
171} 172}
172 173
173lcd_pixelfunc_type* const lcd_pixelfuncs[8] = { 174lcd_fastpixelfunc_type* const lcd_fastpixelfuncs[8] = {
174 flippixel, nopixel, setpixel, setpixel, 175 flippixel, nopixel, setpixel, setpixel,
175 nopixel, clearpixel, nopixel, clearpixel 176 nopixel, clearpixel, nopixel, clearpixel
176}; 177};
@@ -181,7 +182,7 @@ lcd_pixelfunc_type* const lcd_pixelfuncs[8] = {
181void lcd_clear_display(void) 182void lcd_clear_display(void)
182{ 183{
183 fb_data bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern; 184 fb_data bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern;
184 fb_data *dst = &lcd_framebuffer[0][0]; 185 fb_data *dst = LCDADDR(0, 0);
185 fb_data *dst_end = dst + LCD_HEIGHT*LCD_WIDTH; 186 fb_data *dst_end = dst + LCD_HEIGHT*LCD_WIDTH;
186 187
187 do 188 do
@@ -194,7 +195,7 @@ void lcd_clear_display(void)
194void lcd_drawpixel(int x, int y) 195void lcd_drawpixel(int x, int y)
195{ 196{
196 if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) 197 if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
197 lcd_pixelfuncs[drawmode](x, y); 198 lcd_fastpixelfuncs[drawmode](LCDADDR(x, y));
198} 199}
199 200
200/* Draw a line */ 201/* Draw a line */
@@ -206,7 +207,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
206 int d, dinc1, dinc2; 207 int d, dinc1, dinc2;
207 int x, xinc1, xinc2; 208 int x, xinc1, xinc2;
208 int y, yinc1, yinc2; 209 int y, yinc1, yinc2;
209 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode]; 210 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
210 211
211 deltax = abs(x2 - x1); 212 deltax = abs(x2 - x1);
212 deltay = abs(y2 - y1); 213 deltay = abs(y2 - y1);
@@ -251,7 +252,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
251 for (i = 0; i < numpixels; i++) 252 for (i = 0; i < numpixels; i++)
252 { 253 {
253 if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) 254 if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
254 pfunc(x, y); 255 pfunc(LCDADDR(x, y));
255 256
256 if (d < 0) 257 if (d < 0)
257 { 258 {
@@ -272,7 +273,8 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
272void lcd_hline(int x1, int x2, int y) 273void lcd_hline(int x1, int x2, int y)
273{ 274{
274 int x; 275 int x;
275 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode]; 276 fb_data *dst, *dst_end;
277 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
276 278
277 /* direction flip */ 279 /* direction flip */
278 if (x2 < x1) 280 if (x2 < x1)
@@ -292,16 +294,20 @@ void lcd_hline(int x1, int x2, int y)
292 if (x2 >= LCD_WIDTH) 294 if (x2 >= LCD_WIDTH)
293 x2 = LCD_WIDTH-1; 295 x2 = LCD_WIDTH-1;
294 296
297 dst = LCDADDR(x1, y);
298 dst_end = dst + x2 - x1;
299
295 do 300 do
296 pfunc(x1++, y); 301 pfunc(dst++);
297 while (x1 <= x2); 302 while (dst <= dst_end);
298} 303}
299 304
300/* Draw a vertical line (optimised) */ 305/* Draw a vertical line (optimised) */
301void lcd_vline(int x, int y1, int y2) 306void lcd_vline(int x, int y1, int y2)
302{ 307{
303 int y; 308 int y;
304 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode]; 309 fb_data *dst, *dst_end;
310 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
305 311
306 /* direction flip */ 312 /* direction flip */
307 if (y2 < y1) 313 if (y2 < y1)
@@ -321,10 +327,15 @@ void lcd_vline(int x, int y1, int y2)
321 if (y2 >= LCD_HEIGHT) 327 if (y2 >= LCD_HEIGHT)
322 y2 = LCD_HEIGHT-1; 328 y2 = LCD_HEIGHT-1;
323 329
330 dst = LCDADDR(x, y1);
331 dst_end = dst + (y2 - y1) * LCD_WIDTH;
324 332
325 do 333 do
326 pfunc(x, y1++); 334 {
327 while (y1 <= y2); 335 pfunc(dst);
336 dst += LCD_WIDTH;
337 }
338 while (dst <= dst_end);
328} 339}
329 340
330/* Draw a rectangular box */ 341/* Draw a rectangular box */
@@ -345,8 +356,8 @@ void lcd_drawrect(int x, int y, int width, int height)
345/* Fill a rectangular area */ 356/* Fill a rectangular area */
346void lcd_fillrect(int x, int y, int width, int height) 357void lcd_fillrect(int x, int y, int width, int height)
347{ 358{
348 int xe, ye, xc; 359 fb_data *dst, *dst_end;
349 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode]; 360 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
350 361
351 /* nothing to draw? */ 362 /* nothing to draw? */
352 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 363 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
@@ -368,14 +379,22 @@ void lcd_fillrect(int x, int y, int width, int height)
368 width = LCD_WIDTH - x; 379 width = LCD_WIDTH - x;
369 if (y + height > LCD_HEIGHT) 380 if (y + height > LCD_HEIGHT)
370 height = LCD_HEIGHT - y; 381 height = LCD_HEIGHT - y;
382
383 dst = LCDADDR(x, y);
384 dst_end = dst + height * LCD_WIDTH;
371 385
372 ye = y + height; 386 do
373 xe = x + width;
374 for(; y < ye; y++)
375 { 387 {
376 for(xc = x; xc < xe; xc++) 388 fb_data *dst_row = dst;
377 pfunc(xc, y); 389 fb_data *row_end = dst_row + width;
390
391 do
392 pfunc(dst_row++);
393 while (dst_row < row_end);
394
395 dst += LCD_WIDTH;
378 } 396 }
397 while (dst < dst_end);
379} 398}
380 399
381/* About Rockbox' internal monochrome bitmap format: 400/* About Rockbox' internal monochrome bitmap format:
@@ -397,9 +416,10 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
397void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, 416void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
398 int stride, int x, int y, int width, int height) 417 int stride, int x, int y, int width, int height)
399{ 418{
400 int xe, ye, yc; 419 const unsigned char *src_end;
401 lcd_pixelfunc_type *fgfunc; 420 fb_data *dst, *dst_end;
402 lcd_pixelfunc_type *bgfunc; 421 lcd_fastpixelfunc_type *fgfunc;
422 lcd_fastpixelfunc_type *bgfunc;
403 423
404 /* nothing to draw? */ 424 /* nothing to draw? */
405 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 425 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
@@ -426,24 +446,28 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
426 446
427 src += stride * (src_y >> 3) + src_x; /* move starting point */ 447 src += stride * (src_y >> 3) + src_x; /* move starting point */
428 src_y &= 7; 448 src_y &= 7;
449 src_end = src + width;
429 450
430 xe = x + width; 451 dst = LCDADDR(x, y);
431 ye = y + height; 452 fgfunc = lcd_fastpixelfuncs[drawmode];
432 fgfunc = lcd_pixelfuncs[drawmode]; 453 bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID];
433 bgfunc = lcd_pixelfuncs[drawmode ^ DRMODE_INVERSEVID];
434 454
435 for (; x < xe; x++) 455 do
436 { 456 {
437 const unsigned char *src_col = src++; 457 const unsigned char *src_col = src++;
438 unsigned char data = *src_col >> src_y; 458 unsigned data = *src_col >> src_y;
459 fb_data *dst_col = dst++;
439 int numbits = 8 - src_y; 460 int numbits = 8 - src_y;
440 461
441 for (yc = y; yc < ye; yc++) 462 dst_end = dst_col + height * LCD_WIDTH;
463 do
442 { 464 {
443 if (data & 0x01) 465 if (data & 0x01)
444 fgfunc(x, yc); 466 fgfunc(dst_col);
445 else 467 else
446 bgfunc(x, yc); 468 bgfunc(dst_col);
469
470 dst_col += LCD_WIDTH;
447 471
448 data >>= 1; 472 data >>= 1;
449 if (--numbits == 0) 473 if (--numbits == 0)
@@ -453,7 +477,9 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
453 numbits = 8; 477 numbits = 8;
454 } 478 }
455 } 479 }
480 while (dst_col < dst_end);
456 } 481 }
482 while (src < src_end);
457} 483}
458 484
459/* Draw a full monochrome bitmap */ 485/* Draw a full monochrome bitmap */
@@ -469,7 +495,7 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
469void lcd_bitmap_part(const fb_data *src, int src_x, int src_y, 495void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
470 int stride, int x, int y, int width, int height) 496 int stride, int x, int y, int width, int height)
471{ 497{
472 int ye; 498 fb_data *dst, *dst_end;
473 499
474 /* nothing to draw? */ 500 /* nothing to draw? */
475 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 501 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
@@ -495,13 +521,16 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
495 height = LCD_HEIGHT - y; 521 height = LCD_HEIGHT - y;
496 522
497 src += stride * src_y + src_x; /* move starting point */ 523 src += stride * src_y + src_x; /* move starting point */
498 ye = y + height; 524 dst = LCDADDR(x, y);
525 dst_end = dst + height * LCD_WIDTH;
499 526
500 for (; y < ye; y++) 527 do
501 { 528 {
502 memcpy(&lcd_framebuffer[y][x], src, width * sizeof(fb_data)); 529 memcpy(dst, src, width * sizeof(fb_data));
503 src += stride; 530 src += stride;
531 dst += LCD_WIDTH;
504 } 532 }
533 while (dst < dst_end);
505} 534}
506 535
507/* Draw a full native bitmap */ 536/* Draw a full native bitmap */