diff options
| -rw-r--r-- | indra/llcommon/llsingleton.h | 1 | ||||
| -rw-r--r-- | indra/llwindow/llwindow.h | 3 | ||||
| -rw-r--r-- | indra/llwindow/llwindowheadless.h | 3 | ||||
| -rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 530 | ||||
| -rw-r--r-- | indra/llwindow/llwindowwin32.h | 13 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.cpp | 7 | 
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; | 
