summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llsingleton.h1
-rw-r--r--indra/llwindow/llwindow.h3
-rw-r--r--indra/llwindow/llwindowheadless.h3
-rw-r--r--indra/llwindow/llwindowwin32.cpp530
-rw-r--r--indra/llwindow/llwindowwin32.h13
-rw-r--r--indra/newview/lldrawpoolavatar.cpp10
-rw-r--r--indra/newview/llviewerwindow.cpp7
7 files changed, 230 insertions, 337 deletions
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<void()> 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<void()> 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<void()>& func)
{
-#if LL_WINDOW_SINGLE_THREADED
- func();
-#else
mFunctionQueue.pushFront(func);
-#endif
}
void LLWindowWin32::post(const std::function<void()>& func)
{
-#if LL_WINDOW_SINGLE_THREADED
- func();
-#else
mFunctionQueue.pushFront(func);
-#endif
}
+
+void LLWindowWin32::postMouseButtonEvent(const std::function<void()>& 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<std::function<void()>> mFunctionQueue;
+ LLThreadSafeQueue<std::function<void()>> mMouseQueue;
void post(const std::function<void()>& func);
+ void postMouseButtonEvent(const std::function<void()>& 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;