diff options
| author | Rye Cogtail <rye@lindenlab.com> | 2024-09-29 03:19:43 -0400 | 
|---|---|---|
| committer | Erik Kundiman <erik@megapahit.org> | 2025-05-28 23:25:10 +0800 | 
| commit | 643e3d13dda050e20ae4535f67f99a134d53419a (patch) | |
| tree | 85075b2eb2e183821ab507162342e671a8d3308e | |
| parent | 300e52d800112fab9f0137d067e9117bb2f9bba8 (diff) | |
Clean up SDL window creation and fix various bugs
Add support for Core and Debug GL context creation
Fix window position support
Fix vsync handling
Add minimum GL context support
| -rw-r--r-- | indra/llwindow/llwindow.cpp | 2 | ||||
| -rw-r--r-- | indra/llwindow/llwindowsdl.cpp | 283 | ||||
| -rw-r--r-- | indra/llwindow/llwindowsdl.h | 2 | 
3 files changed, 152 insertions, 135 deletions
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 302d038a79..4f3cc69c75 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -421,7 +421,7 @@ LLWindow* LLWindowManager::createWindow(              fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth);  #elif LL_SDL          new_window = new LLWindowSDL(callbacks, -            title, x, y, width, height, flags, +            title, name, x, y, width, height, flags,              fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);  #elif LL_WINDOWS          new_window = new LLWindowWin32(callbacks, diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 982f10503e..3495b8347d 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -153,7 +153,7 @@ Display* LLWindowSDL::get_SDL_Display(void)  #endif // LL_X11  LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, -                         const std::string& title, S32 x, S32 y, S32 width, +                         const std::string& title, const std::string& name, S32 x, S32 y, S32 width,                           S32 height, U32 flags,                           bool fullscreen, bool clearBg,                           bool enable_vsync, bool use_gl, @@ -191,7 +191,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,      mOriginalAspectRatio = 1024.0 / 768.0;      if (title.empty()) -        mWindowTitle = "SDL Window";  // *FIX: (?) +        mWindowTitle = "Second Life";      else          mWindowTitle = title; @@ -488,6 +488,10 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b          width = 1024;      if (height == 0)          width = 768; +    if (x == 0) +        x = SDL_WINDOWPOS_UNDEFINED; +    if (y == 0) +        y = SDL_WINDOWPOS_UNDEFINED;      mFullscreen = fullscreen; @@ -503,23 +507,22 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b      mSDLFlags = sdlflags; +    // Setup default backing colors      GLint redBits{8}, greenBits{8}, blueBits{8}, alphaBits{8}; -      GLint depthBits{(bits <= 16) ? 16 : 24}, stencilBits{8};      if (getenv("LL_GL_NO_STENCIL"))          stencilBits = 0; -    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, alphaBits);      SDL_GL_SetAttribute(SDL_GL_RED_SIZE,   redBits);      SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, greenBits);      SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,  blueBits); -    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits ); +    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, alphaBits); +    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits);      // We need stencil support for a few (minor) things.      if (stencilBits)          SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits); -    // *FIX: try to toggle vsync here?      SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);  #if LL_DARWIN @@ -531,30 +534,51 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b      SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); -    if (mFSAASamples > 0) +    if (LLRender::sGLCoreProfile)      { -        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); -        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, mFSAASamples); +        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);      } +    // This is requesting a minimum context version +    int major_gl_version = 3; +    int minor_gl_version = 2; +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major_gl_version); +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor_gl_version); + +    U32 context_flags = 0; +    if (gDebugGL) +    { +        context_flags |= SDL_GL_CONTEXT_DEBUG_FLAG; +    } +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, context_flags);      SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); -    mWindow = SDL_CreateWindow( mWindowTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, mSDLFlags ); -    if( mWindow ) +    // Create the window +    mWindow = SDL_CreateWindow(mWindowTitle.c_str(), x, y, width, height, mSDLFlags); +    if (mWindow == nullptr)      { -        mContext = SDL_GL_CreateContext( mWindow ); +        LL_WARNS() << "Window creation failure. SDL: " << SDL_GetError() << LL_ENDL; +        setupFailure("Window creation error", "Error", OSMB_OK); +        return FALSE; +    } -        if( mContext == 0 ) -        { -            LL_WARNS() << "Cannot create GL context " << SDL_GetError() << LL_ENDL; -            setupFailure("GL Context creation error creation error", "Error", OSMB_OK); -            return false; -        } -        // SDL_GL_SetSwapInterval(1); +    // Create the context +    mContext = SDL_GL_CreateContext(mWindow); +    if(!mContext) +    { +        LL_WARNS() << "Cannot create GL context " << SDL_GetError() << LL_ENDL; +        setupFailure("GL Context creation error", "Error", OSMB_OK); +        return false;      } +    if (SDL_GL_MakeCurrent(mWindow, mContext) != 0) +    { +        LL_WARNS() << "Failed to make context current. SDL: " << SDL_GetError() << LL_ENDL; +        setupFailure("GL Context failed to set current failure", "Error", OSMB_OK); +        return FALSE; +    } -    if( mFullscreen ) +    if(mFullscreen)      {          if (mWindow)          { @@ -598,70 +622,6 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b          }      } -    // Set the application icon. -    SDL_Surface *bmpsurface; -    bmpsurface = Load_BMP_Resource("ll_icon.BMP"); -    if (bmpsurface) -    { -        SDL_SetWindowIcon(mWindow, bmpsurface); -        SDL_FreeSurface(bmpsurface); -        bmpsurface = NULL; -    } - -    // Detect video memory size. -# if LL_X11 -    gGLManager.mVRAM = x11_detect_VRAM_kb() / 1024; -    if (gGLManager.mVRAM != 0) -    { -        LL_INFOS() << "X11 log-parser detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; -    } else -    { -        PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC queryInteger; -        queryInteger = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) -            glXGetProcAddressARB((const GLubyte *)"glXQueryCurrentRendererIntegerMESA"); -        unsigned int vram_megabytes = 0; -        queryInteger(GLX_RENDERER_VIDEO_MEMORY_MESA, &vram_megabytes); -        if (!vram_megabytes) { -            glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, (int *)&vram_megabytes); -            vram_megabytes /= 1024; -        } -        if (!vram_megabytes) { -            glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, (int *)&vram_megabytes); -            vram_megabytes /= 1024; -        } -        gGLManager.mVRAM = vram_megabytes; -    } -#elif LL_DARWIN -    CGLRendererInfoObj info = 0; -    GLint vram_megabytes = 0; -    int num_renderers = 0; -    auto err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), -        &info, &num_renderers); -    if (!err) { -        CGLDescribeRenderer(info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes); -        CGLDestroyRendererInfo(info); -    } else -        vram_megabytes = 256; -    gGLManager.mVRAM = vram_megabytes; -# endif // LL_X11 -/* -    { -        // fallback to letting SDL detect VRAM. -        // note: I've not seen SDL's detection ever actually find -        // VRAM != 0, but if SDL *does* detect it then that's a bonus. -        gGLManager.mVRAM = 0; -        if (gGLManager.mVRAM != 0) -        { -            LL_INFOS() << "SDL detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; -        } -    } -*/ -    // If VRAM is not detected, that is handled later - -    // *TODO: Now would be an appropriate time to check for some -    // explicitly unsupported cards. -    //const char* RENDERER = (const char*) glGetString(GL_RENDERER); -      SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits);      SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits);      SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits); @@ -697,6 +657,20 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b  #endif      } +    LL_PROFILER_GPU_CONTEXT; + +    // Enable vertical sync +    toggleVSync(enable_vsync); + +    // Set the application icon. +    SDL_Surface* bmpsurface = Load_BMP_Resource("ll_icon.BMP"); +    if (bmpsurface) +    { +        SDL_SetWindowIcon(mWindow, bmpsurface); +        SDL_FreeSurface(bmpsurface); +        bmpsurface = NULL; +    } +  #if LL_X11      /* Grab the window manager specific information */      SDL_SysWMinfo info; @@ -722,6 +696,58 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b      }  #endif // LL_X11 +    // Detect video memory size. +# if LL_X11 +    gGLManager.mVRAM = x11_detect_VRAM_kb() / 1024; +    if (gGLManager.mVRAM != 0) +    { +        LL_INFOS() << "X11 log-parser detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; +    } else +    { +        PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC queryInteger; +        queryInteger = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXQueryCurrentRendererIntegerMESA"); +        unsigned int vram_megabytes = 0; +        queryInteger(GLX_RENDERER_VIDEO_MEMORY_MESA, &vram_megabytes); +        if (!vram_megabytes) +        { +            glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, (int *)&vram_megabytes); +            vram_megabytes /= 1024; +        } +        if (!vram_megabytes) +        { +            glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, (int *)&vram_megabytes); +            vram_megabytes /= 1024; +        } +        gGLManager.mVRAM = vram_megabytes; +    } +#elif LL_DARWIN +    CGLRendererInfoObj info = 0; +    GLint vram_megabytes = 0; +    int num_renderers = 0; +    auto err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), +        &info, &num_renderers); +    if (!err) +    { +        CGLDescribeRenderer(info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes); +        CGLDestroyRendererInfo(info); +    } +    else +    { +        vram_megabytes = 256; +    } +    gGLManager.mVRAM = vram_megabytes; +# endif // LL_X11 +    { +        // fallback to letting SDL detect VRAM. +        // note: I've not seen SDL's detection ever actually find +        // VRAM != 0, but if SDL *does* detect it then that's a bonus. +        gGLManager.mVRAM = 0; +        if (gGLManager.mVRAM != 0) +        { +            LL_INFOS() << "SDL detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; +        } +    } +    // If VRAM is not detected, that is handled later      SDL_StartTextInput();      //make sure multisampling is disabled by default @@ -733,6 +759,45 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b      return true;  } +void* LLWindowSDL::createSharedContext() +{ +    SDL_GLContext pContext = SDL_GL_CreateContext(mWindow); +    if (pContext) +    { +        LL_DEBUGS() << "Creating shared OpenGL context successful!" << LL_ENDL; +        return (void*)pContext; +    } + +    LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL; +    return nullptr; +} + +void LLWindowSDL::makeContextCurrent(void* contextPtr) +{ +    SDL_GL_MakeCurrent(mWindow, contextPtr); +    LL_PROFILER_GPU_CONTEXT; +} + +void LLWindowSDL::destroySharedContext(void* contextPtr) +{ +    SDL_GL_DeleteContext(contextPtr); +} + +void LLWindowSDL::toggleVSync(bool enable_vsync) +{ +    if (!enable_vsync) +    { +        LL_INFOS("Window") << "Disabling vertical sync" << LL_ENDL; +        SDL_GL_SetSwapInterval(0); +        SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"0",SDL_HINT_OVERRIDE); +    } +    else +    { +        LL_INFOS("Window") << "Enabling vertical sync" << LL_ENDL; +        SDL_GL_SetSwapInterval(1); +        SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"1",SDL_HINT_OVERRIDE); +    } +}  // changing fullscreen resolution, or switching between windowed and fullscreen mode.  bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool enable_vsync, const LLCoordScreen * const posp) @@ -745,7 +810,7 @@ bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool      if(needsRebuild)      {          destroyContext(); -        result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, enable_vsync); +        result = createContext(0, 0, size.mX, size.mY, 32, fullscreen, enable_vsync);          if (result)          {              gGLManager.initGL(); @@ -2398,54 +2463,6 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()      return rtns;  } - -void* LLWindowSDL::createSharedContext() -{ -    auto *pContext = SDL_GL_CreateContext(mWindow); -    if ( pContext) -    { -        SDL_GL_SetSwapInterval(0); -        SDL_GL_MakeCurrent(mWindow, mContext); - -        LLCoordScreen size; -        if (getSize(&size)) -            setSize(size); - -        LL_DEBUGS() << "Creating shared OpenGL context successful!" << LL_ENDL; - -        return (void*)pContext; -    } - -    LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL; - -    return nullptr; -} - -void LLWindowSDL::makeContextCurrent(void* contextPtr) -{ -    LL_PROFILER_GPU_CONTEXT; -    SDL_GL_MakeCurrent( mWindow, contextPtr ); -} - -void LLWindowSDL::destroySharedContext(void* contextPtr) -{ -    SDL_GL_DeleteContext( contextPtr ); -} - -void LLWindowSDL::toggleVSync(bool enable_vsync) -{ -    if( !enable_vsync) -    { -        SDL_GL_SetSwapInterval(0); -        SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"0",SDL_HINT_OVERRIDE); -    } -    else -    { -        SDL_GL_SetSwapInterval(1); -        SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"1",SDL_HINT_OVERRIDE); -    } -} -  void LLWindowSDL::setLanguageTextInput(const LLCoordGL& position)  {      LLCoordWindow win_pos; diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index f86a277391..144216f658 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -219,7 +219,7 @@ public:  protected:      LLWindowSDL(LLWindowCallbacks *callbacks, -                const std::string &title, int x, int y, int width, int height, U32 flags, +                const std::string &title, const std::string& name, int x, int y, int width, int height, U32 flags,                  bool fullscreen, bool clearBg, bool enable_vsync, bool use_gl,                  bool ignore_pixel_depth, U32 fsaa_samples);  | 
