Changeset 68a4442 in mainline
- Timestamp:
- 2008-12-26T13:29:49Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 713e6f2d
- Parents:
- edf5774
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fb/fb.c
redf5774 r68a4442 72 72 #define MAX_VIEWPORTS 128 /**< Viewport is a rectangular area on the screen */ 73 73 74 /** Function to render a pixel from a RGB value. */ 74 75 typedef void (*rgb_conv_t)(void *, uint32_t); 76 77 /** Function to draw a glyph. */ 78 typedef void (*dg_t)(unsigned int x, unsigned int y, bool cursor, 79 uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color); 75 80 76 81 struct { … … 100 105 unsigned int rows; 101 106 102 /* Style and glyphs for text printing */ 107 /* 108 * Style and glyphs for text printing 109 */ 110 111 /** Current style. */ 103 112 style_t style; 113 114 /** Pre-rendered mask for rendering glyphs. Different viewports 115 * might use different drawing functions depending on whether their 116 * scanlines are aligned on a word boundary.*/ 104 117 uint8_t *glyphs; 118 105 119 uint8_t *bgpixel; 120 121 /** Glyph drawing function for this viewport. */ 122 dg_t dglyph; 106 123 107 124 /* Auto-cursor position */ … … 140 157 static bool client_connected = false; /**< Allow only 1 connection */ 141 158 142 static void draw_glyph(unsigned int x, unsigned int y, bool cursor, 143 uint8_t *glyphs, uint8_t glyph); 159 static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor, 160 uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color); 161 static void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor, 162 uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color); 163 144 164 static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col, 145 165 unsigned int row); … … 334 354 } 335 355 336 draw_glyph(x, y, false, vport->glyphs, glyph); 356 (*vport->dglyph)(x, y, false, vport->glyphs, glyph, 357 vport->style.fg_color, vport->style.bg_color); 337 358 x += FONT_WIDTH; 338 359 } … … 377 398 screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes], 378 399 (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) 379 ? vport->style.fg_color : vport->style.bg_color);400 ? 0xffffff : 0x000000); 380 401 381 uint32_t curcolor; 382 383 if (y < FONT_SCANLINES - 2) 384 curcolor = 385 (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) 386 ? vport->style.fg_color : vport->style.bg_color; 387 else 388 curcolor = vport->style.fg_color; 389 390 screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes], curcolor); 402 screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes], 403 (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) 404 ? 0x000000 : 0xffffff); 391 405 } 392 406 } … … 423 437 unsigned int bbsize = cols * rows; 424 438 unsigned int glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes; 439 unsigned int word_size = sizeof(unsigned long); 425 440 426 441 uint8_t *backbuf = (uint8_t *) malloc(bbsize); … … 458 473 viewports[i].glyphs = glyphs; 459 474 viewports[i].bgpixel = bgpixel; 460 475 476 /* 477 * Conditions necessary to select aligned version: 478 * 479 * - word size is divisible by pixelbytes 480 * - cell scanline size is divisible by word size 481 * - cell scanlines are word-aligned 482 */ 483 if ((word_size % screen.pixelbytes) == 0 && 484 (FONT_WIDTH * screen.pixelbytes) % word_size == 0 && 485 (x * screen.pixelbytes) % word_size == 0 && 486 screen.scanline % word_size == 0) { 487 488 viewports[i].dglyph = draw_glyph_aligned; 489 } else { 490 viewports[i].dglyph = draw_glyph_fallback; 491 } 492 461 493 viewports[i].cur_col = 0; 462 494 viewports[i].cur_row = 0; … … 535 567 536 568 537 /** Draw a glyph. 538 * 539 * @param x x coordinate of top-left corner on screen. 540 * @param y y coordinate of top-left corner on screen. 541 * @param cursor Draw glyph with cursor 542 * @param glyphs Pointer to font bitmap. 543 * @param glyph Code of the glyph to draw. 544 * 545 */ 546 static void draw_glyph(unsigned int x, unsigned int y, bool cursor, 547 uint8_t *glyphs, uint8_t glyph) 548 { 549 unsigned int yd; 550 551 for (yd = 0; yd < FONT_SCANLINES; yd++) 552 memcpy(&screen.fb_addr[FB_POS(x, y + yd)], 553 &glyphs[GLYPH_POS(glyph, yd, cursor)], screen.glyphscanline); 569 /** Draw a glyph, takes advantage of alignment. 570 * 571 * This version can only be used if the following conditions are met: 572 * 573 * - word size is divisible by pixelbytes 574 * - cell scanline size is divisible by word size 575 * - cell scanlines are word-aligned 576 * 577 * It makes use of the pre-rendered mask to process (possibly) several 578 * pixels at once (word size / pixelbytes pixels at a time are processed) 579 * making it very fast. Most notably this version is not applicable at 24 bits 580 * per pixel. 581 * 582 * @param x x coordinate of top-left corner on screen. 583 * @param y y coordinate of top-left corner on screen. 584 * @param cursor Draw glyph with cursor 585 * @param glyphs Pointer to font bitmap. 586 * @param glyph Code of the glyph to draw. 587 * @param fg_color Foreground color. 588 * @param bg_color Backgroudn color. 589 */ 590 static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor, 591 uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color) 592 { 593 unsigned int i, yd; 594 unsigned long fg_buf, bg_buf; 595 unsigned long *maskp, *dp; 596 unsigned long mask; 597 unsigned int ww, d_add; 598 599 /* 600 * Prepare a pair of words, one filled with foreground-color 601 * pattern and the other filled with background-color pattern. 602 */ 603 for (i = 0; i < sizeof(unsigned long) / screen.pixelbytes; i++) { 604 screen.rgb_conv(&((uint8_t *)&fg_buf)[i * screen.pixelbytes], 605 fg_color); 606 screen.rgb_conv(&((uint8_t *)&bg_buf)[i * screen.pixelbytes], 607 bg_color); 608 } 609 610 611 /* Pointer to the current position in the mask. */ 612 maskp = (unsigned long *) &glyphs[GLYPH_POS(glyph, 0, cursor)]; 613 614 /* Pointer to the current position on the screen. */ 615 dp = (unsigned long *) &screen.fb_addr[FB_POS(x, y)]; 616 617 /* Width of the character cell in words. */ 618 ww = FONT_WIDTH * screen.pixelbytes / sizeof(unsigned long); 619 620 /* Offset to add when moving to another screen scanline. */ 621 d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes; 622 623 for (yd = 0; yd < FONT_SCANLINES; yd++) { 624 /* 625 * Now process the cell scanline, combining foreground 626 * and background color patters using the pre-rendered mask. 627 */ 628 for (i = 0; i < ww; i++) { 629 mask = *maskp++; 630 *dp++ = (fg_buf & mask) | (bg_buf & ~mask); 631 } 632 633 /* Move to the beginning of the next scanline of the cell. */ 634 dp = (unsigned long *) ((uint8_t *) dp + d_add); 635 } 636 } 637 638 /** Draw a glyph, fallback version. 639 * 640 * This version does not make use of the pre-rendered mask, it uses 641 * the font bitmap directly. It works always, but it is slower. 642 * 643 * @param x x coordinate of top-left corner on screen. 644 * @param y y coordinate of top-left corner on screen. 645 * @param cursor Draw glyph with cursor 646 * @param glyphs Pointer to font bitmap. 647 * @param glyph Code of the glyph to draw. 648 * @param fg_color Foreground color. 649 * @param bg_color Backgroudn color. 650 */ 651 void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor, 652 uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color) 653 { 654 unsigned int i, j, yd; 655 uint8_t fg_buf[4], bg_buf[4]; 656 uint8_t *dp, *sp; 657 unsigned int d_add; 658 uint8_t b; 659 660 /* Pre-render 1x the foreground and background color pixels. */ 661 if (cursor) { 662 screen.rgb_conv(fg_buf, bg_color); 663 screen.rgb_conv(bg_buf, fg_color); 664 } else { 665 screen.rgb_conv(fg_buf, fg_color); 666 screen.rgb_conv(bg_buf, bg_color); 667 } 668 669 /* Pointer to the current position on the screen. */ 670 dp = (uint8_t *) &screen.fb_addr[FB_POS(x, y)]; 671 672 /* Offset to add when moving to another screen scanline. */ 673 d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes; 674 675 for (yd = 0; yd < FONT_SCANLINES; yd++) { 676 /* Byte containing bits of the glyph scanline. */ 677 b = fb_font[glyph * FONT_SCANLINES + yd]; 678 679 for (i = 0; i < FONT_WIDTH; i++) { 680 /* Choose color based on the current bit. */ 681 sp = (b & 0x80) ? fg_buf : bg_buf; 682 683 /* Copy the pixel. */ 684 for (j = 0; j < screen.pixelbytes; j++) { 685 *dp++ = *sp++; 686 } 687 688 /* Move to the next bit. */ 689 b = b << 1; 690 } 691 692 /* Move to the beginning of the next scanline of the cell. */ 693 dp += d_add; 694 } 554 695 } 555 696 … … 570 711 571 712 glyph = vport->backbuf[BB_POS(vport, col, row)]; 572 draw_glyph(x, y, cursor, vport->glyphs, glyph); 573 } 574 713 714 (*vport->dglyph)(x, y, cursor, vport->glyphs, glyph, 715 vport->style.fg_color, vport->style.bg_color); 716 } 575 717 576 718 /** Hide cursor if it is shown … … 1339 1481 vport->style.fg_color = IPC_GET_ARG1(call); 1340 1482 vport->style.bg_color = IPC_GET_ARG2(call); 1341 render_glyphs(vport);1342 1483 retval = EOK; 1343 1484 break;
Note:
See TracChangeset
for help on using the changeset viewer.