diff options
| author | Vir Linden <vir@lindenlab.com> | 2021-10-25 15:55:06 +0000 | 
|---|---|---|
| committer | Vir Linden <vir@lindenlab.com> | 2021-10-25 15:55:06 +0000 | 
| commit | ba3459f77fc9b93c8dd79bc3ac7c59ba792da27f (patch) | |
| tree | 6267b828141028889894be919263c6d19c6e54c1 /indra | |
| parent | a42b5d680935f08310de69f240435a7b67227a4d (diff) | |
| parent | 3efd4c50a031ce0c1cb3d2fcc43e403136277e1f (diff) | |
Merged DRTVWR-546 into SL-15999
Diffstat (limited to 'indra')
| -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;  | 
