diff options
58 files changed, 1109 insertions, 1030 deletions
| diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index 1b8c3db2e2..cfff956bcf 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -7,7 +7,7 @@ if (USE_TRACY)    set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy)   # See: indra/llcommon/llprofiler.h -  add_definitions(-DLL_PROFILER_CONFIGURATION=2) +  add_definitions(-DLL_PROFILER_CONFIGURATION=3)    use_prebuilt_binary(tracy)    if (WINDOWS) diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 57b746889d..605f6bf0e3 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -400,6 +400,7 @@ namespace  	ImplMap& ImplMap::makeMap(LLSD::Impl*& var)  	{ +        LL_PROFILE_ZONE_SCOPED;  		if (shared())  		{  			ImplMap* i = new ImplMap(mData); @@ -414,18 +415,21 @@ namespace  	bool ImplMap::has(const LLSD::String& k) const  	{ +        LL_PROFILE_ZONE_SCOPED;  		DataMap::const_iterator i = mData.find(k);  		return i != mData.end();  	}  	LLSD ImplMap::get(const LLSD::String& k) const  	{ +        LL_PROFILE_ZONE_SCOPED;  		DataMap::const_iterator i = mData.find(k);  		return (i != mData.end()) ? i->second : LLSD();  	}  	LLSD ImplMap::getKeys() const  	{  +        LL_PROFILE_ZONE_SCOPED;  		LLSD keys = LLSD::emptyArray();  		DataMap::const_iterator iter = mData.begin();  		while (iter != mData.end()) @@ -438,11 +442,13 @@ namespace  	void ImplMap::insert(const LLSD::String& k, const LLSD& v)  	{ +        LL_PROFILE_ZONE_SCOPED;  		mData.insert(DataMap::value_type(k, v));  	}  	void ImplMap::erase(const LLSD::String& k)  	{ +        LL_PROFILE_ZONE_SCOPED;  		mData.erase(k);  	} @@ -684,6 +690,7 @@ const LLSD::Impl& LLSD::Impl::safe(const Impl* impl)  ImplMap& LLSD::Impl::makeMap(Impl*& var)  { +    LL_PROFILE_ZONE_SCOPED;  	ImplMap* im = new ImplMap;  	reset(var, im);  	return *im; @@ -887,11 +894,16 @@ LLSD& LLSD::with(const String& k, const LLSD& v)  										}  void LLSD::erase(const String& k)		{ makeMap(impl).erase(k); } -LLSD&		LLSD::operator[](const String& k) -										{ return makeMap(impl).ref(k); } +LLSD& LLSD::operator[](const String& k) +{  +    LL_PROFILE_ZONE_SCOPED; +    return makeMap(impl).ref(k);  +}  const LLSD& LLSD::operator[](const String& k) const -										{ return safe(impl).ref(k); } - +{  +    LL_PROFILE_ZONE_SCOPED; +    return safe(impl).ref(k);  +}  LLSD LLSD::emptyArray()  { @@ -914,10 +926,16 @@ LLSD& LLSD::with(Integer i, const LLSD& v)  LLSD& LLSD::append(const LLSD& v)		{ return makeArray(impl).append(v); }  void LLSD::erase(Integer i)				{ makeArray(impl).erase(i); } -LLSD&		LLSD::operator[](Integer i) -										{ return makeArray(impl).ref(i); } +LLSD& LLSD::operator[](Integer i) +{  +    LL_PROFILE_ZONE_SCOPED; +    return makeArray(impl).ref(i);  +}  const LLSD& LLSD::operator[](Integer i) const -										{ return safe(impl).ref(i); } +{  +    LL_PROFILE_ZONE_SCOPED; +    return safe(impl).ref(i); +}  static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)  { diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index 5b6d5545af..b8ddf21596 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -290,9 +290,17 @@ public:  		LLSD& with(const String&, const LLSD&);  		LLSD& operator[](const String&); -		LLSD& operator[](const char* c)			{ return (*this)[String(c)]; } +		LLSD& operator[](const char* c)			 +        {  +            LL_PROFILE_ZONE_SCOPED; +            return (*this)[String(c)];  +        }  		const LLSD& operator[](const String&) const; -		const LLSD& operator[](const char* c) const	{ return (*this)[String(c)]; } +		const LLSD& operator[](const char* c) const	 +        {  +            LL_PROFILE_ZONE_SCOPED; +            return (*this)[String(c)];  +        }  	//@}  	/** @name Array Values */ 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/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 61b59e35aa..89a4eebf26 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -683,6 +683,7 @@ bool LLSettingsBase::Validator::verifyStringLength(LLSD &value, S32 length)  //=========================================================================  void LLSettingsBlender::update(const LLSettingsBase::BlendFactor& blendf)  { +    LL_PROFILE_ZONE_SCOPED;      F64 res = setBlendFactor(blendf);      llassert(res >= 0.0 && res <= 1.0);      (void)res; @@ -713,6 +714,7 @@ F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_  void LLSettingsBlender::triggerComplete()  { +    LL_PROFILE_ZONE_SCOPED;      if (mTarget)          mTarget->replaceSettings(mFinal->getSettings());      LLSettingsBlender::ptr_t hold = shared_from_this();   // prevents this from deleting too soon @@ -725,11 +727,13 @@ const LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::MIN_BLEND_DELTA(FL  LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const  { +    LL_PROFILE_ZONE_SCOPED;      return LLSettingsBase::BlendFactor(fmod((F64)spanpos, (F64)spanlen) / (F64)spanlen);  }  bool LLSettingsBlenderTimeDelta::applyTimeDelta(const LLSettingsBase::Seconds& timedelta)  { +    LL_PROFILE_ZONE_SCOPED;      mTimeSpent += timedelta;      if (mTimeSpent > mBlendSpan) diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 69b4a4929d..82c67a1066 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -444,6 +444,7 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother)  void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf)   { +    LL_PROFILE_ZONE_SCOPED;      llassert(getSettingsType() == end->getSettingsType());      LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast<LLSettingsSky>(end); @@ -1022,6 +1023,7 @@ LLColor3 LLSettingsSky::getLightDiffuse() const  LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default_value) const  { +    LL_PROFILE_ZONE_SCOPED;      if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key))      {          return LLColor3(mSettings[SETTING_LEGACY_HAZE][key]); @@ -1035,6 +1037,7 @@ LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default  F32 LLSettingsSky::getFloat(const std::string& key, F32 default_value) const  { +    LL_PROFILE_ZONE_SCOPED;      if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key))      {          return mSettings[SETTING_LEGACY_HAZE][key].asReal(); diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 394fcd2b2f..0e4753fcc6 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -1017,7 +1017,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu      if (uniform > -1)      { -        gGL.getTexUnit(uniform)->bind(texture, mode); +        gGL.getTexUnit(uniform)->bindFast(texture);          gGL.getTexUnit(uniform)->setTextureColorSpace(colorspace);      } @@ -1048,7 +1048,7 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)      if (uniform > -1)      { -        gGL.getTexUnit(uniform)->unbind(mode); +        gGL.getTexUnit(uniform)->unbindFast(mode);      }      return uniform; @@ -1104,6 +1104,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTe  void LLGLSLShader::uniform1i(U32 index, GLint x)  { +    LL_PROFILE_ZONE_SCOPED      if (mProgramObject)      {             if (mUniform.size() <= index) @@ -1114,7 +1115,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)          if (mUniform[index] >= 0)          { -            std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); +            const auto& iter = mValue.find(mUniform[index]);              if (iter == mValue.end() || iter->second.mV[0] != x)              {                  glUniform1iARB(mUniform[index], x); @@ -1126,6 +1127,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)  void LLGLSLShader::uniform1f(U32 index, GLfloat x)  { +    LL_PROFILE_ZONE_SCOPED      if (mProgramObject)      {             if (mUniform.size() <= index) @@ -1136,7 +1138,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)          if (mUniform[index] >= 0)          { -            std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); +            const auto& iter = mValue.find(mUniform[index]);              if (iter == mValue.end() || iter->second.mV[0] != x)              {                  glUniform1fARB(mUniform[index], x); @@ -1158,7 +1160,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)          if (mUniform[index] >= 0)          { -            std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); +            const auto& iter = mValue.find(mUniform[index]);              LLVector4 vec(x,y,0.f,0.f);              if (iter == mValue.end() || shouldChange(iter->second,vec))              { @@ -1181,7 +1183,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)          if (mUniform[index] >= 0)          { -            std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); +            const auto& iter = mValue.find(mUniform[index]);              LLVector4 vec(x,y,z,0.f);              if (iter == mValue.end() || shouldChange(iter->second,vec))              { @@ -1204,7 +1206,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat          if (mUniform[index] >= 0)          { -            std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); +            const auto& iter = mValue.find(mUniform[index]);              LLVector4 vec(x,y,z,w);              if (iter == mValue.end() || shouldChange(iter->second,vec))              { @@ -1227,7 +1229,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)          if (mUniform[index] >= 0)          { -            std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); +            const auto& iter = mValue.find(mUniform[index]);              LLVector4 vec(v[0],0.f,0.f,0.f);              if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)              { @@ -1250,7 +1252,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)          if (mUniform[index] >= 0)          { -            std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); +            const auto& iter = mValue.find(mUniform[index]);              LLVector4 vec(v[0],0.f,0.f,0.f);              if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)              { @@ -1273,7 +1275,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)          if (mUniform[index] >= 0)          { -            std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); +            const auto& iter = mValue.find(mUniform[index]);              LLVector4 vec(v[0],v[1],0.f,0.f);              if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)              { @@ -1296,7 +1298,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)          if (mUniform[index] >= 0)          { -            std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); +            const auto& iter = mValue.find(mUniform[index]);              LLVector4 vec(v[0],v[1],v[2],0.f);              if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)              { @@ -1319,10 +1321,11 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)          if (mUniform[index] >= 0)          { -            std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); +            const auto& iter = mValue.find(mUniform[index]);              LLVector4 vec(v[0],v[1],v[2],v[3]);              if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)              { +                LL_PROFILE_ZONE_SCOPED;                  glUniform4fvARB(mUniform[index], count, v);                  mValue[mUniform[index]] = vec;              } @@ -1460,7 +1463,7 @@ void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)      if (location >= 0)      { -        std::map<GLint, LLVector4>::iterator iter = mValue.find(location); +        const auto& iter = mValue.find(location);          LLVector4 vec(v,0.f,0.f,0.f);          if (iter == mValue.end() || shouldChange(iter->second,vec))          { @@ -1476,7 +1479,7 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint      if (location >= 0)      { -        std::map<GLint, LLVector4>::iterator iter = mValue.find(location); +        const auto& iter = mValue.find(location);          LLVector4 vec(i,j,0.f,0.f);          if (iter == mValue.end() || shouldChange(iter->second,vec))          { @@ -1493,7 +1496,7 @@ void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)      if (location >= 0)      { -        std::map<GLint, LLVector4>::iterator iter = mValue.find(location); +        const auto& iter = mValue.find(location);          LLVector4 vec(v,0.f,0.f,0.f);          if (iter == mValue.end() || shouldChange(iter->second,vec))          { @@ -1509,7 +1512,7 @@ void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLf      if (location >= 0)      { -        std::map<GLint, LLVector4>::iterator iter = mValue.find(location); +        const auto& iter = mValue.find(location);          LLVector4 vec(x,y,0.f,0.f);          if (iter == mValue.end() || shouldChange(iter->second,vec))          { @@ -1526,7 +1529,7 @@ void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLf      if (location >= 0)      { -        std::map<GLint, LLVector4>::iterator iter = mValue.find(location); +        const auto& iter = mValue.find(location);          LLVector4 vec(x,y,z,0.f);          if (iter == mValue.end() || shouldChange(iter->second,vec))          { @@ -1542,7 +1545,7 @@ void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, co      if (location >= 0)      { -        std::map<GLint, LLVector4>::iterator iter = mValue.find(location); +        const auto& iter = mValue.find(location);          LLVector4 vec(v[0],0.f,0.f,0.f);          if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)          { @@ -1558,7 +1561,7 @@ void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, co      if (location >= 0)      { -        std::map<GLint, LLVector4>::iterator iter = mValue.find(location); +        const auto& iter = mValue.find(location);          LLVector4 vec(v[0],v[1],0.f,0.f);          if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)          { @@ -1574,7 +1577,7 @@ void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, co      if (location >= 0)      { -        std::map<GLint, LLVector4>::iterator iter = mValue.find(location); +        const auto& iter = mValue.find(location);          LLVector4 vec(v[0],v[1],v[2],0.f);          if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)          { @@ -1591,12 +1594,11 @@ void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, co      if (location >= 0)      {          LLVector4 vec(v); -        std::map<GLint, LLVector4>::iterator iter = mValue.find(location); +        const auto& iter = mValue.find(location);          if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)          { -            stop_glerror(); +            LL_PROFILE_ZONE_SCOPED;              glUniform4fvARB(location, count, v); -            stop_glerror();              mValue[location] = vec;          }      } @@ -1636,3 +1638,27 @@ void LLGLSLShader::setMinimumAlpha(F32 minimum)      gGL.flush();      uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum);  } + +void LLShaderUniforms::apply(LLGLSLShader* shader) +{ +    LL_PROFILE_ZONE_SCOPED; +    for (auto& uniform : mIntegers) +    { +        shader->uniform1i(uniform.mUniform, uniform.mValue); +    } + +    for (auto& uniform : mFloats) +    { +        shader->uniform1f(uniform.mUniform, uniform.mValue); +    } + +    for (auto& uniform : mVectors) +    { +        shader->uniform4fv(uniform.mUniform, 1, uniform.mValue.mV); +    } + +    for (auto& uniform : mVector3s) +    { +        shader->uniform3fv(uniform.mUniform, 1, uniform.mValue.mV); +    } +} diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 7cf6d3c941..3b23cf1b28 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -30,6 +30,7 @@  #include "llgl.h"  #include "llrender.h"  #include "llstaticstringtable.h" +#include <unordered_map>  class LLShaderFeatures  { @@ -64,16 +65,79 @@ public:  	LLShaderFeatures();  }; +// ============= Structure for caching shader uniforms =============== +class LLGLSLShader; + +class LLShaderUniforms +{ +public: + +    template<typename T> +    struct UniformSetting +    { +        S32 mUniform; +        T mValue; +    }; + +    typedef UniformSetting<S32> IntSetting; +    typedef UniformSetting<F32> FloatSetting; +    typedef UniformSetting<LLVector4> VectorSetting; +    typedef UniformSetting<LLVector3> Vector3Setting; + +    void clear() +    { +        mIntegers.resize(0); +        mFloats.resize(0); +        mVectors.resize(0); +        mVector3s.resize(0); +    } + +    void uniform1i(S32 index, S32 value) +    { +        mIntegers.push_back({ index, value }); +    } + +    void uniform1f(S32 index, F32 value) +    { +        mFloats.push_back({ index, value }); +    } + +    void uniform4fv(S32 index, const LLVector4& value) +    { +        mVectors.push_back({ index, value }); +    } +     +    void uniform4fv(S32 index, const F32* value) +    { +        mVectors.push_back({ index, LLVector4(value) }); +    } + +    void uniform3fv(S32 index, const LLVector3& value) +    { +        mVector3s.push_back({ index, value }); +    } + +    void apply(LLGLSLShader* shader); +    + +    std::vector<IntSetting> mIntegers; +    std::vector<FloatSetting> mFloats; +    std::vector<VectorSetting> mVectors; +    std::vector<Vector3Setting> mVector3s; +};  class LLGLSLShader  {  public: -	enum  +    // enum primarily used to control application sky settings uniforms +	typedef enum   	{ -		SG_DEFAULT = 0, -		SG_SKY, -		SG_WATER -	}; +		SG_DEFAULT = 0,  // not sky or water specific +		SG_SKY,  // +		SG_WATER, +        SG_ANY, +        SG_COUNT +	} eGroup;  	static std::set<LLGLSLShader*> sInstances;  	static bool sProfileEnabled; @@ -190,13 +254,15 @@ public:  	U32 mAttributeMask;  //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())  	std::vector<GLint> mUniform;   //lookup table of uniform enum to uniform location  	LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location -	std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name -	std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value +    typedef std::unordered_map<GLint, std::string> uniform_name_map_t; +    typedef std::unordered_map<GLint, LLVector4> uniform_value_map_t; +    uniform_name_map_t mUniformNameMap; //lookup map of uniform location to uniform name +	uniform_value_map_t mValue; //lookup map of uniform location to last known value  	std::vector<GLint> mTexture;  	S32 mTotalUniformSize;  	S32 mActiveTextureChannels;  	S32 mShaderLevel; -	S32 mShaderGroup; +	S32 mShaderGroup; // see LLGLSLShader::eGroup  	BOOL mUniformsDirty;  	LLShaderFeatures mFeatures;  	std::vector< std::pair< std::string, GLenum > > mShaderFiles; diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 071912c2c2..028457c510 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -176,7 +176,7 @@ private:  protected:  	void setTexelsPerImage(); -	//note: do not make this function public. +public:  	/*virtual*/ LLImageGL* getGLTexture() const ;  protected: 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 b6711e44e3..aad04beea2 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -229,8 +229,24 @@ void LLTexUnit::disable(void)  	}  } +void LLTexUnit::bindFast(LLTexture* texture) +{ +    LLImageGL* gl_tex = texture->getGLTexture(); + +    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; +} +  bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)  { +    LL_PROFILE_ZONE_SCOPED;  	stop_glerror();  	if (mIndex >= 0)  	{ @@ -294,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())  		{ @@ -315,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(); @@ -323,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);		 @@ -459,6 +477,28 @@ void LLTexUnit::unbind(eTextureType type)  	}  } +void LLTexUnit::unbindFast(eTextureType type) +{ +    activate(); + +    // Disabled caching of binding state. +    if (mCurrTexType == type) +    { +        mCurrTexture = 0; + +        // Always make sure our texture color space is reset to linear.  SRGB sampling should be opt-in in the vast majority of cases.  Also prevents color space "popping". +        mTexColorSpace = TCS_LINEAR; +        if (type == LLTexUnit::TT_TEXTURE) +        { +            glBindTexture(sGLTextureType[type], sWhiteTexture); +        } +        else +        { +            glBindTexture(sGLTextureType[type], 0); +        } +    } +} +  void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)  {  	if (mIndex < 0 || mCurrTexture == 0) return; @@ -1243,8 +1283,6 @@ void LLRender::syncLightState()  void LLRender::syncMatrices()  { -	stop_glerror(); -  	static const U32 name[] =   	{  		LLShaderMgr::MODELVIEW_MATRIX, @@ -1415,8 +1453,6 @@ void LLRender::syncMatrices()  			}  		}  	} - -	stop_glerror();  }  void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) @@ -1927,6 +1963,7 @@ void LLRender::flush()  {  	if (mCount > 0)  	{ +        LL_PROFILE_ZONE_SCOPED;  		if (!mUIOffset.empty())  		{  			sUICalls++; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index c08c2d6881..7f19a45410 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -158,9 +158,20 @@ 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 +    // makes the following assumptions: +    //  - No need for gGL.flush()  +    //  - texture is not null +    //  - gl_tex->getTexName() is not zero +    //  - This texture is not being bound redundantly +    //  - USE_SRGB_DECODE is disabled +    //  - mTexOptionsDirty is false +    //  -  +    void bindFast(LLTexture* texture); +  	// Binds a cubemap to this texture unit   	// (automatically enables the texture unit for cubemaps)  	bool bind(LLCubeMap* cubeMap); @@ -177,6 +188,9 @@ public:  	// (only if there's a texture of the given type currently bound)  	void unbind(eTextureType type); +    // Fast but unsafe version of unbind +    void unbindFast(eTextureType type); +  	// Sets the addressing mode used to sample the texture  	// Warning: this stays set for the bound texture forever,   	// make sure you want to permanently change the address mode  for the bound texture. diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h index 41481fb8a7..256d85ce5a 100644 --- a/indra/llrender/lltexture.h +++ b/indra/llrender/lltexture.h @@ -67,11 +67,9 @@ public:  	virtual S32	       getWidth(S32 discard_level = -1) const;  	virtual S32	       getHeight(S32 discard_level = -1) const;  	virtual bool       isActiveFetching(); +    virtual LLImageGL* getGLTexture() const;  private: -	//note: do not make this function public. -	virtual LLImageGL* getGLTexture() const; -  	virtual void updateBindStatsForTester();  };  #endif diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 0449ac392c..103d5388d3 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -787,6 +787,18 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi  	placeFence();  } +void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const +{ +    mMappable = false; +    gGL.syncMatrices(); + +    U16* idx = ((U16*)(U8*)mAlignedIndexOffset) + indices_offset; + +    LL_PROFILER_GPU_ZONEC("gl.DrawRangeElements", 0xFFFF00) +        glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, +            idx); +} +  void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const  {  	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); @@ -2272,6 +2284,21 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)  	return ret;  } +bool LLVertexBuffer::bindGLBufferFast() +{ +    if (mGLBuffer != sGLRenderBuffer || !sVBOActive) +    { +        glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); +        sGLRenderBuffer = mGLBuffer; +        sBindCount++; +        sVBOActive = true; + +        return true; +    } + +    return false; +} +  static LLTrace::BlockTimerStatHandle FTM_BIND_GL_INDICES("Bind Indices");  bool LLVertexBuffer::bindGLIndices(bool force_bind) @@ -2297,6 +2324,21 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)  	return ret;  } +bool LLVertexBuffer::bindGLIndicesFast() +{ +    if (mGLIndices != sGLRenderIndices || !sIBOActive) +    { +        glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); +        sGLRenderIndices = mGLIndices; +        sBindCount++; +        sIBOActive = true; +         +        return true; +    } + +    return false; +} +  void LLVertexBuffer::flush()  {  	if (useVBOs()) @@ -2487,6 +2529,26 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  	}  } +void LLVertexBuffer::setBufferFast(U32 data_mask) +{ +    //set up pointers if the data mask is different ... +    bool setup = (sLastMask != data_mask); + +     +    const bool bindBuffer = bindGLBufferFast(); +    const bool bindIndices = bindGLIndicesFast(); + +    setup = setup || bindBuffer || bindIndices; + +    setupClientArrays(data_mask); +   +    if (data_mask && setup) +    { +        setupVertexBufferFast(data_mask); +        sSetCount++; +    } +} +  // virtual (default)  void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  { @@ -2644,6 +2706,99 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  	llglassertok();  } +void LLVertexBuffer::setupVertexBufferFast(U32 data_mask) +{ +    U8* base = (U8*)mAlignedOffset; + +    if (data_mask & MAP_NORMAL) +    { +        S32 loc = TYPE_NORMAL; +        void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); +        glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); +    } +    if (data_mask & MAP_TEXCOORD3) +    { +        S32 loc = TYPE_TEXCOORD3; +        void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); +        glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); +    } +    if (data_mask & MAP_TEXCOORD2) +    { +        S32 loc = TYPE_TEXCOORD2; +        void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); +        glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); +    } +    if (data_mask & MAP_TEXCOORD1) +    { +        S32 loc = TYPE_TEXCOORD1; +        void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); +        glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); +    } +    if (data_mask & MAP_TANGENT) +    { +        S32 loc = TYPE_TANGENT; +        void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); +        glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); +    } +    if (data_mask & MAP_TEXCOORD0) +    { +        S32 loc = TYPE_TEXCOORD0; +        void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); +        glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); +    } +    if (data_mask & MAP_COLOR) +    { +        S32 loc = TYPE_COLOR; +        //bind emissive instead of color pointer if emissive is present +        void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); +        glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); +    } +    if (data_mask & MAP_EMISSIVE) +    { +        S32 loc = TYPE_EMISSIVE; +        void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); +        glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + +        if (!(data_mask & MAP_COLOR)) +        { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps +            loc = TYPE_COLOR; +            glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); +        } +    } +    if (data_mask & MAP_WEIGHT) +    { +        S32 loc = TYPE_WEIGHT; +        void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); +        glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); +    } +    if (data_mask & MAP_WEIGHT4) +    { +        S32 loc = TYPE_WEIGHT4; +        void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]); +        glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); +    } +    if (data_mask & MAP_CLOTHWEIGHT) +    { +        S32 loc = TYPE_CLOTHWEIGHT; +        void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); +        glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); +    } +    if (data_mask & MAP_TEXTURE_INDEX) +    { +#if !LL_DARWIN +        S32 loc = TYPE_TEXTURE_INDEX; +        void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); +        glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); +#endif +    } +    if (data_mask & MAP_VERTEX) +    { +        S32 loc = TYPE_VERTEX; +        void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); +        glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); +    } +} +  LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)  : mType(type), mIndex(index), mCount(count)  {  diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 1d60970df4..51ed85510e 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -210,13 +210,17 @@ protected:  	virtual ~LLVertexBuffer(); // use unref() -	virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer() +	virtual void setupVertexBuffer(U32 data_mask); +    void setupVertexBufferFast(U32 data_mask); +  	void setupVertexArray();  	void	genBuffer(U32 size);  	void	genIndices(U32 size);  	bool	bindGLBuffer(bool force_bind = false); +    bool	bindGLBufferFast();  	bool	bindGLIndices(bool force_bind = false); +    bool    bindGLIndicesFast();  	bool	bindGLArray();  	void	releaseBuffer();  	void	releaseIndices(); @@ -239,6 +243,8 @@ public:  	// set for rendering  	virtual void	setBuffer(U32 data_mask); 	// calls  setupVertexBuffer() if data_mask is not 0 +    void	setBufferFast(U32 data_mask); 	// calls setupVertexBufferFast(), assumes data_mask is not 0 among other assumptions +  	void flush(); //flush pending data to GL memory  	// allocate buffer  	bool	allocateBuffer(S32 nverts, S32 nindices, bool create); @@ -290,6 +296,9 @@ public:  	void drawArrays(U32 mode, U32 offset, U32 count) const;  	void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; +    //implementation for inner loops that does no safety checking +    void drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; +  	//for debugging, validate data in given range is valid  	void validateRange(U32 start, U32 end, U32 count, U32 offset) const; 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 0100c3bf0a..1384ddfd82 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -91,6 +91,9 @@ public:      virtual BOOL setCursorPosition(LLCoordWindow position) = 0;  	virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; +#if LL_WINDOWS +    virtual BOOL getCursorDelta(LLCoordCommon* delta) = 0; +#endif  	virtual void showCursor() = 0;  	virtual void hideCursor() = 0;  	virtual BOOL isCursorHidden() = 0; diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index a7ae28aa24..f8ba9bbed4 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -54,6 +54,9 @@ public:      void destroySharedContext(void*)  {}  	/*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;};  	/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; +#if LL_WINDOWS +    /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) { return FALSE; } +#endif  	/*virtual*/ void showCursor() {};  	/*virtual*/ void hideCursor() {};  	/*virtual*/ void showCursorFromMouseMove() {}; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 12d4c6c30e..bf78bcba29 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -28,8 +28,6 @@  #if LL_WINDOWS && !LL_MESA_HEADLESS -#define LL_WINDOW_SINGLE_THREADED 0 -  #include "llwindowwin32.h"  // LLWindow library includes @@ -85,7 +83,7 @@ extern BOOL gDebugWindowProc;  static std::thread::id sWindowThreadId;  static std::thread::id sMainThreadId; -#if 1 || LL_WINDOW_SINGLE_THREADED +#if 1 // flip to zero to enable assertions for functions being called from wrong thread  #define ASSERT_MAIN_THREAD()  #define ASSERT_WINDOW_THREAD()  #else @@ -482,9 +480,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,  {      sMainThreadId = LLThread::currentID();      mWindowThread = new LLWindowWin32Thread(this); -#if !LL_WINDOW_SINGLE_THREADED      mWindowThread->start(); -#endif  	//MAINT-516 -- force a load of opengl32.dll just in case windows went sideways   	LoadLibrary(L"opengl32.dll"); @@ -492,7 +488,6 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,  	mIconResource = gIconResource;  	mOverrideAspectRatio = 0.f;  	mNativeAspectRatio = 0.f; -	mMousePositionModified = FALSE;  	mInputProcessingPaused = FALSE;  	mPreeditor = NULL;  	mKeyCharCode = 0; @@ -814,6 +809,13 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,  	initCursors();  	setCursor( UI_CURSOR_ARROW ); +    mRawMouse.usUsagePage = 0x01;          // HID_USAGE_PAGE_GENERIC +    mRawMouse.usUsage = 0x02;              // HID_USAGE_GENERIC_MOUSE +    mRawMouse.dwFlags = 0;    // adds mouse and also ignores legacy mouse messages +    mRawMouse.hwndTarget = 0; + +    RegisterRawInputDevices(&mRawMouse, 1, sizeof(mRawMouse)); +  	// Initialize (boot strap) the Language text input management,  	// based on the system's (or user's) default settings.  	allowLanguageTextInput(NULL, FALSE); @@ -1927,31 +1929,26 @@ BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position)  {      ASSERT_MAIN_THREAD(); -	if (!mWindowHandle) -	{ -		return FALSE; -	} +    if (!mWindowHandle) +    { +        return FALSE; +    } -    // Inform the application of the new mouse position (needed for per-frame -	// hover/picking to function). -	mCallbacks->handleMouseMove(this, position.convert(), (MASK)0); -	 -    mMousePositionModified = TRUE;      LLCoordScreen screen_pos(position.convert()); -     -    mWindowThread->post([=] + +    // instantly set the cursor position from the app's point of view +    mCursorPosition = position; +    mLastCursorPosition = position; + +    // Inform the application of the new mouse position (needed for per-frame +    // hover/picking to function). +    mCallbacks->handleMouseMove(this, position.convert(), (MASK)0); + +    // actually set the cursor position on the window thread +    mWindowThread->post([=]()          { +            // actually set the OS cursor position              SetCursorPos(screen_pos.mX, screen_pos.mY); -            // DEV-18951 VWR-8524 Camera moves wildly when alt-clicking. -            // Because we have preemptively notified the application of the new -            // mouse position via handleMouseMove() above, we need to clear out -            // any stale mouse move events.  RN/JC -            MSG msg; -            while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) -            { -            } -             -            mMousePositionModified = FALSE;          });      return TRUE; @@ -1960,19 +1957,27 @@ BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position)  BOOL LLWindowWin32::getCursorPosition(LLCoordWindow *position)  {      ASSERT_MAIN_THREAD(); -	POINT cursor_point; - -	if (!mWindowHandle  -		|| !GetCursorPos(&cursor_point) -		|| !position) -	{ -		return FALSE; -	} +    if (!position) +    { +        return FALSE; +    } -	*position = LLCoordScreen(cursor_point.x, cursor_point.y).convert(); +    *position = mCursorPosition;  	return TRUE;  } +BOOL LLWindowWin32::getCursorDelta(LLCoordCommon* delta) +{ +    if (delta == nullptr) +    { +        return FALSE; +    } + +    *delta = mMouseFrameDelta; + +    return TRUE; +} +  void LLWindowWin32::hideCursor()  {      ASSERT_MAIN_THREAD(); @@ -2153,34 +2158,31 @@ void LLWindowWin32::gatherInput()      LL_PROFILE_ZONE_SCOPED      MSG msg; -#if LL_WINDOW_SINGLE_THREADED -    int	msg_count = 0; - -    while ((msg_count < MAX_MESSAGE_PER_UPDATE))      { -        LL_PROFILE_ZONE_NAMED("gi - loop"); -        ++msg_count; -        { -            LL_PROFILE_ZONE_NAMED("gi - PeekMessage"); -            if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) -            { -                break; -            } -        } +        LLMutexLock lock(&mRawMouseMutex); +        mMouseFrameDelta = mRawMouseDelta; -        { -            LL_PROFILE_ZONE_NAMED("gi - translate"); -            TranslateMessage(&msg); -        } +        mRawMouseDelta.mX = 0; +        mRawMouseDelta.mY = 0; +    } -        { -            LL_PROFILE_ZONE_NAMED("gi - dispatch"); -            DispatchMessage(&msg); -        } +    if (mWindowThread->mFunctionQueue.size() > 0) +    { +        LL_PROFILE_ZONE_NAMED("gi - PostMessage"); +        if (mWindowHandle) +        { // post a nonsense user message to wake up the Window Thread in case any functions are pending +            // and no windows events came through this frame +            PostMessage(mWindowHandle, WM_USER + 0x0017, 0xB0B0, 0x1337); +        } +    } +         +    while (mWindowThread->mMessageQueue.tryPopBack(msg)) +    { +        LL_PROFILE_ZONE_NAMED("gi - message queue");          if (mInputProcessingPaused)          { -            break; +            continue;          }          // For async host by name support.  Really hacky. @@ -2190,45 +2192,35 @@ void LLWindowWin32::gatherInput()              gAsyncMsgCallback(msg);          }      } -#else //multi-threaded window impl +      { -        if (mWindowThread->mFunctionQueue.size() > 0) +        LL_PROFILE_ZONE_NAMED("gi - function queue"); +        //process any pending functions +        std::function<void()> curFunc; +        while (mFunctionQueue.tryPopBack(curFunc))          { -            LL_PROFILE_ZONE_NAMED("gi - PostMessage"); -            if (mWindowHandle) -            { // post a nonsense user message to wake up the Window Thread in case any functions are pending -                // and no windows events came through this frame -                PostMessage(mWindowHandle, WM_USER + 0x0017, 0xB0B0, 0x1337); -            } +            curFunc();          } -         -        while (mWindowThread->mMessageQueue.tryPopBack(msg)) -        { -            LL_PROFILE_ZONE_NAMED("gi - message queue"); -            if (mInputProcessingPaused) -            { -                continue; -            } +    } -            // For async host by name support.  Really hacky. -            if (gAsyncMsgCallback && (LL_WM_HOST_RESOLVED == msg.message)) -            { -                LL_PROFILE_ZONE_NAMED("gi - callback"); -                gAsyncMsgCallback(msg); -            } -        } +    // send one and only one mouse move event per frame BEFORE handling mouse button presses +    if (mLastCursorPosition != mCursorPosition) +    { +        LL_PROFILE_ZONE_NAMED("gi - mouse move"); +        mCallbacks->handleMouseMove(this, mCursorPosition.convert(), mMouseMask);      } +     +    mLastCursorPosition = mCursorPosition;      { -        LL_PROFILE_ZONE_NAMED("gi - function queue"); -        //process any pending functions +        LL_PROFILE_ZONE_NAMED("gi - mouse queue"); +        // handle mouse button presses AFTER updating mouse cursor position          std::function<void()> curFunc; -        while (mFunctionQueue.tryPopBack(curFunc)) +        while (mMouseQueue.tryPopBack(curFunc))          {              curFunc();          }      } -#endif  	mInputProcessingPaused = FALSE; @@ -2238,11 +2230,7 @@ void LLWindowWin32::gatherInput()  static LLTrace::BlockTimerStatHandle FTM_KEYHANDLER("Handle Keyboard");  static LLTrace::BlockTimerStatHandle FTM_MOUSEHANDLER("Handle Mouse"); -#if LL_WINDOW_SINGLE_THREADED -#define WINDOW_IMP_POST(x) x -#else  #define WINDOW_IMP_POST(x) window_imp->post([=]() { x; }) -#endif  LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param)  { @@ -2278,10 +2266,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_          // mouse is outside window.          LLCoordWindow window_coord((S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)); -        // This doesn't work, as LOWORD returns unsigned short. -        //LLCoordWindow window_coord(LOWORD(l_param), HIWORD(l_param)); -        LLCoordGL gl_coord; -          // pass along extended flag in mask          MASK mask = (l_param >> 16 & KF_EXTENDED) ? MASK_EXTENDED : 0x0;          BOOL eat_keystroke = TRUE; @@ -2665,35 +2649,19 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_              LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONDOWN");              {                  LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); -                window_imp->post([=]() +                window_imp->postMouseButtonEvent([=]()                      { -                        auto glc = gl_coord;                          sHandleLeftMouseUp = true; - +                                                  if (LLWinImm::isAvailable() && window_imp->mPreeditor)                          {                              window_imp->interruptLanguageTextInput();                          } - -                        // Because we move the cursor position in the app, we need to query -                        // to find out where the cursor at the time the event is handled. -                        // If we don't do this, many clicks could get buffered up, and if the -                        // first click changes the cursor position, all subsequent clicks -                        // will occur at the wrong location.  JC -                        if (window_imp->mMousePositionModified) -                        { -                            LLCoordWindow cursor_coord_window; -                            window_imp->getCursorPosition(&cursor_coord_window); -                            glc = cursor_coord_window.convert(); -                        } -                        else -                        { -                            glc = window_coord.convert(); -                        } +                                                  MASK mask = gKeyboard->currentMask(TRUE); -                        // generate move event to update mouse coordinates -                        window_imp->mCallbacks->handleMouseMove(window_imp, glc, mask); -                        window_imp->mCallbacks->handleMouseDown(window_imp, glc, mask); +                        auto gl_coord = window_imp->mCursorPosition.convert(); +                        window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); +                        window_imp->mCallbacks->handleMouseDown(window_imp, gl_coord, mask);                      });                  return 0; @@ -2704,77 +2672,43 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_          case WM_LBUTTONDBLCLK:          {              LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONDBLCLK"); -            //RN: ignore right button double clicks for now -            //case WM_RBUTTONDBLCLK: -            if (!sHandleDoubleClick) -            { -                sHandleDoubleClick = true; -                return 0; -            } - -            // Because we move the cursor position in the app, we need to query -            // to find out where the cursor at the time the event is handled. -            // If we don't do this, many clicks could get buffered up, and if the -            // first click changes the cursor position, all subsequent clicks -            // will occur at the wrong location.  JC -            if (window_imp->mMousePositionModified) -            { -                LLCoordWindow cursor_coord_window; -                window_imp->getCursorPosition(&cursor_coord_window); -                gl_coord = cursor_coord_window.convert(); -            } -            else -            { -                gl_coord = window_coord.convert(); -            } -            MASK mask = gKeyboard->currentMask(TRUE); -            // generate move event to update mouse coordinates -            window_imp->post([=]() +            window_imp->postMouseButtonEvent([=]()                  { -                    window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); -                    window_imp->mCallbacks->handleDoubleClick(window_imp, gl_coord, mask); +                    //RN: ignore right button double clicks for now +                    //case WM_RBUTTONDBLCLK: +                    if (!sHandleDoubleClick) +                    { +                        sHandleDoubleClick = true; +                        return; +                    } +                    MASK mask = gKeyboard->currentMask(TRUE); + +                    // generate move event to update mouse coordinates +                    window_imp->mCursorPosition = window_coord; +                    window_imp->mCallbacks->handleDoubleClick(window_imp, window_imp->mCursorPosition.convert(), mask);                  }); +              return 0;          }          case WM_LBUTTONUP:          {              LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONUP");              { -                LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - -                if (!sHandleLeftMouseUp) -                { -                    sHandleLeftMouseUp = true; -                    return 0; -                } -                sHandleDoubleClick = true; -                window_imp->post([=]() +                window_imp->postMouseButtonEvent([=]()                      { -                        auto glc = gl_coord; - -                        //if (gDebugClicks) -                        //{ -                        //	LL_INFOS("Window") << "WndProc left button up" << LL_ENDL; -                        //} -                        // Because we move the cursor position in the app, we need to query -                        // to find out where the cursor at the time the event is handled. -                        // If we don't do this, many clicks could get buffered up, and if the -                        // first click changes the cursor position, all subsequent clicks -                        // will occur at the wrong location.  JC -                        if (window_imp->mMousePositionModified) +                        LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); +                        if (!sHandleLeftMouseUp)                          { -                            LLCoordWindow cursor_coord_window; -                            window_imp->getCursorPosition(&cursor_coord_window); -                            glc = cursor_coord_window.convert(); -                        } -                        else -                        { -                            glc = window_coord.convert(); +                            sHandleLeftMouseUp = true; +                            return;                          } +                        sHandleDoubleClick = true; + +                                                  MASK mask = gKeyboard->currentMask(TRUE);                          // generate move event to update mouse coordinates -                        window_imp->mCallbacks->handleMouseMove(window_imp, glc, mask); -                        window_imp->mCallbacks->handleMouseUp(window_imp, glc, mask); +                        window_imp->mCursorPosition = window_coord; +                        window_imp->mCallbacks->handleMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask);                      });              }              return 0; @@ -2785,30 +2719,16 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_              LL_PROFILE_ZONE_NAMED("mwp - WM_RBUTTONDOWN");              {                  LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); -                if (LLWinImm::isAvailable() && window_imp->mPreeditor) -                { -                    WINDOW_IMP_POST(window_imp->interruptLanguageTextInput()); -                } - -                // Because we move the cursor position in the llviewerapp, we need to query -                // to find out where the cursor at the time the event is handled. -                // If we don't do this, many clicks could get buffered up, and if the -                // first click changes the cursor position, all subsequent clicks -                // will occur at the wrong location.  JC -                if (window_imp->mMousePositionModified) -                { -                    LLCoordWindow cursor_coord_window; -                    window_imp->getCursorPosition(&cursor_coord_window); -                    gl_coord = cursor_coord_window.convert(); -                } -                else -                { -                    gl_coord = window_coord.convert(); -                } -                MASK mask = gKeyboard->currentMask(TRUE); -                // generate move event to update mouse coordinates                  window_imp->post([=]()                      { +                        if (LLWinImm::isAvailable() && window_imp->mPreeditor) +                        { +                            WINDOW_IMP_POST(window_imp->interruptLanguageTextInput()); +                        } + +                        MASK mask = gKeyboard->currentMask(TRUE); +                        // generate move event to update mouse coordinates +                        auto gl_coord = window_imp->mCursorPosition.convert();                          window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);                          window_imp->mCallbacks->handleRightMouseDown(window_imp, gl_coord, mask);                      }); @@ -2822,28 +2742,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_              LL_PROFILE_ZONE_NAMED("mwp - WM_RBUTTONUP");              {                  LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); -                // Because we move the cursor position in the app, we need to query -                // to find out where the cursor at the time the event is handled. -                // If we don't do this, many clicks could get buffered up, and if the -                // first click changes the cursor position, all subsequent clicks -                // will occur at the wrong location.  JC -                if (window_imp->mMousePositionModified) -                { -                    LLCoordWindow cursor_coord_window; -                    window_imp->getCursorPosition(&cursor_coord_window); -                    gl_coord = cursor_coord_window.convert(); -                } -                else -                { -                    gl_coord = window_coord.convert(); -                } -                MASK mask = gKeyboard->currentMask(TRUE); -                // generate move event to update mouse coordinates -                window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); -                if (window_imp->mCallbacks->handleRightMouseUp(window_imp, gl_coord, mask)) -                { -                    return 0; -                } +                window_imp->postMouseButtonEvent([=]() +                    { +                        MASK mask = gKeyboard->currentMask(TRUE); +                        window_imp->mCallbacks->handleRightMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask); +                    });              }          }          break; @@ -2854,33 +2757,16 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_              LL_PROFILE_ZONE_NAMED("mwp - WM_MBUTTONDOWN");              {                  LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); -                if (LLWinImm::isAvailable() && window_imp->mPreeditor) -                { -                    window_imp->interruptLanguageTextInput(); -                } +                window_imp->postMouseButtonEvent([=]() +                    { +                        if (LLWinImm::isAvailable() && window_imp->mPreeditor) +                        { +                            window_imp->interruptLanguageTextInput(); +                        } -                // Because we move the cursor position in tllviewerhe app, we need to query -                // to find out where the cursor at the time the event is handled. -                // If we don't do this, many clicks could get buffered up, and if the -                // first click changes the cursor position, all subsequent clicks -                // will occur at the wrong location.  JC -                if (window_imp->mMousePositionModified) -                { -                    LLCoordWindow cursor_coord_window; -                    window_imp->getCursorPosition(&cursor_coord_window); -                    gl_coord = cursor_coord_window.convert(); -                } -                else -                { -                    gl_coord = window_coord.convert(); -                } -                MASK mask = gKeyboard->currentMask(TRUE); -                // generate move event to update mouse coordinates -                window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); -                if (window_imp->mCallbacks->handleMiddleMouseDown(window_imp, gl_coord, mask)) -                { -                    return 0; -                } +                        MASK mask = gKeyboard->currentMask(TRUE); +                        window_imp->mCallbacks->handleMiddleMouseDown(window_imp, window_imp->mCursorPosition.convert(), mask); +                    });              }          }          break; @@ -2890,99 +2776,47 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_              LL_PROFILE_ZONE_NAMED("mwp - WM_MBUTTONUP");              {                  LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); -                // Because we move the cursor position in the llviewer app, we need to query -                // to find out where the cursor at the time the event is handled. -                // If we don't do this, many clicks could get buffered up, and if the -                // first click changes the cursor position, all subsequent clicks -                // will occur at the wrong location.  JC -                if (window_imp->mMousePositionModified) -                { -                    LLCoordWindow cursor_coord_window; -                    window_imp->getCursorPosition(&cursor_coord_window); -                    gl_coord = cursor_coord_window.convert(); -                } -                else -                { -                    gl_coord = window_coord.convert(); -                } -                MASK mask = gKeyboard->currentMask(TRUE); -                // generate move event to update mouse coordinates -                window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); -                if (window_imp->mCallbacks->handleMiddleMouseUp(window_imp, gl_coord, mask)) -                { -                    return 0; -                } +                window_imp->postMouseButtonEvent([=]() +                    { +                        MASK mask = gKeyboard->currentMask(TRUE); +                        window_imp->mCallbacks->handleMiddleMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask); +                    });              }          }          break;          case WM_XBUTTONDOWN:          {              LL_PROFILE_ZONE_NAMED("mwp - WM_XBUTTONDOWN"); -            { -                LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); -                S32 button = GET_XBUTTON_WPARAM(w_param); -                if (LLWinImm::isAvailable() && window_imp->mPreeditor) +            window_imp->postMouseButtonEvent([=]()                  { -                    window_imp->interruptLanguageTextInput(); -                } +                    LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); +                    S32 button = GET_XBUTTON_WPARAM(w_param); +                    if (LLWinImm::isAvailable() && window_imp->mPreeditor) +                    { +                        window_imp->interruptLanguageTextInput(); +                    } -                // Because we move the cursor position in tllviewerhe app, we need to query -                // to find out where the cursor at the time the event is handled. -                // If we don't do this, many clicks could get buffered up, and if the -                // first click changes the cursor position, all subsequent clicks -                // will occur at the wrong location.  JC -                if (window_imp->mMousePositionModified) -                { -                    LLCoordWindow cursor_coord_window; -                    window_imp->getCursorPosition(&cursor_coord_window); -                    gl_coord = cursor_coord_window.convert(); -                } -                else -                { -                    gl_coord = window_coord.convert(); -                } -                MASK mask = gKeyboard->currentMask(TRUE); -                // generate move event to update mouse coordinates -                window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); -                // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 -                if (window_imp->mCallbacks->handleOtherMouseDown(window_imp, gl_coord, mask, button + 3)) -                { -                    return 0; -                } -            } +                    MASK mask = gKeyboard->currentMask(TRUE); +                    // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 +                    window_imp->mCallbacks->handleOtherMouseDown(window_imp, window_imp->mCursorPosition.convert(), mask, button + 3); +                }); +                      }          break;          case WM_XBUTTONUP:          {              LL_PROFILE_ZONE_NAMED("mwp - WM_XBUTTONUP"); -            { -                LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); -                S32 button = GET_XBUTTON_WPARAM(w_param); -                // Because we move the cursor position in the llviewer app, we need to query -                // to find out where the cursor at the time the event is handled. -                // If we don't do this, many clicks could get buffered up, and if the -                // first click changes the cursor position, all subsequent clicks -                // will occur at the wrong location.  JC -                if (window_imp->mMousePositionModified) +            window_imp->postMouseButtonEvent([=]()                  { -                    LLCoordWindow cursor_coord_window; -                    window_imp->getCursorPosition(&cursor_coord_window); -                    gl_coord = cursor_coord_window.convert(); -                } -                else -                { -                    gl_coord = window_coord.convert(); -                } -                MASK mask = gKeyboard->currentMask(TRUE); -                // generate move event to update mouse coordinates -                window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); -                // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 -                if (window_imp->mCallbacks->handleOtherMouseUp(window_imp, gl_coord, mask, button + 3)) -                { -                    return 0; -                } -            } + +                    LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + +                    S32 button = GET_XBUTTON_WPARAM(w_param); +                    MASK mask = gKeyboard->currentMask(TRUE); +                    // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 +                    window_imp->mCallbacks->handleOtherMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask, button + 3); +                });          }          break; @@ -3022,7 +2856,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_              // large deltas, like 480 or so.  Thus we need to scroll more quickly.              if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta)              { -                window_imp->mCallbacks->handleScrollWheel(window_imp, -z_delta / WHEEL_DELTA); +                short clicks = -z_delta / WHEEL_DELTA; +                WINDOW_IMP_POST(window_imp->mCallbacks->handleScrollWheel(window_imp, clicks));                  z_delta = 0;              }              return 0; @@ -3082,11 +2917,16 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_          case WM_MOUSEMOVE:          {              LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEMOVE"); -            if (!window_imp->mMousePositionModified) -            { -                MASK mask = gKeyboard->currentMask(TRUE); -                WINDOW_IMP_POST(window_imp->mCallbacks->handleMouseMove(window_imp, window_coord.convert(), mask)); -            } +            // DO NOT use mouse event queue for move events to ensure cursor position is updated  +            // when button events are handled +            WINDOW_IMP_POST( +                { +                    LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEMOVE lambda"); + +                    MASK mask = gKeyboard->currentMask(TRUE); +                    window_imp->mMouseMask = mask; +                    window_imp->mCursorPosition = window_coord; +                });              return 0;          } @@ -3235,6 +3075,28 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_          }          break; +        case WM_INPUT: +        { +            LL_PROFILE_ZONE_NAMED("MWP - WM_INPUT"); +             +            UINT dwSize = 0; +            GetRawInputData((HRAWINPUT)l_param, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); +            llassert(dwSize < 1024); + +            U8 lpb[1024]; +             +            if (GetRawInputData((HRAWINPUT)l_param, RID_INPUT, (void*)lpb, &dwSize, sizeof(RAWINPUTHEADER)) == dwSize) +            { +                RAWINPUT* raw = (RAWINPUT*)lpb; + +                if (raw->header.dwType == RIM_TYPEMOUSE) +                { +                    LLMutexLock lock(&window_imp->mRawMouseMutex); +                    window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX; +                    window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY; +                } +            } +        }          //list of messages we get often that we don't care to log about          case WM_NCHITTEST:          case WM_NCMOUSEMOVE: @@ -4740,18 +4602,16 @@ inline void LLWindowWin32Thread::run()  void LLWindowWin32Thread::post(const std::function<void()>& func)  { -#if LL_WINDOW_SINGLE_THREADED -    func(); -#else      mFunctionQueue.pushFront(func); -#endif  }  void LLWindowWin32::post(const std::function<void()>& func)  { -#if LL_WINDOW_SINGLE_THREADED -    func(); -#else      mFunctionQueue.pushFront(func); -#endif  } + +void LLWindowWin32::postMouseButtonEvent(const std::function<void()>& func) +{ +    mMouseQueue.pushFront(func); +} + diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 5f253b5df3..b44d458fc6 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -35,6 +35,7 @@  #include "lldragdropwin32.h"  #include "llthread.h"  #include "llthreadsafequeue.h" +#include "llmutex.h"  // Hack for async host by name  #define LL_WM_HOST_RESOLVED      (WM_APP + 1) @@ -98,6 +99,7 @@ public:      void destroySharedContext(void* context) override;  	/*virtual*/ BOOL setCursorPosition(LLCoordWindow position);  	/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); +    /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta);  	/*virtual*/ void showCursor();  	/*virtual*/ void hideCursor();  	/*virtual*/ void showCursorFromMouseMove(); @@ -221,6 +223,14 @@ protected:  	F32			mNativeAspectRatio;  	HCURSOR		mCursor[ UI_CURSOR_COUNT ];  // Array of all mouse cursors +    LLCoordWindow mCursorPosition;  // mouse cursor position, should only be mutated on main thread +    LLMutex mRawMouseMutex; +    RAWINPUTDEVICE mRawMouse; +    LLCoordWindow mLastCursorPosition; // mouse cursor position from previous frame +    LLCoordCommon mRawMouseDelta; // raw mouse delta according to window thread +    LLCoordCommon mMouseFrameDelta; // how much the mouse moved between the last two calls to gatherInput + +    MASK        mMouseMask;  	static BOOL sIsClassRegistered; // has the window class been registered? @@ -231,7 +241,6 @@ protected:  	BOOL		mCustomGammaSet;  	LPWSTR		mIconResource; -	BOOL		mMousePositionModified;  	BOOL		mInputProcessingPaused;  	// The following variables are for Language Text Input control. @@ -261,7 +270,9 @@ protected:      LLWindowWin32Thread* mWindowThread = nullptr;      LLThreadSafeQueue<std::function<void()>> mFunctionQueue; +    LLThreadSafeQueue<std::function<void()>> mMouseQueue;      void post(const std::function<void()>& func); +    void postMouseButtonEvent(const std::function<void()>& func);  	friend class LLWindowManager;      friend class LLWindowWin32Thread; diff --git a/indra/newview/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/lldrawable.cpp b/indra/newview/lldrawable.cpp index 30c4a21e1c..495e06b6f7 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -234,8 +234,6 @@ void LLDrawable::markDead()  LLVOVolume* LLDrawable::getVOVolume() const  { -	LL_PROFILE_ZONE_SCOPED -  	LLViewerObject* objectp = mVObjp;  	if ( !isDead() && objectp && (objectp->getPCode() == LL_PCODE_VOLUME))  	{ diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index d583a692f9..3e4f97e494 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -404,6 +404,7 @@ void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures)  void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)  { +    LL_PROFILE_ZONE_SCOPED;  	for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	  	{  		LLDrawInfo* pparams = *i; @@ -452,6 +453,7 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)  void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  { +    LL_PROFILE_ZONE_SCOPED;      if (!params.mCount)      {          return; @@ -469,7 +471,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba  			{  				if (params.mTextureList[i].notNull())  				{ -					gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); +					gGL.getTexUnit(i)->bindFast(params.mTextureList[i]);  				}  			}  		} @@ -477,8 +479,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba  		{ //not batching textures or batch has only 1 texture -- might need a texture matrix  			if (params.mTexture.notNull())  			{ -				params.mTexture->addTextureStats(params.mVSize); -				gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; +				gGL.getTexUnit(0)->bindFast(params.mTexture);  				if (params.mTextureMatrix)  				{  					tex_setup = true; @@ -490,24 +491,20 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba  			}  			else  			{ -				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +				gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);  			}  		}  	} -	if (params.mVertexBuffer.notNull()) -	{ -		if (params.mGroup) -		{ -			params.mGroup->rebuildMesh(); -		} +    if (params.mGroup) +    { +        params.mGroup->rebuildMesh(); +    } -		LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); -	 -		params.mVertexBuffer->setBuffer(mask); -		params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); -		gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); -	} +    LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); + +    params.mVertexBuffer->setBufferFast(mask); +    params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  	if (tex_setup)  	{ diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 4ee08e869a..369d7a6bb8 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -55,19 +55,7 @@ static BOOL deferred_render = FALSE;  static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETUP("Alpha Setup");  static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");  static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED("Alpha Deferred"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETBUFFER("Alpha SetBuffer"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DRAW("Alpha Draw"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_TEX_BINDS("Alpha Tex Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MATS("Alpha Mat Tex Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GLOW("Alpha Glow Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SHADER_BINDS("Alpha Shader Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS("Alpha Def Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS("Alpha Def Tex Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MESH_REBUILD("Alpha Mesh Rebuild"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_EMISSIVE("Alpha Emissive"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_LIGHT_SETUP("Alpha Light Setup");  LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :  		LLRenderPass(type), current_shader(NULL), target_shader(NULL), @@ -86,6 +74,10 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha()  void LLDrawPoolAlpha::prerender()  {  	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); + +    // TODO: is this even necessay?  These are probably set to never discard +    LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(1024.f*1024.f); +    LLViewerFetchedTexture::sWhiteImagep->addTextureStats(1024.f * 1024.f);  }  S32 LLDrawPoolAlpha::getNumPostDeferredPasses()  @@ -309,7 +301,7 @@ void LLDrawPoolAlpha::render(S32 pass)  		gGL.diffuseColor4f(1,0,0,1);  		LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f); -		gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ; +		gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sSmokeImagep);  		renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |  							LLVertexBuffer::MAP_TEXCOORD0); @@ -358,9 +350,8 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)  				{  					params.mGroup->rebuildMesh();  				} -				params.mVertexBuffer->setBuffer(mask); -				params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); -				gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); +				params.mVertexBuffer->setBufferFast(mask); +				params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  			}  		}  	} @@ -383,27 +374,23 @@ inline bool IsEmissive(LLDrawInfo& params)  inline void Draw(LLDrawInfo* draw, U32 mask)  { -    draw->mVertexBuffer->setBuffer(mask); +    draw->mVertexBuffer->setBufferFast(mask);      LLRenderPass::applyModelMatrix(*draw); -	draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);                     -    gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode); +	draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);                      } -bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader) +bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader* current_shader)  { -    LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_TEX_BINDS);     -      bool tex_setup = false;      if (deferred_render && use_material && current_shader)      { -        LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS);          if (draw->mNormalMap) -		{             +		{  			draw->mNormalMap->addTextureStats(draw->mVSize);  			current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);  		}  -						 +  		if (draw->mSpecularMap)  		{  			draw->mSpecularMap->addTextureStats(draw->mVSize); @@ -412,18 +399,16 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate      }      else if (current_shader == simple_shader)      { -        LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(draw->mVSize);	     -	    LLViewerFetchedTexture::sWhiteImagep->addTextureStats(draw->mVSize); -        current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);						 +        current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);  	    current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);      } -	if (use_shaders && draw->mTextureList.size() > 1) +	if (draw->mTextureList.size() > 1)  	{  		for (U32 i = 0; i < draw->mTextureList.size(); ++i)  		{  			if (draw->mTextureList[i].notNull())  			{ -				gGL.getTexUnit(i)->bind(draw->mTextureList[i], TRUE); +				gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);  			}  		}  	} @@ -431,16 +416,15 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate  	{ //not batching textures or batch has only 1 texture -- might need a texture matrix  		if (draw->mTexture.notNull())  		{ -			draw->mTexture->addTextureStats(draw->mVSize); -			if (use_shaders && use_material) +			if (use_material)  			{  				current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);  			}  			else  			{ -			    gGL.getTexUnit(0)->bind(draw->mTexture, TRUE) ; +			    gGL.getTexUnit(0)->bindFast(draw->mTexture);  			} -						 +  			if (draw->mTextureMatrix)  			{  				tex_setup = true; @@ -452,7 +436,7 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate  		}  		else  		{ -			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +			gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);  		}  	} @@ -470,37 +454,15 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)  	}  } -void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples) -{ -    gPipeline.enableLightsDynamic(); -    simple_shader->bind(); -	simple_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); -	simple_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); -    simple_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); -	simple_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f); -    simple_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 0.0f); -    bool use_shaders = gPipeline.canUseVertexShaders(); -    for (LLDrawInfo* draw : simples) -    { -        bool tex_setup = TexSetup(draw, use_shaders, false, simple_shader); -        LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test); -		gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); - -	    Draw(draw, mask); -        RestoreTexSetup(tex_setup); -    } -    simple_shader->unbind(); -} -  void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights)  {      gPipeline.enableLightsFullbright();      fullbright_shader->bind();      fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f); -    bool use_shaders = gPipeline.canUseVertexShaders(); +          for (LLDrawInfo* draw : fullbrights)      { -        bool tex_setup = TexSetup(draw, use_shaders, false, fullbright_shader); +        bool tex_setup = TexSetup(draw, false, fullbright_shader);          LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);  		gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); @@ -511,65 +473,10 @@ void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& full      fullbright_shader->unbind();  } -void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector<LLDrawInfo*>& materials) -{ -    LLGLSLShader::bindNoShader(); -    current_shader = NULL; - -    gPipeline.enableLightsDynamic(); -    bool use_shaders = gPipeline.canUseVertexShaders(); -    for (LLDrawInfo* draw : materials) -    { -        U32 mask = draw->mShaderMask; - -		llassert(mask < LLMaterial::SHADER_COUNT); -		target_shader = (LLPipeline::sUnderWaterRender) ? &(gDeferredMaterialWaterProgram[mask]) : &(gDeferredMaterialProgram[mask]); - -		if (current_shader != target_shader) -		{ -            LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS); -            if (current_shader) -            { -                gPipeline.unbindDeferredShader(*current_shader); -            } -			gPipeline.bindDeferredShader(*target_shader); -            current_shader = target_shader; -		} -         -        bool tex_setup = TexSetup(draw, use_shaders, true, current_shader); - -        current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, draw->mSpecColor.mV[0], draw->mSpecColor.mV[1], draw->mSpecColor.mV[2], draw->mSpecColor.mV[3]);						 -		current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, draw->mEnvIntensity); -		current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, draw->mFullbright ? 1.f : 0.f); - -        { -            LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS); -			if (draw->mNormalMap) -			{ -				draw->mNormalMap->addTextureStats(draw->mVSize); -				current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap); -			}  -						 -			if (draw->mSpecularMap) -			{ -				draw->mSpecularMap->addTextureStats(draw->mVSize); -				current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap); -			} -        } - -        LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test); -		gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); - -        Draw(draw, mask); -        RestoreTexSetup(tex_setup); -    } -} -  void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)  { -    draw->mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); -	draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); -	gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode); +    draw->mVertexBuffer->setBufferFast((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); +	draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);  }  void LLDrawPoolAlpha::drawEmissiveInline(U32 mask, LLDrawInfo* draw) @@ -599,10 +506,10 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi      // install glow-accumulating blend mode      // don't touch color, add to alpha (glow)  	gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);  -    bool use_shaders = gPipeline.canUseVertexShaders(); +       for (LLDrawInfo* draw : emissives)      { -        bool tex_setup = TexSetup(draw, use_shaders, false, emissive_shader); +        bool tex_setup = TexSetup(draw, false, emissive_shader);          drawEmissive(mask, draw);          RestoreTexSetup(tex_setup);      } @@ -620,8 +527,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  	BOOL initialized_lighting = FALSE;  	BOOL light_enabled = TRUE; -	BOOL use_shaders = gPipeline.canUseVertexShaders(); -		  	for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)  	{  		LLSpatialGroup* group = *i; @@ -631,8 +536,10 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  		if (group->getSpatialPartition()->mRenderByGroup &&  		    !group->isDead())  		{ -            std::vector<LLDrawInfo*> emissives; -            std::vector<LLDrawInfo*> fullbrights; +            static std::vector<LLDrawInfo*> emissives; +            static std::vector<LLDrawInfo*> fullbrights; +            emissives.resize(0); +            fullbrights.resize(0);  			bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE  													  || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; @@ -649,6 +556,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	  			{ +                LL_PROFILE_ZONE_NAMED("ra - push batch")  				LLDrawInfo& params = **k;                  U32 have_mask = params.mVertexBuffer->getTypeMask() & mask;  				if (have_mask != mask) @@ -696,34 +604,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  					// Turn off lighting if it hasn't already been so.  					if (light_enabled || !initialized_lighting)  					{ -                        LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP); -  						initialized_lighting = TRUE; -						if (use_shaders)  -						{ -							target_shader = fullbright_shader; -						} -						else -						{ -							gPipeline.enableLightsFullbright(); -						} +						target_shader = fullbright_shader; +  						light_enabled = FALSE;  					}  				}  				// Turn on lighting if it isn't already.  				else if (!light_enabled || !initialized_lighting)  				{ -                    LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP); -  					initialized_lighting = TRUE; -					if (use_shaders)  -					{ -						target_shader = simple_shader; -					} -					else -					{ -						gPipeline.enableLightsDynamic(); -					} +					target_shader = simple_shader;  					light_enabled = TRUE;  				} @@ -741,7 +632,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  					if (current_shader != target_shader)  					{ -                        LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS);  						gPipeline.bindDeferredShader(*target_shader);                          current_shader = target_shader;  					} @@ -755,25 +645,19 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  					target_shader = fullbright_shader;  				} -				if(use_shaders && (current_shader != target_shader)) +				if(current_shader != target_shader)  				{// If we need shaders, and we're not ALREADY using the proper shader, then bind it  				// (this way we won't rebind shaders unnecessarily). -                    LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SHADER_BINDS);  					current_shader = target_shader;  					current_shader->bind();  				} -				else if (!use_shaders && current_shader != NULL) -				{ -					LLGLSLShader::bindNoShader(); -					current_shader = NULL; -				}                  LLVector4 spec_color(1, 1, 1, 1);                  F32 env_intensity = 0.0f;                  F32 brightness = 1.0f;                  // We have a material.  Supply the appropriate data here. -				if (use_shaders && mat && deferred_render) +				if (mat && deferred_render)  				{  					spec_color    = params.mSpecColor;                      env_intensity = params.mEnvIntensity; @@ -792,20 +676,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  					params.mGroup->rebuildMesh();  				} -                bool tex_setup = TexSetup(¶ms, use_shaders, use_shaders && (mat != nullptr), current_shader); +                bool tex_setup = TexSetup(¶ms, (mat != nullptr), current_shader);  				{ -					LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH); -  					LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);  					gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); -					params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); +					params.mVertexBuffer->setBufferFast(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));                      { -                        LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DRAW); -					    params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); -					    gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); +					    params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);                      }  				} @@ -814,8 +694,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  					draw_glow_for_this_partition &&  					params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))  				{ -                    LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_EMISSIVE); -                      if (batch_emissives)                      {                          emissives.push_back(¶ms); @@ -835,19 +713,29 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  				}  			} + +            bool rebind = false;              if (batch_fullbrights)              { -                light_enabled = false; -                renderFullbrights(mask, fullbrights); +                if (!fullbrights.empty()) +                { +                    light_enabled = false; +                    renderFullbrights(mask, fullbrights); +                    rebind = true; +                }              }              if (batch_emissives)              { -                light_enabled = true; -                renderEmissives(mask, emissives); +                if (!emissives.empty()) +                { +                    light_enabled = true; +                    renderEmissives(mask, emissives); +                    rebind = true; +                }              } -            if (current_shader) +            if (current_shader && rebind)              {                  current_shader->bind();              } diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index a069f805e8..a50b1d929e 100644 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -75,15 +75,13 @@ private:  	LLGLSLShader* fullbright_shader;	  	LLGLSLShader* emissive_shader; -    void renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples);      void renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights); -    void renderMaterials(U32 mask, std::vector<LLDrawInfo*>& fullbrights);      void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);      void drawEmissive(U32 mask, LLDrawInfo* draw);      void drawEmissiveInline(U32 mask, LLDrawInfo* draw); -    bool TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader); +    bool TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader* current_shader);      void RestoreTexSetup(bool tex_setup);  	// our 'normal' alpha blend function for this pass diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 02ab316256..52d308f6bd 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1685,7 +1685,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  				renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);  				renderRigged(avatarp, RIGGED_NORMMAP);  				renderRigged(avatarp, RIGGED_NORMMAP_MASK); -				renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);	 +				renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);  				renderRigged(avatarp, RIGGED_SPECMAP);  				renderRigged(avatarp, RIGGED_SPECMAP_MASK);  				renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); @@ -2067,56 +2067,12 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(  		LLVector4a* pos = (LLVector4a*) position.get();  		LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; -		 -        if (skin == nullptr) -        { -            skin = vobj->getSkinInfo(); -        } -        const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, skin); +        const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, vobj->getMeshID());          const LLMatrix4a* mat = &(mpc.mMatrixPalette[0]); +        const LLMatrix4a& bind_shape_matrix = mpc.mBindShapeMatrix; -        LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); -		const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix; - -#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS -        U8* joint_indices_cursor = vol_face.mJointIndices; -        // fast path with joint indices separate from weights -        if (joint_indices_cursor) -        { -            LLMatrix4a src[4]; -		    for (U32 j = 0; j < buffer->getNumVerts(); ++j) -		    { -			    LLMatrix4a final_mat; -                //LLMatrix4a final_mat_correct; - -                F32* jw = just_weights[j].getF32ptr(); - -                LLSkinningUtil::getPerVertexSkinMatrixWithIndices(jw, joint_indices_cursor, mat, final_mat, src);                 - -                joint_indices_cursor += 4; - -			    LLVector4a& v = vol_face.mPositions[j]; - -			    LLVector4a t; -			    LLVector4a dst; -			    bind_shape_matrix.affineTransform(v, t); -			    final_mat.affineTransform(t, dst); -			    pos[j] = dst; - -			    if (norm) -			    { -				    LLVector4a& n = vol_face.mNormals[j]; -				    bind_shape_matrix.rotate(n, t); -				    final_mat.rotate(t, dst); -				    dst.normalize3fast(); -				    norm[j] = dst; -			    } -		    } -        } -        // slow path with joint indices calculated from weights -        else -#endif +        if (!mpc.mMatrixPalette.empty())          {              for (U32 j = 0; j < buffer->getNumVerts(); ++j)  		    { @@ -2152,9 +2108,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  		return;  	} -	stop_glerror(); - -    const LLMeshSkinInfo* lastSkin = nullptr; +    LLUUID lastMeshId;  	for (U32 i = 0; i < mRiggedFace[type].size(); ++i)  	{ @@ -2188,19 +2142,6 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  			continue;  		} -		const LLMeshSkinInfo* skin = vobj->getSkinInfo(); -		if (!skin) -		{ -			continue; -		} - -		//stop_glerror(); - -		//const LLVolumeFace& vol_face = volume->getVolumeFace(te); -		//updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face); -		 -		//stop_glerror(); -  		U32 data_mask = LLFace::getRiggedDataMask(type);  		LLVertexBuffer* buff = face->getVertexBuffer(); @@ -2290,34 +2231,33 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  		{  			if (sShaderLevel > 0)  			{ -                if (lastSkin != skin) // <== only upload matrix palette to GL if the skininfo changed +                auto& meshId = vobj->getMeshID(); +                 +                if (lastMeshId != meshId) // <== only upload matrix palette to GL if the skininfo changed                  {                      // upload matrix palette to shader -                    const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, skin); +                    const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, meshId);                      U32 count = mpc.mMatrixPalette.size(); -                    stop_glerror(); +                    if (count == 0) +                    { +                        //skin info not loaded yet, don't render +                        continue; +                    }                      LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,                          count,                          FALSE,                          (GLfloat*) &(mpc.mGLMp[0])); - -                    stop_glerror();                  } + +                lastMeshId = meshId;  			}  			else  			{  				data_mask &= ~LLVertexBuffer::MAP_WEIGHT4;  			} -            lastSkin = skin; - -			/*if (glow) -			{ -				gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow()); -			}*/ -  			if (mat)  			{  				//order is important here LLRender::DIFFUSE_MAP should be last, becouse it change  @@ -2332,13 +2272,25 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)                  {                      specular = face->getTexture(LLRender::SPECULAR_MAP);                  } -                if (specular) +                if (specular && specular_channel >= 0)                  { -                    gGL.getTexUnit(specular_channel)->bind(specular); +                    gGL.getTexUnit(specular_channel)->bindFast(specular);                  } -				gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP)); -				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP), false, true); +                if (normal_channel >= 0) +                { +                    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));  				LLColor4 col = mat->getSpecularLightColor(); @@ -2369,23 +2321,28 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  					sVertexProgram->setMinimumAlpha(0.f);  				} -				for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) -				{ -					LLViewerTexture* tex = face->getTexture(i); -					if (tex) -					{ -						tex->addTextureStats(avatar->getPixelArea()); -					} -				} +                if (!LLPipeline::sShadowRender && !LLPipeline::sReflectionRender) +                { +                    for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) +                    { +                        LLViewerTexture* tex = face->getTexture(i); +                        if (tex) +                        { +                            tex->addTextureStats(avatar->getPixelArea()); +                        } +                    } +                }  			}  			else  			{ -				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());  				sVertexProgram->setMinimumAlpha(0.f);  				if (normal_channel > -1)  				{  					LLDrawPoolBump::bindBumpMap(face, normal_channel);  				} + +                gGL.getTexUnit(sDiffuseChannel)->bindFast(face->getTexture()); +  			}  			if (face->mTextureMatrix && vobj->mTexAnimMode) @@ -2399,8 +2356,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				    gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);                  } -				buff->setBuffer(data_mask); -				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); +				buff->setBufferFast(data_mask); +				buff->drawRangeFast(LLRender::TRIANGLES, start, end, count, offset);                  if (tex_index <= 1)                  { @@ -2411,11 +2368,9 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  			}  			else  			{ -				buff->setBuffer(data_mask); -				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);		 +				buff->setBufferFast(data_mask); +				buff->drawRangeFast(LLRender::TRIANGLES, start, end, count, offset);  			} - -			gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);  		}  	}  } @@ -2476,8 +2431,6 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)  				continue;  			} -			stop_glerror(); -  			LLVolumeFace& vol_face = volume->getVolumeFace(te);  			updateRiggedFaceVertexBuffer(avatar, face, vobj, volume, vol_face);  		} @@ -2501,47 +2454,58 @@ void LLDrawPoolAvatar::updateSkinInfoMatrixPalettes(LLVOAvatar* avatarp)      }  } -const LLDrawPoolAvatar::MatrixPaletteCache& LLDrawPoolAvatar::updateSkinInfoMatrixPalette(LLVOAvatar * avatarp, const LLMeshSkinInfo* skin) +const LLDrawPoolAvatar::MatrixPaletteCache& LLDrawPoolAvatar::updateSkinInfoMatrixPalette(LLVOAvatar * avatarp, const LLUUID& meshId)  { -    MatrixPaletteCache& entry = mMatrixPaletteCache[skin]; +    MatrixPaletteCache& entry = mMatrixPaletteCache[meshId];      if (entry.mFrame != gFrameCount)      {          LL_PROFILE_ZONE_SCOPED; + +        const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(meshId);          entry.mFrame = gFrameCount; -        //build matrix palette -        U32 count = LLSkinningUtil::getMeshJointCount(skin); -        entry.mMatrixPalette.resize(count); -        LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, avatarp); -        const LLMatrix4a* mat = &(entry.mMatrixPalette[0]); +        if (skin != nullptr) +        { +            entry.mBindShapeMatrix = skin->mBindShapeMatrix; + +            //build matrix palette +            U32 count = LLSkinningUtil::getMeshJointCount(skin); +            entry.mMatrixPalette.resize(count); +            LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, avatarp); -        stop_glerror(); -         -        entry.mGLMp.resize(count * 12); +            const LLMatrix4a* mat = &(entry.mMatrixPalette[0]); -        F32* mp = &(entry.mGLMp[0]); -         -        for (U32 i = 0; i < count; ++i) -        { -            F32* m = (F32*)mat[i].mMatrix[0].getF32ptr(); +            entry.mGLMp.resize(count * 12); + +            F32* mp = &(entry.mGLMp[0]); + +            for (U32 i = 0; i < count; ++i) +            { +                F32* m = (F32*)mat[i].mMatrix[0].getF32ptr(); -            U32 idx = i * 12; +                U32 idx = i * 12; -            mp[idx + 0] = m[0]; -            mp[idx + 1] = m[1]; -            mp[idx + 2] = m[2]; -            mp[idx + 3] = m[12]; +                mp[idx + 0] = m[0]; +                mp[idx + 1] = m[1]; +                mp[idx + 2] = m[2]; +                mp[idx + 3] = m[12]; -            mp[idx + 4] = m[4]; -            mp[idx + 5] = m[5]; -            mp[idx + 6] = m[6]; -            mp[idx + 7] = m[13]; +                mp[idx + 4] = m[4]; +                mp[idx + 5] = m[5]; +                mp[idx + 6] = m[6]; +                mp[idx + 7] = m[13]; -            mp[idx + 8] = m[8]; -            mp[idx + 9] = m[9]; -            mp[idx + 10] = m[10]; -            mp[idx + 11] = m[14]; +                mp[idx + 8] = m[8]; +                mp[idx + 9] = m[9]; +                mp[idx + 10] = m[10]; +                mp[idx + 11] = m[14]; +            } +        } +        else +        { +            entry.mMatrixPalette.resize(0); +            entry.mGLMp.resize(0);          }      } diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 0c1ee2cced..800bbc5f62 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -283,12 +283,13 @@ typedef enum  	std::vector<LLFace*> mRiggedFace[NUM_RIGGED_PASSES]; +    LL_ALIGN_PREFIX(16)      class MatrixPaletteCache      {      public:          U32 mFrame;          LLMeshSkinInfo::matrix_list_t mMatrixPalette; -         +        LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);          // Float array ready to be sent to GL          std::vector<F32> mGLMp; @@ -296,11 +297,11 @@ typedef enum              mFrame(gFrameCount-1)          {          } -    }; +    } LL_ALIGN_POSTFIX(16); -    const MatrixPaletteCache& updateSkinInfoMatrixPalette(LLVOAvatar* avatarp, const LLMeshSkinInfo* skin); +    const MatrixPaletteCache& updateSkinInfoMatrixPalette(LLVOAvatar* avatarp, const LLUUID& meshId); -    typedef std::unordered_map<const LLMeshSkinInfo*, MatrixPaletteCache> matrix_palette_cache_t; +    typedef std::unordered_map<LLUUID, MatrixPaletteCache> matrix_palette_cache_t;      matrix_palette_cache_t mMatrixPaletteCache;  	/*virtual*/ LLViewerTexture *getDebugTexture(); diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 14069fa6c2..b08fbcbd89 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -677,6 +677,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel)  //static  BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsize, S32 channel)  { +    LL_PROFILE_ZONE_SCOPED;  	//Note: texture atlas does not support bump texture now.  	LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ;  	if(!tex) @@ -693,7 +694,7 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi  		break;  	case BE_BRIGHTNESS:   	case BE_DARKNESS: -		bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );		 +		bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );  		break;  	default: @@ -709,12 +710,13 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi  	{  		if (channel == -2)  		{ -			gGL.getTexUnit(1)->bind(bump); -			gGL.getTexUnit(0)->bind(bump); +			gGL.getTexUnit(1)->bindFast(bump); +			gGL.getTexUnit(0)->bindFast(bump);  		}  		else  		{ -			gGL.getTexUnit(channel)->bind(bump); +            // NOTE: do not use bindFast here (see SL-16222) +            gGL.getTexUnit(channel)->bind(bump);  		}  		return TRUE; @@ -1061,6 +1063,7 @@ void LLBumpImageList::updateImages()  // Note: the caller SHOULD NOT keep the pointer that this function returns.  It may be updated as more data arrives.  LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code )  { +    LL_PROFILE_ZONE_SCOPED;  	llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) );  	LLViewerTexture* bump = NULL; @@ -1497,6 +1500,7 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)  void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  { +    LL_PROFILE_ZONE_SCOPED;  	applyModelMatrix(params);  	bool tex_setup = false; @@ -1507,7 +1511,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL  		{  			if (params.mTextureList[i].notNull())  			{ -				gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); +				gGL.getTexUnit(i)->bindFast(params.mTextureList[i]);  			}  		}  	} @@ -1522,13 +1526,6 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL  			}  			else  			{ -				if (!LLGLSLShader::sNoFixedFunction) -				{ -					gGL.getTexUnit(1)->activate(); -					gGL.matrixMode(LLRender::MM_TEXTURE); -					gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); -				} -  				gGL.getTexUnit(0)->activate();  				gGL.matrixMode(LLRender::MM_TEXTURE);  				gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); @@ -1545,8 +1542,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL  		{  			if (params.mTexture.notNull())  			{ -				gGL.getTexUnit(diffuse_channel)->bind(params.mTexture); -				params.mTexture->addTextureStats(params.mVSize);		 +				gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture);  			}  			else  			{ @@ -1559,10 +1555,10 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL  	{  		params.mGroup->rebuildMesh();  	} -	params.mVertexBuffer->setBuffer(mask); -	params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); -	gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); -	if (tex_setup) +	params.mVertexBuffer->setBufferFast(mask); +	params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + +    if (tex_setup)  	{  		if (mShiny)  		{ @@ -1570,12 +1566,6 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL  		}  		else  		{ -			if (!LLGLSLShader::sNoFixedFunction) -			{ -				gGL.getTexUnit(1)->activate(); -				gGL.matrixMode(LLRender::MM_TEXTURE); -				gGL.loadIdentity(); -			}  			gGL.getTexUnit(0)->activate();  			gGL.matrixMode(LLRender::MM_TEXTURE);  		} diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index 476b1d41b7..bab160c34d 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -32,6 +32,8 @@  #include "lltextureentry.h"  #include "lluuid.h" +#include <unordered_map> +  class LLImageRaw;  class LLSpatialGroup;  class LLDrawInfo; @@ -161,7 +163,7 @@ private:  	static void onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump );  private: -	typedef std::map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t; +	typedef std::unordered_map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t;  	bump_image_map_t mBrightnessEntries;  	bump_image_map_t mDarknessEntries;  }; diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 05b0c1f1a9..d2a8757379 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -106,6 +106,7 @@ void LLDrawPoolMaterials::endDeferredPass(S32 pass)  void LLDrawPoolMaterials::renderDeferred(S32 pass)  { +    LL_PROFILE_ZONE_SCOPED;  	static const U32 type_list[] =   	{  		LLRenderPass::PASS_MATERIAL, @@ -157,7 +158,10 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)  		mShader->setMinimumAlpha(params.mAlphaMaskCutoff);  		mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f); -		pushBatch(params, mask, TRUE); +        { +            LL_PROFILE_ZONE_SCOPED; +            pushMaterialsBatch(params, mask); +        }  	}  } @@ -171,49 +175,37 @@ void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex)  	mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex);  } -void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) +void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask)  { +    LL_PROFILE_ZONE_SCOPED;  	applyModelMatrix(params);  	bool tex_setup = false; -	if (batch_textures && params.mTextureList.size() > 1) +	//not batching textures or batch has only 1 texture -- might need a texture matrix +	if (params.mTextureMatrix)  	{ -		for (U32 i = 0; i < params.mTextureList.size(); ++i) +		//if (mShiny)  		{ -			if (params.mTextureList[i].notNull()) -			{ -				gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); -			} +			gGL.getTexUnit(0)->activate(); +			gGL.matrixMode(LLRender::MM_TEXTURE);  		} -	} -	else -	{ //not batching textures or batch has only 1 texture -- might need a texture matrix -		if (params.mTextureMatrix) -		{ -			//if (mShiny) -			{ -				gGL.getTexUnit(0)->activate(); -				gGL.matrixMode(LLRender::MM_TEXTURE); -			} -			gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); -			gPipeline.mTextureMatrixOps++; +		gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); +		gPipeline.mTextureMatrixOps++; -			tex_setup = true; -		} +		tex_setup = true; +	} -		if (mShaderLevel > 1 && texture) +	if (mShaderLevel > 1) +	{ +		if (params.mTexture.notNull()) +		{ +			gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture); +		} +		else  		{ -			if (params.mTexture.notNull()) -			{ -				gGL.getTexUnit(diffuse_channel)->bind(params.mTexture); -				params.mTexture->addTextureStats(params.mVSize); -			} -			else -			{ -				gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); -			} +			gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE);  		}  	} @@ -224,9 +216,9 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,  	LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); -	params.mVertexBuffer->setBuffer(mask); -	params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); -	gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); +	params.mVertexBuffer->setBufferFast(mask); +	params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); +  	if (tex_setup)  	{  		gGL.getTexUnit(0)->activate(); diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h index eae1aba87c..6e39821b07 100644 --- a/indra/newview/lldrawpoolmaterials.h +++ b/indra/newview/lldrawpoolmaterials.h @@ -69,7 +69,7 @@ public:  	void bindSpecularMap(LLViewerTexture* tex);  	void bindNormalMap(LLViewerTexture* tex); -	/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); +	/*virtual*/ void pushMaterialsBatch(LLDrawInfo& params, U32 mask);  };  #endif //LL_LLDRAWPOOLMATERIALS_H diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 74e6665a96..843288cfb0 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -150,13 +150,6 @@ void LLDrawPoolGlow::render(S32 pass)  	}  } -void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) -{ -	//gGL.diffuseColor4ubv(params.mGlowColor.mV); -	LLRenderPass::pushBatch(params, mask, texture, batch_textures); -} - -  LLDrawPoolSimple::LLDrawPoolSimple() :  	LLRenderPass(POOL_SIMPLE)  { @@ -471,6 +464,7 @@ void LLDrawPoolSimple::endDeferredPass(S32 pass)  void LLDrawPoolSimple::renderDeferred(S32 pass)  { +    LL_PROFILE_ZONE_SCOPED;  	LLGLDisable blend(GL_BLEND);  	LLGLDisable alpha_test(GL_ALPHA_TEST); diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index 608ad9e1eb..b27cc4babc 100644 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -187,7 +187,6 @@ public:  	/*virtual*/ S32 getNumPasses();  	void render(S32 pass = 0); -	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);  }; diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 37dc80e2b7..34a8b6b2cc 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -343,8 +343,6 @@ void LLDrawPoolTerrain::renderFullShader()      LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -    ((LLSettingsVOWater*)pwater.get())->updateShader(shader); -  	//  	// detail texture 1  	// diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 0d5195bdbf..a1ff020068 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -153,6 +153,7 @@ void LLDrawPoolTree::beginDeferredPass(S32 pass)  void LLDrawPoolTree::renderDeferred(S32 pass)  { +    LL_PROFILE_ZONE_SCOPED;  	render(pass);  } diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 0c3d8f3098..8c8dc3f3d2 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -182,8 +182,6 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca          sky_shader->bindTexture(LLShaderMgr::RAINBOW_MAP, rainbow_tex);          sky_shader->bindTexture(LLShaderMgr::HALO_MAP,  halo_tex); -        ((LLSettingsVOSky*)psky.get())->updateShader(sky_shader); -          F32 moisture_level  = (float)psky->getSkyMoistureLevel();          F32 droplet_radius  = (float)psky->getSkyDropletRadius();          F32 ice_level       = (float)psky->getSkyIceLevel(); @@ -406,8 +404,6 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32          cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);          cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor()); -        ((LLSettingsVOSky*)psky.get())->updateShader(cloudshader); -  		/// Render the skydome          renderDome(camPosLocal, camHeightLocal, cloudshader); @@ -462,8 +458,6 @@ void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeigh          cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);          cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor()); -        ((LLSettingsVOSky*)psky.get())->updateShader(cloudshader); -  		/// Render the skydome          renderDome(camPosLocal, camHeightLocal, cloudshader); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 8881d11802..69d3075928 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -1471,6 +1471,7 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::getSharedEnvironmentInstance()  void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool forced)  { +    LL_PROFILE_ZONE_SCOPED;      DayInstance::ptr_t pinstance = getSelectedEnvironmentInstance();      if ((mCurrentEnvironment != pinstance) || forced) @@ -1488,6 +1489,8 @@ void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool f          {              mCurrentEnvironment = pinstance;          } + +        updateSettingsUniforms();      }  } @@ -1614,6 +1617,8 @@ void LLEnvironment::update(const LLViewerCamera * cam)      stop_glerror(); +    updateSettingsUniforms(); +      // *TODO: potential optimization - this block may only need to be      // executed some of the time.  For example for water shaders only.      { @@ -1648,10 +1653,16 @@ void LLEnvironment::updateCloudScroll()  }  // static -void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting) +void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, const LLSettingsBase::ptr_t &psetting)  {      LL_RECORD_BLOCK_TIME(FTM_SHADER_PARAM_UPDATE); +    for (int i = 0; i < LLGLSLShader::SG_COUNT; ++i) +    { +        uniforms[i].clear(); +    } + +    LLShaderUniforms* shader = &uniforms[LLGLSLShader::SG_ANY];      //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL;      LLSettingsBase::parammapping_t params = psetting->getParameterMap();      for (auto &it: params) @@ -1694,7 +1705,7 @@ void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLS          {              LLVector4 vect4(value);              //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL; -            shader->uniform4fv(it.second.getShaderKey(), 1, vect4.mV); +            shader->uniform4fv(it.second.getShaderKey(), vect4 );              break;          } @@ -1707,17 +1718,30 @@ void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLS          default:              break;          } -        stop_glerror();      }      //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL; -    psetting->applySpecial(shader); +    psetting->applySpecial(uniforms); +} + +void LLEnvironment::updateShaderUniforms(LLGLSLShader* shader) +{ +    LL_PROFILE_ZONE_SCOPED; + +    // apply uniforms that should be applied to all shaders +    mSkyUniforms[LLGLSLShader::SG_ANY].apply(shader); +    mWaterUniforms[LLGLSLShader::SG_ANY].apply(shader); + +    // apply uniforms specific to the given shader's shader group +    auto group = shader->mShaderGroup; +    mSkyUniforms[group].apply(shader); +    mWaterUniforms[group].apply(shader);  } -void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader) +void LLEnvironment::updateSettingsUniforms()  { -    updateGLVariablesForSettings(shader, mCurrentEnvironment->getWater()); -    updateGLVariablesForSettings(shader, mCurrentEnvironment->getSky()); +    updateGLVariablesForSettings(mWaterUniforms, mCurrentEnvironment->getWater()); +    updateGLVariablesForSettings(mSkyUniforms, mCurrentEnvironment->getSky());  }  void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envinfo, LLSettingsBase::Seconds transition) @@ -2618,6 +2642,7 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::DayInstance::clone() const  bool LLEnvironment::DayInstance::applyTimeDelta(const LLSettingsBase::Seconds& delta)  { +    LL_PROFILE_ZONE_SCOPED;      ptr_t keeper(shared_from_this());   // makes sure that this does not go away while it is being worked on.      bool changed(false); diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 7cbf2d25bb..3568fbcfd1 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -38,11 +38,12 @@  #include "llatmosphere.h" +#include "llglslshader.h" +  #include <boost/signals2.hpp>  //-------------------------------------------------------------------------  class LLViewerCamera; -class LLGLSLShader;  class LLParcel;  //------------------------------------------------------------------------- @@ -50,8 +51,8 @@ class LLEnvironment : public LLSingleton<LLEnvironment>  {      LLSINGLETON_C11(LLEnvironment);      LOG_CLASS(LLEnvironment); -  public: +      static const F64Seconds     TRANSITION_INSTANT;      static const F64Seconds     TRANSITION_FAST;      static const F64Seconds     TRANSITION_DEFAULT; @@ -131,9 +132,14 @@ public:      void                        update(const LLViewerCamera * cam); -    static void                 updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting); +    static void                 updateGLVariablesForSettings(LLShaderUniforms* uniforms, const LLSettingsBase::ptr_t &psetting); +     +    // apply current sky settings to given shader      void                        updateShaderUniforms(LLGLSLShader *shader); +    // prepare settings to be applied to shaders (call whenever settings are updated) +    void                        updateSettingsUniforms(); +      void                        setSelectedEnvironment(EnvSelection_t env, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, bool forced = false);      EnvSelection_t              getSelectedEnvironment() const                  { return mSelectedEnvironment; } @@ -234,6 +240,11 @@ public:      void                        handleEnvironmentPush(LLSD &message); +    //cached uniform values from LLSD values +    LLShaderUniforms mWaterUniforms[LLGLSLShader::SG_COUNT]; +    LLShaderUniforms mSkyUniforms[LLGLSLShader::SG_COUNT]; +    // ======================================================================================= +      class DayInstance: public std::enable_shared_from_this<DayInstance>      {      public: @@ -288,6 +299,7 @@ public:          LLSettingsDay::ptr_t        mDayCycle;          LLSettingsSky::ptr_t        mSky;          LLSettingsWater::ptr_t      mWater; +          S32                         mSkyTrack;          bool                        mInitialized; 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/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 8ac64dbd15..a19d6d0b19 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4045,7 +4045,7 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo  const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj)  { -	LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); +    LL_PROFILE_ZONE_SCOPED;      if (mesh_id.notNull())      {          skin_map::iterator iter = mSkinMap.find(mesh_id); @@ -4055,6 +4055,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const          }          //no skin info known about given mesh, try to fetch it +        if (requesting_obj != nullptr)          {              LLMutexLock lock(mMeshMutex);              //add volume to list of loading meshes diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index c1698194cb..c0e894fda4 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -586,7 +586,7 @@ public:  	S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);  	static S32 getActualMeshLOD(LLSD& header, S32 lod); -	const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj); +	const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj = nullptr);  	LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);  	void fetchPhysicsShape(const LLUUID& mesh_id);  	bool hasPhysicsShape(const LLUUID& mesh_id); 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/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 1e5b893cbc..6a88a8ef2c 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -637,6 +637,7 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA  //-------------------------------------------------------------------------  void LLSettingsVOSky::updateSettings()  { +    LL_PROFILE_ZONE_SCOPED;      LLSettingsSky::updateSettings();      LLVector3 sun_direction  = getSunDirection();      LLVector3 moon_direction = getMoonDirection(); @@ -665,55 +666,55 @@ void LLSettingsVOSky::updateSettings()  void LLSettingsVOSky::applySpecial(void *ptarget, bool force)  { -    LLGLSLShader *shader = (LLGLSLShader *)ptarget; -      LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm(); -    if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT) +    LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_DEFAULT];  	{         -    shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV); -	shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); +        shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction); +        shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, LLViewerCamera::getInstance()->getOrigin());  	}  -	else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) +     +    shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_SKY];  	{ -    shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV);         +        shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction); -    // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate") -    LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); -    LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() ); +        // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate") +        LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); +        LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() ); -    // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll -    // Keep in Sync! -    // * indra\newview\llsettingsvo.cpp -    // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl -    // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl -    cloud_scroll[0] = -cloud_scroll[0]; -    vect_c_p_d1 += cloud_scroll; -    shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV); +        // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll +        // Keep in Sync! +        // * indra\newview\llsettingsvo.cpp +        // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl +        // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl +        cloud_scroll[0] = -cloud_scroll[0]; +        vect_c_p_d1 += cloud_scroll; +        shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, vect_c_p_d1); -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); +        LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); -    LLColor4 sunDiffuse = psky->getSunlightColor(); -    LLColor4 moonDiffuse = psky->getMoonlightColor(); +        LLVector4 sunDiffuse = LLVector4(psky->getSunlightColor().mV); +        LLVector4 moonDiffuse = LLVector4(psky->getMoonlightColor().mV); -    shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, sunDiffuse.mV); -    shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, moonDiffuse.mV); +        shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse); +        shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse); -    LLColor4 cloud_color(psky->getCloudColor(), 1.0); -    shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, 1, cloud_color.mV); +        LLVector4 cloud_color(LLVector3(psky->getCloudColor().mV), 1.0); +        shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, cloud_color);  	} +    shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_ANY];      shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);      LLColor4 ambient(getTotalAmbient()); -    shader->uniform4fv(LLShaderMgr::AMBIENT, 1, ambient.mV); +    shader->uniform4fv(LLShaderMgr::AMBIENT, LLVector4(ambient.mV));      shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, getIsSunUp() ? 1 : 0);      shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, getSunMoonGlowFactor());      shader->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, getDensityMultiplier());      shader->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER, getDistanceMultiplier()); -    F32 g             = getGamma();     +    F32 g             = getGamma();      F32 display_gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");      shader->uniform1f(LLShaderMgr::GAMMA, g); @@ -907,11 +908,11 @@ LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater)  //-------------------------------------------------------------------------  void LLSettingsVOWater::applySpecial(void *ptarget, bool force)  { -    LLGLSLShader *shader = (LLGLSLShader *)ptarget; -      LLEnvironment& env = LLEnvironment::instance(); -    if (force || (shader->mShaderGroup == LLGLSLShader::SG_WATER)) +    auto group = LLGLSLShader::SG_WATER; +    LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[group]; +      	{          F32 water_height = env.getWaterHeight(); @@ -935,7 +936,7 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)          LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); -        shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, waterPlane.mV); +        shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, waterPlane.mV);          LLVector4 light_direction = env.getClampedLightNorm(); @@ -950,18 +951,19 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)          shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, waterFogDensity);          LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor(), 0.0f); -        shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV); +        shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV);          F32 blend_factor = env.getCurrentWater()->getBlendFactor();          shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);          // update to normal lightnorm, water shader itself will use rotated lightnorm as necessary -        shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, light_direction.mV); +        shader->uniform4fv(LLShaderMgr::LIGHTNORM, light_direction.mV);      }  }  void LLSettingsVOWater::updateSettings()  { +    LL_PROFILE_ZONE_SCOPED;      // base class clears dirty flag so as to not trigger recursive update      LLSettingsBase::updateSettings(); diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h index 65136ad2f5..caa3ac18d3 100644 --- a/indra/newview/llsettingsvo.h +++ b/indra/newview/llsettingsvo.h @@ -102,8 +102,6 @@ public:      bool isAdvanced() const { return  m_isAdvanced; } -    virtual void updateShader(LLGLSLShader* shader) { applySpecial(shader, true); } -  protected:      LLSettingsVOSky(); @@ -136,8 +134,6 @@ public:      static LLSD     convertToLegacy(const ptr_t &); -    virtual void    updateShader(LLGLSLShader* shader) { applySpecial(shader, true); } -  protected:      LLSettingsVOWater(); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 919f386d29..6ef82fac9c 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -41,6 +41,7 @@  #include "llviewercamera.h"  #include "llvector4a.h"  #include <queue> +#include <unordered_map>  #define SG_STATE_INHERIT_MASK (OCCLUDED)  #define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY) @@ -216,10 +217,10 @@ public:  	typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t;  	typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t;  	typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t;  -	typedef std::map<U32, drawmap_elem_t > draw_map_t;	 +	typedef std::unordered_map<U32, drawmap_elem_t > draw_map_t;	  	typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t; -	typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t; -	typedef std::map<U32, buffer_texture_map_t> buffer_map_t; +	typedef std::unordered_map<LLFace*, buffer_list_t> buffer_texture_map_t; +	typedef std::unordered_map<U32, buffer_texture_map_t> buffer_map_t;  	struct CompareDistanceGreater  	{ 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 274f53a160..34847d8618 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -845,14 +845,14 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co  	{  		//flag to reset the values because the old values are used.  		resetMaxVirtualSizeResetCounter(); -		mMaxVirtualSize = virtual_size;		 -		mAdditionalDecodePriority = 0.f;	 +		mMaxVirtualSize = virtual_size; +		mAdditionalDecodePriority = 0.f;  		mNeedsGLTexture = needs_gltexture;  	}  	else if (virtual_size > mMaxVirtualSize)  	{  		mMaxVirtualSize = virtual_size; -	}	 +	}  }  void LLViewerTexture::resetTextureStats() @@ -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 82ece85c1b..ce73037006 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3781,8 +3781,15 @@ void LLViewerWindow::updateLayout()  void LLViewerWindow::updateMouseDelta()  { +#if LL_WINDOWS +    LLCoordCommon delta;  +    mWindow->getCursorDelta(&delta); +    S32 dx = delta.mX; +    S32 dy = delta.mY; +#else  	S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]);  	S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]); +#endif  	//RN: fix for asynchronous notification of mouse leaving window not working  	LLCoordWindow mouse_pos; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e5a4b0f374..b86935b081 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3555,7 +3555,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const  {      if (getVolume())      { -        return gMeshRepo.getSkinInfo(getVolume()->getParams().getSculptID(), this); +        return gMeshRepo.getSkinInfo(getMeshID(), this);      }      else      { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index ce400a3498..b8c6f47bbd 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -296,6 +296,9 @@ public:  	BOOL setIsFlexible(BOOL is_flexible);      const LLMeshSkinInfo* getSkinInfo() const; + +    //convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons) +    const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); }      // Extended Mesh Properties      U32 getExtendedMeshFlags() const; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c0b469af81..c4976c4bbc 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -358,7 +358,6 @@ bool	LLPipeline::sRenderAttachedLights = true;  bool	LLPipeline::sRenderAttachedParticles = true;  bool	LLPipeline::sRenderDeferred = false;  S32		LLPipeline::sVisibleLightCount = 0; -F32		LLPipeline::sMinRenderSize = 0.f;  bool	LLPipeline::sRenderingHUDs;  F32     LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f; @@ -2550,13 +2549,6 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)  		return;  	} -	const LLVector4a* bounds = group->getBounds(); -	if (sMinRenderSize > 0.f &&  -			llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize) -	{ -		return; -	} -  	assertInitialized();  	if (!group->getSpatialPartition()->mRenderByGroup) @@ -3480,7 +3472,6 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)  			group->mLastUpdateDistance = group->mDistance;  		}  	} -  }  void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed) @@ -3787,6 +3778,27 @@ void renderSoundHighlights(LLDrawable* drawablep)  }  } +void LLPipeline::touchTextures(LLDrawInfo* info) +{ +    LL_PROFILE_ZONE_SCOPED; +    for (auto& tex : info->mTextureList) +    { +        if (tex.notNull()) +        { +            LLImageGL* gl_tex = tex->getGLTexture(); +            if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory)) +            { +                tex->setActive(); +            } +        } +    } + +    if (info->mTexture.notNull()) +    { +        info->mTexture->addTextureStats(info->mVSize); +    } +} +  void LLPipeline::postSort(LLCamera& camera)  {  	LL_RECORD_BLOCK_TIME(FTM_STATESORT_POSTSORT); @@ -3839,20 +3851,14 @@ void LLPipeline::postSort(LLCamera& camera)  			for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k)  			{ -				if (sMinRenderSize > 0.f) -				{ -					LLVector4a bounds; -					bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]); - -					if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize) -					{ -						sCull->pushDrawInfo(j->first, *k); -					} -				} -				else -				{ -					sCull->pushDrawInfo(j->first, *k); -				} +                LLDrawInfo* info = *k; +				 +				sCull->pushDrawInfo(j->first, info); +                if (!sShadowRender && !sReflectionRender) +                { +                    touchTextures(info); +                    addTrianglesDrawn(info->mCount, info->mDrawMode); +                }  			}  		} @@ -8421,8 +8427,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_      LLEnvironment& environment = LLEnvironment::instance();      LLSettingsSky::ptr_t sky = environment.getCurrentSky(); - -    static_cast<LLSettingsVOSky*>(sky.get())->updateShader(&shader);  }  LLColor3 pow3f(LLColor3 v, F32 f) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5605d26410..8ffbddca21 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -265,6 +265,8 @@ public:  	void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE);  	void stateSort(LLDrawable* drawablep, LLCamera& camera);  	void postSort(LLCamera& camera); +    //update stats for textures in given DrawInfo +    void touchTextures(LLDrawInfo* info);  	void forAllVisibleDrawables(void (*func)(LLDrawable*));  	void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); @@ -596,7 +598,6 @@ public:  	static bool				sRenderAttachedParticles;  	static bool				sRenderDeferred;  	static S32				sVisibleLightCount; -	static F32				sMinRenderSize;  	static bool				sRenderingHUDs;      static F32              sDistortionWaterClipPlaneMargin; | 
