VirtualBox

Ignore:
Timestamp:
Oct 25, 2019 11:46:30 AM (5 years ago)
Author:
vboxsync
Message:

FE/VBoxSDL: Added first support for SDL2 (by setting VBOX_WITH_SDL2). Very rough / hacky by now and needs more testing first before enabling by default. Also fixed non-starting with SDL 1.2.x on Windows hosts.

Known limitations / todos when running with SDL 2 for now:

  • No alpha channel support for cursors.
  • No mouse wheel support.
  • Desktop geometry handling needs a revamp for multi monitor setups.
  • Check / revamp dirty rectangle blitting.
  • OpenGL renderer needs testing wrt texture blitting.
File:
1 edited

Legend:

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

    r77370 r81537  
    113113                     bool fUpdateImage)
    114114{
    115     int rc;
    116115    LogFlow(("VBoxSDLFB::VBoxSDLFB\n"));
    117116
     
    119118    mfUpdateImage   = fUpdateImage;
    120119    mScreen         = NULL;
    121 #ifdef VBOX_WITH_SDL13
    122     mWindow         = 0;
    123     mTexture        = 0;
     120#ifdef VBOX_WITH_SDL2
     121    mpWindow        = NULL;
     122    mpTexture       = NULL;
     123    mpRenderer      = NULL;
    124124#endif
    125125    mSurfVRAM       = NULL;
     
    150150    mfUpdates = false;
    151151
    152     rc = RTCritSectInit(&mUpdateLock);
     152    int rc = RTCritSectInit(&mUpdateLock);
    153153    AssertMsg(rc == VINF_SUCCESS, ("Error from RTCritSectInit!\n"));
    154154
     
    161161#endif
    162162
    163     return 0;
     163#ifdef VBOX_WITH_SDL2
     164    rc = SDL_GetRendererInfo(mpRenderer, &mRenderInfo);
     165    if (RT_SUCCESS(rc))
     166    {
     167        if (fShowSDLConfig)
     168            RTPrintf("Render info:\n"
     169                     "  Name:                    %s\n"
     170                     "  Render flags:            0x%x\n"
     171                     "  SDL video driver:        %s\n",
     172                     mRenderInfo.name,
     173                     mRenderInfo.flags,
     174                     RTEnvGet("SDL_VIDEODRIVER"));
     175    }
     176#endif
     177
     178    return rc;
    164179}
    165180
     
    184199}
    185200
     201/* static */
    186202bool VBoxSDLFB::init(bool fShowSDLConfig)
    187203{
     
    195211    if (!RTEnvExist("SDL_VIDEODRIVER"))
    196212    {
    197         _putenv("SDL_VIDEODRIVER=directx");
    198 //        _putenv("SDL_VIDEODRIVER=windib");
     213# ifndef VBOX_WITH_SDL2
     214        /* Always select the windib driver by default, as the directx one is known to be broken on newer Windows OSes. */
     215        RTEnvSet("SDL_VIDEODRIVER", "windib");
     216# else
     217        RTEnvSet("SDL_VIDEODRIVER", "directx");
     218# endif
    199219    }
    200220#endif
     
    204224    RTEnvSet("SDL_VIDEO_X11_DGAMOUSE", "0");
    205225#endif
     226
    206227    int rc = SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE);
    207228    if (rc != 0)
     
    212233    gfSdlInitialized = true;
    213234
     235#ifdef VBOX_WITH_SDL2
     236    RT_NOREF(fShowSDLConfig);
     237#else
    214238    const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
    215     Assert(videoInfo);
     239    AssertPtr(videoInfo);
    216240    if (videoInfo)
    217241    {
     
    244268                         RTEnvGet("SDL_VIDEODRIVER"));
    245269    }
    246 
    247     if (12320 == g_cbIco64x01)
    248     {
    249         gWMIcon = SDL_AllocSurface(SDL_SWSURFACE, 64, 64, 24, 0xff, 0xff00, 0xff0000, 0);
    250         /** @todo make it as simple as possible. No PNM interpreter here... */
    251         if (gWMIcon)
    252         {
    253             memcpy(gWMIcon->pixels, g_abIco64x01+32, g_cbIco64x01-32);
    254             SDL_WM_SetIcon(gWMIcon, NULL);
    255         }
    256     }
     270#endif /* !VBOX_WITH_SDL2 */
     271
     272#ifndef VBOX_WITH_SDL2
     273    gWMIcon = SDL_AllocSurface(SDL_SWSURFACE, 64, 64, 24, 0xff, 0xff00, 0xff0000, 0);
     274    /** @todo make it as simple as possible. No PNM interpreter here... */
     275    if (gWMIcon)
     276    {
     277        memcpy(gWMIcon->pixels, g_abIco64x01+32, g_cbIco64x01-32);
     278        SDL_WM_SetIcon(gWMIcon, NULL);
     279    }
     280#endif
    257281
    258282    return true;
     
    270294        AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
    271295        SDL_QuitSubSystem(SDL_INIT_VIDEO);
     296
     297#ifndef VBOX_WITH_SDL2
    272298        if (gWMIcon)
    273299        {
     
    275301            gWMIcon = NULL;
    276302        }
     303#endif
    277304    }
    278305}
     
    581608        /* nope, we don't want that (but still don't freak out if it is set) */
    582609#ifdef DEBUG
    583         printf("VBoxSDL::VideoModeSupported: we refused mode %dx%dx%d\n", width, height, bpp);
     610        RTPrintf("VBoxSDL::VideoModeSupported: we refused mode %dx%dx%d\n", width, height, bpp);
    584611#endif
    585612        *supported = false;
     
    770797{
    771798    LogFlow(("VBoxSDL:resizeSDL\n"));
     799
     800#ifdef VBOX_WITH_SDL2
     801    const int cDisplays = SDL_GetNumVideoDisplays();
     802    if (cDisplays > 0)
     803    {
     804        for (int d = 0; d < cDisplays; d++)
     805        {
     806            const int cDisplayModes = SDL_GetNumDisplayModes(d);
     807            for (int m = 0; m < cDisplayModes; m++)
     808            {
     809                SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 };
     810                if (SDL_GetDisplayMode(d, m, &mode) != 0)
     811                {
     812                    RTPrintf("Display #%d, mode %d:\t\t%i bpp\t%i x %i",
     813                             SDL_BITSPERPIXEL(mode.format), mode.w, mode.h);
     814                }
     815
     816                if (m == 0)
     817                {
     818                    /*
     819                     * according to the SDL documentation, the API guarantees that
     820                     * the modes are sorted from larger to smaller, so we just
     821                     * take the first entry as the maximum.
     822                     */
     823                    mMaxScreenWidth  = mode.w;
     824                    mMaxScreenHeight = mode.h;
     825                }
     826
     827                /* Keep going. */
     828            }
     829        }
     830    }
     831    else
     832        AssertFailed(); /** @todo */
     833#else
    772834
    773835    /*
     
    814876        mMaxScreenHeight = ~(uint32_t)0;
    815877    }
     878#endif /* VBOX_WITH_SDL2 */
    816879
    817880    uint32_t newWidth;
     
    841904    mTopOffset = 0;
    842905
    843 #if defined(VBOX_WITH_SDL13)
     906#ifdef VBOX_WITH_SDL2
    844907    int sdlWindowFlags = SDL_WINDOW_SHOWN;
    845908    if (mfResizable)
    846909        sdlWindowFlags |= SDL_WINDOW_RESIZABLE;
    847     if (!mWindow)
     910    if (!mpWindow)
    848911    {
    849912        SDL_DisplayMode desktop_mode;
     
    851914        int y = 40 + mScreenId * 15;
    852915
    853         SDL_GetDesktopDisplayMode(&desktop_mode);
     916        SDL_GetDesktopDisplayMode(mScreenId, &desktop_mode);
    854917        /* create new window */
    855918
    856919        char szTitle[64];
    857920        RTStrPrintf(szTitle, sizeof(szTitle), "SDL window %d", mScreenId);
    858         mWindow = SDL_CreateWindow(szTitle, x, y,
     921        mpWindow = SDL_CreateWindow(szTitle, x, y,
    859922                                   newWidth, newHeight, sdlWindowFlags);
    860         if (SDL_CreateRenderer(mWindow, -1,
    861                                SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD) < 0)
     923        mpRenderer = SDL_CreateRenderer(mpWindow, -1, 0 /* SDL_RendererFlags */);
     924        if (mpRenderer)
     925        {
     926            SDL_GetRendererInfo(mpRenderer, &mRenderInfo);
     927
     928            mpTexture = SDL_CreateTexture(mpRenderer, desktop_mode.format,
     929                                          SDL_TEXTUREACCESS_STREAMING, newWidth, newHeight);
     930            if (!mpTexture)
     931                AssertReleaseFailed();
     932        }
     933        else
    862934            AssertReleaseFailed();
    863935
    864         SDL_GetRendererInfo(&mRenderInfo);
    865 
    866         mTexture = SDL_CreateTexture(desktop_mode.format,
    867                                      SDL_TEXTUREACCESS_STREAMING, newWidth, newHeight);
    868         if (!mTexture)
    869             AssertReleaseFailed();
     936        if (12320 == g_cbIco64x01)
     937        {
     938            gWMIcon = SDL_CreateRGBSurface(0 /* Flags, must be 0 */, 64, 64, 24, 0xff, 0xff00, 0xff0000, 0);
     939            /** @todo make it as simple as possible. No PNM interpreter here... */
     940            if (gWMIcon)
     941            {
     942                memcpy(gWMIcon->pixels, g_abIco64x01+32, g_cbIco64x01-32);
     943                SDL_SetWindowIcon(mpWindow, gWMIcon);
     944            }
     945        }
    870946    }
    871947    else
     
    876952
    877953        /* resize current window */
    878         SDL_GetWindowSize(mWindow, &w, &h);
     954        SDL_GetWindowSize(mpWindow, &w, &h);
    879955
    880956        if (w != (int)newWidth || h != (int)newHeight)
    881             SDL_SetWindowSize(mWindow, newWidth, newHeight);
    882 
    883         SDL_QueryTexture(mTexture, &format, &access, &w, &h);
    884         SDL_SelectRenderer(mWindow);
    885         SDL_DestroyTexture(mTexture);
    886         mTexture = SDL_CreateTexture(format, access, newWidth, newHeight);
    887         if (!mTexture)
     957            SDL_SetWindowSize(mpWindow, newWidth, newHeight);
     958
     959        SDL_QueryTexture(mpTexture, &format, &access, &w, &h);
     960        SDL_DestroyTexture(mpTexture);
     961        mpTexture = SDL_CreateTexture(mpRenderer, format, access, newWidth, newHeight);
     962        if (!mpTexture)
    888963            AssertReleaseFailed();
    889964    }
     
    895970    uint32_t format;
    896971
    897     if (SDL_QueryTexture(mTexture, &format, NULL, &w, &h) < 0)
     972    if (SDL_QueryTexture(mpTexture, &format, NULL, &w, &h) < 0)
    898973        AssertReleaseFailed();
    899974
     
    901976        AssertReleaseFailed();
    902977
    903     if (SDL_QueryTexturePixels(mTexture, &pixels, &pitch) == 0)
     978    if (SDL_LockTexture(mpTexture, NULL /* SDL_Rect */, &pixels, &pitch) == 0)
    904979    {
    905980        mScreen = SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch,
    906981                                           Rmask, Gmask, Bmask, Amask);
     982        SDL_UnlockTexture(mpTexture); /** @BUGBUG See: https://bugzilla.libsdl.org/show_bug.cgi?id=1586 */
    907983    }
    908984    else
     
    9331009    SDL_VERSION(&info.version);
    9341010    if (SDL_GetWMInfo(&info))
    935         mWinId = (LONG64) info.info.x11.wmwindow;
     1011        mWinId = (LONG64) info.info.x11.wmpWindow;
    9361012# elif defined(RT_OS_DARWIN)
    9371013    mWinId = (intptr_t)VBoxSDLGetDarwinWindowId();
     
    9391015    /* XXX ignore this for other architectures */
    9401016# endif
    941 #endif
     1017#endif /* VBOX_WITH_SDL2 */
    9421018#ifdef VBOX_SECURELABEL
    9431019    /*
     
    9711047            mCenterYOffset = (mFixedSDLHeight - (mGuestYRes + mLabelHeight)) / 2;
    9721048    }
    973 #endif
     1049#endif /* VBOX_SECURELABEL */
     1050
    9741051    AssertMsg(mScreen, ("Error: SDL_SetVideoMode failed!\n"));
    9751052    if (mScreen)
     
    9801057#endif
    9811058        if (mfShowSDLConfig)
    982             RTPrintf("Resized to %dx%d, screen surface type: %s\n", mScreen->w, mScreen->h,
    983                      ((mScreen->flags & SDL_HWSURFACE) == 0) ? "software" : "hardware");
     1059            RTPrintf("Resized to %dx%d\n", mScreen->w, mScreen->h);
    9841060    }
    9851061}
     
    10791155    SDL_BlitSurface(mSurfVRAM, &srcRect, mScreen, &dstRect);
    10801156    /* hardware surfaces don't need update notifications */
    1081 #if defined(VBOX_WITH_SDL13)
     1157#if defined(VBOX_WITH_SDL2)
    10821158    AssertRelease(mScreen->flags & SDL_PREALLOC);
    1083     SDL_SelectRenderer(mWindow);
    1084     SDL_DirtyTexture(mTexture, 1, &dstRect);
    1085     AssertRelease(mRenderInfo.flags & SDL_RENDERER_PRESENTCOPY);
    1086     SDL_RenderCopy(mTexture, &dstRect, &dstRect);
    1087     SDL_RenderPresent();
     1159    /** @todo Do we need to update the dirty rect for the texture for SDL2 here as well? */
     1160    SDL_RenderClear(mpRenderer);
     1161    SDL_RenderCopy(mpRenderer, mpTexture, &dstRect, &dstRect);
     1162    SDL_RenderPresent(mpRenderer);
    10881163#else
    10891164    if ((mScreen->flags & SDL_HWSURFACE) == 0)
     
    11311206void VBoxSDLFB::getFullscreenGeometry(uint32_t *width, uint32_t *height)
    11321207{
     1208#ifndef VBOX_WITH_SDL2
    11331209    SDL_Rect **modes;
    11341210
     
    11591235        }
    11601236    }
    1161 }
     1237#else
     1238    SDL_DisplayMode dm;
     1239    int rc = SDL_GetDesktopDisplayMode(0, &dm); /** @BUGBUG Handle multi monitor setups! */
     1240    if (rc == 0)
     1241    {
     1242        *width  = dm.w;
     1243        *height = dm.w;
     1244    }
     1245#endif
     1246}
     1247
     1248#ifdef VBOX_WITH_SDL2
     1249int VBoxSDLFB::setWindowTitle(const char *pcszTitle)
     1250{
     1251    SDL_SetWindowTitle(mpWindow, pcszTitle);
     1252
     1253    return VINF_SUCCESS;
     1254}
     1255#endif
    11621256
    11631257#ifdef VBOX_SECURELABEL
     
    13021396HRESULT VBoxSDLFBOverlay::init()
    13031397{
    1304     mBlendedBits = SDL_CreateRGBSurface(SDL_ANYFORMAT, mOverlayWidth, mOverlayHeight, 32,
     1398#ifndef VBOX_WITH_SDL2
     1399    Uint32 fFlags = SDL_ANYFORMAT;
     1400#else
     1401    Uint32 fFlags = 0;
     1402#endif
     1403
     1404    mBlendedBits = SDL_CreateRGBSurface(fFlags, mOverlayWidth, mOverlayHeight, 32,
    13051405                                        0x00ff0000, 0x0000ff00, 0x000000ff, 0);
    13061406    AssertMsgReturn(mBlendedBits != NULL, ("Failed to create an SDL surface\n"),
    13071407                    E_OUTOFMEMORY);
    1308     mOverlayBits = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, mOverlayWidth,
     1408
     1409#ifndef VBOX_WITH_SDL2
     1410    fFlags = SDL_SWSURFACE | SDL_SRCALPHA, mOverlayWidth;
     1411#else
     1412    fFlags = 0;
     1413#endif
     1414
     1415    mOverlayBits = SDL_CreateRGBSurface(fFlags,
    13091416                                        mOverlayHeight, 32, 0x00ff0000, 0x0000ff00,
    1310                                         0x000000ff, 0xff000000);
     1417                                        0x000000ff, 0xff000000, 0);
    13111418    AssertMsgReturn(mOverlayBits != NULL, ("Failed to create an SDL surface\n"),
    13121419                    E_OUTOFMEMORY);
     
    16171724    mOverlayHeight = h;
    16181725    SDL_FreeSurface(mOverlayBits);
    1619     mBlendedBits = SDL_CreateRGBSurface(SDL_ANYFORMAT, mOverlayWidth, mOverlayHeight, 32,
     1726
     1727#ifndef VBOX_WITH_SDL2
     1728    Uint32 fFlags = SDL_ANYFORMAT;
     1729#else
     1730    Uint32 fFlags = 0;
     1731#endif
     1732
     1733    mBlendedBits = SDL_CreateRGBSurface(fFlags, mOverlayWidth, mOverlayHeight, 32,
    16201734                                        0x00ff0000, 0x0000ff00, 0x000000ff, 0);
    16211735    AssertMsgReturn(mBlendedBits != NULL, ("Failed to create an SDL surface\n"),
    16221736                    E_OUTOFMEMORY);
    1623     mOverlayBits = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, mOverlayWidth,
     1737
     1738#ifndef VBOX_WITH_SDL2
     1739    fFlags = SDL_SWSURFACE | SDL_SRCALPHA;
     1740#else
     1741    fFlags = 0;
     1742#endif
     1743
     1744    mOverlayBits = SDL_CreateRGBSurface(fFlags, mOverlayWidth,
    16241745                                        mOverlayHeight, 32, 0x00ff0000, 0x0000ff00,
    16251746                                        0x000000ff, 0xff000000);
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