diff options
-rw-r--r-- | indra/llcommon/llsingleton.h | 1 | ||||
-rw-r--r-- | indra/llcommon/workqueue.cpp | 2 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 241 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 16 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 14 | ||||
-rw-r--r-- | indra/llrender/llrender.h | 2 | ||||
-rw-r--r-- | indra/llui/llfloater.h | 2 | ||||
-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/llcallingcard.cpp | 5 | ||||
-rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 10 | ||||
-rw-r--r-- | indra/newview/lldrawpoolbump.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llfloaterimcontainer.cpp | 8 | ||||
-rw-r--r-- | indra/newview/llglsandbox.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llimview.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 25 | ||||
-rw-r--r-- | indra/newview/llnotificationscripthandler.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llscreenchannel.cpp | 3 | ||||
-rw-r--r-- | indra/newview/lltoastpanel.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llviewertexture.cpp | 13 | ||||
-rw-r--r-- | indra/newview/llviewerwindow.cpp | 7 |
23 files changed, 403 insertions, 508 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/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp index ffc9a97dc0..b32357e832 100644 --- a/indra/llcommon/workqueue.cpp +++ b/indra/llcommon/workqueue.cpp @@ -54,6 +54,7 @@ void LL::WorkQueue::runUntilClose() bool LL::WorkQueue::runPending() { + LL_PROFILE_ZONE_SCOPED; for (Work work; mQueue.tryPop(work); ) { callWork(work); @@ -110,6 +111,7 @@ void LL::WorkQueue::callWork(const Queue::DataTuple& work) void LL::WorkQueue::callWork(const Work& work) { + LL_PROFILE_ZONE_SCOPED; try { work(); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index aff29bd857..b5e1910242 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -683,7 +683,7 @@ void LLImageGL::setImage(const LLImageRaw* imageraw) } static LLTrace::BlockTimerStatHandle FTM_SET_IMAGE("setImage"); -BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) +BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips, S32 usename) { LL_RECORD_BLOCK_TIME(FTM_SET_IMAGE); bool is_compressed = false; @@ -702,12 +702,11 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) break; } - - if (mUseMipMaps) { //set has mip maps to true before binding image so tex parameters get set properly - gGL.getTexUnit(0)->unbind(mBindTarget); + gGL.getTexUnit(0)->unbind(mBindTarget); + mHasMipMaps = true; mTexOptionsDirty = true; setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); @@ -717,7 +716,8 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) mHasMipMaps = false; } - llverify(gGL.getTexUnit(0)->bind(this)); + gGL.getTexUnit(0)->bind(this, false, false, usename); + if (mUseMipMaps) { @@ -1211,7 +1211,7 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures) } // static -void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) +void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures) { if (gGLManager.mInited) { @@ -1381,13 +1381,13 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S return FALSE; } - mGLTextureCreated = false ; llassert(gGLManager.mInited); stop_glerror(); if (!imageraw || imageraw->isBufferInvalid()) { LL_WARNS() << "Trying to create a texture from invalid image data" << LL_ENDL; + mGLTextureCreated = false; return FALSE; } @@ -1407,6 +1407,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S if (!setSize(w, h, imageraw->getComponents(), discard_level)) { LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL; + mGLTextureCreated = false; return FALSE; } @@ -1475,6 +1476,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S destroyGLTexture(); mCurrentDiscardLevel = discard_level; mLastBindTime = sLastFrameTime; + mGLTextureCreated = false; return TRUE ; } @@ -1486,104 +1488,123 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE3("createGLTexture3(data)"); BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) { - LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE3); - llassert(data_in); - stop_glerror(); - - if (discard_level < 0) - { - llassert(mCurrentDiscardLevel >= 0); - discard_level = mCurrentDiscardLevel; - } - discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); + LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE3); + llassert(data_in); + stop_glerror(); - if (mTexName != 0 && discard_level == mCurrentDiscardLevel) - { - // This will only be true if the size has not changed - return setImage(data_in, data_hasmips); - } - - U32 old_name = mTexName; -// S32 old_discard = mCurrentDiscardLevel; - - if (usename != 0) - { - mTexName = usename; - } - else - { - LLImageGL::generateTextures(1, &mTexName); - stop_glerror(); - { - llverify(gGL.getTexUnit(0)->bind(this)); - stop_glerror(); - glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0); - stop_glerror(); - glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level); - stop_glerror(); - } - } - if (!mTexName) - { - if (old_name) - { - sGlobalTextureMemory -= mTextureMemory; - LLImageGL::deleteTextures(1, &old_name); - disclaimMem(mTextureMemory); - stop_glerror(); - } + if (discard_level < 0) + { + llassert(mCurrentDiscardLevel >= 0); + discard_level = mCurrentDiscardLevel; + } + discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); - LL_WARNS() << "LLImageGL::createGLTexture failed to make texture" << LL_ENDL; - return FALSE; - } + if (mTexName != 0 && discard_level == mCurrentDiscardLevel) + { + // This will only be true if the size has not changed + return setImage(data_in, data_hasmips); + } - if (mUseMipMaps) - { - mAutoGenMips = gGLManager.mHasMipMapGeneration; + GLuint old_texname = mTexName; + + if (usename != 0) + { + mNewTexName = usename; + } + else + { + LLImageGL::generateTextures(1, &mNewTexName); + { + gGL.getTexUnit(0)->bind(this, false, false, mNewTexName); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel - discard_level); + } + } + + if (mUseMipMaps) + { + mAutoGenMips = gGLManager.mHasMipMapGeneration; #if LL_DARWIN - // On the Mac GF2 and GF4MX drivers, auto mipmap generation doesn't work right with alpha-only textures. - if(gGLManager.mIsGF2or4MX && (mFormatInternal == GL_ALPHA8) && (mFormatPrimary == GL_ALPHA)) - { - mAutoGenMips = FALSE; - } + // On the Mac GF2 and GF4MX drivers, auto mipmap generation doesn't work right with alpha-only textures. + if (gGLManager.mIsGF2or4MX && (mFormatInternal == GL_ALPHA8) && (mFormatPrimary == GL_ALPHA)) + { + mAutoGenMips = FALSE; + } #endif - } + } - mCurrentDiscardLevel = discard_level; + mCurrentDiscardLevel = discard_level; - if (!setImage(data_in, data_hasmips)) - { - stop_glerror(); - return FALSE; - } + if (!setImage(data_in, data_hasmips, mNewTexName)) + { + return FALSE; + } - // Set texture options to our defaults. - gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps); - gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode); - gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption); + // Set texture options to our defaults. + gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps); + gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode); + gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption); - // things will break if we don't unbind after creation - gGL.getTexUnit(0)->unbind(mBindTarget); - stop_glerror(); + // things will break if we don't unbind after creation + gGL.getTexUnit(0)->unbind(mBindTarget); - if (old_name != 0) - { - sGlobalTextureMemory -= mTextureMemory; + if (old_texname != 0) + { + sGlobalTextureMemory -= mTextureMemory; + } - LLImageGL::deleteTextures(1, &old_name); + //if we're on the image loading thread, be sure to delete old_texname and update mTexName on the main thread + if (LLImageGLThread::sInstance != nullptr && + LLThread::currentID() == LLImageGLThread::sInstance->getID()) + { + { + LL_PROFILE_ZONE_NAMED("cglt - sync"); + if (gGLManager.mHasSync) + { + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glClientWaitSync(sync, 0, 0); + glDeleteSync(sync); + } + else + { + glFinish(); + } + } - stop_glerror(); - } + ref(); + LLImageGLThread::sInstance->postCallback([=]() + { + LL_PROFILE_ZONE_NAMED("cglt - delete callback"); + if (old_texname != 0) + { + LLImageGL::deleteTextures(1, &old_texname); + } + mTexName = mNewTexName; + mNewTexName = 0; + unref(); + }); + } + else + { + //not on background thread, immediately set mTexName + if (old_texname != 0) + { + LLImageGL::deleteTextures(1, &old_texname); + } + mTexName = mNewTexName; + mNewTexName = 0; + } + + disclaimMem(mTextureMemory); + mTextureMemory = (S32Bytes)getMipBytes(mCurrentDiscardLevel); + claimMem(mTextureMemory); + sGlobalTextureMemory += mTextureMemory; + mTexelsInGLTexture = getWidth() * getHeight(); - disclaimMem(mTextureMemory); - mTextureMemory = (S32Bytes)getMipBytes(discard_level); - claimMem(mTextureMemory); - sGlobalTextureMemory += mTextureMemory; - mTexelsInGLTexture = getWidth() * getHeight() ; + // mark this as bound at this point, so we don't throw it out immediately + mLastBindTime = sLastFrameTime; - // mark this as bound at this point, so we don't throw it out immediately - mLastBindTime = sLastFrameTime; - return TRUE; + return TRUE; } BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const @@ -2274,17 +2295,7 @@ bool LLImageGLThread::post(const std::function<void()>& func) { try { - if (mFunctionQueue.size() < mFunctionQueue.capacity()) - { - //NOTE: tryPushFront will return immediately if the lock is held - // desired behavior here is to push and return true unless the - // queue is full or closed - mFunctionQueue.pushFront(func); - } - else - { - return false; - } + mFunctionQueue.post(func); } catch (LLThreadSafeQueueInterrupt e) { @@ -2300,7 +2311,7 @@ bool LLImageGLThread::postCallback(const std::function<void()>& callback) { try { - mCallbackQueue.pushFront(callback); + mCallbackQueue.post(callback); } catch (LLThreadSafeQueueInterrupt e) { @@ -2315,34 +2326,14 @@ void LLImageGLThread::executeCallbacks() { LL_PROFILE_ZONE_SCOPED; //executed from main thread - std::function<void()> callback; - while (mCallbackQueue.tryPopBack(callback)) - { - LL_PROFILE_ZONE_NAMED("iglt - callback"); - callback(); - } + mCallbackQueue.runPending(); } void LLImageGLThread::run() { mWindow->makeContextCurrent(mContext); gGL.init(); - try - { - while (true) - { - LL_PROFILE_ZONE_SCOPED; - std::function<void()> curFunc = mFunctionQueue.popBack(); - { - LL_PROFILE_ZONE_NAMED("iglt - function") - curFunc(); - } - } - } - catch (LLThreadSafeQueueInterrupt e) - { - //queue is closed, fall out of run loop - } + mFunctionQueue.runUntilClose(); gGL.shutdown(); mWindow->destroySharedContext(mContext); } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 8e9b483c2d..da626a1093 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -37,6 +37,8 @@ #include "llunits.h" #include "llthreadsafequeue.h" #include "llrender.h" +#include "workqueue.h" + class LLTextureAtlas ; class LLWindow; @@ -50,7 +52,7 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> public: // These 2 functions replace glGenTextures() and glDeleteTextures() static void generateTextures(S32 numTextures, U32 *textures); - static void deleteTextures(S32 numTextures, U32 *textures); + static void deleteTextures(S32 numTextures, const U32 *textures); static void deleteDeadTextures(); // Size calculation @@ -110,7 +112,7 @@ public: S32 category = sMaxCategories-1); BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0); void setImage(const LLImageRaw* imageraw); - BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE); + BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0); BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height); @@ -210,8 +212,9 @@ private: bool mGLTextureCreated ; LLGLuint mTexName; + LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread U16 mWidth; - U16 mHeight; + U16 mHeight; S8 mCurrentDiscardLevel; S8 mDiscardLevelInAtlas; @@ -319,8 +322,11 @@ public: void run() override; - LLThreadSafeQueue<std::function<void()>> mFunctionQueue; - LLThreadSafeQueue<std::function<void()>> mCallbackQueue; + // Work Queue for background thread + LL::WorkQueue mFunctionQueue; + + // Work Queue for main thread (run from updateClass) + LL::WorkQueue mCallbackQueue; LLWindow* mWindow; void* mContext; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 669a09d3ce..aad04beea2 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -236,6 +236,10 @@ void LLTexUnit::bindFast(LLTexture* texture) glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); gGL.mCurrTextureUnitIndex = mIndex; mCurrTexture = gl_tex->getTexName(); + if (!mCurrTexture) + { + mCurrTexture = LLImageGL::sDefaultGLTexture->getTexName(); + } glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); mHasMipMaps = gl_tex->mHasMipMaps; } @@ -306,18 +310,20 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) return true; } -bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) +bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32 usename) { stop_glerror(); if (mIndex < 0) return false; + U32 texname = usename ? usename : texture->getTexName(); + if(!texture) { LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL; return false; } - if(!texture->getTexName()) + if(!texname) { if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName()) { @@ -327,7 +333,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) return false ; } - if ((mCurrTexture != texture->getTexName()) || forceBind) + if ((mCurrTexture != texname) || forceBind) { gGL.flush(); stop_glerror(); @@ -335,7 +341,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) stop_glerror(); enable(texture->getTarget()); stop_glerror(); - mCurrTexture = texture->getTexName(); + mCurrTexture = texname; glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); stop_glerror(); texture->updateBindStats(texture->mTextureMemory); diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 6e2647a16b..7f19a45410 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -158,7 +158,7 @@ public: // Binds the LLImageGL to this texture unit // (automatically enables the unit for the LLImageGL's texture type) - bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false); + bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false, S32 usename = 0); bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false); // bind implementation for inner loops diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 2672d600c6..306760b7fb 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -346,6 +346,8 @@ public: // handle refocusing. static void closeFrontmostFloater(); + static bool isQuitRequested() { return sQuitting; } + // LLNotification::Params contextualNotification(const std::string& name) // { // return LLNotification::Params(name).context(mNotificationContext); diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index c7df729782..b76d313011 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 e668fc1eed..26bb56d72d 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); @@ -1934,31 +1936,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; @@ -1967,19 +1964,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(); @@ -2160,34 +2165,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. @@ -2197,45 +2199,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; @@ -2245,11 +2237,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) { @@ -2285,10 +2273,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; @@ -2672,35 +2656,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; @@ -2711,77 +2679,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; @@ -2792,30 +2726,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); }); @@ -2829,28 +2749,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; @@ -2861,33 +2764,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; @@ -2897,99 +2783,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; @@ -3029,7 +2863,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; @@ -3089,11 +2924,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; } @@ -3242,6 +3082,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: @@ -4747,18 +4609,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 ea1c103bcd..7a9a30ccea 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) @@ -99,6 +100,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(); @@ -222,6 +224,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? @@ -232,7 +242,6 @@ protected: BOOL mCustomGammaSet; LPWSTR mIconResource; - BOOL mMousePositionModified; BOOL mInputProcessingPaused; // The following variables are for Language Text Input control. @@ -262,7 +271,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/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 6d20b23e9f..9ee9900eba 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -257,7 +257,6 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds) LLAvatarName av_name; LLAvatarNameCache::get(agent_id, &av_name); - addChangedMask(LLFriendObserver::ADD, agent_id); LL_DEBUGS() << "Added buddy " << agent_id << ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline") << ", TO: " << mBuddyInfo[agent_id]->getRightsGrantedTo() @@ -493,6 +492,7 @@ void LLAvatarTracker::notifyObservers() // new masks and ids will be processed later from idle. return; } + LL_PROFILE_ZONE_SCOPED mIsNotifyObservers = TRUE; observer_list_t observers(mObservers); @@ -678,6 +678,7 @@ void LLAvatarTracker::processChangeUserRights(LLMessageSystem* msg, void**) void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) { + LL_PROFILE_ZONE_SCOPED S32 count = msg->getNumberOfBlocksFast(_PREHASH_AgentBlock); BOOL chat_notify = gSavedSettings.getBOOL("ChatOnlineNotification"); @@ -712,8 +713,6 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) // we were tracking someone who went offline deleteTrackingData(); } - // *TODO: get actual inventory id - gInventory.addChangedMask(LLInventoryObserver::CALLING_CARD, LLUUID::null); } if(chat_notify) { 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/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index d75884cc16..b08fbcbd89 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -715,7 +715,8 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi } else { - gGL.getTexUnit(channel)->bindFast(bump); + // NOTE: do not use bindFast here (see SL-16222) + gGL.getTexUnit(channel)->bind(bump); } return TRUE; diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 9c84fa1991..2ccb9ab074 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -723,7 +723,13 @@ void LLFloaterIMContainer::setMinimized(BOOL b) } void LLFloaterIMContainer::setVisible(BOOL visible) -{ LLFloaterIMNearbyChat* nearby_chat; +{ + if (LLFloater::isQuitRequested()) + { + return; + } + + LLFloaterIMNearbyChat* nearby_chat; if (visible) { // Make sure we have the Nearby Chat present when showing the conversation container diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 0f288e05ca..91f314c115 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -1090,7 +1090,7 @@ F32 gpu_benchmark() delete [] pixels; //make a dummy triangle to draw with - LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STREAM_DRAW_ARB); + LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STREAM_DRAW_ARB); if (!buff->allocateBuffer(3, 0, true)) { @@ -1100,7 +1100,6 @@ F32 gpu_benchmark() } LLStrider<LLVector3> v; - LLStrider<LLVector2> tc; if (! buff->getVertexStrider(v)) { diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 1059324a16..f5358ba5f2 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1229,7 +1229,6 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, if (!session) { - LL_WARNS() << "session " << session_id << "does not exist " << LL_ENDL; return NULL; } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index fc8179f3b4..844d544e16 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -5714,14 +5714,14 @@ class LLCallingCardObserver : public LLFriendObserver public: LLCallingCardObserver(LLCallingCardBridge* bridge) : mBridgep(bridge) {} virtual ~LLCallingCardObserver() { mBridgep = NULL; } - virtual void changed(U32 mask) - { - mBridgep->refreshFolderViewItem(); - if (mask & LLFriendObserver::ONLINE) - { - mBridgep->checkSearchBySuffixChanges(); - } - } + virtual void changed(U32 mask) + { + if (mask & LLFriendObserver::ONLINE) + { + mBridgep->refreshFolderViewItem(); + mBridgep->checkSearchBySuffixChanges(); + } + } protected: LLCallingCardBridge* mBridgep; }; @@ -5735,14 +5735,15 @@ LLCallingCardBridge::LLCallingCardBridge(LLInventoryPanel* inventory, const LLUUID& uuid ) : LLItemBridge(inventory, root, uuid) { - mObserver = new LLCallingCardObserver(this); - LLAvatarTracker::instance().addObserver(mObserver); + mObserver = new LLCallingCardObserver(this); + LLAvatarTracker::instance().addParticularFriendObserver(getItem()->getCreatorUUID(), mObserver); } LLCallingCardBridge::~LLCallingCardBridge() { - LLAvatarTracker::instance().removeObserver(mObserver); - delete mObserver; + LLAvatarTracker::instance().removeParticularFriendObserver(getItem()->getCreatorUUID(), mObserver); + + delete mObserver; } void LLCallingCardBridge::refreshFolderViewItem() diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index ba831ab2ed..d896c409d7 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -69,7 +69,8 @@ void LLScriptHandler::initChannel() //-------------------------------------------------------------------------- void LLScriptHandler::addToastWithNotification(const LLNotificationPtr& notification) { - LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification); + LL_PROFILE_ZONE_SCOPED + LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification); LLToast::Params p; p.notif_id = notification->getID(); diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 681787bcbe..ca48c9d58c 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -259,7 +259,8 @@ void LLScreenChannel::updatePositionAndSize(LLRect new_world_rect) //-------------------------------------------------------------------------- void LLScreenChannel::addToast(const LLToast::Params& p) { - bool store_toast = false, show_toast = false; + LL_PROFILE_ZONE_SCOPED + bool store_toast = false, show_toast = false; if (mDisplayToastsAlways) { diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index 100d5ee713..d43da93c61 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -114,7 +114,8 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount) LLToastPanel* LLToastPanel::buidPanelFromNotification( const LLNotificationPtr& notification) { - LLToastPanel* res = NULL; + LL_PROFILE_ZONE_SCOPED + LLToastPanel* res = NULL; //process tip toast panels if ("notifytip" == notification->getType()) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 949e71a4c9..34847d8618 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1637,19 +1637,6 @@ void LLViewerFetchedTexture::scheduleCreateTexture() { //actually create the texture on a background thread createTexture(); - { - LL_PROFILE_ZONE_NAMED("iglt - sync"); - if (gGLManager.mHasSync) - { - auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - glClientWaitSync(sync, 0, 0); - glDeleteSync(sync); - } - else - { - glFinish(); - } - } LLImageGLThread::sInstance->postCallback([this]() { //finalize on main thread diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2342b6219c..7dc7b33938 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3802,8 +3802,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; |