diff options
| author | cosmic-linden <111533034+cosmic-linden@users.noreply.github.com> | 2024-04-26 09:27:27 -0700 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-26 09:27:27 -0700 | 
| commit | 6f51d909a2cd4fd5d875cf255f5379bc5c1984d2 (patch) | |
| tree | 385c08e9692d8350521996178cf9d05d69d70cf4 | |
| parent | 86c0c1d5536897c925f4e8aa2859a160313d964c (diff) | |
| parent | 668c63c2c4e2d9757ccaebbfea5f99264b7352c2 (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.cpp | 67 | ||||
| -rw-r--r-- | indra/llimage/llimage.h | 6 | ||||
| -rw-r--r-- | indra/llrender/llgltexture.cpp | 3 | ||||
| -rw-r--r-- | indra/llrender/llgltexture.h | 3 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolterrain.cpp | 36 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.h | 2 | ||||
| -rw-r--r-- | indra/newview/llvlcomposition.cpp | 283 | ||||
| -rw-r--r-- | indra/newview/llvlcomposition.h | 8 | 
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]; | 
