Changeset ab1861a in mainline
- Timestamp:
- 2009-04-22T17:11:06Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 566f4cfb
- Parents:
- a1a83e5e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fb/fb.c
ra1a83e5e rab1861a 31 31 /** 32 32 * @defgroup fb Graphical framebuffer 33 * @brief 33 * @brief HelenOS graphical framebuffer. 34 34 * @ingroup fbs 35 35 * @{ … … 69 69 #define DEFAULT_FGCOLOR 0x000000 70 70 71 #define GLYPH_UNAVAIL 71 #define GLYPH_UNAVAIL '?' 72 72 73 73 #define MAX_ANIM_LEN 8 … … 79 79 typedef void (*rgb_conv_t)(void *, uint32_t); 80 80 81 /** Function to render a bit mask. */ 82 typedef void (*mask_conv_t)(void *, bool); 83 81 84 /** Function to draw a glyph. */ 82 85 typedef void (*dg_t)(unsigned int x, unsigned int y, bool cursor, … … 94 97 unsigned int pixelbytes; 95 98 unsigned int glyphbytes; 96 99 97 100 /** Pre-rendered mask for rendering glyphs. Specific for the visual. */ 98 101 uint8_t *glyphs; 99 102 100 103 rgb_conv_t rgb_conv; 104 mask_conv_t mask_conv; 101 105 } screen; 102 106 … … 122 126 * Style and glyphs for text printing 123 127 */ 124 128 125 129 /** Current attributes. */ 126 130 attr_rgb_t attr; 127 131 128 132 uint8_t *bgpixel; 129 133 130 134 /** 131 135 * Glyph drawing function for this viewport. Different viewports … … 171 175 172 176 static uint32_t color_table[16] = { 173 [COLOR_BLACK] 174 [COLOR_BLUE] 175 [COLOR_GREEN] 176 [COLOR_CYAN] 177 [COLOR_RED] 178 [COLOR_MAGENTA] 179 [COLOR_YELLOW] 180 [COLOR_WHITE] 181 182 [8 + COLOR_BLACK] 183 [8 + COLOR_BLUE] 184 [8 + COLOR_GREEN] 185 [8 + COLOR_CYAN] 186 [8 + COLOR_RED] 187 [8 + COLOR_MAGENTA] 188 [8 + COLOR_YELLOW] 189 [8 + COLOR_WHITE] 177 [COLOR_BLACK] = 0x000000, 178 [COLOR_BLUE] = 0x0000f0, 179 [COLOR_GREEN] = 0x00f000, 180 [COLOR_CYAN] = 0x00f0f0, 181 [COLOR_RED] = 0xf00000, 182 [COLOR_MAGENTA] = 0xf000f0, 183 [COLOR_YELLOW] = 0xf0f000, 184 [COLOR_WHITE] = 0xf0f0f0, 185 186 [8 + COLOR_BLACK] = 0x000000, 187 [8 + COLOR_BLUE] = 0x0000ff, 188 [8 + COLOR_GREEN] = 0x00ff00, 189 [8 + COLOR_CYAN] = 0x00ffff, 190 [8 + COLOR_RED] = 0xff0000, 191 [8 + COLOR_MAGENTA] = 0xff00ff, 192 [8 + COLOR_YELLOW] = 0xffff00, 193 [8 + COLOR_WHITE] = 0xffffff, 190 194 }; 191 195 … … 227 231 static void rgb_0888(void *dst, uint32_t rgb) 228 232 { 229 *((uint32_t *) dst) = rgb & 0xffffff; 233 *((uint32_t *) dst) = rgb & 0x00ffffff; 234 } 235 236 static void mask_0888(void *dst, bool mask) 237 { 238 *((uint32_t *) dst) = (mask ? 0x00ffffff : 0); 230 239 } 231 240 … … 251 260 } 252 261 262 static void mask_888(void *dst, bool mask) 263 { 264 if (mask) { 265 ((uint8_t *) dst)[0] = 0xff; 266 ((uint8_t *) dst)[1] = 0xff; 267 ((uint8_t *) dst)[2] = 0xff; 268 } else { 269 ((uint8_t *) dst)[0] = 0; 270 ((uint8_t *) dst)[1] = 0; 271 ((uint8_t *) dst)[2] = 0; 272 } 273 } 274 253 275 254 276 /** BGR 8:8:8 conversion … … 272 294 } 273 295 296 static void mask_555(void *dst, bool mask) 297 { 298 *((uint16_t *) dst) = (mask ? 0x7fff : 0); 299 } 300 274 301 275 302 /** RGB 5:6:5 conversion … … 282 309 } 283 310 311 static void mask_565(void *dst, bool mask) 312 { 313 *((uint16_t *) dst) = (mask ? 0xffff : 0); 314 } 315 284 316 285 317 /** RGB 3:2:3 … … 292 324 } 293 325 326 static void mask_323(void *dst, bool mask) 327 { 328 *((uint8_t *) dst) = (mask ? 0xff : 0); 329 } 330 294 331 /** Draw a filled rectangle. 295 332 * 296 333 * @note Need real implementation that does not access VRAM twice. 334 * 297 335 */ 298 336 static void draw_filled_rect(unsigned int x0, unsigned int y0, unsigned int x1, 299 337 unsigned int y1, uint32_t color) 300 338 { 301 unsigned int x, y; 339 unsigned int x; 340 unsigned int y; 302 341 unsigned int copy_bytes; 303 304 uint8_t *sp, *dp; 342 343 uint8_t *sp; 344 uint8_t *dp; 305 345 uint8_t cbuf[4]; 306 307 if (y0 >= y1 || x0 >= x1) return; 346 347 if ((y0 >= y1) || (x0 >= x1)) 348 return; 349 308 350 screen.rgb_conv(cbuf, color); 309 351 310 352 sp = &screen.fb_addr[FB_POS(x0, y0)]; 311 353 dp = sp; 312 354 313 355 /* Draw the first line. */ 314 356 for (x = x0; x < x1; x++) { … … 316 358 dp += screen.pixelbytes; 317 359 } 318 360 319 361 dp = sp + screen.scanline; 320 362 copy_bytes = (x1 - x0) * screen.pixelbytes; 321 363 322 364 /* Draw the remaining lines by copying. */ 323 365 for (y = y0 + 1; y < y1; y++) { … … 334 376 static void vport_redraw(viewport_t *vport) 335 377 { 336 unsigned int row, col; 337 378 unsigned int row; 379 unsigned int col; 380 338 381 for (row = 0; row < vport->rows; row++) { 339 382 for (col = 0; col < vport->cols; col++) { … … 341 384 } 342 385 } 343 386 344 387 if (COL2X(vport->cols) < vport->width) { 345 388 draw_filled_rect( … … 348 391 vport->attr.bg_color); 349 392 } 350 393 351 394 if (ROW2Y(vport->rows) < vport->height) { 352 395 draw_filled_rect( … … 360 403 uint32_t bg_color) 361 404 { 362 unsignedi;363 405 size_t i; 406 364 407 for (i = 0; i < len; i++) { 365 408 backbuf[i].glyph = 0; … … 389 432 static void vport_scroll(viewport_t *vport, int lines) 390 433 { 391 unsigned int row, col; 392 unsigned int x, y; 434 unsigned int row; 435 unsigned int col; 436 unsigned int x; 437 unsigned int y; 393 438 uint32_t glyph; 394 439 uint32_t fg_color; 395 440 uint32_t bg_color; 396 bb_cell_t *bbp, *xbp; 397 441 bb_cell_t *bbp; 442 bb_cell_t *xbp; 443 398 444 /* 399 445 * Redraw. 400 446 */ 401 447 402 448 y = vport->y; 403 449 for (row = 0; row < vport->rows; row++) { … … 407 453 xbp = &vport->backbuf[BB_POS(vport, col, row + lines)]; 408 454 bbp = &vport->backbuf[BB_POS(vport, col, row)]; 409 455 410 456 glyph = xbp->glyph; 411 457 fg_color = xbp->fg_color; 412 458 bg_color = xbp->bg_color; 413 414 if ( bbp->glyph == glyph &&415 bbp->fg_color == xbp->fg_color &&416 bbp->bg_color == xbp->bg_color) {459 460 if ((bbp->glyph == glyph) 461 && (bbp->fg_color == xbp->fg_color) 462 && (bbp->bg_color == xbp->bg_color)) { 417 463 x += FONT_WIDTH; 418 464 continue; … … 423 469 bg_color = vport->attr.bg_color; 424 470 } 425 471 426 472 (*vport->dglyph)(x, y, false, screen.glyphs, glyph, 427 473 fg_color, bg_color); … … 430 476 y += FONT_SCANLINES; 431 477 } 432 478 433 479 /* 434 480 * Scroll backbuffer. 435 481 */ 436 482 437 483 if (lines > 0) { 438 484 memmove(vport->backbuf, vport->backbuf + vport->cols * lines, … … 452 498 * Convert glyphs from device independent font 453 499 * description to current visual representation. 500 * 454 501 */ 455 502 static void render_glyphs(void) 456 503 { 457 504 unsigned int glyph; 458 505 459 506 for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { 460 507 unsigned int y; 461 508 462 509 for (y = 0; y < FONT_SCANLINES; y++) { 463 510 unsigned int x; 464 511 465 512 for (x = 0; x < FONT_WIDTH; x++) { 466 screen.rgb_conv(&screen.glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes], 467 (fb_font[glyph][y] & (1 << (7 - x))) 468 ? 0xffffff : 0x000000); 469 470 screen.rgb_conv(&screen.glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes], 471 (fb_font[glyph][y] & (1 << (7 - x))) 472 ? 0x000000 : 0xffffff); 513 screen.mask_conv(&screen.glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes], 514 (fb_font[glyph][y] & (1 << (7 - x))) ? 1 : 0); 515 516 screen.mask_conv(&screen.glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes], 517 (fb_font[glyph][y] & (1 << (7 - x))) ? 1 : 0); 473 518 } 474 519 } 475 520 } 476 521 } 477 478 522 479 523 /** Create new viewport … … 496 540 break; 497 541 } 542 498 543 if (i == MAX_VIEWPORTS) 499 544 return ELIMIT; … … 513 558 return ENOMEM; 514 559 } 515 560 516 561 backbuf_clear(backbuf, cols * rows, DEFAULT_FGCOLOR, DEFAULT_BGCOLOR); 517 562 memset(bgpixel, 0, screen.pixelbytes); … … 529 574 530 575 viewports[i].bgpixel = bgpixel; 531 576 532 577 /* 533 * Conditions necessary to select aligned version: 578 * Conditions necessary to select aligned version: 579 * - word size is divisible by pixelbytes 580 * - cell scanline size is divisible by word size 581 * - cell scanlines are word-aligned 534 582 * 535 * - word size is divisible by pixelbytes536 * - cell scanline size is divisible by word size537 * - cell scanlines are word-aligned538 583 */ 539 if ((word_size % screen.pixelbytes) == 0 && 540 (FONT_WIDTH * screen.pixelbytes) % word_size == 0 && 541 (x * screen.pixelbytes) % word_size == 0 && 542 screen.scanline % word_size == 0) { 543 584 if (((word_size % screen.pixelbytes) == 0) 585 && ((FONT_WIDTH * screen.pixelbytes) % word_size == 0) 586 && ((x * screen.pixelbytes) % word_size == 0) 587 && (screen.scanline % word_size == 0)) { 544 588 viewports[i].dglyph = draw_glyph_aligned; 545 589 } else { 546 590 viewports[i].dglyph = draw_glyph_fallback; 547 591 } 548 592 549 593 viewports[i].cur_col = 0; 550 594 viewports[i].cur_row = 0; … … 575 619 unsigned int scan, unsigned int visual) 576 620 { 577 unsigned int glyphsize;578 uint8_t *glyphs;621 622 579 623 switch (visual) { 580 624 case VISUAL_INDIRECT_8: 581 625 screen.rgb_conv = rgb_323; 626 screen.mask_conv = mask_323; 582 627 screen.pixelbytes = 1; 583 628 break; 584 629 case VISUAL_RGB_5_5_5: 585 630 screen.rgb_conv = rgb_555; 631 screen.mask_conv = mask_555; 586 632 screen.pixelbytes = 2; 587 633 break; 588 634 case VISUAL_RGB_5_6_5: 589 635 screen.rgb_conv = rgb_565; 636 screen.mask_conv = mask_565; 590 637 screen.pixelbytes = 2; 591 638 break; 592 639 case VISUAL_RGB_8_8_8: 593 640 screen.rgb_conv = rgb_888; 641 screen.mask_conv = mask_888; 594 642 screen.pixelbytes = 3; 595 643 break; 596 644 case VISUAL_BGR_8_8_8: 597 645 screen.rgb_conv = bgr_888; 646 screen.mask_conv = mask_888; 598 647 screen.pixelbytes = 3; 599 648 break; 600 649 case VISUAL_RGB_8_8_8_0: 601 650 screen.rgb_conv = rgb_888; 651 screen.mask_conv = mask_888; 602 652 screen.pixelbytes = 4; 603 653 break; 604 654 case VISUAL_RGB_0_8_8_8: 605 655 screen.rgb_conv = rgb_0888; 656 screen.mask_conv = mask_0888; 606 657 screen.pixelbytes = 4; 607 658 break; 608 659 case VISUAL_BGR_0_8_8_8: 609 660 screen.rgb_conv = bgr_0888; 661 screen.mask_conv = mask_0888; 610 662 screen.pixelbytes = 4; 611 663 break; … … 613 665 return false; 614 666 } 615 667 616 668 screen.fb_addr = (unsigned char *) addr; 617 669 screen.xres = xres; … … 621 673 screen.glyphscanline = FONT_WIDTH * screen.pixelbytes; 622 674 screen.glyphbytes = screen.glyphscanline * FONT_SCANLINES; 623 624 glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes;625 glyphs = (uint8_t *) malloc(glyphsize);675 676 size_t glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes; 677 uint8_t *glyphs = (uint8_t *) malloc(glyphsize); 626 678 if (!glyphs) 627 679 return false; … … 629 681 memset(glyphs, 0, glyphsize); 630 682 screen.glyphs = glyphs; 631 683 632 684 render_glyphs(); 633 685 … … 652 704 * per pixel. 653 705 * 654 * @param x x coordinate of top-left corner on screen. 655 * @param y y coordinate of top-left corner on screen. 656 * @param cursor Draw glyph with cursor 657 * @param glyphs Pointer to font bitmap. 658 * @param glyph Code of the glyph to draw. 659 * @param fg_color Foreground color. 660 * @param bg_color Backgroudn color. 706 * @param x x coordinate of top-left corner on screen. 707 * @param y y coordinate of top-left corner on screen. 708 * @param cursor Draw glyph with cursor 709 * @param glyphs Pointer to font bitmap. 710 * @param glyph Code of the glyph to draw. 711 * @param fg_color Foreground color. 712 * @param bg_color Backgroudn color. 713 * 661 714 */ 662 715 static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor, 663 716 uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color) 664 717 { 665 unsigned int i, yd; 666 unsigned long fg_buf, bg_buf; 667 unsigned long *maskp, *dp; 718 unsigned int i; 719 unsigned int yd; 720 unsigned long fg_buf; 721 unsigned long bg_buf; 668 722 unsigned long mask; 669 unsigned int ww, d_add; 670 723 671 724 /* 672 725 * Prepare a pair of words, one filled with foreground-color … … 674 727 */ 675 728 for (i = 0; i < sizeof(unsigned long) / screen.pixelbytes; i++) { 676 screen.rgb_conv(&((uint8_t *) &fg_buf)[i * screen.pixelbytes],729 screen.rgb_conv(&((uint8_t *) &fg_buf)[i * screen.pixelbytes], 677 730 fg_color); 678 screen.rgb_conv(&((uint8_t *) &bg_buf)[i * screen.pixelbytes],731 screen.rgb_conv(&((uint8_t *) &bg_buf)[i * screen.pixelbytes], 679 732 bg_color); 680 733 } 681 734 682 735 /* Pointer to the current position in the mask. */ 683 maskp = (unsigned long *) &glyphs[GLYPH_POS(glyph, 0, cursor)];684 736 unsigned long *maskp = (unsigned long *) &glyphs[GLYPH_POS(glyph, 0, cursor)]; 737 685 738 /* Pointer to the current position on the screen. */ 686 dp = (unsigned long *) &screen.fb_addr[FB_POS(x, y)];687 739 unsigned long *dp = (unsigned long *) &screen.fb_addr[FB_POS(x, y)]; 740 688 741 /* Width of the character cell in words. */ 689 ww = FONT_WIDTH * screen.pixelbytes / sizeof(unsigned long);690 742 unsigned int ww = FONT_WIDTH * screen.pixelbytes / sizeof(unsigned long); 743 691 744 /* Offset to add when moving to another screen scanline. */ 692 d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;693 745 unsigned int d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes; 746 694 747 for (yd = 0; yd < FONT_SCANLINES; yd++) { 695 748 /* … … 701 754 *dp++ = (fg_buf & mask) | (bg_buf & ~mask); 702 755 } 703 756 704 757 /* Move to the beginning of the next scanline of the cell. */ 705 758 dp = (unsigned long *) ((uint8_t *) dp + d_add); … … 712 765 * the font bitmap directly. It works always, but it is slower. 713 766 * 714 * @param x x coordinate of top-left corner on screen. 715 * @param y y coordinate of top-left corner on screen. 716 * @param cursor Draw glyph with cursor 717 * @param glyphs Pointer to font bitmap. 718 * @param glyph Code of the glyph to draw. 719 * @param fg_color Foreground color. 720 * @param bg_color Backgroudn color. 767 * @param x x coordinate of top-left corner on screen. 768 * @param y y coordinate of top-left corner on screen. 769 * @param cursor Draw glyph with cursor 770 * @param glyphs Pointer to font bitmap. 771 * @param glyph Code of the glyph to draw. 772 * @param fg_color Foreground color. 773 * @param bg_color Backgroudn color. 774 * 721 775 */ 722 776 void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor, 723 777 uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color) 724 778 { 725 unsigned int i, j, yd; 726 uint8_t fg_buf[4], bg_buf[4]; 727 uint8_t *dp, *sp; 728 unsigned int d_add; 779 unsigned int i; 780 unsigned int j; 781 unsigned int yd; 782 uint8_t fg_buf[4]; 783 uint8_t bg_buf[4]; 784 uint8_t *sp; 729 785 uint8_t b; 730 786 731 787 /* Pre-render 1x the foreground and background color pixels. */ 732 788 if (cursor) { … … 737 793 screen.rgb_conv(bg_buf, bg_color); 738 794 } 739 795 740 796 /* Pointer to the current position on the screen. */ 741 dp = (uint8_t *) &screen.fb_addr[FB_POS(x, y)];742 797 uint8_t *dp = (uint8_t *) &screen.fb_addr[FB_POS(x, y)]; 798 743 799 /* Offset to add when moving to another screen scanline. */ 744 d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;745 800 unsigned int d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes; 801 746 802 for (yd = 0; yd < FONT_SCANLINES; yd++) { 747 803 /* Byte containing bits of the glyph scanline. */ 748 804 b = fb_font[glyph][yd]; 749 805 750 806 for (i = 0; i < FONT_WIDTH; i++) { 751 807 /* Choose color based on the current bit. */ 752 808 sp = (b & 0x80) ? fg_buf : bg_buf; 753 809 754 810 /* Copy the pixel. */ 755 811 for (j = 0; j < screen.pixelbytes; j++) { 756 812 *dp++ = *sp++; 757 813 } 758 814 759 815 /* Move to the next bit. */ 760 816 b = b << 1; … … 766 822 } 767 823 768 /** Draw glyph at specified position in viewport. 824 /** Draw glyph at specified position in viewport. 769 825 * 770 826 * @param vport Viewport identification … … 779 835 unsigned int x = vport->x + COL2X(col); 780 836 unsigned int y = vport->y + ROW2Y(row); 781 782 uint32_t glyph; 783 uint32_t fg_color; 784 uint32_t bg_color; 785 786 glyph = vport->backbuf[BB_POS(vport, col, row)].glyph; 787 fg_color = vport->backbuf[BB_POS(vport, col, row)].fg_color; 788 bg_color = vport->backbuf[BB_POS(vport, col, row)].bg_color; 789 837 838 uint32_t glyph = vport->backbuf[BB_POS(vport, col, row)].glyph; 839 uint32_t fg_color = vport->backbuf[BB_POS(vport, col, row)].fg_color; 840 uint32_t bg_color = vport->backbuf[BB_POS(vport, col, row)].bg_color; 841 790 842 (*vport->dglyph)(x, y, cursor, screen.glyphs, glyph, 791 843 fg_color, bg_color); … … 840 892 { 841 893 bb_cell_t *bbp; 842 894 843 895 /* Do not hide cursor if we are going to overwrite it */ 844 896 if ((vport->cursor_active) && (vport->cursor_shown) && 845 897 ((vport->cur_col != col) || (vport->cur_row != row))) 846 898 cursor_hide(vport); 847 899 848 900 bbp = &vport->backbuf[BB_POS(vport, col, row)]; 849 901 bbp->glyph = fb_font_glyph(c); 850 902 bbp->fg_color = vport->attr.fg_color; 851 903 bbp->bg_color = vport->attr.bg_color; 852 904 853 905 draw_vp_glyph(vport, false, col, row); 854 906 … … 871 923 * @param vport Viewport id 872 924 * @param data Text data. 873 * @param x Leftmost column of the area. 874 * @param y Topmost row of the area. 875 * @param w Number of rows. 876 * @param h Number of columns. 925 * @param x Leftmost column of the area. 926 * @param y Topmost row of the area. 927 * @param w Number of rows. 928 * @param h Number of columns. 929 * 877 930 */ 878 931 static void draw_text_data(viewport_t *vport, keyfield_t *data, unsigned int x, 879 932 unsigned int y, unsigned int w, unsigned int h) 880 933 { 881 unsigned int i, j; 934 unsigned int i; 935 unsigned int j; 882 936 bb_cell_t *bbp; 883 937 attrs_t *a; 884 938 attr_rgb_t rgb; 885 939 886 940 for (j = 0; j < h; j++) { 887 941 for (i = 0; i < w; i++) { 888 942 unsigned int col = x + i; 889 943 unsigned int row = y + j; 890 944 891 945 bbp = &vport->backbuf[BB_POS(vport, col, row)]; 892 946 893 947 a = &data[j * w + i].attrs; 894 948 rgb_from_attr(&rgb, a); 895 949 896 950 bbp->glyph = fb_font_glyph(data[j * w + i].character); 897 951 bbp->fg_color = rgb.fg_color; 898 952 bbp->bg_color = rgb.bg_color; 899 953 900 954 draw_vp_glyph(vport, false, col, row); 901 955 } … … 1193 1247 if (counts) 1194 1248 return; 1195 1249 1196 1250 for (i = 0; i < MAX_ANIMATIONS; i++) { 1197 1251 if ((!animations[i].animlen) || (!animations[i].initialized) ||
Note:
See TracChangeset
for help on using the changeset viewer.