Merged DRTVWR-546 into SL-15999
commit
ba3459f77f
|
|
@ -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.)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
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);
|
||||
if (discard_level < 0)
|
||||
{
|
||||
llassert(mCurrentDiscardLevel >= 0);
|
||||
discard_level = mCurrentDiscardLevel;
|
||||
}
|
||||
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
|
||||
|
||||
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 (mTexName != 0 && discard_level == mCurrentDiscardLevel)
|
||||
{
|
||||
// This will only be true if the size has not changed
|
||||
return setImage(data_in, data_hasmips);
|
||||
}
|
||||
|
||||
LL_WARNS() << "LLImageGL::createGLTexture failed to make texture" << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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() {};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
LLCoordScreen screen_pos(position.convert());
|
||||
|
||||
// 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);
|
||||
|
||||
mMousePositionModified = TRUE;
|
||||
LLCoordScreen screen_pos(position.convert());
|
||||
|
||||
mWindowThread->post([=]
|
||||
// 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 (!position)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!mWindowHandle
|
||||
|| !GetCursorPos(&cursor_point)
|
||||
|| !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,34 +2199,6 @@ void LLWindowWin32::gatherInput()
|
|||
gAsyncMsgCallback(msg);
|
||||
}
|
||||
}
|
||||
#else //multi-threaded window impl
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("gi - function queue");
|
||||
|
|
@ -2235,7 +2209,25 @@ void LLWindowWin32::gatherInput()
|
|||
curFunc();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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 - mouse queue");
|
||||
// handle mouse button presses AFTER updating mouse cursor position
|
||||
std::function<void()> curFunc;
|
||||
while (mMouseQueue.tryPopBack(curFunc))
|
||||
{
|
||||
curFunc();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
|
||||
if (!sHandleLeftMouseUp)
|
||||
{
|
||||
sHandleLeftMouseUp = true;
|
||||
return;
|
||||
}
|
||||
sHandleDoubleClick = true;
|
||||
|
||||
//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)
|
||||
{
|
||||
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->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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue