NORSPEC-54 Potential fix for crashing on all sorts of random operations.
parent
6620c1f824
commit
41ca92c67c
|
|
@ -262,6 +262,14 @@ class LLRender
|
|||
friend class LLTexUnit;
|
||||
public:
|
||||
|
||||
enum eTexIndex
|
||||
{
|
||||
DIFFUSE_MAP = 0,
|
||||
NORMAL_MAP,
|
||||
SPECULAR_MAP,
|
||||
NUM_TEXTURE_CHANNELS,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TRIANGLES = 0,
|
||||
TRIANGLE_STRIP,
|
||||
|
|
|
|||
|
|
@ -3182,17 +3182,6 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>EnableTextureAtlas</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to use texture atlas or not</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>EnableUIHints</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
#include "llviewerregion.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewershadermgr.h"
|
||||
|
||||
#include "llviewertexture.h"
|
||||
|
||||
#define LL_MAX_INDICES_COUNT 1000000
|
||||
|
||||
|
|
@ -167,8 +167,12 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
|
|||
//special value to indicate uninitialized position
|
||||
mIndicesIndex = 0xFFFFFFFF;
|
||||
|
||||
mIndexInTex = 0;
|
||||
mTexture = NULL;
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
mIndexInTex[i] = 0;
|
||||
mTexture[i] = NULL;
|
||||
}
|
||||
|
||||
mTEOffset = -1;
|
||||
mTextureIndex = 255;
|
||||
|
||||
|
|
@ -185,8 +189,6 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
|
|||
mImportanceToCamera = 0.f ;
|
||||
mBoundingSphereRadius = 0.0f ;
|
||||
|
||||
mAtlasInfop = NULL ;
|
||||
mUsingAtlas = FALSE ;
|
||||
mHasMedia = FALSE ;
|
||||
}
|
||||
|
||||
|
|
@ -197,9 +199,12 @@ void LLFace::destroy()
|
|||
gPipeline.checkReferences(this);
|
||||
}
|
||||
|
||||
if(mTexture.notNull())
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
mTexture->removeFace(this) ;
|
||||
if(mTexture[i].notNull())
|
||||
{
|
||||
mTexture[i]->removeFace(i, this) ;
|
||||
}
|
||||
}
|
||||
|
||||
if (isState(LLFace::PARTICLE))
|
||||
|
|
@ -239,8 +244,7 @@ void LLFace::destroy()
|
|||
}
|
||||
|
||||
setDrawInfo(NULL);
|
||||
removeAtlas();
|
||||
|
||||
|
||||
mDrawablep = NULL;
|
||||
mVObjp = NULL;
|
||||
}
|
||||
|
|
@ -293,90 +297,76 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
|
|||
setTexture(texturep) ;
|
||||
}
|
||||
|
||||
void LLFace::setTexture(LLViewerTexture* tex)
|
||||
void LLFace::setTexture(U32 ch, LLViewerTexture* tex)
|
||||
{
|
||||
if(mTexture == tex)
|
||||
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
|
||||
|
||||
if(mTexture[ch] == tex)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if(mTexture.notNull())
|
||||
if(mTexture[ch].notNull())
|
||||
{
|
||||
mTexture->removeFace(this) ;
|
||||
removeAtlas() ;
|
||||
mTexture[ch]->removeFace(ch, this) ;
|
||||
}
|
||||
|
||||
if(tex)
|
||||
{
|
||||
tex->addFace(this) ;
|
||||
tex->addFace(ch, this) ;
|
||||
}
|
||||
|
||||
mTexture = tex ;
|
||||
mTexture[ch] = tex ;
|
||||
}
|
||||
|
||||
void LLFace::setTexture(LLViewerTexture* tex)
|
||||
{
|
||||
setDiffuseMap(tex);
|
||||
}
|
||||
|
||||
void LLFace::setDiffuseMap(LLViewerTexture* tex)
|
||||
{
|
||||
setTexture(LLRender::DIFFUSE_MAP, tex);
|
||||
}
|
||||
|
||||
void LLFace::setNormalMap(LLViewerTexture* tex)
|
||||
{
|
||||
if(mNormalMap == tex)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if(mNormalMap.notNull())
|
||||
{
|
||||
mNormalMap->removeFace(this) ;
|
||||
removeAtlas() ;
|
||||
}
|
||||
|
||||
if(tex)
|
||||
{
|
||||
tex->addFace(this) ;
|
||||
}
|
||||
|
||||
mNormalMap = tex ;
|
||||
setTexture(LLRender::NORMAL_MAP, tex);
|
||||
}
|
||||
|
||||
void LLFace::setSpecularMap(LLViewerTexture* tex)
|
||||
{
|
||||
if(mSpecMap == tex)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if(mSpecMap.notNull())
|
||||
{
|
||||
mSpecMap->removeFace(this) ;
|
||||
removeAtlas() ;
|
||||
}
|
||||
|
||||
if(tex)
|
||||
{
|
||||
tex->addFace(this) ;
|
||||
}
|
||||
|
||||
mSpecMap = tex ;
|
||||
setTexture(LLRender::SPECULAR_MAP, tex);
|
||||
}
|
||||
|
||||
void LLFace::dirtyTexture()
|
||||
{
|
||||
LLDrawable* drawablep = getDrawable();
|
||||
|
||||
if (mVObjp.notNull() && mVObjp->getVolume() &&
|
||||
mTexture.notNull() && mTexture->getComponents() == 4)
|
||||
{ //dirty texture on an alpha object should be treated as an LoD update
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
if (vobj)
|
||||
if (mVObjp.notNull() && mVObjp->getVolume())
|
||||
{
|
||||
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
|
||||
{
|
||||
vobj->mLODChanged = TRUE;
|
||||
if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4)
|
||||
{ //dirty texture on an alpha object should be treated as an LoD update
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
if (vobj)
|
||||
{
|
||||
vobj->mLODChanged = TRUE;
|
||||
}
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
|
||||
}
|
||||
}
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
gPipeline.markTextured(drawablep);
|
||||
}
|
||||
|
||||
void LLFace::switchTexture(LLViewerTexture* new_texture)
|
||||
void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
|
||||
{
|
||||
if(mTexture == new_texture)
|
||||
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
|
||||
|
||||
if(mTexture[ch] == new_texture)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
|
@ -386,10 +376,17 @@ void LLFace::switchTexture(LLViewerTexture* new_texture)
|
|||
llerrs << "Can not switch to a null texture." << llendl;
|
||||
return;
|
||||
}
|
||||
new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
|
||||
|
||||
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
|
||||
setTexture(new_texture) ;
|
||||
llassert(mTexture[ch].notNull());
|
||||
|
||||
new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ;
|
||||
|
||||
if (ch == LLRender::DIFFUSE_MAP)
|
||||
{
|
||||
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
|
||||
}
|
||||
|
||||
setTexture(ch, new_texture) ;
|
||||
dirtyTexture();
|
||||
}
|
||||
|
||||
|
|
@ -1293,27 +1290,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
const LLTextureEntry *tep = mVObjp->getTE(f);
|
||||
const U8 bump_code = tep ? tep->getBumpmap() : 0;
|
||||
|
||||
F32 tcoord_xoffset = 0.f ;
|
||||
F32 tcoord_yoffset = 0.f ;
|
||||
F32 tcoord_xscale = 1.f ;
|
||||
F32 tcoord_yscale = 1.f ;
|
||||
BOOL in_atlas = FALSE ;
|
||||
|
||||
if (rebuild_tcoord)
|
||||
{
|
||||
in_atlas = isAtlasInUse() ;
|
||||
if(in_atlas)
|
||||
{
|
||||
const LLVector2* tmp = getTexCoordOffset() ;
|
||||
tcoord_xoffset = tmp->mV[0] ;
|
||||
tcoord_yoffset = tmp->mV[1] ;
|
||||
|
||||
tmp = getTexCoordScale() ;
|
||||
tcoord_xscale = tmp->mV[0] ;
|
||||
tcoord_yscale = tmp->mV[1] ;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL is_static = mDrawablep->isStatic();
|
||||
BOOL is_global = is_static;
|
||||
|
||||
|
|
@ -1598,11 +1574,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
break;
|
||||
case BE_BRIGHTNESS:
|
||||
case BE_DARKNESS:
|
||||
if( mTexture.notNull() && mTexture->hasGLTexture())
|
||||
if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture())
|
||||
{
|
||||
// Offset by approximately one texel
|
||||
S32 cur_discard = mTexture->getDiscardLevel();
|
||||
S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
|
||||
S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel();
|
||||
S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() );
|
||||
max_size <<= cur_discard;
|
||||
const F32 ARTIFICIAL_OFFSET = 2.f;
|
||||
offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
|
||||
|
|
@ -1675,8 +1651,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
|
||||
bool do_tex_mat = tex_mode && mTextureMatrix;
|
||||
|
||||
if (!in_atlas && !do_bump)
|
||||
{ //not in atlas or not bump mapped, might be able to do a cheap update
|
||||
if (!do_bump)
|
||||
{ //not bump mapped, might be able to do a cheap update
|
||||
mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount);
|
||||
|
||||
if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
|
||||
|
|
@ -1728,7 +1704,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
}
|
||||
}
|
||||
else
|
||||
{ //do tex mat, no texgen, no atlas, no bump
|
||||
{ //do tex mat, no texgen, no bump
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector2 tc(vf.mTexCoords[i]);
|
||||
|
|
@ -1744,7 +1720,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
}
|
||||
}
|
||||
else
|
||||
{ //no bump, no atlas, tex gen planar
|
||||
{ //no bump, tex gen planar
|
||||
LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);
|
||||
if (do_tex_mat)
|
||||
{
|
||||
|
|
@ -1789,7 +1765,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
}
|
||||
}
|
||||
else
|
||||
{ //either bump mapped or in atlas, just do the whole expensive loop
|
||||
{ //bump mapped, just do the whole expensive loop
|
||||
LLFastTimer t(FTM_FACE_TEX_DEFAULT);
|
||||
mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);
|
||||
|
||||
|
|
@ -1837,93 +1813,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
|
||||
}
|
||||
|
||||
if(in_atlas)
|
||||
{
|
||||
//
|
||||
//manually calculate tex-coord per vertex for varying address modes.
|
||||
//should be removed if shader can handle this.
|
||||
//
|
||||
|
||||
S32 int_part = 0 ;
|
||||
switch(mTexture->getAddressMode())
|
||||
{
|
||||
case LLTexUnit::TAM_CLAMP:
|
||||
if(tc.mV[0] < 0.f)
|
||||
{
|
||||
tc.mV[0] = 0.f ;
|
||||
}
|
||||
else if(tc.mV[0] > 1.f)
|
||||
{
|
||||
tc.mV[0] = 1.f;
|
||||
}
|
||||
|
||||
if(tc.mV[1] < 0.f)
|
||||
{
|
||||
tc.mV[1] = 0.f ;
|
||||
}
|
||||
else if(tc.mV[1] > 1.f)
|
||||
{
|
||||
tc.mV[1] = 1.f;
|
||||
}
|
||||
break;
|
||||
case LLTexUnit::TAM_MIRROR:
|
||||
if(tc.mV[0] < 0.f)
|
||||
{
|
||||
tc.mV[0] = -tc.mV[0] ;
|
||||
}
|
||||
int_part = (S32)tc.mV[0] ;
|
||||
if(int_part & 1) //odd number
|
||||
{
|
||||
tc.mV[0] = int_part + 1 - tc.mV[0] ;
|
||||
}
|
||||
else //even number
|
||||
{
|
||||
tc.mV[0] -= int_part ;
|
||||
}
|
||||
|
||||
if(tc.mV[1] < 0.f)
|
||||
{
|
||||
tc.mV[1] = -tc.mV[1] ;
|
||||
}
|
||||
int_part = (S32)tc.mV[1] ;
|
||||
if(int_part & 1) //odd number
|
||||
{
|
||||
tc.mV[1] = int_part + 1 - tc.mV[1] ;
|
||||
}
|
||||
else //even number
|
||||
{
|
||||
tc.mV[1] -= int_part ;
|
||||
}
|
||||
break;
|
||||
case LLTexUnit::TAM_WRAP:
|
||||
if(tc.mV[0] > 1.f)
|
||||
tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ;
|
||||
else if(tc.mV[0] < -1.f)
|
||||
tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ;
|
||||
|
||||
if(tc.mV[1] > 1.f)
|
||||
tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ;
|
||||
else if(tc.mV[1] < -1.f)
|
||||
tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ;
|
||||
|
||||
if(tc.mV[0] < 0.f)
|
||||
{
|
||||
tc.mV[0] = 1.0f + tc.mV[0] ;
|
||||
}
|
||||
if(tc.mV[1] < 0.f)
|
||||
{
|
||||
tc.mV[1] = 1.0f + tc.mV[1] ;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ;
|
||||
tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;
|
||||
}
|
||||
|
||||
|
||||
*tex_coords++ = tc;
|
||||
if (do_bump)
|
||||
{
|
||||
|
|
@ -2197,9 +2086,9 @@ BOOL LLFace::hasMedia() const
|
|||
{
|
||||
return TRUE ;
|
||||
}
|
||||
if(mTexture.notNull())
|
||||
if(mTexture[LLRender::DIFFUSE_MAP].notNull())
|
||||
{
|
||||
return mTexture->hasParcelMedia() ; //if has a parcel media
|
||||
return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ; //if has a parcel media
|
||||
}
|
||||
|
||||
return FALSE ; //no media.
|
||||
|
|
@ -2251,7 +2140,7 @@ F32 LLFace::getTextureVirtualSize()
|
|||
face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area) ;
|
||||
if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
|
||||
{
|
||||
if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage())
|
||||
if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())
|
||||
{
|
||||
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
|
||||
}
|
||||
|
|
@ -2618,159 +2507,13 @@ LLVector3 LLFace::getPositionAgent() const
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
//atlas
|
||||
//
|
||||
void LLFace::removeAtlas()
|
||||
LLViewerTexture* LLFace::getTexture(U32 ch) const
|
||||
{
|
||||
setAtlasInUse(FALSE) ;
|
||||
mAtlasInfop = NULL ;
|
||||
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
|
||||
|
||||
return mTexture[ch] ;
|
||||
}
|
||||
|
||||
const LLTextureAtlas* LLFace::getAtlas()const
|
||||
{
|
||||
if(mAtlasInfop)
|
||||
{
|
||||
return mAtlasInfop->getAtlas() ;
|
||||
}
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
const LLVector2* LLFace::getTexCoordOffset()const
|
||||
{
|
||||
if(isAtlasInUse())
|
||||
{
|
||||
return mAtlasInfop->getTexCoordOffset() ;
|
||||
}
|
||||
return NULL ;
|
||||
}
|
||||
const LLVector2* LLFace::getTexCoordScale() const
|
||||
{
|
||||
if(isAtlasInUse())
|
||||
{
|
||||
return mAtlasInfop->getTexCoordScale() ;
|
||||
}
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
BOOL LLFace::isAtlasInUse()const
|
||||
{
|
||||
return mUsingAtlas ;
|
||||
}
|
||||
|
||||
BOOL LLFace::canUseAtlas()const
|
||||
{
|
||||
//no drawable or no spatial group, do not use atlas
|
||||
if(!mDrawablep || !mDrawablep->getSpatialGroup())
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
//if bump face, do not use atlas
|
||||
if(getTextureEntry() && getTextureEntry()->getBumpmap())
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
//if animated texture, do not use atlas
|
||||
if(isState(TEXTURE_ANIM))
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
void LLFace::setAtlasInUse(BOOL flag)
|
||||
{
|
||||
//no valid atlas to use.
|
||||
if(flag && (!mAtlasInfop || !mAtlasInfop->isValid()))
|
||||
{
|
||||
flag = FALSE ;
|
||||
}
|
||||
|
||||
if(!flag && !mUsingAtlas)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
//at this stage (flag || mUsingAtlas) is always true.
|
||||
//
|
||||
|
||||
//rebuild the tex coords
|
||||
if(mDrawablep)
|
||||
{
|
||||
gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_TCOORD);
|
||||
mUsingAtlas = flag ;
|
||||
}
|
||||
else
|
||||
{
|
||||
mUsingAtlas = FALSE ;
|
||||
}
|
||||
}
|
||||
|
||||
LLTextureAtlasSlot* LLFace::getAtlasInfo()
|
||||
{
|
||||
return mAtlasInfop ;
|
||||
}
|
||||
|
||||
void LLFace::setAtlasInfo(LLTextureAtlasSlot* atlasp)
|
||||
{
|
||||
if(mAtlasInfop != atlasp)
|
||||
{
|
||||
if(mAtlasInfop)
|
||||
{
|
||||
//llerrs << "Atlas slot changed!" << llendl ;
|
||||
}
|
||||
mAtlasInfop = atlasp ;
|
||||
}
|
||||
}
|
||||
|
||||
LLViewerTexture* LLFace::getTexture() const
|
||||
{
|
||||
if(isAtlasInUse())
|
||||
{
|
||||
return (LLViewerTexture*)mAtlasInfop->getAtlas() ;
|
||||
}
|
||||
|
||||
return mTexture ;
|
||||
}
|
||||
|
||||
//switch to atlas or switch back to gl texture
|
||||
//return TRUE if using atlas.
|
||||
BOOL LLFace::switchTexture()
|
||||
{
|
||||
//no valid atlas or texture
|
||||
if(!mAtlasInfop || !mAtlasInfop->isValid() || !mTexture)
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
if(mTexture->getTexelsInAtlas() >= (U32)mVSize ||
|
||||
mTexture->getTexelsInAtlas() >= mTexture->getTexelsInGLTexture())
|
||||
{
|
||||
//switch to use atlas
|
||||
//atlas resolution is qualified, use it.
|
||||
if(!mUsingAtlas)
|
||||
{
|
||||
setAtlasInUse(TRUE) ;
|
||||
}
|
||||
}
|
||||
else //if atlas not qualified.
|
||||
{
|
||||
//switch back to GL texture
|
||||
if(mUsingAtlas && mTexture->isGLTextureCreated() &&
|
||||
mTexture->getDiscardLevel() < mTexture->getDiscardLevelInAtlas())
|
||||
{
|
||||
setAtlasInUse(FALSE) ;
|
||||
}
|
||||
}
|
||||
|
||||
return mUsingAtlas ;
|
||||
}
|
||||
|
||||
|
||||
void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
|
||||
{
|
||||
mVertexBuffer = buffer;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
#include "llvertexbuffer.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "lldrawable.h"
|
||||
#include "lltextureatlasmanager.h"
|
||||
|
||||
class LLFacePool;
|
||||
class LLVolume;
|
||||
|
|
@ -50,7 +49,6 @@ class LLTextureEntry;
|
|||
class LLVertexProgram;
|
||||
class LLViewerTexture;
|
||||
class LLGeometryManager;
|
||||
class LLTextureAtlasSlot;
|
||||
|
||||
const F32 MIN_ALPHA_SIZE = 1024.f;
|
||||
const F32 MIN_TEX_ANIM_SIZE = 512.f;
|
||||
|
|
@ -110,10 +108,12 @@ public:
|
|||
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
|
||||
void setTextureIndex(U8 index);
|
||||
U8 getTextureIndex() const { return mTextureIndex; }
|
||||
void setTexture(U32 ch, LLViewerTexture* tex);
|
||||
void setTexture(LLViewerTexture* tex) ;
|
||||
void setDiffuseMap(LLViewerTexture* tex);
|
||||
void setNormalMap(LLViewerTexture* tex);
|
||||
void setSpecularMap(LLViewerTexture* tex);
|
||||
void switchTexture(LLViewerTexture* new_texture);
|
||||
void switchTexture(U32 ch, LLViewerTexture* new_texture);
|
||||
void dirtyTexture();
|
||||
LLXformMatrix* getXform() const { return mXform; }
|
||||
BOOL hasGeometry() const { return mGeomCount > 0; }
|
||||
|
|
@ -132,8 +132,8 @@ public:
|
|||
F32 getVirtualSize() const { return mVSize; }
|
||||
F32 getPixelArea() const { return mPixelArea; }
|
||||
|
||||
S32 getIndexInTex() const {return mIndexInTex ;}
|
||||
void setIndexInTex(S32 index) { mIndexInTex = index ;}
|
||||
S32 getIndexInTex(U32 ch) const {llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); return mIndexInTex[ch];}
|
||||
void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index ;}
|
||||
|
||||
void renderSetColor() const;
|
||||
S32 renderElements(const U16 *index_array) const;
|
||||
|
|
@ -151,7 +151,7 @@ public:
|
|||
S32 getLOD() const { return mVObjp.notNull() ? mVObjp->getLOD() : 0; }
|
||||
void setPoolType(U32 type) { mPoolType = type; }
|
||||
S32 getTEOffset() { return mTEOffset; }
|
||||
LLViewerTexture* getTexture() const;
|
||||
LLViewerTexture* getTexture(U32 ch = LLRender::DIFFUSE_MAP) const;
|
||||
|
||||
void setViewerObject(LLViewerObject* object);
|
||||
void setPool(LLFacePool *pool, LLViewerTexture *texturep);
|
||||
|
|
@ -225,16 +225,6 @@ public:
|
|||
void setHasMedia(bool has_media) { mHasMedia = has_media ;}
|
||||
BOOL hasMedia() const ;
|
||||
|
||||
//for atlas
|
||||
LLTextureAtlasSlot* getAtlasInfo() ;
|
||||
void setAtlasInUse(BOOL flag);
|
||||
void setAtlasInfo(LLTextureAtlasSlot* atlasp);
|
||||
BOOL isAtlasInUse()const;
|
||||
BOOL canUseAtlas() const;
|
||||
const LLVector2* getTexCoordScale() const ;
|
||||
const LLVector2* getTexCoordOffset()const;
|
||||
const LLTextureAtlas* getAtlas()const ;
|
||||
void removeAtlas() ;
|
||||
BOOL switchTexture() ;
|
||||
|
||||
//vertex buffer tracking
|
||||
|
|
@ -285,12 +275,12 @@ private:
|
|||
U8 mTextureIndex; // index of texture channel to use for pseudo-atlasing
|
||||
U32 mIndicesCount;
|
||||
U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!)
|
||||
S32 mIndexInTex ;
|
||||
S32 mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS];
|
||||
|
||||
LLXformMatrix* mXform;
|
||||
LLPointer<LLViewerTexture> mTexture;
|
||||
LLPointer<LLViewerTexture> mSpecMap;
|
||||
LLPointer<LLViewerTexture> mNormalMap;
|
||||
|
||||
LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS];
|
||||
|
||||
LLPointer<LLDrawable> mDrawablep;
|
||||
LLPointer<LLViewerObject> mVObjp;
|
||||
S32 mTEOffset;
|
||||
|
|
@ -308,9 +298,6 @@ private:
|
|||
F32 mBoundingSphereRadius ;
|
||||
bool mHasMedia ;
|
||||
|
||||
//atlas
|
||||
LLPointer<LLTextureAtlasSlot> mAtlasInfop ;
|
||||
BOOL mUsingAtlas ;
|
||||
|
||||
protected:
|
||||
static BOOL sSafeRenderSelect;
|
||||
|
|
|
|||
|
|
@ -372,10 +372,12 @@ std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id)
|
|||
std::vector<LLViewerObject*> obj_list;
|
||||
LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id);
|
||||
|
||||
for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(); face_iterator++)
|
||||
U32 ch = LLRender::DIFFUSE_MAP;
|
||||
|
||||
for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(ch); face_iterator++)
|
||||
{
|
||||
// getting an object from a face
|
||||
LLFace* face_to_object = (*old_texture->getFaceList())[face_iterator];
|
||||
LLFace* face_to_object = (*old_texture->getFaceList(ch))[face_iterator];
|
||||
|
||||
if(face_to_object)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ LLTextureAtlas::~LLTextureAtlas()
|
|||
//virtual
|
||||
S8 LLTextureAtlas::getType() const
|
||||
{
|
||||
return LLViewerTexture::ATLAS_TEXTURE ;
|
||||
return 0; //LLViewerTexture::ATLAS_TEXTURE ;
|
||||
}
|
||||
|
||||
void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset)
|
||||
|
|
|
|||
|
|
@ -1193,28 +1193,6 @@ class LLAdvancedCheckWireframe : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
// TEXTURE ATLAS //
|
||||
//////////////////////
|
||||
|
||||
class LLAdvancedToggleTextureAtlas : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLViewerTexture::sUseTextureAtlas = !LLViewerTexture::sUseTextureAtlas;
|
||||
gSavedSettings.setBOOL("EnableTextureAtlas", LLViewerTexture::sUseTextureAtlas) ;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAdvancedCheckTextureAtlas : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
bool new_value = LLViewerTexture::sUseTextureAtlas; // <-- make this using LLCacheControl
|
||||
return new_value;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////
|
||||
// DUMP SCRIPTED CAMERA //
|
||||
|
|
@ -8464,8 +8442,6 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
|
||||
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
|
||||
// Develop > Render
|
||||
view_listener_t::addMenu(new LLAdvancedToggleTextureAtlas(), "Advanced.ToggleTextureAtlas");
|
||||
view_listener_t::addMenu(new LLAdvancedCheckTextureAtlas(), "Advanced.CheckTextureAtlas");
|
||||
view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
|
||||
view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");
|
||||
view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred");
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@
|
|||
#include "llappviewer.h"
|
||||
#include "llface.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "lltextureatlas.h"
|
||||
#include "lltextureatlasmanager.h"
|
||||
#include "lltextureentry.h"
|
||||
#include "llmediaentry.h"
|
||||
#include "llvovolume.h"
|
||||
|
|
@ -97,7 +95,6 @@ S32 LLViewerTexture::sMinLargeImageSize = 65536 ; //256 * 256.
|
|||
S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ;
|
||||
BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ;
|
||||
F32 LLViewerTexture::sCurrentTime = 0.0f ;
|
||||
BOOL LLViewerTexture::sUseTextureAtlas = FALSE ;
|
||||
F32 LLViewerTexture::sTexelPixelRatio = 1.0f;
|
||||
|
||||
LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
|
||||
|
|
@ -556,8 +553,7 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
|
|||
}
|
||||
}
|
||||
sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
|
||||
LLViewerTexture::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ;
|
||||
|
||||
|
||||
F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;
|
||||
F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
|
||||
sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1);
|
||||
|
|
@ -639,9 +635,12 @@ void LLViewerTexture::init(bool firstinit)
|
|||
mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;
|
||||
mAdditionalDecodePriority = 0.f ;
|
||||
mParcelMedia = NULL ;
|
||||
mNumFaces = 0 ;
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
mNumFaces[i] = 0;
|
||||
mFaceList[i].clear();
|
||||
}
|
||||
mNumVolumes = 0;
|
||||
mFaceList.clear() ;
|
||||
mVolumeList.clear();
|
||||
}
|
||||
|
||||
|
|
@ -653,7 +652,10 @@ S8 LLViewerTexture::getType() const
|
|||
|
||||
void LLViewerTexture::cleanup()
|
||||
{
|
||||
mFaceList.clear() ;
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
mFaceList[i].clear() ;
|
||||
}
|
||||
mVolumeList.clear();
|
||||
if(mGLTexturep)
|
||||
{
|
||||
|
|
@ -778,38 +780,57 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
|
|||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerTexture::addFace(LLFace* facep)
|
||||
void LLViewerTexture::addFace(U32 ch, LLFace* facep)
|
||||
{
|
||||
if(mNumFaces >= mFaceList.size())
|
||||
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
|
||||
|
||||
if(mNumFaces[ch] >= mFaceList[ch].size())
|
||||
{
|
||||
mFaceList.resize(2 * mNumFaces + 1) ;
|
||||
mFaceList[ch].resize(2 * mNumFaces[ch] + 1) ;
|
||||
}
|
||||
mFaceList[mNumFaces] = facep ;
|
||||
facep->setIndexInTex(mNumFaces) ;
|
||||
mNumFaces++ ;
|
||||
mFaceList[ch][mNumFaces[ch]] = facep ;
|
||||
facep->setIndexInTex(ch, mNumFaces[ch]) ;
|
||||
mNumFaces[ch]++ ;
|
||||
mLastFaceListUpdateTimer.reset() ;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerTexture::removeFace(LLFace* facep)
|
||||
void LLViewerTexture::removeFace(U32 ch, LLFace* facep)
|
||||
{
|
||||
if(mNumFaces > 1)
|
||||
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
|
||||
|
||||
if(mNumFaces[ch] > 1)
|
||||
{
|
||||
S32 index = facep->getIndexInTex() ;
|
||||
mFaceList[index] = mFaceList[--mNumFaces] ;
|
||||
mFaceList[index]->setIndexInTex(index) ;
|
||||
S32 index = facep->getIndexInTex(ch) ;
|
||||
llassert(index < mFaceList[ch].size());
|
||||
llassert(index < mNumFaces[ch]);
|
||||
mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]] ;
|
||||
mFaceList[ch][index]->setIndexInTex(ch, index) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFaceList.clear() ;
|
||||
mNumFaces = 0 ;
|
||||
mFaceList[ch].clear() ;
|
||||
mNumFaces[ch] = 0 ;
|
||||
}
|
||||
mLastFaceListUpdateTimer.reset() ;
|
||||
}
|
||||
|
||||
S32 LLViewerTexture::getNumFaces() const
|
||||
S32 LLViewerTexture::getTotalNumFaces() const
|
||||
{
|
||||
return mNumFaces ;
|
||||
S32 ret = 0;
|
||||
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
ret += mNumFaces[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
S32 LLViewerTexture::getNumFaces(U32 ch) const
|
||||
{
|
||||
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
|
||||
return mNumFaces[ch];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -832,6 +853,8 @@ void LLViewerTexture::removeVolume(LLVOVolume* volumep)
|
|||
if(mNumVolumes > 1)
|
||||
{
|
||||
S32 index = volumep->getIndexInTex() ;
|
||||
llassert(index < mVolumeList.size());
|
||||
llassert(index < mNumVolumes);
|
||||
mVolumeList[index] = mVolumeList[--mNumVolumes] ;
|
||||
mVolumeList[index]->setIndexInTex(index) ;
|
||||
}
|
||||
|
|
@ -853,18 +876,22 @@ void LLViewerTexture::reorganizeFaceList()
|
|||
static const F32 MAX_WAIT_TIME = 20.f; // seconds
|
||||
static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
|
||||
|
||||
if(mNumFaces + MAX_EXTRA_BUFFER_SIZE > mFaceList.size())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
|
||||
{
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end());
|
||||
}
|
||||
|
||||
mLastFaceListUpdateTimer.reset() ;
|
||||
mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end());
|
||||
}
|
||||
|
||||
void LLViewerTexture::reorganizeVolumeList()
|
||||
|
|
@ -1130,13 +1157,6 @@ void LLViewerTexture::forceUpdateBindStats(void) const
|
|||
return mGLTexturep->forceUpdateBindStats() ;
|
||||
}
|
||||
|
||||
U32 LLViewerTexture::getTexelsInAtlas() const
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
return mGLTexturep->getTexelsInAtlas() ;
|
||||
}
|
||||
|
||||
U32 LLViewerTexture::getTexelsInGLTexture() const
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
|
@ -1151,13 +1171,6 @@ BOOL LLViewerTexture::isGLTextureCreated() const
|
|||
return mGLTexturep->isGLTextureCreated() ;
|
||||
}
|
||||
|
||||
S32 LLViewerTexture::getDiscardLevelInAtlas() const
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
return mGLTexturep->getDiscardLevelInAtlas() ;
|
||||
}
|
||||
|
||||
void LLViewerTexture::destroyGLTexture()
|
||||
{
|
||||
if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
|
||||
|
|
@ -1470,9 +1483,14 @@ void LLViewerFetchedTexture::addToCreateTexture()
|
|||
mGLTexturep->setComponents(mComponents) ;
|
||||
force_update = true ;
|
||||
|
||||
for(U32 i = 0 ; i < mNumFaces ; i++)
|
||||
for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j)
|
||||
{
|
||||
mFaceList[i]->dirtyTexture() ;
|
||||
llassert(mNumFaces[j] <= mFaceList[j].size());
|
||||
|
||||
for(U32 i = 0 ; i < mNumFaces[j]; i++)
|
||||
{
|
||||
mFaceList[j][i]->dirtyTexture() ;
|
||||
}
|
||||
}
|
||||
|
||||
//discard the cached raw image and the saved raw image
|
||||
|
|
@ -1615,11 +1633,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if(!(res = insertToAtlas()))
|
||||
{
|
||||
res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
|
||||
resetFaceAtlas() ;
|
||||
}
|
||||
res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
|
||||
|
||||
setActive() ;
|
||||
|
||||
if (!needsToSaveRawImage())
|
||||
|
|
@ -1908,28 +1923,32 @@ void LLViewerFetchedTexture::updateVirtualSize()
|
|||
addTextureStats(0.f, FALSE) ;//reset
|
||||
}
|
||||
|
||||
for(U32 i = 0 ; i < mNumFaces ; i++)
|
||||
{
|
||||
LLFace* facep = mFaceList[i] ;
|
||||
if( facep )
|
||||
{
|
||||
LLDrawable* drawable = facep->getDrawable();
|
||||
if (drawable)
|
||||
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
|
||||
{
|
||||
llassert(mNumFaces[ch] <= mFaceList[ch].size());
|
||||
|
||||
for(U32 i = 0 ; i < mNumFaces[ch]; i++)
|
||||
{
|
||||
LLFace* facep = mFaceList[ch][i] ;
|
||||
if( facep )
|
||||
{
|
||||
if(drawable->isRecentlyVisible())
|
||||
LLDrawable* drawable = facep->getDrawable();
|
||||
if (drawable)
|
||||
{
|
||||
if (getBoostLevel() == LLViewerTexture::BOOST_NONE &&
|
||||
drawable->getVObj() && drawable->getVObj()->isSelected())
|
||||
if(drawable->isRecentlyVisible())
|
||||
{
|
||||
setBoostLevel(LLViewerTexture::BOOST_SELECTED);
|
||||
if (getBoostLevel() == LLViewerTexture::BOOST_NONE &&
|
||||
drawable->getVObj() && drawable->getVObj()->isSelected())
|
||||
{
|
||||
setBoostLevel(LLViewerTexture::BOOST_SELECTED);
|
||||
}
|
||||
addTextureStats(facep->getVirtualSize()) ;
|
||||
setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
|
||||
}
|
||||
addTextureStats(facep->getVirtualSize()) ;
|
||||
setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//reset whether or not a face was selected after 10 seconds
|
||||
const F32 SELECTION_RESET_TIME = 10.f;
|
||||
|
||||
|
|
@ -3005,190 +3024,6 @@ F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const
|
|||
{
|
||||
return sCurrentTime - mLastReferencedSavedRawImageTime ;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------
|
||||
//atlasing
|
||||
//----------------------------------------------------------------------------------------------
|
||||
void LLViewerFetchedTexture::resetFaceAtlas()
|
||||
{
|
||||
//Nothing should be done here.
|
||||
}
|
||||
|
||||
//invalidate all atlas slots for this image.
|
||||
void LLViewerFetchedTexture::invalidateAtlas(BOOL rebuild_geom)
|
||||
{
|
||||
for(U32 i = 0 ; i < mNumFaces ; i++)
|
||||
{
|
||||
LLFace* facep = mFaceList[i] ;
|
||||
facep->removeAtlas() ;
|
||||
if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup())
|
||||
{
|
||||
facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLViewerFetchedTexture::insertToAtlas()
|
||||
{
|
||||
if(!LLViewerTexture::sUseTextureAtlas)
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
if(getNumFaces() < 1)
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
if(mGLTexturep->getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= mGLTexturep->getDiscardLevelInAtlas())
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), mGLTexturep->getTexTarget()))
|
||||
{
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image.
|
||||
S32 raw_w = mRawImage->getWidth() ;
|
||||
S32 raw_h = mRawImage->getHeight() ;
|
||||
F32 xscale = 1.0f, yscale = 1.0f ;
|
||||
LLPointer<LLTextureAtlasSlot> slot_infop;
|
||||
LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer.
|
||||
LLSpatialGroup* groupp ;
|
||||
LLFace* facep;
|
||||
|
||||
//if the atlas slot pointers for some faces are null, process them later.
|
||||
ll_face_list_t waiting_list ;
|
||||
for(U32 i = 0 ; i < mNumFaces ; i++)
|
||||
{
|
||||
{
|
||||
facep = mFaceList[i] ;
|
||||
|
||||
//face can not use atlas.
|
||||
if(!facep->canUseAtlas())
|
||||
{
|
||||
if(facep->getAtlasInfo())
|
||||
{
|
||||
facep->removeAtlas() ;
|
||||
}
|
||||
ret = FALSE ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
//the atlas slot is updated
|
||||
slot_infop = facep->getAtlasInfo() ;
|
||||
groupp = facep->getDrawable()->getSpatialGroup() ;
|
||||
|
||||
if(slot_infop)
|
||||
{
|
||||
if(slot_infop->getSpatialGroup() != groupp)
|
||||
{
|
||||
if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot
|
||||
{
|
||||
facep->setAtlasInfo(cur_slotp) ;
|
||||
facep->setAtlasInUse(TRUE) ;
|
||||
continue ;
|
||||
}
|
||||
else //do not forget to update slot_infop->getSpatialGroup().
|
||||
{
|
||||
LLSpatialGroup* gp = slot_infop->getSpatialGroup() ;
|
||||
gp->setCurUpdatingTime(gFrameCount) ;
|
||||
gp->setCurUpdatingTexture(this) ;
|
||||
gp->setCurUpdatingSlot(slot_infop) ;
|
||||
}
|
||||
}
|
||||
else //same group
|
||||
{
|
||||
if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated
|
||||
{
|
||||
facep->setAtlasInUse(TRUE) ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//if the slot is null, wait to process them later.
|
||||
waiting_list.push_back(facep) ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
//----------
|
||||
//insert to atlas
|
||||
if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))
|
||||
{
|
||||
|
||||
//the texture does not qualify to add to atlas, do not bother to try for other faces.
|
||||
//invalidateAtlas();
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
//update texture scale
|
||||
slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ;
|
||||
slot_infop->setTexCoordScale(xscale, yscale) ;
|
||||
slot_infop->setValid() ;
|
||||
slot_infop->setUpdatedTime(gFrameCount) ;
|
||||
|
||||
//update spatial group atlas info
|
||||
groupp->setCurUpdatingTime(gFrameCount) ;
|
||||
groupp->setCurUpdatingTexture(this) ;
|
||||
groupp->setCurUpdatingSlot(slot_infop) ;
|
||||
|
||||
//make the face to switch to the atlas.
|
||||
facep->setAtlasInUse(TRUE) ;
|
||||
}
|
||||
}
|
||||
|
||||
//process the waiting_list
|
||||
for(std::vector<LLFace*>::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter)
|
||||
{
|
||||
facep = (LLFace*)*iter ;
|
||||
groupp = facep->getDrawable()->getSpatialGroup() ;
|
||||
|
||||
//check if this texture already inserted to atlas for this group
|
||||
if((cur_slotp = groupp->getCurUpdatingSlot(this)))
|
||||
{
|
||||
facep->setAtlasInfo(cur_slotp) ;
|
||||
facep->setAtlasInUse(TRUE) ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
//need to reserve a slot from atlas
|
||||
slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ;
|
||||
|
||||
facep->setAtlasInfo(slot_infop) ;
|
||||
|
||||
groupp->setCurUpdatingTime(gFrameCount) ;
|
||||
groupp->setCurUpdatingTexture(this) ;
|
||||
groupp->setCurUpdatingSlot(slot_infop) ;
|
||||
|
||||
//slot allocation failed.
|
||||
if(!slot_infop || !slot_infop->getAtlas())
|
||||
{
|
||||
ret = FALSE ;
|
||||
facep->setAtlasInUse(FALSE) ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
//insert to atlas
|
||||
if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))
|
||||
{
|
||||
//the texture does not qualify to add to atlas, do not bother to try for other faces.
|
||||
ret = FALSE ;
|
||||
//invalidateAtlas();
|
||||
break ;
|
||||
}
|
||||
|
||||
//update texture scale
|
||||
slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ;
|
||||
slot_infop->setTexCoordScale(xscale, yscale) ;
|
||||
slot_infop->setValid() ;
|
||||
slot_infop->setUpdatedTime(gFrameCount) ;
|
||||
|
||||
//make the face to switch to the atlas.
|
||||
facep->setAtlasInUse(TRUE) ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
//end of LLViewerFetchedTexture
|
||||
|
|
@ -3535,11 +3370,14 @@ BOOL LLViewerMediaTexture::findFaces()
|
|||
LLViewerTexture* tex = gTextureList.findImage(mID) ;
|
||||
if(tex) //this media is a parcel media for tex.
|
||||
{
|
||||
const ll_face_list_t* face_list = tex->getFaceList() ;
|
||||
U32 end = tex->getNumFaces() ;
|
||||
for(U32 i = 0 ; i < end ; i++)
|
||||
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
|
||||
{
|
||||
mMediaFaceList.push_back((*face_list)[i]) ;
|
||||
const ll_face_list_t* face_list = tex->getFaceList(ch) ;
|
||||
U32 end = tex->getNumFaces(ch) ;
|
||||
for(U32 i = 0 ; i < end ; i++)
|
||||
{
|
||||
mMediaFaceList.push_back((*face_list)[i]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3604,7 +3442,7 @@ void LLViewerMediaTexture::addMediaToFace(LLFace* facep)
|
|||
return ; //no need to add the face because the media is not in playing.
|
||||
}
|
||||
|
||||
switchTexture(facep) ;
|
||||
switchTexture(LLRender::DIFFUSE_MAP, facep) ;
|
||||
}
|
||||
|
||||
void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
|
||||
|
|
@ -3621,19 +3459,19 @@ void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
|
|||
}
|
||||
|
||||
mIsPlaying = FALSE ; //set to remove the media from the face.
|
||||
switchTexture(facep) ;
|
||||
switchTexture(LLRender::DIFFUSE_MAP, facep) ;
|
||||
mIsPlaying = TRUE ; //set the flag back.
|
||||
|
||||
if(getNumFaces() < 1) //no face referencing to this media
|
||||
if(getTotalNumFaces() < 1) //no face referencing to this media
|
||||
{
|
||||
stopPlaying() ;
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerMediaTexture::addFace(LLFace* facep)
|
||||
void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)
|
||||
{
|
||||
LLViewerTexture::addFace(facep) ;
|
||||
LLViewerTexture::addFace(ch, facep) ;
|
||||
|
||||
const LLTextureEntry* te = facep->getTextureEntry() ;
|
||||
if(te && te->getID().notNull())
|
||||
|
|
@ -3660,9 +3498,9 @@ void LLViewerMediaTexture::addFace(LLFace* facep)
|
|||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerMediaTexture::removeFace(LLFace* facep)
|
||||
void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)
|
||||
{
|
||||
LLViewerTexture::removeFace(facep) ;
|
||||
LLViewerTexture::removeFace(ch, facep) ;
|
||||
|
||||
const LLTextureEntry* te = facep->getTextureEntry() ;
|
||||
if(te && te->getID().notNull())
|
||||
|
|
@ -3680,24 +3518,35 @@ void LLViewerMediaTexture::removeFace(LLFace* facep)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
//we have some trouble here: the texture of the face is changed.
|
||||
//we need to find the former texture, and remove it from the list to avoid memory leaking.
|
||||
if(!mNumFaces)
|
||||
std::vector<const LLTextureEntry*> te_list;
|
||||
|
||||
for (U32 ch = 0; ch < 3; ++ch)
|
||||
{
|
||||
//
|
||||
//we have some trouble here: the texture of the face is changed.
|
||||
//we need to find the former texture, and remove it from the list to avoid memory leaking.
|
||||
|
||||
llassert(mNumFaces[ch] <= mFaceList[ch].size());
|
||||
|
||||
for(U32 j = 0 ; j < mNumFaces[ch] ; j++)
|
||||
{
|
||||
te_list.push_back(mFaceList[ch][j]->getTextureEntry());//all textures are in use.
|
||||
}
|
||||
}
|
||||
|
||||
if (te_list.empty())
|
||||
{
|
||||
mTextureList.clear() ;
|
||||
return ;
|
||||
}
|
||||
S32 end = getNumFaces() ;
|
||||
std::vector<const LLTextureEntry*> te_list(end) ;
|
||||
S32 i = 0 ;
|
||||
for(U32 j = 0 ; j < mNumFaces ; j++)
|
||||
{
|
||||
te_list[i++] = mFaceList[j]->getTextureEntry() ;//all textures are in use.
|
||||
}
|
||||
|
||||
S32 end = te_list.size();
|
||||
|
||||
for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
|
||||
iter != mTextureList.end(); ++iter)
|
||||
{
|
||||
S32 i = 0;
|
||||
|
||||
for(i = 0 ; i < end ; i++)
|
||||
{
|
||||
if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use.
|
||||
|
|
@ -3742,7 +3591,7 @@ void LLViewerMediaTexture::stopPlaying()
|
|||
mIsPlaying = FALSE ;
|
||||
}
|
||||
|
||||
void LLViewerMediaTexture::switchTexture(LLFace* facep)
|
||||
void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)
|
||||
{
|
||||
if(facep)
|
||||
{
|
||||
|
|
@ -3758,7 +3607,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep)
|
|||
|
||||
if(mIsPlaying) //old textures switch to the media texture
|
||||
{
|
||||
facep->switchTexture(this) ;
|
||||
facep->switchTexture(ch, this) ;
|
||||
}
|
||||
else //switch to old textures.
|
||||
{
|
||||
|
|
@ -3774,7 +3623,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep)
|
|||
{
|
||||
tex = LLViewerFetchedTexture::sDefaultImagep ;
|
||||
}
|
||||
facep->switchTexture(tex) ;
|
||||
facep->switchTexture(ch, tex) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3813,14 +3662,17 @@ void LLViewerMediaTexture::setPlaying(BOOL playing)
|
|||
|
||||
for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
|
||||
{
|
||||
switchTexture(*iter) ;
|
||||
switchTexture(LLRender::DIFFUSE_MAP, *iter) ;
|
||||
}
|
||||
}
|
||||
else //stop playing this media
|
||||
{
|
||||
for(U32 i = mNumFaces ; i ; i--)
|
||||
U32 ch = LLRender::DIFFUSE_MAP;
|
||||
|
||||
llassert(mNumFaces[ch] <= mFaceList[ch].size());
|
||||
for(U32 i = mNumFaces[ch] ; i ; i--)
|
||||
{
|
||||
switchTexture(mFaceList[i - 1]) ; //current face could be removed in this function.
|
||||
switchTexture(ch, mFaceList[ch][i - 1]) ; //current face could be removed in this function.
|
||||
}
|
||||
}
|
||||
return ;
|
||||
|
|
@ -3842,14 +3694,18 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
|
|||
|
||||
if(mIsPlaying) //media is playing
|
||||
{
|
||||
for(U32 i = 0 ; i < mNumFaces ; i++)
|
||||
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
|
||||
{
|
||||
LLFace* facep = mFaceList[i] ;
|
||||
if(facep->getDrawable()->isRecentlyVisible())
|
||||
llassert(mNumFaces[ch] <= mFaceList[ch].size());
|
||||
for(U32 i = 0 ; i < mNumFaces[ch] ; i++)
|
||||
{
|
||||
addTextureStats(facep->getVirtualSize()) ;
|
||||
}
|
||||
}
|
||||
LLFace* facep = mFaceList[ch][i] ;
|
||||
if(facep->getDrawable()->isRecentlyVisible())
|
||||
{
|
||||
addTextureStats(facep->getVirtualSize()) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else //media is not in playing
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "llgltypes.h"
|
||||
#include "llrender.h"
|
||||
#include "llmetricperformancetester.h"
|
||||
#include "llface.h"
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
|
@ -41,7 +42,6 @@
|
|||
#define MIN_VIDEO_RAM_IN_MEGA_BYTES 32
|
||||
#define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons.
|
||||
|
||||
class LLFace;
|
||||
class LLImageGL ;
|
||||
class LLImageRaw;
|
||||
class LLViewerObject;
|
||||
|
|
@ -103,7 +103,6 @@ public:
|
|||
DYNAMIC_TEXTURE,
|
||||
FETCHED_TEXTURE,
|
||||
LOD_TEXTURE,
|
||||
ATLAS_TEXTURE,
|
||||
INVALID_TEXTURE_TYPE
|
||||
};
|
||||
|
||||
|
|
@ -135,7 +134,6 @@ public:
|
|||
AVATAR_SCRATCH_TEX,
|
||||
DYNAMIC_TEX,
|
||||
MEDIA,
|
||||
ATLAS,
|
||||
OTHER,
|
||||
MAX_GL_IMAGE_CATEGORY
|
||||
};
|
||||
|
|
@ -186,10 +184,11 @@ public:
|
|||
S32 getFullHeight() const { return mFullHeight; }
|
||||
/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
|
||||
|
||||
virtual void addFace(LLFace* facep) ;
|
||||
virtual void removeFace(LLFace* facep) ;
|
||||
S32 getNumFaces() const;
|
||||
const ll_face_list_t* getFaceList() const {return &mFaceList;}
|
||||
virtual void addFace(U32 channel, LLFace* facep) ;
|
||||
virtual void removeFace(U32 channel, LLFace* facep) ;
|
||||
S32 getTotalNumFaces() const;
|
||||
S32 getNumFaces(U32 ch) const;
|
||||
const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];}
|
||||
|
||||
virtual void addVolume(LLVOVolume* volumep);
|
||||
virtual void removeVolume(LLVOVolume* volumep);
|
||||
|
|
@ -234,10 +233,9 @@ public:
|
|||
BOOL isJustBound()const ;
|
||||
void forceUpdateBindStats(void) const;
|
||||
|
||||
U32 getTexelsInAtlas() const ;
|
||||
U32 getTexelsInGLTexture() const ;
|
||||
BOOL isGLTextureCreated() const ;
|
||||
S32 getDiscardLevelInAtlas() const ;
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
//end of functions to access LLImageGL
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
|
@ -292,8 +290,8 @@ protected:
|
|||
LLPointer<LLImageGL> mGLTexturep ;
|
||||
S8 mDontDiscard; // Keep full res version of this image (for UI, etc)
|
||||
|
||||
ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
|
||||
U32 mNumFaces ;
|
||||
ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture
|
||||
U32 mNumFaces[LLRender::NUM_TEXTURE_CHANNELS];
|
||||
LLFrameTimer mLastFaceListUpdateTimer ;
|
||||
|
||||
ll_volume_list_t mVolumeList;
|
||||
|
|
@ -335,8 +333,7 @@ public:
|
|||
static S32 sMaxSmallImageSize ;
|
||||
static BOOL sFreezeImageScalingDown ;//do not scale down image res if set.
|
||||
static F32 sCurrentTime ;
|
||||
static BOOL sUseTextureAtlas ;
|
||||
|
||||
|
||||
enum EDebugTexels
|
||||
{
|
||||
DEBUG_TEXELS_OFF,
|
||||
|
|
@ -515,11 +512,6 @@ private:
|
|||
void saveRawImage() ;
|
||||
void setCachedRawImage() ;
|
||||
|
||||
//for atlas
|
||||
void resetFaceAtlas() ;
|
||||
void invalidateAtlas(BOOL rebuild_geom) ;
|
||||
BOOL insertToAtlas() ;
|
||||
|
||||
private:
|
||||
BOOL mFullyLoaded;
|
||||
BOOL mInDebug;
|
||||
|
|
@ -661,12 +653,12 @@ public:
|
|||
void addMediaToFace(LLFace* facep) ;
|
||||
void removeMediaFromFace(LLFace* facep) ;
|
||||
|
||||
/*virtual*/ void addFace(LLFace* facep) ;
|
||||
/*virtual*/ void removeFace(LLFace* facep) ;
|
||||
/*virtual*/ void addFace(U32 ch, LLFace* facep) ;
|
||||
/*virtual*/ void removeFace(U32 ch, LLFace* facep) ;
|
||||
|
||||
/*virtual*/ F32 getMaxVirtualSize() ;
|
||||
private:
|
||||
void switchTexture(LLFace* facep) ;
|
||||
void switchTexture(U32 ch, LLFace* facep) ;
|
||||
BOOL findFaces() ;
|
||||
void stopPlaying() ;
|
||||
|
||||
|
|
|
|||
|
|
@ -556,37 +556,9 @@ void LLVOVolume::animateTextures()
|
|||
tex_mat.setIdentity();
|
||||
LLVector3 trans ;
|
||||
|
||||
if(facep->isAtlasInUse())
|
||||
{
|
||||
//
|
||||
//if use atlas for animated texture
|
||||
//apply the following transform to the animation matrix.
|
||||
//
|
||||
|
||||
F32 tcoord_xoffset = 0.f ;
|
||||
F32 tcoord_yoffset = 0.f ;
|
||||
F32 tcoord_xscale = 1.f ;
|
||||
F32 tcoord_yscale = 1.f ;
|
||||
if(facep->isAtlasInUse())
|
||||
{
|
||||
const LLVector2* tmp = facep->getTexCoordOffset() ;
|
||||
tcoord_xoffset = tmp->mV[0] ;
|
||||
tcoord_yoffset = tmp->mV[1] ;
|
||||
|
||||
tmp = facep->getTexCoordScale() ;
|
||||
tcoord_xscale = tmp->mV[0] ;
|
||||
tcoord_yscale = tmp->mV[1] ;
|
||||
}
|
||||
trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f));
|
||||
|
||||
tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f));
|
||||
}
|
||||
else //non atlas
|
||||
{
|
||||
trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
|
||||
tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
|
||||
}
|
||||
|
||||
trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
|
||||
tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
|
||||
|
||||
LLVector3 scale(scale_s, scale_t, 1.f);
|
||||
LLQuaternion quat;
|
||||
quat.setQuat(rot, 0, 0, -1.f);
|
||||
|
|
|
|||
|
|
@ -2700,16 +2700,6 @@
|
|||
parameter="TextureLoadFullRes" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Texture Atlas (experimental)"
|
||||
name="Texture Atlas">
|
||||
<menu_item_check.on_check
|
||||
function="CheckControl"
|
||||
parameter="EnableTextureAtlas" />
|
||||
<menu_item_check.on_click
|
||||
function="ToggleControl"
|
||||
parameter="EnableTextureAtlas" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Render Attached Lights"
|
||||
name="Render Attached Lights">
|
||||
<menu_item_check.on_check
|
||||
|
|
|
|||
Loading…
Reference in New Issue