diff options
Diffstat (limited to 'indra/llwindow')
| -rw-r--r-- | indra/llwindow/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/llwindow/llsdl.cpp | 2 | ||||
| -rw-r--r-- | indra/llwindow/llwindowsdl.cpp | 146 | ||||
| -rw-r--r-- | indra/llwindow/llwindowsdl.h | 38 | ||||
| -rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 17 | ||||
| -rw-r--r-- | indra/llwindow/llwindowwin32.h | 3 |
6 files changed, 185 insertions, 23 deletions
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 1f846de35d..aacaef9257 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -160,7 +160,7 @@ if (BUILD_HEADLESS) ${llwindowheadless_HEADER_FILES} ) - target_compile_definitions( llwindowheadless PUBLIC LL_MESA=1 LL_MESA_HEADLESS=1 ) + target_compile_definitions( llwindowheadless PUBLIC LL_MESA_HEADLESS=1 ) target_link_libraries (llwindowheadless llcommon diff --git a/indra/llwindow/llsdl.cpp b/indra/llwindow/llsdl.cpp index c97356ee80..d0a7552647 100644 --- a/indra/llwindow/llsdl.cpp +++ b/indra/llwindow/llsdl.cpp @@ -64,10 +64,12 @@ void sdl_logger(void *userdata, int category, SDL_LogPriority priority, const ch void init_sdl(const std::string& app_name) { +#ifndef LL_SDL_APP if (!gSDLMainHandled) { SDL_SetMainReady(); } +#endif SDL_SetLogOutputFunction(&sdl_logger, nullptr); diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 57110f8634..3fc0257a7f 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -40,11 +40,11 @@ #include "llpreeditor.h" #include "llsdl.h" +#if LL_LINUX #ifdef LL_GLIB #include <glib.h> #endif -#if LL_LINUX extern "C" { # include "fontconfig/fontconfig.h" } @@ -55,6 +55,13 @@ extern "C" { #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> + +#if LL_X11 +LLWindowSDL::X11_DATA LLWindowSDL::sX11Data = {}; +#endif +#if LL_WAYLAND +LLWindowSDL::WAYLAND_DATA LLWindowSDL::sWaylandData = {}; +#endif #endif // LL_LINUX #if LL_DARWIN @@ -224,31 +231,28 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GLContextFlag context_flags{}; if(LLRender::sGLCoreProfile) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); #if LL_DARWIN - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + context_flags |= SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG; #endif - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); } - SDL_GLContextFlag context_flags{}; if (gDebugGL) { context_flags |= SDL_GL_CONTEXT_DEBUG_FLAG; } -#if LL_DARWIN - context_flags |= SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG; -#endif SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, context_flags); SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); if(mFullscreen) { - tryFindFullscreenSize( width, height ); + tryFindFullscreenSize(width, height); } SDL_PropertiesID props = SDL_CreateProperties(); @@ -268,6 +272,7 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b { LL_WARNS() << "Window creation failure. SDL: " << SDL_GetError() << LL_ENDL; setupFailure("Window creation error", "Error", OSMB_OK); + SDL_DestroyProperties(props); return false; } SDL_DestroyProperties(props); // Free properties once window is created @@ -322,6 +327,52 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b mRefreshRate = DEFAULT_REFRESH_RATE; } + /* Grab the window manager specific information */ +#if LL_LINUX + if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) + { + LL_INFOS() << "Running under X11" << LL_ENDL; + mServerProtocol = X11; + + gGLManager.mIsX11 = true; + +#if LL_X11 + sX11Data.xdisplay = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr); + sX11Data.xwindow = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); + sX11Data.xscreen = (int)SDL_GetNumberProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_X11_SCREEN_NUMBER, -1); + if (sX11Data.xdisplay && sX11Data.xwindow) + { + + } +#endif + + gGLManager.initGLX(); + } + else if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) + { + LL_INFOS() << "Running under Wayland" << LL_ENDL; + mServerProtocol = Wayland; + + gGLManager.mIsWayland = true; + +#if LL_WAYLAND + sWaylandData.display = (struct wl_display *)SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nullptr); + sWaylandData.surface = (struct wl_surface *)SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr); + if (sWaylandData.display && sWaylandData.surface) + { + } +#endif + + gGLManager.initEGL(); + + // If set (XWayland) remove DISPLAY, this will prompt dullahan to also use Wayland + if(getenv("DISPLAY")) + { + unsetenv("DISPLAY"); + } + } +#endif + SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits); @@ -378,29 +429,65 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b void* LLWindowSDL::createSharedContext() { - SDL_GLContext pContext = SDL_GL_CreateContext(mWindow); - if (pContext) + SDL_PropertiesID props = SDL_CreateProperties(); + SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, "Second Life OSR Utility"); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, 1); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, 1); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, false); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIDDEN_BOOLEAN, true); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN, false); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_UTILITY_BOOLEAN, true); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, gHiDPISupport); + + auto osr_window = SDL_CreateWindowWithProperties(props); + if (osr_window == nullptr) + { + SDL_DestroyProperties(props); + return nullptr; + } + SDL_DestroyProperties(props); // Free properties once window is created + SDL_GLContext pContext = SDL_GL_CreateContext(osr_window); + + // Hack to ensure main window context is bound + SDL_GL_MakeCurrent(mWindow, mContext); + + if (!pContext) + { + LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL; + SDL_DestroyWindow(osr_window); + return nullptr; + } + { - // HACK to ensure windows GL context is set correctly when threaded - Rye - SDL_GL_MakeCurrent(mWindow, pContext); - SDL_GL_MakeCurrent(mWindow, mContext); - LL_DEBUGS() << "Creating shared OpenGL context successful!" << LL_ENDL; - return (void*)pContext; + LLMutexLock osr_lock(&mOSRMutex); + mOSRContexts.emplace(pContext, osr_window); } - LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL; - return nullptr; + LL_DEBUGS() << "Creating shared OpenGL context successful!" << LL_ENDL; + return (void*)pContext; } void LLWindowSDL::makeContextCurrent(void* contextPtr) { - SDL_GL_MakeCurrent(mWindow, (SDL_GLContext)contextPtr); + LLMutexLock osr_lock(&mOSRMutex); + auto it = mOSRContexts.find((SDL_GLContext)contextPtr); + if(it != mOSRContexts.end()) + { + SDL_GL_MakeCurrent((SDL_Window*)it->second, (SDL_GLContext)it->first); + } LL_PROFILER_GPU_CONTEXT; } void LLWindowSDL::destroySharedContext(void* contextPtr) { - SDL_GL_DestroyContext((SDL_GLContext)contextPtr); + LLMutexLock osr_lock(&mOSRMutex); + auto it = mOSRContexts.find((SDL_GLContext)contextPtr); + if(it != mOSRContexts.end()) + { + SDL_GL_DestroyContext((SDL_GLContext)it->first); + mDeadOSRWindows.push_back((SDL_Window*)it->second); + } } void LLWindowSDL::toggleVSync(bool enable_vsync) @@ -449,6 +536,15 @@ void LLWindowSDL::destroyContext() { LL_INFOS() << "destroyContext begins" << LL_ENDL; + { + LLMutexLock osr_lock(&mOSRMutex); + for(SDL_Window* pWindow : mDeadOSRWindows) + { + SDL_DestroyWindow(pWindow); + } + mDeadOSRWindows.clear(); + } + // Stop unicode input SDL_StopTextInput(mWindow); @@ -1114,6 +1210,14 @@ U32 LLWindowSDL::SDLCheckGrabbyKeys(U32 keysym, bool gain) // virtual void LLWindowSDL::processMiscNativeEvents() { + { + LLMutexLock osr_lock(&mOSRMutex); + for(SDL_Window* pWindow : mDeadOSRWindows) + { + SDL_DestroyWindow(pWindow); + } + mDeadOSRWindows.clear(); + } } void LLWindowSDL::gatherInput() diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 966999ac12..4d4a7a5f65 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -31,10 +31,20 @@ #include "llwindow.h" #include "lltimer.h" +#include "llmutex.h" #include "SDL3/SDL.h" #include "SDL3/SDL_endian.h" +#ifdef LL_WAYLAND +#include <wayland-client-protocol.h> +#endif + +#if LL_X11 +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#endif + class LLPreeditor; class LLWindowSDL final : public LLWindow @@ -216,7 +226,35 @@ private: U32 mKeyVirtualKey = 0; U32 mKeyModifiers = SDL_KMOD_NONE; + LLMutex mOSRMutex; + std::unordered_map<SDL_GLContext, SDL_Window*> mOSRContexts; + std::list<SDL_Window*> mDeadOSRWindows; + void tryFindFullscreenSize(int &aWidth, int &aHeight); + + enum EServerProtocol{ X11, Wayland, Unknown }; + EServerProtocol mServerProtocol = Unknown; +public: +#if LL_X11 + // X11 + struct X11_DATA + { + Display* xdisplay = nullptr; + Window xwindow = 0; + int xscreen = -1; + }; + static X11_DATA sX11Data; +#endif + +#if LL_WAYLAND + // Wayland + struct WAYLAND_DATA + { + struct wl_display* display = nullptr; + struct wl_surface* surface = nullptr; + }; + static WAYLAND_DATA sWaylandData; +#endif }; class LLSplashScreenSDL : public LLSplashScreen diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 824d0f5ec6..011cb0ed9d 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -204,6 +204,7 @@ HKL LLWindowWin32::sWinInputLocale = 0; DWORD LLWindowWin32::sWinIMEConversionMode = IME_CMODE_NATIVE; DWORD LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC; LLCoordWindow LLWindowWin32::sWinIMEWindowPosition(-1,-1); +HMODULE LLWindowWin32::sGLDLLHandle = nullptr; static HWND sWindowHandleForMessageBox = NULL; @@ -458,7 +459,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, mWindowThread = new LLWindowWin32Thread(); //MAINT-516 -- force a load of opengl32.dll just in case windows went sideways - LoadLibrary(L"opengl32.dll"); + sGLDLLHandle = LoadLibrary(L"opengl32.dll"); if (mMaxCores != 0) @@ -1690,6 +1691,8 @@ const S32 max_format = (S32)num_formats - 1; return false; } + gGLManager.initWGL(); // Reinit WGL functions once we have our full context + if (!gGLManager.initGL()) { LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); @@ -4660,6 +4663,18 @@ F32 LLWindowWin32::getSystemUISize() } //static +PROC WINAPI LLWindowWin32::getProcAddress(const char* func) +{ + PROC ret_func = wglGetProcAddress(func); + if (!ret_func && sGLDLLHandle) + { + // Try to fallback to OpenGL32.dll + ret_func = GetProcAddress(sGLDLLHandle, func); + } + return ret_func; +} + +//static std::vector<std::string> LLWindowWin32::getDisplaysResolutionList() { return sMonitorInfo.getResolutionsList(); diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 0fc93ad0b1..77217747cc 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -125,6 +125,7 @@ public: LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); + static PROC WINAPI getProcAddress(const char* func); static std::vector<std::string> getDisplaysResolutionList(); static std::vector<std::string> getDynamicFallbackFontList(); static void setDPIAwareness(); @@ -244,6 +245,8 @@ protected: bool mMouseVanish; + static HMODULE sGLDLLHandle; + // Cached values of GetWindowRect and GetClientRect to be used by app thread void updateWindowRect(); RECT mRect; |
