diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 04dd971dee3a5cc289a4e9b85591df1be89ff3bb..1ecf71cf57738773226e9bc50011a76cb451c17d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -301,6 +301,7 @@ set(viewer_SOURCE_FILES
     llfloaterpreference.cpp
     llfloaterpreferenceviewadvanced.cpp
     llfloaterpreviewtrash.cpp
+    llfloaterprofiletexture.cpp
     llfloaterproperties.cpp
     llfloaterregiondebugconsole.cpp
     llfloaterregioninfo.cpp
@@ -942,6 +943,7 @@ set(viewer_HEADER_FILES
     llfloaterpreference.h
     llfloaterpreferenceviewadvanced.h
     llfloaterpreviewtrash.h
+    llfloaterprofiletexture.h
     llfloaterproperties.h
     llfloaterregiondebugconsole.h
     llfloaterregioninfo.h
diff --git a/indra/newview/llfloaterprofiletexture.cpp b/indra/newview/llfloaterprofiletexture.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ddd7dfc6b16c1a4e35fa3e18b6729ea96004880
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.cpp
@@ -0,0 +1,211 @@
+/** 
+ * @file llfloaterprofiletexture.cpp
+ * @brief LLFloaterProfileTexture class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterprofiletexture.h"
+
+#include "llbutton.h"
+#include "llfloaterreg.h"
+#include "llpreview.h" // fors constants
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "lltextureview.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+
+
+const S32 CLIENT_RECT_VPAD = 4;
+const F32 PREVIEW_TEXTURE_MAX_ASPECT = 20.f;
+const F32 PREVIEW_TEXTURE_MIN_ASPECT = 0.5f;
+
+
+LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner)
+    : LLFloater(LLSD())
+    , mUpdateDimensions(TRUE)
+    , mLastHeight(0)
+    , mLastWidth(0)
+    , mImage(NULL)
+    , mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
+    , mOwnerHandle(owner->getHandle())
+{
+    buildFromFile("floater_profile_texture.xml");
+}
+
+LLFloaterProfileTexture::~LLFloaterProfileTexture()
+{
+    if (mImage.notNull())
+    {
+        mImage->setBoostLevel(mImageOldBoostLevel);
+        mImage = NULL;
+    }
+}
+
+// virtual
+BOOL LLFloaterProfileTexture::postBuild()
+{
+    pProfileIcon = getChild<LLIconCtrl>("profile_pic");
+
+    getChild<LLButton>("close_btn")->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr);
+
+	return TRUE;
+}
+
+// virtual
+void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+	LLFloater::reshape(width, height, called_from_parent);
+}
+
+// It takes a while until we get height and width information.
+// When we receive it, reshape the window accordingly.
+void LLFloaterProfileTexture::updateDimensions()
+{
+    if (mImage.isNull())
+    {
+        return;
+    }
+    if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+    {
+        return;
+    }
+
+    S32 img_width = mImage->getFullWidth();
+    S32 img_height = mImage->getFullHeight();
+
+    if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED
+        || mLastWidth != img_width
+        || mLastHeight != img_height)
+    {
+        mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+        // Asset has been fully loaded
+        mUpdateDimensions = TRUE;
+    }
+
+    mLastHeight = img_height;
+    mLastWidth = img_width;
+
+    // Reshape the floater only when required
+    if (mUpdateDimensions)
+    {
+        mUpdateDimensions = FALSE;
+
+        LLRect old_floater_rect = getRect();
+        LLRect old_image_rect = pProfileIcon->getRect();
+        S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth;
+        S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight;
+
+        //reshape floater
+        reshape(width, height);
+
+        gFloaterView->adjustToFitScreen(this, FALSE);
+    }
+}
+
+void LLFloaterProfileTexture::draw()
+{
+    // drawFrustum
+    LLView *owner = mOwnerHandle.get();
+    static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+    drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+
+    LLFloater::draw();
+}
+
+void LLFloaterProfileTexture::resetAsset()
+{
+    pProfileIcon->setValue("Generic_Person_Large");
+    mImageID = LLUUID::null;
+    if (mImage.notNull())
+    {
+        mImage->setBoostLevel(mImageOldBoostLevel);
+        mImage = NULL;
+    }
+}
+void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id)
+{
+    if (mImageID != image_id)
+    {
+        if (mImage.notNull())
+        {
+            mImage->setBoostLevel(mImageOldBoostLevel);
+            mImage = NULL;
+        }
+    }
+    else
+    {
+        return;
+    }
+
+    pProfileIcon->setValue(image_id);
+    mImageID = image_id;
+    mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+    mImageOldBoostLevel = mImage->getBoostLevel();
+
+    if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+    {
+        mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded,
+            0, TRUE, FALSE, new LLHandle<LLFloater>(getHandle()), &mCallbackTextureList);
+
+        mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+        mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING;
+    }
+    else
+    {
+        mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+    }
+
+    mUpdateDimensions = TRUE;
+    updateDimensions();
+}
+
+// static
+void LLFloaterProfileTexture::onTextureLoaded(
+    BOOL success,
+    LLViewerFetchedTexture *src_vi,
+    LLImageRaw* src,
+    LLImageRaw* aux_src,
+    S32 discard_level,
+    BOOL final,
+    void* userdata)
+{
+    LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata;
+
+    if (!handle->isDead())
+    {
+        LLFloaterProfileTexture* floater = static_cast<LLFloaterProfileTexture*>(handle->get());
+        if (floater && success)
+        {
+            floater->mUpdateDimensions = TRUE;
+            floater->updateDimensions();
+        }
+    }
+
+    if (final || !success)
+    {
+        delete handle;
+    }
+}
diff --git a/indra/newview/llfloaterprofiletexture.h b/indra/newview/llfloaterprofiletexture.h
new file mode 100644
index 0000000000000000000000000000000000000000..84ff4ecb16a914039fefde782cc261259c256bdb
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.h
@@ -0,0 +1,78 @@
+/** 
+ * @file llfloaterprofiletexture.h
+ * @brief LLFloaterProfileTexture class definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERPROFILETEXTURE_H
+#define LL_LLFLOATERPROFILETEXTURE_H
+
+#include "llfloater.h"
+#include "llviewertexture.h"
+
+class LLImageRaw;
+class LLIconCtrl;
+
+class LLFloaterProfileTexture : public LLFloater
+{
+public:
+    LLFloaterProfileTexture(LLView* owner);
+    ~LLFloaterProfileTexture();
+
+    virtual void		draw();
+
+    void resetAsset();
+    void loadAsset(const LLUUID &image_id);
+
+
+    static void onTextureLoaded(
+        BOOL success,
+        LLViewerFetchedTexture *src_vi,
+        LLImageRaw* src,
+        LLImageRaw* aux_src,
+        S32 discard_level,
+        BOOL final,
+        void* userdata);
+
+    virtual void		reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+protected:
+    /* virtual */ BOOL	postBuild();
+
+private:
+    void				updateDimensions();
+
+    LLUUID mImageID;
+    LLPointer<LLViewerFetchedTexture> mImage;
+    S32 mImageOldBoostLevel;
+    S32 mAssetStatus;
+    F32 mContextConeOpacity;
+    S32 mLastHeight;
+    S32 mLastWidth;
+    BOOL mUpdateDimensions;
+
+    LLHandle<LLView> mOwnerHandle;
+    LLIconCtrl* pProfileIcon;
+
+    LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
+};
+#endif  // LL_LLFLOATERPROFILETEXTURE_H
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 1542c425ced550a84329f6c8add69986887c8183..441a69bc5df94c139600494f3c9a8c8c1da579b3 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -59,6 +59,7 @@
 #include "llavatarpropertiesprocessor.h"
 #include "llcallingcard.h"
 #include "llcommandhandler.h"
+#include "llfloaterprofiletexture.h"
 #include "llfloaterreg.h"
 #include "llfilepicker.h"
 #include "llfirstuse.h"
@@ -884,6 +885,7 @@ BOOL LLPanelProfileSecondLife::postBuild()
     mCantSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
     mCanEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
     mCantEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+    mSecondLifePic->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentProfileTexture(); });
 
     return TRUE;
 }
@@ -1075,6 +1077,20 @@ void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset
             FALSE);
     }
 
+    LLFloater *floater = mFloaterProfileTextureHandle.get();
+    if (floater)
+    {
+        LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+        if (mImageId.notNull())
+        {
+            texture_view->loadAsset(mImageId);
+        }
+        else
+        {
+            texture_view->resetAsset();
+        }
+    }
+
     setProfileImageUploading(false);
 }
 
@@ -1529,6 +1545,13 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata)
 
             mSecondLifePic->setValue("Generic_Person_Large");
             mImageId = LLUUID::null;
+
+            LLFloater *floater = mFloaterProfileTextureHandle.get();
+            if (floater)
+            {
+                LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+                texture_view->resetAsset();
+            }
         }
         else
         {
@@ -1718,6 +1741,51 @@ void LLPanelProfileSecondLife::onShowAgentPermissionsDialog()
     }
 }
 
+void LLPanelProfileSecondLife::onShowAgentProfileTexture()
+{
+    if (!getIsLoaded())
+    {
+        return;
+    }
+
+    LLFloater *floater = mFloaterProfileTextureHandle.get();
+    if (!floater)
+    {
+        LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+        if (parent_floater)
+        {
+            LLFloaterProfileTexture * texture_view = new LLFloaterProfileTexture(parent_floater);
+            mFloaterProfileTextureHandle = texture_view->getHandle();
+            if (mImageId.notNull())
+            {
+                texture_view->loadAsset(mImageId);
+            }
+            else
+            {
+                texture_view->resetAsset();
+            }
+            texture_view->openFloater();
+            texture_view->setVisibleAndFrontmost(TRUE);
+
+            parent_floater->addDependentFloater(mFloaterProfileTextureHandle);
+        }
+    }
+    else // already open
+    {
+        LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+        texture_view->setMinimized(FALSE);
+        texture_view->setVisibleAndFrontmost(TRUE);
+        if (mImageId.notNull())
+        {
+            texture_view->loadAsset(mImageId);
+        }
+        else
+        {
+            texture_view->resetAsset();
+        }
+    }
+}
+
 void LLPanelProfileSecondLife::onOpenNotes()
 {
     LLFloater* parent_floater = gFloaterView->getParentFloater(this);
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index 549e84b1fa0f4f438a5fcab58670c70030d77296..4de5f274d8b65569db494f1d6cb1c99c060ac595 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -180,6 +180,7 @@ class LLPanelProfileSecondLife
     void onSaveDescriptionChanges();
     void onDiscardDescriptionChanges();
     void onShowAgentPermissionsDialog();
+    void onShowAgentProfileTexture();
     void onOpenNotes();
 
 private:
@@ -203,6 +204,7 @@ class LLPanelProfileSecondLife
     LLIconCtrl*			mCantEditObjectsIcon;
 
     LLHandle<LLFloater>	mFloaterPermissionsHandle;
+    LLHandle<LLFloater>	mFloaterProfileTextureHandle;
 
     bool				mHasUnsavedDescriptionChanges;
 	bool				mVoiceStatus;
diff --git a/indra/newview/skins/default/xui/en/floater_profile_texture.xml b/indra/newview/skins/default/xui/en/floater_profile_texture.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3b351a332525b541868ca9bd50769166dbb369b5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile_texture.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="false"
+ show_title="false"
+ can_minimize="false"
+ can_close="false"
+ header_height="10"
+ height="223"
+ width="200"
+ layout="topleft"
+ min_height="128"
+ min_width="128"
+ name="profile_texture">
+    <layout_stack
+     name="preview_stack"
+     top="0"
+     left="0"
+     right="-1"
+     bottom="-1"
+     follows="all"
+     orientation="vertical"
+     layout="topleft"
+     animate="false">
+      <layout_panel
+        name="texture_panel"
+        height="196"
+        follows="left|top"
+        auto_resize="true"
+        layout="topleft">
+        <icon
+         name="profile_pic"
+         image_name="Generic_Person_Large"
+         layout="topleft"
+         follows="all"
+         top="5"
+         left="5"
+         bottom="-1"
+         right="-5"/>
+      </layout_panel>
+      <layout_panel
+        name="buttons_panel"
+        height="26"
+        auto_resize="false"
+        layout="topleft">
+        <layout_stack
+         name="buttons_stack"
+         top="0"
+         left="0"
+         right="-1"
+         bottom="-1"
+         follows="all"
+         orientation="horizontal"
+         layout="topleft"
+         animate="false">
+          <layout_panel
+           follows="all"
+           layout="topleft"
+           name="resizer_left"
+           auto_resize="true"
+           width="1">
+          </layout_panel>
+          <layout_panel
+           follows="all"
+           layout="topleft"
+           name="close_panel"
+           auto_resize="false"
+           width="112">
+            <button
+             follows="top|left"
+             height="22"
+             label="Close"
+             layout="topleft"
+             left="1"
+             top="0"
+             width="110"
+             name="close_btn"/>
+          </layout_panel>
+          <layout_panel
+           follows="all"
+           layout="topleft"
+           name="resizer_right"
+           auto_resize="true"
+           width="1">
+          </layout_panel>
+        </layout_stack>
+      </layout_panel>
+    </layout_stack>
+</floater>