diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index 46e1cb4922552772399b989a1507ce170abb2d6b..2e4b013b778787e38809549799f00422fb33c941 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -2584,7 +2584,8 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo
 			next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod];
 			next->getVolumeFaces() = remainder;
 			next->mNormalizedScale = ret->mNormalizedScale;
-			
+			next->mNormalizedTranslation = ret->mNormalizedTranslation;
+
 			if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES)
 			{
 				next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end());
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index ee493968de6adf5dcf660ee898e76b07234ddc3b..99a5697a84f895345f30f4f5a9cd167f9d87e523 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -52,7 +52,8 @@ const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
 
 LLModel::LLModel(LLVolumeParams& params, F32 detail)
 	: LLVolume(params, detail), 
-      mNormalizedScale(1,1,1), 
+      mNormalizedScale(1,1,1),
+      mNormalizedTranslation(0, 0, 0),
       mPelvisOffset( 0.0f ), 
       mStatus(NO_ERRORS), 
       mSubmodelID(0)
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index 7fdef4a3b7d87b8389a1c80e1e372bb70f38709d..b616002b49c74d41ef794b392937641107ea3265 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -94,7 +94,8 @@ void LLGLTexture::setBoostLevel(S32 level)
 	{
 		mBoostLevel = level ;
 		if(mBoostLevel != LLGLTexture::BOOST_NONE
-		   && mBoostLevel != LLGLTexture::BOOST_ICON)
+		   && mBoostLevel != LLGLTexture::BOOST_ICON
+           && mBoostLevel != LLGLTexture::BOOST_THUMBNAIL)
 		{
 			setNoDelete() ;		
 		}
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index 5c693fc93c12bea6b81ddba0a4449e825973f74b..24849d1d1bc41c1fe4e94cb75efbbc6203cc8b81 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -62,6 +62,7 @@ class LLGLTexture : public LLTexture
 		BOOST_SUPER_HIGH    , //textures higher than this need to be downloaded at the required resolution without delay.
 		BOOST_HUD			,
 		BOOST_ICON			,
+        BOOST_THUMBNAIL		,
 		BOOST_UI			,
 		BOOST_PREVIEW		,
 		BOOST_MAP			,
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 9fe9ff9d996b339374d1d060c6195ce7dbd53be7..21c8c7b46b8993bd95ff730695cad0d26e4239f3 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-7.0.1
+7.1.1
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index b9025ef7cdfb57fda5b4fb3ecc20123c8745488f..00b59f9a4d9a319fb210861853bc5eb1d579f9d7 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -533,6 +533,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>RenderSnapshotNoPost</key>
+    <map>
+      <key>Comment</key>
+      <string>Disable tone mapping and exposure correction when snapshot is being rendered</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>AutomaticFly</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 6b9d4580dccdaf44da194bdbc0b80433c4eded78..ca2069cbfca8b986a63afbff2817422559fdf814 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -461,8 +461,8 @@ void LLFloaterSnapshotBase::ImplBase::onClickAutoSnap(LLUICtrl *ctrl, void* data
 {
 	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
 	gSavedSettings.setBOOL( "AutoSnapshot", check->get() );
-	
-	LLFloaterSnapshotBase *view = (LLFloaterSnapshotBase *)data;		
+
+	LLFloaterSnapshotBase *view = (LLFloaterSnapshotBase *)data;
 	if (view)
 	{
 		view->impl->checkAutoSnapshot(view->getPreviewView());
@@ -470,6 +470,17 @@ void LLFloaterSnapshotBase::ImplBase::onClickAutoSnap(LLUICtrl *ctrl, void* data
 	}
 }
 
+// static
+void LLFloaterSnapshotBase::ImplBase::onClickNoPost(LLUICtrl *ctrl, void* data)
+{
+    BOOL no_post = ((LLCheckBoxCtrl*)ctrl)->get();
+    gSavedSettings.setBOOL("RenderSnapshotNoPost", no_post);
+
+    LLFloaterSnapshotBase* view = (LLFloaterSnapshotBase*)data;
+    view->getPreviewView()->updateSnapshot(TRUE, TRUE);
+    view->impl->updateControls(view);
+}
+
 // static
 void LLFloaterSnapshotBase::ImplBase::onClickFilter(LLUICtrl *ctrl, void* data)
 {
@@ -997,6 +1008,9 @@ BOOL LLFloaterSnapshot::postBuild()
 	getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
 	childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
 
+    getChild<LLUICtrl>("no_post_check")->setValue(gSavedSettings.getBOOL("RenderSnapshotNoPost"));
+    childSetCommitCallback("no_post_check", ImplBase::onClickNoPost, this);
+
     getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterSnapshot::onExtendFloater, this));
     getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterSnapshot::onExtendFloater, this));
 
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 7fc62a27469bb91fd84e3216017e2c860b54b585..89cb2bc8095a2d07473419756a5a2fae3188c125 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -100,6 +100,7 @@ class LLFloaterSnapshotBase::ImplBase
 
 	static void onClickNewSnapshot(void* data);
 	static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
+	static void onClickNoPost(LLUICtrl *ctrl, void* data);
 	static void onClickFilter(LLUICtrl *ctrl, void* data);
 	static void onClickUICheck(LLUICtrl *ctrl, void* data);
 	static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index 62180bb066f34eb37259ba181a8e4d8a0199bb15..68581d04ebdec8bdb61f3edcfd3c04f4136cd2b6 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -58,6 +58,7 @@
 static LLPanelInjector<LLInventoryGallery> t_inventory_gallery("inventory_gallery");
 
 const S32 GALLERY_ITEMS_PER_ROW_MIN = 2;
+const S32 FAST_LOAD_THUMBNAIL_TRSHOLD = 50; // load folders below this value immediately
 
 // Helper dnd functions
 BOOL dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, BOOL drop, std::string& tooltip_msg, BOOL is_link);
@@ -106,6 +107,7 @@ LLInventoryGallery::LLInventoryGallery(const LLInventoryGallery::Params& p)
       mGalleryWidthFactor(p.gallery_width_factor),
       mIsInitialized(false),
       mRootDirty(false),
+      mLoadThumbnailsImmediately(true),
       mNeedsArrange(false),
       mSearchType(LLInventoryFilter::SEARCHTYPE_NAME),
       mSortOrder(LLInventoryFilter::SO_DATE)
@@ -540,6 +542,12 @@ void LLInventoryGallery::addToGallery(LLInventoryGalleryItem* item)
     int n_prev = n - 1;
     int row_count_prev = (n_prev % mItemsInRow) == 0 ? n_prev / mItemsInRow : n_prev / mItemsInRow + 1;
 
+    // Avoid loading too many items.
+    // Intent is for small folders to display all content fast
+    // and for large folders to load content mostly as needed
+    // Todo: ideally needs to unload images outside visible area
+    mLoadThumbnailsImmediately = mItemsAddedCount < FAST_LOAD_THUMBNAIL_TRSHOLD;
+
     bool add_row = row_count != row_count_prev;
     int pos = 0;
     if (add_row)
@@ -573,6 +581,8 @@ void LLInventoryGallery::removeFromGalleryLast(LLInventoryGalleryItem* item, boo
     mItemsAddedCount--;
     mIndexToItemMap.erase(mItemsAddedCount);
 
+    mLoadThumbnailsImmediately = mItemsAddedCount < FAST_LOAD_THUMBNAIL_TRSHOLD;
+
     bool remove_row = row_count != row_count_prev;
     removeFromLastRow(mItems[mItemsAddedCount]);
     mItems.pop_back();
@@ -636,6 +646,7 @@ LLInventoryGalleryItem* LLInventoryGallery::buildGalleryItem(std::string name, L
     gitem->setUUID(item_id);
     gitem->setGallery(this);
     gitem->setType(type, inventory_type, flags, is_link);
+    gitem->setLoadImmediately(mLoadThumbnailsImmediately);
     gitem->setThumbnail(thumbnail_id);
     gitem->setWorn(is_worn);
     gitem->setCreatorName(get_searchable_creator_name(&gInventory, item_id));
@@ -997,6 +1008,7 @@ void LLInventoryGallery::updateItemThumbnail(LLUUID item_id)
 
     if (mItemMap[item_id])
     {
+        mItemMap[item_id]->setLoadImmediately(mLoadThumbnailsImmediately);
         mItemMap[item_id]->setThumbnail(thumbnail_id);
 
         bool passes_filter = checkAgainstFilters(mItemMap[item_id], mFilterSubString);
@@ -2557,6 +2569,7 @@ BOOL LLInventoryGalleryItem::postBuild()
 {
     mNameText = getChild<LLTextBox>("item_name");
     mTextBgPanel = getChild<LLPanel>("text_bg_panel");
+    mThumbnailCtrl = getChild<LLThumbnailCtrl>("preview_thumbnail");
 
     return TRUE;
 }
@@ -2632,14 +2645,19 @@ void LLInventoryGalleryItem::setThumbnail(LLUUID id)
     mDefaultImage = id.isNull();
     if(mDefaultImage)
     {
-        getChild<LLThumbnailCtrl>("preview_thumbnail")->clearTexture();
+        mThumbnailCtrl->clearTexture();
     }
     else
     {
-        getChild<LLThumbnailCtrl>("preview_thumbnail")->setValue(id);
+        mThumbnailCtrl->setValue(id);
     }
 }
 
+void LLInventoryGalleryItem::setLoadImmediately(bool val)
+{
+    mThumbnailCtrl->setInitImmediately(val);
+}
+
 void LLInventoryGalleryItem::draw()
 {
     if (isFadeItem())
@@ -2654,7 +2672,7 @@ void LLInventoryGalleryItem::draw()
 
         // Draw border
         LLUIColor border_color = LLUIColorTable::instance().getColor(mSelected ? "MenuItemHighlightBgColor" : "TextFgTentativeColor", LLColor4::white);
-        LLRect border = getChildView("preview_thumbnail")->getRect();
+        LLRect border = mThumbnailCtrl->getRect();
         border.mRight = border.mRight + 1;
         border.mTop = border.mTop + 1;
         gl_rect_2d(border, border_color.get(), FALSE);
@@ -2876,7 +2894,7 @@ void LLInventoryGalleryItem::updateNameText()
     mNameText->setFont(getTextFont());
     mNameText->setText(mItemName + mPermSuffix + mWornSuffix);
     mNameText->setToolTip(mItemName + mPermSuffix + mWornSuffix);
-    getChild<LLThumbnailCtrl>("preview_thumbnail")->setToolTip(mItemName + mPermSuffix + mWornSuffix);
+    mThumbnailCtrl->setToolTip(mItemName + mPermSuffix + mWornSuffix);
 }
 
 bool LLInventoryGalleryItem::isFadeItem()
diff --git a/indra/newview/llinventorygallery.h b/indra/newview/llinventorygallery.h
index 9b3f12701fe1d9538cb191b2800477994ad2dd34..0c52e7b71321880c8a687e48542e91bf8a706700 100644
--- a/indra/newview/llinventorygallery.h
+++ b/indra/newview/llinventorygallery.h
@@ -39,6 +39,7 @@ class LLInventoryGalleryItem;
 class LLScrollContainer;
 class LLTextBox;
 class LLThumbnailsObserver;
+class LLThumbnailCtrl;
 class LLGalleryGestureObserver;
 
 class LLInventoryGalleryContextMenu;
@@ -246,6 +247,7 @@ class LLInventoryGallery : public LLPanel, public LLEditMenuHandler
     int mRowCount;
     int mItemsAddedCount;
     bool mGalleryCreated;
+    bool mLoadThumbnailsImmediately;
     bool mNeedsArrange;
 
     /* Params */
@@ -342,6 +344,7 @@ class LLInventoryGalleryItem : public LLPanel
     LLAssetType::EType getAssetType() { return mType; }
     void setThumbnail(LLUUID id);
     void setGallery(LLInventoryGallery* gallery) { mGallery = gallery; }
+    void setLoadImmediately(bool val);
     bool isFolder() { return mIsFolder; }
     bool isLink() { return mIsLink; }
     EInventorySortGroup getSortGroup() { return mSortGroup; }
@@ -354,6 +357,7 @@ class LLInventoryGalleryItem : public LLPanel
     LLUUID mUUID;
     LLTextBox* mNameText;
     LLPanel* mTextBgPanel;
+    LLThumbnailCtrl* mThumbnailCtrl;
     bool     mSelected;
     bool     mWorn;
     bool     mDefaultImage;
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 70e21cae73c1e9eb0c99058a135dc36bbddaa879..292ddb765f0a5a4294b7e93db59e3822def6da09 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -436,10 +436,10 @@ BOOL LLMaterialEditor::postBuild()
     if (!gAgent.isGodlike())
     {
         // Only allow fully permissive textures
-        mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
-        mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
-        mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
-        mNormalTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+        mBaseColorTextureCtrl->setFilterPermissionMasks(PERM_COPY | PERM_TRANSFER);
+        mMetallicTextureCtrl->setFilterPermissionMasks(PERM_COPY | PERM_TRANSFER);
+        mEmissiveTextureCtrl->setFilterPermissionMasks(PERM_COPY | PERM_TRANSFER);
+        mNormalTextureCtrl->setFilterPermissionMasks(PERM_COPY | PERM_TRANSFER);
     }
 
     // Texture callback
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 02c00e7f871c66137ab1becb696fe009dac53958..ffcc4be29024623e30c25a4e210de4ef50854ea6 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1915,8 +1915,6 @@ class PBRPickerAgentListener : public LLInventoryObserver
     {
         gInventory.removeObserver(this);
         mChangePending = false;
-
-        LLInventoryObserver::~LLInventoryObserver();
     }
 };
 
@@ -1982,7 +1980,7 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
 
         if (objectp->isAttachment())
         {
-            pbr_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER | PERM_MODIFY);
+            pbr_ctrl->setFilterPermissionMasks(PERM_COPY | PERM_TRANSFER | PERM_MODIFY);
         }
         else
         {
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index f58aab308007c19c81a6b2516a71aadc81c3cbed..595609b4deb57cec51ce5bbd22f3ebd863149419 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -746,6 +746,14 @@ void LLPanelVolume::sendIsLight()
 	LL_INFOS() << "update light sent" << LL_ENDL;
 }
 
+void notify_cant_select_reflection_probe()
+{
+    if (!gSavedSettings.getBOOL("SelectReflectionProbes"))
+    {
+        LLNotificationsUtil::add("CantSelectReflectionProbe");
+    }
+}
+
 void LLPanelVolume::sendIsReflectionProbe()
 {
     LLViewerObject* objectp = mObject;
@@ -766,7 +774,7 @@ void LLPanelVolume::sendIsReflectionProbe()
     {
         if (value)
         {
-            LLNotificationsUtil::add("CantSelectReflectionProbe");
+            notify_cant_select_reflection_probe();
         }
         else if (objectp->flagPhantom())
         {
@@ -794,7 +802,7 @@ void LLPanelVolume::doSendIsReflectionProbe(const LLSD & notification, const LLS
         }
         LLVOVolume* volobjp = (LLVOVolume*)objectp;
 
-        LLNotificationsUtil::add("CantSelectReflectionProbe");
+        notify_cant_select_reflection_probe();
         volobjp->setIsReflectionProbe(true);
 
         { // has become a reflection probe, slam to a 10m sphere and pop up a message
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index b7a1832b17af9a16babbebe0d21f85ffa33a64c3..2ff8f50277aa012603aaf91b0681d50f8426adfb 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -559,6 +559,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
                                          mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"),
                                          gSavedSettings.getBOOL("RenderHUDInSnapshot"),
                                          FALSE,
+                                         gSavedSettings.getBOOL("RenderSnapshotNoPost"),
                                          mSnapshotBufferType) )
         {
             raw = NULL ;
@@ -718,6 +719,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
                 previewp->mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"),
                 gSavedSettings.getBOOL("RenderHUDInSnapshot"),
                 FALSE,
+                gSavedSettings.getBOOL("RenderSnapshotNoPost"),
                 previewp->mSnapshotBufferType,
                 previewp->getMaxImageSize()))
         {
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index f302426a43775c19c1764bfa799752253f389724..28e01c6c219234a8cd753bfbcef95fe9b95e57e1 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1715,6 +1715,12 @@ void LLTextureCtrl::setImmediateFilterPermMask(PermissionMask mask)
     }
 }
 
+void LLTextureCtrl::setFilterPermissionMasks(PermissionMask mask) 
+{
+    setImmediateFilterPermMask(mask);
+    setDnDFilterPermMask(mask);
+}
+
 void LLTextureCtrl::setVisible( BOOL visible ) 
 {
 	if( !visible )
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index c47df5accbafd3e1a82c72373f29fd4169732575..7a96eea60dccf2d69ba324756fedc21de6f3380e 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -196,6 +196,7 @@ class LLTextureCtrl
 	void			setDnDFilterPermMask(PermissionMask mask)
 						{ mDnDFilterPermMask = mask; }
 	PermissionMask	getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
+    void setFilterPermissionMasks(PermissionMask mask);
 
 	void			closeDependentFloater();
 
diff --git a/indra/newview/llthumbnailctrl.cpp b/indra/newview/llthumbnailctrl.cpp
index 04130fc724d755b2bce5c48a90d845629c63e006..b558c249cb6fddeee5314f9bff1b64206f5f41cb 100644
--- a/indra/newview/llthumbnailctrl.cpp
+++ b/indra/newview/llthumbnailctrl.cpp
@@ -57,7 +57,8 @@ LLThumbnailCtrl::LLThumbnailCtrl(const LLThumbnailCtrl::Params& p)
 ,   mFallbackImagep(p.fallback_image)
 ,   mInteractable(p.interactable())
 ,   mShowLoadingPlaceholder(p.show_loading())
-,	mPriority(LLGLTexture::BOOST_PREVIEW)
+,   mInited(false)
+,   mInitImmediately(true)
 {
     mLoadingPlaceholderString = LLTrans::getString("texture_loading");
     
@@ -84,6 +85,10 @@ LLThumbnailCtrl::~LLThumbnailCtrl()
 
 void LLThumbnailCtrl::draw()
 {
+    if (!mInited)
+    {
+        initImage();
+    }
     LLRect draw_rect = getLocalRect();
     
     if (mBorderVisible)
@@ -171,11 +176,19 @@ void LLThumbnailCtrl::draw()
     LLUICtrl::draw();
 }
 
+void LLThumbnailCtrl::setVisible(BOOL visible)
+{
+    if (!visible && mInited)
+    {
+        unloadImage();
+    }
+    LLUICtrl::setVisible(visible);
+}
+
 void LLThumbnailCtrl::clearTexture()
 {
-    mImageAssetID = LLUUID::null;
-    mTexturep = nullptr;
-    mImagep = nullptr;
+    setValue(LLSD());
+    mInited = true; // nothing to do
 }
 
 // virtual
@@ -191,34 +204,55 @@ void LLThumbnailCtrl::setValue(const LLSD& value)
     
 	LLUICtrl::setValue(tvalue);
     
-    mImageAssetID = LLUUID::null;
-    mTexturep = nullptr;
-    mImagep = nullptr;
-    
-	if (tvalue.isUUID())
-	{
+    unloadImage();
+
+    if (mInitImmediately)
+    {
+        initImage();
+    }
+}
+
+BOOL LLThumbnailCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+    if (mInteractable && getEnabled())
+    {
+        getWindow()->setCursor(UI_CURSOR_HAND);
+        return TRUE;
+    }
+    return LLUICtrl::handleHover(x, y, mask);
+}
+
+void LLThumbnailCtrl::initImage()
+{
+    if (mInited)
+    {
+        return;
+    }
+    mInited = true;
+    LLSD tvalue = getValue();
+
+    if (tvalue.isUUID())
+    {
         mImageAssetID = tvalue.asUUID();
         if (mImageAssetID.notNull())
         {
             // Should it support baked textures?
-            mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-            
-            mTexturep->setBoostLevel(mPriority);
+            mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_THUMBNAIL);
+
             mTexturep->forceToSaveRawImage(0);
-            
-            S32 desired_draw_width = mTexturep->getWidth();
-            S32 desired_draw_height = mTexturep->getHeight();
-            
+
+            S32 desired_draw_width = MAX_IMAGE_SIZE;
+            S32 desired_draw_height = MAX_IMAGE_SIZE;
             mTexturep->setKnownDrawSize(desired_draw_width, desired_draw_height);
         }
-	}
+    }
     else if (tvalue.isString())
     {
         mImagep = LLUI::getUIImage(tvalue.asString(), LLGLTexture::BOOST_UI);
         if (mImagep)
         {
             LLViewerFetchedTexture* texture = dynamic_cast<LLViewerFetchedTexture*>(mImagep->getImage().get());
-            if(texture)
+            if (texture)
             {
                 mImageAssetID = texture->getID();
             }
@@ -226,14 +260,12 @@ void LLThumbnailCtrl::setValue(const LLSD& value)
     }
 }
 
-BOOL LLThumbnailCtrl::handleHover(S32 x, S32 y, MASK mask)
+void LLThumbnailCtrl::unloadImage()
 {
-    if (mInteractable && getEnabled())
-    {
-        getWindow()->setCursor(UI_CURSOR_HAND);
-        return TRUE;
-    }
-    return LLUICtrl::handleHover(x, y, mask);
+    mImageAssetID = LLUUID::null;
+    mTexturep = nullptr;
+    mImagep = nullptr;
+    mInited = false;
 }
 
 
diff --git a/indra/newview/llthumbnailctrl.h b/indra/newview/llthumbnailctrl.h
index 686603b37300c4c4993764d2f421a62d65dfa390..f84a58327152dc42816be580014cf6551e49233c 100644
--- a/indra/newview/llthumbnailctrl.h
+++ b/indra/newview/llthumbnailctrl.h
@@ -64,17 +64,24 @@ class LLThumbnailCtrl
 	virtual ~LLThumbnailCtrl();
 
 	virtual void draw() override;
+    void setVisible(BOOL visible) override;
 
 	virtual void setValue(const LLSD& value ) override;
+    void setInitImmediately(bool val) { mInitImmediately = val; }
     void clearTexture();
     
     virtual BOOL handleHover(S32 x, S32 y, MASK mask) override;
+
+protected:
+    void initImage();
+    void unloadImage();
 	
 private:
-	S32 mPriority;
     bool mBorderVisible;
     bool mInteractable;
     bool mShowLoadingPlaceholder;
+    bool mInited;
+    bool mInitImmediately;
     std::string mLoadingPlaceholderString;
     LLUUID mImageAssetID;
     LLViewBorder* mBorder;
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 04ca62e0ec3c12fb449ef6a58a4181ace9e57dd5..a936012781612b294c5f5aa0c4b6d62ee8ae089e 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -100,6 +100,7 @@ BOOL gResizeShadowTexture = FALSE;
 BOOL gWindowResized = FALSE;
 BOOL gSnapshot = FALSE;
 BOOL gCubeSnapshot = FALSE;
+BOOL gSnapshotNoPost = FALSE;
 BOOL gShaderProfileFrame = FALSE;
 
 // This is how long the sim will try to teleport you before giving up.
@@ -410,13 +411,13 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		gResizeShadowTexture = FALSE;
 	}
 
+	gSnapshot = for_snapshot;
+
 	if (LLPipeline::sRenderDeferred)
 	{ //hack to make sky show up in deferred snapshots
 		for_snapshot = FALSE;
 	}
 
-	gSnapshot = for_snapshot;
-
 	LLGLSDefault gls_default;
 	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
 	
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index e2791ba128a9f56a4726945538b0205c84724739..5461e0f36228ee1aa192e9ebcee8b80678337381 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -863,8 +863,9 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
 		S32 width = gViewerWindow->getWindowWidthRaw();
 		S32 height = gViewerWindow->getWindowHeightRaw();
 
-		bool render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot");
-		bool render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot");
+		BOOL render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot");
+		BOOL render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot");
+		BOOL render_no_post = gSavedSettings.getBOOL("RenderSnapshotNoPost");
 
 		BOOL high_res = gSavedSettings.getBOOL("HighResSnapshot");
 		if (high_res)
@@ -884,6 +885,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
 									   render_ui,
 									   render_hud,
 									   FALSE,
+									   render_no_post,
 									   LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
 									   high_res ? S32_MAX : MAX_SNAPSHOT_IMAGE_SIZE)) //per side
 		{
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 4a1cf0109e50e41584ef43c6baff2223db14d496..ec6f2c848fd6711bf02f7e84531671a05e711a84 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -93,7 +93,8 @@ S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size
 const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64;
 const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez;
 const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128;
-const S32 DEFAULT_ICON_DIMENTIONS = 32;
+const S32 DEFAULT_ICON_DIMENSIONS = 32;
+const S32 DEFAULT_THUMBNAIL_DIMENSIONS = 256;
 U32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256.
 U32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA;
 bool LLViewerTexture::sFreezeImageUpdates = false;
@@ -665,7 +666,8 @@ void LLViewerTexture::setBoostLevel(S32 level)
 		mBoostLevel = level;
 		if(mBoostLevel != LLViewerTexture::BOOST_NONE && 
 			mBoostLevel != LLViewerTexture::BOOST_SELECTED && 
-			mBoostLevel != LLViewerTexture::BOOST_ICON)
+			mBoostLevel != LLViewerTexture::BOOST_ICON &&
+            mBoostLevel != LLViewerTexture::BOOST_THUMBNAIL)
 		{
 			setNoDelete();		
 		}
@@ -1180,8 +1182,19 @@ void LLViewerFetchedTexture::loadFromFastCache()
             {
                 // Shouldn't do anything usefull since texures in fast cache are 16x16,
                 // it is here in case fast cache changes.
-                S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
-                S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
+                S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS;
+                S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENSIONS;
+                if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
+                {
+                    // scale oversized icon, no need to give more work to gl
+                    mRawImage->scale(expected_width, expected_height);
+                }
+            }
+
+            if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
+            {
+                S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
+                S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
                 if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
                 {
                     // scale oversized icon, no need to give more work to gl
@@ -1682,7 +1695,7 @@ void LLViewerFetchedTexture::processTextureStats()
 		{
 			mDesiredDiscardLevel = 0;
 		}
-        else if (mDontDiscard && mBoostLevel == LLGLTexture::BOOST_ICON)
+        else if (mDontDiscard && (mBoostLevel == LLGLTexture::BOOST_ICON || mBoostLevel == LLGLTexture::BOOST_THUMBNAIL))
         {
             if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
             {
@@ -1916,8 +1929,20 @@ bool LLViewerFetchedTexture::updateFetch()
 
                 if (mBoostLevel == LLGLTexture::BOOST_ICON)
                 {
-                    S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
-                    S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
+                    S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS;
+                    S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENSIONS;
+                    if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
+                    {
+                        // scale oversized icon, no need to give more work to gl
+                        // since we got mRawImage from thread worker and image may be in use (ex: writing cache), make a copy
+                        mRawImage = mRawImage->scaled(expected_width, expected_height);
+                    }
+                }
+
+                if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
+                {
+                    S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
+                    S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
                     if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
                     {
                         // scale oversized icon, no need to give more work to gl
@@ -2652,7 +2677,9 @@ LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level)
 
 	if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level)
 	{
-		if (mSavedRawDiscardLevel != discard_level && mBoostLevel != BOOST_ICON)
+		if (mSavedRawDiscardLevel != discard_level
+            && mBoostLevel != BOOST_ICON
+            && mBoostLevel != BOOST_THUMBNAIL)
 		{
 			mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents());
 			mRawImage->copy(getSavedRawImage());
@@ -2759,8 +2786,22 @@ void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* im
     {
         if (mBoostLevel == LLGLTexture::BOOST_ICON)
         {
-            S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
-            S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
+            S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS;
+            S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENSIONS;
+            if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
+            {
+                mCachedRawImage = new LLImageRaw(expected_width, expected_height, imageraw->getComponents());
+                mCachedRawImage->copyScaled(imageraw);
+            }
+            else
+            {
+                mCachedRawImage = imageraw;
+            }
+        }
+        else if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
+        {
+            S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
+            S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
             if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
             {
                 mCachedRawImage = new LLImageRaw(expected_width, expected_height, imageraw->getComponents());
@@ -2867,8 +2908,22 @@ void LLViewerFetchedTexture::saveRawImage()
 	mSavedRawDiscardLevel = mRawDiscardLevel;
     if (mBoostLevel == LLGLTexture::BOOST_ICON)
     {
-        S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
-        S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
+        S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS;
+        S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENSIONS;
+        if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
+        {
+            mSavedRawImage = new LLImageRaw(expected_width, expected_height, mRawImage->getComponents());
+            mSavedRawImage->copyScaled(mRawImage);
+        }
+        else
+        {
+            mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents());
+        }
+    }
+    else if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
+    {
+        S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
+        S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
         if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
         {
             mSavedRawImage = new LLImageRaw(expected_width, expected_height, mRawImage->getComponents());
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 9ee6f88183fd04c75bbca89dd62ffbfce4460202..f898fb714258f6e119a6edcd79a30748f51f28b2 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -72,7 +72,7 @@ LLViewerTextureList gTextureList;
 
 ETexListType get_element_type(S32 priority)
 {
-    return (priority == LLViewerFetchedTexture::BOOST_ICON) ? TEX_LIST_SCALE : TEX_LIST_STANDARD;
+    return (priority == LLViewerFetchedTexture::BOOST_ICON || priority == LLViewerFetchedTexture::BOOST_THUMBNAIL) ? TEX_LIST_SCALE : TEX_LIST_STANDARD;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -492,7 +492,8 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
 			{
 				imagep->dontDiscard();
 			}
-			if (boost_priority == LLViewerFetchedTexture::BOOST_ICON)
+			if (boost_priority == LLViewerFetchedTexture::BOOST_ICON
+                || boost_priority == LLViewerFetchedTexture::BOOST_THUMBNAIL)
 			{
 				// Agent and group Icons are downloadable content, nothing manages
 				// icon deletion yet, so they should not persist
@@ -604,7 +605,8 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
 		{
 			imagep->dontDiscard();
 		}
-		if (boost_priority == LLViewerFetchedTexture::BOOST_ICON)
+		if (boost_priority == LLViewerFetchedTexture::BOOST_ICON
+            || boost_priority == LLViewerFetchedTexture::BOOST_THUMBNAIL)
 		{
 			// Agent and group Icons are downloadable content, nothing manages
 			// icon deletion yet, so they should not persist.
@@ -1510,8 +1512,9 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
 	LLUIImagePtr new_imagep = new LLUIImage(name, imagep);
 	new_imagep->setScaleStyle(scale_style);
 
-	if (imagep->getBoostLevel() != LLGLTexture::BOOST_ICON &&
-		imagep->getBoostLevel() != LLGLTexture::BOOST_PREVIEW)
+	if (imagep->getBoostLevel() != LLGLTexture::BOOST_ICON
+        && imagep->getBoostLevel() != LLGLTexture::BOOST_THUMBNAIL
+		&& imagep->getBoostLevel() != LLGLTexture::BOOST_PREVIEW)
 	{
 		// Don't add downloadable content into this list
 		// all UI images are non-deletable and list does not support deletion
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ba2b6e1c7cb477c5253b6fb3398ee638e8b02216..ed671fe849bb351a66f6ba3b0ac00dbcf7a9612c 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -229,6 +229,7 @@ extern BOOL gDisplaySwapBuffers;
 extern BOOL gDepthDirty;
 extern BOOL gResizeScreenTexture;
 extern BOOL gCubeSnapshot;
+extern BOOL gSnapshotNoPost;
 
 LLViewerWindow	*gViewerWindow = NULL;
 
@@ -4875,16 +4876,16 @@ void LLViewerWindow::resetSnapshotLoc() const
 	gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string());
 }
 
-BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type)
+BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type)
 {
-	return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, show_hud, do_rebuild, type);
+	return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, show_hud, do_rebuild, no_post, type);
 }
 
 // Saves the image from the screen to a raw image
 // Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy
 // the results over to the final raw image.
 BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, 
-    BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, S32 max_size)
+    BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type, S32 max_size)
 {
 	if (!raw)
 	{
@@ -4901,6 +4902,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 	}
 
 	// PRE SNAPSHOT
+	gSnapshotNoPost = no_post;
 	gDisplaySwapBuffers = FALSE;
 	
     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
@@ -5131,6 +5133,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 	}
 
 	gDisplaySwapBuffers = FALSE;
+	gSnapshotNoPost = FALSE;
 	gDepthDirty = TRUE;
 
 	// POST SNAPSHOT
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 6e8a5b2f4e12718f980406e28a85c2fc21ed701d..ccef006a0709336746892cff142d08c455ebf474 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -362,7 +362,7 @@ class LLViewerWindow : public LLWindowCallbacks
 
 	BOOL			saveSnapshot(const std::string&  filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::ESnapshotFormat format = LLSnapshotModel::SNAPSHOT_FORMAT_BMP);
 	BOOL			rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
-		BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
+		BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, BOOL no_post = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
 
     BOOL			simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes);
 
@@ -380,7 +380,7 @@ class LLViewerWindow : public LLWindowCallbacks
     // special implementation of simpleSnapshot for reflection maps
     BOOL			reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes);
 
-    BOOL			thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
+    BOOL			thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type);
 	BOOL			isSnapshotLocSet() const;
 	void			resetSnapshotLoc() const;
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 7b1e5a55d121efc792f7fe7c11ea3902f9ece9e7..76414b5e4e0bba31ec1ab57bde2bb4f8dcbfd485 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -211,6 +211,7 @@ extern S32 gBoxFrame;
 extern BOOL gDisplaySwapBuffers;
 extern BOOL gDebugGL;
 extern BOOL gCubeSnapshot;
+extern BOOL gSnapshotNoPost;
 
 bool	gAvatarBacklight = false;
 
@@ -6817,7 +6818,7 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
 	{
 		LL_PROFILE_GPU_ZONE("gamma correct");
 
-        static LLCachedControl<bool> no_post(gSavedSettings, "RenderDisablePostProcessing", false);
+        static LLCachedControl<bool> buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false);
 
 		LLGLDepthTest depth(GL_FALSE, GL_FALSE);
 
@@ -6827,7 +6828,8 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
         
         LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
 
-        LLGLSLShader& shader = no_post && gFloaterTools->isAvailable() ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping)
+        bool no_post = gSnapshotNoPost || (buildNoPost && gFloaterTools->isAvailable());
+        LLGLSLShader& shader = no_post ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping)
             psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? gLegacyPostGammaCorrectProgram :
             gDeferredPostGammaCorrectProgram;
         
diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index fcd24d83bb4dc515d0287abecdacac7d361e2b55..1a1131e24c27a22ecad220dd8d9c44770a972313 100644
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -5,7 +5,7 @@
  can_minimize="true"
  can_resize="false"
  can_close="true"
- height="455"
+ height="475"
  layout="topleft"
  name="Snapshot"
  single_instance="true"
@@ -115,7 +115,7 @@
 	   top_delta="0"
        width="31" />
 	<panel
-     height="159"
+     height="179"
      layout="topleft"
 	 follows="top|left"
      left="0"
@@ -193,6 +193,14 @@
          top_pad="1"
          width="180"
          name="auto_snapshot_check" />
+        <check_box
+         label="No post-processing"
+         layout="topleft"
+         height="16"
+         left="10"
+         top_pad="1"
+         width="180"
+         name="no_post_check" />
         <text
          type="string"
          length="1"
@@ -391,8 +399,8 @@
     name="thumbnail_placeholder"
     top="23"
 	left="215"
-	width="400"
-	height="400"
+	width="420"
+	height="420"
     follows="top|left"/>
   <view_border 
    bevel_style="in" 
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 0bfdead6e7866cce629b2c4fbb71c198d1f96272..2c4b03251ae3b4ad373779a31f62bcc25538fa97 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1545,7 +1545,7 @@ function="World.EnvPreset"
         <menu_item_separator/>
           
           <menu_item_check
-            label="No Post"
+            label="No Post-processing"
             name="No Post">
             <menu_item_check.on_check
              control="RenderDisablePostProcessing" />