- Timestamp:
- Jun 19, 2017 1:12:33 PM (8 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA.cpp
r67355 r67474 1786 1786 */ 1787 1787 static int vga_draw_text(PVGASTATE pThis, bool full_update, bool fFailOnResize, bool reset_dirty, 1788 PDMIDISPLAYCONNECTOR *pDrv)1788 PDMIDISPLAYCONNECTOR *pDrv) 1789 1789 { 1790 1790 int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr; … … 2312 2312 uint32_t offPage0 = offSrcLine & ~PAGE_OFFSET_MASK; 2313 2313 uint32_t offPage1 = (offSrcLine + cbScanline - 1) & ~PAGE_OFFSET_MASK; 2314 /** @todo r=klaus this assumes that a line is fully covered by 2 pages, 2315 * irrespective of alignment. Not guaranteed for high res modes, i.e. 2316 * anything wider than 1026 pixels @32bpp. Need to check the pages 2317 * between the first and last one, too. */ 2314 2318 bool fUpdate = fFullUpdate | vga_is_dirty(pThis, offPage0) | vga_is_dirty(pThis, offPage1); 2315 2319 if (offPage1 - offPage0 > PAGE_SIZE) … … 2361 2365 */ 2362 2366 static int vga_draw_graphic(PVGASTATE pThis, bool full_update, bool fFailOnResize, bool reset_dirty, 2363 PDMIDISPLAYCONNECTOR *pDrv)2367 PDMIDISPLAYCONNECTOR *pDrv) 2364 2368 { 2365 2369 int y1, y2, y, page_min, page_max, linesize, y_start, double_scan; … … 2501 2505 page0 = addr & ~PAGE_OFFSET_MASK; 2502 2506 page1 = (addr + bwidth - 1) & ~PAGE_OFFSET_MASK; 2507 /** @todo r=klaus this assumes that a line is fully covered by 2 pages, 2508 * irrespective of alignment. Not guaranteed for high res modes, i.e. 2509 * anything wider than 1026 pixels @32bpp. Need to check the pages 2510 * between the first and last one, too. */ 2503 2511 bool update = full_update | vga_is_dirty(pThis, page0) | vga_is_dirty(pThis, page1); 2504 2512 if (page1 - page0 > PAGE_SIZE) { … … 2556 2564 } 2557 2565 2558 static void vga_draw_blank(PVGASTATE pThis, int full_update, PDMIDISPLAYCONNECTOR *pDrv) 2566 /* 2567 * blanked modes 2568 */ 2569 static int vga_draw_blank(PVGASTATE pThis, bool full_update, bool fFailOnResize, bool reset_dirty, 2570 PDMIDISPLAYCONNECTOR *pDrv) 2559 2571 { 2560 2572 int i, w, val; 2561 2573 uint8_t *d; 2562 2574 uint32_t cbScanline = pDrv->cbScanline; 2563 2575 uint32_t page_min, page_max; 2576 2577 if (pThis->last_width != 0) 2578 { 2579 if (fFailOnResize) 2580 { 2581 /* The caller does not want to call the pfnResize. */ 2582 return VERR_TRY_AGAIN; 2583 } 2584 pThis->last_width = 0; 2585 pThis->last_height = 0; 2586 /* For blanking signal width=0, height=0, bpp=0 and cbLine=0 here. 2587 * There is no screen content, which distinguishes it from text mode. */ 2588 pDrv->pfnResize(pDrv, 0, NULL, 0, 0, 0); 2589 } 2590 /* reset modified pages, i.e. everything */ 2591 if (reset_dirty && pThis->last_scr_height > 0) 2592 { 2593 page_min = (pThis->start_addr * 4) & ~PAGE_OFFSET_MASK; 2594 /* round up page_max by one page, as otherwise this can be -PAGE_SIZE, 2595 * which causes assertion trouble in vga_reset_dirty. */ 2596 page_max = ( pThis->start_addr * 4 + pThis->line_offset * pThis->last_scr_height 2597 - 1 + PAGE_SIZE) & ~PAGE_OFFSET_MASK; 2598 vga_reset_dirty(pThis, page_min, page_max + PAGE_SIZE); 2599 } 2564 2600 if (pDrv->pbData == pThis->vram_ptrR3) /* Do not clear the VRAM itself. */ 2565 return ;2601 return VINF_SUCCESS; 2566 2602 if (!full_update) 2567 return ;2603 return VINF_SUCCESS; 2568 2604 if (pThis->last_scr_width <= 0 || pThis->last_scr_height <= 0) 2569 return ;2605 return VINF_SUCCESS; 2570 2606 if (pDrv->cBits == 8) 2571 2607 val = pThis->rgb_to_pixel(0, 0, 0); … … 2582 2618 } 2583 2619 pDrv->pfnUpdateRect(pDrv, 0, 0, pThis->last_scr_width, pThis->last_scr_height); 2620 return VINF_SUCCESS; 2584 2621 } 2585 2622 … … 2590 2627 2591 2628 2592 #define GMODE_TEXT 02593 #define GMODE_GRAPH 12594 #define GMODE_BLANK 22629 #define GMODE_TEXT 0 2630 #define GMODE_GRAPH 1 2631 #define GMODE_BLANK 2 2595 2632 #ifdef VBOX_WITH_VMSVGA 2596 2633 #define GMODE_SVGA 3 … … 2622 2659 } 2623 2660 2624 if (fUpdateAll) {2625 /* A full update is requested. Special processing for a "blank" mode is required, because2626 * the request must process all pending resolution changes.2627 *2628 * Appropriate vga_draw_graphic or vga_draw_text function, which checks the resolution change,2629 * must be called even if the screen has been blanked, but then the function should do no actual2630 * screen update. To do this, pfnUpdateRect is replaced with a nop.2631 */2632 typedef DECLCALLBACK(void) FNUPDATERECT(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy);2633 typedef FNUPDATERECT *PFNUPDATERECT;2634 2635 PFNUPDATERECT pfnUpdateRect = NULL;2636 2637 /* Detect the "screen blank" conditions. */2638 int fBlank = 0;2639 if (!(pThis->ar_index & 0x20) || (pThis->sr[0x01] & 0x20)) {2640 fBlank = 1;2641 }2642 2643 if (fBlank) {2644 /* Provide a void pfnUpdateRect callback. */2645 if (pDrv) {2646 pfnUpdateRect = pDrv->pfnUpdateRect;2647 pDrv->pfnUpdateRect = voidUpdateRect;2648 }2649 }2650 2651 /* Do a complete redraw, which will pick up a new screen resolution. */2652 #ifdef VBOX_WITH_VMSVGA2653 if (pThis->svga.fEnabled) {2654 *pcur_graphic_mode = GMODE_SVGA;2655 rc = vmsvga_draw_graphic(pThis, 1, fFailOnResize, reset_dirty, pDrv);2656 }2657 else2658 #endif2659 if (pThis->gr[6] & 1) {2660 *pcur_graphic_mode = GMODE_GRAPH;2661 rc = vga_draw_graphic(pThis, 1, fFailOnResize, reset_dirty, pDrv);2662 } else {2663 *pcur_graphic_mode = GMODE_TEXT;2664 rc = vga_draw_text(pThis, 1, fFailOnResize, reset_dirty, pDrv);2665 }2666 2667 if (fBlank) {2668 /* Set the current mode and restore the callback. */2669 *pcur_graphic_mode = GMODE_BLANK;2670 if (pDrv) {2671 pDrv->pfnUpdateRect = pfnUpdateRect;2672 }2673 }2674 return rc;2675 }2676 2677 2661 #ifdef VBOX_WITH_VMSVGA 2678 2662 if (pThis->svga.fEnabled) { … … 2684 2668 graphic_mode = GMODE_BLANK; 2685 2669 } else { 2686 graphic_mode = pThis->gr[6] & 1 ;2687 } 2688 bool full_update = graphic_mode != *pcur_graphic_mode;2670 graphic_mode = pThis->gr[6] & 1 ? GMODE_GRAPH : GMODE_TEXT; 2671 } 2672 bool full_update = fUpdateAll || graphic_mode != *pcur_graphic_mode; 2689 2673 if (full_update) { 2690 2674 *pcur_graphic_mode = graphic_mode; … … 2704 2688 case GMODE_BLANK: 2705 2689 default: 2706 vga_draw_blank(pThis, full_update, pDrv);2690 rc = vga_draw_blank(pThis, full_update, fFailOnResize, reset_dirty, pDrv); 2707 2691 break; 2708 2692 } -
trunk/src/VBox/Main/src-client/DisplayImpl.cpp
r66400 r67474 1078 1078 pFBInfo->pSourceBitmap.setNull(); 1079 1079 1080 /* VGA blanking is signaled as w=0, h=0, bpp=0 and cbLine=0, and it's 1081 * best to keep the old resolution, as otherwise the window size would 1082 * change before the new resolution is known. */ 1083 const bool fVGABlank = fVGAResize && uScreenId == VBOX_VIDEO_PRIMARY_SCREEN 1084 && w == 0 && h == 0 && bpp == 0 && cbLine == 0; 1085 if (fVGABlank) 1086 { 1087 w = pFBInfo->w; 1088 h = pFBInfo->h; 1089 } 1090 1080 1091 /* Update the video mode information. */ 1081 1092 pFBInfo->w = w; … … 1092 1103 pFBInfo->fDisabled = RT_BOOL(flags & VBVA_SCREEN_F_DISABLED); 1093 1104 pFBInfo->fVBVAForceResize = false; 1105 } 1106 else 1107 { 1108 pFBInfo->flags = 0; 1109 if (fVGABlank) 1110 pFBInfo->flags |= VBVA_SCREEN_F_BLANK; 1111 pFBInfo->fDisabled = false; 1094 1112 } 1095 1113
Note:
See TracChangeset
for help on using the changeset viewer.