NORSPEC-54 Potential fix for crashing on all sorts of random operations.

meow-7.2.2
Dave Parks 2013-03-25 18:27:07 -05:00
parent 6620c1f824
commit 41ca92c67c
11 changed files with 253 additions and 738 deletions

View File

@ -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,

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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)

View File

@ -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");

View File

@ -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
{

View File

@ -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() ;

View File

@ -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);

View File

@ -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