diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 155e32ebae60eda8e685f931de685cb2ad9a308d..e5060a1076a335fe5cda259a6917b42fc7801860 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -146,7 +146,7 @@ S32 LLQueuedThread::updateQueue(F32 max_time_ms)
         // schedule a call to threadedUpdate for every call to updateQueue
         if (!isQuitting())
         {
-            mRequestQueue.post([=]()
+            mRequestQueue.postIfOpen([=]()
                 {
                     LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update");
                     mIdleThread = FALSE;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6ca35684d968bbabb6e356d08096a67370fb17c8..54f189625e0bb9a46a33f5978988619ffc1871df 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2071,6 +2071,7 @@ bool LLAppViewer::cleanup()
     if (sTextureFetch)
     {
         sTextureFetch->shutdown();
+        sTextureFetch->waitOnPending();
         delete sTextureFetch;
         sTextureFetch = NULL;
     }
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index f05f0344bd0570ba0dbb97b8d36e059e8f2b0981..5acf0600b65f4301f3f0bb954e3431d42d0d79a0 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1059,24 +1059,39 @@ static void pack_textures(
     LLPointer<LLImageJ2C>& mr_j2c,
     LLPointer<LLImageJ2C>& emissive_j2c)
 {
+    // NOTE : remove log spam and lossless vs lossy comparisons when the logs are no longer useful
+
     if (albedo_img)
     {
         albedo_j2c = LLViewerTextureList::convertToUploadFile(albedo_img);
+        LL_INFOS() << "Albedo: " << albedo_j2c->getDataSize() << LL_ENDL;
     }
 
     if (normal_img)
     {
         normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img);
+
+        LLPointer<LLImageJ2C> test;
+        test = LLViewerTextureList::convertToUploadFile(normal_img, 1024, true);
+
+        S32 lossy_bytes = normal_j2c->getDataSize();
+        S32 lossless_bytes = test->getDataSize();
+
+        LL_INFOS() << llformat("Lossless vs Lossy: (%d/%d) = %.2f", lossless_bytes, lossy_bytes, (F32)lossless_bytes / lossy_bytes) << LL_ENDL;
+
+        normal_j2c = test;
     }
 
     if (mr_img)
     {
         mr_j2c = LLViewerTextureList::convertToUploadFile(mr_img);
+        LL_INFOS() << "Metallic/Roughness: " << mr_j2c->getDataSize() << LL_ENDL;
     }
 
     if (emissive_img)
     {
         emissive_j2c = LLViewerTextureList::convertToUploadFile(emissive_img);
+        LL_INFOS() << "Emissive: " << emissive_j2c->getDataSize() << LL_ENDL;
     }
 }
 
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 9cbbf1c276a760623d0bc2dbe98ea52a164d87c1..511df4bd79c9fc299ad3d207a91c12b948e7b60b 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1224,15 +1224,18 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
 }
 
 // note: modifies the argument raw_image!!!!
-LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions)
+LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions, bool force_lossless)
 {
 	LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	raw_image->biasedScaleToPowerOfTwo(max_image_dimentions);
 	LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
 	
-	if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
-		(raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF))
-		compressedImage->setReversible(TRUE);
+    if (force_lossless ||
+        (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
+            (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)))
+    {
+        compressedImage->setReversible(TRUE);
+    }
 	
 
 	if (gSavedSettings.getBOOL("Jpeg2000AdvancedCompression"))
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 7de3d68e42150cdc436c94a2305f78faad16f0ee..4116be652896cb7f53f90cce8510e4304c10db08 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -96,7 +96,7 @@ class LLViewerTextureList
                                  const std::string& out_filename,
                                  const U8 codec,
                                  const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
-	static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+	static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT, bool force_lossless = false);
 	static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
 	static void receiveImageHeader(LLMessageSystem *msg, void **user_data);
 	static void receiveImagePacket(LLMessageSystem *msg, void **user_data);