VirtualBox

Ignore:
Timestamp:
Jun 5, 2014 9:57:26 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
94194
Message:

VBoxSDL: new IFramebuffer interface cleanup.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp

    r51436 r51547  
    119119    mGuestXRes      = 640;
    120120    mGuestYRes      = 480;
    121     mPixelFormat    = FramebufferPixelFormat_Opaque;
    122     mUsesGuestVRAM  = FALSE;
    123121    mPtrVRAM        = NULL;
    124122    mBitsPerPixel   = 0;
     
    371369    if (!pixelFormat)
    372370        return E_POINTER;
    373     *pixelFormat = mPixelFormat;
     371    *pixelFormat = FramebufferPixelFormat_FOURCC_RGB;
    374372    return S_OK;
    375373}
     
    379377    if (!usesGuestVRAM)
    380378        return E_POINTER;
    381     *usesGuestVRAM = mUsesGuestVRAM;
     379    *usesGuestVRAM = TRUE;
    382380    return S_OK;
    383381}
     
    477475}
    478476
    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 update
    490  *                      could be fully processed in this call (which
    491  *                      has to return immediately) or VBox should wait
    492  *                      for all call to the resize complete API before
    493  *                      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 than
    505      * the main thread (the one which initialized the video mode). So we
    506      * 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 ptr
    516      * and the framebuffer uses the guest VRAM as the source bitmap.
    517      */
    518     if (   mGuestXRes    == w
    519         && mGuestYRes    == h
    520         && mPixelFormat  == pixelFormat
    521         && mBitsPerPixel == bitsPerPixel
    522         && mBytesPerLine == bytesPerLine
    523         && mUsesGuestVRAM
    524        )
    525     {
    526         mfSameSizeRequested = true;
    527     }
    528     else
    529     {
    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 
    557477extern 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    == ulWidth
    596         && mGuestYRes    == ulHeight
    597         && mBitsPerPixel == ulBitsPerPixel
    598         && mBytesPerLine == ulBytesPerLine
    599         && mPtrVRAM == pAddress
    600        )
    601     {
    602         mfSameSizeRequested = true;
    603     }
    604     else
    605     {
    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 }
    619478
    620479STDMETHODIMP VBoxSDLFB::NotifyChange(ULONG aScreenId,
     
    625484{
    626485    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
    630488    RTCritSectEnter(&mUpdateLock);
     489
     490    /* Disable screen updates. */
     491    mfUpdates = false;
    631492
    632493    /* Save the new bitmap. */
     
    726587//
    727588
     589/* This method runs on the main SDL thread. */
     590void 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
    728654/**
    729655 * Method that does the actual resize of the guest framebuffer and
     
    736662              ("Wrong thread! SDL is not threadsafe!\n"));
    737663
    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;
    774665
    775666    /* first free the current surface */
     
    780671    }
    781672
    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. */
    786676        mSurfVRAM = SDL_CreateRGBSurfaceFrom(mPtrVRAM, mGuestXRes, mGuestYRes, mBitsPerPixel,
    787677                                             mBytesPerLine, Rmask, Gmask, Bmask, Amask);
    788         LogRel(("mSurfVRAM from guest %d x %d\n", mGuestXRes,  mGuestYRes));
     678        LogFlow(("VBoxSDL:: using the source bitmap\n"));
    789679    }
    790680    else
    791681    {
    792         /* Create a software surface for which SDL allocates the RAM */
    793682        mSurfVRAM = SDL_CreateRGBSurface(SDL_SWSURFACE, mGuestXRes, mGuestYRes, mBitsPerPixel,
    794683                                         Rmask, Gmask, Bmask, Amask);
    795         LogRel(("mSurfVRAM from SDL %d x %d\n", mGuestXRes,  mGuestYRes));
     684        LogFlow(("VBoxSDL:: using SDL_SWSURFACE\n"));
    796685    }
    797686    LogFlow(("VBoxSDL:: created VRAM surface %p\n", mSurfVRAM));
    798687
    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    {
    805690        mfSameSizeRequested = false;
    806691        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    }
    818698
    819699    /* Enable screen updates. */
     
    1045925                     ((mScreen->flags & SDL_HWSURFACE) == 0) ? "software" : "hardware");
    1046926    }
    1047     repaint();
    1048927}
    1049928
     
    11811060    /* only change the SDL resolution, do not touch the guest framebuffer */
    11821061    resizeSDL();
     1062    repaint();
    11831063}
    11841064
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette