diff options
147 files changed, 2082 insertions, 1152 deletions
| diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7d6bcd2bc4..60ad7e8fe5 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -42,7 +42,7 @@ jobs:      needs: setup      strategy:        matrix: -        runner: [windows-large, macos-12-large] +        runner: [windows-large, macos-15-xlarge]          configuration: ${{ fromJSON(needs.setup.outputs.configurations) }}      runs-on: ${{ matrix.runner }}      outputs: @@ -64,7 +64,7 @@ jobs:        # autobuild-package.xml.        AUTOBUILD_VCS_INFO: "true"        AUTOBUILD_VSVER: "170" -      DEVELOPER_DIR: "/Applications/Xcode_14.0.1.app/Contents/Developer" +      DEVELOPER_DIR: "/Applications/Xcode_16.1.app/Contents/Developer"        # Ensure that Linden viewer builds engage Bugsplat.        BUGSPLAT_DB: ${{ needs.setup.outputs.bugsplat_db }}        build_coverity: false diff --git a/.github/workflows/tag-release.yaml b/.github/workflows/tag-release.yaml index 65d1d43a83..24ee2de794 100644 --- a/.github/workflows/tag-release.yaml +++ b/.github/workflows/tag-release.yaml @@ -37,7 +37,12 @@ jobs:        - name: Update Tag          uses: actions/github-script@v7.0.1          with: -          github-token: ${{ secrets.GITHUB_TOKEN }} +          # use a real access token instead of GITHUB_TOKEN default. +          # required so that the results of this tag creation can trigger the build workflow +          # https://stackoverflow.com/a/71372524 +          # https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow +          # this token will need to be renewed anually in January +          github-token: ${{ secrets.LL_TAG_RELEASE_TOKEN }}            script: |              github.rest.git.createRef({                owner: context.repo.owner, diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 422927704a..3170dbc180 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -29,6 +29,11 @@ else()    set( USE_AUTOBUILD_3P ON )  endif() +if (NOT DEFINED CMAKE_CXX_STANDARD) +  set(CMAKE_CXX_STANDARD 20) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) +  include(Variables)  include(BuildVersion) diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp index 5f98f2c8c1..47798844bc 100644 --- a/indra/llappearance/llavatarappearancedefines.cpp +++ b/indra/llappearance/llavatarappearancedefines.cpp @@ -300,7 +300,8 @@ EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::strin  LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index ) const  { -    return getTexture(index)->mWearableType; +    auto* tex = getTexture(index); +    return tex ? tex->mWearableType : LLWearableType::WT_INVALID;  }  // static diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index a7e5292fed..f30c147b91 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -652,7 +652,7 @@ void LLWearable::setVisualParamWeight(S32 param_index, F32 value)      }      else      { -        LL_ERRS() << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL; +        LL_WARNS() << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL;      }  } @@ -665,7 +665,7 @@ F32 LLWearable::getVisualParamWeight(S32 param_index) const      }      else      { -        LL_WARNS() << "LLWerable::getVisualParam passed invalid parameter index: "  << param_index << " for wearable type: " << this->getName() << LL_ENDL; +        LL_WARNS() << "LLWearable::getVisualParam passed invalid parameter index: "  << param_index << " for wearable type: " << this->getName() << LL_ENDL;      }      return (F32)-1.0;  } diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h index 1b4aec09b4..e9c96edce3 100644 --- a/indra/llcommon/fsyspath.h +++ b/indra/llcommon/fsyspath.h @@ -68,7 +68,11 @@ public:      }      // shadow base-class string() method with UTF-8 aware method -    std::string string() const { return super::u8string(); } +    std::string string() const +    { +        auto u8 = super::u8string(); +        return std::string(u8.begin(), u8.end()); +    }      // On Posix systems, where value_type is already char, this operator      // std::string() method shadows the base class operator string_type()      // method. But on Windows, where value_type is wchar_t, the base class diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 90c6ba309b..d834098994 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1604,11 +1604,11 @@ namespace LLError      std::string LLUserWarningMsg::sLocalizedOutOfMemoryWarning;      LLUserWarningMsg::Handler LLUserWarningMsg::sHandler; -    void LLUserWarningMsg::show(const std::string& message) +    void LLUserWarningMsg::show(const std::string& message, S32 error_code)      {          if (sHandler)          { -            sHandler(std::string(), message); +            sHandler(std::string(), message, error_code);          }      } @@ -1616,7 +1616,7 @@ namespace LLError      {          if (sHandler && !sLocalizedOutOfMemoryTitle.empty())          { -            sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning); +            sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning, ERROR_BAD_ALLOC);          }      } @@ -1627,7 +1627,7 @@ namespace LLError              "Second Life viewer couldn't access some of the files it needs and will be closed."              "\n\nPlease reinstall viewer from  https://secondlife.com/support/downloads/ and "              "contact https://support.secondlife.com if issue persists after reinstall."; -        sHandler("Missing Files", error_string); +        sHandler("Missing Files", error_string, ERROR_MISSING_FILES);      }      void LLUserWarningMsg::setHandler(const LLUserWarningMsg::Handler &handler) diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 8a143ff30a..41893a35e5 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -308,7 +308,16 @@ namespace LLError      class LLUserWarningMsg      {      public: -        typedef std::function<void(const std::string&, const std::string&)> Handler; +        // error codes, tranlates to last_exec states like LAST_EXEC_OTHER_CRASH +        typedef enum +        { +            ERROR_OTHER = 0, +            ERROR_BAD_ALLOC = 1, +            ERROR_MISSING_FILES = 2, +        } eLastExecEvent; + +        // tittle, message and error code to include in error marker file +        typedef std::function<void(const std::string&, const std::string&, S32 error_code)> Handler;          static void setHandler(const Handler&);          static void setOutOfMemoryStrings(const std::string& title, const std::string& message); @@ -316,7 +325,7 @@ namespace LLError          static void showOutOfMemory();          static void showMissingFiles();          // Genering error -        static void show(const std::string&); +        static void show(const std::string&, S32 error_code = -1);      private:          // needs to be preallocated before viewer runs out of memory diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 1c4ac5a7bf..0196a24b18 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -146,7 +146,7 @@ size_t LLQueuedThread::updateQueue(F32 max_time_ms)          // schedule a call to threadedUpdate for every call to updateQueue          if (!isQuitting())          { -            mRequestQueue.post([=]() +            mRequestQueue.post([=, this]()                  {                      LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update");                      mIdleThread = false; @@ -474,7 +474,7 @@ void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req)  #else                  using namespace std::chrono_literals;                  auto retry_time = LL::WorkQueue::TimePoint::clock::now() + 16ms; -                mRequestQueue.post([=] +                mRequestQueue.post([=, this]                      {                          LL_PROFILE_ZONE_NAMED("processRequest - retry");                          if (LL::WorkQueue::TimePoint::clock::now() < retry_time) diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 082d8b2f9f..075abf9536 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -918,7 +918,7 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const      }      //sd[INV_FLAGS_LABEL] = (S32)mFlags;      sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags); -    sd[INV_SALE_INFO_LABEL] = mSaleInfo; +    sd[INV_SALE_INFO_LABEL] = mSaleInfo.asLLSD();      sd[INV_NAME_LABEL] = mName;      sd[INV_DESC_LABEL] = mDescription;      sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate; diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp index 98836b178e..35bbc1dbb1 100644 --- a/indra/llinventory/llsaleinfo.cpp +++ b/indra/llinventory/llsaleinfo.cpp @@ -89,8 +89,14 @@ bool LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const  LLSD LLSaleInfo::asLLSD() const  { -    LLSD sd = LLSD(); -    sd["sale_type"] = lookup(mSaleType); +    LLSD sd; +    const char* type = lookup(mSaleType); +    if (!type) +    { +        LL_WARNS_ONCE() << "Unknown sale type: " << mSaleType << LL_ENDL; +        type = lookup(LLSaleInfo::FS_NOT); +    } +    sd["sale_type"] = type;      sd["sale_price"] = mSalePrice;      return sd;  } diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 50b458de14..ff28c30563 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -137,7 +137,8 @@ const std::string LLSettingsSky::SETTING_REFLECTION_PROBE_AMBIANCE("reflection_p  const LLUUID LLSettingsSky::DEFAULT_ASSET_ID("651510b8-5f4d-8991-1592-e7eeab2a5a06"); -F32 LLSettingsSky::sAutoAdjustProbeAmbiance = 1.f; +const F32 LLSettingsSky::DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE = 1.f; +F32 LLSettingsSky::sAutoAdjustProbeAmbiance = DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE;  static const LLUUID DEFAULT_SUN_ID("32bfbcea-24b1-fb9d-1ef9-48a28a63730f"); // dataserver  static const LLUUID DEFAULT_MOON_ID("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver @@ -2032,43 +2033,43 @@ F32 LLSettingsSky::getGamma() const      return mGamma;  } -F32 LLSettingsSky::getHDRMin() const +F32 LLSettingsSky::getHDRMin(bool auto_adjust) const  { -    if (mCanAutoAdjust) +    if (mCanAutoAdjust && !auto_adjust)          return 0.f;      return mHDRMin;  } -F32 LLSettingsSky::getHDRMax() const +F32 LLSettingsSky::getHDRMax(bool auto_adjust) const  { -    if (mCanAutoAdjust) +    if (mCanAutoAdjust && !auto_adjust)          return 0.f;      return mHDRMax;  } -F32 LLSettingsSky::getHDROffset() const +F32 LLSettingsSky::getHDROffset(bool auto_adjust) const  { -    if (mCanAutoAdjust) +    if (mCanAutoAdjust && !auto_adjust)          return 1.0f;      return mHDROffset;  } -F32 LLSettingsSky::getTonemapMix() const +F32 LLSettingsSky::getTonemapMix(bool auto_adjust) const  { -    if (mCanAutoAdjust) +    if (mCanAutoAdjust && !auto_adjust) +    { +        // legacy settings do not support tonemaping          return 0.0f; +    }      return mTonemapMix;  }  void LLSettingsSky::setTonemapMix(F32 mix)  { -    if (mCanAutoAdjust) -        return; -      mTonemapMix = mix;  } diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index 4c635fd946..ff75aea549 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -103,6 +103,7 @@ public:      static const LLUUID DEFAULT_ASSET_ID; +    static const F32 DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE;      static F32 sAutoAdjustProbeAmbiance;      typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> ptr_t; @@ -209,10 +210,10 @@ public:      F32 getGamma() const; -    F32 getHDRMin() const; -    F32 getHDRMax() const; -    F32 getHDROffset() const; -    F32 getTonemapMix() const; +    F32 getHDRMin(bool auto_adjust = false) const; +    F32 getHDRMax(bool auto_adjust = false) const; +    F32 getHDROffset(bool auto_adjust = false) const; +    F32 getTonemapMix(bool auto_adjust = false) const;      void setTonemapMix(F32 mix);      void setGamma(F32 val); diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 8ef560dadf..4004852e06 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -33,6 +33,9 @@ class LLRotation;  #include <assert.h>  #include "llpreprocessor.h"  #include "llmemory.h" +#include "glm/vec3.hpp" +#include "glm/vec4.hpp" +#include "glm/gtc/type_ptr.hpp"  ///////////////////////////////////  // FIRST TIME USERS PLEASE READ @@ -364,6 +367,16 @@ public:      inline operator LLQuad() const; +    explicit inline operator glm::vec3() const +    { +        return glm::make_vec3(getF32ptr()); +    }; + +    explicit inline operator glm::vec4() const +    { +        return glm::make_vec4(getF32ptr()); +    }; +  private:      LLQuad mQ{};  }; diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index d063b15c74..a3bfa68060 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -31,6 +31,11 @@  #include "llmath.h"  #include "llsd.h" + +#include "glm/vec3.hpp" +#include "glm/vec4.hpp" +#include "glm/gtc/type_ptr.hpp" +  class LLVector2;  class LLVector4;  class LLVector4a; @@ -66,6 +71,11 @@ class LLVector3          explicit LLVector3(const LLVector4a& vec);              // Initializes LLVector4 to (vec[0]. vec[1], vec[2])          explicit LLVector3(const LLSD& sd); +        // GLM interop +        explicit LLVector3(const glm::vec3& vec);   // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) +        explicit LLVector3(const glm::vec4& vec);   // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) +        explicit inline operator glm::vec3() const; // Initializes glm::vec3 to (vec[0]. vec[1], vec[2]) +        explicit inline operator glm::vec4() const; // Initializes glm::vec4 to (vec[0]. vec[1], vec[2], 1)          LLSD getValue() const; @@ -92,6 +102,8 @@ class LLVector3          inline void set(const F32 *vec);            // Sets LLVector3 to vec          const LLVector3& set(const LLVector4 &vec);          const LLVector3& set(const LLVector3d &vec);// Sets LLVector3 to vec +        inline void set(const glm::vec4& vec); // Sets LLVector3 to vec +        inline void set(const glm::vec3& vec); // Sets LLVector3 to vec          inline void setVec(F32 x, F32 y, F32 z);    // deprecated          inline void setVec(const LLVector3 &vec);   // deprecated @@ -190,6 +202,20 @@ inline LLVector3::LLVector3(const F32 *vec)      mV[VZ] = vec[VZ];  } +inline LLVector3::LLVector3(const glm::vec3& vec) +{ +    mV[VX] = vec.x; +    mV[VY] = vec.y; +    mV[VZ] = vec.z; +} + +inline LLVector3::LLVector3(const glm::vec4& vec) +{ +    mV[VX] = vec.x; +    mV[VY] = vec.y; +    mV[VZ] = vec.z; +} +  /*  inline LLVector3::LLVector3(const LLVector3 ©)  { @@ -259,6 +285,20 @@ inline void LLVector3::set(const F32 *vec)      mV[2] = vec[2];  } +inline void LLVector3::set(const glm::vec4& vec) +{ +    mV[VX] = vec.x; +    mV[VY] = vec.y; +    mV[VZ] = vec.z; +} + +inline void LLVector3::set(const glm::vec3& vec) +{ +    mV[VX] = vec.x; +    mV[VY] = vec.y; +    mV[VZ] = vec.z; +} +  // deprecated  inline void LLVector3::setVec(F32 x, F32 y, F32 z)  { @@ -471,6 +511,17 @@ inline LLVector3 operator-(const LLVector3 &a)      return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] );  } +inline LLVector3::operator glm::vec3() const +{ +    // Do not use glm::make_vec3 it can result in a buffer overrun on some platforms due to glm::vec3 being a simd vector internally +    return glm::vec3(mV[VX], mV[VY], mV[VZ]); +} + +inline LLVector3::operator glm::vec4() const +{ +    return glm::vec4(mV[VX], mV[VY], mV[VZ], 1.f); +} +  inline F32  dist_vec(const LLVector3 &a, const LLVector3 &b)  {      F32 x = a.mV[0] - b.mV[0]; diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h index a5b6f506d7..a4c9668fdd 100644 --- a/indra/llmath/v4math.h +++ b/indra/llmath/v4math.h @@ -32,6 +32,10 @@  #include "v3math.h"  #include "v2math.h" +#include "glm/vec3.hpp" +#include "glm/vec4.hpp" +#include "glm/gtc/type_ptr.hpp" +  class LLMatrix3;  class LLMatrix4;  class LLQuaternion; @@ -73,6 +77,11 @@ class LLVector4              mV[3] = (F32)sd[3].asReal();          } +        // GLM interop +        explicit LLVector4(const glm::vec3& vec); // Initializes LLVector4 to (vec, 1) +        explicit LLVector4(const glm::vec4& vec); // Initializes LLVector4 to vec +        explicit operator glm::vec3() const;      // Initializes glm::vec3 to (vec[0]. vec[1], vec[2]) +        explicit operator glm::vec4() const;      // Initializes glm::vec4 to (vec[0]. vec[1], vec[2], vec[3])          inline bool isFinite() const;                                   // checks to see if all values of LLVector3 are finite @@ -85,6 +94,8 @@ class LLVector4          inline void set(const LLVector4 &vec);          // Sets LLVector4 to vec          inline void set(const LLVector3 &vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec          inline void set(const F32 *vec);                // Sets LLVector4 to vec +        inline void set(const glm::vec4& vec); // Sets LLVector4 to vec +        inline void set(const glm::vec3& vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec with w defaulted to 1          inline void setVec(F32 x, F32 y, F32 z);        // deprecated          inline void setVec(F32 x, F32 y, F32 z, F32 w); // deprecated @@ -223,6 +234,21 @@ inline LLVector4::LLVector4(const LLSD &sd)      setValue(sd);  } +inline LLVector4::LLVector4(const glm::vec3& vec) +{ +    mV[VX] = vec.x; +    mV[VY] = vec.y; +    mV[VZ] = vec.z; +    mV[VW] = 1.f; +} + +inline LLVector4::LLVector4(const glm::vec4& vec) +{ +    mV[VX] = vec.x; +    mV[VY] = vec.y; +    mV[VZ] = vec.z; +    mV[VW] = vec.w; +}  inline bool LLVector4::isFinite() const  { @@ -297,6 +323,21 @@ inline void LLVector4::set(const F32 *vec)      mV[VW] = vec[VW];  } +inline void LLVector4::set(const glm::vec4& vec) +{ +    mV[VX] = vec.x; +    mV[VY] = vec.y; +    mV[VZ] = vec.z; +    mV[VW] = vec.w; +} + +inline void LLVector4::set(const glm::vec3& vec, F32 w) +{ +    mV[VX] = vec.x; +    mV[VY] = vec.y; +    mV[VZ] = vec.z; +    mV[VW] = w; +}  // deprecated  inline void LLVector4::setVec(F32 x, F32 y, F32 z) @@ -466,6 +507,16 @@ inline LLVector4 operator-(const LLVector4 &a)      return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] );  } +inline LLVector4::operator glm::vec3() const +{ +    return glm::vec3(mV[VX], mV[VY], mV[VZ]); +} + +inline LLVector4::operator glm::vec4() const +{ +    return glm::make_vec4(mV); +} +  inline F32  dist_vec(const LLVector4 &a, const LLVector4 &b)  {      LLVector4 vec = a - b; diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp index 4f5e13765a..d0a97dc2c6 100644 --- a/indra/llrender/llcubemaparray.cpp +++ b/indra/llrender/llcubemaparray.cpp @@ -109,7 +109,7 @@ LLCubeMapArray::~LLCubeMapArray()  {  } -void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips) +void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips, bool hdr)  {      U32 texname = 0;      mWidth = resolution; @@ -127,7 +127,11 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool us      bind(0);      free_cur_tex_image(); -    U32 format = components == 4 ? GL_RGBA16F : GL_RGB16F; +    U32 format = components == 4 ? GL_RGBA16F : GL_R11F_G11F_B10F; +    if (!hdr) +    { +        format = components == 4 ? GL_RGBA8 : GL_RGB8; +    }      U32 mip = 0;      U32 mip_resolution = resolution;      while (mip_resolution >= 1) diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h index 675aaaf07c..bfc72a321d 100644 --- a/indra/llrender/llcubemaparray.h +++ b/indra/llrender/llcubemaparray.h @@ -52,7 +52,7 @@ public:      // components - number of components per pixel      // count - number of cube maps in the array      // use_mips - if true, mipmaps will be allocated for this cube map array and anisotropic filtering will be used -    void allocate(U32 res, U32 components, U32 count, bool use_mips = true); +    void allocate(U32 res, U32 components, U32 count, bool use_mips = true, bool hdr = true);      void bind(S32 stage);      void unbind(); diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp index ee9cfd0719..83f5d31186 100644 --- a/indra/llrender/llfontbitmapcache.cpp +++ b/indra/llrender/llfontbitmapcache.cpp @@ -107,7 +107,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp              mBitmapHeight = image_height;              S32 num_components = getNumComponents(bitmap_type); -            mImageRawVec[bitmap_idx].push_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components)); +            mImageRawVec[bitmap_idx].emplace_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components));              bitmap_num = static_cast<U32>(mImageRawVec[bitmap_idx].size()) - 1;              LLImageRaw* image_raw = getImageRaw(bitmap_type, bitmap_num); @@ -117,7 +117,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp              }              // Make corresponding GL image. -            mImageGLVec[bitmap_idx].push_back(new LLImageGL(image_raw, false, false)); +            mImageGLVec[bitmap_idx].emplace_back(new LLImageGL(image_raw, false, false));              LLImageGL* image_gl = getImageGL(bitmap_type, bitmap_num);              // Start at beginning of the new image. diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 6128e03fa7..38dc23d1dc 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -552,7 +552,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l          return NULL;      llassert(!mIsFallback); -    fontp->renderGlyph(requested_glyph_type, glyph_index); +    fontp->renderGlyph(requested_glyph_type, glyph_index, wch);      EFontGlyphType bitmap_glyph_type = EFontGlyphType::Unspecified;      switch (fontp->mFTFace->glyph->bitmap.pixel_mode) @@ -697,7 +697,7 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const      }  } -void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const +void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const  {      if (mFTFace == NULL)          return; @@ -712,11 +712,28 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) co      FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags);      if (FT_Err_Ok != error)      { +        if (error == FT_Err_Out_Of_Memory) +        { +            LLError::LLUserWarningMsg::showOutOfMemory(); +            LL_ERRS() << "Out of memory loading glyph for character " << llformat("U+%xu", U32(wch)) << LL_ENDL; +        } +          std::string message = llformat( -            "Error %d (%s) loading glyph %u: bitmap_type=%u, load_flags=%d", -            error, FT_Error_String(error), glyph_index, bitmap_type, load_flags); +            "Error %d (%s) loading wchar %u glyph %u/%u: bitmap_type=%u, load_flags=%d", +            error, FT_Error_String(error), wch, glyph_index, mFTFace->num_glyphs, bitmap_type, load_flags);          LL_WARNS_ONCE() << message << LL_ENDL;          error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR); +        if (FT_Err_Invalid_Outline == error +            || FT_Err_Invalid_Composite == error +            || (FT_Err_Ok != error && LLStringOps::isEmoji(wch))) +        { +            glyph_index = FT_Get_Char_Index(mFTFace, '?'); +            // if '?' is not present, potentially can use last index, that's supposed to be null glyph +            if (glyph_index > 0) +            { +                error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR); +            } +        }          llassert_always_msg(FT_Err_Ok == error, message.c_str());      } diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index eba89f5def..a2d925c5f6 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -148,6 +148,7 @@ public:      void setStyle(U8 style);      U8 getStyle() const; +    S32 getAddedGlyphs() const { return mAddGlyphCount; }  private:      void resetBitmapCache(); @@ -156,7 +157,7 @@ private:      bool hasGlyph(llwchar wch) const;       // Has a glyph for this character      LLFontGlyphInfo* addGlyph(llwchar wch, EFontGlyphType glyph_type) const;        // Add a new character to the font if necessary      LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType bitmap_type) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) -    void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const; +    void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const;      void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;      std::string mName; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 4c9a062246..4037c036e5 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -58,6 +58,7 @@ F32 LLFontGL::sVertDPI = 96.f;  F32 LLFontGL::sHorizDPI = 96.f;  F32 LLFontGL::sScaleX = 1.f;  F32 LLFontGL::sScaleY = 1.f; +S32 LLFontGL::sResolutionGeneration = 0;  bool LLFontGL::sDisplayFont = true ;  std::string LLFontGL::sAppDir; @@ -109,6 +110,11 @@ S32 LLFontGL::getNumFaces(const std::string& filename)      return mFontFreetype->getNumFaces(filename);  } +S32 LLFontGL::getKnownGlyphCount() const +{ +    return mFontFreetype ? mFontFreetype->getAddedGlyphs() : 0; +} +  S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,      ShadowType shadow, S32 max_chars, F32* right_x, bool use_ellipses, bool use_color) const  { @@ -249,6 +255,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons      const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); +    // This looks wrong, value is dynamic. +    // LLFontBitmapCache::nextOpenPos can alter these values when +    // new characters get added to cache, which affects whole string. +    // Todo: Perhaps value should update after symbols were added?      F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();      F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight(); @@ -270,6 +280,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons      const LLFontGlyphInfo* next_glyph = NULL; +    // string can have more than one glyph per char (ex: bold or shadow), +    // make sure that GLYPH_BATCH_SIZE won't end up with half a symbol. +    // See drawGlyph. +    // Ex: with shadows it's 6 glyps per char. 30 fits exactly 5 chars.      static constexpr S32 GLYPH_BATCH_SIZE = 30;      static thread_local LLVector4a vertices[GLYPH_BATCH_SIZE * 6];      static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 6]; @@ -282,6 +296,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons      std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1);      S32 glyph_count = 0; +    llwchar last_char = wstr[begin_offset];      for (i = begin_offset; i < begin_offset + length; i++)      {          llwchar wch = wstr[i]; @@ -299,7 +314,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons          }          // Per-glyph bitmap texture.          std::pair<EFontGlyphType, S32> next_bitmap_entry = fgi->mBitmapEntry; -        if (next_bitmap_entry != bitmap_entry) +        if (next_bitmap_entry != bitmap_entry || last_char != wch)          {              // Actually draw the queued glyphs before switching their texture;              // otherwise the queued glyphs will be taken from wrong textures. @@ -316,6 +331,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons              bitmap_entry = next_bitmap_entry;              LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);              gGL.getTexUnit(0)->bind(font_image); + +            // For some reason it's not enough to compare by bitmap_entry. +            // Issue hits emojis, japenese and chinese glyphs, only on first run. +            // Todo: figure it out, there might be a bug with raw image data. +            last_char = wch;          }          if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth)) diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 4bb6c55c65..73efc6b1eb 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -90,6 +90,7 @@ public:      bool loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n);      S32 getNumFaces(const std::string& filename); +    S32 getKnownGlyphCount() const;      S32 render(const LLWString &text, S32 begin_offset,                  const LLRect& rect, @@ -224,6 +225,7 @@ public:      static F32 sHorizDPI;      static F32 sScaleX;      static F32 sScaleY; +    static S32 sResolutionGeneration;      static bool sDisplayFont ;      static std::string sAppDir;         // For loading fonts diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp index 5bd1ca5eed..b53a841a87 100644 --- a/indra/llrender/llfontvertexbuffer.cpp +++ b/indra/llrender/llfontvertexbuffer.cpp @@ -146,7 +146,9 @@ S32 LLFontVertexBuffer::render(               || mLastScaleY != LLFontGL::sScaleY               || mLastVertDPI != LLFontGL::sVertDPI               || mLastHorizDPI != LLFontGL::sHorizDPI -             || mLastOrigin != LLFontGL::sCurOrigin) +             || mLastOrigin != LLFontGL::sCurOrigin +             || mLastResGeneration != LLFontGL::sResolutionGeneration +             || mLastFontGlyphCount != fontp->getKnownGlyphCount())      {          genBuffers(fontp, text, begin_offset, x, y, color, halign, valign,              style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color); @@ -201,6 +203,8 @@ void LLFontVertexBuffer::genBuffers(      mLastVertDPI = LLFontGL::sVertDPI;      mLastHorizDPI = LLFontGL::sHorizDPI;      mLastOrigin = LLFontGL::sCurOrigin; +    mLastResGeneration = LLFontGL::sResolutionGeneration; +    mLastFontGlyphCount = fontp->getKnownGlyphCount();      if (right_x)      { diff --git a/indra/llrender/llfontvertexbuffer.h b/indra/llrender/llfontvertexbuffer.h index af195dfff9..d5e1280dbf 100644 --- a/indra/llrender/llfontvertexbuffer.h +++ b/indra/llrender/llfontvertexbuffer.h @@ -117,8 +117,13 @@ private:      F32 mLastScaleY = 1.f;      F32 mLastVertDPI = 0.f;      F32 mLastHorizDPI = 0.f; +    S32 mLastResGeneration = 0;      LLCoordGL mLastOrigin; +    // Adding new characters to bitmap cache can alter value from getBitmapWidth(); +    // which alters whole string. So rerender when new characters were added to cache. +    S32 mLastFontGlyphCount = 0; +      static bool sEnableBufferCollection;  }; diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 58c456f134..873ab0cff5 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -59,6 +59,7 @@ public:      bool attachNothing = false;      bool hasHeroProbes = false;      bool isPBRTerrain = false; +    bool hasTonemap = false;  };  // ============= Structure for caching shader uniforms =============== diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 3858811a50..3f8903ca09 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -330,6 +330,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)      case GL_RGB:                                    return 24;      case GL_SRGB:                                   return 24;      case GL_RGB8:                                   return 24; +    case GL_R11F_G11F_B10F:                         return 32;      case GL_RGBA:                                   return 32;      case GL_RGBA8:                                  return 32;      case GL_RGB10_A2:                               return 32; @@ -1773,7 +1774,7 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name)      ref();      LL::WorkQueue::postMaybe(          mMainQueue, -        [=]() +        [=, this]()          {              LL_PROFILE_ZONE_NAMED("cglt - delete callback");              syncTexName(new_tex_name); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 1d53850f74..1dc87a66ce 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -737,9 +737,8 @@ void LLLightState::setPosition(const LLVector4& position)      ++gGL.mLightHash;      mPosition = position;      //transform position by current modelview matrix -    glm::vec4 pos(glm::make_vec4(position.mV)); -    const glm::mat4& mat = gGL.getModelviewMatrix(); -    pos = mat * pos; +    glm::vec4 pos(position); +    pos = gGL.getModelviewMatrix() * pos;      mPosition.set(glm::value_ptr(pos));  } @@ -794,7 +793,7 @@ void LLLightState::setSpotDirection(const LLVector3& direction)      ++gGL.mLightHash;      //transform direction by current modelview matrix -    glm::vec3 dir(glm::make_vec3(direction.mV)); +    glm::vec3 dir(direction);      const glm::mat3 mat(gGL.getModelviewMatrix());      dir = mat * dir; @@ -2088,12 +2087,14 @@ void set_last_projection(const glm::mat4& mat)  glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec)  { -    //const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; -    //return glm::vec3( -    //    (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w, -    //    (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w, -    //    (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w -    //); +#if 1 // SIMD path results in strange crashes. Fall back to scalar for now. +    const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; +    return glm::vec3( +       (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w, +       (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w, +       (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w +    ); +#else      LLVector4a x, y, z, s, t, p, q;      x.splat(vec.x); @@ -2123,4 +2124,5 @@ glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec)      res.setAdd(x, z);      res.div(q);      return glm::make_vec3(res.getF32ptr()); +#endif  } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 0885740934..4807c12226 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -291,6 +291,14 @@ bool LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)          }      } +    if (features->hasTonemap) +    { +        if (!shader->attachFragmentObject("deferred/tonemapUtilF.glsl")) +        { +            return false; +        } +    } +      // NOTE order of shader object attaching is VERY IMPORTANT!!!      if (features->hasAtmospherics)      { @@ -466,6 +474,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev      if (filename.empty())      { +        LL_WARNS("ShaderLoading") << "tried loading empty filename" << LL_ENDL;          return 0;      } @@ -923,6 +932,8 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev          }          LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;      } + +    LL_DEBUGS("ShaderLoading") << "loadShaderFile() completed, ret: " << U32(ret) << LL_ENDL;      return ret;  } @@ -1389,6 +1400,7 @@ void LLShaderMgr::initAttribsAndUniforms()      mReservedUniforms.push_back("screenTex");      mReservedUniforms.push_back("screenDepth");      mReservedUniforms.push_back("refTex"); +    mReservedUniforms.push_back("exclusionTex");      mReservedUniforms.push_back("eyeVec");      mReservedUniforms.push_back("time");      mReservedUniforms.push_back("waveDir1"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 34bd73a42e..46788841a5 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -36,6 +36,8 @@ public:      LLShaderMgr();      virtual ~LLShaderMgr(); +    // Note: although you can use statically hashed strings to just bind a random uniform, it's generally preferably that you use this. +    // Always document what the actual shader uniform is next to the shader uniform in this struct.      // clang-format off      typedef enum      {                                       // Shader uniform name, set in LLShaderMgr::initAttribsAndUniforms() @@ -234,6 +236,7 @@ public:          WATER_SCREENTEX,                    //  "screenTex"          WATER_SCREENDEPTH,                  //  "screenDepth"          WATER_REFTEX,                       //  "refTex" +        WATER_EXCLUSIONTEX,                 //  "exclusionTex"          WATER_EYEVEC,                       //  "eyeVec"          WATER_TIME,                         //  "time"          WATER_WAVE_DIR1,                    //  "waveDir1" diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 42a9e267d2..b664065532 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -28,6 +28,7 @@  #include "llfolderview.h"  #include "llfolderviewmodel.h" +#include "llcallbacklist.h"  #include "llclipboard.h" // *TODO: remove this once hack below gone.  #include "llkeyboard.h"  #include "lllineeditor.h" @@ -274,7 +275,11 @@ LLFolderView::~LLFolderView( void )      mRenamer = NULL;      mStatusTextBox = NULL; -    if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); +    if (mPopupMenuHandle.get()) +    { +        mPopupMenuHandle.get()->die(); +        gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); +    }      mPopupMenuHandle.markDead();      mAutoOpenItems.removeAllNodes(); @@ -1095,7 +1100,10 @@ bool LLFolderView::handleKeyHere( KEY key, MASK mask )      LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();      if (menu && menu->isOpen())      { -        LLMenuGL::sMenuContainer->hideMenus(); +        if (LLMenuGL::sMenuContainer->hideMenus()) +        { +            gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); +        }      }      switch( key ) @@ -1340,7 +1348,10 @@ bool LLFolderView::handleUnicodeCharHere(llwchar uni_char)          LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();          if (menu && menu->isOpen())          { -            LLMenuGL::sMenuContainer->hideMenus(); +            if (LLMenuGL::sMenuContainer->hideMenus()) +            { +                gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); +            }          }          //do text search @@ -1612,7 +1623,11 @@ void LLFolderView::deleteAllChildren()      {          LLUI::getInstance()->removePopup(mRenamer);      } -    if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); +    if (mPopupMenuHandle.get()) +    { +        mPopupMenuHandle.get()->die(); +        gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); +    }      mPopupMenuHandle.markDead();      mScrollContainer = NULL;      mRenameItem = NULL; @@ -1979,9 +1994,24 @@ void LLFolderView::updateMenu()      LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();      if (menu && menu->getVisible())      { -        updateMenuOptions(menu); +        // When fetching folders in bulk or in parts, each callback +        // cause updateMenu individually, so make sure it gets called +        // only once per frame, after callbacks are done. +        // gIdleCallbacks has built in dupplicate protection. +        gIdleCallbacks.addFunction(onIdleUpdateMenu, this); +    } +} + +void LLFolderView::onIdleUpdateMenu(void* user_data) +{ +    LLFolderView* self = (LLFolderView*)user_data; +    LLMenuGL* menu = (LLMenuGL*)self->mPopupMenuHandle.get(); +    if (menu) +    { +        self->updateMenuOptions(menu);          menu->needsArrange(); // update menu height if needed      } +    gIdleCallbacks.deleteFunction(onIdleUpdateMenu, self);  }  bool LLFolderView::isFolderSelected() diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 62ef2a0626..7ed10d9223 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -266,6 +266,7 @@ public:  private:      void updateMenuOptions(LLMenuGL* menu);      void updateRenamerPosition(); +    static void onIdleUpdateMenu(void* user_data);  protected:      LLScrollContainer* mScrollContainer;  // NULL if this is not a child of a scroll container. @@ -414,6 +415,7 @@ public:      virtual void doItem(LLFolderViewItem* item) {}      void setApply(bool apply);      void clearOpenFolders() { mOpenFolders.clear(); } +    bool hasOpenFolders() { return !mOpenFolders.empty(); }  protected:      std::set<LLUUID> mOpenFolders;      bool mApply; diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index cd80e7f63f..7405413a3d 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1555,7 +1555,7 @@ bool LLNotifications::loadTemplates()          gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS);      if (search_paths.empty())      { -        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); +        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);          LL_ERRS() << "Problem finding notifications.xml" << LL_ENDL;      } @@ -1565,7 +1565,7 @@ bool LLNotifications::loadTemplates()      if (!success || root.isNull() || !root->hasName( "notifications" ))      { -        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); +        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);          LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL;          return false;      } @@ -1576,7 +1576,7 @@ bool LLNotifications::loadTemplates()      if(!params.validateBlock())      { -        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); +        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);          LL_ERRS() << "Problem reading XUI from UI Notifications file: " << base_filename << LL_ENDL;          return false;      } @@ -1643,7 +1643,7 @@ bool LLNotifications::loadVisibilityRules()      if(!params.validateBlock())      { -        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); +        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);          LL_ERRS() << "Problem reading UI Notification Visibility Rules file: " << full_filename << LL_ENDL;          return false;      } diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index df4b0ef6a0..4714665e8b 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -39,7 +39,7 @@ LLStyle::Params::Params()      readonly_color("readonly_color", LLColor4::black),      selected_color("selected_color", LLColor4::black),      alpha("alpha", 1.f), -    font("font", LLFontGL::getFontMonospace()), +    font("font", LLStyle::getDefaultFont()),      image("image"),      link_href("href"),      is_link("is_link") @@ -70,6 +70,11 @@ const LLFontGL* LLStyle::getFont() const      return mFont;  } +const LLFontGL* LLStyle::getDefaultFont() +{ +    return LLFontGL::getFontMonospace(); +} +  void LLStyle::setLinkHREF(const std::string& href)  {      mLink = href; diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index e506895de5..0c78fe5a9f 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -72,6 +72,7 @@ public:      void setFont(const LLFontGL* font);      const LLFontGL* getFont() const; +    static const LLFontGL* getDefaultFont();      const std::string& getLinkHREF() const { return mLink; }      void setLinkHREF(const std::string& href); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index cbbf83d679..fae22fd248 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1438,7 +1438,8 @@ void LLTextBase::onVisibilityChange( bool new_visibility )  //virtual  void LLTextBase::setValue(const LLSD& value )  { -    setText(value.asString()); +    static const LLStyle::Params input_params = LLStyle::Params(); +    setText(value.asString(), input_params);  }  //virtual @@ -3880,8 +3881,7 @@ bool LLInlineViewSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& w          if (mForceNewLine)          {              // Chat, string can't be smaller then font height even if it is empty -            LLStyleSP s(new LLStyle(LLStyle::Params().visible(true))); -            height = s->getFont()->getLineHeight(); +            height = LLStyle::getDefaultFont()->getLineHeight();              return true; // new line          } @@ -3945,9 +3945,7 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)  LLLineBreakTextSegment::LLLineBreakTextSegment(S32 pos):LLTextSegment(pos,pos+1)  { -    LLStyleSP s( new LLStyle(LLStyle::Params().visible(true))); - -    mFontHeight = s->getFont()->getLineHeight(); +    mFontHeight = LLStyle::getDefaultFont()->getLineHeight();  }  LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLTextSegment(pos,pos+1)  { diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 05af36b71e..9f945d3735 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -159,7 +159,8 @@ LLSD LLTextBox::getValue() const  bool LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text )  {      mText.setArg(key, text); -    LLTextBase::setText(mText.getString()); +    static const LLStyle::Params input_params = LLStyle::Params(); +    LLTextBase::setText(mText.getString(), input_params);      return true;  } diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 4af5376a8b..e82af0b96f 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -48,7 +48,7 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s              "Second Life viewer couldn't access some of the files it needs and will be closed."              "\n\nPlease reinstall viewer from  https://secondlife.com/support/downloads/ and "              "contact https://support.secondlife.com if issue persists after reinstall."; -        LLError::LLUserWarningMsg::show(error_string); +        LLError::LLUserWarningMsg::show(error_string, LLError::LLUserWarningMsg::ERROR_MISSING_FILES);          gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);          LL_ERRS() << "Couldn't load string table " << xml_filename << " " << errno << LL_ENDL;          return false; diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index c160382c17..195f68e08b 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -194,6 +194,11 @@ bool LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor,      return false;  } +bool LLWindowCallbacks::handleDisplayChanged() +{ +    return false; +} +  bool LLWindowCallbacks::handleWindowDidChangeScreen(LLWindow *window)  {      return false; diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 63b585231f..d812f93524 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -69,6 +69,7 @@ public:      virtual bool handleTimerEvent(LLWindow *window);      virtual bool handleDeviceChange(LLWindow *window);      virtual bool handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); +    virtual bool handleDisplayChanged();      virtual bool handleWindowDidChangeScreen(LLWindow *window);      enum DragNDropAction { diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index f26d692363..6c3be3eef8 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1060,7 +1060,7 @@ F32 LLWindowMacOSX::getGamma()          &greenGamma,          &blueMin,          &blueMax, -        &blueGamma) == noErr) +        &blueGamma) == kCGErrorSuccess)      {          // So many choices...          // Let's just return the green channel gamma for now. @@ -1111,7 +1111,7 @@ bool LLWindowMacOSX::setGamma(const F32 gamma)          &greenGamma,          &blueMin,          &blueMax, -        &blueGamma) != noErr) +        &blueGamma) != kCGErrorSuccess)      {          return false;      } @@ -1126,7 +1126,7 @@ bool LLWindowMacOSX::setGamma(const F32 gamma)          gamma,          blueMin,          blueMax, -        gamma) != noErr) +        gamma) != kCGErrorSuccess)      {          return false;      } @@ -1178,7 +1178,7 @@ bool LLWindowMacOSX::setCursorPosition(const LLCoordWindow position)      newPosition.y = screen_pos.mY;      CGSetLocalEventsSuppressionInterval(0.0); -    if(CGWarpMouseCursorPosition(newPosition) == noErr) +    if(CGWarpMouseCursorPosition(newPosition) == kCGErrorSuccess)      {          result = true;      } diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 91437b98d1..832cf254d1 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -44,6 +44,7 @@  #include "llstring.h"  #include "lldir.h"  #include "llsdutil.h" +#include "llsys.h"  #include "llglslshader.h"  #include "llthreadsafequeue.h"  #include "stringize.h" @@ -80,10 +81,6 @@ const S32   BITS_PER_PIXEL = 32;  const S32   MAX_NUM_RESOLUTIONS = 32;  const F32   ICON_FLASH_TIME = 0.5f; -#ifndef WM_DPICHANGED -#define WM_DPICHANGED 0x02E0 -#endif -  #ifndef USER_DEFAULT_SCREEN_DPI  #define USER_DEFAULT_SCREEN_DPI 96 // Win7  #endif @@ -1317,8 +1314,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo      catch (...)      {          LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat"); -        OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), -            mCallbacks->translateString("MBError"), OSMB_OK); +        LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);          close();          return false;      } @@ -1329,8 +1325,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo      if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR),          &pfd))      { -        OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), -            mCallbacks->translateString("MBError"), OSMB_OK); +        LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtDescErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);          close();          return false;      } @@ -1368,8 +1363,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo      if (!SetPixelFormat(mhDC, pixel_format, &pfd))      { -        OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), -            mCallbacks->translateString("MBError"), OSMB_OK); +        LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtSetErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);          close();          return false;      } @@ -1377,16 +1371,14 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo      if (!(mhRC = SafeCreateContext(mhDC)))      { -        OSMessageBox(mCallbacks->translateString("MBGLContextErr"), -            mCallbacks->translateString("MBError"), OSMB_OK); +        LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);          close();          return false;      }      if (!wglMakeCurrent(mhDC, mhRC))      { -        OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), -            mCallbacks->translateString("MBError"), OSMB_OK); +        LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextActErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);          close();          return false;      } @@ -1592,15 +1584,14 @@ const   S32   max_format  = (S32)num_formats - 1;          if (!mhDC)          { -            OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); +            LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBDevContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);              close();              return false;          }          if (!SetPixelFormat(mhDC, pixel_format, &pfd))          { -            OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), -                mCallbacks->translateString("MBError"), OSMB_OK); +            LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtSetErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);              close();              return false;          } @@ -1632,7 +1623,7 @@ const   S32   max_format  = (S32)num_formats - 1;      {          LL_WARNS("Window") << "No wgl_ARB_pixel_format extension!" << LL_ENDL;          // cannot proceed without wgl_ARB_pixel_format extension, shutdown same as any other gGLManager.initGL() failure -        OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK); +        LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);          close();          return false;      } @@ -1641,7 +1632,7 @@ const   S32   max_format  = (S32)num_formats - 1;      if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR),          &pfd))      { -        OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), mCallbacks->translateString("MBError"), OSMB_OK); +        LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtDescErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);          close();          return false;      } @@ -1663,14 +1654,14 @@ const   S32   max_format  = (S32)num_formats - 1;      if (!wglMakeCurrent(mhDC, mhRC))      { -        OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), mCallbacks->translateString("MBError"), OSMB_OK); +        LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextActErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);          close();          return false;      }      if (!gGLManager.initGL())      { -        OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK); +        LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);          close();          return false;      } @@ -1875,7 +1866,7 @@ void* LLWindowWin32::createSharedContext()      if (!rc && !(rc = wglCreateContext(mhDC)))      {          close(); -        OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); +        LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);      }      return rc; @@ -2974,6 +2965,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_              return 0;          } +        case WM_DISPLAYCHANGE: +        { +            WINDOW_IMP_POST(window_imp->mCallbacks->handleDisplayChanged()); +        } +          case WM_SETFOCUS:          {              LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SETFOCUS"); @@ -4681,6 +4677,23 @@ void LLWindowWin32::LLWindowWin32Thread::checkDXMem()                      // Alternatively use GetDesc from below to get adapter's memory                      UINT64 budget_mb = info.Budget / (1024 * 1024); +                    if (gGLManager.mIsIntel) +                    { +                        U32Megabytes phys_mb = gSysMemory.getPhysicalMemoryKB(); +                        LL_WARNS() << "Physical memory: " << phys_mb << " MB" << LL_ENDL; + +                        if (phys_mb > 0) +                        { +                            // Intel uses 'shared' vram, cap it to 25% of total memory +                            // Todo: consider caping all adapters at least to 50% ram +                            budget_mb = llmin(budget_mb, (UINT64)(phys_mb * 0.25)); +                        } +                        else +                        { +                            // if no data available, cap to 2Gb +                            budget_mb = llmin(budget_mb, (UINT64)2048); +                        } +                    }                      if (gGLManager.mVRAM < (S32)budget_mb)                      {                          gGLManager.mVRAM = (S32)budget_mb; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5bcfddfe25..d2736c7c12 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -156,6 +156,7 @@ set(viewer_SOURCE_FILES      lldrawpooltree.cpp      lldrawpoolwater.cpp      lldrawpoolwlsky.cpp +    lldrawpoolwaterexclusion.cpp      lldynamictexture.cpp      llemote.cpp      llenvironment.cpp @@ -823,6 +824,7 @@ set(viewer_HEADER_FILES      lldrawpooltree.h      lldrawpoolwater.h      lldrawpoolwlsky.h +    lldrawpoolwaterexclusion.h      lldynamictexture.h      llemote.h      llenvironment.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 07298fa921..4293fa3034 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12717,7 +12717,7 @@      <key>UpdaterWillingToTest</key>      <map>        <key>Comment</key> -      <string>Whether or not the updater should offer test candidate upgrades.</string> +      <string>Whether or not the updater should offer Beta upgrades.</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl index fc6d4d7727..c4610bffac 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl @@ -28,138 +28,11 @@  out vec4 frag_color;  uniform sampler2D diffuseRect; -uniform sampler2D exposureMap; -uniform vec2 screen_res;  in vec2 vary_fragcoord;  vec3 linear_to_srgb(vec3 cl); - -//=============================================================== -// tone mapping taken from Khronos sample implementation -//=============================================================== - -// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT -const mat3 ACESInputMat = mat3 -( -    0.59719, 0.07600, 0.02840, -    0.35458, 0.90834, 0.13383, -    0.04823, 0.01566, 0.83777 -); - - -// ODT_SAT => XYZ => D60_2_D65 => sRGB -const mat3 ACESOutputMat = mat3 -( -    1.60475, -0.10208, -0.00327, -    -0.53108,  1.10813, -0.07276, -    -0.07367, -0.00605,  1.07602 -); - -// ACES tone map (faster approximation) -// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ -vec3 toneMapACES_Narkowicz(vec3 color) -{ -    const float A = 2.51; -    const float B = 0.03; -    const float C = 2.43; -    const float D = 0.59; -    const float E = 0.14; -    return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); -} - - -// ACES filmic tone map approximation -// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl -vec3 RRTAndODTFit(vec3 color) -{ -    vec3 a = color * (color + 0.0245786) - 0.000090537; -    vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; -    return a / b; -} - - -// tone mapping -vec3 toneMapACES_Hill(vec3 color) -{ -    color = ACESInputMat * color; - -    // Apply RRT and ODT -    color = RRTAndODTFit(color); - -    color = ACESOutputMat * color; - -    // Clamp to [0, 1] -    color = clamp(color, 0.0, 1.0); - -    return color; -} - -// Khronos Neutral tonemapping -// https://github.com/KhronosGroup/ToneMapping/tree/main -// Input color is non-negative and resides in the Linear Rec. 709 color space. -// Output color is also Linear Rec. 709, but in the [0, 1] range. -vec3 PBRNeutralToneMapping( vec3 color ) -{ -  const float startCompression = 0.8 - 0.04; -  const float desaturation = 0.15; - -  float x = min(color.r, min(color.g, color.b)); -  float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; -  color -= offset; - -  float peak = max(color.r, max(color.g, color.b)); -  if (peak < startCompression) return color; - -  const float d = 1. - startCompression; -  float newPeak = 1. - d * d / (peak + d - startCompression); -  color *= newPeak / peak; - -  float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.); -  return mix(color, newPeak * vec3(1, 1, 1), g); -} - -uniform float exposure; -uniform float tonemap_mix; -uniform int tonemap_type; - -vec3 toneMap(vec3 color) -{ -#ifndef NO_POST -    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; - -    color *= exposure * exp_scale; - -    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); - -    switch(tonemap_type) -    { -    case 0: -        color = PBRNeutralToneMapping(color); -        break; -    case 1: -        color = toneMapACES_Hill(color); -        break; -    } - -    // mix tonemapped and linear here to provide adjustment -    color = mix(clamped_color, color, tonemap_mix); -#endif - -    return color; -} - -//=============================================================== - -void debugExposure(inout vec3 color) -{ -    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; -    exp_scale *= 0.5; -    if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1) -    { -        color = vec3(1,0,0); -    } -} +vec3 toneMap(vec3 color);  void main()  { diff --git a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl new file mode 100644 index 0000000000..a63b8d7c2b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl @@ -0,0 +1,180 @@ +/** + * @file postDeferredTonemap.glsl + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +/*[EXTRA_CODE_HERE]*/ + +uniform sampler2D exposureMap; +uniform vec2 screen_res; +in vec2 vary_fragcoord; + +//=============================================================== +// tone mapping taken from Khronos sample implementation +//=============================================================== + +// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT +const mat3 ACESInputMat = mat3 +( +    0.59719, 0.07600, 0.02840, +    0.35458, 0.90834, 0.13383, +    0.04823, 0.01566, 0.83777 +); + + +// ODT_SAT => XYZ => D60_2_D65 => sRGB +const mat3 ACESOutputMat = mat3 +( +    1.60475, -0.10208, -0.00327, +    -0.53108,  1.10813, -0.07276, +    -0.07367, -0.00605,  1.07602 +); + +// ACES tone map (faster approximation) +// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ +vec3 toneMapACES_Narkowicz(vec3 color) +{ +    const float A = 2.51; +    const float B = 0.03; +    const float C = 2.43; +    const float D = 0.59; +    const float E = 0.14; +    return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); +} + + +// ACES filmic tone map approximation +// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl +vec3 RRTAndODTFit(vec3 color) +{ +    vec3 a = color * (color + 0.0245786) - 0.000090537; +    vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; +    return a / b; +} + + +// tone mapping +vec3 toneMapACES_Hill(vec3 color) +{ +    color = ACESInputMat * color; + +    // Apply RRT and ODT +    color = RRTAndODTFit(color); + +    color = ACESOutputMat * color; + +    // Clamp to [0, 1] +    color = clamp(color, 0.0, 1.0); + +    return color; +} + +// Khronos Neutral tonemapping +// https://github.com/KhronosGroup/ToneMapping/tree/main +// Input color is non-negative and resides in the Linear Rec. 709 color space. +// Output color is also Linear Rec. 709, but in the [0, 1] range. +vec3 PBRNeutralToneMapping( vec3 color ) +{ +  const float startCompression = 0.8 - 0.04; +  const float desaturation = 0.15; + +  float x = min(color.r, min(color.g, color.b)); +  float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; +  color -= offset; + +  float peak = max(color.r, max(color.g, color.b)); +  if (peak < startCompression) return color; + +  const float d = 1. - startCompression; +  float newPeak = 1. - d * d / (peak + d - startCompression); +  color *= newPeak / peak; + +  float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.); +  return mix(color, newPeak * vec3(1, 1, 1), g); +} + +uniform float exposure; +uniform float tonemap_mix; +uniform int tonemap_type; + +vec3 toneMap(vec3 color) +{ +#ifndef NO_POST +    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; + +    color *= exposure * exp_scale; + +    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); + +    switch(tonemap_type) +    { +    case 0: +        color = PBRNeutralToneMapping(color); +        break; +    case 1: +        color = toneMapACES_Hill(color); +        break; +    } + +    // mix tonemapped and linear here to provide adjustment +    color = mix(clamped_color, color, tonemap_mix); +#endif + +    return color; +} + + +vec3 toneMapNoExposure(vec3 color) +{ +#ifndef NO_POST +    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); + +    switch(tonemap_type) +    { +    case 0: +        color = PBRNeutralToneMapping(color); +        break; +    case 1: +        color = toneMapACES_Hill(color); +        break; +    } + +    // mix tonemapped and linear here to provide adjustment +    color = mix(clamped_color, color, tonemap_mix); +#endif + +    return color; +} + + +//=============================================================== + +void debugExposure(inout vec3 color) +{ +    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; +    exp_scale *= 0.5; +    if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1) +    { +        color = vec3(1,0,0); +    } +} diff --git a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl index d7f6d20547..bf8737615f 100644 --- a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl @@ -41,6 +41,26 @@ vec3 srgb_to_linear(vec3 cs)  } + +vec4 srgb_to_linear4(vec4 cs) +{ +    vec4 low_range = cs / vec4(12.92); +    vec4 high_range = pow((cs+vec4(0.055))/vec4(1.055), vec4(2.4)); +    bvec4 lte = lessThanEqual(cs,vec4(0.04045)); + +#ifdef OLD_SELECT +    vec4 result; +    result.r = lte.r ? low_range.r : high_range.r; +    result.g = lte.g ? low_range.g : high_range.g; +    result.b = lte.b ? low_range.b : high_range.b; +    result.a = lte.a ? low_range.a : high_range.a; +    return result; +#else +    return mix(high_range, low_range, lte); +#endif + +} +  vec3 linear_to_srgb(vec3 cl)  {      cl = clamp(cl, vec3(0), vec3(1)); diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl index 20b61e9302..44a979e565 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -66,11 +66,11 @@ vec4 getWaterFogViewNoClip(vec3 pos)      float t2 = kd + ks * es;      float t3 = pow(F, t2*l) - 1.0; -    float L = min(t1/t2*t3, 1.0); +    float L = pow(min(t1/t2*t3, 1.0), 1.0/1.7);      float D = pow(0.98, l*kd); -    return vec4(srgb_to_linear(kc.rgb*L), D); +    return vec4(srgb_to_linear(kc.rgb)*L, D);  }  vec4 getWaterFogView(vec3 pos) diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl new file mode 100644 index 0000000000..dea76da5a5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl @@ -0,0 +1,57 @@ +/** + * @file simpleColorF.glsl + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +out vec4 frag_color; + +in vec4 vertex_color; +in vec4 vertex_position; + +uniform vec4 waterPlane; +uniform float waterSign; + +void waterClip(vec3 pos) +{ +    // TODO: make this less branchy +    if (waterSign > 0) +    { +        if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) < 0.0) +        { +            discard; +        } +    } +    else +    { +        if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) > 0.0) +        { +            discard; +        } +    } +} + +void main() +{ + +    frag_color = vertex_color; +} diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl new file mode 100644 index 0000000000..4564e56313 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl @@ -0,0 +1,43 @@ +/** + * @file simpleNoAtmosV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_matrix; +uniform mat4 modelview_projection_matrix; + +uniform vec4 color; + +in vec3 position; + +out vec4 vertex_color; +out vec4 vertex_position; + +void main() +{ +    //transform vertex +    vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); +    vertex_position = modelview_projection_matrix * vec4(position.xyz, 1.0); +    gl_Position = vertex_position; +    vertex_color = color; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 3e702f26be..cc9d72fae6 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -150,7 +150,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec          float amb_da = 0.0;//ambiance;          if (da > 0)          { -            lit = max(da * dist_atten,0.0); +            lit = clamp(da * dist_atten, 0.0, 1.0);              col = lit * light_col * diffuse;              amb_da += (da*0.5+0.5) * ambiance;          } diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index 7f871c0d5e..5708fc319f 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -140,7 +140,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe          float amb_da = ambiance;          if (da >= 0)          { -            lit = max(da * dist_atten, 0.0); +            lit = clamp(da * dist_atten, 0.0, 1.0);              col = lit * light_col * diffuse;              amb_da += (da*0.5 + 0.5) * ambiance;          } diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 5dfa196cf6..136b3dd966 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -38,6 +38,8 @@ uniform float max_probe_lod;  uniform bool transparent_surface; +uniform int classic_mode; +  #define MAX_REFMAP_COUNT 256  // must match LL_MAX_REFLECTION_PROBE_COUNT  layout (std140) uniform ReflectionProbes @@ -739,7 +741,10 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,      vec3 refnormpersp = reflect(pos.xyz, norm.xyz); -    ambenv = sampleProbeAmbient(pos, norm, amblit); +    ambenv = amblit; + +    if (classic_mode == 0) +        ambenv = sampleProbeAmbient(pos, norm, amblit);      float lod = (1.0-glossiness)*reflection_lods;      glossenv = sampleProbes(pos, normalize(refnormpersp), lod); @@ -784,9 +789,6 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,      probeIndex[probeInfluences++] = 0;      doProbeSample(ambenv, glossenv, tc, pos, norm, glossiness, false, amblit); - -    // fudge factor to get PBR water at a similar luminance ot legacy water -    glossenv *= 0.4;  }  void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col) @@ -845,7 +847,10 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout      vec3 refnormpersp = reflect(pos.xyz, norm.xyz); -    ambenv = sampleProbeAmbient(pos, norm, amblit); +    ambenv = amblit; + +    if (classic_mode == 0) +        ambenv = sampleProbeAmbient(pos, norm, amblit);      if (glossiness > 0.0)      { diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl index 2bf785e773..091c25d15e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl @@ -35,13 +35,25 @@ vec4 getWaterFogView(vec3 pos);  uniform int above_water; +uniform sampler2D exclusionTex; +  void main()  {      vec2  tc           = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5;      float depth        = getDepth(tc.xy); +    float mask = texture(exclusionTex, tc.xy).r;      if (above_water > 0)      { +        // Just discard if we're in the exclusion mask. +        // The previous invisiprim hack we're replacing would also crank up water fog desntiy. +        // But doing that makes exclusion surfaces very slow as we'd need to render even more into the mask. +        // - Geenz 2025-02-06 +        if (mask < 1) +        { +            discard; +        } +          // we want to depth test when the camera is above water, but some GPUs have a hard time          // with depth testing against render targets that are bound for sampling in the same shader          // so we do it manually here @@ -51,11 +63,13 @@ void main()          {              discard;          } +      }      vec4  pos          = getPositionWithDepth(tc, depth);      vec4 fogged = getWaterFogView(pos.xyz); +    fogged.a = max(pow(fogged.a, 1.7), 0);      frag_color = max(fogged, vec4(0)); //output linear since local lights will be added to this shader's results diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl index 1c02dc764d..fa410e9f11 100644 --- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl @@ -26,6 +26,7 @@  out vec4 frag_color;  uniform sampler2D bumpMap; +uniform sampler2D exclusionTex;  #ifdef TRANSPARENT_WATER  uniform sampler2D screenTex; @@ -59,6 +60,9 @@ void mirrorClip(vec3 position);  void main()  {      mirrorClip(vary_position); +    vec2 screen_tc = (refCoord.xy/refCoord.z) * 0.5 + 0.5; +    float water_mask = texture(exclusionTex, screen_tc).r; +      vec4 color;      //get detail normals @@ -68,8 +72,8 @@ void main()      vec3 wavef = normalize(wave1+wave2+wave3);      //figure out distortion vector (ripply) -    vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; -    distort = distort+wavef.xy*refScale; +    vec2 distort = screen_tc; +    distort = mix(distort, distort+wavef.xy*refScale, water_mask);  #ifdef TRANSPARENT_WATER      vec4 fb = texture(screenTex, distort); diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index 8bf4ec0a7e..35b2f8bd10 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -25,6 +25,8 @@  // class3/environment/waterF.glsl +#define WATER_MINIMAL 1 +  out vec4 frag_color;  #ifdef HAS_SUN_SHADOW @@ -86,23 +88,17 @@ uniform sampler2D screenTex;  uniform sampler2D depthMap;  #endif -uniform sampler2D refTex; +uniform sampler2D exclusionTex; -uniform float sunAngle; -uniform float sunAngle2; +uniform int classic_mode;  uniform vec3 lightDir;  uniform vec3 specular; -uniform float lightExp; +uniform float blurMultiplier;  uniform float refScale;  uniform float kd; -uniform vec2 screenRes;  uniform vec3 normScale;  uniform float fresnelScale;  uniform float fresnelOffset; -uniform float blurMultiplier; -uniform vec4 waterFogColor; -uniform vec3 waterFogColorLinear; -  //bigWave is (refCoord.w, view.w);  in vec4 refCoord; @@ -122,6 +118,10 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2)  vec3 srgb_to_linear(vec3 col);  vec3 linear_to_srgb(vec3 col); +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); +vec3 toneMapNoExposure(vec3 color); +  vec3 vN, vT, vB;  vec3 transform_normal(vec3 vNt) @@ -132,59 +132,107 @@ vec3 transform_normal(vec3 vNt)  void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, vec3 amblit_linear); +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, +        vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear); + +void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +        vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit); + +  vec3 getPositionWithNDC(vec3 ndc); +void generateWaveNormals(out vec3 wave1, out vec3 wave2, out vec3 wave3) +{ +    // Generate all of our wave normals. +    // We layer these back and forth. + +    vec2 bigwave = vec2(refCoord.w, view.w); + +    vec3 wave1_a = texture(bumpMap, bigwave).xyz * 2.0 - 1.0; +    vec3 wave2_a = texture(bumpMap, littleWave.xy).xyz * 2.0 - 1.0; +    vec3 wave3_a = texture(bumpMap, littleWave.zw).xyz * 2.0 - 1.0; + +    vec3 wave1_b = texture(bumpMap2, bigwave).xyz * 2.0 - 1.0; +    vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz * 2.0 - 1.0; +    vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz * 2.0 - 1.0; + +    wave1 = BlendNormal(wave1_a, wave1_b); +    wave2 = BlendNormal(wave2_a, wave2_b); +    wave3 = BlendNormal(wave3_a, wave3_b); +} + +void calculateFresnelFactors(out vec3 df3, out vec2 df2, vec3 viewVec, vec3 wave1, vec3 wave2, vec3 wave3, vec3 wavef) +{ +    // We calculate the fresnel here. +    // We do this by getting the dot product for each sets of waves, and applying scale and offset. + +    df3 = max(vec3(0), vec3( +        dot(viewVec, wave1), +        dot(viewVec, (wave2 + wave3) * 0.5), +        dot(viewVec, wave3) +    ) * fresnelScale + fresnelOffset); + +    df3 *= df3; + +    df2 = max(vec2(0), vec2( +        df3.x + df3.y + df3.z, +        dot(viewVec, wavef) * fresnelScale + fresnelOffset +    )); +} +  void main()  {      mirrorClip(vary_position); +      vN = vary_normal;      vT = vary_tangent;      vB = cross(vN, vT);      vec3 pos = vary_position.xyz; +    float linear_depth = 1 / -pos.z;      float dist = length(pos.xyz);      //normalize view vector      vec3 viewVec = normalize(pos.xyz); -    //get wave normals -    vec2 bigwave = vec2(refCoord.w, view.w); -    vec3 wave1_a = texture(bumpMap, bigwave, -2      ).xyz*2.0-1.0; -    vec3 wave2_a = texture(bumpMap, littleWave.xy).xyz*2.0-1.0; -    vec3 wave3_a = texture(bumpMap, littleWave.zw).xyz*2.0-1.0; +    // Setup our waves. -    vec3 wave1_b = texture(bumpMap2, bigwave      ).xyz*2.0-1.0; -    vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz*2.0-1.0; -    vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz*2.0-1.0; +    vec3 wave1 = vec3(0, 0, 1); +    vec3 wave2 = vec3(0, 0, 1); +    vec3 wave3 = vec3(0, 0, 1); -    //wave1_a = wave2_a = wave3_a = wave1_b = wave2_b = wave3_b = vec3(0,0,1); - -    vec3 wave1 = BlendNormal(wave1_a, wave1_b); -    vec3 wave2 = BlendNormal(wave2_a, wave2_b); -    vec3 wave3 = BlendNormal(wave3_a, wave3_b); +    generateWaveNormals(wave1, wave2, wave3); +    float dmod = sqrt(dist);      vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; -    //wave1 = transform_normal(wave1); -    //wave2 = transform_normal(wave2); -    //wave3 = transform_normal(wave3); -      vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; +    vec3 df3 = vec3(0); +    vec2 df2 = vec2(0); + +    vec3 sunlit; +    vec3 amblit; +    vec3 additive; +    vec3 atten; +    calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten); + +    calculateFresnelFactors(df3, df2, normalize(view.xyz), wave1, wave2, wave3, wavef); +      vec3 waver = wavef*3;      vec3 up = transform_normal(vec3(0,0,1));      float vdu = -dot(viewVec, up)*2; -    vec3 wave_ibl = wavef; +    vec3 wave_ibl = wavef * normScale;      wave_ibl.z *= 2.0;      wave_ibl = transform_normal(normalize(wave_ibl));      vec3 norm = transform_normal(normalize(wavef));      vdu = clamp(vdu, 0, 1); -    wavef.z *= max(vdu*vdu*vdu, 0.1); +    //wavef.z *= max(vdu*vdu*vdu, 0.1);      wavef = normalize(wavef); @@ -194,62 +242,66 @@ void main()      float dist2 = dist;      dist = max(dist, 5.0); -    float dmod = sqrt(dist); -      //figure out distortion vector (ripply) -    vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0); +    vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0) * 2;      distort2 = clamp(distort2, vec2(0), vec2(0.999)); -    vec3 sunlit; -    vec3 amblit; -    vec3 additive; -    vec3 atten; -      float shadow = 1.0f; +    float water_mask = texture(exclusionTex, distort).r; +  #ifdef HAS_SUN_SHADOW      shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, distort);  #endif -    calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten); -      vec3 sunlit_linear = srgb_to_linear(sunlit); - +    float fade = 1;  #ifdef TRANSPARENT_WATER -    vec4 fb = texture(screenTex, distort2); -    float depth = texture(depthMap, distort2).r; -    vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0)); +    float depth = texture(depthMap, distort).r; + +    vec3 refPos = getPositionWithNDC(vec3(distort*2.0-vec2(1.0), depth*2.0-1.0)); + +    // Calculate some distance fade in the water to better assist with refraction blending and reducing the refraction texture's "disconnect". +    fade = max(0,min(1, (pos.z - refPos.z) / 10)) * water_mask; +    distort2 = mix(distort, distort2, min(1, fade * 10)); +    depth = texture(depthMap, distort2).r; + +    refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0)); -    if (refPos.z > pos.z-0.05) +    if (pos.z < refPos.z - 0.05)      { -        //we sampled an above water sample, don't distort          distort2 = distort; -        fb = texture(screenTex, distort2); -        depth = texture(depthMap, distort2).r; -        refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));      } +    vec4 fb = texture(screenTex, distort2); +  #else      vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0)); -#endif -    // fudge sample on other side of water to be a tad darker -    fb.rgb *= 0.75; +    if (water_mask < 1) +        discard; +#endif -    float metallic = 0.0; -    float perceptualRoughness = 0.05; -    float gloss      = 1.0 - perceptualRoughness; +    float metallic = 1.0; +    float perceptualRoughness = blurMultiplier; +    float gloss      = 1 - perceptualRoughness;      vec3  irradiance = vec3(0);      vec3  radiance  = vec3(0); -    sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit); +    vec3 legacyenv = vec3(0); -    irradiance       = vec3(0); +    // TODO: Make this an option. +#ifdef WATER_MINIMAL +    sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit); +#elif WATER_MINIMAL_PLUS +    sampleReflectionProbes(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, false, amblit); +#endif      vec3 diffuseColor = vec3(0);      vec3 specularColor = vec3(0); -    calcDiffuseSpecular(vec3(1), metallic, diffuseColor, specularColor); +    vec3 specular_linear = srgb_to_linear(specular); +    calcDiffuseSpecular(specular_linear, metallic, diffuseColor, specularColor);      vec3 v = -normalize(pos.xyz); @@ -257,46 +309,36 @@ void main()      float ao = 1.0;      vec3 light_dir = transform_normal(lightDir); -    perceptualRoughness = 0.0; -    metallic = 1.0; -      float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);      float nl = 0;      vec3 diffPunc = vec3(0);      vec3 specPunc = vec3(0); -    pbrPunctual(vec3(0), specularColor, 0.1, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir), nl, diffPunc, specPunc); - -    vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10)); - -    vec3 color = punctual * sunlit_linear * 2.75 * shadow; -    vec3 iblDiff; -    vec3 iblSpec; -    pbrIbl(vec3(0), vec3(1), radiance, vec3(0), ao, NdotV, 0.0, iblDiff, iblSpec); - -    color += iblDiff + iblSpec; +    pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir), nl, diffPunc, specPunc); -    float nv = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0); -    vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0); -    float f = 1.0-brdf.y; //1.0 - (brdf.x+brdf.y); -    f *= 0.9; -    f *= f; +    vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10)) * sunlit_linear * shadow; +    radiance *= df2.y; +    //radiance = toneMapNoExposure(radiance); +    vec3 color = vec3(0); +    color = mix(fb.rgb, radiance, min(1, df2.x)) + punctual.rgb; -    // incoming scale is [0, 1] with 0.5 being default -    // shift to 0.5 to 1.5 -    f *= (fresnelScale - 0.5)+1.0; +    float water_haze_scale = 4; -    // incoming offset is [0, 1] with 0.5 being default -    // shift from -1 to 1 -    f += (fresnelOffset - 0.5) * 2.0; +    if (classic_mode > 0) +        water_haze_scale = 1; -    f = clamp(f, 0, 1); +    // This looks super janky, but we do this to restore water haze in the distance. +    // These values were finagled in to try and bring back some of the distant brightening on legacy water.  Also works reasonably well on PBR skies such as PBR midday. +    // color = mix(color, additive * water_haze_scale, (1 - atten)); -    color = ((1.0 - f) * color) + fb.rgb; +    // We shorten the fade here at the shoreline so it doesn't appear too soft from a distance. +    fade *= 60; +    fade = min(1, fade); +    color = mix(fb.rgb, color, fade); -    float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05); +    float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0); -    frag_color = max(vec4(color, spec), vec4(0)); +    frag_color = min(vec4(1),max(vec4(color.rgb, spec * water_mask), vec4(0)));  } diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index d894e1b24e..cb79410d72 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -85,6 +85,7 @@ RenderExposure				1   4  RenderTonemapType			1   1  RenderTonemapMix			1   1  RenderDisableVintageMode           1   1 +RenderMaxTextureResolution         1   2048  //  // Low Graphics Settings @@ -126,6 +127,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderDisableVintageMode           1   0 +RenderMaxTextureResolution         1   512  //  // Medium Low Graphics Settings @@ -167,6 +169,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderDisableVintageMode           1   0 +RenderMaxTextureResolution         1   1024  //  // Medium Graphics Settings (standard) @@ -207,6 +210,7 @@ RenderCASSharpness          1   0  RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7 +RenderMaxTextureResolution  1   2048  //  // Medium High Graphics Settings @@ -247,6 +251,7 @@ RenderCASSharpness          1   0  RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7 +RenderMaxTextureResolution  1   2048  //  // High Graphics Settings (SSAO + sun shadows) @@ -287,6 +292,7 @@ RenderCASSharpness          1   0.4  RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7 +RenderMaxTextureResolution  1   2048  //  // High Ultra Graphics Settings (deferred + SSAO + all shadows) @@ -327,6 +333,7 @@ RenderCASSharpness          1   0.4  RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7 +RenderMaxTextureResolution  1   2048  //  // Ultra graphics (REALLY PURTY!) @@ -367,6 +374,7 @@ RenderCASSharpness          1   0.4  RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7 +RenderMaxTextureResolution  1   2048  //  // Class Unknown Hardware (unknown) @@ -399,6 +407,7 @@ RenderShadowDetail			0	0  RenderReflectionProbeDetail	0	-1  RenderMirrors				0	0  RenderDisableVintageMode           1   0 +RenderMaxTextureResolution         1   2048  list Intel  RenderAnisotropic			1	0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index cfcd96d650..dc9473b042 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -85,6 +85,7 @@ RenderTonemapType			1   1  RenderTonemapMix			1   1  RenderDisableVintageMode           1   1  RenderDownScaleMethod       1   0 +RenderMaxTextureResolution         1   2048  //  // Low Graphics Settings @@ -126,6 +127,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderDisableVintageMode           1   0 +RenderMaxTextureResolution         1   512  //  // Medium Low Graphics Settings @@ -167,6 +169,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderDisableVintageMode           1   0 +RenderMaxTextureResolution         1   1024  //  // Medium Graphics Settings (standard) @@ -207,6 +210,7 @@ RenderCASSharpness          1   0  RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7 +RenderMaxTextureResolution  1   2048  //  // Medium High Graphics Settings @@ -247,6 +251,7 @@ RenderCASSharpness          1   0  RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7 +RenderMaxTextureResolution  1   2048  //  // High Graphics Settings (SSAO + sun shadows) @@ -287,6 +292,7 @@ RenderCASSharpness          1   0  RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7 +RenderMaxTextureResolution  1   2048  //  // High Ultra Graphics Settings (SSAO + all shadows) @@ -327,6 +333,7 @@ RenderCASSharpness          1   0.4  RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7 +RenderMaxTextureResolution  1   2048  //  // Ultra graphics (REALLY PURTY!) @@ -367,6 +374,7 @@ RenderCASSharpness          1   0.4  RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7 +RenderMaxTextureResolution  1   2048  //  // Class Unknown Hardware (unknown) @@ -398,6 +406,7 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  RenderMirrors				0	0  RenderDisableVintageMode           1   0 +RenderMaxTextureResolution         1   2048  list TexUnit8orLess  RenderDeferredSSAO			0	0 diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index ed66753267..7863d25696 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -500,7 +500,7 @@ void GLTFSceneManager::update()              LLNewBufferedResourceUploadInfo::uploadFinish_f finish = [this, buffer](LLUUID assetId, LLSD response)              {                  LLAppViewer::instance()->postToMainCoro( -                    [=]() +                    [=, this]()                      {                          if (mUploadingAsset)                          { @@ -975,9 +975,9 @@ void renderAssetDebug(LLViewerObject* obj, Asset* asset)      LLVector4a t;      agent_to_asset.affineTransform(gDebugRaycastStart, t); -    start = glm::make_vec4(t.getF32ptr()); +    start = vec4(t);      agent_to_asset.affineTransform(gDebugRaycastEnd, t); -    end = glm::make_vec4(t.getF32ptr()); +    end = vec4(t);      start.w = end.w = 1.0; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 26c080bf89..8756baa04a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4879,10 +4879,19 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename)      LLXMLNodePtr root;      bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); -    if (!success || !root || !root->hasName( "teleport_messages" )) +    if (!success)      { +        LLError::LLUserWarningMsg::showMissingFiles();          LL_ERRS() << "Problem reading teleport string XML file: " -               << xml_filename << LL_ENDL; +            << xml_filename << LL_ENDL; +        return; +    } + +    if (!root || !root->hasName("teleport_messages")) +    { +        LLError::LLUserWarningMsg::showMissingFiles(); +        LL_ERRS() << "Invalid teleport string XML file: " +            << xml_filename << LL_ENDL;          return;      } diff --git a/indra/newview/llagentpicksinfo.cpp b/indra/newview/llagentpicksinfo.cpp index e2a2d2d8a9..265e4060ff 100644 --- a/indra/newview/llagentpicksinfo.cpp +++ b/indra/newview/llagentpicksinfo.cpp @@ -28,6 +28,7 @@  #include "llagentpicksinfo.h"  #include "llagent.h" +#include "llagentbenefits.h"  #include "llavatarpropertiesprocessor.h"  const S32 MAX_AVATAR_PICKS = 10; @@ -85,10 +86,9 @@ private:  LLAgentPicksInfo::LLAgentPicksInfo()   : mAgentPicksObserver(NULL) - , mMaxNumberOfPicks(MAX_AVATAR_PICKS)   // Disable Pick creation until we get number of Picks from server - in case   // avatar has maximum number of Picks. - , mNumberOfPicks(mMaxNumberOfPicks) + , mNumberOfPicks(S32_MAX)  {  } @@ -110,7 +110,13 @@ void LLAgentPicksInfo::requestNumberOfPicks()      mAgentPicksObserver->sendAgentPicksRequest();  } -bool LLAgentPicksInfo::isPickLimitReached() +// static +S32 LLAgentPicksInfo::getMaxNumberOfPicks() +{ +    return LLAgentBenefitsMgr::current().getPicksLimit(); +} + +bool LLAgentPicksInfo::isPickLimitReached() const  {      return getNumberOfPicks() >= getMaxNumberOfPicks();  } diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h index 9bc105a655..3514ade65d 100644 --- a/indra/newview/llagentpicksinfo.h +++ b/indra/newview/llagentpicksinfo.h @@ -52,17 +52,17 @@ public:      /**       * Returns number of Picks.       */ -    S32 getNumberOfPicks() { return mNumberOfPicks; } +    S32 getNumberOfPicks() const { return mNumberOfPicks; }      /**       * Returns maximum number of Picks.       */ -    S32 getMaxNumberOfPicks() { return mMaxNumberOfPicks; } +    static S32 getMaxNumberOfPicks();      /**       * Returns true if Agent has maximum allowed number of Picks.       */ -    bool isPickLimitReached(); +    bool isPickLimitReached() const;      /**       * After creating or deleting a Pick we can assume operation on server will be @@ -83,15 +83,9 @@ private:      */      void setNumberOfPicks(S32 number) { mNumberOfPicks = number; } -    /** -    * Sets maximum number of Picks. -    */ -    void setMaxNumberOfPicks(S32 max_picks) { mMaxNumberOfPicks = max_picks; } -  private:      LLAgentPicksObserver* mAgentPicksObserver; -    S32 mMaxNumberOfPicks;      S32 mNumberOfPicks;  }; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 946d674e8b..4e0c5d7df0 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -537,9 +537,14 @@ LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()          selfStopPhase("update_appearance_on_destroy"); -        LLAppearanceMgr::instance().updateAppearanceFromCOF(mEnforceItemRestrictions, -                                                            mEnforceOrdering, -                                                            mPostUpdateFunc); +        //avoid calling an update inside coroutine +        bool force_restrictions(mEnforceItemRestrictions); +        bool enforce_ordering(mEnforceOrdering); +        nullary_func_t post_update_func(mPostUpdateFunc); +        doOnIdleOneTime([force_restrictions,enforce_ordering,post_update_func]() +        { +            LLAppearanceMgr::instance().updateAppearanceFromCOF(force_restrictions, enforce_ordering, post_update_func); +        });      }  } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c770b7c917..9889765fff 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -298,6 +298,7 @@ bool gUseQuickTime = true;  eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL;  S32 gLastExecDuration = -1; // (<0 indicates unknown) +LLUUID gLastAgentSessionId;  #if LL_WINDOWS  #   define LL_PLATFORM_KEY "win" @@ -372,7 +373,6 @@ const int MAX_MARKER_LENGTH = 1024;  const std::string MARKER_FILE_NAME("SecondLife.exec_marker");  const std::string START_MARKER_FILE_NAME("SecondLife.start_marker");  const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker"); -const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");  const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker");  static bool gDoDisconnect = false;  static std::string gLaunchFileOnQuit; @@ -2219,6 +2219,7 @@ bool LLAppViewer::initThreads()      return true;  } +// Callback for all LL_ERROR calls  void errorCallback(LLError::ELevel level, const std::string &error_string)  {      if (level == LLError::LEVEL_ERROR) @@ -2234,15 +2235,38 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)          // haven't actually trashed anything yet, we can afford to write the whole          // static info file.          LLAppViewer::instance()->writeDebugInfo(); + +        std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); +        if (!LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB)) +        { +            // If marker doesn't exist, create a marker with llerror code for next launch +            // otherwise don't override existing file +            LLAppViewer::instance()->createErrorMarker(LAST_EXEC_LLERROR_CRASH); +        }      }  } -void errorMSG(const std::string& title_string, const std::string& message_string) +// Callback for LLError::LLUserWarningMsg +void errorHandler(const std::string& title_string, const std::string& message_string, S32 code)  {      if (!message_string.empty())      {          OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK);      } +    switch (code) +    { +    case LLError::LLUserWarningMsg::ERROR_OTHER: +        LLAppViewer::instance()->createErrorMarker(LAST_EXEC_OTHER_CRASH); +        break; +    case LLError::LLUserWarningMsg::ERROR_BAD_ALLOC: +        LLAppViewer::instance()->createErrorMarker(LAST_EXEC_BAD_ALLOC); +        break; +    case LLError::LLUserWarningMsg::ERROR_MISSING_FILES: +        LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES); +        break; +    default: +        break; +    }  }  void LLAppViewer::initLoggingAndGetLastDuration() @@ -2256,7 +2280,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()      LLError::addGenericRecorder(&errorCallback);      //LLError::setTimeFunction(getRuntime); -    LLError::LLUserWarningMsg::setHandler(errorMSG); +    LLError::LLUserWarningMsg::setHandler(errorHandler);      if (mSecondInstance) @@ -2540,6 +2564,7 @@ bool LLAppViewer::initConfiguration()          OSMessageBox(              "Unable to load default settings file. The installation may be corrupted.",              LLStringUtil::null,OSMB_OK); +        LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES);          return false;      } @@ -3702,16 +3727,21 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const      bool sameVersion = false;      std::string my_version(LLVersionInfo::instance().getChannelAndVersion()); -    char marker_version[MAX_MARKER_LENGTH]; +    char marker_data[MAX_MARKER_LENGTH];      S32  marker_version_length;      LLAPRFile marker_file;      marker_file.open(marker_name, LL_APR_RB);      if (marker_file.getFileHandle())      { -        marker_version_length = marker_file.read(marker_version, sizeof(marker_version)); -        std::string marker_string(marker_version, marker_version_length); -        if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) ) +        marker_version_length = marker_file.read(marker_data, sizeof(marker_data)); +        std::string marker_string(marker_data, marker_version_length); +        size_t pos = marker_string.find('\n'); +        if (pos != std::string::npos) +        { +            marker_string = marker_string.substr(0, pos); +        } +        if ( 0 == my_version.compare( 0, my_version.length(), marker_string, 0, marker_string.length()) )          {              sameVersion = true;          } @@ -3725,6 +3755,88 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const      return sameVersion;  } +void LLAppViewer::recordSessionToMarker() +{ +    std::string marker_version(LLVersionInfo::instance().getChannelAndVersion()); +    std::string uuid_str = "\n" + gAgentSessionID.asString(); +    if (marker_version.length() + uuid_str.length() > MAX_MARKER_LENGTH) +    { +        LL_WARNS_ONCE("MarkerFile") << "Version length (" << marker_version.length() << ")" +            << " greater than maximum (" << MAX_MARKER_LENGTH << ")" +            << ": marker matching may be incorrect" +            << LL_ENDL; +    } + +    mMarkerFile.seek(APR_SET, (S32)marker_version.length()); +    mMarkerFile.write(uuid_str.data(), (S32)uuid_str.length()); +} + +LLUUID LLAppViewer::getMarkerSessionId(const std::string& marker_name) const +{ +    std::string data; +    if (getMarkerData(marker_name, data)) +    { +        return LLUUID(data); +    } +    return LLUUID(); +} + +S32 LLAppViewer::getMarkerErrorCode(const std::string& marker_name) const +{ +    std::string data; +    if (getMarkerData(marker_name, data)) +    { +        if (data.empty()) +        { +            return 0; +        } +        else +        { +            return std::stoi(data); +        } +    } +    return -1; +} + +bool LLAppViewer::getMarkerData(const std::string& marker_name, std::string& data) const +{ +    bool sameVersion = false; + +    std::string my_version(LLVersionInfo::instance().getChannelAndVersion()); +    char marker_data[MAX_MARKER_LENGTH]; +    S32  marker_version_length; + +    LLAPRFile marker_file; +    marker_file.open(marker_name, LL_APR_RB); +    if (marker_file.getFileHandle()) +    { +        marker_version_length = marker_file.read(marker_data, sizeof(marker_data)); +        marker_file.close(); +        std::string marker_string(marker_data, marker_version_length); +        size_t pos = marker_string.find('\n'); +        if (pos != std::string::npos) +        { +            data = marker_string.substr(pos + 1, marker_version_length - pos - 1); +            marker_string = marker_string.substr(0, pos); +        } +        if (0 == my_version.compare(0, my_version.length(), marker_string, 0, marker_string.length())) +        { +            sameVersion = true; +        } +        else +        { +            return false; +        } +        LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': " +            << "\n   mine '" << my_version << "'" +            << "\n marker '" << marker_string << "'" +            << "\n " << (sameVersion ? "same" : "different") << " version" +            << LL_ENDL; +        return true; +    } +    return false; +} +  void LLAppViewer::processMarkerFiles()  {      //We've got 4 things to test for here @@ -3743,6 +3855,10 @@ void LLAppViewer::processMarkerFiles()          // File exists...          // first, read it to see if it was created by the same version (we need this later)          marker_is_same_version = markerIsSameVersion(mMarkerFileName); +        if (marker_is_same_version) +        { +            gLastAgentSessionId = getMarkerSessionId(mMarkerFileName); +        }          // now test to see if this file is locked by a running process (try to open for write)          marker_log_stream << "Checking exec marker file for lock..."; @@ -3832,44 +3948,27 @@ void LLAppViewer::processMarkerFiles()          }          LLAPRFile::remove(logout_marker_file);      } -    // further refine based on whether or not a marker created during an llerr crash is found -    std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME); -    if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB)) -    { -        if (markerIsSameVersion(llerror_marker_file)) -        { -            if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE ) -            { -                gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; -                LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; -            } -            else -            { -                gLastExecEvent = LAST_EXEC_LLERROR_CRASH; -                LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL; -            } -        } -        else -        { -            LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL; -        } -        LLAPRFile::remove(llerror_marker_file); -    }      // and last refine based on whether or not a marker created during a non-llerr crash is found      std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);      if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))      { -        if (markerIsSameVersion(error_marker_file)) +        S32 marker_code = getMarkerErrorCode(error_marker_file); +        if (marker_code >= 0)          {              if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)              {                  gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;                  LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;              } +            else if (marker_code > 0 && marker_code < (S32)LAST_EXEC_COUNT) +            { +                gLastExecEvent = (eLastExecEvent)marker_code; +                LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +            }              else              {                  gLastExecEvent = LAST_EXEC_OTHER_CRASH; -                LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +                LL_INFOS("MarkerFile") << "Error marker '" << error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;              }          }          else @@ -5159,6 +5258,24 @@ void LLAppViewer::postToMainCoro(const LL::WorkQueue::Work& work)      gMainloopWork.post(work);  } +void LLAppViewer::createErrorMarker(eLastExecEvent error_code) const +{ +    if (!mSecondInstance) +    { +        std::string error_marker = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); + +        LLAPRFile file; +        file.open(error_marker, LL_APR_WB); +        if (file.getFileHandle()) +        { +            recordMarkerVersion(file); +            std::string data = "\n" + std::to_string((S32)error_code); +            file.write(data.data(), static_cast<S32>(data.length())); +            file.close(); +        } +    } +} +  void LLAppViewer::outOfMemorySoftQuit()  {      if (!mQuitRequested) diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 4ce4259ed8..b4756eecd6 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -66,6 +66,20 @@ class LLViewerRegion;  extern LLTrace::BlockTimerStatHandle FTM_FRAME; +typedef enum +{ +    LAST_EXEC_NORMAL = 0, +    LAST_EXEC_FROZE, +    LAST_EXEC_LLERROR_CRASH, +    LAST_EXEC_OTHER_CRASH, +    LAST_EXEC_LOGOUT_FROZE, +    LAST_EXEC_LOGOUT_CRASH, +    LAST_EXEC_BAD_ALLOC, +    LAST_EXEC_MISSING_FILES, +    LAST_EXEC_GRAPHICS_INIT, +    LAST_EXEC_COUNT +} eLastExecEvent; +  class LLAppViewer : public LLApp  {  public: @@ -147,6 +161,7 @@ public:      void saveExperienceCache();      void removeMarkerFiles(); +    void recordSessionToMarker();      void removeDumpDir();      // LLAppViewer testing helpers. @@ -227,6 +242,9 @@ public:      // post given work to the "mainloop" work queue for handling on the main thread      void postToMainCoro(const LL::WorkQueue::Work& work); +    // Writes an error code into the error_marker file for use on next startup. +    void createErrorMarker(eLastExecEvent error_code) const; +      // Attempt a 'soft' quit with disconnect and saving of settings/cache.      // Intended to be thread safe.      // Good chance of viewer crashing either way, but better than alternatives. @@ -272,6 +290,9 @@ private:      void processMarkerFiles();      static void recordMarkerVersion(LLAPRFile& marker_file);      bool markerIsSameVersion(const std::string& marker_name) const; +    LLUUID getMarkerSessionId(const std::string& marker_name) const; +    S32 getMarkerErrorCode(const std::string& marker_name) const; +    bool getMarkerData(const std::string& marker_name, std::string &data) const;      void idle();      void idleShutdown(); @@ -347,18 +368,9 @@ private:  extern LLSD gDebugInfo;  extern bool gShowObjectUpdates; -typedef enum -{ -    LAST_EXEC_NORMAL = 0, -    LAST_EXEC_FROZE, -    LAST_EXEC_LLERROR_CRASH, -    LAST_EXEC_OTHER_CRASH, -    LAST_EXEC_LOGOUT_FROZE, -    LAST_EXEC_LOGOUT_CRASH -} eLastExecEvent; -  extern eLastExecEvent gLastExecEvent; // llstartup  extern S32 gLastExecDuration; ///< the duration of the previous run in seconds (<0 indicates unknown) +extern LLUUID gLastAgentSessionId; // will be set if agent logged in  extern const char* gPlatform; diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 4cd85ac756..5004055666 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -357,8 +357,9 @@ void LLConversationItemSession::clearParticipants()  void LLConversationItemSession::clearAndDeparentModels()  { -    for (LLFolderViewModelItem* child : mChildren) +    for (child_list_t::iterator it = mChildren.begin(); it != mChildren.end();)      { +        LLFolderViewModelItem* child = *it;          if (child->getNumRefs() == 0)          {              // LLConversationItemParticipant can be created but not assigned to any view, @@ -370,8 +371,8 @@ void LLConversationItemSession::clearAndDeparentModels()              // Model is still assigned to some view/widget              child->setParent(NULL);          } +        it = mChildren.erase(it);      } -    mChildren.clear();  }  LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id) diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 7bd5206453..e60b3eb5dc 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -42,6 +42,7 @@  #include "lldrawpooltree.h"  #include "lldrawpoolterrain.h"  #include "lldrawpoolwater.h" +#include "lldrawpoolwaterexclusion.h"  #include "llface.h"  #include "llviewerobjectlist.h" // For debug listing.  #include "pipeline.h" @@ -119,6 +120,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)      case POOL_GLTF_PBR_ALPHA_MASK:          poolp = new LLDrawPoolGLTFPBR(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);          break; +    case POOL_WATEREXCLUSION: +        poolp = new LLDrawPoolWaterExclusion(); +        break;      default:          LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;          return NULL; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index bc412214c7..1c8864a9df 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -55,6 +55,7 @@ public:          // based on fill rate and likelihood to occlude future passes (faster, large occluders first).          //          POOL_SKY = 1, +        POOL_WATEREXCLUSION,          POOL_WL_SKY,          POOL_SIMPLE,          POOL_FULLBRIGHT, @@ -140,7 +141,7 @@ public:          PASS_GRASS,          PASS_FULLBRIGHT,          PASS_FULLBRIGHT_RIGGED, -        PASS_INVISIBLE, +        PASS_INVISIBLE,                         // Formerly, invisiprims.  Now, water exclusion surfaces.          PASS_INVISIBLE_RIGGED,          PASS_INVISI_SHINY,          PASS_INVISI_SHINY_RIGGED, diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 53d6e528b6..32de0e5ee7 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -176,173 +176,156 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)          light_diffuse *= (1.5f + (6.f * ground_proj_sq));      } -    // set up normal maps filtering -    for (auto norm_map : mWaterNormp) -        { -        if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT); -        } +    LLTexUnit::eTextureFilterOptions filter_mode = has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT;      LLColor4      specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor());      F32           phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f;      LLGLSLShader *shader     = nullptr; -    // two passes, first with standard water shader bound, second with edge water shader bound -    for (int edge = 0; edge < 2; edge++) +    // One pass, one of two shaders.  Void water and region water share state. +    // There isn't a good reason anymore to really have void water run in a separate pass. +    // It also just introduced a bunch of weird state consistency stuff that we really don't need. +    // Not to mention, re-binding the the same shader and state for that shader is kind of wasteful. +    // - Geenz 2025-02-11 +    // select shader +    if (underwater)      { -        // select shader -        if (underwater) -        { -            shader = &gUnderWaterProgram; -        } -        else -        { -            if (edge) -            { -                shader = &gWaterEdgeProgram; -            } -            else -            { -                shader = &gWaterProgram; -            } -        } +        shader = &gUnderWaterProgram; +    } +    else +    { +        shader = &gWaterProgram; +    } -        gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis); +    gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis); -        //bind normal map -        S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); -        S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2); +    LLViewerTexture* tex_a = mWaterNormp[0]; +    LLViewerTexture* tex_b = mWaterNormp[1]; -        LLViewerTexture* tex_a = mWaterNormp[0]; -        LLViewerTexture* tex_b = mWaterNormp[1]; +    F32 blend_factor = (F32)pwater->getBlendFactor(); -        F32 blend_factor = (F32)pwater->getBlendFactor(); +    if (tex_a && (!tex_b || (tex_a == tex_b))) +    { +        shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a); +        tex_a->setFilteringOption(filter_mode); +        blend_factor = 0; // only one tex provided, no blending +    } +    else if (tex_b && !tex_a) +    { +        shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_b); +        tex_a->setFilteringOption(filter_mode); +        blend_factor = 0; // only one tex provided, no blending +    } +    else if (tex_b != tex_a) +    { +        shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a); +        tex_a->setFilteringOption(filter_mode); +        shader->bindTexture(LLViewerShaderMgr::BUMP_MAP2, tex_b); +        tex_b->setFilteringOption(filter_mode); +    } -        gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE); -        gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE); +    shader->bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &gPipeline.mWaterExclusionMask); -        if (tex_a && (!tex_b || (tex_a == tex_b))) -        { -            gGL.getTexUnit(bumpTex)->bind(tex_a); -            blend_factor = 0; // only one tex provided, no blending -        } -        else if (tex_b && !tex_a) -        { -            gGL.getTexUnit(bumpTex)->bind(tex_b); -            blend_factor = 0; // only one tex provided, no blending -        } -        else if (tex_b != tex_a) -        { -            gGL.getTexUnit(bumpTex)->bind(tex_a); -            gGL.getTexUnit(bumpTex2)->bind(tex_b); -        } +    shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); -        // bind reflection texture from RenderTarget -        S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX); +    F32      fog_density = pwater->getModifiedWaterFogDensity(underwater); -        F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] }; +    shader->bindTexture(LLShaderMgr::WATER_SCREENTEX, &gPipeline.mWaterDis); -        shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes); -        shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); +    if (mShaderLevel == 1) +    { +        fog_color.mV[VALPHA] = (F32)(log(fog_density) / log(2)); +    } -        F32      fog_density = pwater->getModifiedWaterFogDensity(underwater); +    F32 water_height = environment.getWaterHeight(); +    F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2]; +    shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height); +    shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time); +    shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); -        if (screentex > -1) -        { -            shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density); -            gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis); -        } +    shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); -        if (mShaderLevel == 1) -        { -            fog_color.mV[VALPHA] = (F32)(log(fog_density) / log(2)); -        } +    shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); +    shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); -        F32 water_height = environment.getWaterHeight(); -        F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2]; -        shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height); -        shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time); -        shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); +    shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); -        shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV); -        shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV); -        shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, 1, fog_color_linear.mV); +    shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); +    shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale()); +    shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset()); +    shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, fmaxf(0, pwater->getBlurMultiplier()) * 2); -        shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); -        shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); +    static LLStaticHashedString s_exposure("exposure"); +    static LLStaticHashedString tonemap_mix("tonemap_mix"); +    static LLStaticHashedString tonemap_type("tonemap_type"); -        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); -        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); +    static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f); -        shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); +    F32 e = llclamp(exposure(), 0.5f, 4.f); -        shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); -        shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale()); -        shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset()); -        shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier()); +    static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", false); -        F32 sunAngle = llmax(0.f, light_dir.mV[1]); -        F32 scaledAngle = 1.f - sunAngle; +    shader->uniform1f(s_exposure, e); +    static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U); +    shader->uniform1i(tonemap_type, tonemap_type_setting); +    shader->uniform1f(tonemap_mix, psky->getTonemapMix(should_auto_adjust())); -        shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0); -        shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle); -        shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle); -        shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle); -        shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0); +    F32 sunAngle = llmax(0.f, light_dir.mV[1]); +    F32 scaledAngle = 1.f - sunAngle; -        // SL-15861 This was changed from getRotatedLightNorm() as it was causing -        // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV. -        LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm(); -        shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV); +    shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0); -        shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); +    // SL-15861 This was changed from getRotatedLightNorm() as it was causing +    // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV. +    LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm(); +    shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV); -        if (LLViewerCamera::getInstance()->cameraUnderWater()) -        { -            shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow()); -        } -        else -        { -            shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove()); -        } +    shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); -        LLGLDisable cullface(GL_CULL_FACE); +    if (LLViewerCamera::getInstance()->cameraUnderWater()) +    { +        shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow()); +    } +    else +    { +        shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove()); +    } -        LLVOWater* water = nullptr; -        for (LLFace* const& face : mDrawFace) -        { -            if (!face) continue; -            water = static_cast<LLVOWater*>(face->getViewerObject()); -            if (!water) continue; - -            if ((bool)edge == (bool)water->getIsEdgePatch()) -            { -                face->renderIndexed(); - -                // Note non-void water being drawn, updates required -                if (!edge)  // SL-16461 remove !LLPipeline::sUseOcclusion check -                { -                    sNeedsReflectionUpdate = true; -                    sNeedsDistortionUpdate = true; -                } -            } -        } +    LLGLDisable cullface(GL_CULL_FACE); -        shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); -        shader->disableTexture(LLShaderMgr::WATER_SCREENTEX); -        shader->disableTexture(LLShaderMgr::BUMP_MAP); -        shader->disableTexture(LLShaderMgr::WATER_REFTEX); +    // Only push the water planes once. +    // Previously we did this twice: once for void water and one for region water. +    // However, the void water and region water shaders are the same exact shader. +    // They also had the same exact state with the sole exception setting an edge water flag. +    // That flag was not actually used anywhere in the shaders. +    // - Geenz 2025-02-11 +    pushWaterPlanes(0); -        // clean up -        gPipeline.unbindDeferredShader(*shader); +    // clean up +    gPipeline.unbindDeferredShader(*shader); -        gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE); -        gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE); -    } +    gGL.setColorMask(true, false); +} -    gGL.getTexUnit(0)->activate(); -    gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +void LLDrawPoolWater::pushWaterPlanes(int pass) +{ +    LLVOWater* water = nullptr; +    for (LLFace* const& face : mDrawFace) +    { +        water = static_cast<LLVOWater*>(face->getViewerObject()); -    gGL.setColorMask(true, false); +        face->renderIndexed(); + +        // Note non-void water being drawn, updates required +        // Previously we had some logic to determine if this pass was also our water edge pass. +        // Now we only have one pass.  Check if we're doing a region water plane or void water plane. +        // - Geenz 2025-02-11 +        if (!water->getIsEdgePatch()) +        { +            sNeedsReflectionUpdate = true; +            sNeedsDistortionUpdate = true; +        } +    }  }  LLViewerTexture *LLDrawPoolWater::getDebugTexture() diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index f64477a059..7fc9b68bcf 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -74,6 +74,8 @@ public:      void setOpaqueTexture(const LLUUID& opaqueTextureId);      void setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId); +    void pushWaterPlanes(int pass); +  protected:      void renderOpaqueLegacyWater();  }; diff --git a/indra/newview/lldrawpoolwaterexclusion.cpp b/indra/newview/lldrawpoolwaterexclusion.cpp new file mode 100644 index 0000000000..d796bf39bf --- /dev/null +++ b/indra/newview/lldrawpoolwaterexclusion.cpp @@ -0,0 +1,79 @@ +/** + * @file lldrawpool.cpp + * @brief LLDrawPoolMaterials class implementation + * @author Jonathan "Geenz" Goodman + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lldrawpoolwaterexclusion.h" +#include "llviewershadermgr.h" +#include "pipeline.h" +#include "llglcommonfunc.h" +#include "llvoavatar.h" +#include "lldrawpoolwater.h" + +LLDrawPoolWaterExclusion::LLDrawPoolWaterExclusion() : LLRenderPass(LLDrawPool::POOL_WATEREXCLUSION) +{ +    LL_INFOS("DPInvisible") << "Creating water exclusion draw pool" << LL_ENDL; +} + + +void LLDrawPoolWaterExclusion::render(S32 pass) +{                                             // render invisiprims +    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; // LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE); + +    if (gPipeline.shadersLoaded()) +    { +        gDrawColorProgram.bind(); +    } + + +    LLGLDepthTest depth(GL_TRUE); +    gDrawColorProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, 1, 1, 1, 1); + +    LLDrawPoolWater* pwaterpool = (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER); +    if (pwaterpool) +    { +        // Just treat our water planes as double sided for the purposes of generating the exclusion mask. +        LLGLDisable cullface(GL_CULL_FACE); +        pwaterpool->pushWaterPlanes(0); + +        // Take care of the edge water tiles. +        pwaterpool->pushWaterPlanes(1); +    } + +    gDrawColorProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, 0, 0, 0, 1); + +    static LLStaticHashedString waterSign("waterSign"); +    gDrawColorProgram.uniform1f(waterSign, 1.f); + +    pushBatches(LLRenderPass::PASS_INVISIBLE, false, false); + + +    if (gPipeline.shadersLoaded()) +    { +        gDrawColorProgram.unbind(); +    } +} diff --git a/indra/newview/lldrawpoolwaterexclusion.h b/indra/newview/lldrawpoolwaterexclusion.h new file mode 100644 index 0000000000..e95721a443 --- /dev/null +++ b/indra/newview/lldrawpoolwaterexclusion.h @@ -0,0 +1,61 @@ +/** + * @file lldrawpoolwaterexclusion.h + * @brief LLDrawPoolWaterExclusion class definition + * @author Jonathan "Geenz" Goodman + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLDRAWPOOLWATEREXCLUSION_H +#define LL_LLDRAWPOOLWATEREXCLUSION_H + +#include "v4coloru.h" +#include "v2math.h" +#include "v3math.h" +#include "llvertexbuffer.h" +#include "lldrawpool.h" + +class LLViewerTexture; +class LLDrawInfo; +class LLGLSLShader; + +class LLDrawPoolWaterExclusion : public LLRenderPass +{ +public: +    LLDrawPoolWaterExclusion(); + +    enum +    { +        VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX +    }; + +    virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + +    virtual void prerender() {} + +    virtual void render(S32 pass = 0); +    virtual void beginRenderPass(S32 pass) {} +    virtual void endRenderPass(S32 pass) {} +    virtual S32  getNumPasses() { return 1; } +}; + +#endif // LL_LLDRAWPOOLWATEREXCLUSION_H diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 3ccb363321..811aacb2ed 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -893,7 +893,7 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& po      //VECTORIZE THIS      // see if we have a non-default mapping -    U8 texgen = getTextureEntry()->getTexGen(); +    U8 texgen = tep->getTexGen();      if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)      {          LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter); @@ -983,8 +983,17 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to,  LLVector2* res_st_offs          return false;      }      const LLTextureEntry *orig_tep = align_to->getTextureEntry(); +    if (!orig_tep) +    { +        return false; +    } +    const LLTextureEntry* tep = getTextureEntry(); +    if (!tep) +    { +        return false; +    }      if ((orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR) || -        (getTextureEntry()->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR)) +        (tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR))      {          return false;      } @@ -1563,7 +1572,8 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,                  bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);              } -            U8 texgen = getTextureEntry()->getTexGen(); +            const LLTextureEntry* tep = getTextureEntry(); +            U8 texgen = tep ? tep->getTexGen() : LLTextureEntry::TEX_GEN_DEFAULT;              if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)              { //planar texgen needs binormals                  mVObjp->getVolume()->genTangents(face_index); @@ -2051,7 +2061,12 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,              LLStrider<LLColor4U> emissive;              mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount); -            U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); +            const LLTextureEntry* tep = getTextureEntry(); +            U8 glow = 0; +            if (tep) +            { +                glow = (U8)llclamp((S32)(tep->getGlow() * 255), 0, 255); +            }              LLVector4a src; diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index af38d696bc..655674357f 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -633,7 +633,8 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD& args)      chat_args["show_names_for_p2p_conv"] = !mIsP2PChat ||              gSavedSettings.getBOOL("IMShowNamesForP2PConv"); -    mChatHistory->appendMessage(chat, chat_args); +    static const LLStyle::Params input_append_params = LLStyle::Params(); +    mChatHistory->appendMessage(chat, chat_args, input_append_params);  }  void LLFloaterIMSessionTab::updateUsedEmojis(LLWStringView text) diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index fb4537f22a..68b9e758a1 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -60,6 +60,10 @@ LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase*  {      LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container");      LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel_container->getCurrentPanel()); +    if (!active_panel) +    { +        LL_WARNS() << "No snapshot active panel, current panel index: " << panel_container->getCurrentPanelIndex() << LL_ENDL; +    }      if (!ok_if_not_found)      {          llassert_always(active_panel != NULL); @@ -643,20 +647,18 @@ void LLFloaterSnapshotBase::ImplBase::setWorking(bool working)      working_lbl->setVisible(working);      mFloater->getChild<LLUICtrl>("working_indicator")->setVisible(working); -    if (working) -    { -        const std::string panel_name = getActivePanel(mFloater, false)->getName(); -        const std::string prefix = panel_name.substr(getSnapshotPanelPrefix().size()); -        std::string progress_text = mFloater->getString(prefix + "_" + "progress_str"); -        working_lbl->setValue(progress_text); -    } -      // All controls should be disabled while posting.      mFloater->setCtrlsEnabled(!working); -    LLPanelSnapshot* active_panel = getActivePanel(mFloater); -    if (active_panel) +    if (LLPanelSnapshot* active_panel = getActivePanel(mFloater))      {          active_panel->enableControls(!working); +        if (working) +        { +            const std::string panel_name = active_panel->getName(); +            const std::string prefix = panel_name.substr(getSnapshotPanelPrefix().size()); +            std::string progress_text = mFloater->getString(prefix + "_" + "progress_str"); +            working_lbl->setValue(progress_text); +        }      }  } diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 112008172e..5484ce6276 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -903,6 +903,39 @@ private:  }; +F32 shader_timer_benchmark(std::vector<LLRenderTarget> & dest, TextureHolder & texHolder, U32 textures_count, LLVertexBuffer * buff, F32 &seconds) +{ +    // run GPU timer benchmark + +    //number of samples to take +    const S32 samples = 64; + +    { +        ShaderProfileHelper initProfile; +        dest[0].bindTarget(); +        gBenchmarkProgram.bind(); +        for (S32 c = 0; c < samples; ++c) +        { +            for (U32 i = 0; i < textures_count; ++i) +            { +                texHolder.bind(i); +                buff->setBuffer(); +                buff->drawArrays(LLRender::TRIANGLES, 0, 3); +            } +        } +        gBenchmarkProgram.unbind(); +        dest[0].flush(); +    } + +    F32 ms = gBenchmarkProgram.mTimeElapsed / 1000000.f; +    seconds = ms / 1000.f; + +    F64 samples_drawn = (F64)gBenchmarkProgram.mSamplesDrawn; +    F64 gpixels_drawn = samples_drawn / 1000000000.0; +    F32 samples_sec = (F32)(gpixels_drawn / seconds); +    return samples_sec * 4;  // 4 bytes per sample +} +  //-----------------------------------------------------------------------------  // gpu_benchmark()  //  returns measured memory bandwidth of GPU in gigabytes per second @@ -944,9 +977,6 @@ F32 gpu_benchmark()      //number of textures      const U32 count = 32; -    //number of samples to take -    const S32 samples = 64; -      //time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark.      const F32 time_limit = 30; @@ -1036,33 +1066,15 @@ F32 gpu_benchmark()      LLGLSLShader::unbind(); -    // run GPU timer benchmark -    { -        ShaderProfileHelper initProfile; -        dest[0].bindTarget(); -        gBenchmarkProgram.bind(); -        for (S32 c = 0; c < samples; ++c) -        { -            for (U32 i = 0; i < count; ++i) -            { -                texHolder.bind(i); -                buff->setBuffer(); -                buff->drawArrays(LLRender::TRIANGLES, 0, 3); -            } -        } -        gBenchmarkProgram.unbind(); -        dest[0].flush(); -    } +    // run GPU timer benchmark twice +    F32 seconds = 0; +    F32 gbps = shader_timer_benchmark(dest, texHolder, count, buff.get(), seconds); -    F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f; -    F32 seconds = ms/1000.f; +    LL_INFOS("Benchmark") << "Memory bandwidth, 1st run is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL; -    F64 samples_drawn = (F64)gBenchmarkProgram.mSamplesDrawn; -    F64 gpixels_drawn = samples_drawn / 1000000000.0; -    F32 samples_sec = (F32)(gpixels_drawn/seconds); -    F32 gbps = samples_sec*4;  // 4 bytes per sample +    gbps = shader_timer_benchmark(dest, texHolder, count, buff.get(), seconds); -    LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL; +    LL_INFOS("Benchmark") << "Memory bandwidth, final run is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;      return gbps;  } diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index cf6b08797d..da1f1a466f 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -472,9 +472,9 @@ bool LLGLTFPreviewTexture::render()      gPipeline.setupHWLights();      glm::mat4 mat = get_current_modelview(); -    glm::vec4 transformed_light_dir = glm::make_vec4(light_dir.mV); +    glm::vec4 transformed_light_dir(light_dir);      transformed_light_dir = mat * transformed_light_dir; -    SetTemporarily<LLVector4> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(glm::value_ptr(transformed_light_dir))); +    SetTemporarily<LLVector4> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(transformed_light_dir));      // Override lights to ensure the sun is always shining from a certain direction (low graphics)      // See also force_sun_direction_high_graphics and fixup_shader_constants      { diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index ce419498cf..e754de2fd1 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -89,9 +89,11 @@ void LLHeroProbeManager::update()      initReflectionMaps(); +    static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); +      if (!mRenderTarget.isComplete())      { -        U32 color_fmt = GL_RGBA16F; +        U32 color_fmt = render_hdr ? GL_RGBA16F : GL_RGBA8;          mRenderTarget.allocate(mProbeResolution, mProbeResolution, color_fmt, true);      } @@ -103,7 +105,7 @@ void LLHeroProbeManager::update()          mMipChain.resize(count);          for (U32 i = 0; i < count; ++i)          { -            mMipChain[i].allocate(res, res, GL_RGBA16F); +            mMipChain[i].allocate(res, res, render_hdr ? GL_RGBA16F : GL_RGBA8);              res /= 2;          }      } @@ -220,7 +222,7 @@ void LLHeroProbeManager::renderProbes()      static LLCachedControl<S32> sUpdateRate(gSavedSettings, "RenderHeroProbeUpdateRate", 0);      F32 near_clip = 0.01f; -    if (mNearestHero != nullptr && +    if (mNearestHero != nullptr && !mNearestHero->isDead() &&          !gTeleportDisplay && !gDisconnected && !LLAppViewer::instance()->logoutRequestSent())      {          LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime"); @@ -249,12 +251,13 @@ void LLHeroProbeManager::renderProbes()              LL_PROFILE_ZONE_NUM(gFrameCount % rate);              LL_PROFILE_ZONE_NUM(rate); +            bool dynamic = mNearestHero->getReflectionProbeIsDynamic() && sDetail() > 0;              for (U32 i = 0; i < 6; ++i)              {                  if ((gFrameCount % rate) == (i % rate))                  { // update 6/rate faces per frame                      LL_PROFILE_ZONE_NUM(i); -                    updateProbeFace(mProbes[0], i, mNearestHero->getReflectionProbeIsDynamic() && sDetail > 0, near_clip); +                    updateProbeFace(mProbes[0], i, dynamic, near_clip);                  }              }              generateRadiance(mProbes[0]); @@ -537,8 +540,10 @@ void LLHeroProbeManager::initReflectionMaps()          mTexture = new LLCubeMapArray(); +        static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); +          // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) -        mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); +        mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr);          if (mDefaultProbe.isNull())          { diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index 135fba7897..6850e57b94 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -106,7 +106,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,      LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();      glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight()); -    glm::vec3 win_coord = glm::project(glm::make_vec3(render_pos.mV), get_current_modelview(), get_current_projection(), viewport); +    glm::vec3 win_coord = glm::project(glm::vec3(render_pos), get_current_modelview(), get_current_projection(), viewport);      //fonts all render orthographically, set up projection``      gGL.matrixMode(LLRender::MM_PROJECTION); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 2e8b1b94fe..e7584018a8 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4231,14 +4231,9 @@ void LLFolderBridge::staticFolderOptionsMenu()  bool LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type)  { -    LLInventoryModel::cat_array_t cat_array; -    LLInventoryModel::item_array_t item_array; -    model->collectDescendentsIf(mUUID, -                                cat_array, -                                item_array, +    return model->hasMatchingDescendents(mUUID,                                  LLInventoryModel::EXCLUDE_TRASH,                                  is_type); -    return !item_array.empty();  }  void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items, menuentry_vec_t& disabled_items) @@ -4415,21 +4410,26 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items          //Added by aura to force inventory pull on right-click to display folder options correctly. 07-17-06          mCallingCards = mWearables = false; -        LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); -        if (checkFolderForContentsOfType(model, is_callingcard)) +        if (gInventory.getRootFolderID() != mUUID)          { -            mCallingCards=true; -        } +            LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); +            if (checkFolderForContentsOfType(model, is_callingcard)) +            { +                mCallingCards = true; +            } -        LLFindWearables is_wearable; -        LLIsType is_object( LLAssetType::AT_OBJECT ); -        LLIsType is_gesture( LLAssetType::AT_GESTURE ); +            const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE }; +            LLIsOneOfTypes is_wearable(types); -        if (checkFolderForContentsOfType(model, is_wearable) || -            checkFolderForContentsOfType(model, is_object)   || -            checkFolderForContentsOfType(model, is_gesture)    ) +            if (checkFolderForContentsOfType(model, is_wearable)) +            { +                mWearables = true; +            } +        } +        else          { -            mWearables=true; +            // Assume that there are wearables in the root folder +            mWearables = true;          }      }      else @@ -4442,13 +4442,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items          LLFolderType::EType type = category->getPreferredType();          const bool is_system_folder = LLFolderType::lookupIsProtectedType(type); -        LLFindWearables is_wearable; -        LLIsType is_object(LLAssetType::AT_OBJECT); -        LLIsType is_gesture(LLAssetType::AT_GESTURE); +        const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE }; +        LLIsOneOfTypes is_wearable(types); -        if (checkFolderForContentsOfType(model, is_wearable) || -            checkFolderForContentsOfType(model, is_object) || -            checkFolderForContentsOfType(model, is_gesture)) +        if (checkFolderForContentsOfType(model, is_wearable))          {              mWearables = true;          } @@ -4571,14 +4568,11 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&      // wearables related functionality for folders.      //is_wearable -    LLFindWearables is_wearable; -    LLIsType is_object( LLAssetType::AT_OBJECT ); -    LLIsType is_gesture( LLAssetType::AT_GESTURE ); +    const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE }; +    LLIsOneOfTypes is_wearable(types);      if (mWearables || -        checkFolderForContentsOfType(model, is_wearable)  || -        checkFolderForContentsOfType(model, is_object) || -        checkFolderForContentsOfType(model, is_gesture) ) +        checkFolderForContentsOfType(model, is_wearable))      {          // Only enable add/replace outfit for non-system folders.          if (!is_system_folder) diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index dadd0590a9..1ccefa3212 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2634,6 +2634,22 @@ bool LLIsType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)      return false;  } +bool LLIsOneOfTypes::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ +    for (LLAssetType::EType &type : mTypes) +    { +        if (type == LLAssetType::AT_CATEGORY) +        { +            if (cat) return true; +        } +        if (item) +        { +            if (item->getType() == type) return true; +        } +    } +    return false; +} +  bool LLIsNotType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)  {      if(mType == LLAssetType::AT_CATEGORY) diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index a25c0d5ad6..13a64f21dc 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -246,6 +246,24 @@ protected:  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLIsOneOfTypes +// +// Implementation of a LLInventoryCollectFunctor which returns true if +// the type is one of the types passed in during construction. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLIsOneOfTypes : public LLInventoryCollectFunctor +{ +public: +    LLIsOneOfTypes(const std::vector<LLAssetType::EType> &types) : mTypes(types) {} +    virtual ~LLIsOneOfTypes() {} +    virtual bool operator()(LLInventoryCategory* cat, +        LLInventoryItem* item); +protected: +    std::vector <LLAssetType::EType> mTypes; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLIsNotType  //  // Implementation of a LLInventoryCollectFunctor which returns false if the diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index d57cb13362..9fffe6378e 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1305,6 +1305,47 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,      }  } +bool LLInventoryModel::hasMatchingDescendents(const LLUUID& id, +    bool include_trash, +    LLInventoryCollectFunctor& matches) +{ +    if (!include_trash) +    { +        const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH); +        if (trash_id.notNull() && (trash_id == id)) +            return false; +    } +    cat_array_t* cat_array = get_ptr_in_map(mParentChildCategoryTree, id); +    if (cat_array) +    { +        for (auto& cat : *cat_array) +        { +            if (matches(cat, NULL)) +            { +                return true; +            } +            if (hasMatchingDescendents(cat->getUUID(), include_trash, matches)) +            { +                return true; +            } +        } +    } + +    item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, id); + +    if (item_array) +    { +        for (auto& item : *item_array) +        { +            if (matches(NULL, item)) +            { +                return true; +            } +        } +    } +    return false; +} +  void LLInventoryModel::addChangedMaskForLinks(const LLUUID& object_id, U32 mask)  {      const LLInventoryObject *obj = getObject(object_id); diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 1472b705e4..d28743357e 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -287,6 +287,9 @@ public:                                item_array_t& items,                                bool include_trash,                                LLInventoryCollectFunctor& add); +    bool hasMatchingDescendents(const LLUUID& id, +        bool include_trash, +        LLInventoryCollectFunctor& add);      // Collect all items in inventory that are linked to item_id.      // Assumes item_id is itself not a linked item. diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index e4d1010231..5a067ba454 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -579,7 +579,7 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve      {          if (model_item && view_item && viewmodel_item)          { -            const LLUUID& idp = viewmodel_item->getUUID(); +            const LLUUID idp = viewmodel_item->getUUID();              view_item->destroyView();              removeItemID(idp);          } @@ -1334,6 +1334,8 @@ void LLInventoryPanel::openStartFolderOrMyInventory()          LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);          if (fchild              && fchild->getViewModelItem() +            // Is this right? Name might be localized, +            // use FT_ROOT_INVENTORY or gInventory.getRootFolderID()?              && fchild->getViewModelItem()->getName() == "My Inventory")          {              fchild->setOpen(true); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index ad04c11cc6..cbc3744aa3 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -212,6 +212,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia      request_params["read_critical"] = false; // handleTOSResponse      request_params["last_exec_event"] = mLastExecEvent;      request_params["last_exec_duration"] = mLastExecDuration; +    request_params["last_exec_session_id"] = mLastAgentSessionId.asString();      request_params["mac"] = (char*)hashed_unique_id_string;      request_params["version"] = LLVersionInfo::instance().getVersion();      request_params["channel"] = LLVersionInfo::instance().getChannel(); diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index 624408d46d..748909c069 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -64,6 +64,7 @@ public:      void setSerialNumber(const std::string& sn) { mSerialNumber = sn; }      void setLastExecEvent(int lee) { mLastExecEvent = lee; }      void setLastExecDuration(S32 duration) { mLastExecDuration = duration; } +    void setLastAgentSessionId(const LLUUID& id) { mLastAgentSessionId = id; }      void setPlatformInfo(const std::string platform, const std::string platform_version, const std::string platform_name);      void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; } @@ -101,6 +102,7 @@ private:      std::string mSerialNumber;      int mLastExecEvent;      S32 mLastExecDuration; +    LLUUID mLastAgentSessionId;      std::string mPlatform;      std::string mPlatformVersion;      std::string mPlatformVersionName; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a5bed1dbe6..93453f507c 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -548,8 +548,8 @@ LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMate      return ppTex ? (*ppTex).get() : NULL;  } -volatile S32 LLMeshRepoThread::sActiveHeaderRequests = 0; -volatile S32 LLMeshRepoThread::sActiveLODRequests = 0; +std::atomic<S32> LLMeshRepoThread::sActiveHeaderRequests = 0; +std::atomic<S32> LLMeshRepoThread::sActiveLODRequests = 0;  U32 LLMeshRepoThread::sMaxConcurrentRequests = 1;  S32 LLMeshRepoThread::sRequestLowWater = REQUEST2_LOW_WATER_MIN;  S32 LLMeshRepoThread::sRequestHighWater = REQUEST2_HIGH_WATER_MIN; @@ -3916,7 +3916,7 @@ void LLMeshRepository::notifyLoadedMeshes()              }              // erase from background thread -            mThread->mWorkQueue.post([=]() +            mThread->mWorkQueue.post([=, this]()                  {                      mThread->mSkinMap.erase(id);                  }); diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index b5c2424578..3d25a4dd78 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -256,8 +256,8 @@ class LLMeshRepoThread : public LLThread  {  public: -    volatile static S32 sActiveHeaderRequests; -    volatile static S32 sActiveLODRequests; +    static std::atomic<S32> sActiveHeaderRequests; +    static std::atomic<S32> sActiveLODRequests;      static U32 sMaxConcurrentRequests;      static S32 sRequestLowWater;      static S32 sRequestHighWater; diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index dbf56c2b6d..7910bcb41d 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -139,32 +139,60 @@ void LLPanelContents::getState(LLViewerObject *objectp )  void LLPanelContents::onFilterEdit()  {      const std::string& filter_substring = mFilterEditor->getText(); -    if (filter_substring.empty()) +    if (!mPanelInventoryObject->hasInventory())      { -        if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) -        { -            // The current filter and the new filter are empty, nothing to do -            return; -        } - -        mSavedFolderState.setApply(true); -        mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState); - -        // Add a folder with the current item to the list of previously opened folders -        LLOpenFoldersWithSelection opener; -        mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(opener); -        mPanelInventoryObject->getRootFolder()->scrollToShowSelection(); +        mDirtyFilter = true;      } -    else if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) +    else      { -        // The first letter in search term, save existing folder open state -        if (!mPanelInventoryObject->getFilter().isNotDefault()) +        LLFolderView* root_folder = mPanelInventoryObject->getRootFolder(); +        if (filter_substring.empty())          { -            mSavedFolderState.setApply(false); -            mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState); +            if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) +            { +                // The current filter and the new filter are empty, nothing to do +                return; +            } + +            if (mDirtyFilter && !mSavedFolderState.hasOpenFolders()) +            { +                if (root_folder) +                { +                    root_folder->setOpenArrangeRecursively(true, LLFolderViewFolder::ERecurseType::RECURSE_DOWN); +                } +            } +            else +            { +                mSavedFolderState.setApply(true); +                if (root_folder) +                { +                    root_folder->applyFunctorRecursively(mSavedFolderState); +                } +            } +            mDirtyFilter = false; + +            // Add a folder with the current item to the list of previously opened folders +            if (root_folder) +            { +                LLOpenFoldersWithSelection opener; +                root_folder->applyFunctorRecursively(opener); +                root_folder->scrollToShowSelection(); +            } +        } +        else if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) +        { +            // The first letter in search term, save existing folder open state +            if (!mPanelInventoryObject->getFilter().isNotDefault()) +            { +                mSavedFolderState.setApply(false); +                if (root_folder) +                { +                    root_folder->applyFunctorRecursively(mSavedFolderState); +                } +                mDirtyFilter = false; +            }          }      } -      mPanelInventoryObject->getFilter().setFilterSubString(filter_substring);  } diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h index bb6308e8b8..6e02b17bab 100644 --- a/indra/newview/llpanelcontents.h +++ b/indra/newview/llpanelcontents.h @@ -70,6 +70,8 @@ protected:      void getState(LLViewerObject *object);      void onFilterEdit(); +    bool mDirtyFilter { false }; +  public:      class LLFilterEditor* mFilterEditor;      LLSaveFolderState mSavedFolderState; diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp index cb89a5910e..fc1bf6ca93 100644 --- a/indra/newview/llpanelemojicomplete.cpp +++ b/indra/newview/llpanelemojicomplete.cpp @@ -438,7 +438,7 @@ void LLPanelEmojiComplete::updateConstraints()  {      mRenderRect = getLocalRect(); -    mEmojiWidth = (U16)(mIconFont->getWidthF32(u8"\U0001F431") + mPadding * 2); +    mEmojiWidth = (U16)(mIconFont->getWidthF32(LLWString(1, 0x1F431).c_str()) + mPadding * 2);      if (mVertical)      {          mEmojiHeight = mIconFont->getLineHeight() + mPadding * 2; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 544b6fbc9c..c080d72580 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -898,6 +898,10 @@ struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor          if (facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot))          {              const LLTextureEntry* tep = facep->getTextureEntry(); +            if (!tep) +            { +                return false; +            }              LLVector2 st_offset, st_scale;              tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);              tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]); diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp index 433db74cda..8032e207cd 100644 --- a/indra/newview/llpanelgroupbulk.cpp +++ b/indra/newview/llpanelgroupbulk.cpp @@ -56,6 +56,7 @@ LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) :      mGroupID(group_id),      mBulkAgentList(NULL),      mOKButton(NULL), +    mAddButton(nullptr),      mRemoveButton(NULL),      mGroupName(NULL),      mLoadingText(), @@ -79,29 +80,18 @@ LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl()      }  } -// static -void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata) +void LLPanelGroupBulkImpl::callbackClickAdd(LLPanelGroupBulk* panelp)  { -    if (LLPanelGroupBulk* panelp = (LLPanelGroupBulk*)userdata) -    { -        // Right now this is hard coded with some knowledge that it is part -        // of a floater since the avatar picker needs to be added as a dependent -        // floater to the parent floater. -        // Soon the avatar picker will be embedded into this panel -        // instead of being it's own separate floater.  But that is next week. -        // This will do for now. -jwolk May 10, 2006 -        LLView* button = panelp->findChild<LLButton>("add_button"); -        LLFloater* root_floater = gFloaterView->getParentFloater(panelp); -        LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( -            [&](const uuid_vec_t& agent_ids, const std::vector<LLAvatarName>&) -            { -                panelp->mImplementation->addUsers(agent_ids); -            }, true, false, false, root_floater->getName(), button); -        if (picker) +    LLFloater* root_floater = gFloaterView->getParentFloater(panelp); +    LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( +        [this](const uuid_vec_t& agent_ids, const std::vector<LLAvatarName>&)          { -            root_floater->addDependentFloater(picker); -            LLGroupMgr::getInstance()->sendCapGroupMembersRequest(panelp->mImplementation->mGroupID); -        } +            addUsers(agent_ids); +        }, true, false, false, root_floater->getName(), mAddButton); +    if (picker) +    { +        root_floater->addDependentFloater(picker); +        LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);      }  } diff --git a/indra/newview/llpanelgroupbulkban.cpp b/indra/newview/llpanelgroupbulkban.cpp index 3c764887a6..1d3edad0f3 100644 --- a/indra/newview/llpanelgroupbulkban.cpp +++ b/indra/newview/llpanelgroupbulkban.cpp @@ -68,35 +68,26 @@ bool LLPanelGroupBulkBan::postBuild()          mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation);      } -    LLButton* button = getChild<LLButton>("add_button", recurse); -    if ( button ) +    mImplementation->mAddButton = getChild<LLButton>("add_button", recurse); +    // default to opening avatarpicker automatically +    mImplementation->mAddButton->setClickedCallback( +        [this](LLUICtrl* ctrl, const LLSD& param)      { -        // default to opening avatarpicker automatically -        // (*impl::callbackClickAdd)((void*)this); -        button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd, this); -    } +        mImplementation->callbackClickAdd(this); +    });      mImplementation->mRemoveButton =          getChild<LLButton>("remove_button", recurse); -    if ( mImplementation->mRemoveButton ) -    { -        mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation); -        mImplementation->mRemoveButton->setEnabled(false); -    } +    mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation); +    mImplementation->mRemoveButton->setEnabled(false);      mImplementation->mOKButton =          getChild<LLButton>("ban_button", recurse); -    if ( mImplementation->mOKButton ) -    { -        mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this); -        mImplementation->mOKButton->setEnabled(false); -    } +    mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this); +    mImplementation->mOKButton->setEnabled(false); -    button = getChild<LLButton>("cancel_button", recurse); -    if ( button ) -    { -        button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation); -    } +    LLButton* button = getChild<LLButton>("cancel_button", recurse); +    button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation);      mImplementation->mTooManySelected = getString("ban_selection_too_large");      mImplementation->mBanNotPermitted = getString("ban_not_permitted"); diff --git a/indra/newview/llpanelgroupbulkimpl.h b/indra/newview/llpanelgroupbulkimpl.h index 5a479f8117..5515bd6d9a 100644 --- a/indra/newview/llpanelgroupbulkimpl.h +++ b/indra/newview/llpanelgroupbulkimpl.h @@ -44,7 +44,7 @@ public:      LLPanelGroupBulkImpl(const LLUUID& group_id);      ~LLPanelGroupBulkImpl(); -    static void callbackClickAdd(void* userdata); +    void callbackClickAdd(LLPanelGroupBulk* panelp);      static void callbackClickRemove(void* userdata);      static void callbackClickCancel(void* userdata); @@ -70,6 +70,7 @@ public:      LLNameListCtrl*     mBulkAgentList;      LLButton*           mOKButton; +    LLButton*           mAddButton;      LLButton*           mRemoveButton;      LLTextBox*          mGroupName; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 377af4384a..a5b4db0580 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -2425,10 +2425,14 @@ void LLPanelMainInventory::updateCombinationVisibility()          mCombinationGalleryLayoutPanel->setVisible(!is_gallery_empty);          mCombinationListLayoutPanel->setVisible(show_inv_pane); -        mCombinationInventoryPanel->getRootFolder()->setForceArrange(!show_inv_pane); -        if(mCombinationInventoryPanel->hasVisibleItems()) +        LLFolderView* root_folder = mCombinationInventoryPanel->getRootFolder(); +        if (root_folder)          { -            mForceShowInvLayout = false; +            root_folder->setForceArrange(!show_inv_pane); +            if (mCombinationInventoryPanel->hasVisibleItems()) +            { +                mForceShowInvLayout = false; +            }          }          if(is_gallery_empty)          { diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index abb48dbeed..154639e4bb 100644 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -85,6 +85,8 @@ public:      static void idle(void* user_data); +    bool hasInventory(){ return mHaveInventory; }; +  protected:      void reset();      /*virtual*/ void inventoryChanged(LLViewerObject* object, diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 4db0a5b59d..b8c12ce0b9 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -660,11 +660,11 @@ void LLPanelPrimMediaControls::updateShape()          for(; vert_it != vert_end; ++vert_it)          {              // project silhouette vertices into screen space -            glm::vec3 screen_vert(glm::make_vec3(vert_it->mV)); +            glm::vec3 screen_vert(*vert_it);              screen_vert = mul_mat4_vec3(mat, screen_vert);              // add to screenspace bounding box -            update_min_max(min, max, LLVector3(glm::value_ptr(screen_vert))); +            update_min_max(min, max, LLVector3(screen_vert));          }          // convert screenspace bbox to pixels (in screen coords) diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 80e403dfde..2c09943b83 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -81,10 +81,9 @@ bool LLProgressView::postBuild()  {      mProgressBar = getChild<LLProgressBar>("login_progress_bar"); -    mLogosLabel = getChild<LLTextBox>("logos_lbl"); -      mProgressText = getChild<LLTextBox>("progress_text");      mMessageText = getChild<LLTextBox>("message_text"); +    mMessageTextRectInitial = mMessageText->getRect(); // auto resizes, save initial size      // media control that is used to play intro video      mMediaCtrl = getChild<LLMediaCtrl>("login_media_panel"); @@ -96,6 +95,12 @@ bool LLProgressView::postBuild()      mCancelBtn = getChild<LLButton>("cancel_btn");      mCancelBtn->setClickedCallback(  LLProgressView::onCancelButtonClicked, NULL ); +    mLayoutPanel4 = getChild<LLView>("panel4"); +    mLayoutPanel4RectInitial = mLayoutPanel4->getRect(); + +    mLayoutMOTD = getChild<LLView>("panel_motd"); +    mLayoutMOTDRectInitial = mLayoutMOTD->getRect(); +      getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle()));      getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage, this); @@ -234,33 +239,6 @@ void LLProgressView::drawStartTexture(F32 alpha)      gGL.popMatrix();  } -void LLProgressView::drawLogos(F32 alpha) -{ -    if (mLogosList.empty()) -    { -        return; -    } - -    // logos are tied to label, -    // due to potential resizes we have to figure offsets out on draw or resize -    S32 offset_x, offset_y; -    mLogosLabel->localPointToScreen(0, 0, &offset_x, &offset_y); -    std::vector<TextureData>::const_iterator iter = mLogosList.begin(); -    std::vector<TextureData>::const_iterator end = mLogosList.end(); -    for (; iter != end; iter++) -    { -        gl_draw_scaled_image_with_border(iter->mDrawRect.mLeft + offset_x, -                             iter->mDrawRect.mBottom + offset_y, -                             iter->mDrawRect.getWidth(), -                             iter->mDrawRect.getHeight(), -                             iter->mTexturep.get(), -                             UI_VERTEX_COLOR % alpha, -                             false, -                             iter->mClipRect, -                             iter->mOffsetRect); -    } -} -  void LLProgressView::draw()  {      static LLTimer timer; @@ -276,7 +254,6 @@ void LLProgressView::draw()          }          LLPanel::draw(); -        drawLogos(alpha);          return;      } @@ -289,7 +266,6 @@ void LLProgressView::draw()          drawStartTexture(alpha);          LLPanel::draw(); -        drawLogos(alpha);          // faded out completely - remove panel and reveal world          if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME ) @@ -324,7 +300,6 @@ void LLProgressView::draw()      drawStartTexture(1.0f);      // draw children      LLPanel::draw(); -    drawLogos(1.0f);  }  void LLProgressView::setText(const std::string& text) @@ -341,90 +316,18 @@ void LLProgressView::setMessage(const std::string& msg)  {      mMessage = msg;      mMessageText->setValue(mMessage); -} - -void LLProgressView::loadLogo(const std::string &path, -                              const U8 image_codec, -                              const LLRect &pos_rect, -                              const LLRectf &clip_rect, -                              const LLRectf &offset_rect) -{ -    // We need these images very early, so we have to force-load them, otherwise they might not load in time. -    if (!gDirUtilp->fileExists(path)) +    S32 height = mMessageText->getTextPixelHeight(); +    S32 delta  = height - mMessageTextRectInitial.getHeight(); +    if (delta > 0)      { -        return; +        mLayoutPanel4->reshape(mLayoutPanel4RectInitial.getWidth(), mLayoutPanel4RectInitial.getHeight() + delta); +        mLayoutMOTD->reshape(mLayoutMOTDRectInitial.getWidth(), mLayoutMOTDRectInitial.getHeight() + delta);      } - -    LLPointer<LLImageFormatted> start_image_frmted = LLImageFormatted::createFromType(image_codec); -    if (!start_image_frmted->load(path)) -    { -        LL_WARNS("AppInit") << "Image load failed: " << path << LL_ENDL; -        return; -    } - -    LLPointer<LLImageRaw> raw = new LLImageRaw; -    if (!start_image_frmted->decode(raw, 0.0f)) +    else      { -        LL_WARNS("AppInit") << "Image decode failed " << path << LL_ENDL; -        return; +        mLayoutPanel4->reshape(mLayoutPanel4RectInitial.getWidth(), mLayoutPanel4RectInitial.getHeight()); +        mLayoutMOTD->reshape(mLayoutMOTDRectInitial.getWidth(), mLayoutMOTDRectInitial.getHeight());      } -    // HACK: getLocalTexture allows only power of two dimentions -    raw->expandToPowerOfTwo(); - -    TextureData data; -    data.mTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), false); -    data.mDrawRect = pos_rect; -    data.mClipRect = clip_rect; -    data.mOffsetRect = offset_rect; -    mLogosList.push_back(data); -} - -void LLProgressView::initLogos() -{ -    mLogosList.clear(); - -    const U8 image_codec = IMG_CODEC_PNG; -    const LLRectf default_clip(0.f, 1.f, 1.f, 0.f); -    const S32 default_height = 28; -    const S32 default_pad = 15; - -    S32 icon_width, icon_height; - -    // We don't know final screen rect yet, so we can't precalculate position fully -    S32 texture_start_x = (S32)mLogosLabel->getFont()->getWidthF32(mLogosLabel->getWText().c_str()) + default_pad; -    S32 texture_start_y = -7; - -    // Normally we would just preload these textures from textures.xml, -    // and display them via icon control, but they are only needed on -    // startup and preloaded/UI ones stay forever -    // (and this code was done already so simply reused it) -    std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "textures", "3p_icons"); - -    temp_str += gDirUtilp->getDirDelimiter(); - -#ifdef LL_HAVOK -    // original image size is 342x113, central element is on a larger side -    // plus internal padding, so it gets slightly more height than desired 32 -    icon_width = 88; -    icon_height = 29; -    S32 pad_havok_y = -1; -    loadLogo(temp_str + "havok_logo.png", -        image_codec, -        LLRect(texture_start_x, texture_start_y + pad_havok_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_havok_y), -        default_clip, -        default_clip); - -    texture_start_x += icon_width + default_pad; -#endif //LL_HAVOK - -    // 108x41 -    icon_width = 74; -    icon_height = default_height; -    loadLogo(temp_str + "vivox_logo.png", -        image_codec, -        LLRect(texture_start_x, texture_start_y + icon_height, texture_start_x + icon_width, texture_start_y), -        default_clip, -        default_clip);  }  void LLProgressView::initStartTexture(S32 location_id, bool is_in_production) @@ -505,19 +408,11 @@ void LLProgressView::initStartTexture(S32 location_id, bool is_in_production)  void LLProgressView::initTextures(S32 location_id, bool is_in_production)  {      initStartTexture(location_id, is_in_production); -    initLogos(); - -    childSetVisible("panel_icons", !mLogosList.empty()); -    childSetVisible("panel_top_spacer", mLogosList.empty());  }  void LLProgressView::releaseTextures()  {      gStartTexture = NULL; -    mLogosList.clear(); - -    childSetVisible("panel_top_spacer", true); -    childSetVisible("panel_icons", false);  }  void LLProgressView::setCancelButtonVisible(bool b, const std::string& label) diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index 15b04a8eb9..250ee511d7 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -53,7 +53,6 @@ public:      /*virtual*/ void draw();      void drawStartTexture(F32 alpha); -    void drawLogos(F32 alpha);      /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask);      /*virtual*/ bool handleKeyHere(KEY key, MASK mask); @@ -86,7 +85,6 @@ public:  protected:      LLProgressBar* mProgressBar;      LLMediaCtrl* mMediaCtrl; -    LLTextBox* mLogosLabel = nullptr;      LLTextBox* mProgressText = nullptr;      LLTextBox* mMessageText = nullptr;      F32 mPercentDone; @@ -95,6 +93,13 @@ protected:      LLFrameTimer mFadeToWorldTimer;      LLFrameTimer mFadeFromLoginTimer;      LLRect mOutlineRect; +    LLView* mLayoutPanel4 = nullptr; +    LLView* mLayoutMOTD = nullptr; +    // Rects for resizing purposes +    LLRect mMessageTextRectInitial; +    LLRect mLayoutPanel4RectInitial; +    LLRect mLayoutMOTDRectInitial; +      bool mMouseDownInActiveArea;      bool mStartupComplete; @@ -105,25 +110,8 @@ protected:      bool handleUpdate(const LLSD& event_data);      static void onIdle(void* user_data); -    void loadLogo(const std::string &path, const U8 image_codec, const LLRect &pos_rect, const LLRectf &clip_rect, const LLRectf &offset_rect); -    // logos have unusual location and need to be preloaded to not appear grey, then deleted -    void initLogos();      // Loads a bitmap to display during load      void initStartTexture(S32 location_id, bool is_in_production); - -private: -    // We need to draw textures on login, but only once. -    // So this vector gets filled up for textures to render and gets cleaned later -    // Some textures have unusual requirements, so we are rendering directly -    class TextureData -    { -    public: -        LLPointer<LLViewerTexture> mTexturep; -        LLRect mDrawRect; -        LLRectf mClipRect; -        LLRectf mOffsetRect; -    }; -    std::vector<TextureData> mLogosList;  };  #endif // LL_LLPROGRESSVIEW_H diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index f77d37f821..f3adb52d5e 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -65,8 +65,9 @@ void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 n      }      F32 clip = (near_clip > 0) ? near_clip : getNearClip(); +    bool dynamic = force_dynamic || getIsDynamic(); -    gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, getIsDynamic() || force_dynamic, useClipPlane, clipPlane); +    gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, dynamic, useClipPlane, clipPlane);  }  void LLReflectionMap::autoAdjustOrigin() @@ -185,7 +186,7 @@ void LLReflectionMap::autoAdjustOrigin()      }  } -bool LLReflectionMap::intersects(LLReflectionMap* other) +bool LLReflectionMap::intersects(LLReflectionMap* other) const  {      LLVector4a delta;      delta.setSub(other->mOrigin, mOrigin); @@ -201,24 +202,24 @@ bool LLReflectionMap::intersects(LLReflectionMap* other)  extern LLControlGroup gSavedSettings; -F32 LLReflectionMap::getAmbiance() +F32 LLReflectionMap::getAmbiance() const  {      F32 ret = 0.f; -    if (mViewerObject && mViewerObject->getVolume()) +    if (mViewerObject && mViewerObject->getVolumeConst())      { -        ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance(); +        ret = mViewerObject->getReflectionProbeAmbiance();      }      return ret;  } -F32 LLReflectionMap::getNearClip() +F32 LLReflectionMap::getNearClip() const  {      const F32 MINIMUM_NEAR_CLIP = 0.1f;      F32 ret = 0.f; -    if (mViewerObject && mViewerObject->getVolume()) +    if (mViewerObject && mViewerObject->getVolumeConst())      {          ret = mViewerObject->getReflectionProbeNearClip();      } @@ -234,11 +235,13 @@ F32 LLReflectionMap::getNearClip()      return llmax(ret, MINIMUM_NEAR_CLIP);  } -bool LLReflectionMap::getIsDynamic() +bool LLReflectionMap::getIsDynamic() const  { -    if (gSavedSettings.getS32("RenderReflectionProbeDetail") > (S32) LLReflectionMapManager::DetailLevel::STATIC_ONLY && +    static LLCachedControl<S32> detail(gSavedSettings, "RenderReflectionProbeDetail", 1); +    if (detail() > (S32)LLReflectionMapManager::DetailLevel::STATIC_ONLY &&          mViewerObject && -        mViewerObject->getVolume()) +        !mViewerObject->isDead() && +        mViewerObject->getVolumeConst())      {          return mViewerObject->getReflectionProbeIsDynamic();      } @@ -256,7 +259,7 @@ bool LLReflectionMap::getBox(LLMatrix4& box)              glm::mat4 mv(get_current_modelview());              LLVector3 s = mViewerObject->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));              mRadius = s.magVec(); -            glm::mat4 scale = glm::scale(glm::make_vec3(s.mV)); +            glm::mat4 scale = glm::scale(glm::vec3(s));              if (mViewerObject->mDrawable != nullptr)              {                  // object to agent space (no scale) @@ -278,12 +281,12 @@ bool LLReflectionMap::getBox(LLMatrix4& box)      return false;  } -bool LLReflectionMap::isActive() +bool LLReflectionMap::isActive() const  {      return mCubeIndex != -1;  } -bool LLReflectionMap::isRelevant() +bool LLReflectionMap::isRelevant() const  {      static LLCachedControl<S32> RenderReflectionProbeLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index 117ea4cfa6..d20bba7059 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -58,16 +58,16 @@ public:      void autoAdjustOrigin();      // return true if given Reflection Map's influence volume intersect's with this one's -    bool intersects(LLReflectionMap* other); +    bool intersects(LLReflectionMap* other) const;      // Get the ambiance value to use for this probe -    F32 getAmbiance(); +    F32 getAmbiance() const;      // Get the near clip plane distance to use for this probe -    F32 getNearClip(); +    F32 getNearClip() const;      // Return true if this probe should include avatars in its reflection map -    bool getIsDynamic(); +    bool getIsDynamic() const;      // get the encoded bounding box of this probe's influence volume      // will only return a box if this probe is associated with a VOVolume @@ -76,13 +76,13 @@ public:      bool getBox(LLMatrix4& box);      // return true if this probe is active for rendering -    bool isActive(); +    bool isActive() const;      // perform occlusion query/readback      void doOcclusion(const LLVector4a& eye);      // return false if this probe isn't currently relevant (for example, disabled due to graphics preferences) -    bool isRelevant(); +    bool isRelevant() const;      // point at which environment map was last generated from (in agent space)      LLVector4a mOrigin; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8f75b108cc..9a20977652 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -223,9 +223,11 @@ void LLReflectionMapManager::update()      initReflectionMaps(); +    static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); +      if (!mRenderTarget.isComplete())      { -        U32 color_fmt = GL_RGB16F; +        U32 color_fmt = render_hdr ? GL_R11F_G11F_B10F : GL_RGB8;          U32 targetRes = mProbeResolution * 4; // super sample          mRenderTarget.allocate(targetRes, targetRes, color_fmt, true);      } @@ -238,7 +240,7 @@ void LLReflectionMapManager::update()          mMipChain.resize(count);          for (U32 i = 0; i < count; ++i)          { -            mMipChain[i].allocate(res, res, GL_RGB16F); +            mMipChain[i].allocate(res, res, render_hdr ? GL_R11F_G11F_B10F : GL_RGB8);              res /= 2;          }      } @@ -306,7 +308,7 @@ void LLReflectionMapManager::update()          LLReflectionMap* probe = mProbes[i];          llassert(probe != nullptr); -        if (probe->mCubeIndex != -1 && mUpdatingProbe != probe) +        if (probe && probe->mCubeIndex != -1 && mUpdatingProbe != probe)          { // free this index              mCubeFree.push_back(probe->mCubeIndex); @@ -1415,11 +1417,13 @@ void LLReflectionMapManager::initReflectionMaps()          {              mTexture = new LLCubeMapArray(); +            static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); +              // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) -            mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); +            mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr);              mIrradianceMaps = new LLCubeMapArray(); -            mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false); +            mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr);          }          // reset probe state diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index cf96072ae2..6023f6885d 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -807,7 +807,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)      static LLCachedControl<F32> tonemap_mix_setting(gSavedSettings, "RenderTonemapMix", 1.f);      // sky is a "classic" sky following pre SL 7.0 shading -    bool classic_mode = psky->canAutoAdjust(); +    bool classic_mode = psky->canAutoAdjust() && !should_auto_adjust();      if (!classic_mode)      { @@ -832,6 +832,10 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)          {              shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV));              shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, sqrtf(g)*2.0f); // use a modifier here so 1.0 maps to the "most desirable" default and the maximum value doesn't go off the rails + +            // Low quality setting +            if (!LLPipeline::sReflectionProbesEnabled) +                probe_ambiance = DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE;          }          else if (psky->canAutoAdjust() && should_auto_adjust)          { // auto-adjust legacy sky to take advantage of probe ambiance @@ -1093,8 +1097,8 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)          LLVector4 waterPlane(enorm.x, enorm.y, enorm.z, -glm::dot(ep, enorm)); -        norm = glm::make_vec3(gPipeline.mHeroProbeManager.mMirrorNormal.mV); -        p    = glm::make_vec3(gPipeline.mHeroProbeManager.mMirrorPosition.mV); +        norm = glm::vec3(gPipeline.mHeroProbeManager.mMirrorNormal); +        p    = glm::vec3(gPipeline.mHeroProbeManager.mMirrorPosition);          enorm = mul_mat4_vec3(invtrans, norm);          enorm = glm::normalize(enorm);          ep = mul_mat4_vec3(mat, p); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index a1a67c319c..f3cfbd9565 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2609,12 +2609,8 @@ void renderTexturePriority(LLDrawable* drawable)          LLGLDisable blend(GL_BLEND); -        //LLViewerTexture* imagep = facep->getTexture(); -        //if (imagep)          if (facep)          { - -            //F32 vsize = imagep->mMaxVirtualSize;              F32 vsize = facep->getPixelArea();              if (vsize > sCurMaxTexPriority) @@ -2640,18 +2636,6 @@ void renderTexturePriority(LLDrawable* drawable)          size.mul(0.5f);          size.add(LLVector4a(0.01f));          drawBox(center, size); - -        /*S32 boost = imagep->getBoostLevel(); -        if (boost>LLGLTexture::BOOST_NONE) -        { -            F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1); -            LLVector4 col = lerp(boost_cold, boost_hot, t); -            LLGLEnable blend_on(GL_BLEND); -            gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); -            gGL.diffuseColor4fv(col.mV); -            drawBox(center, size); -            gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -        }*/      }  } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index b32b80331a..6c3f3849ce 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1045,6 +1045,7 @@ bool idle_startup()          login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());          login->setLastExecEvent(gLastExecEvent);          login->setLastExecDuration(gLastExecDuration); +        login->setLastAgentSessionId(gLastAgentSessionId);          // This call to LLLoginInstance::connect() starts the          // authentication process. @@ -1393,7 +1394,7 @@ bool idle_startup()          }          else if (regionp->capabilitiesError())          { -            LL_WARNS("AppInit") << "Failed to get capabilities. Backing up to login screen!" << LL_ENDL; +            LL_WARNS("AppInit") << "Failed to get capabilities. Logging out and backing up to login screen!" << LL_ENDL;              if (gRememberPassword)              {                  LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); @@ -1402,6 +1403,15 @@ bool idle_startup()              {                  LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);              } + +            // Session was created, don't just hang up on server, send a logout request +            LLMessageSystem* msg = gMessageSystem; +            msg->newMessageFast(_PREHASH_LogoutRequest); +            msg->nextBlockFast(_PREHASH_AgentData); +            msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +            msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +            gAgent.sendReliableMessage(); +              reset_login();          }          else @@ -1409,7 +1419,7 @@ bool idle_startup()              U32 num_retries = regionp->getNumSeedCapRetries();              if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_ABORT)              { -                LL_WARNS("AppInit") << "Failed to get capabilities. Backing up to login screen!" << LL_ENDL; +                LL_WARNS("AppInit") << "Failed to get capabilities. Logging out and backing up to login screen!" << LL_ENDL;                  if (gRememberPassword)                  {                      LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); @@ -1418,6 +1428,15 @@ bool idle_startup()                  {                      LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);                  } + +                // Session was created, don't just hang up on server, send a logout request +                LLMessageSystem* msg = gMessageSystem; +                msg->newMessageFast(_PREHASH_LogoutRequest); +                msg->nextBlockFast(_PREHASH_AgentData); +                msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +                msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +                gAgent.sendReliableMessage(); +                  reset_login();              }              else if (num_retries > 0) @@ -1507,7 +1526,7 @@ bool idle_startup()          // create a container's instance for start a controlling conversation windows          // by the voice's events          LLFloaterIMContainer *im_inst = LLFloaterIMContainer::getInstance(); -        if(gAgent.isFirstLogin()) +        if(gAgent.isFirstLogin() && im_inst)          {              im_inst->openFloater(im_inst->getKey());          } @@ -1720,7 +1739,7 @@ bool idle_startup()          if (!gAgentMovementCompleted && timeout.getElapsedTimeF32() > STATE_AGENT_WAIT_TIMEOUT)          { -            LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL; +            LL_WARNS("AppInit") << "Timeout on agent movement. Sending logout and backing up to login screen!" << LL_ENDL;              if (gRememberPassword)              {                  LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); @@ -1729,6 +1748,15 @@ bool idle_startup()              {                  LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);              } + +            // Session was created, don't just hang up on server, send a logout request +            LLMessageSystem* msg = gMessageSystem; +            msg->newMessageFast(_PREHASH_LogoutRequest); +            msg->nextBlockFast(_PREHASH_AgentData); +            msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +            msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +            gAgent.sendReliableMessage(); +              reset_login();          }          return false; @@ -3529,6 +3557,7 @@ bool process_login_success_response()      text = response["session_id"].asString();      if(!text.empty()) gAgentSessionID.set(text);      gDebugInfo["SessionID"] = text; +    LLAppViewer::instance()->recordSessionToMarker();      // Session id needed for parcel info request in LLUrlEntryParcel      // to resolve parcel name. diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index bac0c736b1..087761cbd0 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -29,6 +29,7 @@  #include <iostream>  #include <map>  #include <algorithm> +#include <atomic>  #include "lltexturefetch.h" @@ -2843,7 +2844,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, S3  bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)  {      LL_PROFILE_ZONE_SCOPED; -    mRequestQueue.tryPost([=]() +    mRequestQueue.tryPost([=, this]()          {              LLTextureFetchWorker* worker = getWorker(id);              if (worker) @@ -3571,29 +3572,30 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)      //if (! gViewerAssetStatsThread1)      //  return true; -    static volatile bool reporting_started(false); -    static volatile S32 report_sequence(0); +    static std::atomic<bool> reporting_started(false); +    static std::atomic<S32> report_sequence(0);      // In mStatsSD, we have a copy we own of the LLSD representation      // of the asset stats. Add some additional fields and ship it off.      static const S32 metrics_data_version = 2; -    bool initial_report = !reporting_started; +    bool initial_report = !reporting_started.load();      mStatsSD["session_id"] = mSessionID;      mStatsSD["agent_id"] = mAgentID;      mStatsSD["message"] = "ViewerAssetMetrics"; -    mStatsSD["sequence"] = report_sequence; +    mStatsSD["sequence"] = report_sequence.load();      mStatsSD["initial"] = initial_report;      mStatsSD["version"] = metrics_data_version;      mStatsSD["break"] = static_cast<bool>(LLTextureFetch::svMetricsDataBreak);      // Update sequence number -    if (S32_MAX == ++report_sequence) +    if (S32_MAX == report_sequence.fetch_add(1))      { -        report_sequence = 0; +        report_sequence.store(0);      } -    reporting_started = true; + +    reporting_started.store(true);      // Limit the size of the stats report if necessary. diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index aa43b2dbad..7d777162ed 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -420,7 +420,7 @@ bool LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord      LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();      glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight()); -    glm::vec3 win_coord = glm::project(glm::make_vec3(pos_agent.mV), get_current_modelview(), get_current_projection(), viewport); +    glm::vec3 win_coord = glm::project(glm::vec3(pos_agent), get_current_modelview(), get_current_projection(), viewport);      {          // convert screen coordinates to virtual UI coordinates @@ -514,7 +514,7 @@ bool LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,      LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();      glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight()); -    glm::vec3 win_coord = glm::project(glm::make_vec3(pos_agent.mV), get_current_modelview(), get_current_projection(), viewport); +    glm::vec3 win_coord = glm::project(glm::vec3(pos_agent), get_current_modelview(), get_current_projection(), viewport);      {          win_coord.x /= gViewerWindow->getDisplayScale().mV[VX]; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 18746e76fc..598ad89907 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -261,6 +261,8 @@ static bool handleDisableVintageMode(const LLSD& newvalue)  static bool handleEnableHDR(const LLSD& newvalue)  { +    gPipeline.mReflectionMapManager.reset(); +    gPipeline.mHeroProbeManager.reset();      return handleReleaseGLBufferChanged(newvalue) && handleSetShaderChanged(newvalue);  } @@ -448,11 +450,11 @@ static bool handleReflectionProbeDetailChanged(const LLSD& newvalue)      if (gPipeline.isInit())      {          LLPipeline::refreshCachedSettings(); +        gPipeline.mReflectionMapManager.reset(); +        gPipeline.mHeroProbeManager.reset();          gPipeline.releaseGLBuffers();          gPipeline.createGLBuffers();          LLViewerShaderMgr::instance()->setShaders(); -        gPipeline.mReflectionMapManager.reset(); -        gPipeline.mHeroProbeManager.reset();      }      return true;  } @@ -762,9 +764,9 @@ LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const st      LLPointer<LLControlVariable> cntrl_ptr = group.getControl(setting);      if (cntrl_ptr.isNull())      { +        LLError::LLUserWarningMsg::showMissingFiles();          LL_ERRS() << "Unable to set up setting listener for " << setting -            << ". Please reinstall viewer from  https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." -            << LL_ENDL; +            << "." << LL_ENDL;      }      return cntrl_ptr;  } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 4e7416bb63..d688d5930c 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -2902,14 +2902,14 @@ void LLViewerMediaImpl::update()              media_tex->ref();              main_queue->postTo(                  mTexUpdateQueue, // Worker thread queue -                [=]() // work done on update worker thread +                [=, this]() // work done on update worker thread                  {  #if LL_IMAGEGL_THREAD_CHECK                      media_tex->getGLTexture()->mActiveThread = LLThread::currentID();  #endif                      doMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height, true);                  }, -                [=]() // callback to main thread +                [=, this]() // callback to main thread                  {  #if LL_IMAGEGL_THREAD_CHECK                      media_tex->getGLTexture()->mActiveThread = LLThread::currentID(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 80c75ec919..d92faf4d1b 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -5199,15 +5199,16 @@ void handle_take(bool take_separate)      // MAINT-290      // Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez.      // Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened -    params.functor.function([take_separate](const LLSD ¬ification, const LLSD &response) +    LLObjectSelectionHandle obj_selection = LLSelectMgr::instance().getSelection(); +    params.functor.function([take_separate, obj_selection](const LLSD ¬ification, const LLSD &response)      {          if (take_separate)          { -            confirm_take_separate(notification, response, LLSelectMgr::instance().getSelection()); +            confirm_take_separate(notification, response, obj_selection);          }          else          { -            confirm_take(notification, response, LLSelectMgr::instance().getSelection()); +            confirm_take(notification, response, obj_selection);          }      }); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index b6846c6716..206840ebfb 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -727,6 +727,9 @@ public:      // index into LLViewerObjectList::mActiveObjects or -1 if not in list      S32             mListIndex; +    // last index data for mIndexAndLocalIDToUUID +    U32             mRegionIndex; +      LLPointer<LLViewerTexture> *mTEImages;      LLPointer<LLViewerTexture> *mTENormalMaps;      LLPointer<LLViewerTexture> *mTESpecularMaps; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index d667fdbea8..d72d428c08 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -164,21 +164,14 @@ U64 LLViewerObjectList::getIndex(const U32 local_id,      return (((U64)index) << 32) | (U64)local_id;  } -bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) +bool LLViewerObjectList::removeFromLocalIDTable(LLViewerObject* objectp)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; -    if(objectp && objectp->getRegion()) +    if(objectp && objectp->mRegionIndex != 0)      {          U32 local_id = objectp->mLocalID; -        U32 ip = objectp->getRegion()->getHost().getAddress(); -        U32 port = objectp->getRegion()->getHost().getPort(); -        U64 ipport = (((U64)ip) << 32) | (U64)port; -        U32 index = mIPAndPortToIndex[ipport]; - -        // LL_INFOS() << "Removing object from table, local ID " << local_id << ", ip " << ip << ":" << port << LL_ENDL; - -        U64 indexid = (((U64)index) << 32) | (U64)local_id; +        U64 indexid = (((U64)objectp->mRegionIndex) << 32) | (U64)local_id;          std::map<U64, LLUUID>::iterator iter = mIndexAndLocalIDToUUID.find(indexid);          if (iter == mIndexAndLocalIDToUUID.end()) @@ -190,6 +183,7 @@ bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)          if (iter->second == objectp->getID())          {   // Full UUIDs match, so remove the entry              mIndexAndLocalIDToUUID.erase(iter); +            objectp->mRegionIndex = 0;              return true;          }          // UUIDs did not match - this would zap a valid entry, so don't erase it @@ -203,7 +197,8 @@ bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)  void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,                                            const U32 local_id,                                            const U32 ip, -                                          const U32 port) +                                          const U32 port, +                                          LLViewerObject* objectp)  {      U64 ipport = (((U64)ip) << 32) | (U64)port; @@ -215,6 +210,7 @@ void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,          mIPAndPortToIndex[ipport] = index;      } +    objectp->mRegionIndex = index; // should never be zero, sSimulatorMachineIndex starts from 1      U64 indexid = (((U64)index) << 32) | (U64)local_id;      mIndexAndLocalIDToUUID[indexid] = id; @@ -335,7 +331,8 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry*              removeFromLocalIDTable(objectp);              setUUIDAndLocal(fullid, entry->getLocalID(),                              regionp->getHost().getAddress(), -                            regionp->getHost().getPort()); +                            regionp->getHost().getPort(), +                            objectp);              if (objectp->mLocalID != entry->getLocalID())              {   // Update local ID in object with the one sent from the region @@ -582,7 +579,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,              setUUIDAndLocal(fullid,                              local_id,                              gMessageSystem->getSenderIP(), -                            gMessageSystem->getSenderPort()); +                            gMessageSystem->getSenderPort(), +                            objectp);              if (objectp->mLocalID != local_id)              {   // Update local ID in object with the one sent from the region @@ -1381,11 +1379,20 @@ void LLViewerObjectList::killObjects(LLViewerRegion *regionp)  void LLViewerObjectList::killAllObjects()  {      // Used only on global destruction. -    LLViewerObject *objectp; +    // Mass cleanup to not clear lists one item at a time +    mIndexAndLocalIDToUUID.clear(); +    mActiveObjects.clear(); +    mMapObjects.clear(); + +    LLViewerObject *objectp;      for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)      {          objectp = *iter; +        objectp->setOnActiveList(false); +        objectp->setListIndex(-1); +        objectp->mRegionIndex = 0; +        objectp->mOnMap = false;          killObject(objectp);          // Object must be dead, or it's the LLVOAvatarSelf which never dies.          llassert((objectp == gAgentAvatarp) || objectp->isDead()); @@ -1398,18 +1405,6 @@ void LLViewerObjectList::killAllObjects()          LL_WARNS() << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.size() << LL_ENDL;          mObjects.clear();      } - -    if (!mActiveObjects.empty()) -    { -        LL_WARNS() << "Some objects still on active object list!" << LL_ENDL; -        mActiveObjects.clear(); -    } - -    if (!mMapObjects.empty()) -    { -        LL_WARNS() << "Some objects still on map object list!" << LL_ENDL; -        mMapObjects.clear(); -    }  }  void LLViewerObjectList::cleanDeadObjects(bool use_timer) @@ -1471,20 +1466,25 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp)  {      S32 idx = objectp->getListIndex();      if (idx != -1) -    { //remove by moving last element to this object's position -        llassert(mActiveObjects[idx] == objectp); - +    {          objectp->setListIndex(-1); -        S32 last_index = static_cast<S32>(mActiveObjects.size()) - 1; - -        if (idx != last_index) +        S32 size = (S32)mActiveObjects.size(); +        if (size > 0) // mActiveObjects could have been cleaned already          { -            mActiveObjects[idx] = mActiveObjects[last_index]; -            mActiveObjects[idx]->setListIndex(idx); -        } +            // Remove by moving last element to this object's position -        mActiveObjects.pop_back(); +            llassert(idx < size); // idx should be always within mActiveObjects, unless killAllObjects was called +            llassert(mActiveObjects[idx] == objectp); // object should be there + +            S32 last_index = size - 1; +            if (idx < last_index) +            { +                mActiveObjects[idx] = mActiveObjects[last_index]; +                mActiveObjects[idx]->setListIndex(idx); +            } // else assume it's the last element, no need to swap +            mActiveObjects.pop_back(); +        }      }  } @@ -1509,9 +1509,9 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp)                  mActiveObjects.push_back(objectp);                  objectp->setListIndex(static_cast<S32>(mActiveObjects.size()) - 1);              objectp->setOnActiveList(true); -        } -        else -        { +            } +            else +            {                  llassert(idx < mActiveObjects.size());                  llassert(mActiveObjects[idx] == objectp); @@ -1863,7 +1863,8 @@ LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, L      setUUIDAndLocal(uuid,                      local_id,                      regionp->getHost().getAddress(), -                    regionp->getHost().getPort()); +                    regionp->getHost().getPort(), +                    objectp);      mObjects.push_back(objectp);      updateActive(objectp); @@ -1901,7 +1902,8 @@ LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRe      setUUIDAndLocal(fullid,                      local_id,                      gMessageSystem->getSenderIP(), -                    gMessageSystem->getSenderPort()); +                    gMessageSystem->getSenderPort(), +                    objectp);      mObjects.push_back(objectp); diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index dc31995eb1..547ef9fb2d 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -179,9 +179,10 @@ public:      void setUUIDAndLocal(const LLUUID &id,                                  const U32 local_id,                                  const U32 ip, -                                const U32 port); // Requires knowledge of message system info! +                                const U32 port, +                                LLViewerObject* objectp); // Requires knowledge of message system info! -    bool removeFromLocalIDTable(const LLViewerObject* objectp); +    bool removeFromLocalIDTable(LLViewerObject* objectp);      // Used ONLY by the orphaned object code.      U64 getIndex(const U32 local_id, const U32 ip, const U32 port); diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 8c24b2438b..8e6657b4b9 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1824,6 +1824,16 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use                  S32 bitmap_size =   parcel_mgr.mParcelsPerEdge                                      * parcel_mgr.mParcelsPerEdge                                      / 8; +                S32 size = msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_Bitmap); +                if (size != bitmap_size) +                { +                    // Might be better to ignore bitmap and drop highlights +                    LL_WARNS("ParcelMgr") << "Parcel Bitmap size expected: " << bitmap_size +                        << " actual " << size +                        << ". Bitmap might be corrupted!" << LL_ENDL; +                    bitmap_size = size; +                } +                  U8* bitmap = new U8[ bitmap_size ];                  msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5b4648a0bf..a0a9906724 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -101,6 +101,7 @@ LLGLSLShader    gReflectionProbeDisplayProgram;  LLGLSLShader    gCopyProgram;  LLGLSLShader    gCopyDepthProgram;  LLGLSLShader    gPBRTerrainBakeProgram; +LLGLSLShader    gDrawColorProgram;  //object shaders  LLGLSLShader        gObjectPreviewProgram; @@ -113,7 +114,6 @@ LLGLSLShader        gObjectAlphaMaskNoColorProgram;  //environment shaders  LLGLSLShader        gWaterProgram; -LLGLSLShader        gWaterEdgeProgram;  LLGLSLShader        gUnderWaterProgram;  //interface shaders @@ -409,7 +409,6 @@ void LLViewerShaderMgr::finalizeShaderList()      //ONLY shaders that need WL Param management should be added here      mShaderList.push_back(&gAvatarProgram);      mShaderList.push_back(&gWaterProgram); -    mShaderList.push_back(&gWaterEdgeProgram);      mShaderList.push_back(&gAvatarEyeballProgram);      mShaderList.push_back(&gImpostorProgram);      mShaderList.push_back(&gObjectBumpProgram); @@ -623,6 +622,8 @@ void LLViewerShaderMgr::setShaders()      else      {          // "ShaderLoading" and "Shader" need to be logged +        LL_WARNS("Shader") << "Failed loading basic shaders.  Retrying with increased log level..." << LL_ENDL; +          LLError::ELevel lvl = LLError::getDefaultLevel();          LLError::setDefaultLevel(LLError::LEVEL_DEBUG);          loadBasicShaders(); @@ -843,7 +844,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()          // Note usage of GL_VERTEX_SHADER          if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0)          { -            LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; +            LL_WARNS("Shader") << "Failed to load basic vertex shader " << i << ": " << shaders[i].first << LL_ENDL;              return shaders[i].first;          }      } @@ -874,6 +875,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()      index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/shadowUtil.glsl",                      1) );      index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/aoUtil.glsl",                          1) );      index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/pbrterrainUtilF.glsl",                 1) ); +    index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/tonemapUtilF.glsl",                    1) );      index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl",                has_reflection_probes ? 3 : 2) );      index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl",             ssr ? 3 : 1) );      index_channels.push_back(-1);    shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl",                    mShaderLevel[SHADER_LIGHTING] ) ); @@ -906,7 +908,6 @@ bool LLViewerShaderMgr::loadShadersWater()      if (mShaderLevel[SHADER_WATER] == 0)      {          gWaterProgram.unload(); -        gWaterEdgeProgram.unload();          gUnderWaterProgram.unload();          return true;      } @@ -920,6 +921,7 @@ bool LLViewerShaderMgr::loadShadersWater()          gWaterProgram.mFeatures.hasGamma = true;          gWaterProgram.mFeatures.hasSrgb = true;          gWaterProgram.mFeatures.hasReflectionProbes = true; +        gWaterProgram.mFeatures.hasTonemap = true;          gWaterProgram.mFeatures.hasShadows = use_sun_shadow;          gWaterProgram.mShaderFiles.clear();          gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER)); @@ -943,36 +945,6 @@ bool LLViewerShaderMgr::loadShadersWater()      if (success)      { -    // load water shader -        gWaterEdgeProgram.mName = "Water Edge Shader"; -        gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true; -        gWaterEdgeProgram.mFeatures.hasAtmospherics = true; -        gWaterEdgeProgram.mFeatures.hasGamma = true; -        gWaterEdgeProgram.mFeatures.hasSrgb = true; -        gWaterEdgeProgram.mFeatures.hasReflectionProbes = true; -        gWaterEdgeProgram.mFeatures.hasShadows = use_sun_shadow; -        gWaterEdgeProgram.mShaderFiles.clear(); -        gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER)); -        gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER)); -        gWaterEdgeProgram.clearPermutations(); -        gWaterEdgeProgram.addPermutation("WATER_EDGE", "1"); -        if (LLPipeline::sRenderTransparentWater) -        { -            gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1"); -        } - -        if (use_sun_shadow) -        { -            gWaterEdgeProgram.addPermutation("HAS_SUN_SHADOW", "1"); -        } -        gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER; -        gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; -        success = gWaterEdgeProgram.createShader(); -        llassert(success); -    } - -    if (success) -    {          //load under water vertex shader          gUnderWaterProgram.mName = "Underwater Shader";          gUnderWaterProgram.mFeatures.calculatesAtmospherics = true; @@ -2481,6 +2453,7 @@ bool LLViewerShaderMgr::loadShadersDeferred()          gDeferredPostTonemapProgram.mName = "Deferred Tonemap Post Process";          gDeferredPostTonemapProgram.mFeatures.hasSrgb = true;          gDeferredPostTonemapProgram.mFeatures.isDeferred = true; +        gDeferredPostTonemapProgram.mFeatures.hasTonemap = true;          gDeferredPostTonemapProgram.mShaderFiles.clear();          gDeferredPostTonemapProgram.clearPermutations();          gDeferredPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); @@ -2495,6 +2468,7 @@ bool LLViewerShaderMgr::loadShadersDeferred()          gNoPostTonemapProgram.mName = "No Post Tonemap Post Process";          gNoPostTonemapProgram.mFeatures.hasSrgb = true;          gNoPostTonemapProgram.mFeatures.isDeferred = true; +        gNoPostTonemapProgram.mFeatures.hasTonemap = true;          gNoPostTonemapProgram.mShaderFiles.clear();          gNoPostTonemapProgram.clearPermutations();          gNoPostTonemapProgram.addPermutation("NO_POST", "1"); @@ -3353,6 +3327,17 @@ bool LLViewerShaderMgr::loadShadersInterface()          success = gCopyDepthProgram.createShader();      } +    if (success) +    { +        gDrawColorProgram.mName = "Draw Color Shader"; +        gDrawColorProgram.mShaderFiles.clear(); +        gDrawColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoAtmosV.glsl", GL_VERTEX_SHADER)); +        gDrawColorProgram.mShaderFiles.push_back(make_pair("objects/simpleColorF.glsl", GL_FRAGMENT_SHADER)); +        gDrawColorProgram.clearPermutations(); +        gDrawColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; +        success = gDrawColorProgram.createShader(); +    } +      if (gSavedSettings.getBOOL("LocalTerrainPaintEnabled"))      {          if (success) diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index b08796025a..7ad2da9464 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -175,6 +175,7 @@ extern LLGLSLShader         gReflectionProbeDisplayProgram;  extern LLGLSLShader         gCopyProgram;  extern LLGLSLShader         gCopyDepthProgram;  extern LLGLSLShader         gPBRTerrainBakeProgram; +extern LLGLSLShader         gDrawColorProgram;  //output tex0[tc0] - tex1[tc1]  extern LLGLSLShader         gTwoTextureCompareProgram; @@ -191,7 +192,6 @@ extern LLGLSLShader     gObjectAlphaMaskNoColorProgram;  //environment shaders  extern LLGLSLShader         gWaterProgram; -extern LLGLSLShader         gWaterEdgeProgram;  extern LLGLSLShader         gUnderWaterProgram;  extern LLGLSLShader         gGlowProgram;  extern LLGLSLShader         gGlowExtractProgram; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 36b6787ace..609ad38e96 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -87,6 +87,7 @@ S32 LLViewerTexture::sRawCount = 0;  S32 LLViewerTexture::sAuxCount = 0;  LLFrameTimer LLViewerTexture::sEvaluationTimer;  F32 LLViewerTexture::sDesiredDiscardBias = 0.f; +U32 LLViewerTexture::sBiasTexturesUpdated = 0;  S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size  constexpr S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64; @@ -107,12 +108,6 @@ LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTextur  const F64 log_2 = log(2.0); -#if ADDRESS_SIZE == 32 -const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT / 2; -#else -const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT; -#endif -  //----------------------------------------------------------------------------------------------  //namespace: LLViewerTextureAccess  //---------------------------------------------------------------------------------------------- @@ -518,6 +513,7 @@ void LLViewerTexture::updateClass()      bool is_sys_low = isSystemMemoryLow();      bool is_low = is_sys_low || over_pct > 0.f; +    F32 discard_bias = sDesiredDiscardBias;      static bool was_low = false;      static bool was_sys_low = false; @@ -556,12 +552,13 @@ void LLViewerTexture::updateClass()          // don't execute above until the slam to 1.5 has a chance to take effect          sEvaluationTimer.reset(); -        // lower discard bias over time when free memory is available -        if (sDesiredDiscardBias > 1.f && over_pct < 0.f) +        // lower discard bias over time when at least 10% of budget is free +        const F32 FREE_PERCENTAGE_TRESHOLD = -0.1f; +        if (sDesiredDiscardBias > 1.f && over_pct < FREE_PERCENTAGE_TRESHOLD)          {              static LLCachedControl<F32> high_mem_discard_decrement(gSavedSettings, "RenderHighMemMinDiscardDecrement", .1f); -            F32 decrement = high_mem_discard_decrement - llmin(over_pct, 0.f); +            F32 decrement = high_mem_discard_decrement - llmin(over_pct - FREE_PERCENTAGE_TRESHOLD, 0.f);              sDesiredDiscardBias -= decrement * gFrameIntervalSeconds;          }      } @@ -603,6 +600,12 @@ void LLViewerTexture::updateClass()      }      sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 1.f, 4.f); +    if (discard_bias != sDesiredDiscardBias) +    { +        // bias changed, reset texture update counter to +        // let updates happen at an increased rate. +        sBiasTexturesUpdated = 0; +    }      LLViewerTexture::sFreezeImageUpdates = false;  } @@ -1685,6 +1688,16 @@ void LLViewerFetchedTexture::processTextureStats()          static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false); +        U32 max_tex_res = MAX_IMAGE_SIZE_DEFAULT; +        if (mBoostLevel < LLGLTexture::BOOST_HIGH) +        { +            // restrict texture resolution to download based on RenderMaxTextureResolution +            static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048); +            // sanity clamp debug setting to avoid settings hack shenanigans +            max_tex_res = (U32)llclamp((U32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT); +            mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)(max_tex_res * max_tex_res)); +        } +          if (textures_fullres)          {              mDesiredDiscardLevel = 0; @@ -1706,10 +1719,9 @@ void LLViewerFetchedTexture::processTextureStats()          }          else          { -            U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096              if(!mKnownDrawWidth || !mKnownDrawHeight || (S32)mFullWidth <= mKnownDrawWidth || (S32)mFullHeight <= mKnownDrawHeight)              { -                if (mFullWidth > desired_size || mFullHeight > desired_size) +                if (mFullWidth > max_tex_res || mFullHeight > max_tex_res)                  {                      mDesiredDiscardLevel = 1;                  } @@ -2913,8 +2925,6 @@ LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, co  void LLViewerLODTexture::init(bool firstinit)  {      mTexelsPerImage = 64*64; -    mDiscardVirtualSize = 0.f; -    mCalculatedDiscardLevel = -1.f;  }  //virtual @@ -2939,12 +2949,14 @@ void LLViewerLODTexture::processTextureStats()      static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false); -    { // restrict texture resolution to download based on RenderMaxTextureResolution +    F32 max_tex_res = MAX_IMAGE_SIZE_DEFAULT; +    if (mBoostLevel < LLGLTexture::BOOST_HIGH) +    { +        // restrict texture resolution to download based on RenderMaxTextureResolution          static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048);          // sanity clamp debug setting to avoid settings hack shenanigans -        F32 tex_res = (F32)llclamp((S32)max_texture_resolution, 512, 2048); -        tex_res *= tex_res; -        mMaxVirtualSize = llmin(mMaxVirtualSize, tex_res); +        max_tex_res = (F32)llclamp((S32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT); +        mMaxVirtualSize = llmin(mMaxVirtualSize, max_tex_res * max_tex_res);      }      if (textures_fullres) @@ -2993,19 +3005,12 @@ void LLViewerLODTexture::processTextureStats()          {              // Calculate the required scale factor of the image using pixels per texel              discard_level = (F32)(log(mTexelsPerImage / mMaxVirtualSize) / log_4); -            mDiscardVirtualSize = mMaxVirtualSize; -            mCalculatedDiscardLevel = discard_level;          }          discard_level = floorf(discard_level);          F32 min_discard = 0.f; -        U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 -        if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED) -        { -            desired_size = DESIRED_NORMAL_TEXTURE_SIZE; -        } -        if (mFullWidth > desired_size || mFullHeight > desired_size) +        if (mFullWidth > max_tex_res || mFullHeight > max_tex_res)              min_discard = 1.f;          discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL); @@ -3543,18 +3548,7 @@ void LLViewerMediaTexture::setPlaying(bool playing)          for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)          {              LLFace* facep = *iter; -            const LLTextureEntry* te = facep->getTextureEntry(); -            if (te->getGLTFMaterial()) -            { -                // PBR material, switch emissive and basecolor -                switchTexture(LLRender::EMISSIVE_MAP, *iter); -                switchTexture(LLRender::BASECOLOR_MAP, *iter); -            } -            else -            { -                // blinn-phong material, switch diffuse map only -                switchTexture(LLRender::DIFFUSE_MAP, *iter); -            } +            switchTexture(LLRender::DIFFUSE_MAP, facep);          }      }      else //stop playing this media diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 4241ef958f..e1582c74bd 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -220,6 +220,7 @@ public:      static S32 sAuxCount;      static LLFrameTimer sEvaluationTimer;      static F32 sDesiredDiscardBias; +    static U32 sBiasTexturesUpdated;      static S32 sMaxSculptRez ;      static U32 sMinLargeImageSize ;      static U32 sMaxSmallImageSize ; @@ -540,10 +541,6 @@ public:  private:      void init(bool firstinit) ; - -private: -    F32 mDiscardVirtualSize;        // Virtual size used to calculate desired discard -    F32 mCalculatedDiscardLevel;    // Last calculated discard level  };  // diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 0b79c2d8e0..12543089c9 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -266,7 +266,7 @@ void LLViewerTextureList::doPrefetchImages()          S32 pixel_area = imagesd["area"];          S32 texture_type = imagesd["type"]; -        if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type) +        if((LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type))          {              LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type);              if (image) @@ -1081,7 +1081,8 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)          imagep->mCreatePending = false;          mCreateTextureList.pop(); -        if (imagep->hasGLTexture() && imagep->getDiscardLevel() < imagep->getDesiredDiscardLevel()) +        if (imagep->hasGLTexture() && imagep->getDiscardLevel() < imagep->getDesiredDiscardLevel() && +           (imagep->getDesiredDiscardLevel() <= MAX_DISCARD_LEVEL))          {              // NOTE: this may happen if the desired discard reduces while a decode is in progress and does not              // necessarily indicate a problem, but if log occurrences excede that of dsiplay_stats: FPS, @@ -1198,10 +1199,17 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)      //update MIN_UPDATE_COUNT or 5% of other textures, whichever is greater      update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/20); -    if (LLViewerTexture::sDesiredDiscardBias > 1.f) +    if (LLViewerTexture::sDesiredDiscardBias > 1.f +        && LLViewerTexture::sBiasTexturesUpdated < (U32)mUUIDMap.size())      { -        // we are over memory target, update more agresively +        // We are over memory target. Bias affects discard rates, so update +        // existing textures agresively to free memory faster.          update_count = (S32)(update_count * LLViewerTexture::sDesiredDiscardBias); + +        // This isn't particularly precise and can overshoot, but it doesn't need +        // to be, just making sure it did a full circle and doesn't get stuck updating +        // at bias = 4 with 4 times the rate permanently. +        LLViewerTexture::sBiasTexturesUpdated += update_count;      }      update_count = llmin(update_count, (U32) mUUIDMap.size()); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8a5aac9b8b..1795d62adc 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1331,7 +1331,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi                                  // Check the whitelist, if there's media (otherwise just show it)                                  if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url))                                  { -                                    if ( obj != mDragHoveredObject) +                                    if ( obj != mDragHoveredObject.get())                                      {                                          // Highlight the dragged object                                          LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); @@ -1746,6 +1746,7 @@ bool LLViewerWindow::handleDeviceChange(LLWindow *window)  bool LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height)  { +    LLFontGL::sResolutionGeneration++;      if (ui_scale_factor >= MIN_UI_SCALE && ui_scale_factor <= MAX_UI_SCALE)      {          LLViewerWindow::reshape(window_width, window_height); @@ -1759,6 +1760,12 @@ bool LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32      }  } +bool LLViewerWindow::handleDisplayChanged() +{ +    LLFontGL::sResolutionGeneration++; +    return false; +} +  bool LLViewerWindow::handleWindowDidChangeScreen(LLWindow *window)  {      LLCoordScreen window_rect; @@ -1927,6 +1934,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)      mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));      mDisplayScale *= ui_scale_factor;      LLUI::setScaleFactor(mDisplayScale); +    LLFontGL::sResolutionGeneration++;      {          LLCoordWindow size; @@ -2494,6 +2502,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)          bool display_scale_changed = mDisplayScale != LLUI::getScaleFactor();          LLUI::setScaleFactor(mDisplayScale); +        LLFontGL::sResolutionGeneration++;          // update our window rectangle          mWindowRectScaled.mRight = mWindowRectScaled.mLeft + ll_round((F32)width / mDisplayScale.mV[VX]); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 1b995ea650..fbc2c58fbf 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -225,6 +225,7 @@ public:      /*virtual*/ bool handleTimerEvent(LLWindow *window);      /*virtual*/ bool handleDeviceChange(LLWindow *window);      /*virtual*/ bool handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); +    /*virtual*/ bool handleDisplayChanged();      /*virtual*/ bool handleWindowDidChangeScreen(LLWindow *window);      /*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7bc9d06f9a..7bf9c88b99 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1928,8 +1928,8 @@ bool LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&              glm::mat4 inverse = glm::inverse(mat);              glm::mat4 norm_mat = glm::transpose(inverse); -            glm::vec3 p1(glm::make_vec3(start.getF32ptr())); -            glm::vec3 p2(glm::make_vec3(end.getF32ptr())); +            glm::vec3 p1(start); +            glm::vec3 p2(end);              p1 = mul_mat4_vec3(inverse, p1);              p2 = mul_mat4_vec3(inverse, p2); @@ -1937,12 +1937,12 @@ bool LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&              LLVector3 position;              LLVector3 norm; -            if (linesegment_sphere(LLVector3(glm::value_ptr(p1)), LLVector3(glm::value_ptr(p2)), LLVector3(0,0,0), 1.f, position, norm)) +            if (linesegment_sphere(LLVector3(p1), LLVector3(p2), LLVector3(0,0,0), 1.f, position, norm))              { -                glm::vec3 res_pos(glm::make_vec3(position.mV)); +                glm::vec3 res_pos(position);                  res_pos = mul_mat4_vec3(mat, res_pos); -                 glm::vec3 res_norm(glm::make_vec3(norm.mV)); +                 glm::vec3 res_norm(norm);                  res_norm = glm::normalize(res_norm);                  res_norm = glm::mat3(norm_mat) * res_norm; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 623d8deac9..3edd2b473c 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -285,6 +285,7 @@ void LLVoiceClient::setNonSpatialVoiceModule(const std::string &voice_server_typ  void LLVoiceClient::setHidden(bool hidden)  { +    LL_INFOS("Voice") << "( " << (hidden ? "true" : "false") << " )" << LL_ENDL;      LLWebRTCVoiceClient::getInstance()->setHidden(hidden);      LLVivoxVoiceClient::getInstance()->setHidden(hidden);  } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 7d6ad743bd..8792ae3285 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -2004,7 +2004,7 @@ bool LLVivoxVoiceClient::waitForChannel()              {                  recordingAndPlaybackMode();              } -            else if (mProcessChannels && (mNextAudioSession == NULL) && checkParcelChanged()) +            else if (mProcessChannels && ((mNextAudioSession == NULL) || checkParcelChanged()))              {                  // the parcel is changed, or we have no pending audio sessions,                  // so try to request the parcel voice info diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index b2e5de5371..93c217a7ba 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -345,6 +345,8 @@ void LLWebRTCVoiceClient::updateSettings()      static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice");      setRenderDevice(sOutputDevice); +    LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL; +      static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic");      setMicGain(sMicLevel); @@ -554,7 +556,7 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()                  }              }              LL::WorkQueue::postMaybe(mMainQueue, -                [=] { +                [=, this] {                      if  (sShuttingDown)                      {                          return; @@ -672,7 +674,7 @@ void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceLi  {      LL::WorkQueue::postMaybe(mMainQueue, -                             [=] +                             [=, this]          {              OnDevicesChangedImpl(render_devices, capture_devices);          }); @@ -896,7 +898,7 @@ void LLWebRTCVoiceClient::OnConnectionShutDown(const std::string &channelID, con          {              if (mSession && mSession->mChannelID == channelID)              { -                LL_DEBUGS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL; +                LL_INFOS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL;              }          }          mSession->removeAllParticipants(regionID); @@ -1504,6 +1506,11 @@ bool LLWebRTCVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD &  // we're muting the mic, so tell each session such  void LLWebRTCVoiceClient::setMuteMic(bool muted)  { +    if (mMuteMic != muted) +    { +        LL_INFOS("Voice") << "( " << (muted ? "true" : "false") << " )" << LL_ENDL; +    } +      mMuteMic = muted;      // when you're hidden, your mic is always muted.      if (!mHidden) @@ -1552,14 +1559,10 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE; -    LL_DEBUGS("Voice") -        << "( " << (enabled ? "enabled" : "disabled") << " )" -        << " was "<< (mVoiceEnabled ? "enabled" : "disabled") -        << " coro "<< (mIsCoroutineActive ? "active" : "inactive") -        << LL_ENDL; -      if (enabled != mVoiceEnabled)      { +        LL_INFOS("Voice") << "( " << (enabled ? "enabled" : "disabled") << " )" +                           << ", coro: " << (mIsCoroutineActive ? "active" : "inactive") << LL_ENDL;          // TODO: Refactor this so we don't call into LLVoiceChannel, but simply          // use the status observer          mVoiceEnabled = enabled; @@ -2208,7 +2211,7 @@ LLVoiceWebRTCConnection::~LLVoiceWebRTCConnection()  void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState state)  {      LL::WorkQueue::postMaybe(mMainQueue, -        [=] { +        [=, this] {              LL_DEBUGS("Voice") << "Ice Gathering voice account. " << state << LL_ENDL;              switch (state) @@ -2231,7 +2234,7 @@ void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObs  // callback from llwebrtc  void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate& candidate)  { -    LL::WorkQueue::postMaybe(mMainQueue, [=] { mIceCandidates.push_back(candidate); }); +    LL::WorkQueue::postMaybe(mMainQueue, [=, this] { mIceCandidates.push_back(candidate); });  }  void LLVoiceWebRTCConnection::processIceUpdates() @@ -2349,7 +2352,7 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection)  void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)  {      LL::WorkQueue::postMaybe(mMainQueue, -        [=] { +        [=, this] {              if (mShutDown)              {                  return; @@ -2376,7 +2379,7 @@ void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)  void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface* audio_interface)  {      LL::WorkQueue::postMaybe(mMainQueue, -        [=] { +        [=, this] {              if (mShutDown)              {                  return; @@ -2398,7 +2401,7 @@ void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterfac  void LLVoiceWebRTCConnection::OnRenegotiationNeeded()  {      LL::WorkQueue::postMaybe(mMainQueue, -        [=] { +        [=, this] {              LL_DEBUGS("Voice") << "Voice channel requires renegotiation." << LL_ENDL;              if (!mShutDown)              { @@ -2412,7 +2415,7 @@ void LLVoiceWebRTCConnection::OnRenegotiationNeeded()  void LLVoiceWebRTCConnection::OnPeerConnectionClosed()  {      LL::WorkQueue::postMaybe(mMainQueue, -        [=] { +        [=, this] {              LL_DEBUGS("Voice") << "Peer connection has closed." << LL_ENDL;              if (mVoiceConnectionState == VOICE_STATE_WAIT_FOR_CLOSE)              { @@ -2483,7 +2486,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE; -    LL_DEBUGS("Voice") << "Disconnecting voice." << LL_ENDL; +    LL_INFOS("Voice") << "Disconnecting voice." << LL_ENDL;      if (connection->mWebRTCDataInterface)      {          connection->mWebRTCDataInterface->unsetDataObserver(connection.get()); @@ -2591,6 +2594,7 @@ void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()      LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];      LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); +    LL_INFOS("Voice") << "Voice connection request: " << (status ? "Success" : status.toString()) << LL_ENDL;      if (status)      {          OnVoiceConnectionRequestSuccess(result); @@ -2884,7 +2888,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()  // llwebrtc callback  void LLVoiceWebRTCConnection::OnDataReceived(const std::string& data, bool binary)  { -    LL::WorkQueue::postMaybe(mMainQueue, [=] { LLVoiceWebRTCConnection::OnDataReceivedImpl(data, binary); }); +    LL::WorkQueue::postMaybe(mMainQueue, [=, this] { LLVoiceWebRTCConnection::OnDataReceivedImpl(data, binary); });  }  // @@ -3040,7 +3044,7 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b  void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface)  {      LL::WorkQueue::postMaybe(mMainQueue, -        [=] { +        [=, this] {              if (mShutDown)              {                  return; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6514db0814..4e8932f912 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -645,8 +645,12 @@ void LLVOVolume::animateTextures()                          // LLVOVolume::updateTextureVirtualSize when the                          // mTextureMatrix is not yet present                          gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); -                        mDrawable->getSpatialGroup()->dirtyGeom(); -                        gPipeline.markRebuild(mDrawable->getSpatialGroup()); +                        LLSpatialGroup* group = mDrawable->getSpatialGroup(); +                        if (group) +                        { +                            group->dirtyGeom(); +                            gPipeline.markRebuild(group); +                        }                      }                  } @@ -5735,13 +5739,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)                      continue;                  } -                LLFetchedGLTFMaterial *gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial(); +                LLFetchedGLTFMaterial* gltf_mat = nullptr; +                const LLTextureEntry* te = facep->getTextureEntry(); +                if (te) +                { +                    gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial(); +                } // if not te, continue?                  bool is_pbr = gltf_mat != nullptr;                  if (is_pbr)                  {                      // tell texture streaming system to ignore blinn-phong textures -                    facep->setTexture(LLRender::DIFFUSE_MAP, nullptr); +                    // except the special case of the diffuse map containing a +                    // media texture that will be reused for swapping on to the pbr face +                    if (!facep->hasMedia()) +                    { +                        facep->setTexture(LLRender::DIFFUSE_MAP, nullptr); +                    }                      facep->setTexture(LLRender::NORMAL_MAP, nullptr);                      facep->setTexture(LLRender::SPECULAR_MAP, nullptr); @@ -5797,10 +5811,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)                  {                      cur_total += facep->getGeomCount(); -                    const LLTextureEntry* te = facep->getTextureEntry();                      LLViewerTexture* tex = facep->getTexture(); -                    if (te->getGlow() > 0.f) +                    if (te && te->getGlow() > 0.f)                      {                          emissive = true;                      } @@ -5895,6 +5908,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)                              facep->mLastUpdateTime = gFrameTimeSeconds;                          } +                        if (te)                          {                              LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); @@ -5959,6 +5973,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)                                  add_face(sFullbrightFaces, fullbright_count, facep);                              }                          } +                        else // no texture entry +                        { +                            facep->setState(LLFace::FULLBRIGHT); +                            add_face(sFullbrightFaces, fullbright_count, facep); +                        }                      }                  }                  else @@ -6713,8 +6732,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace              { //shiny                  if (tex->getPrimaryFormat() == GL_ALPHA)                  { //invisiprim+shiny -                    registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); -                    registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); +                    if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh()) +                    { +                        registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); +                        registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); +                    }                  }                  else if (!hud_group)                  { //deferred rendering @@ -6750,7 +6772,10 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace              { //not alpha and not shiny                  if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)                  { //invisiprim -                    registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); +                    if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh()) +                    { +                        registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); +                    }                  }                  else if (fullbright || bake_sunlight)                  { //fullbright diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1ca67dd88a..18dd694246 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -431,6 +431,7 @@ void LLPipeline::init()      stop_glerror();      //create render pass pools +    getPool(LLDrawPool::POOL_WATEREXCLUSION);      getPool(LLDrawPool::POOL_ALPHA_PRE_WATER);      getPool(LLDrawPool::POOL_ALPHA_POST_WATER);      getPool(LLDrawPool::POOL_SIMPLE); @@ -673,6 +674,8 @@ void LLPipeline::cleanup()      // don't delete wl sky pool it was handled above in the for loop      //delete mWLSkyPool;      mWLSkyPool = NULL; +    delete mWaterExclusionPool; +    mWaterExclusionPool = nullptr;      releaseGLBuffers(); @@ -907,6 +910,15 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY)          mPostMap.allocate(resX, resY, screenFormat); +        // The water exclusion mask needs its own depth buffer so we can take care of the problem of multiple water planes. +        // Should we ever make water not just a plane, it also aids with that as well as the water planes will be rendered into the mask. +        // Why do we do this? Because it saves us some janky logic in the exclusion shader when we generate the mask. +        // Regardless, this should always only be an R8 texture unless we choose to start having multiple kinds of exclusion that 8 bits can't handle. +        // - Geenz 2025-02-06 +        bool success = mWaterExclusionMask.allocate(resX, resY, GL_R8, true); + +        assert(success); +          // used to scale down textures          // See LLViwerTextureList::updateImagesCreateTextures and LLImageGL::scaleDown          mDownResMap.allocate(1024, 1024, GL_RGBA); @@ -1166,6 +1178,8 @@ void LLPipeline::releaseGLBuffers()      mSceneMap.release(); +    mWaterExclusionMask.release(); +      mPostMap.release();      mFXAAMap.release(); @@ -1676,6 +1690,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)          poolp = mPBRAlphaMaskPool;          break; +    case LLDrawPool::POOL_WATEREXCLUSION: +        poolp = mWaterExclusionPool; +        break; +      default:          llassert(0);          LL_ERRS() << "Invalid Pool Type in  LLPipeline::findPool() type=" << type << LL_ENDL; @@ -3855,7 +3873,12 @@ void LLPipeline::renderSelectedFaces(const LLColor4& color)          for (auto facep : mSelectedFaces)          { -            if (!facep || facep->getDrawable()->isDead()) +            if (!facep || !facep->getViewerObject()) +            { +                LLSelectMgr::getInstance()->clearSelections(); +                return; +            } +            if (!facep->getDrawable() || facep->getDrawable()->isDead())              {                  LL_ERRS() << "Bad face on selection" << LL_ENDL;                  return; @@ -4063,6 +4086,8 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)      }  } +// Render all of our geometry that's required after our deferred pass. +// This is gonna be stuff like alpha, water, etc.  void LLPipeline::renderGeomPostDeferred(LLCamera& camera)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; @@ -4079,6 +4104,10 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)      bool done_atmospherics = LLPipeline::sRenderingHUDs; //skip atmospherics on huds      bool done_water_haze = done_atmospherics; +    bool done_water_exclusion = false; + +    // do water exclusion just before water pass. +    U32 water_exclusion_pass = LLDrawPool::POOL_WATEREXCLUSION;      // do atmospheric haze just before post water alpha      U32 atmospherics_pass = LLDrawPool::POOL_ALPHA_POST_WATER; @@ -4117,6 +4146,12 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)          cur_type = poolp->getType(); +        if (cur_type >= water_exclusion_pass && !done_water_exclusion) +        { // do water exclusion against depth buffer before rendering alpha +            doWaterExclusionMask(); +            done_water_exclusion = true; +        } +          if (cur_type >= atmospherics_pass && !done_atmospherics)          { // do atmospherics against depth buffer before rendering alpha              doAtmospherics(); @@ -5196,6 +5231,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )          }          break; +    case LLDrawPool::POOL_WATEREXCLUSION: +        if (mWaterExclusionPool) +        { +            llassert(0); +            LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water Exclusion Pool" << LL_ENDL; +        } +        else +        { +            mWaterExclusionPool = new_poolp; +        } +        break;      default:          llassert(0); @@ -5318,6 +5364,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )          mPBRAlphaMaskPool = NULL;          break; +    case LLDrawPool::POOL_WATEREXCLUSION: +        llassert(poolp == mWaterExclusionPool); +        mWaterExclusionPool = nullptr; +        break; +      default:          llassert(0);          LL_WARNS() << "Invalid Pool Type in  LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL; @@ -7076,7 +7127,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool          LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky(); -        F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust); +        F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust());          F32 exp_min = 1.f;          F32 exp_max = 1.f; @@ -7087,13 +7138,13 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool          {              if (dynamic_exposure_enabled)              { -                exp_min = sky->getHDROffset() - sky->getHDRMin(); -                exp_max = sky->getHDROffset() + sky->getHDRMax(); +                exp_min = sky->getHDROffset(should_auto_adjust()) - sky->getHDRMin(should_auto_adjust()); +                exp_max = sky->getHDROffset(should_auto_adjust()) + sky->getHDRMax(should_auto_adjust());              }              else              { -                exp_min = sky->getHDROffset(); -                exp_max = sky->getHDROffset(); +                exp_min = sky->getHDROffset(should_auto_adjust()); +                exp_max = sky->getHDROffset(should_auto_adjust());              }          }          else if (dynamic_exposure_enabled) @@ -7113,7 +7164,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool          shader->uniform1f(dt, gFrameIntervalSeconds);          shader->uniform2f(noiseVec, ll_frand() * 2.0f - 1.0f, ll_frand() * 2.0f - 1.0f);          shader->uniform4f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max, dynamic_exposure_speed_error); -        shader->uniform4f(dynamic_exposure_params2, sky->getHDROffset(), exp_min, exp_max, dynamic_exposure_speed_target); +        shader->uniform4f(dynamic_exposure_params2, sky->getHDROffset(should_auto_adjust()), exp_min, exp_max, dynamic_exposure_speed_target);          mScreenTriangleVB->setBuffer();          mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -7171,7 +7222,7 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst)          static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U);          shader.uniform1i(tonemap_type, tonemap_type_setting); -        shader.uniform1f(tonemap_mix, psky->getTonemapMix()); +        shader.uniform1f(tonemap_mix, psky->getTonemapMix(should_auto_adjust()));          mScreenTriangleVB->setBuffer();          mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -8391,13 +8442,13 @@ void LLPipeline::renderDeferredLighting()          setupHWLights();  // to set mSun/MoonDir; -        glm::vec4 tc(glm::make_vec4(mSunDir.mV)); +        glm::vec4 tc(mSunDir);          tc = mat * tc; -        mTransformedSunDir.set(glm::value_ptr(tc)); +        mTransformedSunDir.set(tc); -        glm::vec4 tc_moon(glm::make_vec4(mMoonDir.mV)); +        glm::vec4 tc_moon(mMoonDir);          tc_moon = mat * tc_moon; -        mTransformedMoonDir.set(glm::value_ptr(tc_moon)); +        mTransformedMoonDir.set(tc_moon);          if ((RenderDeferredSSAO && !gCubeSnapshot) || RenderShadowDetail > 0)          { @@ -8650,7 +8701,7 @@ void LLPipeline::renderDeferredLighting()                              continue;                          } -                        glm::vec3 tc(glm::make_vec3(c)); +                        glm::vec3 tc(center);                          tc = mul_mat4_vec3(mat, tc);                          fullscreen_lights.push_back(LLVector4(tc.x, tc.y, tc.z, s)); @@ -8757,13 +8808,12 @@ void LLPipeline::renderDeferredLighting()                      LLDrawable* drawablep = *iter;                      LLVOVolume* volume = drawablep->getVOVolume();                      LLVector3   center = drawablep->getPositionAgent(); -                    F32* c = center.mV;                      F32         light_size_final = volume->getLightRadius() * 1.5f;                      F32         light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF);                      sVisibleLightCount++; -                    glm::vec3 tc(glm::make_vec3(c)); +                    glm::vec3 tc(center);                      tc = mul_mat4_vec3(mat, tc);                      setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); @@ -8820,6 +8870,7 @@ void LLPipeline::renderDeferredLighting()                            LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,                            LLPipeline::RENDER_TYPE_TERRAIN,                            LLPipeline::RENDER_TYPE_WATER, +                          LLPipeline::RENDER_TYPE_WATEREXCLUSION,                            END_RENDER_TYPES);          renderGeomPostDeferred(*LLViewerCamera::getInstance()); @@ -8958,6 +9009,8 @@ void LLPipeline::doWaterHaze()          static LLStaticHashedString above_water_str("above_water");          haze_shader.uniform1i(above_water_str, sUnderWaterRender ? -1 : 1); +        haze_shader.bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &mWaterExclusionMask); +          if (LLPipeline::sUnderWaterRender)          {              LLGLDepthTest depth(GL_FALSE); @@ -8988,6 +9041,17 @@ void LLPipeline::doWaterHaze()      }  } +void LLPipeline::doWaterExclusionMask() +{ +    mWaterExclusionMask.bindTarget(); +    glClearColor(1, 1, 1, 1); +    mWaterExclusionMask.clear(); +    mWaterExclusionPool->render(); + +    mWaterExclusionMask.flush(); +    glClearColor(0, 0, 0, 0); +} +  void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)  {      //construct frustum @@ -9898,10 +9962,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)      LLVector3 lightDir = -caster_dir;      lightDir.normVec(); -    glm::vec3 light_dir(glm::make_vec3(lightDir.mV)); -      //create light space camera matrix -      LLVector3 at = lightDir;      LLVector3 up = camera.getAtAxis(); @@ -9953,9 +10014,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)          //get good split distances for frustum          for (U32 i = 0; i < fp.size(); ++i)          { -            glm::vec3 v(glm::make_vec3(fp[i].mV)); +            glm::vec3 v(fp[i]);              v = mul_mat4_vec3(saved_view, v); -            fp[i].setVec(glm::value_ptr(v)); +            fp[i] = LLVector3(v);          }          min = fp[0]; @@ -10104,9 +10165,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)              for (U32 i = 0; i < fp.size(); i++)              { -                glm::vec3 p = glm::make_vec3(fp[i].mV); +                glm::vec3 p(fp[i]);                  p = mul_mat4_vec3(view[j], p); -                wpf.push_back(LLVector3(glm::value_ptr(p))); +                wpf.push_back(LLVector3(p));              }              min = wpf[0]; @@ -10307,19 +10368,19 @@ void LLPipeline::generateSunShadow(LLCamera& camera)                          view[j] = glm::inverse(view[j]);                          //llassert(origin.isFinite()); -                        glm::vec3 origin_agent(glm::make_vec3(origin.mV)); +                        glm::vec3 origin_agent(origin);                          //translate view to origin                          origin_agent = mul_mat4_vec3(view[j], origin_agent); -                        eye = LLVector3(glm::value_ptr(origin_agent)); +                        eye = LLVector3(origin_agent);                          //llassert(eye.isFinite());                          if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)                          {                              mShadowFrustOrigin[j] = eye;                          } -                        view[j] = look(LLVector3(glm::value_ptr(origin_agent)), lightDir, -up); +                        view[j] = look(LLVector3(origin_agent), lightDir, -up);                          F32 fx = 1.f/tanf(fovx);                          F32 fz = 1.f/tanf(fovz); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5c9b95ef4a..315e38ed8c 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -337,6 +337,9 @@ public:      // should be called just before rendering pre-water alpha objects      void doWaterHaze(); +    // Generate the water exclusion surface mask. +    void doWaterExclusionMask(); +      void postDeferredGammaCorrect(LLRenderTarget* screen_target);      void generateSunShadow(LLCamera& camera); @@ -500,6 +503,7 @@ public:          RENDER_TYPE_AVATAR                      = LLDrawPool::POOL_AVATAR,          RENDER_TYPE_CONTROL_AV                  = LLDrawPool::POOL_CONTROL_AV, // Animesh          RENDER_TYPE_TREE                        = LLDrawPool::POOL_TREE, +        RENDER_TYPE_WATEREXCLUSION              = LLDrawPool::POOL_WATEREXCLUSION,          RENDER_TYPE_VOIDWATER                   = LLDrawPool::POOL_VOIDWATER,          RENDER_TYPE_WATER                       = LLDrawPool::POOL_WATER,          RENDER_TYPE_GLTF_PBR                    = LLDrawPool::POOL_GLTF_PBR, @@ -714,6 +718,7 @@ public:      LLRenderTarget          mSpotShadow[2];      LLRenderTarget          mPbrBrdfLut; +    LLRenderTarget          mWaterExclusionMask;      // copy of the color/depth buffer just before gamma correction      // for use by SSR @@ -953,6 +958,7 @@ protected:      LLDrawPool*                 mWLSkyPool = nullptr;      LLDrawPool*                 mPBROpaquePool = nullptr;      LLDrawPool*                 mPBRAlphaMaskPool = nullptr; +    LLDrawPool*                 mWaterExclusionPool      = nullptr;      // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar diff --git a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png b/indra/newview/skins/default/textures/3p_icons/fmod_logo.pngBinary files differ deleted file mode 100644 index 5a50e0ad34..0000000000 --- a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/3p_icons/havok_logo.png b/indra/newview/skins/default/textures/3p_icons/havok_logo.pngBinary files differ deleted file mode 100644 index ff1ea3a72e..0000000000 --- a/indra/newview/skins/default/textures/3p_icons/havok_logo.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png b/indra/newview/skins/default/textures/3p_icons/vivox_logo.pngBinary files differ deleted file mode 100644 index 6f20e87b7a..0000000000 --- a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png +++ /dev/null diff --git a/indra/newview/skins/default/xui/de/panel_progress.xml b/indra/newview/skins/default/xui/de/panel_progress.xml index 8d1abdcac1..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/de/panel_progress.xml +++ b/indra/newview/skins/default/xui/de/panel_progress.xml @@ -1,10 +1,8 @@  <?xml version="1.0" ?>  <panel name="login_progress_panel"> -	<layout_panel name="panel_icons"/>  	<layout_stack name="vertical_centering"/>  	<layout_panel name="panel4"/>  	<layout_panel name="center"/>  	<layout_stack name="horizontal_centering"> -		<text name="logos_lbl">Second Life verwendet</text>  	</layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 65b98c65cf..96de9e61cb 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -1,6 +1,6 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <floater -  height="430" +  height="452"    layout="topleft"    name="prefs_graphics_advanced"    help_topic="Preferences_Graphics_Advanced" @@ -118,6 +118,41 @@      name="MaxLights"      top_delta="16"      width="336" /> +    <text +      type="string" +      length="1" +      follows="left|top" +      height="16" +      layout="topleft" +      top_delta="16" +      left="30" +      width="160" +      name="MaxTextureResolutionLabel" +      text_readonly_color="LabelDisabledColor"> +        Maximum LOD resolution: +    </text> +    <combo_box +     control_name="RenderMaxTextureResolution" +     height="19" +     layout="topleft" +     left_pad="10" +     top_delta="0" +     name="MaxTextureResolution" +     tool_tip="Maximum resolution for 'level of detail' textures" +     width="90"> +        <combo_box.item +          label="512" +          name="512" +          value="512"/> +        <combo_box.item +          label="1024" +          name="1024" +          value="1024"/> +        <combo_box.item +          label="2048" +          name="2048" +          value="2048"/> +    </combo_box>    <check_box      control_name="RenderVSyncEnable" @@ -152,7 +187,7 @@        layout="topleft"        left="30"        top_delta="16" -      width="128" +      width="130"        name="AvatarComplexityModeLabel"        text_readonly_color="LabelDisabledColor">          Avatar display: @@ -160,10 +195,10 @@      <combo_box       control_name="RenderAvatarComplexityMode" -     height="18" +     height="19"       layout="topleft" -     left_delta="130" -     top_delta="0" +     left_pad="40" +     top_delta="-1"       name="AvatarComplexityMode"       width="150">          <combo_box.item @@ -195,7 +230,7 @@      max_val="101"      name="IndirectMaxComplexity"      show_text="false" -    top_delta="16" +    top_delta="19"      width="300">      <slider.commit_callback        function="Pref.UpdateIndirectMaxComplexity" @@ -368,7 +403,7 @@        left="30"        name="antialiasing label"        top_delta="20" -      width="120"> +      width="130">          Antialiasing:      </text>      <combo_box @@ -403,7 +438,7 @@      left="30"      name="antialiasing quality label"      top_delta="20" -    width="120"> +    width="130">        Antialiasing Quality:    </text>    <combo_box @@ -1015,7 +1050,7 @@        layout="topleft"        left="13"        name="horiz_border" -      top="393" +      top="415"        top_delta="5"        width="774"/>    <button diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 1d1b81e31a..5fff9b7bc0 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -95,18 +95,11 @@          </menu_item_call>          <menu_item_separator/>          <menu_item_call -             label="[SECOND_LIFE] News" -             name="Second Life News"> -             <menu_item_call.on_click -                 function="Advanced.ShowURL" -                 parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>   -        </menu_item_call> -        <menu_item_call               label="[SECOND_LIFE] Blogs"               name="Second Life Blogs">               <menu_item_call.on_click                   function="Advanced.ShowURL" -                 parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/> +                 parameter="https://community.secondlife.com/news/"/>          </menu_item_call>          <menu_item_separator/>                 <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index e0e9fdcc32..0e70e75c0b 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1773,18 +1773,11 @@ function="World.EnvPreset"          </menu_item_call>          <menu_item_separator/>          <menu_item_call -             label="[SECOND_LIFE] News" -             name="Second Life News"> -             <menu_item_call.on_click -                 function="Advanced.ShowURL" -                 parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>   -        </menu_item_call> -        <menu_item_call               label="[SECOND_LIFE] Blogs"               name="Second Life Blogs">               <menu_item_call.on_click                   function="Advanced.ShowURL" -                 parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/> +                 parameter="https://community.secondlife.com/news/"/>          </menu_item_call>          <menu_item_separator/> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index 28c2d2af6e..258c49785e 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -202,7 +202,7 @@      follows="left|top"      height="14"      control_name="UpdaterWillingToTest" -    label="Willing to update to release candidates" +    label="Willing to update to Beta"      left_delta="0"      mouse_opaque="true"      name="update_willing_to_test" diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml index 242b96b695..6b19907372 100644 --- a/indra/newview/skins/default/xui/en/panel_progress.xml +++ b/indra/newview/skins/default/xui/en/panel_progress.xml @@ -33,7 +33,7 @@               layout="topleft"               left="0"               orientation="vertical"  -             name="vertical_centering" +             name="vertical_centering1"               top="0"               width="670">                  <layout_panel @@ -44,40 +44,32 @@                   width="670" />                  <layout_panel                   auto_resize="false" -                 height="275" +                 height="220"                   layout="topleft" -                 min_height="275" +                 min_height="220"                   name="panel4"                   width="670">                      <icon                       color="LoginProgressBoxCenterColor"                       follows="left|right|bottom|top" -                     height="275"                       image_name="Rounded_Square"                       layout="topleft"                       left="0"                       top="0" +                     height="220"                       width="670" />                      <layout_stack                       follows="left|right|top|bottom" -                     height="275" +                     height="220"                       layout="topleft"                       left="0"                       orientation="vertical" -                     name="vertical_centering" +                     name="vertical_centering2"                       animate="false"                       top="0"                       width="670">                        <layout_panel                         auto_resize="false" -                       height="30" -                       layout="topleft" -                       min_height="30" -                       name="panel_top_spacer" -                       width="670"> -                      </layout_panel> -                      <layout_panel -                       auto_resize="false"                         height="100"                         layout="topleft"                         min_height="100" @@ -121,9 +113,9 @@                        </layout_panel>                        <layout_panel                         auto_resize="false" -                       height="110" +                       height="90"                         layout="topleft" -                       min_height="110" +                       min_height="90"                         name="panel_motd"                         width="670">                          <text @@ -132,7 +124,7 @@                           font_shadow="none"                           halign="left"                           valign="center" -                         height="100" +                         height="80"                           layout="topleft"                           left="45"                           line_spacing.pixels="2" @@ -142,30 +134,6 @@                           right="-90"                           word_wrap="true"/>                        </layout_panel> -                      <layout_panel -                       auto_resize="false" -                       height="40" -                       layout="topleft" -                       min_height="40" -                       name="panel_icons" -                       width="670"> -                        <!--Logos are tied to following label from code--> -                        <text -                         follows="left|right|top" -                         layout="topleft" -                         font="SansSerifLarge" -                         font_shadow="none" -                         halign="left" -                         height="16" -                         width="240" -                         left="47" -                         top="6" -                         line_spacing.pixels="2" -                         name="logos_lbl" -                         text_color="LoginProgressBoxTextColor"> -                          Second Life uses -                        </text> -                      </layout_panel>                      </layout_stack>                  </layout_panel>                  <layout_panel diff --git a/indra/newview/skins/default/xui/es/panel_progress.xml b/indra/newview/skins/default/xui/es/panel_progress.xml index 64aaf246f8..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/es/panel_progress.xml +++ b/indra/newview/skins/default/xui/es/panel_progress.xml @@ -1,10 +1,8 @@  <?xml version="1.0" ?>  <panel name="login_progress_panel"> -	<layout_panel name="panel_icons"/>  	<layout_stack name="vertical_centering"/>  	<layout_panel name="panel4"/>  	<layout_panel name="center"/>  	<layout_stack name="horizontal_centering"> -		<text name="logos_lbl">Usos de Second Life</text>  	</layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_progress.xml b/indra/newview/skins/default/xui/fr/panel_progress.xml index 673ec63642..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/fr/panel_progress.xml +++ b/indra/newview/skins/default/xui/fr/panel_progress.xml @@ -1,10 +1,8 @@  <?xml version="1.0" ?>  <panel name="login_progress_panel"> -	<layout_panel name="panel_icons"/>  	<layout_stack name="vertical_centering"/>  	<layout_panel name="panel4"/>  	<layout_panel name="center"/>  	<layout_stack name="horizontal_centering"> -		<text name="logos_lbl">Second Life utilise</text>  	</layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/it/panel_progress.xml b/indra/newview/skins/default/xui/it/panel_progress.xml index fd2892a88f..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/it/panel_progress.xml +++ b/indra/newview/skins/default/xui/it/panel_progress.xml @@ -1,10 +1,8 @@  <?xml version="1.0" ?>  <panel name="login_progress_panel"> -	<layout_panel name="panel_icons"/>  	<layout_stack name="vertical_centering"/>  	<layout_panel name="panel4"/>  	<layout_panel name="center"/>  	<layout_stack name="horizontal_centering"> -		<text name="logos_lbl">Utilizzi di Second Life</text>  	</layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml index f487bc32a9..959f827a61 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml @@ -30,7 +30,7 @@  		<combo_box.item label="オプションのアップデートのインストール準備ができたら通知する" name="Install_ask"/>  		<combo_box.item label="必須アップデートのみインストールする" name="Install_manual"/>  	</combo_box> -	<check_box label="release candidate にアップグレードします" name="update_willing_to_test"/> +	<check_box label="Beta にアップグレードします" name="update_willing_to_test"/>  	<check_box label="更新後にリリースノートを表示する" name="update_show_release_notes"/>  	<text name="Proxy Settings:">  		プロキシ設定: diff --git a/indra/newview/skins/default/xui/ja/panel_progress.xml b/indra/newview/skins/default/xui/ja/panel_progress.xml index 7fd7d5ab5c..1edada6098 100644 --- a/indra/newview/skins/default/xui/ja/panel_progress.xml +++ b/indra/newview/skins/default/xui/ja/panel_progress.xml @@ -1,12 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="login_progress_panel"> -	<layout_panel name="panel_icons"/>  	<layout_stack name="vertical_centering"/>  	<layout_panel name="panel4"/>  	<layout_panel name="center"/>  	<layout_stack name="horizontal_centering"> -		<text name="logos_lbl"> -			セカンドライフ使用 -		</text>  	</layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/pl/panel_progress.xml b/indra/newview/skins/default/xui/pl/panel_progress.xml index 22b6a8fcf5..8da982cc3f 100644 --- a/indra/newview/skins/default/xui/pl/panel_progress.xml +++ b/indra/newview/skins/default/xui/pl/panel_progress.xml @@ -2,14 +2,9 @@  <panel name="login_progress_panel">  	<layout_stack name="horizontal_centering">  		<layout_panel name="center"> -			<layout_stack name="vertical_centering"> +			<layout_stack name="vertical_centering1">  				<layout_panel name="panel4"> -					<layout_stack name="vertical_centering"> -						<layout_panel name="panel_icons"> -							<text name="logos_lbl"> -								Second Life używa -							</text> -						</layout_panel> +					<layout_stack name="vertical_centering2">  					</layout_stack>  				</layout_panel>  			</layout_stack> diff --git a/indra/newview/skins/default/xui/pt/panel_progress.xml b/indra/newview/skins/default/xui/pt/panel_progress.xml index 63bb663cfc..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/pt/panel_progress.xml +++ b/indra/newview/skins/default/xui/pt/panel_progress.xml @@ -1,10 +1,8 @@  <?xml version="1.0" ?>  <panel name="login_progress_panel"> -	<layout_panel name="panel_icons"/>  	<layout_stack name="vertical_centering"/>  	<layout_panel name="panel4"/>  	<layout_panel name="center"/>  	<layout_stack name="horizontal_centering"> -		<text name="logos_lbl">Usos do Second Life</text>  	</layout_stack>  </panel> diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index feebecf4cb..425df0e0f9 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -128,7 +128,7 @@ void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params)      // Launch a coroutine with our login_() method. Run the coroutine until      // its first wait; at that point, return here.      std::string coroname = -        LLCoros::instance().launch("LLLogin::Impl::login_", [=]() { loginCoro(uri, login_params); }); +        LLCoros::instance().launch("LLLogin::Impl::login_", [=, this]() { loginCoro(uri, login_params); });      LL_DEBUGS("LLLogin") << " connected with uri '" << uri << "', login_params " << login_params << LL_ENDL;  } | 
