From d00272e0cc9974f35a46f0c313ee2c0e11cddbda Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 11 Oct 2021 16:03:40 +0000 Subject: SL-16099 Multi-threaded OpenGL usage on Windows, enable Core Profile and VAOs by default. --- indra/llwindow/llwindowheadless.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indra/llwindow/llwindowheadless.h') diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index c692666df1..a7ae28aa24 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -49,6 +49,9 @@ public: /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; + void* createSharedContext() { return nullptr; } + void makeContextCurrent(void*) {} + void destroySharedContext(void*) {} /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; /*virtual*/ void showCursor() {}; -- cgit v1.3 From 5553d614211998b5a10529f6b3ec68d2b25dc07a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 22 Oct 2021 17:01:33 +0000 Subject: SL-16203 Fix for wonky handling of mouse deltas. --- indra/llcommon/llsingleton.h | 1 + indra/llwindow/llwindow.h | 3 + indra/llwindow/llwindowheadless.h | 3 + indra/llwindow/llwindowwin32.cpp | 530 ++++++++++++++----------------------- indra/llwindow/llwindowwin32.h | 13 +- indra/newview/lldrawpoolavatar.cpp | 10 +- indra/newview/llviewerwindow.cpp | 7 + 7 files changed, 230 insertions(+), 337 deletions(-) (limited to 'indra/llwindow/llwindowheadless.h') diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 7c81d65a8b..2e43a3cbed 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -455,6 +455,7 @@ public: static DERIVED_TYPE* getInstance() { + LL_PROFILE_ZONE_SCOPED; // We know the viewer has LLSingleton dependency circularities. If you // feel strongly motivated to eliminate them, cheers and good luck. // (At that point we could consider a much simpler locking mechanism.) diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 0100c3bf0a..1384ddfd82 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -91,6 +91,9 @@ public: virtual BOOL setCursorPosition(LLCoordWindow position) = 0; virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; +#if LL_WINDOWS + virtual BOOL getCursorDelta(LLCoordCommon* delta) = 0; +#endif virtual void showCursor() = 0; virtual void hideCursor() = 0; virtual BOOL isCursorHidden() = 0; diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index a7ae28aa24..f8ba9bbed4 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -54,6 +54,9 @@ public: void destroySharedContext(void*) {} /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; +#if LL_WINDOWS + /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) { return FALSE; } +#endif /*virtual*/ void showCursor() {}; /*virtual*/ void hideCursor() {}; /*virtual*/ void showCursorFromMouseMove() {}; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 12d4c6c30e..bf78bcba29 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -28,8 +28,6 @@ #if LL_WINDOWS && !LL_MESA_HEADLESS -#define LL_WINDOW_SINGLE_THREADED 0 - #include "llwindowwin32.h" // LLWindow library includes @@ -85,7 +83,7 @@ extern BOOL gDebugWindowProc; static std::thread::id sWindowThreadId; static std::thread::id sMainThreadId; -#if 1 || LL_WINDOW_SINGLE_THREADED +#if 1 // flip to zero to enable assertions for functions being called from wrong thread #define ASSERT_MAIN_THREAD() #define ASSERT_WINDOW_THREAD() #else @@ -482,9 +480,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, { sMainThreadId = LLThread::currentID(); mWindowThread = new LLWindowWin32Thread(this); -#if !LL_WINDOW_SINGLE_THREADED mWindowThread->start(); -#endif //MAINT-516 -- force a load of opengl32.dll just in case windows went sideways LoadLibrary(L"opengl32.dll"); @@ -492,7 +488,6 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, mIconResource = gIconResource; mOverrideAspectRatio = 0.f; mNativeAspectRatio = 0.f; - mMousePositionModified = FALSE; mInputProcessingPaused = FALSE; mPreeditor = NULL; mKeyCharCode = 0; @@ -814,6 +809,13 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, initCursors(); setCursor( UI_CURSOR_ARROW ); + mRawMouse.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC + mRawMouse.usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE + mRawMouse.dwFlags = 0; // adds mouse and also ignores legacy mouse messages + mRawMouse.hwndTarget = 0; + + RegisterRawInputDevices(&mRawMouse, 1, sizeof(mRawMouse)); + // Initialize (boot strap) the Language text input management, // based on the system's (or user's) default settings. allowLanguageTextInput(NULL, FALSE); @@ -1927,31 +1929,26 @@ BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position) { ASSERT_MAIN_THREAD(); - if (!mWindowHandle) - { - return FALSE; - } + if (!mWindowHandle) + { + return FALSE; + } - // Inform the application of the new mouse position (needed for per-frame - // hover/picking to function). - mCallbacks->handleMouseMove(this, position.convert(), (MASK)0); - - mMousePositionModified = TRUE; LLCoordScreen screen_pos(position.convert()); - - mWindowThread->post([=] + + // instantly set the cursor position from the app's point of view + mCursorPosition = position; + mLastCursorPosition = position; + + // Inform the application of the new mouse position (needed for per-frame + // hover/picking to function). + mCallbacks->handleMouseMove(this, position.convert(), (MASK)0); + + // actually set the cursor position on the window thread + mWindowThread->post([=]() { + // actually set the OS cursor position SetCursorPos(screen_pos.mX, screen_pos.mY); - // DEV-18951 VWR-8524 Camera moves wildly when alt-clicking. - // Because we have preemptively notified the application of the new - // mouse position via handleMouseMove() above, we need to clear out - // any stale mouse move events. RN/JC - MSG msg; - while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) - { - } - - mMousePositionModified = FALSE; }); return TRUE; @@ -1960,19 +1957,27 @@ BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position) BOOL LLWindowWin32::getCursorPosition(LLCoordWindow *position) { ASSERT_MAIN_THREAD(); - POINT cursor_point; - - if (!mWindowHandle - || !GetCursorPos(&cursor_point) - || !position) - { - return FALSE; - } + if (!position) + { + return FALSE; + } - *position = LLCoordScreen(cursor_point.x, cursor_point.y).convert(); + *position = mCursorPosition; return TRUE; } +BOOL LLWindowWin32::getCursorDelta(LLCoordCommon* delta) +{ + if (delta == nullptr) + { + return FALSE; + } + + *delta = mMouseFrameDelta; + + return TRUE; +} + void LLWindowWin32::hideCursor() { ASSERT_MAIN_THREAD(); @@ -2153,34 +2158,31 @@ void LLWindowWin32::gatherInput() LL_PROFILE_ZONE_SCOPED MSG msg; -#if LL_WINDOW_SINGLE_THREADED - int msg_count = 0; - - while ((msg_count < MAX_MESSAGE_PER_UPDATE)) { - LL_PROFILE_ZONE_NAMED("gi - loop"); - ++msg_count; - { - LL_PROFILE_ZONE_NAMED("gi - PeekMessage"); - if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - break; - } - } + LLMutexLock lock(&mRawMouseMutex); + mMouseFrameDelta = mRawMouseDelta; - { - LL_PROFILE_ZONE_NAMED("gi - translate"); - TranslateMessage(&msg); - } + mRawMouseDelta.mX = 0; + mRawMouseDelta.mY = 0; + } - { - LL_PROFILE_ZONE_NAMED("gi - dispatch"); - DispatchMessage(&msg); - } + if (mWindowThread->mFunctionQueue.size() > 0) + { + LL_PROFILE_ZONE_NAMED("gi - PostMessage"); + if (mWindowHandle) + { // post a nonsense user message to wake up the Window Thread in case any functions are pending + // and no windows events came through this frame + PostMessage(mWindowHandle, WM_USER + 0x0017, 0xB0B0, 0x1337); + } + } + + while (mWindowThread->mMessageQueue.tryPopBack(msg)) + { + LL_PROFILE_ZONE_NAMED("gi - message queue"); if (mInputProcessingPaused) { - break; + continue; } // For async host by name support. Really hacky. @@ -2190,45 +2192,35 @@ void LLWindowWin32::gatherInput() gAsyncMsgCallback(msg); } } -#else //multi-threaded window impl + { - if (mWindowThread->mFunctionQueue.size() > 0) + LL_PROFILE_ZONE_NAMED("gi - function queue"); + //process any pending functions + std::function curFunc; + while (mFunctionQueue.tryPopBack(curFunc)) { - LL_PROFILE_ZONE_NAMED("gi - PostMessage"); - if (mWindowHandle) - { // post a nonsense user message to wake up the Window Thread in case any functions are pending - // and no windows events came through this frame - PostMessage(mWindowHandle, WM_USER + 0x0017, 0xB0B0, 0x1337); - } + curFunc(); } - - while (mWindowThread->mMessageQueue.tryPopBack(msg)) - { - LL_PROFILE_ZONE_NAMED("gi - message queue"); - if (mInputProcessingPaused) - { - continue; - } + } - // For async host by name support. Really hacky. - if (gAsyncMsgCallback && (LL_WM_HOST_RESOLVED == msg.message)) - { - LL_PROFILE_ZONE_NAMED("gi - callback"); - gAsyncMsgCallback(msg); - } - } + // send one and only one mouse move event per frame BEFORE handling mouse button presses + if (mLastCursorPosition != mCursorPosition) + { + LL_PROFILE_ZONE_NAMED("gi - mouse move"); + mCallbacks->handleMouseMove(this, mCursorPosition.convert(), mMouseMask); } + + mLastCursorPosition = mCursorPosition; { - LL_PROFILE_ZONE_NAMED("gi - function queue"); - //process any pending functions + LL_PROFILE_ZONE_NAMED("gi - mouse queue"); + // handle mouse button presses AFTER updating mouse cursor position std::function curFunc; - while (mFunctionQueue.tryPopBack(curFunc)) + while (mMouseQueue.tryPopBack(curFunc)) { curFunc(); } } -#endif mInputProcessingPaused = FALSE; @@ -2238,11 +2230,7 @@ void LLWindowWin32::gatherInput() static LLTrace::BlockTimerStatHandle FTM_KEYHANDLER("Handle Keyboard"); static LLTrace::BlockTimerStatHandle FTM_MOUSEHANDLER("Handle Mouse"); -#if LL_WINDOW_SINGLE_THREADED -#define WINDOW_IMP_POST(x) x -#else #define WINDOW_IMP_POST(x) window_imp->post([=]() { x; }) -#endif LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param) { @@ -2278,10 +2266,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // mouse is outside window. LLCoordWindow window_coord((S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)); - // This doesn't work, as LOWORD returns unsigned short. - //LLCoordWindow window_coord(LOWORD(l_param), HIWORD(l_param)); - LLCoordGL gl_coord; - // pass along extended flag in mask MASK mask = (l_param >> 16 & KF_EXTENDED) ? MASK_EXTENDED : 0x0; BOOL eat_keystroke = TRUE; @@ -2665,35 +2649,19 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONDOWN"); { LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - window_imp->post([=]() + window_imp->postMouseButtonEvent([=]() { - auto glc = gl_coord; sHandleLeftMouseUp = true; - + if (LLWinImm::isAvailable() && window_imp->mPreeditor) { window_imp->interruptLanguageTextInput(); } - - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - glc = cursor_coord_window.convert(); - } - else - { - glc = window_coord.convert(); - } + MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, glc, mask); - window_imp->mCallbacks->handleMouseDown(window_imp, glc, mask); + auto gl_coord = window_imp->mCursorPosition.convert(); + window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + window_imp->mCallbacks->handleMouseDown(window_imp, gl_coord, mask); }); return 0; @@ -2704,77 +2672,43 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_LBUTTONDBLCLK: { LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONDBLCLK"); - //RN: ignore right button double clicks for now - //case WM_RBUTTONDBLCLK: - if (!sHandleDoubleClick) - { - sHandleDoubleClick = true; - return 0; - } - - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->post([=]() + window_imp->postMouseButtonEvent([=]() { - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - window_imp->mCallbacks->handleDoubleClick(window_imp, gl_coord, mask); + //RN: ignore right button double clicks for now + //case WM_RBUTTONDBLCLK: + if (!sHandleDoubleClick) + { + sHandleDoubleClick = true; + return; + } + MASK mask = gKeyboard->currentMask(TRUE); + + // generate move event to update mouse coordinates + window_imp->mCursorPosition = window_coord; + window_imp->mCallbacks->handleDoubleClick(window_imp, window_imp->mCursorPosition.convert(), mask); }); + return 0; } case WM_LBUTTONUP: { LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONUP"); { - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - - if (!sHandleLeftMouseUp) - { - sHandleLeftMouseUp = true; - return 0; - } - sHandleDoubleClick = true; - window_imp->post([=]() + window_imp->postMouseButtonEvent([=]() { - auto glc = gl_coord; - - //if (gDebugClicks) - //{ - // LL_INFOS("Window") << "WndProc left button up" << LL_ENDL; - //} - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + if (!sHandleLeftMouseUp) { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - glc = cursor_coord_window.convert(); - } - else - { - glc = window_coord.convert(); + sHandleLeftMouseUp = true; + return; } + sHandleDoubleClick = true; + + MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, glc, mask); - window_imp->mCallbacks->handleMouseUp(window_imp, glc, mask); + window_imp->mCursorPosition = window_coord; + window_imp->mCallbacks->handleMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask); }); } return 0; @@ -2785,30 +2719,16 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ LL_PROFILE_ZONE_NAMED("mwp - WM_RBUTTONDOWN"); { LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - WINDOW_IMP_POST(window_imp->interruptLanguageTextInput()); - } - - // Because we move the cursor position in the llviewerapp, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates window_imp->post([=]() { + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + WINDOW_IMP_POST(window_imp->interruptLanguageTextInput()); + } + + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + auto gl_coord = window_imp->mCursorPosition.convert(); window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); window_imp->mCallbacks->handleRightMouseDown(window_imp, gl_coord, mask); }); @@ -2822,28 +2742,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ LL_PROFILE_ZONE_NAMED("mwp - WM_RBUTTONUP"); { LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleRightMouseUp(window_imp, gl_coord, mask)) - { - return 0; - } + window_imp->postMouseButtonEvent([=]() + { + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->mCallbacks->handleRightMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask); + }); } } break; @@ -2854,33 +2757,16 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ LL_PROFILE_ZONE_NAMED("mwp - WM_MBUTTONDOWN"); { LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } + window_imp->postMouseButtonEvent([=]() + { + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + window_imp->interruptLanguageTextInput(); + } - // Because we move the cursor position in tllviewerhe app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleMiddleMouseDown(window_imp, gl_coord, mask)) - { - return 0; - } + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->mCallbacks->handleMiddleMouseDown(window_imp, window_imp->mCursorPosition.convert(), mask); + }); } } break; @@ -2890,99 +2776,47 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ LL_PROFILE_ZONE_NAMED("mwp - WM_MBUTTONUP"); { LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - // Because we move the cursor position in the llviewer app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleMiddleMouseUp(window_imp, gl_coord, mask)) - { - return 0; - } + window_imp->postMouseButtonEvent([=]() + { + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->mCallbacks->handleMiddleMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask); + }); } } break; case WM_XBUTTONDOWN: { LL_PROFILE_ZONE_NAMED("mwp - WM_XBUTTONDOWN"); - { - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - S32 button = GET_XBUTTON_WPARAM(w_param); - if (LLWinImm::isAvailable() && window_imp->mPreeditor) + window_imp->postMouseButtonEvent([=]() { - window_imp->interruptLanguageTextInput(); - } + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + S32 button = GET_XBUTTON_WPARAM(w_param); + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + window_imp->interruptLanguageTextInput(); + } - // Because we move the cursor position in tllviewerhe app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 - if (window_imp->mCallbacks->handleOtherMouseDown(window_imp, gl_coord, mask, button + 3)) - { - return 0; - } - } + MASK mask = gKeyboard->currentMask(TRUE); + // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 + window_imp->mCallbacks->handleOtherMouseDown(window_imp, window_imp->mCursorPosition.convert(), mask, button + 3); + }); + } break; case WM_XBUTTONUP: { LL_PROFILE_ZONE_NAMED("mwp - WM_XBUTTONUP"); - { - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - S32 button = GET_XBUTTON_WPARAM(w_param); - // Because we move the cursor position in the llviewer app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) + window_imp->postMouseButtonEvent([=]() { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 - if (window_imp->mCallbacks->handleOtherMouseUp(window_imp, gl_coord, mask, button + 3)) - { - return 0; - } - } + + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + + S32 button = GET_XBUTTON_WPARAM(w_param); + MASK mask = gKeyboard->currentMask(TRUE); + // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 + window_imp->mCallbacks->handleOtherMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask, button + 3); + }); } break; @@ -3022,7 +2856,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // large deltas, like 480 or so. Thus we need to scroll more quickly. if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta) { - window_imp->mCallbacks->handleScrollWheel(window_imp, -z_delta / WHEEL_DELTA); + short clicks = -z_delta / WHEEL_DELTA; + WINDOW_IMP_POST(window_imp->mCallbacks->handleScrollWheel(window_imp, clicks)); z_delta = 0; } return 0; @@ -3082,11 +2917,16 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_MOUSEMOVE: { LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEMOVE"); - if (!window_imp->mMousePositionModified) - { - MASK mask = gKeyboard->currentMask(TRUE); - WINDOW_IMP_POST(window_imp->mCallbacks->handleMouseMove(window_imp, window_coord.convert(), mask)); - } + // DO NOT use mouse event queue for move events to ensure cursor position is updated + // when button events are handled + WINDOW_IMP_POST( + { + LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEMOVE lambda"); + + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->mMouseMask = mask; + window_imp->mCursorPosition = window_coord; + }); return 0; } @@ -3235,6 +3075,28 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ } break; + case WM_INPUT: + { + LL_PROFILE_ZONE_NAMED("MWP - WM_INPUT"); + + UINT dwSize = 0; + GetRawInputData((HRAWINPUT)l_param, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); + llassert(dwSize < 1024); + + U8 lpb[1024]; + + if (GetRawInputData((HRAWINPUT)l_param, RID_INPUT, (void*)lpb, &dwSize, sizeof(RAWINPUTHEADER)) == dwSize) + { + RAWINPUT* raw = (RAWINPUT*)lpb; + + if (raw->header.dwType == RIM_TYPEMOUSE) + { + LLMutexLock lock(&window_imp->mRawMouseMutex); + window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX; + window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY; + } + } + } //list of messages we get often that we don't care to log about case WM_NCHITTEST: case WM_NCMOUSEMOVE: @@ -4740,18 +4602,16 @@ inline void LLWindowWin32Thread::run() void LLWindowWin32Thread::post(const std::function& func) { -#if LL_WINDOW_SINGLE_THREADED - func(); -#else mFunctionQueue.pushFront(func); -#endif } void LLWindowWin32::post(const std::function& func) { -#if LL_WINDOW_SINGLE_THREADED - func(); -#else mFunctionQueue.pushFront(func); -#endif } + +void LLWindowWin32::postMouseButtonEvent(const std::function& func) +{ + mMouseQueue.pushFront(func); +} + diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 5f253b5df3..b44d458fc6 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -35,6 +35,7 @@ #include "lldragdropwin32.h" #include "llthread.h" #include "llthreadsafequeue.h" +#include "llmutex.h" // Hack for async host by name #define LL_WM_HOST_RESOLVED (WM_APP + 1) @@ -98,6 +99,7 @@ public: void destroySharedContext(void* context) override; /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); + /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta); /*virtual*/ void showCursor(); /*virtual*/ void hideCursor(); /*virtual*/ void showCursorFromMouseMove(); @@ -221,6 +223,14 @@ protected: F32 mNativeAspectRatio; HCURSOR mCursor[ UI_CURSOR_COUNT ]; // Array of all mouse cursors + LLCoordWindow mCursorPosition; // mouse cursor position, should only be mutated on main thread + LLMutex mRawMouseMutex; + RAWINPUTDEVICE mRawMouse; + LLCoordWindow mLastCursorPosition; // mouse cursor position from previous frame + LLCoordCommon mRawMouseDelta; // raw mouse delta according to window thread + LLCoordCommon mMouseFrameDelta; // how much the mouse moved between the last two calls to gatherInput + + MASK mMouseMask; static BOOL sIsClassRegistered; // has the window class been registered? @@ -231,7 +241,6 @@ protected: BOOL mCustomGammaSet; LPWSTR mIconResource; - BOOL mMousePositionModified; BOOL mInputProcessingPaused; // The following variables are for Language Text Input control. @@ -261,7 +270,9 @@ protected: LLWindowWin32Thread* mWindowThread = nullptr; LLThreadSafeQueue> mFunctionQueue; + LLThreadSafeQueue> mMouseQueue; void post(const std::function& func); + void postMouseButtonEvent(const std::function& func); friend class LLWindowManager; friend class LLWindowWin32Thread; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 8dd8c15b87..52d308f6bd 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -2279,7 +2279,15 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) if (normal_channel >= 0) { - gGL.getTexUnit(normal_channel)->bindFast(face->getTexture(LLRender::NORMAL_MAP)); + auto* texture = face->getTexture(LLRender::NORMAL_MAP); + if (texture) + { + gGL.getTexUnit(normal_channel)->bindFast(texture); + } + //else + //{ + // TODO handle missing normal map + //} } gGL.getTexUnit(sDiffuseChannel)->bindFast(face->getTexture(LLRender::DIFFUSE_MAP)); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 82ece85c1b..ce73037006 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3781,8 +3781,15 @@ void LLViewerWindow::updateLayout() void LLViewerWindow::updateMouseDelta() { +#if LL_WINDOWS + LLCoordCommon delta; + mWindow->getCursorDelta(&delta); + S32 dx = delta.mX; + S32 dy = delta.mY; +#else S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]); S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]); +#endif //RN: fix for asynchronous notification of mouse leaving window not working LLCoordWindow mouse_pos; -- cgit v1.3 From 768b7a4d33b64dc3e9d7f7c0c384bb2aa37b458b Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 9 Nov 2021 17:17:49 +0200 Subject: SL-16330 Clean up vertical sync handling, add to UI --- indra/llwindow/llwindow.cpp | 12 ++++----- indra/llwindow/llwindow.h | 5 ++-- indra/llwindow/llwindowheadless.cpp | 2 +- indra/llwindow/llwindowheadless.h | 5 ++-- indra/llwindow/llwindowmacosx.cpp | 12 ++++----- indra/llwindow/llwindowmacosx.h | 6 ++--- indra/llwindow/llwindowwin32.cpp | 31 +++++++++++++--------- indra/llwindow/llwindowwin32.h | 5 ++-- indra/newview/app_settings/settings.xml | 6 ++--- indra/newview/llviewercontrol.cpp | 7 +++++ indra/newview/llviewerwindow.cpp | 4 +-- indra/newview/llviewerwindow.h | 2 +- indra/newview/pipeline.cpp | 3 --- .../en/floater_preferences_graphics_advanced.xml | 8 +++--- 14 files changed, 60 insertions(+), 48 deletions(-) (limited to 'indra/llwindow/llwindowheadless.h') diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 67ef98d7b3..f4678a70c5 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -403,7 +403,7 @@ LLWindow* LLWindowManager::createWindow( const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples) @@ -415,26 +415,26 @@ LLWindow* LLWindowManager::createWindow( #if LL_MESA_HEADLESS new_window = new LLWindowMesaHeadless(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth); #elif LL_SDL new_window = new LLWindowSDL(callbacks, title, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #elif LL_WINDOWS new_window = new LLWindowWin32(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #elif LL_DARWIN new_window = new LLWindowMacOSX(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #endif } else { new_window = new LLWindowHeadless(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth); } if (FALSE == new_window->isValid()) diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index b76d313011..43d81e4d59 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -77,7 +77,7 @@ public: BOOL setSize(LLCoordScreen size); BOOL setSize(LLCoordWindow size); virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); - virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) = 0; + virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) = 0; //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread // returns a pointer to be handed back to destroySharedConext/makeContextCurrent @@ -92,6 +92,7 @@ public: virtual BOOL setCursorPosition(LLCoordWindow position) = 0; virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; #if LL_WINDOWS + virtual void toggleVSync(bool enable_vsync) = 0; virtual BOOL getCursorDelta(LLCoordCommon* delta) = 0; #endif virtual void showCursor() = 0; @@ -295,7 +296,7 @@ public: U32 flags = 0, BOOL fullscreen = FALSE, BOOL clearBg = FALSE, - BOOL disable_vsync = TRUE, + BOOL enable_vsync = FALSE, BOOL use_gl = TRUE, BOOL ignore_pixel_depth = FALSE, U32 fsaa_samples = 0); diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp index 70f473281b..c3738af6ca 100644 --- a/indra/llwindow/llwindowheadless.cpp +++ b/indra/llwindow/llwindowheadless.cpp @@ -35,7 +35,7 @@ // LLWindowHeadless::LLWindowHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clear_background, - BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth) + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth) : LLWindow(callbacks, fullscreen, flags) { // Initialize a headless keyboard. diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index f8ba9bbed4..78c5e4bae4 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -48,13 +48,14 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; void* createSharedContext() { return nullptr; } void makeContextCurrent(void*) {} void destroySharedContext(void*) {} /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; #if LL_WINDOWS + /*virtual*/ virtual void toggleVSync(bool enable_vsync) { } /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) { return FALSE; } #endif /*virtual*/ void showCursor() {}; @@ -103,7 +104,7 @@ public: S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clear_background, - BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth); + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth); virtual ~LLWindowHeadless(); private: diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 23830dd24e..a74fa78388 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -111,7 +111,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL use_gl, + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(NULL, fullscreen, flags) @@ -165,7 +165,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, // Stash an object pointer for OSMessageBox() gWindowImplementation = this; // Create the GL context and set it up for windowed or fullscreen, as appropriate. - if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) + if(createContext(x, y, width, height, 32, fullscreen, enable_vsync)) { if(mWindow != NULL) { @@ -610,7 +610,7 @@ void LLWindowMacOSX::getMouseDeltas(float* delta) delta[1] = mCursorLastEventDeltaY; } -BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) +BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync) { BOOL glNeedsInit = FALSE; @@ -625,7 +625,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits { // Our OpenGL view is already defined within SecondLife.xib. // Get the view instead. - mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync); + mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync); mContext = getCGLContextObj(mGLView); // Since we just created the context, it needs to be set up. @@ -653,7 +653,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // Disable vertical sync for swap GLint frames_per_swap = 0; - if (disable_vsync) + if (!enable_vsync) { frames_per_swap = 0; } @@ -689,7 +689,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // We only support OS X 10.7's fullscreen app mode which is literally a full screen window that fills a virtual desktop. // This makes this method obsolete. -BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp) { return FALSE; } diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index ede2b453d5..18fa86930f 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -60,7 +60,7 @@ public: BOOL setPosition(LLCoordScreen position) override; BOOL setSizeImpl(LLCoordScreen size) override; BOOL setSizeImpl(LLCoordWindow size) override; - BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) override; + BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) override; BOOL setCursorPosition(LLCoordWindow position) override; BOOL getCursorPosition(LLCoordWindow *position) override; void showCursor() override; @@ -143,7 +143,7 @@ public: protected: LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, - BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, + BOOL fullscreen, BOOL clearBg, BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowMacOSX(); @@ -176,7 +176,7 @@ protected: // // create or re-create the GL context/window. Called from the constructor and switchContext(). - BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync); + BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync); void destroyContext(); void setupFailure(const std::string& text, const std::string& caption, U32 type); void adjustCursorDecouple(bool warpingMouse = false); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index dddc8deb02..e52624d66a 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -473,7 +473,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL use_gl, + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(callbacks, fullscreen, flags) @@ -800,7 +800,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, LLCoordScreen windowPos(x,y); LLCoordScreen windowSize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); - if (!switchContext(mFullscreen, windowSize, disable_vsync, &windowPos)) + if (!switchContext(mFullscreen, windowSize, enable_vsync, &windowPos)) { return; } @@ -1126,7 +1126,7 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordWindow size) } // changing fullscreen resolution -BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BOOL disable_vsync, const LLCoordScreen* const posp) +BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BOOL enable_vsync, const LLCoordScreen* const posp) { //called from main thread GLuint pixel_format; @@ -1802,16 +1802,7 @@ const S32 max_format = (S32)num_formats - 1; } // Disable vertical sync for swap - if (disable_vsync && wglSwapIntervalEXT) - { - LL_DEBUGS("Window") << "Disabling vertical sync" << LL_ENDL; - wglSwapIntervalEXT(0); - } - else - { - LL_DEBUGS("Window") << "Keeping vertical sync" << LL_ENDL; - wglSwapIntervalEXT(1); - } + toggleVSync(enable_vsync); SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, (LONG_PTR)this); @@ -1906,6 +1897,20 @@ void LLWindowWin32::destroySharedContext(void* contextPtr) wglDeleteContext((HGLRC)contextPtr); } +void LLWindowWin32::toggleVSync(bool enable_vsync) +{ + if (!enable_vsync && wglSwapIntervalEXT) + { + LL_INFOS("Window") << "Disabling vertical sync" << LL_ENDL; + wglSwapIntervalEXT(0); + } + else + { + LL_INFOS("Window") << "Enabling vertical sync" << LL_ENDL; + wglSwapIntervalEXT(1); + } +} + void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScreen& size ) { if( mIsMouseClipping ) diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 7a9a30ccea..d082080807 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -93,11 +93,12 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position); /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL); /*virtual*/ void setTitle(const std::string title); void* createSharedContext() override; void makeContextCurrent(void* context) override; void destroySharedContext(void* context) override; + /*virtual*/ void toggleVSync(bool enable_vsync); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta); @@ -164,7 +165,7 @@ public: protected: LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, - BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, + BOOL fullscreen, BOOL clearBg, BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowWin32(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 291f0f7d95..f15b5d0981 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3352,16 +3352,16 @@ Value 0 - DisableVerticalSync + RenderVSyncEnable Comment - Update frames as fast as possible (FALSE = update frames between display scans). Requires restart. + Update frames between display scans (FALSE = Update frames as fast as possible). Persist 1 Type Boolean Value - 0 + 1 EnableGroupChatPopups diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 76dc9a6790..3e7459ee8a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -241,6 +241,12 @@ static bool handleAnisotropicChanged(const LLSD& newvalue) return true; } +static bool handleVSyncChanged(const LLSD& newvalue) +{ + gViewerWindow->getWindow()->toggleVSync(newvalue.asBoolean()); + return true; +} + static bool handleVolumeLODChanged(const LLSD& newvalue) { LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR); @@ -665,6 +671,7 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2)); gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); + gSavedSettings.getControl("RenderVSyncEnable")->getSignal()->connect(boost::bind(&handleVSyncChanged, _2)); gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); gSavedSettings.getControl("RenderDebugGL")->getSignal()->connect(boost::bind(&handleRenderDebugGLChanged, _2)); gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2)); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 7dc7b33938..a35ad55cf7 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1903,7 +1903,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) p.title, p.name, p.x, p.y, p.width, p.height, 0, p.fullscreen, gHeadlessClient, - gSavedSettings.getBOOL("DisableVerticalSync"), + gSavedSettings.getBOOL("RenderVSyncEnable"), !gHeadlessClient, p.ignore_pixel_depth, gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled @@ -5569,7 +5569,7 @@ void LLViewerWindow::restartDisplay(BOOL show_progress_bar) } } -BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar) +BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar) { //BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized"); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 8a6df613dc..93194b1884 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -424,7 +424,7 @@ public: void requestResolutionUpdate(); void checkSettings(); void restartDisplay(BOOL show_progress_bar); - BOOL changeDisplaySettings(LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar); + BOOL changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar); BOOL getIgnoreDestroyWindow() { return mIgnoreActivate; } F32 getWorldViewAspectRatio() const; const LLVector2& getDisplayScale() const { return mDisplayScale; } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1821ca067a..71a438302a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8388,8 +8388,6 @@ LLVector4 pow4fsrgb(LLVector4 v, F32 f) return v; } -static LLTrace::BlockTimerStatHandle FTM_DEFERRED_LIGHTING("Deferred Lighting"); - void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) { LL_PROFILE_ZONE_SCOPED; @@ -8397,7 +8395,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) { return; } - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_LIGHTING); LLRenderTarget *deferred_target = &mDeferredScreen; LLRenderTarget *deferred_depth_target = &mDeferredDepth; diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 7786ba8a1c..cba75e8ea7 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -334,15 +334,15 @@ width="256" /> Date: Wed, 17 Nov 2021 17:51:50 +0200 Subject: SL-16330 Allow vsync update without restart on mac --- indra/llwindow/llwindow.h | 2 +- indra/llwindow/llwindowheadless.h | 6 +++--- indra/llwindow/llwindowmacosx.cpp | 27 ++++++++++++++++----------- indra/llwindow/llwindowmacosx.h | 2 ++ indra/newview/llviewercontrol.cpp | 2 -- 5 files changed, 22 insertions(+), 17 deletions(-) (limited to 'indra/llwindow/llwindowheadless.h') diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 43d81e4d59..0edf39f6ef 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -88,11 +88,11 @@ public: //Must be called on the same thread that called createSharedContext() virtual void destroySharedContext(void* context) = 0; + virtual void toggleVSync(bool enable_vsync) = 0; virtual BOOL setCursorPosition(LLCoordWindow position) = 0; virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; #if LL_WINDOWS - virtual void toggleVSync(bool enable_vsync) = 0; virtual BOOL getCursorDelta(LLCoordCommon* delta) = 0; #endif virtual void showCursor() = 0; diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index 78c5e4bae4..410da79623 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -52,10 +52,10 @@ public: void* createSharedContext() { return nullptr; } void makeContextCurrent(void*) {} void destroySharedContext(void*) {} - /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; - /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; + /*virtual*/ void toggleVSync(bool enable_vsync) { } + /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; + /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; #if LL_WINDOWS - /*virtual*/ virtual void toggleVSync(bool enable_vsync) { } /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) { return FALSE; } #endif /*virtual*/ void showCursor() {}; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index dac84690db..0e37e82091 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -661,17 +661,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits } // Disable vertical sync for swap - GLint frames_per_swap = 0; - if (!enable_vsync) - { - frames_per_swap = 0; - } - else - { - frames_per_swap = 1; - } - - CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap); + toggleVSync(enable_vsync); //enable multi-threaded OpenGL if (sUseMultGL) @@ -1944,6 +1934,21 @@ void LLWindowMacOSX::destroySharedContext(void* context) delete sc; } +void LLWindowMacOSX::toggleVSync(bool enable_vsync) +{ + GLint frames_per_swap = 0; + if (!enable_vsync) + { + frames_per_swap = 0; + } + else + { + frames_per_swap = 1; + } + + CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap); +} + void LLWindowMacOSX::interruptLanguageTextInput() { commitCurrentPreedit(mGLView); diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 18fa86930f..b0f339e1db 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -140,6 +140,8 @@ public: //Must be called on the same thread that called createSharedContext() void destroySharedContext(void* context) override; + void toggleVSync(bool enable_vsync) override; + protected: LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 9f76543647..e20c64e48e 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -260,9 +260,7 @@ static bool handleAnisotropicChanged(const LLSD& newvalue) static bool handleVSyncChanged(const LLSD& newvalue) { -#if LL_WINDOWS gViewerWindow->getWindow()->toggleVSync(newvalue.asBoolean()); -#endif return true; } -- cgit v1.3