Changeset 51547 in vbox for trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
- Timestamp:
- Jun 5, 2014 9:57:26 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 94194
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
r51436 r51547 119 119 mGuestXRes = 640; 120 120 mGuestYRes = 480; 121 mPixelFormat = FramebufferPixelFormat_Opaque;122 mUsesGuestVRAM = FALSE;123 121 mPtrVRAM = NULL; 124 122 mBitsPerPixel = 0; … … 371 369 if (!pixelFormat) 372 370 return E_POINTER; 373 *pixelFormat = mPixelFormat;371 *pixelFormat = FramebufferPixelFormat_FOURCC_RGB; 374 372 return S_OK; 375 373 } … … 379 377 if (!usesGuestVRAM) 380 378 return E_POINTER; 381 *usesGuestVRAM = mUsesGuestVRAM;379 *usesGuestVRAM = TRUE; 382 380 return S_OK; 383 381 } … … 477 475 } 478 476 479 /**480 * Request a display resize from the framebuffer.481 *482 * @returns COM status code.483 * @param pixelFormat The requested pixel format.484 * @param vram Pointer to the guest VRAM buffer (can be NULL).485 * @param bitsPerPixel Color depth in bits.486 * @param bytesPerLine Size of a scanline in bytes.487 * @param w New display width in pixels.488 * @param h New display height in pixels.489 * @param finished Address of output flag whether the update490 * could be fully processed in this call (which491 * has to return immediately) or VBox should wait492 * for all call to the resize complete API before493 * continuing with display updates.494 */495 STDMETHODIMP VBoxSDLFB::RequestResize(ULONG aScreenId, ULONG pixelFormat, BYTE *vram,496 ULONG bitsPerPixel, ULONG bytesPerLine,497 ULONG w, ULONG h, BOOL *finished)498 {499 LogFlowFunc (("w=%d, h=%d, pixelFormat=0x%08lX, vram=%p, "500 "bpp=%d, bpl=%d\n",501 w, h, pixelFormat, vram, bitsPerPixel, bytesPerLine));502 503 /*504 * SDL does not allow us to make this call from any other thread than505 * the main thread (the one which initialized the video mode). So we506 * have to send an event to the main SDL thread and tell VBox to wait.507 */508 if (!finished)509 {510 AssertMsgFailed(("RequestResize requires the finished flag!\n"));511 return E_FAIL;512 }513 514 /*515 * Optimize the case when the guest has changed only the VRAM ptr516 * and the framebuffer uses the guest VRAM as the source bitmap.517 */518 if ( mGuestXRes == w519 && mGuestYRes == h520 && mPixelFormat == pixelFormat521 && mBitsPerPixel == bitsPerPixel522 && mBytesPerLine == bytesPerLine523 && mUsesGuestVRAM524 )525 {526 mfSameSizeRequested = true;527 }528 else529 {530 mfSameSizeRequested = false;531 }532 533 mGuestXRes = w;534 mGuestYRes = h;535 mPixelFormat = pixelFormat;536 mPtrVRAM = vram;537 mBitsPerPixel = bitsPerPixel;538 mBytesPerLine = bytesPerLine;539 mUsesGuestVRAM = FALSE; /* yet */540 541 SDL_Event event;542 event.type = SDL_USEREVENT;543 event.user.type = SDL_USER_EVENT_RESIZE;544 event.user.code = mScreenId;545 546 /* Try multiple times if necessary */547 PushSDLEventForSure(&event);548 549 /* we want this request to be processed quickly, so yield the CPU */550 RTThreadYield();551 552 *finished = false;553 554 return S_OK;555 }556 557 477 extern ComPtr<IDisplay> gpDisplay; 558 559 /* This method runs on the main SDL thread. */560 void VBoxSDLFB::notifyChange(ULONG aScreenId)561 {562 /* Disable screen updates. */563 RTCritSectEnter(&mUpdateLock);564 565 if (mpPendingSourceBitmap.isNull())566 {567 /* Do nothing. Change event already processed. */568 RTCritSectLeave(&mUpdateLock);569 return;570 }571 572 /* Disable screen updates. */573 mfUpdates = false;574 575 /* Release the current bitmap and keep the pending one. */576 mpSourceBitmap = mpPendingSourceBitmap;577 mpPendingSourceBitmap.setNull();578 579 RTCritSectLeave(&mUpdateLock);580 581 BYTE *pAddress = NULL;582 ULONG ulWidth = 0;583 ULONG ulHeight = 0;584 ULONG ulBitsPerPixel = 0;585 ULONG ulBytesPerLine = 0;586 ULONG ulPixelFormat = 0;587 588 mpSourceBitmap->QueryBitmapInfo(&pAddress,589 &ulWidth,590 &ulHeight,591 &ulBitsPerPixel,592 &ulBytesPerLine,593 &ulPixelFormat);594 595 if ( mGuestXRes == ulWidth596 && mGuestYRes == ulHeight597 && mBitsPerPixel == ulBitsPerPixel598 && mBytesPerLine == ulBytesPerLine599 && mPtrVRAM == pAddress600 )601 {602 mfSameSizeRequested = true;603 }604 else605 {606 mfSameSizeRequested = false;607 }608 609 mGuestXRes = ulWidth;610 mGuestYRes = ulHeight;611 mPixelFormat = FramebufferPixelFormat_Opaque;612 mPtrVRAM = pAddress;613 mBitsPerPixel = ulBitsPerPixel;614 mBytesPerLine = ulBytesPerLine;615 mUsesGuestVRAM = FALSE; /* yet */616 617 resizeGuest();618 }619 478 620 479 STDMETHODIMP VBoxSDLFB::NotifyChange(ULONG aScreenId, … … 625 484 { 626 485 LogRel(("NotifyChange: %d %d,%d %dx%d\n", 627 aScreenId, aXOrigin, aYOrigin, aWidth, aHeight)); 628 629 /* Obtain the new screen bitmap. */ 486 aScreenId, aXOrigin, aYOrigin, aWidth, aHeight)); 487 630 488 RTCritSectEnter(&mUpdateLock); 489 490 /* Disable screen updates. */ 491 mfUpdates = false; 631 492 632 493 /* Save the new bitmap. */ … … 726 587 // 727 588 589 /* This method runs on the main SDL thread. */ 590 void VBoxSDLFB::notifyChange(ULONG aScreenId) 591 { 592 /* Disable screen updates. */ 593 RTCritSectEnter(&mUpdateLock); 594 595 if (mpPendingSourceBitmap.isNull()) 596 { 597 /* Do nothing. Change event already processed. */ 598 RTCritSectLeave(&mUpdateLock); 599 return; 600 } 601 602 /* Release the current bitmap and keep the pending one. */ 603 mpSourceBitmap = mpPendingSourceBitmap; 604 mpPendingSourceBitmap.setNull(); 605 606 RTCritSectLeave(&mUpdateLock); 607 608 if (mpSourceBitmap.isNull()) 609 { 610 mPtrVRAM = NULL; 611 mBitsPerPixel = 32; 612 mBytesPerLine = mGuestXRes * 4; 613 } 614 else 615 { 616 BYTE *pAddress = NULL; 617 ULONG ulWidth = 0; 618 ULONG ulHeight = 0; 619 ULONG ulBitsPerPixel = 0; 620 ULONG ulBytesPerLine = 0; 621 ULONG ulPixelFormat = 0; 622 623 mpSourceBitmap->QueryBitmapInfo(&pAddress, 624 &ulWidth, 625 &ulHeight, 626 &ulBitsPerPixel, 627 &ulBytesPerLine, 628 &ulPixelFormat); 629 630 if ( mGuestXRes == ulWidth 631 && mGuestYRes == ulHeight 632 && mBitsPerPixel == ulBitsPerPixel 633 && mBytesPerLine == ulBytesPerLine 634 && mPtrVRAM == pAddress 635 ) 636 { 637 mfSameSizeRequested = true; 638 } 639 else 640 { 641 mfSameSizeRequested = false; 642 } 643 644 mGuestXRes = ulWidth; 645 mGuestYRes = ulHeight; 646 mPtrVRAM = pAddress; 647 mBitsPerPixel = ulBitsPerPixel; 648 mBytesPerLine = ulBytesPerLine; 649 } 650 651 resizeGuest(); 652 } 653 728 654 /** 729 655 * Method that does the actual resize of the guest framebuffer and … … 736 662 ("Wrong thread! SDL is not threadsafe!\n")); 737 663 738 uint32_t Rmask, Gmask, Bmask, Amask = 0; 739 740 mUsesGuestVRAM = FALSE; 741 742 /* pixel characteristics. if we don't support the format directly, we will 743 * fallback to the indirect 32bpp buffer (mUsesGuestVRAM will remain 744 * FALSE) */ 745 if (mPixelFormat == FramebufferPixelFormat_FOURCC_RGB) 746 { 747 switch (mBitsPerPixel) 748 { 749 case 16: 750 case 24: 751 case 32: 752 mUsesGuestVRAM = TRUE; 753 break; 754 default: 755 /* the fallback buffer is always 32bpp */ 756 mBitsPerPixel = 32; 757 mBytesPerLine = mGuestXRes * 4; 758 break; 759 } 760 } 761 else 762 { 763 /* the fallback buffer is always RGB, 32bpp */ 764 mPixelFormat = FramebufferPixelFormat_FOURCC_RGB; 765 mBitsPerPixel = 32; 766 mBytesPerLine = mGuestXRes * 4; 767 } 768 769 switch (mBitsPerPixel) 770 { 771 case 16: Rmask = 0x0000F800; Gmask = 0x000007E0; Bmask = 0x0000001F; break; 772 default: Rmask = 0x00FF0000; Gmask = 0x0000FF00; Bmask = 0x000000FF; break; 773 } 664 const uint32_t Rmask = 0x00FF0000, Gmask = 0x0000FF00, Bmask = 0x000000FF, Amask = 0; 774 665 775 666 /* first free the current surface */ … … 780 671 } 781 672 782 /* is the guest in a linear framebuffer mode we support? */ 783 if (mPtrVRAM || mUsesGuestVRAM) 784 { 785 /* Create a source surface from guest VRAM. */ 673 if (mPtrVRAM) 674 { 675 /* Create a source surface from the source bitmap. */ 786 676 mSurfVRAM = SDL_CreateRGBSurfaceFrom(mPtrVRAM, mGuestXRes, mGuestYRes, mBitsPerPixel, 787 677 mBytesPerLine, Rmask, Gmask, Bmask, Amask); 788 Log Rel(("mSurfVRAM from guest %d x %d\n", mGuestXRes, mGuestYRes));678 LogFlow(("VBoxSDL:: using the source bitmap\n")); 789 679 } 790 680 else 791 681 { 792 /* Create a software surface for which SDL allocates the RAM */793 682 mSurfVRAM = SDL_CreateRGBSurface(SDL_SWSURFACE, mGuestXRes, mGuestYRes, mBitsPerPixel, 794 683 Rmask, Gmask, Bmask, Amask); 795 Log Rel(("mSurfVRAM from SDL %d x %d\n", mGuestXRes, mGuestYRes));684 LogFlow(("VBoxSDL:: using SDL_SWSURFACE\n")); 796 685 } 797 686 LogFlow(("VBoxSDL:: created VRAM surface %p\n", mSurfVRAM)); 798 687 799 if (mfSameSizeRequested && mUsesGuestVRAM) 800 { 801 /* 802 * Same size has been requested and the framebuffer still uses the guest VRAM. 803 * Reset the condition and return. 804 */ 688 if (mfSameSizeRequested) 689 { 805 690 mfSameSizeRequested = false; 806 691 LogFlow(("VBoxSDL:: the same resolution requested, skipping the resize.\n")); 807 808 /* Enable screen updates. */ 809 RTCritSectEnter(&mUpdateLock); 810 mfUpdates = true; 811 RTCritSectLeave(&mUpdateLock); 812 813 return; 814 } 815 816 /* now adjust the SDL resolution */ 817 resizeSDL(); 692 } 693 else 694 { 695 /* now adjust the SDL resolution */ 696 resizeSDL(); 697 } 818 698 819 699 /* Enable screen updates. */ … … 1045 925 ((mScreen->flags & SDL_HWSURFACE) == 0) ? "software" : "hardware"); 1046 926 } 1047 repaint();1048 927 } 1049 928 … … 1181 1060 /* only change the SDL resolution, do not touch the guest framebuffer */ 1182 1061 resizeSDL(); 1062 repaint(); 1183 1063 } 1184 1064
Note:
See TracChangeset
for help on using the changeset viewer.