diff options
42 files changed, 559 insertions, 271 deletions
| diff --git a/autobuild.xml b/autobuild.xml index ea4f761441..14b120e4f5 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -412,11 +412,11 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>f6835c4d7745cd1cadfbce47b40331d08affb532</string> +              <string>e03eb77224290c875ff84f75b7fe3d0e7c162c94</string>                <key>hash_algorithm</key>                <string>sha1</string>                <key>url</key> -              <string>https://github.com/secondlife/3p-dictionaries/releases/download/v1.0.1-dev2.gf887629-f887629/dictionaries-common-None.tar.zst</string> +              <string>https://github.com/secondlife/3p-dictionaries/releases/download/v1-a01bb6c/dictionaries-1.a01bb6c-common-a01bb6c.tar.zst</string>              </map>              <key>name</key>              <string>common</string> @@ -429,7 +429,7 @@          <key>copyright</key>          <string>Copyright 2014 Apache OpenOffice software</string>          <key>version</key> -        <string>None</string> +        <string>1.a01bb6c</string>          <key>name</key>          <string>dictionaries</string>          <key>description</key> @@ -720,11 +720,11 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>6604c1cca515d287e697997a8d5593d1cae172a9</string> +              <string>066625e7aa7f697a4b6cd461aad960c57181011f</string>                <key>hash_algorithm</key>                <string>sha1</string>                <key>url</key> -              <string>https://github.com/secondlife/3p-glh_linear/releases/download/v1.0.1-dev2.g3253ed7-3253ed7/glh_linear-common-None.tar.zst</string> +              <string>https://github.com/secondlife/3p-glh_linear/releases/download/v1.0.1-dev4-984c397/glh_linear-1.0.1-dev4-common-984c397.tar.zst</string>              </map>              <key>name</key>              <string>common</string> @@ -737,7 +737,7 @@          <key>copyright</key>          <string>Copyright (c) 2000 Cass Everitt</string>          <key>version</key> -        <string>None</string> +        <string>1.0.1-dev4</string>          <key>name</key>          <string>glh_linear</string>          <key>description</key> @@ -852,11 +852,11 @@                <key>creds</key>                <string>github</string>                <key>hash</key> -              <string>a193ff65d6db48626d65d96c6124c6efca85e8ec</string> +              <string>ae2c2a215b1bc2e3f37a67e301926dc405902d1a</string>                <key>hash_algorithm</key>                <string>sha1</string>                <key>url</key> -              <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/108912596</string> +              <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/136778143</string>              </map>              <key>name</key>              <string>darwin64</string> @@ -880,11 +880,11 @@                <key>creds</key>                <string>github</string>                <key>hash</key> -              <string>ebfb82b6143874e7938b9d1e8a70d0a2e28aa818</string> +              <string>0393dd75c58f7046bed47e62a8884a78cb02a5c3</string>                <key>hash_algorithm</key>                <string>sha1</string>                <key>url</key> -              <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/108912599</string> +              <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/136778145</string>              </map>              <key>name</key>              <string>windows64</string> @@ -1030,11 +1030,11 @@                <key>creds</key>                <string>github</string>                <key>hash</key> -              <string>bcc7e2c34896fc9cbc41828dee8a4ddf54f10453</string> +              <string>ad72fa1d103df777906f0d98f3e882b9916aeada</string>                <key>hash_algorithm</key>                <string>sha1</string>                <key>url</key> -              <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/108298968</string> +              <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774118</string>              </map>              <key>name</key>              <string>darwin64</string> @@ -1046,11 +1046,11 @@                <key>creds</key>                <string>github</string>                <key>hash</key> -              <string>9de772df2ed12e9c742df6c90670c7cbbb9c93a6</string> +              <string>e46e4ac93a237b5c4a14183766f76ba5d58935a2</string>                <key>hash_algorithm</key>                <string>sha1</string>                <key>url</key> -              <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/108298969</string> +              <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774125</string>              </map>              <key>name</key>              <string>linux64</string> @@ -1062,15 +1062,31 @@                <key>creds</key>                <string>github</string>                <key>hash</key> -              <string>92533ff0f8c1881ad85e75800f9072c413ccf7b7</string> +              <string>bb37557f78c72b26580a521f8b8dabfa1b34e6e6</string>                <key>hash_algorithm</key>                <string>sha1</string>                <key>url</key> -              <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/108298970</string> +              <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774126</string>              </map>              <key>name</key>              <string>windows64</string>            </map> +          <key>linux</key> +          <map> +            <key>archive</key> +            <map> +              <key>creds</key> +              <string>github</string> +              <key>hash</key> +              <string>711b82f9f588d3a125af7dcd8c81f93d9c343a7d</string> +              <key>hash_algorithm</key> +              <string>sha1</string> +              <key>url</key> +              <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774121</string> +            </map> +            <key>name</key> +            <string>linux</string> +          </map>          </map>          <key>license</key>          <string>Kakadu</string> @@ -1079,7 +1095,7 @@          <key>copyright</key>          <string>Kakadu software</string>          <key>version</key> -        <string>7.10.4.539108</string> +        <string>7.10.4.4b9ec5f</string>          <key>name</key>          <string>kdu</string>          <key>description</key> @@ -1378,11 +1394,11 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>e50ea94bbaa4ff41bf53b84b7192df1a694c5337</string> +              <string>a9503e1b4e1d9790cf29d18a3d9ab39e6a515679</string>                <key>hash_algorithm</key>                <string>sha1</string>                <key>url</key> -              <string>https://github.com/secondlife/llca/releases/download/v202310121525.0-d22bd98/llca-202310121530.0-common-d22bd98.tar.zst</string> +              <string>https://github.com/secondlife/llca/releases/download/v202402012004.0-0f5d9c3/llca-202402012004.0-common-0f5d9c3.tar.zst</string>              </map>              <key>name</key>              <string>common</string> @@ -1658,6 +1674,18 @@        </map>        <key>mikktspace</key>        <map> +        <key>canonical_repo</key> +        <string>https://bitbucket.org/lindenlab/3p-mikktspace</string> +        <key>copyright</key> +        <string>Copyright (C) 2011 by Morten S. Mikkelsen, Copyright (C) 2022 Blender Authors</string> +        <key>description</key> +        <string>Mikktspace Tangent Generator</string> +        <key>license</key> +        <string>Apache 2.0</string> +        <key>license_file</key> +        <string>mikktspace.txt</string> +        <key>name</key> +        <string>mikktspace</string>          <key>platforms</key>          <map>            <key>darwin64</key> @@ -1703,20 +1731,8 @@              <string>windows64</string>            </map>          </map> -        <key>license</key> -        <string>Apache 2.0</string> -        <key>license_file</key> -        <string>mikktspace.txt</string> -        <key>copyright</key> -        <string>Copyright (C) 2011 by Morten S. Mikkelsen, Copyright (C) 2022 Blender Authors</string>          <key>version</key>          <string>1</string> -        <key>name</key> -        <string>mikktspace</string> -        <key>canonical_repo</key> -        <string>https://bitbucket.org/lindenlab/3p-mikktspace</string> -        <key>description</key> -        <string>Mikktspace Tangent Generator</string>        </map>        <key>minizip-ng</key>        <map> @@ -2365,9 +2381,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>              <key>archive</key>              <map>                <key>hash</key> -              <string>4dad1c0948141e1667c01a3ee755e4dc</string> +              <string>2c47ae2d0c38c86b8c2db8d9317f0ab15edfc74f</string> +              <key>hash_algorithm</key> +              <string>sha1</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105849/926137/tinygltf-v2.5.0-common-575729.tar.bz2</string> +              <string>https://github.com/secondlife/3p-tinygltf/releases/download/v2.5.0-1ae57fd/tinygltf-v2.5.0-common-1ae57fd.tar.zst</string>              </map>              <key>name</key>              <string>common</string> @@ -2645,8 +2663,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>          <string>LICENSE</string>          <key>copyright</key>          <string>Copyright (c) 2000-2012, Linden Research, Inc.</string> -        <key>version</key> -        <string>3.0-f14b5ec</string>          <key>name</key>          <string>viewer-manager</string>          <key>description</key> @@ -2655,6 +2671,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>          <string>https://bitbucket.org/lindenlab/vmp-standalone</string>          <key>source_type</key>          <string>hg</string> +        <key>version</key> +        <string>3.0-f14b5ec</string>        </map>        <key>vlc-bin</key>        <map> @@ -2704,51 +2722,29 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>        <map>          <key>platforms</key>          <map> -          <key>darwin64</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>8cff2060843db3db788511ee34a8e8cc</string> -              <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101316/891509/vulkan_gltf-1-darwin64-572743.tar.bz2</string> -            </map> -            <key>name</key> -            <string>darwin64</string> -          </map> -          <key>windows</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>58eea384be49ba756ce9c5e66669540b</string> -              <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101318/891520/vulkan_gltf-1-windows-572743.tar.bz2</string> -            </map> -            <key>name</key> -            <string>windows</string> -          </map> -          <key>windows64</key> +          <key>common</key>            <map>              <key>archive</key>              <map>                <key>hash</key> -              <string>79b6a11622c2f83cfc2b7cd1fafb867b</string> +              <string>8e365eff8dcace48d91e2530f8b13e420849aefc</string> +              <key>hash_algorithm</key> +              <string>sha1</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101319/891521/vulkan_gltf-1-windows64-572743.tar.bz2</string> +              <string>https://github.com/secondlife/3p-vulkan-gltf-pbr/releases/download/v1.0.0-d7c372f/vulkan_gltf-1.0.0-common-d7c372f.tar.zst</string>              </map>              <key>name</key> -            <string>windows64</string> +            <string>common</string>            </map>          </map>          <key>license</key>          <string>Copyright (c) 2018 Sascha Willems</string>          <key>license_file</key> -        <string>LICENSES/vulkan_gltf.txt</string> +        <string>vulkan_gltf.txt</string>          <key>copyright</key>          <string>Copyright (c) 2018 Sascha Willems</string>          <key>version</key> -        <string>1</string> +        <string>1.0.0</string>          <key>name</key>          <string>vulkan_gltf</string>          <key>canonical_repo</key> @@ -2831,54 +2827,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>              <key>archive</key>              <map>                <key>hash</key> -              <string>e4f77ba0a9b8ec3cc3fabc51c4da81d2</string> -              <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110070/956941/xxhash-0.8.1.578006-windows-578006.tar.bz2</string> -            </map> -            <key>name</key> -            <string>common</string> -          </map> -          <key>darwin64</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>fdcc803a76a3359bb426db7dac161406676d51e7</string> +              <string>1a73c476b371b62066d1c3eced249660e9467e53</string>                <key>hash_algorithm</key>                <string>sha1</string>                <key>url</key> -              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-darwin64-7501c90.tar.zst</string> +              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-69ff69a/xxhash-0.8.1-69ff69a-common-69ff69a.tar.zst</string>              </map>              <key>name</key> -            <string>darwin64</string> -          </map> -          <key>linux64</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>7acb3f94a549fbb9bd7bc16604e34f33c5365a9b</string> -              <key>hash_algorithm</key> -              <string>sha1</string> -              <key>url</key> -              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-linux64-7501c90.tar.zst</string> -            </map> -            <key>name</key> -            <string>linux64</string> -          </map> -          <key>windows64</key> -          <map> -            <key>archive</key> -            <map> -              <key>hash</key> -              <string>4522d075ea4703ef4b527c3039864ef735ea7953</string> -              <key>hash_algorithm</key> -              <string>sha1</string> -              <key>url</key> -              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-windows64-7501c90.tar.zst</string> -            </map> -            <key>name</key> -            <string>windows64</string> +            <string>common</string>            </map>          </map>          <key>license</key> @@ -2888,7 +2844,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>          <key>copyright</key>          <string>Copyright (c) 2012-2021 Yann Collet</string>          <key>version</key> -        <string>0.8.1.7501c90</string> +        <string>0.8.1-69ff69a</string>          <key>name</key>          <string>xxhash</string>          <key>description</key> diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 07deaa56b0..5a1fb72eca 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -32,6 +32,10 @@ add_compile_definitions( ADDRESS_SIZE=${ADDRESS_SIZE})  # -- which we do. Without one or the other, we get a ton of Boost warnings.  add_compile_definitions(BOOST_BIND_GLOBAL_PLACEHOLDERS) +# Force enable SSE2 instructions in GLM per the manual +# https://github.com/g-truc/glm/blob/master/manual.md#section2_10 +add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_FORCE_SSE2=1) +  # Configure crash reporting  set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds")  set(NON_RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in developer builds") diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index b85bd2573b..6da764f94c 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -90,7 +90,7 @@ bool LLApp::sDisableCrashlogger = false;  // Local flag for whether or not to do logging in signal handlers.  //static -bool LLApp::sLogInSignal = false; +bool LLApp::sLogInSignal = true;  // static  // Keeps track of application status @@ -373,6 +373,9 @@ static std::map<LLApp::EAppStatus, const char*> statusDesc  // static  void LLApp::setStatus(EAppStatus status)  { +    auto status_it = statusDesc.find(status); +    std::string status_text = status_it != statusDesc.end() ? std::string(status_it->second) : std::to_string(status); +    LL_INFOS() << "status: " << status_text << LL_ENDL;      // notify everyone waiting on sStatus any time its value changes      sStatus.set_all(status); @@ -381,18 +384,7 @@ void LLApp::setStatus(EAppStatus status)      if (! LLEventPumps::wasDeleted())      {          // notify interested parties of status change -        LLSD statsd; -        auto found = statusDesc.find(status); -        if (found != statusDesc.end()) -        { -            statsd = found->second; -        } -        else -        { -            // unknown status? at least report value -            statsd = LLSD::Integer(status); -        } -        LLEventPumps::instance().obtain("LLApp").post(llsd::map("status", statsd)); +        LLEventPumps::instance().obtain("LLApp").post(llsd::map("status", status_text));      }  } @@ -487,6 +479,33 @@ int LLApp::getPid()  #endif  } +// static +void LLApp::notifyOutOfDiskSpace() +{ +    static const U32Seconds min_interval = U32Seconds(60); +    static U32Seconds min_time_to_send = U32Seconds(0); +    U32Seconds now = LLTimer::getTotalTime(); +    if (now < min_time_to_send) +        return; + +    min_time_to_send = now + min_interval; + +    if (LLApp* app = instance()) +    { +        app->sendOutOfDiskSpaceNotification(); +    } +    else +    { +        LL_WARNS() << "No app instance" << LL_ENDL; +    } +} + +// virtual +void LLApp::sendOutOfDiskSpaceNotification() +{ +    LL_WARNS() << "Should never be called" << LL_ENDL; // Should be overridden +} +  #ifndef LL_WINDOWS  void setup_signals()  { @@ -654,6 +673,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)              {                  LL_WARNS() << "Signal handler - Handling fatal signal!" << LL_ENDL;              } +              if (LLApp::isError())              {                  // Received second fatal signal while handling first, just die right now @@ -691,11 +711,11 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)              clear_signals();              raise(signum);              return; -        } else { -            if (LLApp::sLogInSignal) -            { -                LL_INFOS() << "Signal handler - Unhandled signal " << signum << ", ignoring!" << LL_ENDL; -            } +        } + +        if (LLApp::sLogInSignal) +        { +            LL_INFOS() << "Signal handler - Unhandled signal " << signum << ", ignoring!" << LL_ENDL;          }      }  } diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index ad8912ca88..d90ecdf661 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -202,6 +202,8 @@ public:      static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)      static int getPid(); +    static void notifyOutOfDiskSpace(); +      //      // Sleep for specified time while still running      // @@ -301,6 +303,8 @@ protected:        */      void stepFrame(); +    virtual void sendOutOfDiskSpaceNotification(); +  private:      // Contains the filename of the minidump file after a crash.      char mMinidumpPath[MAX_MINDUMP_PATH_LENGTH]; diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index b085f8f5dc..01763c49aa 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -28,6 +28,7 @@  #include "linden_common.h"  #include "llapr.h" +#include "llapp.h"  #include "llmutex.h"  #include "apr_dso.h" @@ -606,7 +607,11 @@ S32 LLAPRFile::writeEx(const std::string& filename, const void *buf, S32 offset,          apr_status_t s = apr_file_write(file_handle, buf, &bytes_written);          if (s != APR_SUCCESS)          { -            LL_WARNS("APR") << " Attempting to write filename: " << filename << LL_ENDL; +            LL_WARNS("APR") << "Attempting to write filename: " << filename << LL_ENDL; +            if (APR_STATUS_IS_ENOSPC(s)) +            { +                LLApp::notifyOutOfDiskSpace(); +            }              ll_apr_warn_status(s);              bytes_written = 0;          } diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 42eecbb97c..8b966b8ea3 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -32,37 +32,37 @@  #include "llpointer.h"  #include "lltrace.h" -const S32 MIN_IMAGE_MIP =  2; // 4x4, only used for expand/contract power of 2 -const S32 MAX_IMAGE_MIP = 12; // 4096x4096 +constexpr S32 MIN_IMAGE_MIP =  2; // 4x4, only used for expand/contract power of 2 +constexpr S32 MAX_IMAGE_MIP = 12; // 4096x4096  // *TODO : Use MAX_IMAGE_MIP as max discard level and modify j2c management so that the number  // of levels is read from the header's file, not inferred from its size. -const S32 MAX_DISCARD_LEVEL = 5; +constexpr S32 MAX_DISCARD_LEVEL = 5;  // JPEG2000 size constraints  // Those are declared here as they are germane to other image constraints used in the viewer  // and declared right here. Some come from the JPEG2000 spec, some conventions specific to SL. -const S32 MAX_DECOMPOSITION_LEVELS = 32;    // Number of decomposition levels cannot exceed 32 according to jpeg2000 spec -const S32 MIN_DECOMPOSITION_LEVELS = 5;     // the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is) -const S32 MAX_PRECINCT_SIZE = 4096;         // No reason to be bigger than MAX_IMAGE_SIZE -const S32 MIN_PRECINCT_SIZE = 4;            // Can't be smaller than MIN_BLOCK_SIZE -const S32 MAX_BLOCK_SIZE = 64;              // Max total block size is 4096, hence 64x64 when using square blocks -const S32 MIN_BLOCK_SIZE = 4;               // Min block dim is 4 according to jpeg2000 spec -const S32 MIN_LAYER_SIZE = 2000;            // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!! -const S32 MAX_NB_LAYERS = 64;               // Max number of layers we'll entertain in SL (practical limit) - -const S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP); // 4, only used for expand/contract power of 2 -const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 4096 -const S32 MIN_IMAGE_AREA = MIN_IMAGE_SIZE * MIN_IMAGE_SIZE; -const S32 MAX_IMAGE_AREA = MAX_IMAGE_SIZE * MAX_IMAGE_SIZE; -const S32 MAX_IMAGE_COMPONENTS = 8; -const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; //4096 * 4096 * 8 = 128 MB +constexpr S32 MAX_DECOMPOSITION_LEVELS = 32;    // Number of decomposition levels cannot exceed 32 according to jpeg2000 spec +constexpr S32 MIN_DECOMPOSITION_LEVELS = 5;     // the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is) +constexpr S32 MAX_PRECINCT_SIZE = 4096;         // No reason to be bigger than MAX_IMAGE_SIZE +constexpr S32 MIN_PRECINCT_SIZE = 4;            // Can't be smaller than MIN_BLOCK_SIZE +constexpr S32 MAX_BLOCK_SIZE = 64;              // Max total block size is 4096, hence 64x64 when using square blocks +constexpr S32 MIN_BLOCK_SIZE = 4;               // Min block dim is 4 according to jpeg2000 spec +constexpr S32 MIN_LAYER_SIZE = 2000;            // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!! +constexpr S32 MAX_NB_LAYERS = 64;               // Max number of layers we'll entertain in SL (practical limit) + +constexpr S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP); // 4, only used for expand/contract power of 2 +constexpr S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 4096 +constexpr S32 MIN_IMAGE_AREA = MIN_IMAGE_SIZE * MIN_IMAGE_SIZE; +constexpr S32 MAX_IMAGE_AREA = MAX_IMAGE_SIZE * MAX_IMAGE_SIZE; +constexpr S32 MAX_IMAGE_COMPONENTS = 8; +constexpr S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; //4096 * 4096 * 8 = 128 MB  // Note!  These CANNOT be changed without modifying simulator code  // *TODO: change both to 1024 when SIM texture fetching is deprecated -const S32 FIRST_PACKET_SIZE = 600; -const S32 MAX_IMG_PACKET_SIZE = 1000; -const S32 HTTP_PACKET_SIZE = 1496; +constexpr S32 FIRST_PACKET_SIZE = 600; +constexpr S32 MAX_IMG_PACKET_SIZE = 1000; +constexpr S32 HTTP_PACKET_SIZE = 1496;  // Base classes for images.  // There are two major parts for the image: diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 0058b91b0f..29449a5d2e 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -275,30 +275,23 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r      // For details about the equation used here, see https://wiki.lindenlab.com/wiki/THX1138_KDU_Improvements#Byte_Range_Study      // Estimate the number of layers. This is consistent with what's done for j2c encoding in LLImageJ2CKDU::encodeImpl(). +    constexpr S32 precision = 8; // assumed bitrate per component channel, might change in future for HDR support      S32 nb_layers = 1; -    S32 surface = w*h; +    const S32 surface = w*h;      S32 s = 64*64; +    S32 totalbytes = (S32)(s * comp * precision * rate); // first level computed before loop      while (surface > s)      { +        if (nb_layers <= (5 - discard_level)) +            totalbytes += (S32)(s * comp * precision * rate);          nb_layers++;          s *= 4;      } -    F32 layer_factor =  3.0f * (7 - llclamp(nb_layers,1,6)); - -    // Compute w/pow(2,discard_level) and h/pow(2,discard_level) -    w >>= discard_level; -    h >>= discard_level; -    w = llmax(w, 1); -    h = llmax(h, 1); - -    // Temporary: compute both new and old range and pick one according to the settings TextureNewByteRange -    // *TODO: Take the old code out once we have enough tests done -    S32 bytes; -    S32 new_bytes = (S32) (sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/layer_factor); -    S32 old_bytes = (S32)((F32)(w*h*comp)*rate); -    bytes = (LLImage::useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes); -    bytes = llmax(bytes, calcHeaderSizeJ2C()); -    return bytes; + +    totalbytes /= 8; // to bytes +    totalbytes += calcHeaderSizeJ2C();  // header + +    return totalbytes;  }  S32 LLImageJ2C::calcHeaderSize() diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index b2bd3186a0..f4bcb97a5d 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -431,23 +431,20 @@ public:          opj_set_default_encoder_parameters(¶meters);          parameters.cod_format = OPJ_CODEC_J2K;          parameters.cp_disto_alloc = 1; -        parameters.max_cs_size = (1 << 15);          if (reversible)          { +            parameters.max_cs_size = 0; // do not limit size for reversible compression +            parameters.irreversible = 0; // should be the default, but, just in case              parameters.tcp_numlayers = 1; -            parameters.tcp_rates[0] = 1.0f; +            /* documentation seems to be wrong, should be 0.0f for lossless, not 1.0f +               see https://github.com/uclouvain/openjpeg/blob/39e8c50a2f9bdcf36810ee3d41bcbf1cc78968ae/src/lib/openjp2/j2k.c#L7755 +            */ +            parameters.tcp_rates[0] = 0.0f;          }          else          { -            parameters.tcp_numlayers = 5; -            parameters.tcp_rates[0] = 1920.0f; -            parameters.tcp_rates[1] = 960.0f; -            parameters.tcp_rates[2] = 480.0f; -            parameters.tcp_rates[3] = 120.0f; -            parameters.tcp_rates[4] = 30.0f;              parameters.irreversible = 1; -            parameters.tcp_mct = 1;          }          if (comment_text) @@ -501,6 +498,50 @@ public:          parameters.prog_order = OPJ_RLCP;          parameters.cp_disto_alloc = 1; +        // if not lossless compression, computes tcp_numlayers and max_cs_size depending on the image dimensions +        if( parameters.irreversible ) { + +            // computes a number of layers +            U32 surface = rawImageIn.getWidth() * rawImageIn.getHeight(); +            U32 nb_layers = 1; +            U32 s = 64*64; +            while (surface > s) +            { +                nb_layers++; +                s *= 4; +            } +            nb_layers = llclamp(nb_layers, 1, 6); + +            parameters.tcp_numlayers = nb_layers; +            parameters.tcp_rates[nb_layers - 1] = (U32)(1.f / DEFAULT_COMPRESSION_RATE); // 1:8 by default + +            // for each subsequent layer, computes its rate and adds surface * numcomps * 1/rate to the max_cs_size +            U32 max_cs_size = (U32)(surface * image->numcomps * DEFAULT_COMPRESSION_RATE); +            U32 multiplier; +            for (int i = nb_layers - 2; i >= 0; i--) +            { +                if( i == nb_layers - 2 ) +                { +                    multiplier = 15; +                } +                else if( i == nb_layers - 3 ) +                { +                    multiplier = 4; +                } +                else +                { +                    multiplier = 2; +                } +                parameters.tcp_rates[i] = parameters.tcp_rates[i + 1] * multiplier; +                max_cs_size += (U32)(surface * image->numcomps * (1 / parameters.tcp_rates[i])); +            } + +            //ensure that we have at least a minimal size +            max_cs_size = llmax(max_cs_size, (U32)FIRST_PACKET_SIZE); + +            parameters.max_cs_size = max_cs_size; +        } +          if (!opj_setup_encoder(encoder, ¶meters, image))          {              return false; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index d0eb9a1873..12d5c41de1 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1205,24 +1205,64 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)              {                  S32 delta_x = 0;                  S32 delta_y = 0; + +                // take translation of dependee floater into account +                delta_x += new_rect.mLeft - old_rect.mLeft; +                delta_y += new_rect.mBottom - old_rect.mBottom; +                  // check to see if it snapped to right or top, and move if dependee floater is resizing                  LLRect dependent_rect = floaterp->getRect(); -                if (dependent_rect.mLeft - getRect().mLeft >= old_rect.getWidth() || // dependent on my right? -                    dependent_rect.mRight == getRect().mLeft + old_rect.getWidth()) // dependent aligned with my right +                if ((dependent_rect.mLeft - getRect().mLeft >= old_rect.getWidth() || // dependent on my right? +                     dependent_rect.mRight == getRect().mLeft + old_rect.getWidth()) // dependent aligned with my right +                    && dependent_rect.mBottom <= old_rect.mTop + 1)                  {                      // was snapped directly onto right side or aligned with it                      delta_x += new_rect.getWidth() - old_rect.getWidth(); + +                    // make sure dependent still touches floater and din't go too high, +                    // it can go over edge, but should't detach completely +                    if (delta_y > 0 +                        && dependent_rect.mBottom + delta_y > new_rect.mTop) +                    { +                        delta_y = llmax(new_rect.mTop - dependent_rect.mBottom, 0); +                    } +                } +                else if (dependent_rect.mRight == old_rect.mLeft) +                { +                    // make sure dependent still touches floater and don't go too high +                    if (delta_y > 0 +                        && dependent_rect.mBottom <= old_rect.mTop +                        && dependent_rect.mBottom + delta_y > new_rect.mTop) +                    { +                        delta_y = llmax(new_rect.mTop - dependent_rect.mBottom, 0); +                    }                  } -                if (dependent_rect.mBottom - getRect().mBottom >= old_rect.getHeight() || -                    dependent_rect.mTop == getRect().mBottom + old_rect.getHeight()) + +                if ((dependent_rect.mBottom - getRect().mBottom >= old_rect.getHeight() || +                     dependent_rect.mTop == getRect().mBottom + old_rect.getHeight()) +                    && dependent_rect.mLeft <= old_rect.mRight + 1)                  {                      // was snapped directly onto top side or aligned with it                      delta_y += new_rect.getHeight() - old_rect.getHeight(); -                } -                // take translation of dependee floater into account as well -                delta_x += new_rect.mLeft - old_rect.mLeft; -                delta_y += new_rect.mBottom - old_rect.mBottom; +                    // make sure dependent still touches floater +                    // and din't go too far to the right +                    if (delta_x > 0 +                        && dependent_rect.mLeft + delta_x > new_rect.mRight) +                    { +                        delta_x = llmax(new_rect.mRight - dependent_rect.mLeft, 0); +                    } +                } +                else if (dependent_rect.mTop == old_rect.mBottom) +                { +                    // make sure dependent still touches floater and don't go too far to the right +                    if (delta_x > 0 +                        && dependent_rect.mLeft <= old_rect.mRight +                        && dependent_rect.mLeft + delta_x > new_rect.mRight) +                    { +                        delta_x = llmax(new_rect.mRight - dependent_rect.mLeft, 0); +                    } +                }                  dependent_rect.translate(delta_x, delta_y);                  floaterp->setShape(dependent_rect, by_user); diff --git a/indra/llui/llscrollingpanellist.cpp b/indra/llui/llscrollingpanellist.cpp index b158d7b1b7..7696a27320 100644 --- a/indra/llui/llscrollingpanellist.cpp +++ b/indra/llui/llscrollingpanellist.cpp @@ -84,42 +84,35 @@ void LLScrollingPanelList::removePanel(LLScrollingPanel* panel)      if (!mPanelList.empty())      { -        for (iter = mPanelList.begin(); iter != mPanelList.end(); ++iter, ++index) -        { -            if (*iter == panel) -            { -                break; -            } -        } +        LLScrollingPanelList::panel_list_t::const_iterator iter = +            std::find(mPanelList.begin(), mPanelList.end(), panel);          if (iter != mPanelList.end())          { -            removePanel(index); +            removeChild(panel); +            mPanelList.erase(iter); +            rearrange();          }      }  } -void LLScrollingPanelList::removePanel( U32 panel_index ) +void LLScrollingPanelList::removePanel(U32 panel_index)  { -    if ( mPanelList.empty() || panel_index >= mPanelList.size() ) +    if (panel_index >= mPanelList.size())      {          LL_WARNS() << "Panel index " << panel_index << " is out of range!" << LL_ENDL;          return;      } -    else -    { -        removeChild( mPanelList.at(panel_index) ); -        mPanelList.erase( mPanelList.begin() + panel_index ); -    } +    LLScrollingPanelList::panel_list_t::const_iterator iter = mPanelList.begin() + panel_index; +    removeChild(*iter); +    mPanelList.erase(iter);      rearrange();  }  void LLScrollingPanelList::updatePanels(bool allow_modify)  { -    for (std::deque<LLScrollingPanel*>::iterator iter = mPanelList.begin(); -         iter != mPanelList.end(); ++iter) +    for (LLScrollingPanel* childp : mPanelList)      { -        LLScrollingPanel *childp = *iter;          childp->updatePanel(allow_modify);      }  } @@ -131,10 +124,8 @@ void LLScrollingPanelList::rearrange()      if (!mPanelList.empty())      {          new_width = new_height = mPadding * 2; -        for (std::deque<LLScrollingPanel*>::iterator iter = mPanelList.begin(); -            iter != mPanelList.end(); ++iter) +        for (LLScrollingPanel* childp : mPanelList)          { -            LLScrollingPanel* childp = *iter;              const LLRect& rect = childp->getRect();              if (mIsHorizontal)              { @@ -180,10 +171,8 @@ void LLScrollingPanelList::rearrange()      // Reposition each of the child views      S32 pos = mIsHorizontal ? mPadding : rc.getHeight() - mPadding; -    for (std::deque<LLScrollingPanel*>::iterator iter = mPanelList.begin(); -        iter != mPanelList.end(); ++iter) +    for (LLScrollingPanel* childp : mPanelList)      { -        LLScrollingPanel* childp = *iter;          const LLRect& rect = childp->getRect();          if (mIsHorizontal)          { @@ -211,10 +200,11 @@ void LLScrollingPanelList::updatePanelVisiblilty()          getParent()->getRect().getHeight() - mPadding,          &parent_screen_rect.mRight, &parent_screen_rect.mTop ); -    for (std::deque<LLScrollingPanel*>::iterator iter = mPanelList.begin(); -         iter != mPanelList.end(); ++iter) +    for (LLScrollingPanel* childp : mPanelList)      { -        LLScrollingPanel *childp = *iter; +        if (childp->isDead()) +            continue; +          const LLRect& local_rect = childp->getRect();          LLRect screen_rect;          childp->localPointToScreen( diff --git a/indra/llwebrtc/llwebrtc.h b/indra/llwebrtc/llwebrtc.h index 54eefc8554..62b40636d2 100644 --- a/indra/llwebrtc/llwebrtc.h +++ b/indra/llwebrtc/llwebrtc.h @@ -230,7 +230,7 @@ class LLWebRTCSignalingObserver  // allows for management of this peer connection.  class LLWebRTCPeerConnectionInterface  { -  public: +public:      struct InitOptions      { diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 70316ec36a..94762db5c5 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -187,6 +187,8 @@ DWORD   LLWindowWin32::sWinIMEConversionMode = IME_CMODE_NATIVE;  DWORD   LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC;  LLCoordWindow LLWindowWin32::sWinIMEWindowPosition(-1,-1); +static HWND sWindowHandleForMessageBox = NULL; +  // The following class LLWinImm delegates Windows IMM APIs.  // It was originally introduced to support US Windows XP, on which we needed  // to dynamically load IMM32.DLL and use GetProcAddress to resolve its entry @@ -848,6 +850,11 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,  LLWindowWin32::~LLWindowWin32()  { +    if (sWindowHandleForMessageBox == mWindowHandle) +    { +        sWindowHandleForMessageBox = NULL; +    } +      delete mDragDrop;      delete [] mWindowTitle; @@ -970,6 +977,11 @@ void LLWindowWin32::close()      LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; +    if (sWindowHandleForMessageBox == mWindowHandle) +    { +        sWindowHandleForMessageBox = NULL; +    } +      mhDC = NULL;      mWindowHandle = NULL; @@ -1702,10 +1714,15 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw      auto oldWindowHandle = mWindowHandle;      auto oldDCHandle = mhDC; +    if (sWindowHandleForMessageBox == mWindowHandle) +    { +        sWindowHandleForMessageBox = NULL; +    } +      // zero out mWindowHandle and mhDC before destroying window so window      // thread falls back to peekmessage -    mWindowHandle = 0; -    mhDC = 0; +    mWindowHandle = NULL; +    mhDC = NULL;      std::promise<std::pair<HWND, HDC>> promise;      // What follows must be done on the window thread. @@ -1802,6 +1819,8 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw      auto pair = future.get();      mWindowHandle = pair.first;      mhDC = pair.second; + +    sWindowHandleForMessageBox = mWindowHandle;  }  void* LLWindowWin32::createSharedContext() @@ -3684,7 +3703,14 @@ S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 t          break;      } -    int retval_win = MessageBoxW(NULL, // HWND +    // AG: Of course, the using of the static global variable sWindowHandleForMessageBox +    // instead of using the field mWindowHandle of the class LLWindowWin32 looks strange. +    // But in fact, the function OSMessageBoxWin32() doesn't have access to gViewerWindow +    // because the former is implemented in the library llwindow which is abstract enough. +    // +    // "This is why I'm doing it this way, instead of what you would think would be more obvious..." +    // (C) Nat Goodspeed +    int retval_win = MessageBoxW(sWindowHandleForMessageBox, // HWND                                   ll_convert_string_to_wide(text).c_str(),                                   ll_convert_string_to_wide(caption).c_str(),                                   uType); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4190719504..235d294849 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -13122,7 +13122,7 @@        <key>Type</key>        <string>Boolean</string>        <key>Value</key> -      <integer>0</integer> +      <integer>1</integer>      </map>      <key>AutoDisengageMic</key>      <map> diff --git a/indra/newview/gltf/primitive.cpp b/indra/newview/gltf/primitive.cpp index e1579374d4..81caff8ab2 100644 --- a/indra/newview/gltf/primitive.cpp +++ b/indra/newview/gltf/primitive.cpp @@ -109,7 +109,7 @@ struct MikktMesh          for (U32 tri_idx = 0; tri_idx < U32(triangle_count); ++tri_idx)          { -            U32 idx[3]; +            U32 idx[3] = {0, 0, 0};              if (prim->mMode == Primitive::Mode::TRIANGLES)              { diff --git a/indra/newview/llagentbenefits.cpp b/indra/newview/llagentbenefits.cpp index e9f00f6556..f651b42010 100644 --- a/indra/newview/llagentbenefits.cpp +++ b/indra/newview/llagentbenefits.cpp @@ -195,6 +195,19 @@ S32 LLAgentBenefits::getTextureUploadCost(const LLImageBase* tex) const      return getTextureUploadCost();  } +S32 LLAgentBenefits::getTextureUploadCost(S32 w, S32 h) const +{ +    if (w > 0 && h > 0) +    { +        S32 area = w * h; +        if (area >= MIN_2K_TEXTURE_AREA) +        { +            return get2KTextureUploadCost(area); +        } +    } +    return getTextureUploadCost(); +} +  S32 LLAgentBenefits::get2KTextureUploadCost(S32 area) const  {      if (m_2k_texture_upload_cost.empty()) diff --git a/indra/newview/llagentbenefits.h b/indra/newview/llagentbenefits.h index ff23241aa9..c0aa6edd90 100644 --- a/indra/newview/llagentbenefits.h +++ b/indra/newview/llagentbenefits.h @@ -54,6 +54,7 @@ public:      S32 getTextureUploadCost() const;      S32 getTextureUploadCost(const LLViewerTexture* tex) const;      S32 getTextureUploadCost(const LLImageBase* tex) const; +    S32 getTextureUploadCost(S32 w, S32 h) const;      S32 get2KTextureUploadCost(S32 area) const;      bool findUploadCost(LLAssetType::EType& asset_type, S32& cost) const; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a10ef451e1..b380b09129 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3067,6 +3067,13 @@ bool LLAppViewer::meetsRequirementsForMaximizedStart()      return maximizedOk;  } +// virtual +void LLAppViewer::sendOutOfDiskSpaceNotification() +{ +    LL_WARNS() << "Out of disk space notification requested" << LL_ENDL; +    LLNotificationsUtil::add("OutOfDiskSpace"); +} +  bool LLAppViewer::initWindow()  {      LL_INFOS("AppInit") << "Initializing window..." << LL_ENDL; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 32d3df4f83..417ab0fa00 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -245,6 +245,8 @@ protected:      virtual bool meetsRequirementsForMaximizedStart(); // Used on first login to decide to launch maximized +    virtual void sendOutOfDiskSpaceNotification(); +  private:      bool doFrame(); diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp index 48547852c4..6c5d2570f2 100644 --- a/indra/newview/llfloatersidepanelcontainer.cpp +++ b/indra/newview/llfloatersidepanelcontainer.cpp @@ -28,6 +28,7 @@  #include "llfloaterreg.h"  #include "llfloatersidepanelcontainer.h" +#include "llnotificationsutil.h"  #include "llpaneleditwearable.h"  // newview includes @@ -90,6 +91,46 @@ void LLFloaterSidePanelContainer::closeFloater(bool app_quitting)      }  } +void LLFloaterSidePanelContainer::onClickCloseBtn(bool app_quitting) +{ +    if (!app_quitting) +    { +        LLPanelOutfitEdit* panel_outfit_edit = +            dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::findPanel("appearance", "panel_outfit_edit")); +        if (panel_outfit_edit) +        { +            LLFloater* parent = gFloaterView->getParentFloater(panel_outfit_edit); +            if (parent == this) +            { +                LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance*>(getPanel("appearance")); +                if (panel_appearance) +                { +                    LLPanelEditWearable* edit_wearable_ptr = panel_appearance->getWearable(); +                    if (edit_wearable_ptr && edit_wearable_ptr->getVisible() && edit_wearable_ptr->isDirty()) +                    { +                        LLNotificationsUtil::add("UsavedWearableChanges", LLSD(), LLSD(), [this](const LLSD& notification, const LLSD& response) +                        { +                            onCloseMsgCallback(notification, response); +                        }); +                        return; +                    } +                } +            } +        } +    } + +    closeFloater(); +} + +void LLFloaterSidePanelContainer::onCloseMsgCallback(const LLSD& notification, const LLSD& response) +{ +    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +    if (0 == option) +    { +        closeFloater(); +    } +} +  LLFloater* LLFloaterSidePanelContainer::getTopmostInventoryFloater()  {      LLFloater* topmost_floater = NULL; diff --git a/indra/newview/llfloatersidepanelcontainer.h b/indra/newview/llfloatersidepanelcontainer.h index 19d6c747cb..d7f6c309c4 100644 --- a/indra/newview/llfloatersidepanelcontainer.h +++ b/indra/newview/llfloatersidepanelcontainer.h @@ -49,9 +49,11 @@ public:      LLFloaterSidePanelContainer(const LLSD& key, const Params& params = getDefaultParams());      ~LLFloaterSidePanelContainer(); -    /*virtual*/ void onOpen(const LLSD& key); +    void onOpen(const LLSD& key) override; -    /*virtual*/ void closeFloater(bool app_quitting = false); +    void closeFloater(bool app_quitting = false) override; + +    void onClickCloseBtn(bool app_qutting) override;      void cleanup() { destroy(); } @@ -84,6 +86,9 @@ public:          }          return panel;      } + +protected: +    void onCloseMsgCallback(const LLSD& notification, const LLSD& response);  };  #endif // LL_LLFLOATERSIDEPANELCONTAINER_H diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 75b24a6bbc..e03b11e572 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -46,12 +46,12 @@  ///----------------------------------------------------------------------------  /// Local function declarations, constants, enums, and typedefs  ///---------------------------------------------------------------------------- -LLSnapshotFloaterView* gSnapshotFloaterView = NULL; +LLSnapshotFloaterView* gSnapshotFloaterView = nullptr; -const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f; +constexpr F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f; -const S32 MAX_POSTCARD_DATASIZE = 1572864; // 1.5 megabyte, similar to simulator limit -const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512 +constexpr S32 MAX_POSTCARD_DATASIZE = 1572864; // 1.5 megabyte, similar to simulator limit +constexpr S32 MAX_TEXTURE_SIZE = 2048 ; //max upload texture size 2048 * 2048  static LLDefaultChildRegistry::Register<LLSnapshotFloaterView> r("snapshot_floater_view"); diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp index 735776f7e5..e58e819345 100644 --- a/indra/newview/llfloaterspellchecksettings.cpp +++ b/indra/newview/llfloaterspellchecksettings.cpp @@ -67,7 +67,11 @@ bool LLFloaterSpellCheckerSettings::postBuild(void)      LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLFloaterSpellCheckerSettings::onSpellCheckSettingsChange, this));      getChild<LLUICtrl>("spellcheck_remove_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnRemove, this));      getChild<LLUICtrl>("spellcheck_import_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnImport, this)); -    getChild<LLUICtrl>("spellcheck_main_combo")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::refreshDictionaries, this, false)); +    getChild<LLUICtrl>("spellcheck_main_combo")->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& data) +    { +        mMainSelectionChanged = true; +        refreshDictionaries(false); +    });      getChild<LLUICtrl>("spellcheck_moveleft_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnMove, this, "spellcheck_active_list", "spellcheck_available_list"));      getChild<LLUICtrl>("spellcheck_moveright_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnMove, this, "spellcheck_available_list", "spellcheck_active_list"));      center(); @@ -146,7 +150,7 @@ void LLFloaterSpellCheckerSettings::onBtnRemove()  void LLFloaterSpellCheckerSettings::onSpellCheckSettingsChange()  { -    refreshDictionaries(true); +    refreshDictionaries(!mMainSelectionChanged);  }  void LLFloaterSpellCheckerSettings::refreshDictionaries(bool from_settings) diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h index f05bf68040..ff76ff6ba5 100644 --- a/indra/newview/llfloaterspellchecksettings.h +++ b/indra/newview/llfloaterspellchecksettings.h @@ -45,6 +45,8 @@ protected:      void onBtnRemove();      void onSpellCheckSettingsChange();      void refreshDictionaries(bool from_settings); + +    bool mMainSelectionChanged{ false };  };  class LLFloaterSpellCheckerImport : public LLFloater diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 215f3dd3a7..25438eae5e 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -55,6 +55,8 @@ LLGLTFMaterialList::modify_queue_t LLGLTFMaterialList::sModifyQueue;  LLGLTFMaterialList::apply_queue_t LLGLTFMaterialList::sApplyQueue;  LLSD LLGLTFMaterialList::sUpdates; +const size_t MAX_TASK_UPDATES = 255; +  #ifdef SHOW_ASSERT  // return true if given data is (probably) valid update message for ModifyMaterialParams capability  static bool is_valid_update(const LLSD& data) @@ -362,6 +364,17 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L          LLGLTFMaterial* material = new LLGLTFMaterial(*material_override);          sApplyQueue.push_back({ obj->getID(), side, asset_id, material });      } + +    if (sUpdates.size() >= MAX_TASK_UPDATES) +    { +        LLCoros::instance().launch("modifyMaterialCoro", +            std::bind(&LLGLTFMaterialList::modifyMaterialCoro, +                gAgent.getRegionCapability("ModifyMaterialParams"), +                sUpdates, +                std::shared_ptr<CallbackHolder>(nullptr))); + +        sUpdates = LLSD::emptyArray(); +    }  }  void LLGLTFMaterialList::queueUpdate(const LLSD& data) @@ -374,16 +387,41 @@ void LLGLTFMaterialList::queueUpdate(const LLSD& data)      }      sUpdates[sUpdates.size()] = data; + +    if (sUpdates.size() >= MAX_TASK_UPDATES) +    { +        LLCoros::instance().launch("modifyMaterialCoro", +            std::bind(&LLGLTFMaterialList::modifyMaterialCoro, +                gAgent.getRegionCapability("ModifyMaterialParams"), +                sUpdates, +                std::shared_ptr<CallbackHolder>(nullptr))); + +        sUpdates = LLSD::emptyArray(); +    }  }  void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))  { +    std::shared_ptr<CallbackHolder> callback_holder; +    if (done_callback) +    { +        callback_holder = std::make_shared<CallbackHolder>(done_callback); +    } +    while (!sModifyQueue.empty() || !sApplyQueue.empty()) +    { +        flushUpdatesOnce(callback_holder); +    } +} + +void LLGLTFMaterialList::flushUpdatesOnce(std::shared_ptr<CallbackHolder> callback_holder) +{      LLSD& data = sUpdates; -    auto i = data.size(); +    size_t i = data.size(); -    for (ModifyMaterialData& e : sModifyQueue) +    while (!sModifyQueue.empty() && i < MAX_TASK_UPDATES)      { +        ModifyMaterialData& e = sModifyQueue.front();  #ifdef SHOW_ASSERT          // validate object has a material id          LLViewerObject* obj = gObjectList.findObject(e.object_id); @@ -405,11 +443,12 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))          llassert(is_valid_update(data[i]));          ++i; +        sModifyQueue.pop_front();      } -    sModifyQueue.clear(); -    for (ApplyMaterialAssetData& e : sApplyQueue) +    while (!sApplyQueue.empty() && i < MAX_TASK_UPDATES)      { +        ApplyMaterialAssetData& e = sApplyQueue.front();          data[i]["object_id"] = e.object_id;          data[i]["side"] = e.side;          data[i]["asset_id"] = e.asset_id; @@ -425,8 +464,8 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))          llassert(is_valid_update(data[i]));          ++i; +        sApplyQueue.pop_front();      } -    sApplyQueue.clear();  #if 0 // debug output of data being sent to capability      std::stringstream str; @@ -440,7 +479,7 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))              std::bind(&LLGLTFMaterialList::modifyMaterialCoro,                  gAgent.getRegionCapability("ModifyMaterialParams"),                  sUpdates, -                done_callback)); +                callback_holder));          sUpdates = LLSD::emptyArray();      } @@ -661,7 +700,7 @@ void LLGLTFMaterialList::flushMaterials()  }  // static -void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides, void(*done_callback)(bool) ) +void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides, std::shared_ptr<CallbackHolder> callback_holder)  {      LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);      LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t @@ -691,9 +730,12 @@ void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides,          success = false;      } -    if (done_callback) +    if (callback_holder)      { -        done_callback(success); +        // Set to false even if something went through +        // since at the moment it get used to refresh UI +        // if update failed +        callback_holder->mSuccess &= success;      }  } diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index 982538f106..e79da3592a 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -58,7 +58,9 @@ public:      // NOTE: do not use to revert to asset when applying a new asset id, use queueApply below      static void queueModify(const LLViewerObject* obj, S32 side, const LLGLTFMaterial* mat); -    // Queue an application of a material asset we want to send to the simulator.  Call "flushUpdates" to flush pending updates. +    // Queue an application of a material asset we want to send to the simulator. +    //  Call "flushUpdates" to flush pending updates immediately. +    //  Will be flushed automatically if queue is full.      //  object_id - ID of object to apply material asset to      //  side - TextureEntry index to apply material to, or -1 for all sides      //  asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset @@ -66,7 +68,9 @@ public:      // NOTE: Implicitly clears most override data if present      static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id); -    // Queue an application of a material asset we want to send to the simulator.  Call "flushUpdates" to flush pending updates. +    // Queue an application of a material asset we want to send to the simulator. +    //  Call "flushUpdates" to flush pending updates immediately. +    //  Will be flushed automatically if queue is full.      //  object_id - ID of object to apply material asset to      //  side - TextureEntry index to apply material to, or -1 for all sides      //  asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset @@ -104,7 +108,22 @@ private:      // NOTE: this is NOT for applying overrides from the UI, see queueModifyMaterial above      void queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data); -    static void modifyMaterialCoro(std::string cap_url, LLSD overrides, void(*done_callback)(bool)); + +    class CallbackHolder +    { +    public: +        CallbackHolder(void(*done_callback)(bool)) +            : mCallback(done_callback) +        {} +        ~CallbackHolder() +        { +            if (mCallback) mCallback(mSuccess); +        } +        std::function<void(bool)> mCallback = nullptr; +        bool mSuccess = true; +    }; +    static void flushUpdatesOnce(std::shared_ptr<CallbackHolder> callback_holder); +    static void modifyMaterialCoro(std::string cap_url, LLSD overrides, std::shared_ptr<CallbackHolder> callback_holder);  protected:      static void onAssetLoadComplete( diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 81d738cf42..0f2f0ec942 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1190,6 +1190,7 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags,              || (U32)depth > (max_depth + 1))          {              disabled_items.push_back(std::string("New Folder")); +            disabled_items.push_back(std::string("New Listing Folder"));          }      } @@ -4268,6 +4269,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items          if (LLMarketplaceData::instance().isUpdating(mUUID))          {              disabled_items.push_back(std::string("New Folder")); +            disabled_items.push_back(std::string("New Listing Folder"));              disabled_items.push_back(std::string("Rename"));              disabled_items.push_back(std::string("Cut"));              disabled_items.push_back(std::string("Copy")); @@ -4278,12 +4280,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items      if (getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK)      {          disabled_items.push_back(std::string("New Folder")); +        disabled_items.push_back(std::string("New Listing Folder"));          disabled_items.push_back(std::string("upload_def"));          disabled_items.push_back(std::string("create_new"));      }      if (marketplace_listings_id == mUUID)      {          disabled_items.push_back(std::string("New Folder")); +        disabled_items.push_back(std::string("New Listing Folder"));          disabled_items.push_back(std::string("Rename"));          disabled_items.push_back(std::string("Cut"));          disabled_items.push_back(std::string("Delete")); diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp index 69047a30cd..32c9f6f402 100644 --- a/indra/newview/llpanelsnapshot.cpp +++ b/indra/newview/llpanelsnapshot.cpp @@ -41,7 +41,7 @@  #include "llagentbenefits.h" -constexpr S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512 +constexpr S32 MAX_TEXTURE_SIZE = 2048 ; //max upload texture size 2048 * 2048  S32 power_of_two(S32 sz, S32 upper)  { @@ -61,7 +61,9 @@ LLPanelSnapshot::LLPanelSnapshot()  // virtual  bool LLPanelSnapshot::postBuild()  { -    getChild<LLUICtrl>("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost())); +    S32 w = getTypedPreviewWidth(); +    S32 h = getTypedPreviewHeight(); +    getChild<LLUICtrl>("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost(w, h)));      getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onResolutionComboCommit, this, _1));      if (!getWidthSpinnerName().empty())      { diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp index 4abb89120b..96b17acc40 100644 --- a/indra/newview/llpanelsnapshotinventory.cpp +++ b/indra/newview/llpanelsnapshotinventory.cpp @@ -155,7 +155,19 @@ void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl)  void LLPanelSnapshotInventoryBase::onSend()  { -    S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); +    S32 w = 0; +    S32 h = 0; + +    if( mSnapshotFloater ) +    { +        LLSnapshotLivePreview* preview = mSnapshotFloater->getPreviewView(); +        if( preview ) +        { +            preview->getSize(w, h); +        } +    } + +    S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(w, h);      if (can_afford_transaction(expected_upload_cost))      {          if (mSnapshotFloater) diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp index 776de460a9..962d3bba16 100644 --- a/indra/newview/llpanelsnapshotoptions.cpp +++ b/indra/newview/llpanelsnapshotoptions.cpp @@ -30,6 +30,7 @@  #include "llsidetraypanelcontainer.h"  #include "llfloatersnapshot.h" // FIXME: create a snapshot model +#include "llsnapshotlivepreview.h"  #include "llfloaterreg.h"  #include "llagentbenefits.h" @@ -89,7 +90,19 @@ void LLPanelSnapshotOptions::onOpen(const LLSD& key)  void LLPanelSnapshotOptions::updateUploadCost()  { -    S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); +    S32 w = 0; +    S32 h = 0; + +    if( mSnapshotFloater ) +    { +        LLSnapshotLivePreview* preview = mSnapshotFloater->getPreviewView(); +        if( preview ) +        { +            preview->getSize(w, h); +        } +    } + +    S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(w, h);      getChild<LLUICtrl>("save_to_inventory_btn")->setLabelArg("[AMOUNT]", llformat("%d", upload_cost));  } diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index c2188ea638..b7c929f0b5 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -414,7 +414,13 @@ LLScriptEdCore::~LLScriptEdCore()      if (script_search && script_search->getEditorCore() == this)      {          script_search->closeFloater(); -        delete script_search; +        // closeFloater can delete instance since it's not reusable nor single instance +        // so make sure instance is still there before deleting +        script_search = LLFloaterScriptSearch::getInstance(); +        if (script_search) +        { +            delete script_search; +        }      }      delete mLiveFile; diff --git a/indra/newview/llsetkeybinddialog.cpp b/indra/newview/llsetkeybinddialog.cpp index e172e15a0e..5dbd579b45 100644 --- a/indra/newview/llsetkeybinddialog.cpp +++ b/indra/newview/llsetkeybinddialog.cpp @@ -337,8 +337,8 @@ void LLSetKeyBindDialog::onCancel(void* user_data)  void LLSetKeyBindDialog::onBlank(void* user_data)  {      LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; -    // tmp needs 'no key' button -    self->setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); + +    self->setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, self->pCheckBox->getValue().asBoolean());      self->closeFloater();  } diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 451f5bd607..0b73aa493c 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -65,10 +65,10 @@ constexpr F32 FALL_TIME = 0.6f;  constexpr S32 BORDER_WIDTH = 6;  constexpr S32 TOP_PANEL_HEIGHT = 30; -constexpr S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512 +constexpr S32 MAX_TEXTURE_SIZE = 2048 ; //max upload texture size 2048 * 2048  std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList; -LLPointer<LLImageFormatted> LLSnapshotLivePreview::sSaveLocalImage = NULL; +LLPointer<LLImageFormatted> LLSnapshotLivePreview::sSaveLocalImage = nullptr;  LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Params& p)      :   LLView(p), @@ -1024,7 +1024,7 @@ void LLSnapshotLivePreview::saveTexture(bool outfit_snapshot, std::string name)          LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);          std::string who_took_it;          LLAgentUI::buildFullname(who_took_it); -        S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); +        S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(scaled->getWidth(), scaled->getHeight());          std::string res_name = outfit_snapshot ? name : "Snapshot : " + pos_string;          std::string res_desc = outfit_snapshot ? "" : "Taken by " + who_took_it + " at " + pos_string;          LLFolderType::EType folder_type = outfit_snapshot ? LLFolderType::FT_NONE : LLFolderType::FT_SNAPSHOT_CATEGORY; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 85683a544b..ffe5fa394f 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3978,12 +3978,14 @@ void LLCullResult::clear()      for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)      { -        for (U32 j = 0; j < mRenderMapSize[i]; j++) +        drawinfo_list_t& render_map = mRenderMap[i]; +        U32 render_map_size = llmin((U32)render_map.size(), mRenderMapSize[i]); +        for (U32 j = 0; j < render_map_size; j++)          { -            mRenderMap[i][j] = 0; +            render_map[j] = 0;          }          mRenderMapSize[i] = 0; -        mRenderMapEnd[i] = &(mRenderMap[i][0]); +        mRenderMapEnd[i] = &render_map.front();      }  } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index adcf91f4ed..2ae3d016c4 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -654,7 +654,7 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot)      gPipeline.resetFrameStats();    // Reset per-frame statistics. -    if (!gDisconnected) +    if (!gDisconnected && !LLApp::isExiting())      {          // Render mirrors and associated hero probes before we render the rest of the scene.          // This ensures the scene state in the hero probes are exactly the same as the rest of the scene before we render it. diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 96c839d918..7623ab56a5 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2496,10 +2496,10 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)                  gSavedSettings.setBOOL("GLTFEnabled", false);              } -            llassert(gAgent.getRegion()); -            if (gAgent.getRegion() && gAgent.getRegion()->isCapabilityAvailable("ModifyRegion")) +            if (features.has("PBRTerrainTransformsEnabled"))              { -                gSavedSettings.setBOOL("RenderTerrainPBRTransformsEnabled", true); +                bool enabled = features["PBRTerrainTransformsEnabled"]; +                gSavedSettings.setBOOL("RenderTerrainPBRTransformsEnabled", enabled);              }              else              { @@ -3147,16 +3147,24 @@ void LLViewerRegion::unpackRegionHandshake()              compp->setParamsReady();          } -        LLPBRTerrainFeatures::queueQuery(*this, [](LLUUID region_id, bool success, const LLModifyRegion& composition_changes) +        std::string cap = getCapability("ModifyRegion"); // needed for queueQuery +        if (cap.empty())          { -            if (!success) { return; } -            LLViewerRegion* region = LLWorld::getInstance()->getRegionFromID(region_id); -            if (!region) { return; } -            LLVLComposition* compp = region->getComposition(); -            if (!compp) { return; } -            compp->apply(composition_changes); -            LLFloaterRegionInfo::sRefreshFromRegion(region); -        }); +            LLFloaterRegionInfo::sRefreshFromRegion(this); +        } +        else +        { +            LLPBRTerrainFeatures::queueQuery(*this, [](LLUUID region_id, bool success, const LLModifyRegion& composition_changes) +            { +                if (!success) { return; } +                LLViewerRegion* region = LLWorld::getInstance()->getRegionFromID(region_id); +                if (!region) { return; } +                LLVLComposition* compp = region->getComposition(); +                if (!compp) { return; } +                compp->apply(composition_changes); +                LLFloaterRegionInfo::sRefreshFromRegion(region); +            }); +        }      } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index e486449b4d..d31c53d000 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -926,6 +926,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag      }      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; +    bool onFace = false;      for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)      {          for (S32 fi = 0; fi < imagep->getNumFaces(i); ++fi) @@ -934,6 +935,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag              if (face && face->getViewerObject())              { +                onFace = true;                  F32 radius;                  F32 cos_angle_to_view_dir;                  bool in_frustum = face->calcPixelArea(cos_angle_to_view_dir, radius); @@ -1031,7 +1033,8 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag              imagep->getLastReferencedTimer()->reset();              //reset texture state. -            imagep->setInactive(); +            if(!onFace) +                imagep->setInactive();          }      } diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 813fda1647..075f6ae915 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -229,8 +229,8 @@ public:      bool mForceResetTextureStats;      // to make "for (auto& imagep : gTextureList)" work -    const image_list_t::iterator begin() const { return mImageList.begin(); } -    const image_list_t::iterator end() const { return mImageList.end(); } +    const image_list_t::const_iterator begin() const { return mImageList.cbegin(); } +    const image_list_t::const_iterator end() const { return mImageList.cend(); }  private:      typedef std::map< LLTextureKey, LLPointer<LLViewerFetchedTexture> > uuid_map_t; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ac95a2f8f7..fadea01d3c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2589,6 +2589,9 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; +    if (LLApp::isExiting()) +        return; +      if (isDead())      {          LL_INFOS() << "Warning!  Idle on dead avatar" << LL_ENDL; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 67f41b2733..891c9383bf 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -137,7 +137,7 @@ LLVoiceClient::LLVoiceClient(LLPumpIO *pump)      mSpatialVoiceModule(NULL),      mNonSpatialVoiceModule(NULL),      m_servicePump(NULL), -    mVoiceEffectEnabled(LLCachedControl<bool>(gSavedSettings, "VoiceMorphingEnabled", false)), +    mVoiceEffectEnabled(LLCachedControl<bool>(gSavedSettings, "VoiceMorphingEnabled", true)),      mVoiceEffectDefault(LLCachedControl<std::string>(gSavedPerAccountSettings, "VoiceEffectDefault", "00000000-0000-0000-0000-000000000000")),      mVoiceEffectSupportNotified(false),      mPTTDirty(true), @@ -577,7 +577,7 @@ bool LLVoiceClient::onVoiceEffectsNotSupported(const LLSD ¬ification, const L      switch (option)      {          case 0:  // "Okay" -            gSavedSettings.setBOOL("VoiceMorphingEnabled", FALSE); +            gSavedPerAccountSettings.setString("VoiceEffectDefault", LLUUID::null.asString());              break;          case 1:  // "Cancel" diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index fcb8a0a4f2..060e1243ab 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -2540,7 +2540,6 @@ void LLVivoxVoiceClient::sessionCreateSendMessage(const sessionStatePtr_t &sessi      stream          << "<ConnectAudio>" << (startAudio?"true":"false") << "</ConnectAudio>"          << "<ConnectText>" << (startText?"true":"false") << "</ConnectText>" -        << "<VoiceFontID>" << font_index << "</VoiceFontID>"          << "<Name>" << mChannelName << "</Name>"      << "</Request>\n\n\n";      LL_WARNS("Voice") << "Session.Create: " << stream.str() << LL_ENDL; @@ -2579,7 +2578,6 @@ void LLVivoxVoiceClient::sessionGroupAddSessionSendMessage(const sessionStatePtr          << "<Name>" << mChannelName << "</Name>"          << "<ConnectAudio>" << (startAudio?"true":"false") << "</ConnectAudio>"          << "<ConnectText>" << (startText?"true":"false") << "</ConnectText>" -        << "<VoiceFontID>" << font_index << "</VoiceFontID>"          << "<Password>" << password << "</Password>"          << "<PasswordHashAlgorithm>SHA1UserName</PasswordHashAlgorithm>"      << "</Request>\n\n\n" @@ -2603,7 +2601,6 @@ void LLVivoxVoiceClient::sessionMediaConnectSendMessage(const sessionStatePtr_t      << "<Request requestId=\"" << session->mHandle << "\" action=\"Session.MediaConnect.1\">"          << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>"          << "<SessionHandle>" << session->mHandle << "</SessionHandle>" -        << "<VoiceFontID>" << font_index << "</VoiceFontID>"          << "<Media>Audio</Media>"      << "</Request>\n\n\n"; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 16d66123ae..6cf7d9f51c 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -5287,7 +5287,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;      assertInitialized(); -    if (LLPipeline::sReflectionRender || gCubeSnapshot || LLPipeline::sRenderingHUDs) +    if (LLPipeline::sReflectionRender || gCubeSnapshot || LLPipeline::sRenderingHUDs || LLApp::isExiting())      {          return;      } diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a1e25f48ed..2c19a89fb2 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3032,6 +3032,15 @@ This is usually a temporary failure. Please customize and save the wearable agai    </notification>    <notification +   icon="notifytip.tga" +   name="OutOfDiskSpace" +   type="notifytip"> +The system is out of disk space. You will need to free up some space on your computer or clear the cache. +<tag>fail</tag> +    <unique/> +  </notification> + +  <notification     icon="alertmodal.tga"     name="YouHaveBeenLoggedOut"     type="alertmodal"> @@ -4254,6 +4263,20 @@ Can't change appearance until clothing and shape are loaded.    <notification     icon="alertmodal.tga" +   name="UsavedWearableChanges" +   type="alertmodal"> +You have unsaved changes. +      <tag>group</tag> +    <tag>confirm</tag> +    <usetemplate +     ignoretext="Confirm before I discard unsaved wearable changes" +     name="okcancelignore" +     notext="Keep Editing" +     yestext="Discard"/> +  </notification> + +  <notification +   icon="alertmodal.tga"     name="ClassifiedMustBeAlphanumeric"     type="alertmodal">  The name of your classified must start with a letter from A to Z or a number.  No punctuation is allowed. | 
