summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcosmic-linden <111533034+cosmic-linden@users.noreply.github.com>2024-04-26 09:27:27 -0700
committerGitHub <noreply@github.com>2024-04-26 09:27:27 -0700
commit6f51d909a2cd4fd5d875cf255f5379bc5c1984d2 (patch)
tree385c08e9692d8350521996178cf9d05d69d70cf4
parent86c0c1d5536897c925f4e8aa2859a160313d964c (diff)
parent668c63c2c4e2d9757ccaebbfea5f99264b7352c2 (diff)
Merge pull request #1337 from secondlife/v-1184
Cached minimap textures still using extra memory/loading still not reliable
-rw-r--r--indra/llimage/llimage.cpp67
-rw-r--r--indra/llimage/llimage.h6
-rw-r--r--indra/llrender/llgltexture.cpp3
-rw-r--r--indra/llrender/llgltexture.h3
-rw-r--r--indra/newview/lldrawpoolterrain.cpp36
-rw-r--r--indra/newview/llviewertexture.h2
-rw-r--r--indra/newview/llvlcomposition.cpp283
-rw-r--r--indra/newview/llvlcomposition.h8
8 files changed, 268 insertions, 140 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 91a66082bf..ed8f36286f 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -1874,6 +1874,73 @@ void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S3
}
}
+
+void LLImageRaw::addEmissive(LLImageRaw* src)
+{
+ LLImageRaw* dst = this; // Just for clarity.
+
+ if (!validateSrcAndDst(__FUNCTION__, src, dst))
+ {
+ return;
+ }
+
+ llassert((3 == src->getComponents()) || (4 == src->getComponents()));
+ llassert(3 == dst->getComponents());
+
+ if( 3 == dst->getComponents() )
+ {
+ if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
+ {
+ addEmissiveUnscaled(src);
+ }
+ else
+ {
+ addEmissiveScaled(src);
+ }
+ }
+}
+
+void LLImageRaw::addEmissiveUnscaled(LLImageRaw* src)
+{
+ LLImageRaw* dst = this; // Just for clarity.
+
+ llassert((3 == src->getComponents()) || (4 == src->getComponents()));
+ llassert((3 == dst->getComponents()) || (4 == dst->getComponents()));
+ llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+
+ U8* const src_data = src->getData();
+ U8* const dst_data = dst->getData();
+ for(S32 y = 0; y < dst->getHeight(); ++y)
+ {
+ const S32 src_row_offset = src->getComponents() * src->getWidth() * y;
+ const S32 dst_row_offset = dst->getComponents() * dst->getWidth() * y;
+ for (S32 x = 0; x < dst->getWidth(); ++x)
+ {
+ const S32 src_offset = src_row_offset + (x * src->getComponents());
+ const S32 dst_offset = dst_row_offset + (x * dst->getComponents());
+ U8* const src_pixel = src_data + src_offset;
+ U8* const dst_pixel = dst_data + dst_offset;
+ dst_pixel[0] = llmin(255, dst_pixel[0] + src_pixel[0]);
+ dst_pixel[1] = llmin(255, dst_pixel[1] + src_pixel[1]);
+ dst_pixel[2] = llmin(255, dst_pixel[2] + src_pixel[2]);
+ }
+ }
+}
+
+void LLImageRaw::addEmissiveScaled(LLImageRaw* src)
+{
+ LLImageRaw* dst = this; // Just for clarity.
+
+ llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
+
+ LLImageRaw temp(dst->getWidth(), dst->getHeight(), dst->getComponents());
+ llassert_always(temp.getDataSize() > 0);
+ temp.copyScaled(src);
+
+ dst->addEmissiveUnscaled(&temp);
+}
+
+
bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst)
{
if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid())
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 93b58b2356..c49184e338 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -276,6 +276,12 @@ public:
// Src and dst are same size. Src has 4 components. Dst has 3 components.
void compositeUnscaled4onto3( LLImageRaw* src );
+ // Emissive operations used by minimap
+ // Roughly emulates GLTF emissive texture, but is not GLTF-compliant
+ // *TODO: Remove in favor of shader
+ void addEmissive(LLImageRaw* src);
+ void addEmissiveScaled(LLImageRaw* src);
+ void addEmissiveUnscaled(LLImageRaw* src);
protected:
// Create an image from a local file (generally used in tools)
//bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false);
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index b616002b49..a590a8e745 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -95,7 +95,8 @@ void LLGLTexture::setBoostLevel(S32 level)
mBoostLevel = level ;
if(mBoostLevel != LLGLTexture::BOOST_NONE
&& mBoostLevel != LLGLTexture::BOOST_ICON
- && mBoostLevel != LLGLTexture::BOOST_THUMBNAIL)
+ && mBoostLevel != LLGLTexture::BOOST_THUMBNAIL
+ && mBoostLevel != LLGLTexture::BOOST_TERRAIN)
{
setNoDelete() ;
}
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index 1cc8fbe523..fa6faa2583 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -52,10 +52,11 @@ public:
BOOST_AVATAR ,
BOOST_AVATAR_BAKED ,
BOOST_SCULPTED ,
+ BOOST_TERRAIN , // Needed for minimap generation for now. Lower than BOOST_HIGH so the texture stats don't get forced, i.e. texture stats are manually managed by minimap/terrain instead.
BOOST_HIGH = 10,
BOOST_BUMP ,
- BOOST_TERRAIN , // has to be high priority for minimap / low detail
+ BOOST_UNUSED_1 , // Placeholder to avoid disrupting habits around texture debug
BOOST_SELECTED ,
BOOST_AVATAR_BAKED_SELF ,
BOOST_AVATAR_SELF , // needed for baking avatar
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 2d198c5b4b..c5932a6ad9 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -115,41 +115,7 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures()
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
- for (S32 i = 0; i < 4; i++)
- {
- constexpr LLGLTexture::EBoostLevel level = LLGLTexture::BOOST_TERRAIN;
- constexpr float stats = 1024.f * 1024.f;
-
- LLPointer<LLViewerFetchedTexture>& tex = compp->mDetailTextures[i];
- llassert(tex.notNull());
- tex->setBoostLevel(level);
- tex->addTextureStats(stats);
-
- LLPointer<LLFetchedGLTFMaterial>& fetched_material = compp->mDetailMaterials[i];
- if (fetched_material)
- {
- if (fetched_material->mBaseColorTexture)
- {
- fetched_material->mBaseColorTexture->setBoostLevel(level);
- fetched_material->mBaseColorTexture->addTextureStats(stats);
- }
- if (fetched_material->mNormalTexture)
- {
- fetched_material->mNormalTexture->setBoostLevel(level);
- fetched_material->mNormalTexture->addTextureStats(stats);
- }
- if (fetched_material->mMetallicRoughnessTexture)
- {
- fetched_material->mMetallicRoughnessTexture->setBoostLevel(level);
- fetched_material->mMetallicRoughnessTexture->addTextureStats(stats);
- }
- if (fetched_material->mEmissiveTexture)
- {
- fetched_material->mEmissiveTexture->setBoostLevel(level);
- fetched_material->mEmissiveTexture->addTextureStats(stats);
- }
- }
- }
+ compp->boost();
}
void LLDrawPoolTerrain::beginDeferredPass(S32 pass)
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 35fb0a2237..52b2f19ada 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -398,7 +398,6 @@ public:
BOOL isCachedRawImageReady() const {return mCachedRawImageReady ;}
BOOL isRawImageValid()const { return mIsRawImageValid ; }
void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ;
- void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f);
/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override;
void destroySavedRawImage() ;
LLImageRaw* getSavedRawImage() ;
@@ -420,6 +419,7 @@ public:
protected:
/*virtual*/ void switchToCachedImage() override;
S32 getCurrentDiscardLevelForFetching() ;
+ void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f);
private:
void init(bool firstinit) ;
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index 6c0691c6a9..8d3b5cc8a5 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -28,6 +28,8 @@
#include "llvlcomposition.h"
+#include <functional>
+
#include "llerror.h"
#include "v3math.h"
#include "llsurface.h"
@@ -45,6 +47,7 @@
extern LLColor4U MAX_WATER_COLOR;
static const U32 BASE_SIZE = 128;
+static const F32 TERRAIN_DECODE_PRIORITY = 2048.f * 2048.f;
namespace
{
@@ -64,25 +67,38 @@ namespace
return result;
}
- void unboost_minimap_texture(LLPointer<LLViewerFetchedTexture>& tex)
+ void boost_minimap_texture(LLViewerFetchedTexture* tex, F32 virtual_size)
+ {
+ llassert(tex);
+ if (!tex) { return; }
+
+ tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case the raw image is at low detail
+ tex->addTextureStats(virtual_size); // priority
+ }
+
+ void boost_minimap_material(LLFetchedGLTFMaterial* mat, F32 virtual_size)
+ {
+ if (!mat) { return; }
+ if (mat->mBaseColorTexture) { boost_minimap_texture(mat->mBaseColorTexture, virtual_size); }
+ if (mat->mNormalTexture) { boost_minimap_texture(mat->mNormalTexture, virtual_size); }
+ if (mat->mMetallicRoughnessTexture) { boost_minimap_texture(mat->mMetallicRoughnessTexture, virtual_size); }
+ if (mat->mEmissiveTexture) { boost_minimap_texture(mat->mEmissiveTexture, virtual_size); }
+ }
+
+ void unboost_minimap_texture(LLViewerFetchedTexture* tex)
{
if (!tex) { return; }
tex->setBoostLevel(LLGLTexture::BOOST_NONE);
tex->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1);
-
- if (tex->getTextureState() == LLGLTexture::NO_DELETE)
- {
- tex->forceActive();
- }
}
- void unboost_minimap_material(LLPointer<LLFetchedGLTFMaterial>& mat)
+ void unboost_minimap_material(LLFetchedGLTFMaterial* mat)
{
if (!mat) { return; }
- unboost_minimap_texture(mat->mBaseColorTexture);
- unboost_minimap_texture(mat->mNormalTexture);
- unboost_minimap_texture(mat->mMetallicRoughnessTexture);
- unboost_minimap_texture(mat->mEmissiveTexture);
+ if (mat->mBaseColorTexture) { unboost_minimap_texture(mat->mBaseColorTexture); }
+ if (mat->mNormalTexture) { unboost_minimap_texture(mat->mNormalTexture); }
+ if (mat->mMetallicRoughnessTexture) { unboost_minimap_texture(mat->mMetallicRoughnessTexture); }
+ if (mat->mEmissiveTexture) { unboost_minimap_texture(mat->mEmissiveTexture); }
}
};
@@ -96,11 +112,7 @@ LLTerrainMaterials::LLTerrainMaterials()
LLTerrainMaterials::~LLTerrainMaterials()
{
- for (S32 i = 0; i < ASSET_COUNT; ++i)
- {
- unboost_minimap_texture(mDetailTextures[i]);
- unboost_minimap_material(mDetailMaterials[i]);
- }
+ unboost();
}
BOOL LLTerrainMaterials::generateMaterials()
@@ -118,6 +130,31 @@ BOOL LLTerrainMaterials::generateMaterials()
return FALSE;
}
+void LLTerrainMaterials::boost()
+{
+ for (S32 i = 0; i < ASSET_COUNT; ++i)
+ {
+ LLPointer<LLViewerFetchedTexture>& tex = mDetailTextures[i];
+ llassert(tex.notNull());
+ boost_minimap_texture(tex, TERRAIN_DECODE_PRIORITY);
+
+ LLPointer<LLFetchedGLTFMaterial>& mat = mDetailMaterials[i];
+ boost_minimap_material(mat, TERRAIN_DECODE_PRIORITY);
+ }
+}
+
+void LLTerrainMaterials::unboost()
+{
+ for (S32 i = 0; i < ASSET_COUNT; ++i)
+ {
+ LLPointer<LLViewerFetchedTexture>& tex = mDetailTextures[i];
+ unboost_minimap_texture(tex);
+
+ LLPointer<LLFetchedGLTFMaterial>& mat = mDetailMaterials[i];
+ unboost_minimap_material(mat);
+ }
+}
+
LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset)
{
llassert(mDetailTextures[asset] && mDetailMaterials[asset]);
@@ -135,7 +172,6 @@ LLPointer<LLViewerFetchedTexture> fetch_terrain_texture(const LLUUID& id)
}
LLPointer<LLViewerFetchedTexture> tex = LLViewerTextureManager::getFetchedTexture(id);
- tex->setNoDelete();
return tex;
}
@@ -240,8 +276,7 @@ bool LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, bo
{
if (boost)
{
- tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
- tex->addTextureStats(BASE_SIZE*BASE_SIZE);
+ boost_minimap_texture(tex, BASE_SIZE*BASE_SIZE);
}
return false;
}
@@ -251,6 +286,8 @@ bool LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, bo
{
if (boost)
{
+ boost_minimap_texture(tex, BASE_SIZE*BASE_SIZE);
+
S32 width = tex->getFullWidth();
S32 height = tex->getFullHeight();
S32 min_dim = llmin(width, height);
@@ -260,9 +297,7 @@ bool LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, bo
ddiscard++;
min_dim /= 2;
}
- tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
tex->setMinDiscardLevel(ddiscard);
- tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority
}
return false;
}
@@ -480,6 +515,108 @@ BOOL LLVLComposition::generateComposition()
return LLTerrainMaterials::generateMaterials();
}
+namespace
+{
+ void prepare_fallback_image(LLImageRaw* raw_image)
+ {
+ raw_image->resize(BASE_SIZE, BASE_SIZE, 4);
+ raw_image->fill(LLColor4U::white);
+ }
+
+ // Check if the raw image is loaded for this texture at a discard
+ // level the minimap can use, and if not then try to get it loaded.
+ bool prepare_raw_image(LLPointer<LLImageRaw>& raw_image, bool emissive, LLViewerFetchedTexture* tex, bool& delete_raw_post)
+ {
+ if (!tex)
+ {
+ if (!emissive)
+ {
+ prepare_fallback_image(raw_image);
+ }
+ else
+ {
+ llassert(!raw_image);
+ raw_image = nullptr;
+ }
+ return true;
+ }
+ if (raw_image)
+ {
+ // Callback already initiated
+ if (raw_image->getDataSize() > 0)
+ {
+ // Callback finished
+ delete_raw_post = true;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ raw_image = new LLImageRaw();
+
+ S32 ddiscard = 0;
+ {
+ S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight());
+ while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
+ {
+ ddiscard++;
+ min_dim /= 2;
+ }
+ }
+
+ struct PendingImage
+ {
+ LLImageRaw* mRawImage;
+ S32 mDesiredDiscard;
+ LLUUID mTextureId;
+ PendingImage(LLImageRaw* raw_image, S32 ddiscard, const LLUUID& texture_id)
+ : mRawImage(raw_image)
+ , mDesiredDiscard(ddiscard)
+ , mTextureId(texture_id)
+ {
+ mRawImage->ref();
+ }
+ ~PendingImage()
+ {
+ mRawImage->unref();
+ }
+ };
+ PendingImage* pending_image = new PendingImage(raw_image, ddiscard, tex->getID());
+
+ loaded_callback_func cb = [](BOOL success, LLViewerFetchedTexture * src_vi, LLImageRaw * src, LLImageRaw * src_aux, S32 discard_level, BOOL is_final, void* userdata) {
+ PendingImage* pending = (PendingImage*)userdata;
+ // Owning LLVLComposition still exists
+
+ // Assume mRawImage only used by single LLVLComposition for now
+ const bool in_use_by_composition = pending->mRawImage->getNumRefs() > 1;
+ llassert(pending->mRawImage->getNumRefs());
+ llassert(pending->mRawImage->getNumRefs() <= 2);
+ const bool needs_data = !pending->mRawImage->getDataSize();
+ if (in_use_by_composition && needs_data)
+ {
+ if (success && pending->mDesiredDiscard == discard_level)
+ {
+ pending->mRawImage->resize(BASE_SIZE, BASE_SIZE, src->getComponents());
+ pending->mRawImage->copyScaled(src);
+ }
+ else if (is_final)
+ {
+ prepare_fallback_image(pending->mRawImage);
+ }
+ }
+
+ if (is_final) { delete pending; }
+ };
+ tex->setLoadedCallback(cb, ddiscard, true, false, pending_image, nullptr);
+ tex->forceToSaveRawImage(ddiscard);
+
+ return false;
+ }
+};
+
BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
const F32 width, const F32 height)
{
@@ -547,96 +684,28 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
}
if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; }
- // tex_emissive can be null, and then will be ignored
-
- S32 ddiscard = 0;
- {
- S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight());
- while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
- {
- ddiscard++;
- min_dim /= 2;
- }
- }
-
- S32 ddiscard_emissive = 0;
- if (tex_emissive)
- {
- S32 min_dim_emissive = llmin(tex_emissive->getFullWidth(), tex_emissive->getFullHeight());
- while (min_dim_emissive > BASE_SIZE && ddiscard_emissive < MAX_DISCARD_LEVEL)
- {
- ddiscard_emissive++;
- min_dim_emissive /= 2;
- }
- }
- // *NOTE: It is probably safe to call destroyRawImage no matter
- // what, as LLViewerFetchedTexture::mRawImage is managed by
- // LLPointer and not modified with the rare exception of
- // icons (see BOOST_ICON). Nevertheless, gate this fix for now, as
- // it may have unintended consequences on texture loading.
- // We may want to also set the boost level in setDetailAssetID, but
- // that is not guaranteed to work if a texture is loaded on an object
- // before being loaded as terrain, so we will need this fix
- // regardless.
- static LLCachedControl<bool> sRenderTerrainPBREnabled(gSavedSettings, "RenderTerrainPBREnabled", false);
- BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL || sRenderTerrainPBREnabled);
- BOOL delete_raw_emissive = (tex_emissive &&
- (tex_emissive->reloadRawImage(ddiscard_emissive) != NULL || sRenderTerrainPBREnabled));
-
- if(tex->getRawImageLevel() != ddiscard)
- {
- // Raw image is not ready, will enter here again later.
- if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage())
- {
- tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
- tex->forceToRefetchTexture(ddiscard);
- }
-
- if(delete_raw)
- {
- tex->destroyRawImage() ;
- }
- return FALSE;
- }
- if (tex_emissive)
- {
- if(tex_emissive->getRawImageLevel() != ddiscard_emissive)
- {
- // Raw image is not ready, will enter here again later.
- if (tex_emissive->getFetchPriority() <= 0.0f && !tex_emissive->hasSavedRawImage())
- {
- tex_emissive->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
- tex_emissive->forceToRefetchTexture(ddiscard_emissive);
- }
-
- if(delete_raw_emissive)
- {
- tex_emissive->destroyRawImage() ;
- }
- return FALSE;
- }
- }
+ bool delete_raw_post = false;
+ bool delete_raw_post_emissive = false;
+ if (!prepare_raw_image(mRawImagesBaseColor[i], false, tex, delete_raw_post)) { return FALSE; }
+ if (tex_emissive && !prepare_raw_image(mRawImagesEmissive[i], true, tex_emissive, delete_raw_post_emissive)) { return FALSE; }
+ // tex_emissive can be null, and then will be ignored
- mRawImages[i] = tex->getRawImage() ;
- if(delete_raw)
- {
- tex->destroyRawImage() ;
- }
+ // In the simplest case, the minimap image is just the base color.
+ // This will be replaced if we need to do any tinting/compositing.
+ mRawImages[i] = mRawImagesBaseColor[i];
// *TODO: This isn't quite right for PBR:
// 1) It does not convert the color images from SRGB to linear
// before mixing (which will always require copying the image).
// 2) It mixes emissive and base color before mixing terrain
// materials, but it should be the other way around
- // 3) The composite function used to put emissive into base color
- // is not an alpha blend.
// Long-term, we should consider a method that is more
// maintainable. Shaders, perhaps? Bake shaders to textures?
LLPointer<LLImageRaw> raw_emissive;
if (tex_emissive)
{
- raw_emissive = tex_emissive->getRawImage();
+ raw_emissive = mRawImagesEmissive[i];
if (has_emissive_factor ||
tex_emissive->getWidth(tex_emissive->getRawImageLevel()) != BASE_SIZE ||
tex_emissive->getHeight(tex_emissive->getRawImageLevel()) != BASE_SIZE ||
@@ -644,7 +713,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
{
LLPointer<LLImageRaw> newraw_emissive = new LLImageRaw(BASE_SIZE, BASE_SIZE, 4);
// Copy RGB, leave alpha alone (set to opaque by default)
- newraw_emissive->copy(mRawImages[i]);
+ newraw_emissive->copy(mRawImagesEmissive[i]);
if (has_emissive_factor)
{
newraw_emissive->tint(emissive_factor);
@@ -669,7 +738,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
MAX_WATER_COLOR.mV[VZ],
255);
}
- newraw->composite(mRawImages[i]);
+ newraw->composite(mRawImagesBaseColor[i]);
if (has_base_color_factor)
{
newraw->tint(base_color_factor);
@@ -677,16 +746,24 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
// Apply emissive texture
if (raw_emissive)
{
- newraw->composite(raw_emissive);
+ newraw->addEmissive(raw_emissive);
}
mRawImages[i] = newraw; // deletes old
}
- if (delete_raw_emissive)
+ if (delete_raw_post)
+ {
+ tex->destroyRawImage();
+ }
+ if (delete_raw_post_emissive)
{
tex_emissive->destroyRawImage();
}
+
+ // Remove intermediary image references
+ mRawImagesBaseColor[i] = nullptr;
+ mRawImagesEmissive[i] = nullptr;
}
st_data[i] = mRawImages[i]->getData();
st_data_size[i] = mRawImages[i]->getDataSize();
@@ -860,6 +937,8 @@ void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id)
}
LLTerrainMaterials::setDetailAssetID(asset, id);
mRawImages[asset] = NULL;
+ mRawImagesBaseColor[asset] = NULL;
+ mRawImagesEmissive[asset] = NULL;
}
void LLVLComposition::setStartHeight(S32 corner, const F32 start_height)
diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h
index 7397ff1e8d..5db832e034 100644
--- a/indra/newview/llvlcomposition.h
+++ b/indra/newview/llvlcomposition.h
@@ -58,6 +58,8 @@ public:
BOOL generateMaterials();
+ void boost();
+
virtual LLUUID getDetailAssetID(S32 asset);
virtual void setDetailAssetID(S32 asset, const LLUUID& id);
Type getMaterialType();
@@ -67,6 +69,7 @@ public:
bool materialsReady(bool boost, bool strict);
protected:
+ void unboost();
static bool textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost);
// strict = true -> all materials must be sufficiently loaded
// strict = false -> at least one material must be loaded
@@ -127,8 +130,13 @@ protected:
BOOL mParamsReady = FALSE;
LLSurface *mSurfacep;
+ // Final minimap raw images
LLPointer<LLImageRaw> mRawImages[LLTerrainMaterials::ASSET_COUNT];
+ // Only non-null during minimap tile generation
+ LLPointer<LLImageRaw> mRawImagesBaseColor[LLTerrainMaterials::ASSET_COUNT];
+ LLPointer<LLImageRaw> mRawImagesEmissive[LLTerrainMaterials::ASSET_COUNT];
+
F32 mStartHeight[CORNER_COUNT];
F32 mHeightRange[CORNER_COUNT];