1836 dont store texture in system memory unless absolutely necessary (#1843)
* #1836 Texture memory usage overhaul. Much decrufting - don't keep a copy of textures in system memory - use GPU to downrez textures instead of reloading from cache - use GPU to generate brightness/darkness bumpmapsmaster
parent
e95df8a284
commit
ab87978cbc
|
|
@ -351,20 +351,6 @@ void LLGLTexture::forceUpdateBindStats(void) const
|
|||
return mGLTexturep->forceUpdateBindStats() ;
|
||||
}
|
||||
|
||||
U32 LLGLTexture::getTexelsInAtlas() const
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
return mGLTexturep->getTexelsInAtlas() ;
|
||||
}
|
||||
|
||||
U32 LLGLTexture::getTexelsInGLTexture() const
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
return mGLTexturep->getTexelsInGLTexture() ;
|
||||
}
|
||||
|
||||
bool LLGLTexture::isGLTextureCreated() const
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
|
@ -372,13 +358,6 @@ bool LLGLTexture::isGLTextureCreated() const
|
|||
return mGLTexturep->isGLTextureCreated() ;
|
||||
}
|
||||
|
||||
S32 LLGLTexture::getDiscardLevelInAtlas() const
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
return mGLTexturep->getDiscardLevelInAtlas() ;
|
||||
}
|
||||
|
||||
void LLGLTexture::destroyGLTexture()
|
||||
{
|
||||
if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
|
||||
|
|
|
|||
|
|
@ -51,10 +51,10 @@ public:
|
|||
BOOST_NONE = 0,
|
||||
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_SCULPTED ,
|
||||
BOOST_BUMP ,
|
||||
BOOST_UNUSED_1 , // Placeholder to avoid disrupting habits around texture debug
|
||||
BOOST_SELECTED ,
|
||||
|
|
@ -75,7 +75,6 @@ public:
|
|||
AVATAR_SCRATCH_TEX,
|
||||
DYNAMIC_TEX,
|
||||
MEDIA,
|
||||
ATLAS,
|
||||
OTHER,
|
||||
MAX_GL_IMAGE_CATEGORY
|
||||
};
|
||||
|
|
@ -156,10 +155,7 @@ public:
|
|||
bool isJustBound()const ;
|
||||
void forceUpdateBindStats(void) const;
|
||||
|
||||
U32 getTexelsInAtlas() const ;
|
||||
U32 getTexelsInGLTexture() const ;
|
||||
bool isGLTextureCreated() const ;
|
||||
S32 getDiscardLevelInAtlas() const ;
|
||||
LLGLTextureState getTextureState() const { return mTextureState; }
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "llrender.h"
|
||||
#include "llwindow.h"
|
||||
#include "llframetimer.h"
|
||||
#include <unordered_set>
|
||||
|
||||
extern LL_COMMON_API bool on_main_thread();
|
||||
|
||||
|
|
@ -130,10 +131,9 @@ S32 LLImageGL::sCount = 0;
|
|||
|
||||
bool LLImageGL::sGlobalUseAnisotropic = false;
|
||||
F32 LLImageGL::sLastFrameTime = 0.f;
|
||||
bool LLImageGL::sAllowReadBackRaw = false ;
|
||||
LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
|
||||
bool LLImageGL::sCompressTextures = false;
|
||||
std::set<LLImageGL*> LLImageGL::sImageList;
|
||||
std::unordered_set<LLImageGL*> LLImageGL::sImageList;
|
||||
|
||||
|
||||
bool LLImageGLThread::sEnabledTextures = false;
|
||||
|
|
@ -150,6 +150,9 @@ S32 LLImageGL::sMaxCategories = 1 ;
|
|||
|
||||
//optimization for when we don't need to calculate mIsMask
|
||||
bool LLImageGL::sSkipAnalyzeAlpha;
|
||||
U32 LLImageGL::sScratchPBO = 0;
|
||||
U32 LLImageGL::sScratchPBOSize = 0;
|
||||
|
||||
|
||||
//------------------------
|
||||
//****************************************************************************************************
|
||||
|
|
@ -159,20 +162,6 @@ bool LLImageGL::sSkipAnalyzeAlpha;
|
|||
//**************************************************************************************
|
||||
//below are functions for debug use
|
||||
//do not delete them even though they are not currently being used.
|
||||
void check_all_images()
|
||||
{
|
||||
for (std::set<LLImageGL*>::iterator iter = LLImageGL::sImageList.begin();
|
||||
iter != LLImageGL::sImageList.end(); iter++)
|
||||
{
|
||||
LLImageGL* glimage = *iter;
|
||||
if (glimage->getTexName() && glimage->isGLTextureCreated())
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(glimage) ;
|
||||
glimage->checkTexSize() ;
|
||||
gGL.getTexUnit(0)->unbind(glimage->getTarget()) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLImageGL::checkTexSize(bool forced) const
|
||||
{
|
||||
|
|
@ -252,6 +241,11 @@ void LLImageGL::initClass(LLWindow* window, S32 num_catagories, bool skip_analyz
|
|||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
sSkipAnalyzeAlpha = skip_analyze_alpha;
|
||||
|
||||
if (sScratchPBO == 0)
|
||||
{
|
||||
glGenBuffers(1, &sScratchPBO);
|
||||
}
|
||||
|
||||
if (thread_texture_loads || thread_media_updates)
|
||||
{
|
||||
LLImageGLThread::createInstance(window);
|
||||
|
|
@ -265,6 +259,12 @@ void LLImageGL::cleanupClass()
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LLImageGLThread::deleteSingleton();
|
||||
if (sScratchPBO != 0)
|
||||
{
|
||||
glDeleteBuffers(1, &sScratchPBO);
|
||||
sScratchPBO = 0;
|
||||
sScratchPBOSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -360,66 +360,19 @@ void LLImageGL::updateStats(F32 current_time)
|
|||
//----------------------------------------------------------------------------
|
||||
|
||||
//static
|
||||
void LLImageGL::destroyGL(bool save_state)
|
||||
void LLImageGL::destroyGL()
|
||||
{
|
||||
for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++)
|
||||
{
|
||||
gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
|
||||
sAllowReadBackRaw = true ;
|
||||
for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
|
||||
iter != sImageList.end(); iter++)
|
||||
{
|
||||
LLImageGL* glimage = *iter;
|
||||
if (glimage->mTexName)
|
||||
{
|
||||
if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
|
||||
{
|
||||
glimage->mSaveData = new LLImageRaw;
|
||||
if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
|
||||
{
|
||||
glimage->mSaveData = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
glimage->destroyGLTexture();
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
sAllowReadBackRaw = false ;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageGL::restoreGL()
|
||||
{
|
||||
for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
|
||||
iter != sImageList.end(); iter++)
|
||||
{
|
||||
LLImageGL* glimage = *iter;
|
||||
if(glimage->getTexName())
|
||||
{
|
||||
LL_ERRS() << "tex name is not 0." << LL_ENDL ;
|
||||
}
|
||||
if (glimage->mSaveData.notNull())
|
||||
{
|
||||
if (glimage->getComponents() && glimage->mSaveData->getComponents())
|
||||
{
|
||||
glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, true, glimage->getCategory());
|
||||
stop_glerror();
|
||||
}
|
||||
glimage->mSaveData = NULL; // deletes data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageGL::dirtyTexOptions()
|
||||
{
|
||||
for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
|
||||
iter != sImageList.end(); iter++)
|
||||
for (auto& glimage : sImageList)
|
||||
{
|
||||
LLImageGL* glimage = *iter;
|
||||
glimage->mTexOptionsDirty = true;
|
||||
stop_glerror();
|
||||
}
|
||||
|
|
@ -542,10 +495,6 @@ void LLImageGL::init(bool usemipmaps)
|
|||
mHeight = 0;
|
||||
mCurrentDiscardLevel = -1;
|
||||
|
||||
mDiscardLevelInAtlas = -1 ;
|
||||
mTexelsInAtlas = 0 ;
|
||||
mTexelsInGLTexture = 0 ;
|
||||
|
||||
mAllowCompression = true;
|
||||
|
||||
mTarget = GL_TEXTURE_2D;
|
||||
|
|
@ -622,9 +571,6 @@ bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
|
|||
return false;
|
||||
}
|
||||
|
||||
// pickmask validity depends on old image size, delete it
|
||||
freePickMask();
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mComponents = ncomponents;
|
||||
|
|
@ -1025,98 +971,6 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32
|
|||
return true;
|
||||
}
|
||||
|
||||
bool LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
|
||||
{
|
||||
//not compatible with core GL profile
|
||||
llassert(!LLRender::sGLCoreProfile);
|
||||
|
||||
if (gGLManager.mIsDisabled)
|
||||
{
|
||||
LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
llassert(gGLManager.mInited);
|
||||
stop_glerror();
|
||||
|
||||
if (discard_level < 0)
|
||||
{
|
||||
llassert(mCurrentDiscardLevel >= 0);
|
||||
discard_level = mCurrentDiscardLevel;
|
||||
}
|
||||
|
||||
// Actual image width/height = raw image width/height * 2^discard_level
|
||||
S32 w = raw_image->getWidth() << discard_level;
|
||||
S32 h = raw_image->getHeight() << discard_level;
|
||||
|
||||
// setSize may call destroyGLTexture if the size does not match
|
||||
if (!setSize(w, h, raw_image->getComponents(), discard_level))
|
||||
{
|
||||
LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mHasExplicitFormat)
|
||||
{
|
||||
switch (mComponents)
|
||||
{
|
||||
case 1:
|
||||
// Use luminance alpha (for fonts)
|
||||
mFormatInternal = GL_LUMINANCE8;
|
||||
mFormatPrimary = GL_LUMINANCE;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 2:
|
||||
// Use luminance alpha (for fonts)
|
||||
mFormatInternal = GL_LUMINANCE8_ALPHA8;
|
||||
mFormatPrimary = GL_LUMINANCE_ALPHA;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 3:
|
||||
mFormatInternal = GL_RGB8;
|
||||
mFormatPrimary = GL_RGB;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 4:
|
||||
mFormatInternal = GL_RGBA8;
|
||||
mFormatPrimary = GL_RGBA;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
default:
|
||||
LL_ERRS() << "Bad number of components for texture: " << (U32) getComponents() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentDiscardLevel = discard_level;
|
||||
mDiscardLevelInAtlas = discard_level;
|
||||
mTexelsInAtlas = raw_image->getWidth() * raw_image->getHeight() ;
|
||||
mLastBindTime = sLastFrameTime;
|
||||
mGLTextureCreated = false ;
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, raw_image->getWidth());
|
||||
stop_glerror();
|
||||
|
||||
if(mFormatSwapBytes)
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
void LLImageGL::postAddToAtlas()
|
||||
{
|
||||
if(mFormatSwapBytes)
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
U32 type_width_from_pixtype(U32 pixtype)
|
||||
{
|
||||
U32 type_width = 0;
|
||||
|
|
@ -1752,7 +1606,6 @@ bool LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, bool data_
|
|||
|
||||
|
||||
mTextureMemory = (S64Bytes)getMipBytes(mCurrentDiscardLevel);
|
||||
mTexelsInGLTexture = getWidth() * getHeight();
|
||||
|
||||
// mark this as bound at this point, so we don't throw it out immediately
|
||||
mLastBindTime = sLastFrameTime;
|
||||
|
|
@ -1830,8 +1683,7 @@ void LLImageGL::syncTexName(LLGLuint texname)
|
|||
|
||||
bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
|
||||
{
|
||||
llassert_always(sAllowReadBackRaw) ;
|
||||
//LL_ERRS() << "should not call this function!" << LL_ENDL ;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
if (discard_level < 0)
|
||||
{
|
||||
|
|
@ -2297,6 +2149,8 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
|
|||
//----------------------------------------------------------------------------
|
||||
U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
freePickMask();
|
||||
U32 pick_width = pWidth/2 + 1;
|
||||
U32 pick_height = pHeight/2 + 1;
|
||||
|
||||
|
|
@ -2314,7 +2168,6 @@ U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
|
|||
//----------------------------------------------------------------------------
|
||||
void LLImageGL::freePickMask()
|
||||
{
|
||||
// pickmask validity depends on old image size, delete it
|
||||
if (mPickMask != NULL)
|
||||
{
|
||||
delete [] mPickMask;
|
||||
|
|
@ -2352,16 +2205,16 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
|
|||
return ;
|
||||
}
|
||||
|
||||
freePickMask();
|
||||
|
||||
if (mFormatType != GL_UNSIGNED_BYTE ||
|
||||
((mFormatPrimary != GL_RGBA)
|
||||
&& (mFormatPrimary != GL_SRGB_ALPHA)))
|
||||
{
|
||||
//cannot generate a pick mask for this texture
|
||||
freePickMask();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SHOW_ASSERT
|
||||
const U32 pickSize = createPickMask(width, height);
|
||||
#else // SHOW_ASSERT
|
||||
|
|
@ -2460,6 +2313,73 @@ void LLImageGL::resetCurTexSizebar()
|
|||
sCurTexSizeBar = -1 ;
|
||||
sCurTexPickSize = -1 ;
|
||||
}
|
||||
|
||||
bool LLImageGL::scaleDown(S32 desired_discard)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
if (mTarget != GL_TEXTURE_2D)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
desired_discard = llmin(desired_discard, mMaxDiscardLevel);
|
||||
|
||||
if (desired_discard <= mCurrentDiscardLevel)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
S32 mip = desired_discard - mCurrentDiscardLevel;
|
||||
|
||||
S32 desired_width = getWidth(desired_discard);
|
||||
S32 desired_height = getHeight(desired_discard);
|
||||
|
||||
U64 size = getBytes(desired_discard);
|
||||
llassert(size <= 2048*2048*4); // we shouldn't be using this method to downscale huge textures, but it'll work
|
||||
gGL.getTexUnit(0)->bind(this);
|
||||
|
||||
|
||||
if (sScratchPBO == 0)
|
||||
{
|
||||
glGenBuffers(1, &sScratchPBO);
|
||||
sScratchPBOSize = 0;
|
||||
}
|
||||
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, sScratchPBO);
|
||||
|
||||
if (size > sScratchPBOSize)
|
||||
{
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, size, NULL, GL_STREAM_COPY);
|
||||
sScratchPBOSize = size;
|
||||
}
|
||||
|
||||
glGetTexImage(mTarget, mip, mFormatPrimary, mFormatType, nullptr);
|
||||
|
||||
free_tex_image(mTexName);
|
||||
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sScratchPBO);
|
||||
glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, nullptr);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
alloc_tex_image(desired_width, desired_height, mFormatPrimary);
|
||||
|
||||
if (mHasMipMaps)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap");
|
||||
glGenerateMipmap(mTarget);
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
mCurrentDiscardLevel = desired_discard;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#if LL_IMAGEGL_THREAD_CHECK
|
||||
void LLImageGL::checkActiveThread()
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "llrender.h"
|
||||
#include "threadpool.h"
|
||||
#include "workqueue.h"
|
||||
#include <unordered_set>
|
||||
|
||||
#define LL_IMAGEGL_THREAD_CHECK 0 //set to 1 to enable thread debugging for ImageGL
|
||||
|
||||
|
|
@ -83,9 +84,8 @@ public:
|
|||
// needs to be called every frame
|
||||
static void updateStats(F32 current_time);
|
||||
|
||||
// Save off / restore GL textures
|
||||
static void destroyGL(bool save_state = true);
|
||||
static void restoreGL();
|
||||
// cleanup GL state
|
||||
static void destroyGL();
|
||||
static void dirtyTexOptions();
|
||||
|
||||
static bool checkSize(S32 width, S32 height);
|
||||
|
|
@ -148,6 +148,10 @@ public:
|
|||
S32 getDiscardLevel() const { return mCurrentDiscardLevel; }
|
||||
S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; }
|
||||
|
||||
// override the current discard level
|
||||
// should only be used for local textures where you know exactly what you're doing
|
||||
void setDiscardLevel(S32 level) { mCurrentDiscardLevel = level; }
|
||||
|
||||
S32 getCurrentWidth() const { return mWidth ;}
|
||||
S32 getCurrentHeight() const { return mHeight ;}
|
||||
S32 getWidth(S32 discard_level = -1) const;
|
||||
|
|
@ -194,26 +198,26 @@ public:
|
|||
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
|
||||
LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; }
|
||||
|
||||
LLGLenum getTexTarget()const { return mTarget ;}
|
||||
S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;}
|
||||
U32 getTexelsInAtlas()const { return mTexelsInAtlas ;}
|
||||
U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;}
|
||||
|
||||
LLGLenum getTexTarget()const { return mTarget; }
|
||||
|
||||
void init(bool usemipmaps);
|
||||
virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors
|
||||
|
||||
void setNeedsAlphaAndPickMask(bool need_mask);
|
||||
|
||||
bool preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image);
|
||||
void postAddToAtlas() ;
|
||||
|
||||
#if LL_IMAGEGL_THREAD_CHECK
|
||||
// thread debugging
|
||||
std::thread::id mActiveThread;
|
||||
void checkActiveThread();
|
||||
#endif
|
||||
|
||||
// scale down to the desired discard level using GPU
|
||||
// returns true if texture was scaled down
|
||||
// desired discard will be clamped to max discard
|
||||
// if desired discard is less than or equal to current discard, no scaling will occur
|
||||
// only works for GL_TEXTURE_2D target
|
||||
bool scaleDown(S32 desired_discard);
|
||||
|
||||
public:
|
||||
// Various GL/Rendering options
|
||||
S64Bytes mTextureMemory;
|
||||
|
|
@ -240,15 +244,10 @@ private:
|
|||
|
||||
bool mGLTextureCreated ;
|
||||
LLGLuint mTexName;
|
||||
//LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread
|
||||
U16 mWidth;
|
||||
U16 mHeight;
|
||||
S8 mCurrentDiscardLevel;
|
||||
|
||||
S8 mDiscardLevelInAtlas;
|
||||
U32 mTexelsInAtlas ;
|
||||
U32 mTexelsInGLTexture;
|
||||
|
||||
bool mAllowCompression;
|
||||
|
||||
protected:
|
||||
|
|
@ -275,7 +274,7 @@ protected:
|
|||
|
||||
// STATICS
|
||||
public:
|
||||
static std::set<LLImageGL*> sImageList;
|
||||
static std::unordered_set<LLImageGL*> sImageList;
|
||||
static S32 sCount;
|
||||
|
||||
static F32 sLastFrameTime;
|
||||
|
|
@ -301,6 +300,8 @@ public:
|
|||
private:
|
||||
static S32 sMaxCategories;
|
||||
static bool sSkipAnalyzeAlpha;
|
||||
static U32 sScratchPBO;
|
||||
static U32 sScratchPBOSize;
|
||||
|
||||
//the flag to allow to call readBackRaw(...).
|
||||
//can be removed if we do not use that function at all.
|
||||
|
|
|
|||
|
|
@ -25,24 +25,53 @@
|
|||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
|
||||
|
||||
// generate a normal map using an approximation of the old emboss bump map "brightness/darkness" technique
|
||||
// srcMap is a source color image, output should be a normal
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
uniform sampler2D alphaMap;
|
||||
uniform sampler2D srcMap;
|
||||
|
||||
in vec2 vary_texcoord0;
|
||||
|
||||
uniform float stepX;
|
||||
uniform float stepY;
|
||||
uniform float norm_scale;
|
||||
uniform int bump_code;
|
||||
|
||||
#define BE_BRIGHTNESS 1
|
||||
#define BE_DARKNESS 2
|
||||
|
||||
// get luminance or inverse luminance depending on bump_code
|
||||
float getBumpValue(vec2 texcoord)
|
||||
{
|
||||
vec3 c = texture(srcMap, texcoord).rgb;
|
||||
|
||||
vec3 WEIGHT = vec3(0.2995, 0.5875, 0.1145);
|
||||
|
||||
float l = dot(c, WEIGHT);
|
||||
|
||||
if (bump_code == BE_DARKNESS)
|
||||
{
|
||||
l = 1.0 - l;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
float c = texture(alphaMap, vary_texcoord0).r;
|
||||
float c = getBumpValue(vary_texcoord0).r;
|
||||
|
||||
vec3 right = vec3(norm_scale, 0, (texture(alphaMap, vary_texcoord0+vec2(stepX, 0)).r-c)*255);
|
||||
vec3 left = vec3(-norm_scale, 0, (texture(alphaMap, vary_texcoord0-vec2(stepX, 0)).r-c)*255);
|
||||
vec3 up = vec3(0, -norm_scale, (texture(alphaMap, vary_texcoord0-vec2(0, stepY)).r-c)*255);
|
||||
vec3 down = vec3(0, norm_scale, (texture(alphaMap, vary_texcoord0+vec2(0, stepY)).r-c)*255);
|
||||
float scaler = 512.0;
|
||||
|
||||
vec3 right = vec3(norm_scale, 0, (getBumpValue(vary_texcoord0+vec2(stepX, 0)).r-c)*scaler);
|
||||
vec3 left = vec3(-norm_scale, 0, (getBumpValue(vary_texcoord0-vec2(stepX, 0)).r-c)*scaler);
|
||||
vec3 up = vec3(0, -norm_scale, (getBumpValue(vary_texcoord0-vec2(0, stepY)).r-c)*scaler);
|
||||
vec3 down = vec3(0, norm_scale, (getBumpValue(vary_texcoord0+vec2(0, stepY)).r-c)*scaler);
|
||||
|
||||
vec3 norm = cross(right, down) + cross(down, left) + cross(left,up) + cross(up, right);
|
||||
|
||||
|
|
|
|||
|
|
@ -180,6 +180,16 @@ namespace LL
|
|||
data[3] = src[3];
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void copyVec4<U8, U64>(U8* src, U64& dst)
|
||||
{
|
||||
U8* data = (U8*)&dst;
|
||||
data[0] = src[0];
|
||||
data[1] = src[1];
|
||||
data[2] = src[2];
|
||||
data[3] = src[3];
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void copyVec4<U16, LLColor4U>(U16* src, LLColor4U& dst)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ void GLTFSceneManager::uploadSelection()
|
|||
}
|
||||
else
|
||||
{
|
||||
raw = image.mTexture->getCachedRawImage();
|
||||
raw = image.mTexture->getRawImage();
|
||||
}
|
||||
|
||||
if (raw.notNull())
|
||||
|
|
@ -339,6 +339,7 @@ void GLTFSceneManager::renderAlpha()
|
|||
|
||||
void GLTFSceneManager::addGLTFObject(LLViewerObject* obj, LLUUID gltf_id)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_GLTF;
|
||||
llassert(obj->getVolume()->getParams().getSculptID() == gltf_id);
|
||||
llassert(obj->getVolume()->getParams().getSculptType() == LL_SCULPT_TYPE_GLTF);
|
||||
|
||||
|
|
|
|||
|
|
@ -105,10 +105,7 @@ void LLDebugView::init()
|
|||
addChild(gSceneMonitorView);
|
||||
gSceneMonitorView->setRect(rect);
|
||||
|
||||
r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f),
|
||||
(S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f));
|
||||
|
||||
r.set(150, rect.getHeight() - 50, 820, 100);
|
||||
r.set(150, rect.getHeight() - 60, 820, 110);
|
||||
LLTextureView::Params tvp;
|
||||
tvp.name("gTextureView");
|
||||
tvp.rect(r);
|
||||
|
|
@ -116,7 +113,6 @@ void LLDebugView::init()
|
|||
tvp.visible(false);
|
||||
gTextureView = LLUICtrlFactory::create<LLTextureView>(tvp);
|
||||
addChild(gTextureView);
|
||||
//gTextureView->reshape(r.getWidth(), r.getHeight(), true);
|
||||
}
|
||||
|
||||
void LLDebugView::draw()
|
||||
|
|
|
|||
|
|
@ -79,11 +79,6 @@ static S32 diffuse_channel = -1;
|
|||
static S32 bump_channel = -1;
|
||||
static bool shiny = false;
|
||||
|
||||
// Enabled after changing LLViewerTexture::mNeedsCreateTexture to an
|
||||
// LLAtomicBool; this should work just fine, now. HB
|
||||
#define LL_BUMPLIST_MULTITHREADED 1
|
||||
|
||||
|
||||
// static
|
||||
void LLStandardBumpmap::shutdown()
|
||||
{
|
||||
|
|
@ -764,24 +759,21 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
|
|||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
|
||||
llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) );
|
||||
|
||||
LLViewerTexture* bump = NULL;
|
||||
LLViewerTexture* bump = nullptr;
|
||||
|
||||
bump_image_map_t* entries_list = NULL;
|
||||
void (*callback_func)( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata ) = NULL;
|
||||
bump_image_map_t* entries_list = nullptr;
|
||||
|
||||
switch( bump_code )
|
||||
{
|
||||
case BE_BRIGHTNESS:
|
||||
entries_list = &mBrightnessEntries;
|
||||
callback_func = LLBumpImageList::onSourceBrightnessLoaded;
|
||||
break;
|
||||
case BE_DARKNESS:
|
||||
entries_list = &mDarknessEntries;
|
||||
callback_func = LLBumpImageList::onSourceDarknessLoaded;
|
||||
break;
|
||||
default:
|
||||
llassert(0);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bump_image_map_t::iterator iter = entries_list->find(src_image->getID());
|
||||
|
|
@ -789,51 +781,18 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
|
|||
{
|
||||
bump = iter->second;
|
||||
}
|
||||
else
|
||||
|
||||
if (bump == nullptr ||
|
||||
src_image->getWidth() != bump->getWidth() ||
|
||||
src_image->getHeight() != bump->getHeight())
|
||||
{
|
||||
(*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( true );
|
||||
bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image
|
||||
onSourceUpdated(src_image, (EBumpEffect) bump_code);
|
||||
}
|
||||
|
||||
if (!src_image->hasCallbacks())
|
||||
{ //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again
|
||||
if (src_image->getWidth() != bump->getWidth() ||
|
||||
src_image->getHeight() != bump->getHeight())// ||
|
||||
//(LLPipeline::sRenderDeferred && bump->getComponents() != 4))
|
||||
{
|
||||
src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
|
||||
src_image->setLoadedCallback( callback_func, 0, true, false, new LLUUID(src_image->getID()), NULL );
|
||||
src_image->forceToSaveRawImage(0) ;
|
||||
}
|
||||
}
|
||||
|
||||
return bump;
|
||||
return (*entries_list)[src_image->getID()];
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLBumpImageList::onSourceBrightnessLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
|
||||
LLUUID* source_asset_id = (LLUUID*)userdata;
|
||||
LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS );
|
||||
if( final )
|
||||
{
|
||||
delete source_asset_id;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLBumpImageList::onSourceDarknessLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata )
|
||||
{
|
||||
LLUUID* source_asset_id = (LLUUID*)userdata;
|
||||
LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS );
|
||||
if( final )
|
||||
{
|
||||
delete source_asset_id;
|
||||
}
|
||||
}
|
||||
|
||||
void LLBumpImageList::onSourceStandardLoaded( bool success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata)
|
||||
{
|
||||
if (success && LLPipeline::sRenderDeferred)
|
||||
|
|
@ -909,289 +868,108 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr
|
|||
}
|
||||
|
||||
// static
|
||||
void LLBumpImageList::onSourceLoaded( bool success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code )
|
||||
void LLBumpImageList::onSourceUpdated(LLViewerTexture* src, EBumpEffect bump_code)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
|
||||
|
||||
if( success )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
|
||||
const LLUUID& src_id = src->getID();
|
||||
|
||||
LLImageDataSharedLock lock(src);
|
||||
bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries);
|
||||
bump_image_map_t::iterator iter = entries_list.find(src_id);
|
||||
|
||||
bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries );
|
||||
bump_image_map_t::iterator iter = entries_list.find(source_asset_id);
|
||||
|
||||
{
|
||||
if (iter == entries_list.end() ||
|
||||
iter->second.isNull() ||
|
||||
iter->second->getWidth() != src->getWidth() ||
|
||||
iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
|
||||
{ //make sure an entry exists for this image
|
||||
entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(true);
|
||||
iter = entries_list.find(src_vi->getID());
|
||||
}
|
||||
}
|
||||
|
||||
if (iter->second->getWidth() != src->getWidth() ||
|
||||
iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
|
||||
{
|
||||
LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1);
|
||||
U8* dst_data = dst_image->getData();
|
||||
S32 dst_data_size = dst_image->getDataSize();
|
||||
|
||||
const U8* src_data = src->getData();
|
||||
S32 src_data_size = src->getDataSize();
|
||||
|
||||
S32 src_components = src->getComponents();
|
||||
|
||||
// Convert to luminance and then scale and bias that to get ready for
|
||||
// embossed bump mapping. (0-255 maps to 127-255)
|
||||
|
||||
// Convert to fixed point so we don't have to worry about precision/clamping.
|
||||
const S32 FIXED_PT = 8;
|
||||
const S32 R_WEIGHT = S32(0.2995f * (1<<FIXED_PT));
|
||||
const S32 G_WEIGHT = S32(0.5875f * (1<<FIXED_PT));
|
||||
const S32 B_WEIGHT = S32(0.1145f * (1<<FIXED_PT));
|
||||
|
||||
S32 minimum = 255;
|
||||
S32 maximum = 0;
|
||||
|
||||
switch( src_components )
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
{
|
||||
if( src_data_size == dst_data_size * src_components )
|
||||
{
|
||||
for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
|
||||
{
|
||||
dst_data[i] = src_data[j];
|
||||
if( dst_data[i] < minimum )
|
||||
{
|
||||
minimum = dst_data[i];
|
||||
}
|
||||
if( dst_data[i] > maximum )
|
||||
{
|
||||
maximum = dst_data[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert(0);
|
||||
dst_image->clear();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
{
|
||||
if( src_data_size == dst_data_size * src_components )
|
||||
{
|
||||
for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
|
||||
{
|
||||
// RGB to luminance
|
||||
dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT;
|
||||
//llassert( dst_data[i] <= 255 );true because it's 8bit
|
||||
if( dst_data[i] < minimum )
|
||||
{
|
||||
minimum = dst_data[i];
|
||||
}
|
||||
if( dst_data[i] > maximum )
|
||||
{
|
||||
maximum = dst_data[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert(0);
|
||||
dst_image->clear();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
llassert(0);
|
||||
dst_image->clear();
|
||||
break;
|
||||
}
|
||||
|
||||
if( maximum > minimum )
|
||||
{
|
||||
U8 bias_and_scale_lut[256];
|
||||
F32 twice_one_over_range = 2.f / (maximum - minimum);
|
||||
S32 i;
|
||||
|
||||
const F32 ARTIFICIAL_SCALE = 2.f; // Advantage: exaggerates the effect in midrange. Disadvantage: clamps at the extremes.
|
||||
if (BE_DARKNESS == bump_code)
|
||||
{
|
||||
for( i = minimum; i <= maximum; i++ )
|
||||
{
|
||||
F32 minus_one_to_one = F32(maximum - i) * twice_one_over_range - 1.f;
|
||||
bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = minimum; i <= maximum; i++ )
|
||||
{
|
||||
F32 minus_one_to_one = F32(i - minimum) * twice_one_over_range - 1.f;
|
||||
bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128));
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < dst_data_size; i++ )
|
||||
{
|
||||
dst_data[i] = bias_and_scale_lut[dst_data[i]];
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
// immediately assign bump to a smart pointer in case some local smart pointer
|
||||
// accidentally releases it.
|
||||
LLPointer<LLViewerTexture> bump = iter->second;
|
||||
|
||||
if (!LLPipeline::sRenderDeferred)
|
||||
{
|
||||
bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
|
||||
|
||||
#if LL_BUMPLIST_MULTITHREADED
|
||||
auto tex_queue = LLImageGLThread::sEnabledTextures ? sTexUpdateQueue.lock() : nullptr;
|
||||
|
||||
if (tex_queue)
|
||||
{ //dispatch creation to background thread
|
||||
LLImageRaw* dst_ptr = dst_image;
|
||||
LLViewerTexture* bump_ptr = bump;
|
||||
dst_ptr->ref();
|
||||
bump_ptr->ref();
|
||||
tex_queue->post(
|
||||
[=]()
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("bil - create texture");
|
||||
bump_ptr->createGLTexture(0, dst_ptr);
|
||||
bump_ptr->unref();
|
||||
dst_ptr->unref();
|
||||
});
|
||||
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
bump->createGLTexture(0, dst_image);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //convert to normal map
|
||||
LL_PROFILE_ZONE_NAMED("bil - create normal map");
|
||||
LLImageGL* img = bump->getGLTexture();
|
||||
LLImageRaw* dst_ptr = dst_image.get();
|
||||
LLGLTexture* bump_ptr = bump.get();
|
||||
|
||||
dst_ptr->ref();
|
||||
img->ref();
|
||||
bump_ptr->ref();
|
||||
auto create_func = [=]()
|
||||
{
|
||||
img->setUseMipMaps(true);
|
||||
// upload dst_image to GPU (greyscale in red channel)
|
||||
img->setExplicitFormat(GL_RED, GL_RED);
|
||||
|
||||
bump_ptr->createGLTexture(0, dst_ptr);
|
||||
dst_ptr->unref();
|
||||
};
|
||||
|
||||
auto generate_func = [=]()
|
||||
{
|
||||
// Allocate an empty RGBA texture at "tex_name" the same size as bump
|
||||
// Note: bump will still point at GPU copy of dst_image
|
||||
bump_ptr->setExplicitFormat(GL_RGBA, GL_RGBA);
|
||||
LLGLuint tex_name;
|
||||
img->createGLTexture(0, nullptr, false, 0, true, &tex_name);
|
||||
|
||||
// point render target at empty buffer
|
||||
sRenderTarget.setColorAttachment(img, tex_name);
|
||||
|
||||
// generate normal map in empty texture
|
||||
{
|
||||
sRenderTarget.bindTarget();
|
||||
|
||||
LLGLDepthTest depth(GL_FALSE);
|
||||
LLGLDisable cull(GL_CULL_FACE);
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
gGL.setColorMask(true, true);
|
||||
|
||||
gNormalMapGenProgram.bind();
|
||||
|
||||
static LLStaticHashedString sNormScale("norm_scale");
|
||||
static LLStaticHashedString sStepX("stepX");
|
||||
static LLStaticHashedString sStepY("stepY");
|
||||
|
||||
gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
|
||||
gNormalMapGenProgram.uniform1f(sStepX, 1.f / bump_ptr->getWidth());
|
||||
gNormalMapGenProgram.uniform1f(sStepY, 1.f / bump_ptr->getHeight());
|
||||
|
||||
gGL.getTexUnit(0)->bind(bump_ptr);
|
||||
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
gGL.texCoord2f(0, 0);
|
||||
gGL.vertex2f(0, 0);
|
||||
|
||||
gGL.texCoord2f(0, 1);
|
||||
gGL.vertex2f(0, 1);
|
||||
|
||||
gGL.texCoord2f(1, 0);
|
||||
gGL.vertex2f(1, 0);
|
||||
|
||||
gGL.texCoord2f(1, 1);
|
||||
gGL.vertex2f(1, 1);
|
||||
|
||||
gGL.end();
|
||||
|
||||
gGL.flush();
|
||||
|
||||
gNormalMapGenProgram.unbind();
|
||||
|
||||
sRenderTarget.flush();
|
||||
sRenderTarget.releaseColorAttachment();
|
||||
}
|
||||
|
||||
// point bump at normal map and free gpu copy of dst_image
|
||||
img->syncTexName(tex_name);
|
||||
|
||||
// generate mipmap
|
||||
gGL.getTexUnit(0)->bind(img);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
gGL.getTexUnit(0)->disable();
|
||||
|
||||
bump_ptr->unref();
|
||||
img->unref();
|
||||
};
|
||||
|
||||
#if LL_BUMPLIST_MULTITHREADED
|
||||
auto main_queue = LLImageGLThread::sEnabledTextures ? sMainQueue.lock() : nullptr;
|
||||
|
||||
if (main_queue)
|
||||
{ //dispatch texture upload to background thread, issue GPU commands to generate normal map on main thread
|
||||
main_queue->postTo(
|
||||
sTexUpdateQueue,
|
||||
create_func,
|
||||
generate_func);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{ // immediate upload texture and generate normal map
|
||||
create_func();
|
||||
generate_func();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
iter->second = bump; // derefs (and deletes) old image
|
||||
//---------------------------------------------------
|
||||
}
|
||||
if (iter == entries_list.end())
|
||||
{ //make sure an entry exists for this image
|
||||
entries_list[src_id] = LLViewerTextureManager::getLocalTexture(true);
|
||||
iter = entries_list.find(src_id);
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
// immediately assign bump to a smart pointer in case some local smart pointer
|
||||
// accidentally releases it.
|
||||
LLPointer<LLViewerTexture> bump = iter->second;
|
||||
|
||||
if (bump->getWidth() != src->getWidth() ||
|
||||
bump->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
|
||||
{
|
||||
//convert to normal map
|
||||
LL_PROFILE_ZONE_NAMED("bil - create normal map");
|
||||
|
||||
bump->setExplicitFormat(GL_RGBA, GL_RGBA);
|
||||
|
||||
LLImageGL* src_img = src->getGLTexture();
|
||||
LLImageGL* dst_img = bump->getGLTexture();
|
||||
dst_img->setSize(src->getWidth(), src->getHeight(), 4, 0);
|
||||
dst_img->setUseMipMaps(true);
|
||||
dst_img->setDiscardLevel(0);
|
||||
dst_img->createGLTexture();
|
||||
|
||||
gGL.getTexUnit(0)->bind(bump);
|
||||
|
||||
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, dst_img->getPrimaryFormat(), dst_img->getWidth(), dst_img->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false);
|
||||
|
||||
LLGLuint tex_name = dst_img->getTexName();
|
||||
// point render target at empty buffer
|
||||
sRenderTarget.setColorAttachment(bump->getGLTexture(), tex_name);
|
||||
|
||||
// generate normal map in empty texture
|
||||
{
|
||||
sRenderTarget.bindTarget();
|
||||
|
||||
LLGLDepthTest depth(GL_FALSE);
|
||||
LLGLDisable cull(GL_CULL_FACE);
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
gGL.setColorMask(true, true);
|
||||
|
||||
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
|
||||
gNormalMapGenProgram.bind();
|
||||
|
||||
static LLStaticHashedString sNormScale("norm_scale");
|
||||
static LLStaticHashedString sStepX("stepX");
|
||||
static LLStaticHashedString sStepY("stepY");
|
||||
static LLStaticHashedString sBumpCode("bump_code");
|
||||
|
||||
gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
|
||||
gNormalMapGenProgram.uniform1f(sStepX, 1.f / bump->getWidth());
|
||||
gNormalMapGenProgram.uniform1f(sStepY, 1.f / bump->getHeight());
|
||||
gNormalMapGenProgram.uniform1i(sBumpCode, bump_code);
|
||||
|
||||
gGL.getTexUnit(0)->bind(src);
|
||||
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
gGL.texCoord2f(0, 0);
|
||||
gGL.vertex2f(0, 0);
|
||||
|
||||
gGL.texCoord2f(0, 1);
|
||||
gGL.vertex2f(0, 1);
|
||||
|
||||
gGL.texCoord2f(1, 0);
|
||||
gGL.vertex2f(1, 0);
|
||||
|
||||
gGL.texCoord2f(1, 1);
|
||||
gGL.vertex2f(1, 1);
|
||||
|
||||
gGL.end();
|
||||
|
||||
gGL.flush();
|
||||
|
||||
sRenderTarget.flush();
|
||||
sRenderTarget.releaseColorAttachment();
|
||||
|
||||
if (shader)
|
||||
{
|
||||
shader->bind();
|
||||
}
|
||||
}
|
||||
|
||||
// generate mipmap
|
||||
gGL.getTexUnit(0)->bind(bump);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
|
||||
iter->second = bump; // derefs (and deletes) old image
|
||||
//---------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolBump::pushBumpBatches(U32 type)
|
||||
|
|
|
|||
|
|
@ -140,14 +140,13 @@ public:
|
|||
LLViewerTexture* getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code);
|
||||
void addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size);
|
||||
|
||||
static void onSourceBrightnessLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata );
|
||||
static void onSourceDarknessLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata );
|
||||
static void onSourceStandardLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata );
|
||||
static void generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nrm_image);
|
||||
|
||||
|
||||
private:
|
||||
static void onSourceLoaded( bool success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump );
|
||||
// should be called whenever resolution of src_vi changes compared to the current entry
|
||||
static void onSourceUpdated( LLViewerTexture *src_vi, EBumpEffect bump );
|
||||
|
||||
private:
|
||||
typedef std::unordered_map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t;
|
||||
|
|
|
|||
|
|
@ -951,8 +951,8 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit()
|
|||
|| texturep->getFullWidth() == 0)
|
||||
{
|
||||
if (texturep->isFullyLoaded()
|
||||
&& (texturep->getCachedRawImageLevel() == 0 || texturep->getRawImageLevel() == 0)
|
||||
&& (texturep->isCachedRawImageReady() || texturep->isRawImageValid()))
|
||||
&& (texturep->getRawImageLevel() == 0)
|
||||
&& (texturep->isRawImageValid()))
|
||||
{
|
||||
LLUUID task_id = mTaskId;
|
||||
uuid_set_t inventory_ids = mItemList;
|
||||
|
|
@ -962,20 +962,10 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit()
|
|||
{
|
||||
onUploadComplete(asset_id, task_id, inventory_ids, handle);
|
||||
};
|
||||
if (texturep->isRawImageValid())
|
||||
{
|
||||
LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getRawImage(),
|
||||
*mItemList.begin(),
|
||||
mTaskId,
|
||||
callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getCachedRawImage(),
|
||||
*mItemList.begin(),
|
||||
mTaskId,
|
||||
callback);
|
||||
}
|
||||
LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getRawImage(),
|
||||
*mItemList.begin(),
|
||||
mTaskId,
|
||||
callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -215,7 +215,6 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
|
|||
("file://"+mFilename, FTT_LOCAL_FILE, mWorldID, LL_LOCAL_USE_MIPMAPS);
|
||||
|
||||
texture->createGLTexture(LL_LOCAL_DISCARD_LEVEL, raw_image);
|
||||
texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image);
|
||||
texture->ref();
|
||||
|
||||
gTextureList.addImage(texture, TEX_LIST_STANDARD);
|
||||
|
|
|
|||
|
|
@ -296,8 +296,6 @@ void LLNetMap::draw()
|
|||
gGL.color4f(1.f, 0.5f, 0.5f, 1.f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Draw using texture.
|
||||
gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());
|
||||
gGL.begin(LLRender::QUADS);
|
||||
|
|
@ -311,24 +309,6 @@ void LLNetMap::draw()
|
|||
gGL.vertex2f(right, top);
|
||||
gGL.end();
|
||||
|
||||
// Draw water
|
||||
gGL.flush();
|
||||
{
|
||||
if (regionp->getLand().getWaterTexture())
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture());
|
||||
gGL.begin(LLRender::QUADS);
|
||||
gGL.texCoord2f(0.f, 1.f);
|
||||
gGL.vertex2f(left, top);
|
||||
gGL.texCoord2f(0.f, 0.f);
|
||||
gGL.vertex2f(left, bottom);
|
||||
gGL.texCoord2f(1.f, 0.f);
|
||||
gGL.vertex2f(right, bottom);
|
||||
gGL.texCoord2f(1.f, 1.f);
|
||||
gGL.vertex2f(right, top);
|
||||
gGL.end();
|
||||
}
|
||||
}
|
||||
gGL.flush();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include "llglheaders.h"
|
||||
#include "lldrawpoolterrain.h"
|
||||
#include "lldrawable.h"
|
||||
#include "llworldmipmap.h"
|
||||
|
||||
extern LLPipeline gPipeline;
|
||||
extern bool gShiftFrame;
|
||||
|
|
@ -74,7 +75,6 @@ LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) :
|
|||
mDetailTextureScale(0.f),
|
||||
mOriginGlobal(0.0, 0.0, 0.0),
|
||||
mSTexturep(NULL),
|
||||
mWaterTexturep(NULL),
|
||||
mGridsPerPatchEdge(0),
|
||||
mMetersPerGrid(1.0f),
|
||||
mMetersPerEdge(1.0f),
|
||||
|
|
@ -129,14 +129,7 @@ LLSurface::~LLSurface()
|
|||
{
|
||||
gPipeline.removePool(poolp);
|
||||
// Don't enable this until we blitz the draw pool for it as well. -- djs
|
||||
if (mSTexturep)
|
||||
{
|
||||
mSTexturep = NULL;
|
||||
}
|
||||
if (mWaterTexturep)
|
||||
{
|
||||
mWaterTexturep = NULL;
|
||||
}
|
||||
mSTexturep = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -216,62 +209,17 @@ LLViewerTexture* LLSurface::getSTexture()
|
|||
return mSTexturep;
|
||||
}
|
||||
|
||||
LLViewerTexture* LLSurface::getWaterTexture()
|
||||
{
|
||||
if (mWaterTexturep.notNull() && !mWaterTexturep->hasGLTexture())
|
||||
{
|
||||
createWaterTexture();
|
||||
}
|
||||
return mWaterTexturep;
|
||||
}
|
||||
|
||||
void LLSurface::createSTexture()
|
||||
{
|
||||
if (!mSTexturep)
|
||||
{
|
||||
// Fill with dummy gray data.
|
||||
// GL NOT ACTIVE HERE
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize, sTextureSize, 3);
|
||||
U8 *default_texture = raw->getData();
|
||||
for (S32 i = 0; i < sTextureSize; i++)
|
||||
{
|
||||
for (S32 j = 0; j < sTextureSize; j++)
|
||||
{
|
||||
*(default_texture + (i*sTextureSize + j)*3) = 128;
|
||||
*(default_texture + (i*sTextureSize + j)*3 + 1) = 128;
|
||||
*(default_texture + (i*sTextureSize + j)*3 + 2) = 128;
|
||||
}
|
||||
}
|
||||
U64 handle = mRegionp->getHandle();
|
||||
|
||||
mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), false);
|
||||
mSTexturep->dontDiscard();
|
||||
gGL.getTexUnit(0)->bind(mSTexturep);
|
||||
mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
}
|
||||
}
|
||||
U32 grid_x, grid_y;
|
||||
|
||||
void LLSurface::createWaterTexture()
|
||||
{
|
||||
if (!mWaterTexturep)
|
||||
{
|
||||
// Create the water texture
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize/2, sTextureSize/2, 4);
|
||||
U8 *default_texture = raw->getData();
|
||||
for (S32 i = 0; i < sTextureSize/2; i++)
|
||||
{
|
||||
for (S32 j = 0; j < sTextureSize/2; j++)
|
||||
{
|
||||
*(default_texture + (i*sTextureSize/2 + j)*4) = MAX_WATER_COLOR.mV[0];
|
||||
*(default_texture + (i*sTextureSize/2 + j)*4 + 1) = MAX_WATER_COLOR.mV[1];
|
||||
*(default_texture + (i*sTextureSize/2 + j)*4 + 2) = MAX_WATER_COLOR.mV[2];
|
||||
*(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3];
|
||||
}
|
||||
}
|
||||
grid_from_region_handle(handle, &grid_x, &grid_y);
|
||||
|
||||
mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), false);
|
||||
mWaterTexturep->dontDiscard();
|
||||
gGL.getTexUnit(0)->bind(mWaterTexturep);
|
||||
mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
mSTexturep = LLWorldMipmap::loadObjectsTile(grid_x, grid_y, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -285,11 +233,10 @@ void LLSurface::initTextures()
|
|||
|
||||
///////////////////////
|
||||
//
|
||||
// Water texture
|
||||
// Water object
|
||||
//
|
||||
if (gSavedSettings.getBOOL("RenderWater") )
|
||||
{
|
||||
createWaterTexture();
|
||||
mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp);
|
||||
gPipeline.createObject(mWaterObjp);
|
||||
LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle());
|
||||
|
|
@ -683,11 +630,8 @@ bool LLSurface::idleUpdate(F32 max_update_time)
|
|||
}
|
||||
}
|
||||
|
||||
if (did_update)
|
||||
{
|
||||
// some patches changed, update region reflection probes
|
||||
mRegionp->updateReflectionProbes();
|
||||
}
|
||||
// some patches changed, update region reflection probes
|
||||
mRegionp->updateReflectionProbes(did_update);
|
||||
|
||||
return did_update;
|
||||
}
|
||||
|
|
@ -1221,98 +1165,3 @@ F32 LLSurface::getWaterHeight() const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLSurface::generateWaterTexture(const F32 x, const F32 y,
|
||||
const F32 width, const F32 height)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED
|
||||
if (!getWaterTexture())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
S32 tex_width = mWaterTexturep->getWidth();
|
||||
S32 tex_height = mWaterTexturep->getHeight();
|
||||
S32 tex_comps = mWaterTexturep->getComponents();
|
||||
S32 tex_stride = tex_width * tex_comps;
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
|
||||
U8 *rawp = raw->getData();
|
||||
|
||||
F32 scale = 256.f * getMetersPerGrid() / (F32)tex_width;
|
||||
F32 scale_inv = 1.f / scale;
|
||||
|
||||
S32 x_begin, y_begin, x_end, y_end;
|
||||
|
||||
x_begin = ll_round(x * scale_inv);
|
||||
y_begin = ll_round(y * scale_inv);
|
||||
x_end = ll_round((x + width) * scale_inv);
|
||||
y_end = ll_round((y + width) * scale_inv);
|
||||
|
||||
if (x_end > tex_width)
|
||||
{
|
||||
x_end = tex_width;
|
||||
}
|
||||
if (y_end > tex_width)
|
||||
{
|
||||
y_end = tex_width;
|
||||
}
|
||||
|
||||
// OK, for now, just have the composition value equal the height at the point.
|
||||
LLVector3 location;
|
||||
LLColor4U coloru;
|
||||
|
||||
const F32 WATER_HEIGHT = getWaterHeight();
|
||||
|
||||
S32 i, j, offset;
|
||||
for (j = y_begin; j < y_end; j++)
|
||||
{
|
||||
for (i = x_begin; i < x_end; i++)
|
||||
{
|
||||
//F32 nv[2];
|
||||
//nv[0] = i/256.f;
|
||||
//nv[1] = j/256.f;
|
||||
// const S32 modulation = noise2(nv)*40;
|
||||
offset = j*tex_stride + i*tex_comps;
|
||||
location.mV[VX] = i*scale;
|
||||
location.mV[VY] = j*scale;
|
||||
|
||||
// Sample multiple points
|
||||
const F32 height = resolveHeightRegion(location);
|
||||
|
||||
if (height > WATER_HEIGHT)
|
||||
{
|
||||
// Above water...
|
||||
coloru = MAX_WATER_COLOR;
|
||||
coloru.mV[3] = ABOVE_WATERLINE_ALPHA;
|
||||
*(rawp + offset++) = coloru.mV[0];
|
||||
*(rawp + offset++) = coloru.mV[1];
|
||||
*(rawp + offset++) = coloru.mV[2];
|
||||
*(rawp + offset++) = coloru.mV[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Want non-linear curve for transparency gradient
|
||||
coloru = MAX_WATER_COLOR;
|
||||
const F32 frac = 1.f - 2.f/(2.f - (height - WATER_HEIGHT));
|
||||
S32 alpha = 64 + ll_round((255-64)*frac);
|
||||
|
||||
alpha = llmin(ll_round((F32)MAX_WATER_COLOR.mV[3]), alpha);
|
||||
alpha = llmax(64, alpha);
|
||||
|
||||
coloru.mV[3] = alpha;
|
||||
*(rawp + offset++) = coloru.mV[0];
|
||||
*(rawp + offset++) = coloru.mV[1];
|
||||
*(rawp + offset++) = coloru.mV[2];
|
||||
*(rawp + offset++) = coloru.mV[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mWaterTexturep->hasGLTexture())
|
||||
{
|
||||
mWaterTexturep->createGLTexture(0, raw);
|
||||
}
|
||||
|
||||
mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ public:
|
|||
F32 getWaterHeight() const;
|
||||
|
||||
LLViewerTexture *getSTexture();
|
||||
LLViewerTexture *getWaterTexture();
|
||||
|
||||
bool hasZData() const { return mHasZData; }
|
||||
|
||||
void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters
|
||||
|
|
@ -171,19 +171,11 @@ public:
|
|||
|
||||
protected:
|
||||
void createSTexture();
|
||||
void createWaterTexture();
|
||||
void initTextures();
|
||||
void initWater();
|
||||
|
||||
|
||||
void createPatchData(); // Allocates memory for patches.
|
||||
void destroyPatchData(); // Deallocates memory for patches.
|
||||
|
||||
bool generateWaterTexture(const F32 x, const F32 y,
|
||||
const F32 width, const F32 height); // Generate texture from composition values.
|
||||
|
||||
//F32 updateTexture(LLSurfacePatch *ppatch);
|
||||
|
||||
LLSurfacePatch *getPatch(const S32 x, const S32 y) const;
|
||||
|
||||
protected:
|
||||
|
|
@ -201,7 +193,6 @@ protected:
|
|||
|
||||
// The textures should never be directly initialized - use the setter methods!
|
||||
LLPointer<LLViewerTexture> mSTexturep; // Texture for surface
|
||||
LLPointer<LLViewerTexture> mWaterTexturep; // Water texture
|
||||
|
||||
LLPointer<LLVOWater> mWaterObjp;
|
||||
|
||||
|
|
|
|||
|
|
@ -906,15 +906,8 @@ void LLSurfacePatch::updateGL()
|
|||
|
||||
updateCompositionStats();
|
||||
F32 tex_patch_size = meters_per_grid*grids_per_patch_edge;
|
||||
if (comp->generateMinimapTileLand((F32)origin_region[VX], (F32)origin_region[VY],
|
||||
tex_patch_size, tex_patch_size))
|
||||
{
|
||||
mSTexUpdate = false;
|
||||
|
||||
// Also generate the water texture
|
||||
mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY],
|
||||
tex_patch_size, tex_patch_size);
|
||||
}
|
||||
mSTexUpdate = false;
|
||||
}
|
||||
|
||||
void LLSurfacePatch::dirtyZ()
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ public:
|
|||
: texture_view("texture_view")
|
||||
{
|
||||
S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
|
||||
changeDefault(rect, LLRect(0,0,100,line_height * 4));
|
||||
changeDefault(rect, LLRect(0,0,0,line_height * 7));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -492,19 +492,51 @@ void LLGLTexMemBar::draw()
|
|||
U32 total_objects = gObjectList.getNumObjects();
|
||||
F32 x_right = 0.0;
|
||||
|
||||
U32 image_count = gTextureList.getNumImages();
|
||||
U32 raw_image_count = 0;
|
||||
U64 raw_image_bytes = 0;
|
||||
|
||||
U32 saved_raw_image_count = 0;
|
||||
U64 saved_raw_image_bytes = 0;
|
||||
|
||||
U32 aux_raw_image_count = 0;
|
||||
U64 aux_raw_image_bytes = 0;
|
||||
|
||||
for (auto& image : gTextureList)
|
||||
{
|
||||
const LLImageRaw* raw_image = image->getRawImage();
|
||||
|
||||
if (raw_image)
|
||||
{
|
||||
raw_image_count++;
|
||||
raw_image_bytes += raw_image->getDataSize();
|
||||
}
|
||||
|
||||
raw_image = image->getSavedRawImage();
|
||||
if (raw_image)
|
||||
{
|
||||
saved_raw_image_count++;
|
||||
saved_raw_image_bytes += raw_image->getDataSize();
|
||||
}
|
||||
|
||||
raw_image = image->getAuxRawImage();
|
||||
if (raw_image)
|
||||
{
|
||||
aux_raw_image_count++;
|
||||
aux_raw_image_bytes += raw_image->getDataSize();
|
||||
}
|
||||
}
|
||||
|
||||
F64 raw_image_bytes_MB = raw_image_bytes / (1024.0 * 1024.0);
|
||||
F64 saved_raw_image_bytes_MB = saved_raw_image_bytes / (1024.0 * 1024.0);
|
||||
F64 aux_raw_image_bytes_MB = aux_raw_image_bytes / (1024.0 * 1024.0);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
LLGLSUIDefault gls_ui;
|
||||
LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
|
||||
LLColor4 color;
|
||||
|
||||
// Gray background using completely magic numbers
|
||||
gGL.color4f(0.f, 0.f, 0.f, 0.25f);
|
||||
// const LLRect & rect(getRect());
|
||||
// gl_rect_2d(-4, v_offset, rect.mRight - rect.mLeft + 2, v_offset + line_height*4);
|
||||
|
||||
std::string text = "";
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
LLTrace::Recording& recording = LLViewerStats::instance().getRecording();
|
||||
|
||||
|
|
@ -525,6 +557,10 @@ void LLGLTexMemBar::draw()
|
|||
U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
|
||||
U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
|
||||
|
||||
// draw a background above first line.... no idea where the rest of the background comes from for the below text
|
||||
gGL.color4f(0.f, 0.f, 0.f, 0.25f);
|
||||
gl_rect_2d(-10, getRect().getHeight() + line_height + 1, getRect().getWidth()+2, getRect().getHeight()+2);
|
||||
|
||||
text = llformat("Est. Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
|
||||
(S32)LLViewerTexture::sFreeVRAMMegabytes,
|
||||
LLMemory::getAvailableMemKB()/1024,
|
||||
|
|
@ -532,11 +568,15 @@ void LLGLTexMemBar::draw()
|
|||
discard_bias,
|
||||
cache_usage,
|
||||
cache_max_usage);
|
||||
//, cache_entries, cache_max_entries
|
||||
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*7,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
text = llformat("Images: %d Raw: %d (%.2f MB) Saved: %d (%.2f MB) Aux: %d (%.2f MB)", image_count, raw_image_count, raw_image_bytes_MB,
|
||||
saved_raw_image_count, saved_raw_image_bytes_MB,
|
||||
aux_raw_image_count, aux_raw_image_bytes_MB);
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height * 6,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
U32 cache_read(0U), cache_write(0U), res_wait(0U);
|
||||
LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait);
|
||||
|
||||
|
|
@ -549,7 +589,6 @@ void LLGLTexMemBar::draw()
|
|||
cache_read,
|
||||
cache_write,
|
||||
res_wait);
|
||||
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*5,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
|
|
@ -789,7 +828,7 @@ void LLTextureView::draw()
|
|||
LL_INFOS() << "ID\tMEM\tBOOST\tPRI\tWIDTH\tHEIGHT\tDISCARD" << LL_ENDL;
|
||||
}
|
||||
|
||||
for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin();
|
||||
for (LLViewerTextureList::image_list_t::iterator iter = gTextureList.mImageList.begin();
|
||||
iter != gTextureList.mImageList.end(); )
|
||||
{
|
||||
LLPointer<LLViewerFetchedTexture> imagep = *iter++;
|
||||
|
|
|
|||
|
|
@ -1253,41 +1253,46 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
|
|||
hostEnd = authority.size();
|
||||
}
|
||||
|
||||
LLViewerMedia* inst = getInstance();
|
||||
if (url.length())
|
||||
{
|
||||
LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
|
||||
if (media_instance)
|
||||
{
|
||||
std::string cookie_host = authority.substr(hostStart, hostEnd - hostStart);
|
||||
std::string cookie_name = "";
|
||||
std::string cookie_value = "";
|
||||
std::string cookie_path = "";
|
||||
bool httponly = true;
|
||||
bool secure = true;
|
||||
if (inst->parseRawCookie(inst->mOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure) &&
|
||||
media_instance->getMediaPlugin())
|
||||
LLAppViewer::instance()->postToMainCoro([=]()
|
||||
{
|
||||
// MAINT-5711 - inexplicably, the CEF setCookie function will no longer set the cookie if the
|
||||
// url and domain are not the same. This used to be my.sl.com and id.sl.com respectively and worked.
|
||||
// For now, we use the URL for the OpenID POST request since it will have the same authority
|
||||
// as the domain field.
|
||||
// (Feels like there must be a less dirty way to construct a URL from component LLURL parts)
|
||||
// MAINT-6392 - Rider: Do not change, however, the original URI requested, since it is used further
|
||||
// down.
|
||||
std::string cefUrl(std::string(inst->mOpenIDURL.mURI) + "://" + std::string(inst->mOpenIDURL.mAuthority));
|
||||
LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
|
||||
if (media_instance)
|
||||
{
|
||||
LLViewerMedia* inst = getInstance();
|
||||
std::string cookie_host = authority.substr(hostStart, hostEnd - hostStart);
|
||||
std::string cookie_name = "";
|
||||
std::string cookie_value = "";
|
||||
std::string cookie_path = "";
|
||||
bool httponly = true;
|
||||
bool secure = true;
|
||||
if (inst->parseRawCookie(inst->mOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure) &&
|
||||
media_instance->getMediaPlugin())
|
||||
{
|
||||
// MAINT-5711 - inexplicably, the CEF setCookie function will no longer set the cookie if the
|
||||
// url and domain are not the same. This used to be my.sl.com and id.sl.com respectively and worked.
|
||||
// For now, we use the URL for the OpenID POST request since it will have the same authority
|
||||
// as the domain field.
|
||||
// (Feels like there must be a less dirty way to construct a URL from component LLURL parts)
|
||||
// MAINT-6392 - Rider: Do not change, however, the original URI requested, since it is used further
|
||||
// down.
|
||||
std::string cefUrl(std::string(inst->mOpenIDURL.mURI) + "://" + std::string(inst->mOpenIDURL.mAuthority));
|
||||
|
||||
media_instance->getMediaPlugin()->setCookie(cefUrl, cookie_name, cookie_value, cookie_host,
|
||||
cookie_path, httponly, secure);
|
||||
media_instance->getMediaPlugin()->setCookie(cefUrl, cookie_name, cookie_value, cookie_host,
|
||||
cookie_path, httponly, secure);
|
||||
|
||||
// Now that we have parsed the raw cookie, we must store it so that each new media instance
|
||||
// can also get a copy and faciliate logging into internal SL sites.
|
||||
media_instance->getMediaPlugin()->storeOpenIDCookie(cefUrl, cookie_name, cookie_value,
|
||||
cookie_host, cookie_path, httponly, secure);
|
||||
}
|
||||
}
|
||||
// Now that we have parsed the raw cookie, we must store it so that each new media instance
|
||||
// can also get a copy and faciliate logging into internal SL sites.
|
||||
media_instance->getMediaPlugin()->storeOpenIDCookie(cefUrl, cookie_name, cookie_value,
|
||||
cookie_host, cookie_path, httponly, secure);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
LLViewerMedia* inst = getInstance();
|
||||
|
||||
// Note: Rider: MAINT-6392 - Some viewer code requires access to the my.sl.com openid cookie for such
|
||||
// actions as posting snapshots to the feed. This is handled through HTTPCore rather than CEF and so
|
||||
// we must learn to SHARE the cookies.
|
||||
|
|
|
|||
|
|
@ -3676,7 +3676,9 @@ bool LLViewerObject::updateLOD()
|
|||
|
||||
bool LLViewerObject::updateGeometry(LLDrawable *drawable)
|
||||
{
|
||||
return false;
|
||||
// return true means "update complete", return false means "try again next frame"
|
||||
// default should be return true
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLViewerObject::updateGL()
|
||||
|
|
|
|||
|
|
@ -1269,8 +1269,12 @@ U32 LLViewerRegion::getNumOfVisibleGroups() const
|
|||
return mImpl ? static_cast<U32>(mImpl->mVisibleGroups.size()) : 0;
|
||||
}
|
||||
|
||||
void LLViewerRegion::updateReflectionProbes()
|
||||
void LLViewerRegion::updateReflectionProbes(bool full_update)
|
||||
{
|
||||
if (!full_update && mReflectionMaps.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
|
||||
const F32 probe_spacing = 32.f;
|
||||
const F32 probe_radius = sqrtf((probe_spacing * 0.5f) * (probe_spacing * 0.5f) * 3.f);
|
||||
|
|
|
|||
|
|
@ -428,7 +428,7 @@ public:
|
|||
static bool isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;}
|
||||
|
||||
// rebuild reflection probe list
|
||||
void updateReflectionProbes();
|
||||
void updateReflectionProbes(bool full_update);
|
||||
|
||||
private:
|
||||
void addToVOCacheTree(LLVOCacheEntry* entry);
|
||||
|
|
|
|||
|
|
@ -414,8 +414,6 @@ void LLViewerTextureManager::init()
|
|||
}
|
||||
}
|
||||
imagep->createGLTexture(0, image_raw);
|
||||
//cache the raw image
|
||||
imagep->setCachedRawImage(0, image_raw);
|
||||
image_raw = NULL;
|
||||
#else
|
||||
LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, true, LLGLTexture::BOOST_UI);
|
||||
|
|
@ -728,9 +726,6 @@ bool LLViewerTexture::bindDefaultImage(S32 stage)
|
|||
}
|
||||
stop_glerror();
|
||||
|
||||
//check if there is cached raw image and switch to it if possible
|
||||
switchToCachedImage();
|
||||
|
||||
LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
|
||||
if (tester)
|
||||
{
|
||||
|
|
@ -931,18 +926,6 @@ void LLViewerTexture::reorganizeVolumeList()
|
|||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerTexture::switchToCachedImage()
|
||||
{
|
||||
//nothing here.
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
|
||||
{
|
||||
//nothing here.
|
||||
}
|
||||
|
||||
bool LLViewerTexture::isLargeImage()
|
||||
{
|
||||
return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize;
|
||||
|
|
@ -1077,10 +1060,6 @@ void LLViewerFetchedTexture::init(bool firstinit)
|
|||
mIsFetched = false;
|
||||
mInFastCacheList = false;
|
||||
|
||||
mCachedRawImage = NULL;
|
||||
mCachedRawDiscardLevel = -1;
|
||||
mCachedRawImageReady = false;
|
||||
|
||||
mSavedRawImage = NULL;
|
||||
mForceToSaveRawImage = false;
|
||||
mSaveRawImage = false;
|
||||
|
|
@ -1138,9 +1117,6 @@ void LLViewerFetchedTexture::cleanup()
|
|||
|
||||
// Clean up image data
|
||||
destroyRawImage();
|
||||
mCachedRawImage = NULL;
|
||||
mCachedRawDiscardLevel = -1;
|
||||
mCachedRawImageReady = false;
|
||||
mSavedRawImage = NULL;
|
||||
mSavedRawDiscardLevel = -1;
|
||||
}
|
||||
|
|
@ -1220,13 +1196,17 @@ void LLViewerFetchedTexture::setForSculpt()
|
|||
{
|
||||
static const S32 MAX_INTERVAL = 8; //frames
|
||||
|
||||
forceToSaveRawImage(0, F32_MAX);
|
||||
|
||||
setBoostLevel(llmax((S32)getBoostLevel(),
|
||||
(S32)LLGLTexture::BOOST_SCULPTED));
|
||||
|
||||
mForSculpt = true;
|
||||
if(isForSculptOnly() && hasGLTexture() && !getBoundRecently())
|
||||
{
|
||||
destroyGLTexture(); //sculpt image does not need gl texture.
|
||||
mTextureState = ACTIVE;
|
||||
}
|
||||
checkCachedRawSculptImage();
|
||||
setMaxVirtualSizeResetInterval(MAX_INTERVAL);
|
||||
}
|
||||
|
||||
|
|
@ -1339,10 +1319,6 @@ void LLViewerFetchedTexture::addToCreateTexture()
|
|||
}
|
||||
}
|
||||
|
||||
//discard the cached raw image and the saved raw image
|
||||
mCachedRawImageReady = false;
|
||||
mCachedRawDiscardLevel = -1;
|
||||
mCachedRawImage = NULL;
|
||||
mSavedRawDiscardLevel = -1;
|
||||
mSavedRawImage = NULL;
|
||||
}
|
||||
|
|
@ -2043,13 +2019,6 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current < min");
|
||||
make_request = false;
|
||||
}
|
||||
else if(mCachedRawImage.notNull() // can be empty
|
||||
&& mCachedRawImageReady
|
||||
&& (current_discard < 0 || current_discard > mCachedRawDiscardLevel))
|
||||
{
|
||||
make_request = false;
|
||||
switchToCachedImage(); //use the cached raw data first
|
||||
}
|
||||
|
||||
if (make_request)
|
||||
{
|
||||
|
|
@ -2542,20 +2511,6 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Do a readback if required, OR start off a texture decode
|
||||
//
|
||||
if (need_readback && (getMaxDiscardLevel() > gl_discard))
|
||||
{
|
||||
// Do a readback to get the GL data into the raw image
|
||||
// We have GL data.
|
||||
|
||||
destroyRawImage();
|
||||
reloadRawImage(mLoadedCallbackDesiredDiscardLevel);
|
||||
llassert(mRawImage.notNull());
|
||||
llassert(!mNeedsAux || mAuxRawImage.notNull());
|
||||
}
|
||||
|
||||
//
|
||||
// Run raw/auxiliary data callbacks
|
||||
//
|
||||
|
|
@ -2663,61 +2618,6 @@ void LLViewerFetchedTexture::forceImmediateUpdate()
|
|||
return;
|
||||
}
|
||||
|
||||
LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level)
|
||||
{
|
||||
llassert(mGLTexturep.notNull());
|
||||
llassert(discard_level >= 0);
|
||||
llassert(mComponents > 0);
|
||||
|
||||
if (mRawImage.notNull())
|
||||
{
|
||||
//mRawImage is in use by somebody else, do not delete it.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level)
|
||||
{
|
||||
if (mSavedRawDiscardLevel != discard_level
|
||||
&& mBoostLevel != BOOST_ICON
|
||||
&& mBoostLevel != BOOST_THUMBNAIL)
|
||||
{
|
||||
mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents());
|
||||
mRawImage->copy(getSavedRawImage());
|
||||
}
|
||||
else
|
||||
{
|
||||
mRawImage = getSavedRawImage();
|
||||
}
|
||||
mRawDiscardLevel = discard_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
//force to fetch raw image again if cached raw image is not good enough.
|
||||
if(mCachedRawDiscardLevel > discard_level)
|
||||
{
|
||||
mRawImage = mCachedRawImage;
|
||||
mRawDiscardLevel = mCachedRawDiscardLevel;
|
||||
}
|
||||
else //cached raw image is good enough, copy it.
|
||||
{
|
||||
if(mCachedRawDiscardLevel != discard_level)
|
||||
{
|
||||
mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents());
|
||||
mRawImage->copy(mCachedRawImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
mRawImage = mCachedRawImage;
|
||||
}
|
||||
mRawDiscardLevel = discard_level;
|
||||
}
|
||||
}
|
||||
mIsRawImageValid = true;
|
||||
sRawCount++;
|
||||
|
||||
return mRawImage;
|
||||
}
|
||||
|
||||
bool LLViewerFetchedTexture::needsToSaveRawImage()
|
||||
{
|
||||
return mForceToSaveRawImage || mSaveRawImage;
|
||||
|
|
@ -2742,7 +2642,6 @@ void LLViewerFetchedTexture::destroyRawImage()
|
|||
{
|
||||
saveRawImage();
|
||||
}
|
||||
setCachedRawImage();
|
||||
}
|
||||
|
||||
mRawImage = NULL;
|
||||
|
|
@ -2752,151 +2651,6 @@ void LLViewerFetchedTexture::destroyRawImage()
|
|||
}
|
||||
}
|
||||
|
||||
//use the mCachedRawImage to (re)generate the gl texture.
|
||||
//virtual
|
||||
void LLViewerFetchedTexture::switchToCachedImage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if(mCachedRawImage.notNull() &&
|
||||
!mNeedsCreateTexture) // <--- texture creation is pending, don't step on it
|
||||
{
|
||||
mRawImage = mCachedRawImage;
|
||||
|
||||
if (getComponents() != mRawImage->getComponents())
|
||||
{
|
||||
// We've changed the number of components, so we need to move any
|
||||
// objects using this pool to a different pool.
|
||||
mComponents = mRawImage->getComponents();
|
||||
mGLTexturep->setComponents(mComponents);
|
||||
gTextureList.dirtyImage(this);
|
||||
}
|
||||
|
||||
mIsRawImageValid = true;
|
||||
mRawDiscardLevel = mCachedRawDiscardLevel;
|
||||
|
||||
scheduleCreateTexture();
|
||||
}
|
||||
}
|
||||
|
||||
//cache the imageraw forcefully.
|
||||
//virtual
|
||||
void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
|
||||
{
|
||||
if(imageraw != mRawImage.get())
|
||||
{
|
||||
if (mBoostLevel == LLGLTexture::BOOST_ICON)
|
||||
{
|
||||
S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS;
|
||||
S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENSIONS;
|
||||
if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
|
||||
{
|
||||
mCachedRawImage = new LLImageRaw(expected_width, expected_height, imageraw->getComponents());
|
||||
mCachedRawImage->copyScaled(imageraw);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCachedRawImage = imageraw;
|
||||
}
|
||||
}
|
||||
else if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
|
||||
{
|
||||
S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
|
||||
S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
|
||||
if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
|
||||
{
|
||||
mCachedRawImage = new LLImageRaw(expected_width, expected_height, imageraw->getComponents());
|
||||
mCachedRawImage->copyScaled(imageraw);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCachedRawImage = imageraw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mCachedRawImage = imageraw;
|
||||
}
|
||||
mCachedRawDiscardLevel = discard_level;
|
||||
mCachedRawImageReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::setCachedRawImage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if(mRawImage == mCachedRawImage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!mIsRawImageValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(mCachedRawImageReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(mCachedRawDiscardLevel < 0 || mCachedRawDiscardLevel > mRawDiscardLevel)
|
||||
{
|
||||
S32 i = 0;
|
||||
S32 w = mRawImage->getWidth();
|
||||
S32 h = mRawImage->getHeight();
|
||||
|
||||
S32 max_size = MAX_CACHED_RAW_IMAGE_AREA;
|
||||
if(LLGLTexture::BOOST_TERRAIN == mBoostLevel)
|
||||
{
|
||||
max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA;
|
||||
}
|
||||
if(mForSculpt)
|
||||
{
|
||||
max_size = MAX_CACHED_RAW_SCULPT_IMAGE_AREA;
|
||||
mCachedRawImageReady = !mRawDiscardLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCachedRawImageReady = (!mRawDiscardLevel || ((w * h) >= max_size));
|
||||
}
|
||||
|
||||
while(((w >> i) * (h >> i)) > max_size)
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
if(i)
|
||||
{
|
||||
if(!(w >> i) || !(h >> i))
|
||||
{
|
||||
--i;
|
||||
}
|
||||
|
||||
{
|
||||
//make a duplicate in case somebody else is using this raw image
|
||||
mRawImage = mRawImage->scaled(w >> i, h >> i);
|
||||
}
|
||||
}
|
||||
mCachedRawImage = mRawImage;
|
||||
mRawDiscardLevel += i;
|
||||
mCachedRawDiscardLevel = mRawDiscardLevel;
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::checkCachedRawSculptImage()
|
||||
{
|
||||
if(mCachedRawImageReady && mCachedRawDiscardLevel > 0)
|
||||
{
|
||||
if(getDiscardLevel() != 0)
|
||||
{
|
||||
mCachedRawImageReady = false;
|
||||
}
|
||||
else if(isForSculptOnly())
|
||||
{
|
||||
resetTextureStats(); //do not update this image any more.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::saveRawImage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
|
@ -2936,6 +2690,20 @@ void LLViewerFetchedTexture::saveRawImage()
|
|||
mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents());
|
||||
}
|
||||
}
|
||||
else if (mBoostLevel == LLGLTexture::BOOST_SCULPTED)
|
||||
{
|
||||
S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : sMaxSculptRez;
|
||||
S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : sMaxSculptRez;
|
||||
if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
|
||||
{
|
||||
mSavedRawImage = new LLImageRaw(expected_width, expected_height, mRawImage->getComponents());
|
||||
mSavedRawImage->copyScaled(mRawImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents());
|
||||
|
|
@ -2981,20 +2749,23 @@ void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, F32 kept_t
|
|||
{
|
||||
mForceToSaveRawImage = true;
|
||||
mDesiredSavedRawDiscardLevel = desired_discard;
|
||||
}
|
||||
}
|
||||
|
||||
//copy from the cached raw image if exists.
|
||||
if(mCachedRawImage.notNull() && mRawImage.isNull() )
|
||||
void LLViewerFetchedTexture::readbackRawImage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
if (mGLTexturep.notNull() && mGLTexturep->getTexName() != 0 && mRawImage.isNull())
|
||||
{
|
||||
mRawImage = new LLImageRaw();
|
||||
if (!mGLTexturep->readBackRaw(-1, mRawImage, false))
|
||||
{
|
||||
mRawImage = mCachedRawImage;
|
||||
mRawDiscardLevel = mCachedRawDiscardLevel;
|
||||
|
||||
saveRawImage();
|
||||
|
||||
mRawImage = NULL;
|
||||
mRawDiscardLevel = INVALID_DISCARD_LEVEL;
|
||||
mRawImage = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::destroySavedRawImage()
|
||||
{
|
||||
if(mLastReferencedSavedRawImageTime < mKeptSavedRawImageTime)
|
||||
|
|
@ -3029,6 +2800,11 @@ LLImageRaw* LLViewerFetchedTexture::getSavedRawImage()
|
|||
return mSavedRawImage;
|
||||
}
|
||||
|
||||
const LLImageRaw* LLViewerFetchedTexture::getSavedRawImage() const
|
||||
{
|
||||
return mSavedRawImage;
|
||||
}
|
||||
|
||||
bool LLViewerFetchedTexture::hasSavedRawImage() const
|
||||
{
|
||||
return mSavedRawImage.notNull();
|
||||
|
|
@ -3205,20 +2981,14 @@ void LLViewerLODTexture::processTextureStats()
|
|||
|
||||
bool LLViewerLODTexture::scaleDown()
|
||||
{
|
||||
if(hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel())
|
||||
if (mGLTexturep.isNull())
|
||||
{
|
||||
switchToCachedImage();
|
||||
|
||||
LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
|
||||
if (tester)
|
||||
{
|
||||
tester->setStablizingTime();
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
return mGLTexturep->scaleDown(mDesiredDiscardLevel);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
//end of LLViewerLODTexture
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -166,8 +166,6 @@ public:
|
|||
S32 getNumVolumes(U32 channel) const;
|
||||
const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; }
|
||||
|
||||
|
||||
virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
|
||||
bool isLargeImage() ;
|
||||
|
||||
void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;}
|
||||
|
|
@ -185,8 +183,6 @@ private:
|
|||
friend class LLBumpImageList;
|
||||
friend class LLUIImageList;
|
||||
|
||||
virtual void switchToCachedImage();
|
||||
|
||||
protected:
|
||||
friend class LLViewerTextureList;
|
||||
LLUUID mID;
|
||||
|
|
@ -371,7 +367,6 @@ public:
|
|||
U32 getFetchPriority() const { return mFetchPriority ;}
|
||||
F32 getDownloadProgress() const {return mDownloadProgress ;}
|
||||
|
||||
LLImageRaw* reloadRawImage(S8 discard_level) ;
|
||||
void destroyRawImage();
|
||||
bool needsToSaveRawImage();
|
||||
|
||||
|
|
@ -390,17 +385,20 @@ public:
|
|||
bool isForSculptOnly() const;
|
||||
|
||||
//raw image management
|
||||
void checkCachedRawSculptImage() ;
|
||||
LLImageRaw* getRawImage()const { return mRawImage ;}
|
||||
S32 getRawImageLevel() const {return mRawDiscardLevel;}
|
||||
LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;}
|
||||
S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;}
|
||||
bool isCachedRawImageReady() const {return mCachedRawImageReady ;}
|
||||
bool isRawImageValid()const { return mIsRawImageValid ; }
|
||||
void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ;
|
||||
/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override;
|
||||
|
||||
// readback the raw image from OpenGL if mRawImage is not valid
|
||||
void readbackRawImage();
|
||||
|
||||
void destroySavedRawImage() ;
|
||||
LLImageRaw* getSavedRawImage() ;
|
||||
S32 getSavedRawImageLevel() const {return mSavedRawDiscardLevel; }
|
||||
|
||||
const LLImageRaw* getSavedRawImage() const;
|
||||
const LLImageRaw* getAuxRawImage() const { return mAuxRawImage; }
|
||||
bool hasSavedRawImage() const ;
|
||||
F32 getElapsedLastReferencedSavedRawImageTime() const ;
|
||||
bool isFullyLoaded() const;
|
||||
|
|
@ -417,7 +415,6 @@ public:
|
|||
/*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline.
|
||||
|
||||
protected:
|
||||
/*virtual*/ void switchToCachedImage() override;
|
||||
S32 getCurrentDiscardLevelForFetching() ;
|
||||
void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f);
|
||||
|
||||
|
|
@ -426,7 +423,6 @@ private:
|
|||
void cleanup() ;
|
||||
|
||||
void saveRawImage() ;
|
||||
void setCachedRawImage() ;
|
||||
|
||||
//for atlas
|
||||
void resetFaceAtlas() ;
|
||||
|
|
@ -498,11 +494,6 @@ protected:
|
|||
F32 mLastReferencedSavedRawImageTime ;
|
||||
F32 mKeptSavedRawImageTime ;
|
||||
|
||||
//a small version of the copy of the raw image (<= 64 * 64)
|
||||
LLPointer<LLImageRaw> mCachedRawImage;
|
||||
S32 mCachedRawDiscardLevel;
|
||||
bool mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit.
|
||||
|
||||
LLHost mTargetHost; // if invalid, just request from agent's simulator
|
||||
|
||||
// Timers
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ void LLViewerTextureList::shutdown()
|
|||
// Write out list of currently loaded textures for precaching on startup
|
||||
typedef std::set<std::pair<S32,LLViewerFetchedTexture*> > image_area_list_t;
|
||||
image_area_list_t image_area_list;
|
||||
for (image_priority_list_t::iterator iter = mImageList.begin();
|
||||
for (image_list_t::iterator iter = mImageList.begin();
|
||||
iter != mImageList.end(); ++iter)
|
||||
{
|
||||
LLViewerFetchedTexture* image = *iter;
|
||||
|
|
@ -367,7 +367,7 @@ void LLViewerTextureList::dump()
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LL_INFOS() << "LLViewerTextureList::dump()" << LL_ENDL;
|
||||
for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it)
|
||||
for (image_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it)
|
||||
{
|
||||
LLViewerFetchedTexture* image = *it;
|
||||
|
||||
|
|
@ -381,15 +381,9 @@ void LLViewerTextureList::dump()
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerTextureList::destroyGL(bool save_state)
|
||||
void LLViewerTextureList::destroyGL()
|
||||
{
|
||||
LLImageGL::destroyGL(save_state);
|
||||
}
|
||||
|
||||
void LLViewerTextureList::restoreGL()
|
||||
{
|
||||
llassert_always(mInitialized) ;
|
||||
LLImageGL::restoreGL();
|
||||
LLImageGL::destroyGL();
|
||||
}
|
||||
|
||||
/* Vertical tab container button image IDs
|
||||
|
|
@ -895,7 +889,7 @@ void LLViewerTextureList::clearFetchingRequests()
|
|||
|
||||
LLAppViewer::getTextureFetch()->deleteAllRequests();
|
||||
|
||||
for (image_priority_list_t::iterator iter = mImageList.begin();
|
||||
for (image_list_t::iterator iter = mImageList.begin();
|
||||
iter != mImageList.end(); ++iter)
|
||||
{
|
||||
LLViewerFetchedTexture* imagep = *iter;
|
||||
|
|
@ -1208,7 +1202,7 @@ void LLViewerTextureList::updateImagesUpdateStats()
|
|||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if (mForceResetTextureStats)
|
||||
{
|
||||
for (image_priority_list_t::iterator iter = mImageList.begin();
|
||||
for (image_list_t::iterator iter = mImageList.begin();
|
||||
iter != mImageList.end(); )
|
||||
{
|
||||
LLViewerFetchedTexture* imagep = *iter++;
|
||||
|
|
@ -1228,7 +1222,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
|
|||
|
||||
// Update texture stats and priorities
|
||||
std::vector<LLPointer<LLViewerFetchedTexture> > image_list;
|
||||
for (image_priority_list_t::iterator iter = mImageList.begin();
|
||||
for (image_list_t::iterator iter = mImageList.begin();
|
||||
iter != mImageList.end(); )
|
||||
{
|
||||
LLViewerFetchedTexture* imagep = *iter++;
|
||||
|
|
@ -1248,7 +1242,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
|
|||
image_list.clear();
|
||||
|
||||
// Update fetch (decode)
|
||||
for (image_priority_list_t::iterator iter = mImageList.begin();
|
||||
for (image_list_t::iterator iter = mImageList.begin();
|
||||
iter != mImageList.end(); )
|
||||
{
|
||||
LLViewerFetchedTexture* imagep = *iter++;
|
||||
|
|
@ -1275,7 +1269,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
|
|||
}
|
||||
}
|
||||
// Update fetch again
|
||||
for (image_priority_list_t::iterator iter = mImageList.begin();
|
||||
for (image_list_t::iterator iter = mImageList.begin();
|
||||
iter != mImageList.end(); )
|
||||
{
|
||||
LLViewerFetchedTexture* imagep = *iter++;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
#include "llviewertexture.h"
|
||||
#include "llui.h"
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include "lluiimage.h"
|
||||
|
||||
const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128;
|
||||
|
|
@ -115,8 +115,7 @@ public:
|
|||
void init();
|
||||
void shutdown();
|
||||
void dump();
|
||||
void destroyGL(bool save_state = true);
|
||||
void restoreGL();
|
||||
void destroyGL();
|
||||
bool isInitialized() const {return mInitialized;}
|
||||
|
||||
void findTexturesByID(const LLUUID &image_id, std::vector<LLViewerFetchedTexture*> &output);
|
||||
|
|
@ -188,7 +187,7 @@ private:
|
|||
LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation.
|
||||
S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
|
||||
LLGLint internal_format = 0,
|
||||
LLGLenum primary_format = 0,
|
||||
LLGLenum primary_format = 0,
|
||||
const LLUUID& force_id = LLUUID::null
|
||||
);
|
||||
|
||||
|
|
@ -211,7 +210,7 @@ private:
|
|||
{ return getImage(image_id, f_type, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }
|
||||
|
||||
public:
|
||||
typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t;
|
||||
typedef std::unordered_set<LLPointer<LLViewerFetchedTexture> > image_list_t;
|
||||
image_list_t mLoadingStreamList;
|
||||
image_list_t mCreateTextureList;
|
||||
image_list_t mCallbackList;
|
||||
|
|
@ -222,16 +221,19 @@ public:
|
|||
|
||||
bool mForceResetTextureStats;
|
||||
|
||||
// to make "for (auto& imagep : gTextureList)" work
|
||||
const image_list_t::iterator begin() const { return mImageList.begin(); }
|
||||
const image_list_t::iterator end() const { return mImageList.end(); }
|
||||
|
||||
private:
|
||||
typedef std::map< LLTextureKey, LLPointer<LLViewerFetchedTexture> > uuid_map_t;
|
||||
uuid_map_t mUUIDMap;
|
||||
LLTextureKey mLastUpdateKey;
|
||||
|
||||
typedef std::set < LLPointer<LLViewerFetchedTexture> > image_priority_list_t;
|
||||
image_priority_list_t mImageList;
|
||||
image_list_t mImageList;
|
||||
|
||||
// simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon
|
||||
std::set<LLPointer<LLViewerFetchedTexture> > mImagePreloads;
|
||||
std::unordered_set<LLPointer<LLViewerFetchedTexture> > mImagePreloads;
|
||||
|
||||
bool mInitialized ;
|
||||
LLFrameTimer mForceDecodeTimer;
|
||||
|
|
|
|||
|
|
@ -1827,10 +1827,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
|
|||
mToolStored( NULL ),
|
||||
mHideCursorPermanent( false ),
|
||||
mCursorHidden(false),
|
||||
mIgnoreActivate( false ),
|
||||
mResDirty(false),
|
||||
mStatesDirty(false),
|
||||
mCurrResolutionIndex(0),
|
||||
mProgressView(NULL)
|
||||
{
|
||||
// gKeyboard is still NULL, so it doesn't do LLWindowListener any good to
|
||||
|
|
@ -2402,7 +2400,7 @@ void LLViewerWindow::shutdownGL()
|
|||
LLSelectMgr::getInstance()->cleanup();
|
||||
|
||||
LL_INFOS() << "Stopping GL during shutdown" << LL_ENDL;
|
||||
stopGL(false);
|
||||
stopGL();
|
||||
stop_glerror();
|
||||
|
||||
gGL.shutdown();
|
||||
|
|
@ -5715,7 +5713,7 @@ void LLViewerWindow::dumpState()
|
|||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
void LLViewerWindow::stopGL(bool save_state)
|
||||
void LLViewerWindow::stopGL()
|
||||
{
|
||||
//Note: --bao
|
||||
//if not necessary, do not change the order of the function calls in this function.
|
||||
|
|
@ -5761,7 +5759,7 @@ void LLViewerWindow::stopGL(bool save_state)
|
|||
gPostProcess->invalidate();
|
||||
}
|
||||
|
||||
gTextureList.destroyGL(save_state);
|
||||
gTextureList.destroyGL();
|
||||
stop_glerror();
|
||||
|
||||
gGLManager.mIsDisabled = true;
|
||||
|
|
@ -5778,6 +5776,14 @@ void LLViewerWindow::stopGL(bool save_state)
|
|||
|
||||
void LLViewerWindow::restoreGL(const std::string& progress_message)
|
||||
{
|
||||
llassert(false);
|
||||
// DEPRECATED -- this is left over from when we would completely destroy and restore a GL context
|
||||
// when switching from windowed to fullscreen. None of this machinery has been exercised in years
|
||||
// and is unreliable. If we ever *do* have another use case where completely unloading and reloading
|
||||
// everthing is necessary, requiring a viewer restart for that operation is a fine thing to do.
|
||||
// -- davep
|
||||
|
||||
|
||||
//Note: --bao
|
||||
//if not necessary, do not change the order of the function calls in this function.
|
||||
//if change something, make sure it will not break anything.
|
||||
|
|
@ -5790,8 +5796,6 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
|
|||
initGLDefaults();
|
||||
LLGLState::restoreGL();
|
||||
|
||||
gTextureList.restoreGL();
|
||||
|
||||
// for future support of non-square pixels, and fonts that are properly stretched
|
||||
//LLFontGL::destroyDefaultFonts();
|
||||
initFonts();
|
||||
|
|
@ -5867,122 +5871,6 @@ void LLViewerWindow::checkSettings()
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerWindow::restartDisplay(bool show_progress_bar)
|
||||
{
|
||||
LL_INFOS() << "Restaring GL" << LL_ENDL;
|
||||
stopGL();
|
||||
if (show_progress_bar)
|
||||
{
|
||||
restoreGL(LLTrans::getString("ProgressChangingResolution"));
|
||||
}
|
||||
else
|
||||
{
|
||||
restoreGL();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLViewerWindow::changeDisplaySettings(LLCoordScreen size, bool enable_vsync, bool show_progress_bar)
|
||||
{
|
||||
//bool was_maximized = gSavedSettings.getBOOL("WindowMaximized");
|
||||
|
||||
//gResizeScreenTexture = true;
|
||||
|
||||
|
||||
//U32 fsaa = gSavedSettings.getU32("RenderFSAASamples");
|
||||
//U32 old_fsaa = mWindow->getFSAASamples();
|
||||
|
||||
// if not maximized, use the request size
|
||||
if (!mWindow->getMaximized())
|
||||
{
|
||||
mWindow->setSize(size);
|
||||
}
|
||||
|
||||
//if (fsaa == old_fsaa)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
// Close floaters that don't handle settings change
|
||||
LLFloaterReg::hideInstance("snapshot");
|
||||
|
||||
bool result_first_try = false;
|
||||
bool result_second_try = false;
|
||||
|
||||
LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
|
||||
send_agent_pause();
|
||||
LL_INFOS() << "Stopping GL during changeDisplaySettings" << LL_ENDL;
|
||||
stopGL();
|
||||
mIgnoreActivate = true;
|
||||
LLCoordScreen old_size;
|
||||
LLCoordScreen old_pos;
|
||||
mWindow->getSize(&old_size);
|
||||
|
||||
//mWindow->setFSAASamples(fsaa);
|
||||
|
||||
result_first_try = mWindow->switchContext(false, size, disable_vsync);
|
||||
if (!result_first_try)
|
||||
{
|
||||
// try to switch back
|
||||
//mWindow->setFSAASamples(old_fsaa);
|
||||
result_second_try = mWindow->switchContext(false, old_size, disable_vsync);
|
||||
|
||||
if (!result_second_try)
|
||||
{
|
||||
// we are stuck...try once again with a minimal resolution?
|
||||
send_agent_resume();
|
||||
mIgnoreActivate = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
send_agent_resume();
|
||||
|
||||
LL_INFOS() << "Restoring GL during resolution change" << LL_ENDL;
|
||||
if (show_progress_bar)
|
||||
{
|
||||
restoreGL(LLTrans::getString("ProgressChangingResolution"));
|
||||
}
|
||||
else
|
||||
{
|
||||
restoreGL();
|
||||
}
|
||||
|
||||
if (!result_first_try)
|
||||
{
|
||||
LLSD args;
|
||||
args["RESX"] = llformat("%d",size.mX);
|
||||
args["RESY"] = llformat("%d",size.mY);
|
||||
LLNotificationsUtil::add("ResolutionSwitchFail", args);
|
||||
size = old_size; // for reshape below
|
||||
}
|
||||
|
||||
bool success = result_first_try || result_second_try;
|
||||
|
||||
if (success)
|
||||
{
|
||||
// maximize window if was maximized, else reposition
|
||||
if (was_maximized)
|
||||
{
|
||||
mWindow->maximize();
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 windowX = gSavedSettings.getS32("WindowX");
|
||||
S32 windowY = gSavedSettings.getS32("WindowY");
|
||||
|
||||
mWindow->setPosition(LLCoordScreen ( windowX, windowY ) );
|
||||
}
|
||||
}
|
||||
|
||||
mIgnoreActivate = false;
|
||||
gFocusMgr.setKeyboardFocus(keyboard_focus);
|
||||
|
||||
return success;
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
F32 LLViewerWindow::getWorldViewAspectRatio() const
|
||||
{
|
||||
F32 world_aspect = (F32)mWorldViewRectRaw.getWidth() / (F32)mWorldViewRectRaw.getHeight();
|
||||
|
|
|
|||
|
|
@ -455,9 +455,7 @@ public:
|
|||
// handle shutting down GL and bringing it back up
|
||||
void requestResolutionUpdate();
|
||||
void checkSettings();
|
||||
void restartDisplay(bool show_progress_bar);
|
||||
bool changeDisplaySettings(LLCoordScreen size, bool enable_vsync, bool show_progress_bar);
|
||||
bool getIgnoreDestroyWindow() { return mIgnoreActivate; }
|
||||
|
||||
F32 getWorldViewAspectRatio() const;
|
||||
const LLVector2& getDisplayScale() const { return mDisplayScale; }
|
||||
void calcDisplayScale();
|
||||
|
|
@ -471,7 +469,7 @@ private:
|
|||
void switchToolByMask(MASK mask);
|
||||
void destroyWindow();
|
||||
void drawMouselookInstructions();
|
||||
void stopGL(bool save_state = true);
|
||||
void stopGL();
|
||||
void restoreGL(const std::string& progress_message = LLStringUtil::null);
|
||||
void initFonts(F32 zoom_factor = 1.f);
|
||||
void schedulePick(LLPickInfo& pick_info);
|
||||
|
|
@ -528,8 +526,6 @@ private:
|
|||
|
||||
std::string mOverlayTitle; // Used for special titles such as "Second Life - Special E3 2003 Beta"
|
||||
|
||||
bool mIgnoreActivate;
|
||||
|
||||
std::string mInitAlert; // Window / GL initialization requires an alert
|
||||
|
||||
LLHandle<LLView> mWorldViewPlaceholder; // widget that spans the portion of screen dedicated to rendering the 3d world
|
||||
|
|
@ -542,7 +538,6 @@ private:
|
|||
|
||||
bool mResDirty;
|
||||
bool mStatesDirty;
|
||||
U32 mCurrResolutionIndex;
|
||||
|
||||
std::unique_ptr<LLWindowListener> mWindowListener;
|
||||
std::unique_ptr<LLViewerWindowListener> mViewerWindowListener;
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ bool LLTerrainMaterials::makeMaterialsReady(bool boost, bool strict)
|
|||
// static
|
||||
bool LLTerrainMaterials::makeTextureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost)
|
||||
{
|
||||
llassert(tex);
|
||||
//llassert(tex); ??? maybe ok ???
|
||||
if (!tex) { return false; }
|
||||
|
||||
if (tex->getDiscardLevel() < 0)
|
||||
|
|
@ -571,416 +571,6 @@ 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)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED
|
||||
llassert(mSurfacep);
|
||||
llassert(x >= 0.f);
|
||||
llassert(y >= 0.f);
|
||||
|
||||
///////////////////////////
|
||||
//
|
||||
// Generate raw data arrays for surface textures
|
||||
//
|
||||
//
|
||||
|
||||
// These have already been validated by generateComposition.
|
||||
U8* st_data[ASSET_COUNT];
|
||||
S32 st_data_size[ASSET_COUNT]; // for debugging
|
||||
|
||||
const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR;
|
||||
if (use_textures)
|
||||
{
|
||||
if (!makeTexturesReady(true, true)) { return false; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!makeMaterialsReady(true, true)) { return false; }
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < ASSET_COUNT; i++)
|
||||
{
|
||||
if (mRawImages[i].isNull())
|
||||
{
|
||||
// Read back a raw image for this discard level, if it exists
|
||||
LLViewerFetchedTexture* tex;
|
||||
LLViewerFetchedTexture* tex_emissive; // Can be null
|
||||
bool has_base_color_factor;
|
||||
bool has_emissive_factor;
|
||||
bool has_alpha;
|
||||
LLColor3 base_color_factor;
|
||||
LLColor3 emissive_factor;
|
||||
if (use_textures)
|
||||
{
|
||||
tex = mDetailTextures[i];
|
||||
tex_emissive = nullptr;
|
||||
has_base_color_factor = false;
|
||||
has_emissive_factor = false;
|
||||
has_alpha = false;
|
||||
llassert(tex);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPointer<LLFetchedGLTFMaterial>& mat = mDetailRenderMaterials[i];
|
||||
tex = mat->mBaseColorTexture;
|
||||
tex_emissive = mat->mEmissiveTexture;
|
||||
base_color_factor = LLColor3(mat->mBaseColor);
|
||||
// *HACK: Treat alpha as black
|
||||
base_color_factor *= (mat->mBaseColor.mV[VW]);
|
||||
emissive_factor = mat->mEmissiveColor;
|
||||
has_base_color_factor = (base_color_factor.mV[VX] != 1.f ||
|
||||
base_color_factor.mV[VY] != 1.f ||
|
||||
base_color_factor.mV[VZ] != 1.f);
|
||||
has_emissive_factor = (emissive_factor.mV[VX] != 1.f ||
|
||||
emissive_factor.mV[VY] != 1.f ||
|
||||
emissive_factor.mV[VZ] != 1.f);
|
||||
has_alpha = mat->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_OPAQUE;
|
||||
}
|
||||
|
||||
if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; }
|
||||
|
||||
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
|
||||
|
||||
// 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
|
||||
// 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 = mRawImagesEmissive[i];
|
||||
if (has_emissive_factor ||
|
||||
tex_emissive->getWidth(tex_emissive->getRawImageLevel()) != BASE_SIZE ||
|
||||
tex_emissive->getHeight(tex_emissive->getRawImageLevel()) != BASE_SIZE ||
|
||||
tex_emissive->getComponents() != 4)
|
||||
{
|
||||
LLPointer<LLImageRaw> newraw_emissive = new LLImageRaw(BASE_SIZE, BASE_SIZE, 4);
|
||||
// Copy RGB, leave alpha alone (set to opaque by default)
|
||||
newraw_emissive->copy(mRawImagesEmissive[i]);
|
||||
if (has_emissive_factor)
|
||||
{
|
||||
newraw_emissive->tint(emissive_factor);
|
||||
}
|
||||
raw_emissive = newraw_emissive;
|
||||
}
|
||||
}
|
||||
if (has_base_color_factor ||
|
||||
raw_emissive ||
|
||||
has_alpha ||
|
||||
tex->getWidth(tex->getRawImageLevel()) != BASE_SIZE ||
|
||||
tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE ||
|
||||
tex->getComponents() != 3)
|
||||
{
|
||||
LLPointer<LLImageRaw> newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3);
|
||||
if (has_alpha)
|
||||
{
|
||||
// Approximate the water underneath terrain alpha with solid water color
|
||||
newraw->clear(
|
||||
MAX_WATER_COLOR.mV[VX],
|
||||
MAX_WATER_COLOR.mV[VY],
|
||||
MAX_WATER_COLOR.mV[VZ],
|
||||
255);
|
||||
}
|
||||
newraw->composite(mRawImagesBaseColor[i]);
|
||||
if (has_base_color_factor)
|
||||
{
|
||||
newraw->tint(base_color_factor);
|
||||
}
|
||||
// Apply emissive texture
|
||||
if (raw_emissive)
|
||||
{
|
||||
newraw->addEmissive(raw_emissive);
|
||||
}
|
||||
|
||||
mRawImages[i] = newraw; // deletes old
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
// Generate and clamp x/y bounding box.
|
||||
//
|
||||
//
|
||||
|
||||
S32 x_begin, y_begin, x_end, y_end;
|
||||
x_begin = (S32)(x * mScaleInv);
|
||||
y_begin = (S32)(y * mScaleInv);
|
||||
x_end = ll_round( (x + width) * mScaleInv );
|
||||
y_end = ll_round( (y + width) * mScaleInv );
|
||||
|
||||
if (x_end > mWidth)
|
||||
{
|
||||
llassert(false);
|
||||
x_end = mWidth;
|
||||
}
|
||||
if (y_end > mWidth)
|
||||
{
|
||||
llassert(false);
|
||||
y_end = mWidth;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// Generate target texture information, stride ratios.
|
||||
//
|
||||
//
|
||||
|
||||
LLViewerTexture *texturep;
|
||||
U32 tex_width, tex_height, tex_comps;
|
||||
U32 tex_stride;
|
||||
F32 tex_x_scalef, tex_y_scalef;
|
||||
S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end;
|
||||
F32 tex_x_ratiof, tex_y_ratiof;
|
||||
|
||||
texturep = mSurfacep->getSTexture();
|
||||
tex_width = texturep->getWidth();
|
||||
tex_height = texturep->getHeight();
|
||||
tex_comps = texturep->getComponents();
|
||||
tex_stride = tex_width * tex_comps;
|
||||
|
||||
U32 st_comps = 3;
|
||||
U32 st_width = BASE_SIZE;
|
||||
U32 st_height = BASE_SIZE;
|
||||
|
||||
if (tex_comps != st_comps)
|
||||
{
|
||||
llassert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
tex_x_scalef = (F32)tex_width / (F32)mWidth;
|
||||
tex_y_scalef = (F32)tex_height / (F32)mWidth;
|
||||
tex_x_begin = (S32)((F32)x_begin * tex_x_scalef);
|
||||
tex_y_begin = (S32)((F32)y_begin * tex_y_scalef);
|
||||
tex_x_end = (S32)((F32)x_end * tex_x_scalef);
|
||||
tex_y_end = (S32)((F32)y_end * tex_y_scalef);
|
||||
|
||||
tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width;
|
||||
tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height;
|
||||
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
|
||||
U8 *rawp = raw->getData();
|
||||
|
||||
F32 st_x_stride, st_y_stride;
|
||||
st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width);
|
||||
st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height);
|
||||
|
||||
llassert(st_x_stride > 0.f);
|
||||
llassert(st_y_stride > 0.f);
|
||||
////////////////////////////////
|
||||
//
|
||||
// Iterate through the target texture, striding through the
|
||||
// subtextures and interpolating appropriately.
|
||||
//
|
||||
//
|
||||
|
||||
F32 sti, stj;
|
||||
S32 st_offset;
|
||||
sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width));
|
||||
stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height));
|
||||
|
||||
st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps;
|
||||
for (S32 j = tex_y_begin; j < tex_y_end; j++)
|
||||
{
|
||||
U32 offset = j * tex_stride + tex_x_begin * tex_comps;
|
||||
sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width);
|
||||
for (S32 i = tex_x_begin; i < tex_x_end; i++)
|
||||
{
|
||||
S32 tex0, tex1;
|
||||
F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof);
|
||||
|
||||
tex0 = llfloor( composition );
|
||||
tex0 = llclamp(tex0, 0, 3);
|
||||
composition -= tex0;
|
||||
tex1 = tex0 + 1;
|
||||
tex1 = llclamp(tex1, 0, 3);
|
||||
|
||||
st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps;
|
||||
for (U32 k = 0; k < tex_comps; k++)
|
||||
{
|
||||
// Linearly interpolate based on composition.
|
||||
if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1])
|
||||
{
|
||||
// SJB: This shouldn't be happening, but does... Rounding error?
|
||||
//LL_WARNS() << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << LL_ENDL;
|
||||
//LL_WARNS() << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 a = *(st_data[tex0] + st_offset);
|
||||
F32 b = *(st_data[tex1] + st_offset);
|
||||
rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) );
|
||||
}
|
||||
offset++;
|
||||
st_offset++;
|
||||
}
|
||||
|
||||
sti += st_x_stride;
|
||||
if (sti >= st_width)
|
||||
{
|
||||
sti -= st_width;
|
||||
}
|
||||
}
|
||||
|
||||
stj += st_y_stride;
|
||||
if (stj >= st_height)
|
||||
{
|
||||
stj -= st_height;
|
||||
}
|
||||
}
|
||||
|
||||
if (!texturep->hasGLTexture())
|
||||
{
|
||||
texturep->createGLTexture(0, raw);
|
||||
}
|
||||
texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin);
|
||||
|
||||
// Un-boost detail textures (will get re-boosted if rendering in high detail)
|
||||
for (S32 i = 0; i < ASSET_COUNT; i++)
|
||||
{
|
||||
unboost_minimap_texture(mDetailTextures[i]);
|
||||
}
|
||||
|
||||
// Un-boost textures for each detail material (will get re-boosted if rendering in high detail)
|
||||
for (S32 i = 0; i < ASSET_COUNT; i++)
|
||||
{
|
||||
unboost_minimap_material(mDetailMaterials[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
F32 LLVLComposition::getStartHeight(S32 corner)
|
||||
{
|
||||
return mStartHeight[corner];
|
||||
|
|
|
|||
|
|
@ -114,8 +114,6 @@ public:
|
|||
// Viewer side hack to generate composition values
|
||||
bool generateHeights(const F32 x, const F32 y, const F32 width, const F32 height);
|
||||
bool generateComposition();
|
||||
// Generate texture from composition values.
|
||||
bool generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height);
|
||||
|
||||
// Use these as indeces ito the get/setters below that use 'corner'
|
||||
enum ECorner
|
||||
|
|
|
|||
|
|
@ -851,19 +851,9 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
|
|||
|
||||
if (mSculptTexture.notNull())
|
||||
{
|
||||
mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
|
||||
(S32)LLGLTexture::BOOST_SCULPTED));
|
||||
mSculptTexture->setForSculpt() ;
|
||||
|
||||
if(!mSculptTexture->isCachedRawImageReady())
|
||||
{
|
||||
S32 lod = llmin(mLOD, 3);
|
||||
F32 lodf = ((F32)(lod + 1.0f)/4.f);
|
||||
F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ;
|
||||
mSculptTexture->addTextureStats(2.f * tex_size * tex_size, false);
|
||||
}
|
||||
|
||||
S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture
|
||||
S32 texture_discard = mSculptTexture->getRawImageLevel(); //try to match the texture
|
||||
S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ;
|
||||
|
||||
if (texture_discard >= 0 && //texture has some data available
|
||||
|
|
@ -1159,7 +1149,9 @@ void LLVOVolume::updateSculptTexture()
|
|||
LLUUID id = sculpt_params->getSculptTexture();
|
||||
if (id.notNull())
|
||||
{
|
||||
mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, true, LLGLTexture::BOOST_SCULPTED, LLViewerTexture::LOD_TEXTURE);
|
||||
mSculptTexture->forceToSaveRawImage(0, F32_MAX);
|
||||
mSculptTexture->addTextureStats(256.f*256.f);
|
||||
}
|
||||
|
||||
mSkinInfoUnavaliable = false;
|
||||
|
|
@ -1252,8 +1244,22 @@ void LLVOVolume::sculpt()
|
|||
S8 sculpt_components = 0;
|
||||
const U8* sculpt_data = NULL;
|
||||
|
||||
S32 discard_level = mSculptTexture->getCachedRawImageLevel() ;
|
||||
LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ;
|
||||
S32 discard_level = mSculptTexture->getRawImageLevel() ;
|
||||
LLImageRaw* raw_image = mSculptTexture->getRawImage() ;
|
||||
|
||||
if (!raw_image)
|
||||
{
|
||||
raw_image = mSculptTexture->getSavedRawImage();
|
||||
S32 discard_level = mSculptTexture->getSavedRawImageLevel();
|
||||
}
|
||||
|
||||
if (!raw_image)
|
||||
{
|
||||
// last resort, read back from GL
|
||||
mSculptTexture->readbackRawImage();
|
||||
raw_image = mSculptTexture->getRawImage();
|
||||
discard_level = mSculptTexture->getRawImageLevel();
|
||||
}
|
||||
|
||||
S32 max_discard = mSculptTexture->getMaxDiscardLevel();
|
||||
if (discard_level > max_discard)
|
||||
|
|
@ -1310,8 +1316,6 @@ void LLVOVolume::sculpt()
|
|||
|
||||
if(!raw_image)
|
||||
{
|
||||
llassert(discard_level < 0) ;
|
||||
|
||||
sculpt_width = 0;
|
||||
sculpt_height = 0;
|
||||
sculpt_data = NULL ;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ LLVOWater::LLVOWater(const LLUUID &id,
|
|||
mbCanSelect = false;
|
||||
setScale(LLVector3(256.f, 256.f, 0.f)); // Hack for setting scale for bounding boxes/visibility.
|
||||
|
||||
mUseTexture = true;
|
||||
mIsEdgePatch = false;
|
||||
}
|
||||
|
||||
|
|
@ -101,14 +100,7 @@ LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline)
|
|||
|
||||
LLDrawPoolWater *pool = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
|
||||
|
||||
if (mUseTexture)
|
||||
{
|
||||
mDrawable->setNumFaces(1, pool, mRegionp->getLand().getWaterTexture());
|
||||
}
|
||||
else
|
||||
{
|
||||
mDrawable->setNumFaces(1, pool, LLWorld::getInstance()->getDefaultWaterTexture());
|
||||
}
|
||||
mDrawable->setNumFaces(1, pool, LLWorld::getInstance()->getDefaultWaterTexture());
|
||||
|
||||
return mDrawable;
|
||||
}
|
||||
|
|
@ -249,11 +241,6 @@ void setVecZ(LLVector3& v)
|
|||
v.mV[VZ] = 1;
|
||||
}
|
||||
|
||||
void LLVOWater::setUseTexture(const bool use_texture)
|
||||
{
|
||||
mUseTexture = use_texture;
|
||||
}
|
||||
|
||||
void LLVOWater::setIsEdgePatch(const bool edge_patch)
|
||||
{
|
||||
mIsEdgePatch = edge_patch;
|
||||
|
|
|
|||
|
|
@ -70,13 +70,10 @@ public:
|
|||
|
||||
/*virtual*/ bool isActive() const; // Whether this object needs to do an idleUpdate.
|
||||
|
||||
void setUseTexture(const bool use_texture);
|
||||
void setIsEdgePatch(const bool edge_patch);
|
||||
bool getUseTexture() const { return mUseTexture; }
|
||||
bool getIsEdgePatch() const { return mIsEdgePatch; }
|
||||
|
||||
protected:
|
||||
bool mUseTexture;
|
||||
bool mIsEdgePatch;
|
||||
S32 mRenderType;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -961,7 +961,6 @@ void LLWorld::updateWaterObjects()
|
|||
if (!getRegionFromHandle(region_handle))
|
||||
{ // No region at that area, so make water
|
||||
LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion());
|
||||
waterp->setUseTexture(false);
|
||||
waterp->setPositionGlobal(LLVector3d(x + rwidth/2,
|
||||
y + rwidth/2,
|
||||
256.f + water_height));
|
||||
|
|
@ -1015,7 +1014,6 @@ void LLWorld::updateWaterObjects()
|
|||
mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER,
|
||||
gAgent.getRegion());
|
||||
waterp = mEdgeWaterObjects[dir];
|
||||
waterp->setUseTexture(false);
|
||||
waterp->setIsEdgePatch(true);
|
||||
gPipeline.createObject(waterp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32
|
|||
}
|
||||
}
|
||||
|
||||
//static
|
||||
LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32 grid_y, S32 level)
|
||||
{
|
||||
// Get the grid coordinates
|
||||
|
|
|
|||
|
|
@ -74,11 +74,13 @@ public:
|
|||
// Convert world coordinates to mipmap grid coordinates at a given level
|
||||
static void globalToMipmap(F64 global_x, F64 global_y, S32 level, U32* grid_x, U32* grid_y);
|
||||
|
||||
// Load the relevant tile from S3
|
||||
static LLPointer<LLViewerFetchedTexture> loadObjectsTile(U32 grid_x, U32 grid_y, S32 level);
|
||||
|
||||
private:
|
||||
// Get a handle (key) from grid coordinates
|
||||
U64 convertGridToHandle(U32 grid_x, U32 grid_y) { return to_region_handle(grid_x * REGION_WIDTH_UNITS, grid_y * REGION_WIDTH_UNITS); }
|
||||
// Load the relevant tile from S3
|
||||
LLPointer<LLViewerFetchedTexture> loadObjectsTile(U32 grid_x, U32 grid_y, S32 level);
|
||||
|
||||
// Clear a level from its "missing" tiles
|
||||
void cleanMissedTilesFromLevel(S32 level);
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
d7915d67467e59287857630bd89bf9529d065199
|
||||
d7915d67467e59287857630bd89bf9529d065199
|
||||
Loading…
Reference in New Issue