Changeset a35b458 in mainline for kernel/genarch/src/fb/fb.c
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/fb/fb.c
r3061bc1 ra35b458 84 84 typedef struct { 85 85 SPINLOCK_DECLARE(lock); 86 86 87 87 parea_t parea; 88 88 89 89 uint8_t *addr; 90 90 uint16_t *backbuf; 91 91 uint8_t *glyphs; 92 92 uint8_t *bgscan; 93 93 94 94 rgb_conv_t rgb_conv; 95 95 96 96 unsigned int xres; 97 97 unsigned int yres; 98 98 99 99 /** Number of rows that fit on framebuffer */ 100 100 unsigned int rowtrim; 101 101 102 102 unsigned int scanline; 103 103 unsigned int glyphscanline; 104 104 105 105 unsigned int pixelbytes; 106 106 unsigned int glyphbytes; 107 107 unsigned int bgscanbytes; 108 108 109 109 /** Number of columns in the backbuffer */ 110 110 unsigned int cols; 111 111 /** Number of rows in the backbuffer */ 112 112 unsigned int rows; 113 113 114 114 /** Starting row in the cyclic backbuffer */ 115 115 unsigned int start_row; 116 116 117 117 /** Top-most visible row (relative to start_row) */ 118 118 unsigned int offset_row; 119 119 120 120 /** Current backbuffer position */ 121 121 unsigned int position; … … 236 236 if (!overlay) 237 237 instance->backbuf[BB_POS(instance, col, row)] = glyph; 238 238 239 239 /* Do not output if the framebuffer is used by user space */ 240 240 if ((instance->parea.mapped) && (!console_override)) 241 241 return; 242 242 243 243 /* Check whether the glyph should be visible */ 244 244 if (row < instance->offset_row) 245 245 return; 246 246 247 247 unsigned int rel_row = row - instance->offset_row; 248 248 if (rel_row >= instance->rowtrim) 249 249 return; 250 250 251 251 unsigned int x = COL2X(col); 252 252 unsigned int y = ROW2Y(rel_row); 253 253 254 254 for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) 255 255 memcpy(&instance->addr[FB_POS(instance, x, y + yd)], … … 267 267 unsigned int y = ROW2Y(rel_row); 268 268 unsigned int row = rel_row + instance->offset_row; 269 269 270 270 for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) { 271 271 unsigned int x; 272 272 unsigned int col; 273 273 274 274 for (col = 0, x = 0; col < instance->cols; 275 275 col++, x += FONT_WIDTH) { 276 276 uint16_t glyph; 277 277 278 278 if (row < instance->rows - 1) { 279 279 if (instance->backbuf[BB_POS(instance, col, row)] == 280 280 instance->backbuf[BB_POS(instance, col, row + 1)]) 281 281 continue; 282 282 283 283 glyph = instance->backbuf[BB_POS(instance, col, row + 1)]; 284 284 } else 285 285 glyph = 0; 286 286 287 287 memcpy(&instance->addr[FB_POS(instance, x, y + yd)], 288 288 &instance->glyphs[GLYPH_POS(instance, glyph, yd)], … … 292 292 } 293 293 } 294 294 295 295 /* 296 296 * Implement backbuffer scrolling by wrapping around 297 297 * the cyclic buffer. 298 298 */ 299 299 300 300 instance->start_row++; 301 301 if (instance->start_row == instance->rows) 302 302 instance->start_row = 0; 303 303 304 304 memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)], 305 305 instance->cols, 0); … … 310 310 unsigned int col = instance->position % instance->cols; 311 311 unsigned int row = instance->position / instance->cols; 312 312 313 313 glyph_draw(instance, fb_font_glyph(U_CURSOR), col, row, true); 314 314 } … … 318 318 unsigned int col = instance->position % instance->cols; 319 319 unsigned int row = instance->position / instance->cols; 320 320 321 321 glyph_draw(instance, instance->backbuf[BB_POS(instance, col, row)], 322 322 col, row, true); … … 333 333 /* Prerender glyphs */ 334 334 uint16_t glyph; 335 335 336 336 for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { 337 337 uint32_t fg_color; 338 338 339 339 if (glyph == FONT_GLYPHS - 1) 340 340 fg_color = INV_COLOR; 341 341 else 342 342 fg_color = FG_COLOR; 343 343 344 344 unsigned int y; 345 345 346 346 for (y = 0; y < FONT_SCANLINES; y++) { 347 347 unsigned int x; 348 348 349 349 for (x = 0; x < FONT_WIDTH; x++) { 350 350 void *dst = … … 357 357 } 358 358 } 359 359 360 360 /* Prerender background scanline */ 361 361 unsigned int x; 362 362 363 363 for (x = 0; x < instance->xres; x++) 364 364 instance->rgb_conv(&instance->bgscan[x * instance->pixelbytes], BG_COLOR); … … 370 370 unsigned int y = ROW2Y(rel_row); 371 371 unsigned int row = rel_row + instance->offset_row; 372 372 373 373 for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) { 374 374 unsigned int x; 375 375 unsigned int col; 376 376 377 377 for (col = 0, x = 0; col < instance->cols; 378 378 col++, x += FONT_WIDTH) { … … 385 385 } 386 386 } 387 387 388 388 if (COL2X(instance->cols) < instance->xres) { 389 389 unsigned int y; 390 390 unsigned int size = 391 391 (instance->xres - COL2X(instance->cols)) * instance->pixelbytes; 392 392 393 393 for (y = 0; y < instance->yres; y++) 394 394 memcpy(&instance->addr[FB_POS(instance, COL2X(instance->cols), y)], 395 395 instance->bgscan, size); 396 396 } 397 397 398 398 if (ROW2Y(instance->rowtrim) < instance->yres) { 399 399 unsigned int y; 400 400 401 401 for (y = ROW2Y(instance->rowtrim); y < instance->yres; y++) 402 402 memcpy(&instance->addr[FB_POS(instance, 0, y)], … … 414 414 fb_instance_t *instance = (fb_instance_t *) dev->data; 415 415 spinlock_lock(&instance->lock); 416 416 417 417 switch (ch) { 418 418 case '\n': … … 446 446 instance->position++; 447 447 } 448 448 449 449 if (instance->position >= instance->cols * instance->rows) { 450 450 instance->position -= instance->cols; 451 451 screen_scroll(instance); 452 452 } 453 453 454 454 cursor_put(instance); 455 455 456 456 spinlock_unlock(&instance->lock); 457 457 } … … 464 464 fb_instance_t *instance = (fb_instance_t *) dev->data; 465 465 spinlock_lock(&instance->lock); 466 466 467 467 if (instance->offset_row >= instance->rowtrim / 2) 468 468 instance->offset_row -= instance->rowtrim / 2; 469 469 else 470 470 instance->offset_row = 0; 471 471 472 472 fb_redraw_internal(instance); 473 473 cursor_put(instance); 474 474 475 475 spinlock_unlock(&instance->lock); 476 476 } … … 483 483 fb_instance_t *instance = (fb_instance_t *) dev->data; 484 484 spinlock_lock(&instance->lock); 485 485 486 486 if (instance->offset_row + instance->rowtrim / 2 <= 487 487 instance->rows - instance->rowtrim) … … 489 489 else 490 490 instance->offset_row = instance->rows - instance->rowtrim; 491 491 492 492 fb_redraw_internal(instance); 493 493 cursor_put(instance); 494 494 495 495 spinlock_unlock(&instance->lock); 496 496 } … … 502 502 { 503 503 fb_instance_t *instance = (fb_instance_t *) dev->data; 504 504 505 505 spinlock_lock(&instance->lock); 506 506 fb_redraw_internal(instance); … … 517 517 assert(props->y > 0); 518 518 assert(props->scan > 0); 519 519 520 520 rgb_conv_t rgb_conv; 521 521 unsigned int pixelbytes; 522 522 523 523 switch (props->visual) { 524 524 case VISUAL_INDIRECT_8: … … 570 570 return NULL; 571 571 } 572 572 573 573 outdev_t *fbdev = malloc(sizeof(outdev_t), FRAME_ATOMIC); 574 574 if (!fbdev) 575 575 return NULL; 576 576 577 577 fb_instance_t *instance = malloc(sizeof(fb_instance_t), FRAME_ATOMIC); 578 578 if (!instance) { … … 580 580 return NULL; 581 581 } 582 582 583 583 outdev_initialize("fbdev", fbdev, &fbdev_ops); 584 584 fbdev->data = instance; 585 585 586 586 spinlock_initialize(&instance->lock, "*fb.instance.lock"); 587 587 588 588 instance->rgb_conv = rgb_conv; 589 589 instance->pixelbytes = pixelbytes; … … 591 591 instance->yres = props->y; 592 592 instance->scanline = props->scan; 593 593 594 594 instance->rowtrim = Y2ROW(instance->yres); 595 595 596 596 instance->cols = X2COL(instance->xres); 597 597 instance->rows = FB_PAGES * instance->rowtrim; 598 598 599 599 instance->start_row = instance->rows - instance->rowtrim; 600 600 instance->offset_row = instance->start_row; 601 601 instance->position = instance->start_row * instance->cols; 602 602 603 603 instance->glyphscanline = FONT_WIDTH * instance->pixelbytes; 604 604 instance->glyphbytes = ROW2Y(instance->glyphscanline); 605 605 instance->bgscanbytes = instance->xres * instance->pixelbytes; 606 606 607 607 size_t fbsize = instance->scanline * instance->yres; 608 608 size_t bbsize = instance->cols * instance->rows * sizeof(uint16_t); 609 609 size_t glyphsize = FONT_GLYPHS * instance->glyphbytes; 610 610 611 611 instance->addr = (uint8_t *) km_map((uintptr_t) props->addr, fbsize, 612 612 PAGE_WRITE | PAGE_NOT_CACHEABLE); … … 617 617 return NULL; 618 618 } 619 619 620 620 instance->backbuf = (uint16_t *) malloc(bbsize, 0); 621 621 if (!instance->backbuf) { … … 625 625 return NULL; 626 626 } 627 627 628 628 instance->glyphs = (uint8_t *) malloc(glyphsize, 0); 629 629 if (!instance->glyphs) { … … 634 634 return NULL; 635 635 } 636 636 637 637 instance->bgscan = malloc(instance->bgscanbytes, 0); 638 638 if (!instance->bgscan) { … … 644 644 return NULL; 645 645 } 646 646 647 647 memsetw(instance->backbuf, instance->cols * instance->rows, 0); 648 648 glyphs_render(instance); 649 649 650 650 link_initialize(&instance->parea.link); 651 651 instance->parea.pbase = props->addr; … … 654 654 instance->parea.mapped = false; 655 655 ddi_parea_register(&instance->parea); 656 656 657 657 if (!fb_exported) { 658 658 /* … … 668 668 sysinfo_set_item_val("fb.visual", NULL, props->visual); 669 669 sysinfo_set_item_val("fb.address.physical", NULL, props->addr); 670 670 671 671 fb_exported = true; 672 672 } 673 673 674 674 fb_redraw(fbdev); 675 675 return fbdev;
Note:
See TracChangeset
for help on using the changeset viewer.