From f690d8f06fb2a13491048c1354c926c8e01e8e4c Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Sat, 3 Feb 2024 22:39:55 -0500
Subject: [PATCH] Revert "Merge"

This reverts commit 678817626b844fe7a635ca97315ba524487252a6.
---
 indra/newview/CMakeLists.txt               |   2 -
 indra/newview/llfetchedgltfmaterial.cpp    |  52 ++
 indra/newview/llfetchedgltfmaterial.h      |   5 +
 indra/newview/llgltfmaterialpreviewmgr.cpp | 553 ---------------------
 indra/newview/llgltfmaterialpreviewmgr.h   |  82 ---
 indra/newview/lltexturectrl.cpp            |  93 +---
 indra/newview/lltexturectrl.h              |   3 -
 indra/newview/pipeline.cpp                 |   9 +-
 indra/newview/pipeline.h                   |   1 -
 9 files changed, 86 insertions(+), 714 deletions(-)
 delete mode 100644 indra/newview/llgltfmaterialpreviewmgr.cpp
 delete mode 100644 indra/newview/llgltfmaterialpreviewmgr.h

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 0f671d861c1..7976f75778b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -372,7 +372,6 @@ set(viewer_SOURCE_FILES
     llgiveinventory.cpp
     llglsandbox.cpp
     llgltfmateriallist.cpp
-    llgltfmaterialpreviewmgr.cpp
     llgroupactions.cpp
     llgroupiconctrl.cpp
     llgrouplist.cpp
@@ -1105,7 +1104,6 @@ set(viewer_HEADER_FILES
     llgesturemgr.h
     llgiveinventory.h
     llgltfmateriallist.h
-    llgltfmaterialpreviewmgr.h
     llgroupactions.h
     llgroupiconctrl.h
     llgrouplist.h
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index 90ec08391d6..46b9dffae94 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -254,3 +254,55 @@ void LLFetchedGLTFMaterial::materialComplete()
     materialCompleteCallbacks.clear();
     materialCompleteCallbacks.shrink_to_fit();
 }
+
+LLPointer<LLViewerFetchedTexture> LLFetchedGLTFMaterial::getUITexture()
+{
+    if (mFetching)
+    {
+        return nullptr;
+    }
+
+    auto fetch_texture_for_ui = [](LLPointer<LLViewerFetchedTexture>& img, const LLUUID& id)
+    {
+        if (id.notNull())
+        {
+            if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
+            {
+                LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+                if (obj)
+                {
+                    LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id);
+                    img = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
+                }
+
+            }
+            else
+            {
+                img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+            }
+        }
+        if (img)
+        {
+            img->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+            img->forceToSaveRawImage(0);
+        }
+    };
+
+    fetch_texture_for_ui(mBaseColorTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+    fetch_texture_for_ui(mNormalTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
+    fetch_texture_for_ui(mMetallicRoughnessTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
+    fetch_texture_for_ui(mEmissiveTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
+
+    if ((mBaseColorTexture && (mBaseColorTexture->getRawImageLevel() != 0)) ||
+        (mNormalTexture && (mNormalTexture->getRawImageLevel() != 0)) ||
+        (mMetallicRoughnessTexture && (mMetallicRoughnessTexture->getRawImageLevel() != 0)) ||
+        (mEmissiveTexture && (mEmissiveTexture->getRawImageLevel() != 0)))
+    {
+        return nullptr;
+    }
+
+    // *HACK: Use one of the PBR texture components as the preview texture for now
+    mPreviewTexture = mBaseColorTexture;
+
+    return mPreviewTexture;
+}
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
index 2559aa46cc3..a9e539633d1 100644
--- a/indra/newview/llfetchedgltfmaterial.h
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -50,6 +50,8 @@ class LLFetchedGLTFMaterial: public LLGLTFMaterial
 
     bool isFetching() const { return mFetching; }
 
+    LLPointer<LLViewerFetchedTexture> getUITexture();
+
     void addTextureEntry(LLTextureEntry* te) override;
     void removeTextureEntry(LLTextureEntry* te) override;
     virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) override;
@@ -63,6 +65,9 @@ class LLFetchedGLTFMaterial: public LLGLTFMaterial
 
     std::set<LLTextureEntry*> mTextureEntires;
 
+    // Texture used for previewing the material in the UI
+    LLPointer<LLViewerFetchedTexture> mPreviewTexture;
+
 protected:
     // Lifetime management
     
diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp
deleted file mode 100644
index d020f5a2ff8..00000000000
--- a/indra/newview/llgltfmaterialpreviewmgr.cpp
+++ /dev/null
@@ -1,553 +0,0 @@
-/**
- * @file llgltfmaterialpreviewmgr.cpp
- *
- * $LicenseInfo:firstyear=2023&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2023, 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 "llgltfmaterialpreviewmgr.h"
-
-#include <memory>
-#include <vector>
-
-#include "llavatarappearancedefines.h"
-#include "llenvironment.h"
-#include "llselectmgr.h"
-#include "llviewercamera.h"
-#include "llviewerobject.h"
-#include "llviewershadermgr.h"
-#include "llviewertexturelist.h"
-#include "llviewerwindow.h"
-#include "llvolumemgr.h"
-#include "pipeline.h"
-
-LLGLTFMaterialPreviewMgr gGLTFMaterialPreviewMgr;
-
-namespace
-{
-    constexpr S32 FULLY_LOADED = 0;
-    constexpr S32 NOT_LOADED = 99;
-};
-
-LLGLTFPreviewTexture::MaterialLoadLevels::MaterialLoadLevels()
-{
-    for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
-    {
-        levels[i] = NOT_LOADED;
-    }
-}
-
-S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i)
-{
-    llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT);
-    return levels[i];
-}
-
-const S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i) const
-{
-    llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT);
-    return levels[i];
-}
-
-bool LLGLTFPreviewTexture::MaterialLoadLevels::operator<(const MaterialLoadLevels& other) const
-{
-    bool less = false;
-    for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
-    {
-        if (((*this)[i] > other[i])) { return false; }
-        less = less || ((*this)[i] < other[i]);
-    }
-    return less;
-}
-
-bool LLGLTFPreviewTexture::MaterialLoadLevels::operator>(const MaterialLoadLevels& other) const
-{
-    bool great = false;
-    for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
-    {
-        if (((*this)[i] < other[i])) { return false; }
-        great = great || ((*this)[i] > other[i]);
-    }
-    return great;
-}
-
-namespace
-{
-    void fetch_texture_for_ui(LLPointer<LLViewerFetchedTexture>& img, const LLUUID& id)
-    {
-        if (id.notNull())
-        {
-            if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
-            {
-                LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
-                if (obj)
-                {
-                    LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id);
-                    img = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
-                }
-            }
-            else
-            {
-                img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-            }
-        }
-        if (img)
-        {
-            img->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
-            img->forceToSaveRawImage(0);
-        }
-    };
-
-    // *NOTE: Does not use the same conventions as texture discard level. Lower is better.
-    S32 get_texture_load_level(const LLPointer<LLViewerFetchedTexture>& texture)
-    {
-        if (!texture) { return FULLY_LOADED; }
-        const S32 raw_level = texture->getDiscardLevel();
-        if (raw_level < 0) { return NOT_LOADED; }
-        return raw_level;
-    }
-
-    LLGLTFPreviewTexture::MaterialLoadLevels get_material_load_levels(LLFetchedGLTFMaterial& material)
-    {
-        using MaterialTextures = LLPointer<LLViewerFetchedTexture>*[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
-
-        MaterialTextures textures;
-
-        textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = &material.mBaseColorTexture;
-        textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = &material.mNormalTexture;
-        textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = &material.mMetallicRoughnessTexture;
-        textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = &material.mEmissiveTexture;
-
-        LLGLTFPreviewTexture::MaterialLoadLevels levels;
-
-        for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
-        {
-            fetch_texture_for_ui(*textures[i], material.mTextureId[i]);
-            levels[i] = get_texture_load_level(*textures[i]);
-        }
-
-        return levels;
-    }
-
-    // Is the material loaded enough to start rendering a preview?
-    bool is_material_loaded_enough_for_ui(LLFetchedGLTFMaterial& material)
-    {
-        if (material.isFetching())
-        {
-            return false;
-        }
-
-        LLGLTFPreviewTexture::MaterialLoadLevels levels = get_material_load_levels(material);
-
-        for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
-        {
-            if (levels[i] == NOT_LOADED)
-            {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-};  // namespace
-
-LLGLTFPreviewTexture::LLGLTFPreviewTexture(LLPointer<LLFetchedGLTFMaterial> material, S32 width)
-    : LLViewerDynamicTexture(width, width, 4, EOrder::ORDER_MIDDLE, FALSE)
-    , mGLTFMaterial(material)
-{
-}
-
-// static
-LLPointer<LLGLTFPreviewTexture> LLGLTFPreviewTexture::create(LLPointer<LLFetchedGLTFMaterial> material)
-{
-    return new LLGLTFPreviewTexture(material, LLPipeline::MAX_BAKE_WIDTH);
-}
-
-void LLGLTFPreviewTexture::preRender(BOOL clear_depth)
-{
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
-
-    MaterialLoadLevels current_load = get_material_load_levels(*mGLTFMaterial.get());
-    if (current_load < mBestLoad)
-    {
-        mShouldRender = true;
-        mBestLoad = current_load;
-    }
-
-    if (!mShouldRender) { return; }
-
-    LLViewerDynamicTexture::preRender(clear_depth);
-}
-
-
-namespace {
-
-struct GLTFPreviewModel
-{
-    GLTFPreviewModel(LLPointer<LLDrawInfo>& info, const LLMatrix4& mat)
-    : mDrawInfo(info)
-    , mModelMatrix(mat)
-    {
-        mDrawInfo->mModelMatrix = &mModelMatrix;
-    }
-    GLTFPreviewModel(GLTFPreviewModel&) = delete;
-    ~GLTFPreviewModel()
-    {
-        // No model matrix necromancy
-        llassert(gGLLastMatrix != &mModelMatrix);
-        gGLLastMatrix = nullptr;
-    }
-    LLPointer<LLDrawInfo> mDrawInfo;
-    LLMatrix4a mModelMatrix; // Referenced by mDrawInfo
-};
-
-using PreviewSpherePart = std::unique_ptr<GLTFPreviewModel>;
-using PreviewSphere = std::vector<PreviewSpherePart>;
-
-// Like LLVolumeGeometryManager::registerFace but without batching or too-many-indices/vertices checking.
-PreviewSphere create_preview_sphere(LLPointer<LLFetchedGLTFMaterial>& material, const LLMatrix4& model_matrix)
-{
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
-
-    const LLColor4U vertex_color(material->mBaseColor);
-
-    LLPrimitive prim;
-    prim.init_primitive(LL_PCODE_VOLUME);
-    LLVolumeParams params;
-    params.setType(LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE);
-    params.setBeginAndEndS(0.f, 1.f);
-    params.setBeginAndEndT(0.f, 1.f);
-    params.setRatio(1, 1);
-    params.setShear(0, 0);
-    constexpr auto MAX_LOD = LLVolumeLODGroup::NUM_LODS - 1;
-    prim.setVolume(params, MAX_LOD);
-
-    LLVolume* volume = prim.getVolume();
-    llassert(volume);
-    for (LLVolumeFace& face : volume->getVolumeFaces())
-    {
-        face.createTangents();
-    }
-
-    PreviewSphere preview_sphere;
-    preview_sphere.reserve(volume->getNumFaces());
-
-    LLPointer<LLVertexBuffer> buf = new LLVertexBuffer(
-        LLVertexBuffer::MAP_VERTEX |
-        LLVertexBuffer::MAP_NORMAL |
-        LLVertexBuffer::MAP_TEXCOORD0 |
-        LLVertexBuffer::MAP_COLOR |
-        LLVertexBuffer::MAP_TANGENT
-    );
-    U32 nv = 0;
-    U32 ni = 0;
-    for (LLVolumeFace& face : volume->getVolumeFaces())
-    {
-        nv += face.mNumVertices;
-        ni += face.mNumIndices;
-    }
-    buf->allocateBuffer(nv, ni);
-
-    // UV hacks
-    // Higher factor helps to see more details on the preview sphere
-    const LLVector2 uv_factor(2.0f, 2.0f);
-    // Offset places center of material in center of view
-    const LLVector2 uv_offset(-0.5f, -0.5f);
-
-    LLStrider<U16> indices;
-    LLStrider<LLVector4a> positions;
-    LLStrider<LLVector4a> normals;
-    LLStrider<LLVector2> texcoords;
-    LLStrider<LLColor4U> colors;
-    LLStrider<LLVector4a> tangents;
-	buf->getIndexStrider(indices);
-	buf->getVertexStrider(positions);
-	buf->getNormalStrider(normals);
-	buf->getTexCoord0Strider(texcoords);
-	buf->getColorStrider(colors);
-	buf->getTangentStrider(tangents);
-    U32 index_offset = 0;
-    U32 vertex_offset = 0;
-    for (const LLVolumeFace& face : volume->getVolumeFaces())
-    {
-        for (S32 i = 0; i < face.mNumIndices; ++i)
-        {
-            *indices++ = face.mIndices[i] + vertex_offset;
-        }
-        for (S32 v = 0; v < face.mNumVertices; ++v)
-        {
-            *positions++ = face.mPositions[v];
-            *normals++ = face.mNormals[v];
-            LLVector2 uv(face.mTexCoords[v]);
-            uv.scaleVec(uv_factor);
-            uv += uv_offset;
-            *texcoords++ = uv;
-            *colors++ = vertex_color;
-            *tangents++ = face.mTangents[v];
-        }
-
-        constexpr LLViewerTexture* no_media = nullptr;
-        LLPointer<LLDrawInfo> info = new LLDrawInfo(U16(vertex_offset), U16(vertex_offset + face.mNumVertices - 1), face.mNumIndices, index_offset, no_media, buf.get());
-        info->mGLTFMaterial = material;
-        preview_sphere.emplace_back(std::make_unique<GLTFPreviewModel>(info, model_matrix));
-        index_offset += face.mNumIndices;
-        vertex_offset += face.mNumVertices;
-    }
-
-    buf->unmapBuffer();
-
-    return preview_sphere;
-}
-
-void set_preview_sphere_material(PreviewSphere& preview_sphere, LLPointer<LLFetchedGLTFMaterial>& material)
-{
-    llassert(!preview_sphere.empty());
-    if (preview_sphere.empty()) { return; }
-
-    const LLColor4U vertex_color(material->mBaseColor);
-
-    // See comments about unmapBuffer in llvertexbuffer.h
-    for (PreviewSpherePart& part : preview_sphere)
-    {
-        LLDrawInfo* info = part->mDrawInfo.get();
-        info->mGLTFMaterial = material;
-        LLVertexBuffer* buf = info->mVertexBuffer.get();
-        LLStrider<LLColor4U> colors;
-        const S32 count = info->mEnd - info->mStart;
-        buf->getColorStrider(colors, info->mStart, count);
-        for (S32 i = 0; i < count; ++i)
-        {
-            *colors++ = vertex_color;
-        }
-        buf->unmapBuffer();
-    }
-}
-
-PreviewSphere& get_preview_sphere(LLPointer<LLFetchedGLTFMaterial>& material, const LLMatrix4& model_matrix)
-{
-    static PreviewSphere preview_sphere;
-    if (preview_sphere.empty())
-    {
-        preview_sphere = create_preview_sphere(material, model_matrix);
-    }
-    else
-    {
-        set_preview_sphere_material(preview_sphere, material);
-    }
-    return preview_sphere;
-}
-
-// Final, direct modifications to shader constants, just before render
-void fixup_shader_constants(LLGLSLShader& shader)
-{
-    // Sunlight intensity of 0 no matter what
-    shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, 1);
-    shader.uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, 1, LLColor3::white.mV);
-    shader.uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, 0.0f);
-
-    // Ignore sun shadow (if enabled)
-    for (U32 i = 0; i < 6; i++)
-    {
-        const S32 channel = shader.getTextureChannel(LLShaderMgr::DEFERRED_SHADOW0+i);
-        if (channel != -1)
-        {
-            gGL.getTexUnit(channel)->bind(LLViewerFetchedTexture::sWhiteImagep, TRUE);
-        }
-    }
-}
-
-// Set a variable to a value temporarily, and restor the variable's old value
-// when this object leaves scope.
-template<typename T>
-struct SetTemporarily
-{
-    T* mRef;
-    T mOldVal;
-    SetTemporarily(T* var, T temp_val)
-    {
-        mRef = var;
-        mOldVal = *mRef;
-        *mRef = temp_val;
-    }
-    ~SetTemporarily()
-    {
-        *mRef = mOldVal;
-    }
-};
-
-}; // namespace
-
-BOOL LLGLTFPreviewTexture::render()
-{
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
-
-    if (!mShouldRender) { return FALSE; }
-
-    glClearColor(0, 0, 0, 0);
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-    
-    LLGLDepthTest(GL_FALSE);
-    LLGLDisable stencil(GL_STENCIL_TEST);
-    LLGLDisable scissor(GL_SCISSOR_TEST);
-    SetTemporarily<bool> no_dof(&LLPipeline::RenderDepthOfField, false);
-    SetTemporarily<bool> no_glow(&LLPipeline::sRenderGlow, false);
-    SetTemporarily<bool> no_ssr(&LLPipeline::RenderScreenSpaceReflections, false);
-    SetTemporarily<U32> no_fxaa(&LLPipeline::RenderFSAASamples, U32(0));
-    SetTemporarily<LLPipeline::RenderTargetPack*> use_auxiliary_render_target(&gPipeline.mRT, &gPipeline.mAuxillaryRT);
-
-    const LLVector4a light_dir(1.0f, 1.0f, 1.0f, 0.f);
-    SetTemporarily<S32> sun_light_only(&LLPipeline::RenderLocalLightCount, 0);
-
-    gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms();
-
-    LLViewerCamera camera;
-
-    // Calculate the object distance at which the object of a given radius will
-    // span the partial width of the screen given by fill_ratio.
-    // Assume the primitive has a scale of 1 (this is the default).
-    constexpr F32 fill_ratio = 0.8f;
-    constexpr F32 object_radius = 0.5f;
-    const F32 object_distance = (object_radius / fill_ratio) * tan(camera.getDefaultFOV());
-    // Negative coordinate shows the textures on the sphere right-side up, when
-    // combined with the UV hacks in create_preview_sphere
-    const LLVector3 object_position(0.0, -object_distance, 0.0);
-    LLMatrix4 object_transform;
-    object_transform.translate(object_position);
-
-    // Set up camera and viewport
-    const LLVector3 origin(0.0, 0.0, 0.0);
-    camera.lookAt(origin, object_position);
-    camera.setAspect(mFullHeight / mFullWidth);
-    const LLRect texture_rect(0, mFullHeight, mFullWidth, 0);
-    camera.setPerspective(NOT_FOR_SELECTION, texture_rect.mLeft, texture_rect.mBottom, texture_rect.getWidth(), texture_rect.getHeight(), FALSE, camera.getNear(), MAX_FAR_CLIP*2.f);
-
-    // Generate sphere object on-the-fly. Discard afterwards. (Vertex buffer is
-    // discarded, but the sphere should be cached in LLVolumeMgr.)
-    PreviewSphere& preview_sphere = get_preview_sphere(mGLTFMaterial, object_transform);
-
-    gPipeline.setupHWLights();
-    const LLMatrix4a& mat = gGLModelView;
-    LLVector4a transformed_light_dir;
-    mat.rotate4(light_dir, transformed_light_dir);
-    SetTemporarily<LLVector4a> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, transformed_light_dir);
-    // Override lights to ensure the sun is always shining from a certain direction (low graphics)
-    // See also force_sun_direction_high_graphics and fixup_shader_constants
-    {
-        LLLightState* light = gGL.getLight(0);
-        light->setPosition(LLVector4(light_dir.getF32ptr()));
-        constexpr bool sun_up = true;
-        light->setSunPrimary(sun_up);
-    }
-
-    LLRenderTarget& screen = gPipeline.mAuxillaryRT.screen;
-
-    // *HACK: Force reset of the model matrix
-    gGLLastMatrix = nullptr;
-
-#if 0
-    if (mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_OPAQUE || mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
-    {
-        // *TODO: Opaque/alpha mask rendering
-    }
-    else
-#endif
-    {
-        // Alpha blend rendering
-
-        screen.bindTarget();
-        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-        LLGLSLShader& shader = gDeferredPBRAlphaProgram;
-
-        gPipeline.bindDeferredShader(shader);
-        fixup_shader_constants(shader);
-
-        for (PreviewSpherePart& part : preview_sphere)
-        {
-            LLRenderPass::pushGLTFBatch(*part->mDrawInfo);
-        }
-
-        gPipeline.unbindDeferredShader(shader);
-
-        screen.flush();
-    }
-
-    gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap);
-    gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap);
-    gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap);
-    gPipeline.gammaCorrect(&screen, &gPipeline.mPostMap);
-    LLVertexBuffer::unbind();
-    gPipeline.generateGlow(&gPipeline.mPostMap);
-    gPipeline.combineGlow(&gPipeline.mPostMap, &screen);
-	gPipeline.renderDoF(&screen, &gPipeline.mPostMap);
-	gPipeline.applyFXAA(&gPipeline.mPostMap, &screen);
-
-    // Final render
-
-	gDeferredPostNoDoFProgram.bind();
-
-	// From LLPipeline::renderFinalize: "Whatever is last in the above post processing chain should _always_ be rendered directly here.  If not, expect problems."
-	gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &screen);
-	gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, mBoundTarget, true);
-
-	{
-		LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
-		gPipeline.mScreenTriangleVB->setBuffer();
-		gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-	}
-
-	gDeferredPostNoDoFProgram.unbind();
-
-    // Clean up
-    gPipeline.setupHWLights();
-    gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms(false);
-
-    return TRUE;
-}
-
-void LLGLTFPreviewTexture::postRender(BOOL success)
-{
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
-
-    if (!mShouldRender) { return; }
-    mShouldRender = false;
-
-    LLViewerDynamicTexture::postRender(success);
-}
-
-// static
-LLPointer<LLViewerTexture> LLGLTFMaterialPreviewMgr::getPreview(LLPointer<LLFetchedGLTFMaterial> &material)
-{
-    if (!material)
-    {
-        return nullptr;
-    }
-
-    if (!is_material_loaded_enough_for_ui(*material))
-    {
-        return nullptr;
-    }
-
-    return LLGLTFPreviewTexture::create(material);
-}
diff --git a/indra/newview/llgltfmaterialpreviewmgr.h b/indra/newview/llgltfmaterialpreviewmgr.h
deleted file mode 100644
index cc40a6f2e2a..00000000000
--- a/indra/newview/llgltfmaterialpreviewmgr.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * @file llgltfmaterialpreviewmgr.h
- *
- * $LicenseInfo:firstyear=2023&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2023, 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$
- */
-
-#pragma once
-
-#include "lldrawpool.h"
-#include "lldynamictexture.h"
-#include "llfetchedgltfmaterial.h"
-#include "llsingleton.h"
-#include "lltexture.h"
-
-class LLGLTFPreviewTexture : public LLViewerDynamicTexture
-{
-protected:
-    LLGLTFPreviewTexture(LLPointer<LLFetchedGLTFMaterial> material, S32 width);
-
-public:
-    // Width scales with size of material's textures
-    static LLPointer<LLGLTFPreviewTexture> create(LLPointer<LLFetchedGLTFMaterial> material);
-
-    BOOL needsRender() override { return mNeedsRender; }
-    void preRender(BOOL clear_depth = TRUE) override;
-    BOOL render() override;
-    void postRender(BOOL success) override;
-
-    struct MaterialLoadLevels
-    {
-        S32 levels[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
-
-        MaterialLoadLevels();
-
-        S32& operator[](size_t i);
-
-        const S32& operator[](size_t i) const;
-
-        // Less is better
-        // Returns false if lhs is not strictly less or equal for all levels
-        bool operator<(const MaterialLoadLevels& other) const;
-
-        // Less is better
-        // Returns false if lhs is not strictly greater or equal for all levels
-        bool operator>(const MaterialLoadLevels& other) const;
-    };
-
-private:
-    LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
-    bool mNeedsRender = true;
-    bool mShouldRender = true;
-    MaterialLoadLevels mBestLoad;
-};
-
-class LLGLTFMaterialPreviewMgr
-{
-  public:
-    // Returns null if the material is not loaded yet.
-    // *NOTE: User should cache the texture if the same material is being previewed
-    LLPointer<LLViewerTexture> getPreview(LLPointer<LLFetchedGLTFMaterial> &material);
-};
-
-extern LLGLTFMaterialPreviewMgr gGLTFMaterialPreviewMgr;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 598cf299f56..c52e57ec3fc 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -63,7 +63,6 @@
 
 #include "llradiogroup.h"
 #include "llfloaterreg.h"
-#include "llgltfmaterialpreviewmgr.h"
 #include "lllocalgltfmaterials.h"
 #include "llerror.h"
 
@@ -664,7 +663,6 @@ void LLFloaterTexturePicker::draw()
 	if( mOwner ) 
 	{
 		mTexturep = NULL;
-        LLPointer<LLFetchedGLTFMaterial> old_material = mGLTFMaterial;
         mGLTFMaterial = NULL;
         if (mImageAssetID.notNull())
         {
@@ -672,23 +670,10 @@ void LLFloaterTexturePicker::draw()
             {
                 mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID);
                 llassert(mGLTFMaterial == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr);
-                if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (*old_material.get() != *mGLTFMaterial.get())))
-                {
-                    // Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview.
-                    if (mGLTFMaterial.isNull())
-                    {
-                        mGLTFPreview = nullptr;
-                    }
-                    else
-                    {
-                        mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial);
-                    }
-                }
             }
             else
             {
                 LLPointer<LLViewerFetchedTexture> texture = NULL;
-                mGLTFPreview = nullptr;
 
                 if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
                 {
@@ -698,7 +683,7 @@ void LLFloaterTexturePicker::draw()
                     if (obj)
                     {
                         LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID);
-						texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
+                        texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
                     }
                 }
 
@@ -740,29 +725,27 @@ void LLFloaterTexturePicker::draw()
 
 		// If the floater is focused, don't apply its alpha to the texture (STORM-677).
 		const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
-        LLViewerTexture* preview = nullptr;
+        LLViewerTexture* texture = nullptr;
         if (mGLTFMaterial)
         {
-            preview = mGLTFPreview.get();
+            texture = mGLTFMaterial->getUITexture();
         }
         else
         {
-            preview = mTexturep.get();
-            if (mTexturep)
-            {
-                // Pump the priority
-				mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
-            }
+            texture = mTexturep.get();
         }
 
-		if( preview )
+		if( texture )
 		{
-			if( preview->getComponents() == 4 )
+			if( texture->getComponents() == 4 )
 			{
 				gl_rect_2d_checkerboard( interior, alpha );
 			}
 
-			gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha );
+			gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), texture, UI_VERTEX_COLOR % alpha );
+
+			// Pump the priority
+			texture->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
 		}
 		else if (!mFallbackImage.isNull())
 		{
@@ -2210,69 +2193,48 @@ void LLTextureCtrl::draw()
 {
 	mBorder->setKeyboardFocusHighlight(hasFocus());
 
-    LLPointer<LLViewerTexture> preview = NULL;
-
 	if (!mValid)
 	{
 		mTexturep = NULL;
-        mGLTFMaterial = NULL;
-        mGLTFPreview = NULL;
 	}
 	else if (!mImageAssetID.isNull())
 	{
+		LLPointer<LLViewerFetchedTexture> texture = NULL;
+
 		if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
 		{
 			LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
 			if (obj)
 			{
 				LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID);
-				mTexturep = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
-				mGLTFMaterial = NULL;
-				mGLTFPreview = NULL;
-
-                preview = mTexturep;
+				texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
 			}
 			
 		}
 
-		if (preview.isNull())
+		if (texture.isNull())
 		{
-            LLPointer<LLFetchedGLTFMaterial> old_material = mGLTFMaterial;
-            mGLTFMaterial = NULL;
-            mTexturep = NULL;
             if (mInventoryPickType == PICK_MATERIAL)
             {
-                mGLTFMaterial = gGLTFMaterialList.getMaterial(mImageAssetID);
-                if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (*old_material.get() != *mGLTFMaterial.get())))
+                LLPointer<LLFetchedGLTFMaterial> material = gGLTFMaterialList.getMaterial(mImageAssetID);
+                if (material)
                 {
-                    // Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview.
-                    if (mGLTFMaterial.isNull())
-                    {
-                        mGLTFPreview = nullptr;
-                    }
-                    else
-                    {
-                        mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial);
-                    }
+                    texture = material->getUITexture();
                 }
-
-                preview = mGLTFPreview;
             }
             else
             {
-				mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-				mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
-				mTexturep->forceToSaveRawImage(0);
-
-				preview = mTexturep;
+                texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+                texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+                texture->forceToSaveRawImage(0);
             }
 		}
+
+		mTexturep = texture;
 	}
 	else//mImageAssetID == LLUUID::null
 	{
 		mTexturep = NULL; 
-        mGLTFMaterial = NULL;
-        mGLTFPreview = NULL;
 	}
 	
 	// Border
@@ -2285,18 +2247,15 @@ void LLTextureCtrl::draw()
 
 	// If we're in a focused floater, don't apply the floater's alpha to the texture (STORM-677).
 	const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
-	if( preview )
+	if( mTexturep )
 	{
-		if( preview->getComponents() == 4 )
+		if( mTexturep->getComponents() == 4 )
 		{
 			gl_rect_2d_checkerboard( interior, alpha );
 		}
 		
-		gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha);
-        if (mTexturep)
-        {
-            mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
-        }
+		gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha);
+		mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
 	}
 	else if (!mFallbackImage.isNull())
 	{
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index aba1df8c9bb..1e3792c69a0 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -252,8 +252,6 @@ class LLTextureCtrl
 	commit_callback_t		 	mOnCloseCallback;
 	texture_selected_callback	mOnTextureSelectedCallback;
 	LLPointer<LLViewerFetchedTexture> mTexturep;
-	LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
-	LLPointer<LLViewerTexture> mGLTFPreview;
 	LLUIColor				 	mBorderColor;
 	LLUUID					 	mImageItemID;
 	LLUUID					 	mImageAssetID;
@@ -391,7 +389,6 @@ class LLFloaterTexturePicker final : public LLFloater
 
 	LLPointer<LLViewerTexture> mTexturep;
     LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
-    LLPointer<LLViewerTexture> mGLTFPreview;
 	LLView*				mOwner;
 
 	LLUUID				mImageAssetID; // Currently selected texture
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 64d1956b85d..6120253a7f5 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -179,7 +179,6 @@ F32 LLPipeline::CameraFocusTransitionTime;
 F32 LLPipeline::CameraFNumber;
 F32 LLPipeline::CameraFocalLength;
 F32 LLPipeline::CameraFieldOfView;
-S32 LLPipeline::RenderLocalLightCount;
 F32 LLPipeline::RenderShadowNoise;
 F32 LLPipeline::RenderShadowBlurSize;
 F32 LLPipeline::RenderSSAOScale;
@@ -550,7 +549,6 @@ void LLPipeline::init()
 	connectRefreshCachedSettingsSafe("CameraFNumber");
 	connectRefreshCachedSettingsSafe("CameraFocalLength");
 	connectRefreshCachedSettingsSafe("CameraFieldOfView");
-	connectRefreshCachedSettingsSafe("RenderLocalLightCount");
 	connectRefreshCachedSettingsSafe("RenderShadowNoise");
 	connectRefreshCachedSettingsSafe("RenderShadowBlurSize");
 	connectRefreshCachedSettingsSafe("RenderSSAOScale");
@@ -1091,7 +1089,6 @@ void LLPipeline::refreshCachedSettings()
 	CameraFNumber = gSavedSettings.getF32("CameraFNumber");
 	CameraFocalLength = gSavedSettings.getF32("CameraFocalLength");
 	CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView");
-	RenderLocalLightCount = gSavedSettings.getS32("RenderLocalLightCount");
 	RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise");
 	RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize");
 	RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale");
@@ -5366,7 +5363,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 		return;
 	}
 
-    const S32 local_light_count = LLPipeline::RenderLocalLightCount;
+    static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
 
 	if (local_light_count >= 1)
 	{
@@ -5633,7 +5630,7 @@ void LLPipeline::setupHWLights()
 
 	mLightMovingMask = 0;
 	
-    const S32 local_light_count = LLPipeline::RenderLocalLightCount;
+    static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
 
 	if (local_light_count >= 1)
 	{
@@ -8019,7 +8016,7 @@ void LLPipeline::renderDeferredLighting()
             unbindDeferredShader(soften_shader);
         }
 
-        const S32 local_light_count = LLPipeline::RenderLocalLightCount;
+        static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
 
         if (local_light_count > 0)
         {
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 76b1ba11efc..f56a3872621 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -1007,7 +1007,6 @@ class LLPipeline
 	static F32 CameraFNumber;
 	static F32 CameraFocalLength;
 	static F32 CameraFieldOfView;
-	static S32 RenderLocalLightCount;
 	static F32 RenderShadowNoise;
 	static F32 RenderShadowBlurSize;
 	static F32 RenderSSAOScale;
-- 
GitLab