svn merge -r 59178:59364 svn+ssh://svn.lindenlab.com/svn/linden/branches/maintenance --> release

master
Josh Bell 2007-03-21 19:36:11 +00:00
parent fceae96eb1
commit c93c38e047
49 changed files with 1325 additions and 736 deletions

View File

@ -9,14 +9,14 @@ blino Nakamura - VWR-17
Drewan Keats - VWR-28
Dylan Haskell - VWR-72
Eddy Stryker - VWR-15, VWR-23
Hiro Sommambulist - VWR-66
Hiro Sommambulist - VWR-66, VWR-97, VWR-100, VWR-105, VWR-108, VWR-118
Joghert LeSabre - VWR-64
Kage Pixel - VWR-11
Kunnis Basiat - VWR-82
Paul Churchill - VWR-20
Paula Innis - VWR-30
Peekay Semyorka - VWR-7, VWR-19, VWR-49
SpacedOut Frye - VWR-57, VWR-123
SpacedOut Frye - VWR-57, VWR-94, VWR-121, VWR-123
Strife Onizuka - VWR-74, VWR-85, SVC-9
Zipherius Turas - VWR-76, VWR-77

View File

@ -195,6 +195,10 @@ public:
II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE = 0x080000,
II_FLAGS_OBJECT_PERM_OVERWRITE_NEXT_OWNER = 0x100000,
// flag to indicate whether an object that is returned is composed
// of muiltiple items or not.
II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS = 0x200000,
// wearables use the low order byte of flags to store the
// EWearableType enumeration found in newview/llwearable.h
};

View File

@ -2059,7 +2059,7 @@ bool LLVolumeParams::setSkew(const F32 skew_value)
{
skew = min_skew_mag;
}
valid = approx_zero(delta);
valid = approx_zero(delta, .01f);
}
mPathParams.setSkew(skew);

View File

@ -948,7 +948,7 @@ BOOL LLCircuitData::updateWatchDogTimers(LLMessageSystem *msgsys)
<< (*it).first;
llinfos << str.str().c_str() << llendl;
}
mPotentialLostPackets.erase((*(it++)).first);
mPotentialLostPackets.erase(it++);
}
else
{

View File

@ -202,16 +202,15 @@ bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll)
{
// remove any matching poll file descriptors for this pipe.
LLIOPipe::ptr_t pipe_ptr(pipe);
LLChainInfo::conditionals_t::iterator it = (*mCurrentChain).mDescriptors.begin();
LLChainInfo::conditionals_t::iterator end = (*mCurrentChain).mDescriptors.end();
while (it != end)
LLChainInfo::conditionals_t::iterator it;
it = (*mCurrentChain).mDescriptors.begin();
while(it != (*mCurrentChain).mDescriptors.end())
{
LLChainInfo::pipe_conditional_t& value = (*it);
if ( pipe_ptr == value.first )
if(pipe_ptr == value.first)
{
ll_delete_apr_pollset_fd_client_data()(value);
(*mCurrentChain).mDescriptors.erase(it++);
it = (*mCurrentChain).mDescriptors.erase(it);
mRebuildPollset = true;
}
else
@ -453,7 +452,7 @@ void LLPumpIO::pump()
// << (*run_chain).mChainLinks[0].mPipe
// << " because we reached the end." << llendl;
#endif
mRunningChains.erase(run_chain++);
run_chain = mRunningChains.erase(run_chain);
continue;
}
}
@ -532,7 +531,7 @@ void LLPumpIO::pump()
(*run_chain).mDescriptors.begin(),
(*run_chain).mDescriptors.end(),
ll_delete_apr_pollset_fd_client_data());
mRunningChains.erase(run_chain++);
run_chain = mRunningChains.erase(run_chain);
// *NOTE: may not always need to rebuild the pollset.
mRebuildPollset = true;

View File

@ -285,14 +285,18 @@ BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
sSansSerifHuge->reset();
}
if (!sSSHugeFallback)
if (sSSHugeFallback)
{
sSSHugeFallback = new LLFontList();
if (!loadFaceFallback(sSSHugeFallback, sanserif_fallback_file, huge_size*ss_fallback_scale))
{
delete sSSHugeFallback;
sSSHugeFallback = NULL;
}
delete sSSHugeFallback;
}
sSSHugeFallback = new LLFontList();
if (!loadFaceFallback(
sSSHugeFallback,
sanserif_fallback_file,
huge_size*ss_fallback_scale))
{
delete sSSHugeFallback;
sSSHugeFallback = NULL;
}
failed |= !loadFace(sSansSerifHuge, sansserif_file, huge_size, sSSHugeFallback);
@ -307,14 +311,18 @@ BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
sSansSerifBig->reset();
}
if (!sSSBigFallback)
if (sSSBigFallback)
{
sSSBigFallback = new LLFontList();
if (!loadFaceFallback(sSSBigFallback, sanserif_fallback_file, big_size*ss_fallback_scale))
{
delete sSSBigFallback;
sSSBigFallback = NULL;
}
delete sSSBigFallback;
}
sSSBigFallback = new LLFontList();
if (!loadFaceFallback(
sSSBigFallback,
sanserif_fallback_file,
big_size*ss_fallback_scale))
{
delete sSSBigFallback;
sSSBigFallback = NULL;
}
failed |= !loadFace(sSansSerifBig, sansserif_file, big_size, sSSBigFallback);
@ -329,14 +337,18 @@ BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
sSansSerif->reset();
}
if (!sSSFallback)
if (sSSFallback)
{
sSSFallback = new LLFontList();
if (!loadFaceFallback(sSSFallback, sanserif_fallback_file, medium_size*ss_fallback_scale))
{
delete sSSFallback;
sSSFallback = NULL;
}
delete sSSFallback;
}
sSSFallback = new LLFontList();
if (!loadFaceFallback(
sSSFallback,
sanserif_fallback_file,
medium_size*ss_fallback_scale))
{
delete sSSFallback;
sSSFallback = NULL;
}
failed |= !loadFace(sSansSerif, sansserif_file, medium_size, sSSFallback);
@ -350,14 +362,18 @@ BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
sSansSerifSmall->reset();
}
if (!sSSSmallFallback)
if(sSSSmallFallback)
{
sSSSmallFallback = new LLFontList();
if (!loadFaceFallback(sSSSmallFallback, sanserif_fallback_file, small_size*ss_fallback_scale))
{
delete sSSSmallFallback;
sSSSmallFallback = NULL;
}
delete sSSSmallFallback;
}
sSSSmallFallback = new LLFontList();
if (!loadFaceFallback(
sSSSmallFallback,
sanserif_fallback_file,
small_size*ss_fallback_scale))
{
delete sSSSmallFallback;
sSSSmallFallback = NULL;
}
failed |= !loadFace(sSansSerifSmall, sansserif_file, small_size, sSSSmallFallback);
@ -374,14 +390,18 @@ BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
sSansSerifBold->reset();
}
if (!sSSBoldFallback)
if (sSSBoldFallback)
{
sSSBoldFallback = new LLFontList();
if (!loadFaceFallback(sSSBoldFallback, sanserif_fallback_file, medium_size*ss_fallback_scale))
{
delete sSSBoldFallback;
sSSBoldFallback = NULL;
}
delete sSSBoldFallback;
}
sSSBoldFallback = new LLFontList();
if (!loadFaceFallback(
sSSBoldFallback,
sanserif_fallback_file,
medium_size*ss_fallback_scale))
{
delete sSSBoldFallback;
sSSBoldFallback = NULL;
}
failed |= !loadFace(sSansSerifBold, sansserif_bold_file, medium_size, sSSBoldFallback);

View File

@ -213,6 +213,10 @@ LLWindow::LLWindow(BOOL fullscreen, U32 flags)
mHideCursorPermanent(FALSE),
mFlags(flags)
{
for (U32 i = 0; i < 6; i++)
{
mJoyAxis[i] = 0;
}
}
// virtual
@ -230,6 +234,15 @@ void LLWindow::decBusyCount()
}
}
F32 LLWindow::getJoystickAxis(U32 axis)
{
if (axis < 6)
{
return mJoyAxis[axis];
}
return 0.f;
}
void LLWindow::setCallbacks(LLWindowCallbacks *callbacks)
{
mCallbacks = callbacks;

View File

@ -181,7 +181,8 @@ public:
virtual F32 getNativeAspectRatio() = 0;
virtual F32 getPixelAspectRatio() = 0;
virtual void setNativeAspectRatio(F32 aspect) = 0;
F32 getJoystickAxis(U32 axis);
void setCallbacks(LLWindowCallbacks *callbacks);
virtual void beforeDialog() {}; // prepare to put up an OS dialog (if special measures are required, such as in fullscreen mode)
@ -219,6 +220,7 @@ protected:
ESwapMethod mSwapMethod;
BOOL mHideCursorPermanent;
U32 mFlags;
F32 mJoyAxis[6];
friend class LLWindowManager;
};

View File

@ -2796,6 +2796,13 @@ void LLWindowWin32::updateJoystick( )
if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE), &js ) ) )
return; // The device should have been acquired during the Poll()
mJoyAxis[0] = js.lX/1000.f;
mJoyAxis[1] = js.lY/1000.f;
mJoyAxis[2] = js.lZ/1000.f;
mJoyAxis[3] = js.lRx/1000.f;
mJoyAxis[4] = js.lRy/1000.f;
mJoyAxis[5] = js.lRz/1000.f;
if (js.lX <= -500)
{
if (!(mJoyStickState & 0x1))

View File

@ -132,5 +132,7 @@ void main()
//apply fog
applyScatter(color.rgb);
color.a = spec*0.5+fb.a;
gl_FragColor = color;
}

View File

@ -1,3 +1,5 @@
_CarbonSndPlayDoubleBuffer
_ConvertFromIeeeExtended
__book_maptype1_quantvals
__book_unquantize
__float32_pack
@ -138,3 +140,101 @@ _ov_pcm_seek_page_lap
_ov_raw_seek_lap
_ov_time_seek_lap
_ov_time_seek_page_lap
_II_step_one
_II_step_two
_MyRecComp
_SampleRates
_Sinfo
_ValidStepIndex
__Z11fmodwrapperv
__Z11fmodwrapperv.eh
__floor_P
__mapping_P
__residue_P
__ve_envelope_clear
__ve_envelope_init
__ve_envelope_mark
__ve_envelope_search
__ve_envelope_shift
__vi_gpsy_free
__vi_psy_free
__vorbis_window_init
__vp_ampmax_decay
__vp_couple
__vp_global_free
__vp_global_look
__vp_noise_normalize
__vp_noise_normalize_sort
__vp_noisemask
__vp_offset_and_mix
__vp_psy_clear
__vp_psy_init
__vp_quantize_couple_memo
__vp_quantize_couple_sort
__vp_remove_floor
__vp_tonemask
_alloc_0
_alloc_1
_alloc_2
_alloc_3
_alloc_4
_bandInfo
_cdcallback
_cdchannel
_cdmode
_cdnumtracks
_cdstream
_cdtrack
_drft_backward
_drft_clear
_drft_forward
_drft_init
_eatwhite
_floor0_exportbundle
_floor1_exportbundle
_gFreeList
_gNMRecBusy
_gNMRecPtr
_gSilenceOnes
_gSilenceTwos
_longLimit
_mapping0_exportbundle
_mdct_backward
_mdct_clear
_mdct_forward
_mdct_init
_muls
_mystrdup
_res0_free_info
_res0_free_look
_res0_inverse
_res0_look
_res0_unpack
_res1_class
_res1_inverse
_res2_inverse
_residue0_exportbundle
_residue1_exportbundle
_residue2_exportbundle
_scale
_shortLimit
_tabsel_123
_F_Free
_F_Malloc
_F_ReAlloc
_F_memcmp
_F_memmove
_F_strcat
_F_strchr
_F_strcmp
_F_strcpy
_F_stricmp
_F_strlen
_F_strncat
_F_strncmp
_F_strncpy
_F_strnicmp
_F_strstr
_F_strupr
_F_tolower
_F_toupper

View File

@ -43,6 +43,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
case POOL_SIMPLE:
poolp = new LLDrawPoolSimple();
break;
case POOL_GLOW:
poolp = new LLDrawPoolGlow();
break;
case POOL_ALPHA:
poolp = new LLDrawPoolAlpha();
break;

View File

@ -38,6 +38,7 @@ public:
POOL_BUMP,
POOL_AVATAR,
POOL_TREE,
POOL_GLOW,
POOL_ALPHA,
POOL_WATER,
POOL_ALPHA_POST_WATER,
@ -86,8 +87,8 @@ public:
enum
{
PASS_SIMPLE = NUM_POOL_TYPES,
PASS_FULLBRIGHT,
PASS_GLOW,
PASS_FULLBRIGHT,
PASS_INVISIBLE,
PASS_SHINY,
PASS_BUMP,

View File

@ -271,12 +271,20 @@ void LLDrawPoolAlpha::renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask
{
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
light_enabled = FALSE;
if (LLPipeline::sRenderGlow)
{
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
}
}
else if (!light_enabled)
{
gPipeline.enableLightsDynamic(1.f);
light_enabled = TRUE;
if (LLPipeline::sRenderGlow)
{
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
}
}
/*if (params.mParticle)
@ -309,6 +317,11 @@ void LLDrawPoolAlpha::renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask
if (!light_enabled)
{
gPipeline.enableLightsDynamic(1.f);
if (LLPipeline::sRenderGlow)
{
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
}
}
/*glPointSize(1.f);

View File

@ -27,7 +27,7 @@ public:
LLDrawPoolBump();
/*virtual*/ void render(S32 pass = 0);
virtual void render(S32 pass = 0);
/*virtual*/ void beginRenderPass( S32 pass );
/*virtual*/ void endRenderPass( S32 pass );
/*virtual*/ S32 getNumPasses();

View File

@ -9,44 +9,92 @@
#include "llviewerprecompiledheaders.h"
#include "lldrawpoolsimple.h"
#include "lldrawpoolbump.h"
#include "llviewercamera.h"
#include "llagent.h"
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
#include "pipeline.h"
class LLRenderPassGlow : public LLRenderPass
class LLRenderShinyGlow : public LLDrawPoolBump
{
public:
LLRenderPassGlow(): LLRenderPass(LLRenderPass::PASS_GLOW) { }
LLRenderShinyGlow() { }
enum
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD
};
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
virtual void prerender() { }
void render(S32 pass = 0)
{
LLGLEnable blend(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask());
renderActive(LLRenderPass::PASS_GLOW, getVertexDataMask());
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap();
if( cube_map )
{
cube_map->enable(0);
cube_map->setMatrix(0);
cube_map->bind();
glEnableClientState(GL_NORMAL_ARRAY);
glColor4f(1,1,1,1);
void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE)
{
glColor4ubv(params.mGlowColor.mV);
LLRenderPass::pushBatch(params, mask, texture);
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL;
renderStatic(LLRenderPass::PASS_SHINY, mask);
renderActive(LLRenderPass::PASS_SHINY, mask);
glDisableClientState(GL_NORMAL_ARRAY);
cube_map->disable();
cube_map->restoreMatrix();
}
}
};
void LLDrawPoolGlow::render(S32 pass)
{
LLGLEnable blend(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask());
renderActive(LLRenderPass::PASS_GLOW, getVertexDataMask());
if (gSky.mVOSkyp)
{
glPushMatrix();
LLVector3 origin = gCamera->getOrigin();
glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]);
LLFace* facep = gSky.mVOSkyp->mFace[LLVOSky::FACE_BLOOM];
if (facep)
{
LLGLDisable cull(GL_CULL_FACE);
facep->getTexture()->bind();
glColor4f(1,1,1,1);
facep->renderIndexed(getVertexDataMask());
}
glPopMatrix();
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (LLPipeline::sDynamicReflections)
{
LLRenderShinyGlow glow;
glow.render();
}
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
{
glColor4ubv(params.mGlowColor.mV);
LLRenderPass::pushBatch(params, mask, texture);
}
LLDrawPoolSimple::LLDrawPoolSimple() :
LLRenderPass(POOL_SIMPLE)
{
@ -97,21 +145,15 @@ void LLDrawPoolSimple::render(S32 pass)
renderActive(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);
}
{
LLFastTimer t(LLFastTimer::FTM_RENDER_GLOW);
glDisableClientState(GL_COLOR_ARRAY);
LLRenderPassGlow glow;
glow.render();
}
{
LLFastTimer t(LLFastTimer::FTM_RENDER_INVISIBLE);
U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
renderInvisible(invisi_mask);
renderActive(LLRenderPass::PASS_INVISIBLE, invisi_mask);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
}
}

View File

@ -31,4 +31,24 @@ public:
};
class LLDrawPoolGlow : public LLRenderPass
{
public:
LLDrawPoolGlow(): LLRenderPass(LLDrawPool::POOL_GLOW) { }
enum
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD
};
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
virtual void prerender() { }
void render(S32 pass = 0);
void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE);
};
#endif // LL_LLDRAWPOOLSIMPLE_H

View File

@ -33,16 +33,6 @@ const LLUUID WATER_TEST("2bfd3884-7e27-69b9-ba3a-3e673f680004");
static float sTime;
int nhpo2(int v)
{
int r = 1;
while (r < v) {
r *= 2;
}
return r;
}
static GLuint sScreenTex = 0;
BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
LLDrawPoolWater::LLDrawPoolWater() :
@ -69,30 +59,9 @@ LLDrawPoolWater::~LLDrawPoolWater()
//static
void LLDrawPoolWater::restoreGL()
{
if (gPipeline.getVertexShaderLevel(LLPipeline::SHADER_ENVIRONMENT) >= SHADER_LEVEL_RIPPLE)
{
//build screen texture
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glActiveTextureARB(GL_TEXTURE0_ARB);
glGenTextures(1, &sScreenTex);
LLGLEnable gl_texture_2d(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, sScreenTex);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
GLuint resX = nhpo2(viewport[2]);
GLuint resY = nhpo2(viewport[3]);
gImageList.updateMaxResidentTexMem(-1, resX*resY*3);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resX, resY, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
LLDrawPool *LLDrawPoolWater::instancePool()
{
llerrs << "Should never be calling instancePool on a water pool!" << llendl;
@ -130,7 +99,7 @@ void LLDrawPoolWater::render(S32 pass)
std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
LLGLSPipelineAlpha alphaState;
LLGLEnable blend(GL_BLEND);
if ((mVertexShaderLevel >= SHADER_LEVEL_RIPPLE))
{
@ -324,7 +293,6 @@ void LLDrawPoolWater::render(S32 pass)
glDisableClientState(GL_NORMAL_ARRAY);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
@ -508,50 +476,10 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void bindScreenToTexture()
{
if (LLDrawPoolWater::sSkipScreenCopy)
{
glBindTexture(GL_TEXTURE_2D, 0);
}
else
{
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
GLuint resX = nhpo2(viewport[2]);
GLuint resY = nhpo2(viewport[3]);
glBindTexture(GL_TEXTURE_2D, sScreenTex);
GLint cResX;
GLint cResY;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &cResX);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &cResY);
if (cResX != (GLint)resX || cResY != (GLint)resY)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resX, resY, 0, GL_RGB, GL_FLOAT, NULL);
gImageList.updateMaxResidentTexMem(-1, resX*resY*3);
}
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, viewport[0], viewport[1], 0, 0, viewport[2], viewport[3]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
float scale[2];
scale[0] = (float) viewport[2]/resX;
scale[1] = (float) viewport[3]/resY;
glUniform2fvARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_FBSCALE], 1, scale);
LLImageGL::sBoundTextureMemory += resX * resY * 3;
}
}
void LLDrawPoolWater::shade()
{
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
static LLVector2 d1( 0.5f, -0.17f );
static LLVector2 d2( 0.58f, -0.67f );
static LLVector2 d3( 0.5f, 0.25f );
@ -630,8 +558,18 @@ void LLDrawPoolWater::shade()
gPipeline.mWaterProgram.bind();
bindScreenToTexture();
if (!sSkipScreenCopy)
{
gPipeline.bindScreenToTexture();
}
else
{
glBindTexture(GL_TEXTURE_2D, 0);
}
glUniform2fvARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_FBSCALE], 1,
gPipeline.mScreenScale.mV);
S32 diffTex = gPipeline.mWaterProgram.enableTexture(LLPipeline::GLSL_DIFFUSE_MAP);
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
@ -693,6 +631,7 @@ void LLDrawPoolWater::shade()
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
}
void LLDrawPoolWater::renderForSelect()

View File

@ -47,26 +47,31 @@ LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder
//-----------------------------------------------------------------------------
LLDynamicTexture::~LLDynamicTexture()
{
releaseGLTexture();
for( S32 order = 0; order < ORDER_COUNT; order++ )
{
LLDynamicTexture::sInstances[order].removeData(this); // will fail in all but one case.
}
}
//-----------------------------------------------------------------------------
// releaseGLTexture()
//-----------------------------------------------------------------------------
void LLDynamicTexture::releaseGLTexture()
{
if (mTexture.notNull())
{
// llinfos << "RELEASING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl;
mTexture = NULL;
}
}
//-----------------------------------------------------------------------------
// generateGLTexture()
//-----------------------------------------------------------------------------
void LLDynamicTexture::generateGLTexture()
{
if (mComponents < 1 || mComponents > 4)
{
llerrs << "Bad number of components in dynamic texture: " << mComponents << llendl;
}
LLPointer<LLImageRaw> raw_image = new LLImageRaw(mWidth, mHeight, mComponents);
mTexture = new LLImageGL(mWidth, mHeight, mComponents, FALSE);
mTexture->createGLTexture(0, raw_image);
mTexture->setClamp(mClamp, mClamp);
generateGLTexture(-1, 0, 0, FALSE);
}
void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
@ -75,10 +80,14 @@ void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum prima
{
llerrs << "Bad number of components in dynamic texture: " << mComponents << llendl;
}
releaseGLTexture();
LLPointer<LLImageRaw> raw_image = new LLImageRaw(mWidth, mHeight, mComponents);
mTexture = new LLImageGL(mWidth, mHeight, mComponents, FALSE);
mTexture->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
if (internal_format >= 0)
{
mTexture->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
}
// llinfos << "ALLOCATING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl;
mTexture->createGLTexture(0, raw_image);
mTexture->setClamp(mClamp, mClamp);
}

View File

@ -47,6 +47,7 @@ public:
static void restoreGL();
protected:
void releaseGLTexture();
void generateGLTexture();
void generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes = FALSE);

View File

@ -915,7 +915,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector2 tmin, tmax;
const LLTextureEntry *tep = mVObjp->getTE(f);
U8 bump_code = tep ? bump_code = tep->getBumpmap() : 0;
U8 bump_code = tep ? tep->getBumpmap() : 0;
if (rebuild_tcoord)
{

View File

@ -128,7 +128,8 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
// Compute icon for this item
LLUUID icon_id = get_item_icon_uuid(LLAssetType::AT_OBJECT,
LLInventoryType::IT_OBJECT,
0x0);
0x0, FALSE);
row["columns"][0]["column"] = "icon";
row["columns"][0]["type"] = "icon";
row["columns"][0]["value"] = icon_id;
@ -224,9 +225,16 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
LLSD row;
// Compute icon for this item
BOOL item_is_multi = FALSE;
if ( inv_item->getFlags() & LLInventoryItem::II_FLAGS_LANDMARK_VISITED )
{
item_is_multi = TRUE;
}
LLUUID icon_id = get_item_icon_uuid(inv_item->getType(),
inv_item->getInventoryType(),
inv_item->getFlags());
inv_item->getFlags(),
item_is_multi);
row["columns"][0]["column"] = "icon";
row["columns"][0]["type"] = "icon";
row["columns"][0]["value"] = icon_id;

View File

@ -195,9 +195,17 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
// Create the line in the list
LLSD row;
BOOL item_is_multi = FALSE;
if ( inv_item->getFlags() & LLInventoryItem::II_FLAGS_LANDMARK_VISITED )
{
item_is_multi = TRUE;
}
LLUUID icon_id = get_item_icon_uuid(inv_item->getType(),
inv_item->getInventoryType(),
inv_item->getFlags());
inv_item->getFlags(),
item_is_multi);
row["columns"][0]["column"] = "icon";
row["columns"][0]["type"] = "icon";
row["columns"][0]["value"] = icon_id;

View File

@ -218,7 +218,7 @@ public:
{
}
// *TODO define custom uploadFailed here so it's not such a generic message
void LLSendPostcardResponder::uploadComplete(const LLSD& content)
void uploadComplete(const LLSD& content)
{
// we don't care about what the server returns from this post, just clean up the UI
LLUploadDialog::modalUploadFinished();

View File

@ -2524,6 +2524,7 @@ LLFolderView::LLFolderView( const LLString& name, LLViewerImage* root_folder_ico
mShowSingleSelection(FALSE),
mArrangeGeneration(0),
mSelectCallback(NULL),
mSelectionChanged(FALSE),
mMinWidth(0),
mDragAndDropThisFrame(FALSE)
{
@ -4408,9 +4409,11 @@ LLInventoryFilter::LLInventoryFilter(const LLString& name) :
mFilterGeneration = 0;
mMustPassGeneration = S32_MAX;
mMinRequiredGeneration = 0;
mFilterCount = 0;
mNextFilterGeneration = mFilterGeneration + 1;
mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");
mFilterBehavior = FILTER_NONE;
}
LLInventoryFilter::~LLInventoryFilter()

View File

@ -103,6 +103,7 @@ const char* ICON_NAME[ICON_NAME_COUNT] =
"inv_item_script.tga",
"inv_item_clothing.tga",
"inv_item_object.tga",
"inv_item_object_multi.tga",
"inv_item_notecard.tga",
"inv_item_bodypart.tga",
"inv_item_snapshot.tga",
@ -2313,7 +2314,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLViewerImage* LLScriptBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0);
return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE);
}
// +=================================================+
@ -2325,7 +2326,7 @@ LLString LLTextureBridge::sPrefix("Texture: ");
LLViewerImage* LLTextureBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_TEXTURE, mInvType, 0);
return get_item_icon(LLAssetType::AT_TEXTURE, mInvType, 0, FALSE);
}
void open_texture(const LLUUID& item_id,
@ -2375,7 +2376,7 @@ LLString LLSoundBridge::sPrefix("Sound: ");
LLViewerImage* LLSoundBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0);
return get_item_icon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0, FALSE);
}
void LLSoundBridge::openItem()
@ -2470,7 +2471,7 @@ LLString LLLandmarkBridge::sPrefix("Landmark: ");
LLViewerImage* LLLandmarkBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, mVisited);
return get_item_icon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, mVisited, FALSE);
}
void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
@ -2631,7 +2632,7 @@ LLViewerImage* LLCallingCardBridge::getIcon() const
{
online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID());
}
return get_item_icon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, online);
return get_item_icon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, online, FALSE);
}
LLString LLCallingCardBridge::getLabelSuffix() const
@ -2779,7 +2780,7 @@ LLString LLNotecardBridge::sPrefix("Note: ");
LLViewerImage* LLNotecardBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0);
return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE);
}
void open_notecard(const LLUUID& item_id,
@ -2851,7 +2852,7 @@ LLString LLGestureBridge::sPrefix("Gesture: ");
LLViewerImage* LLGestureBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0);
return get_item_icon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0, FALSE);
}
LLFontGL::StyleFlags LLGestureBridge::getLabelStyle() const
@ -2984,7 +2985,7 @@ LLString LLAnimationBridge::sPrefix("Animation: ");
LLViewerImage* LLAnimationBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0);
return get_item_icon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0, FALSE);
}
void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
@ -3102,7 +3103,7 @@ BOOL LLObjectBridge::isItemRemovable()
LLViewerImage* LLObjectBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_OBJECT, mInvType, mAttachPt);
return get_item_icon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject );
}
void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment);
@ -3357,7 +3358,7 @@ LLString LLLSLTextBridge::sPrefix("Script: ");
LLViewerImage* LLLSLTextBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0);
return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE);
}
void LLLSLTextBridge::openItem()
@ -4120,7 +4121,7 @@ LLString LLWearableBridge::getLabelSuffix() const
LLViewerImage* LLWearableBridge::getIcon() const
{
return get_item_icon(mAssetType, mInvType, mWearableType);
return get_item_icon(mAssetType, mInvType, mWearableType, FALSE);
}
// virtual

View File

@ -22,6 +22,7 @@ enum EInventoryIcon
SCRIPT_ICON_NAME,
CLOTHING_ICON_NAME,
OBJECT_ICON_NAME,
OBJECT_MULTI_ICON_NAME,
NOTECARD_ICON_NAME,
BODYPART_ICON_NAME,
SNAPSHOT_ICON_NAME,
@ -509,6 +510,8 @@ protected:
LLItemBridge(inventory, uuid), mInvType(type)
{
mAttachPt = (flags & 0xff); // low bye of inventory flags
mIsMultiObject = ( flags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) ? TRUE: FALSE;
}
protected:
@ -516,7 +519,7 @@ protected:
static LLUUID sContextMenuItemID; // Only valid while the context menu is open.
LLInventoryType::EType mInvType;
U32 mAttachPt;
BOOL mIsMultiObject;
};

View File

@ -1678,7 +1678,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
}
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
}
glPushMatrix();

View File

@ -304,9 +304,16 @@ void LLPanelGroupNotices::setItem(LLPointer<LLInventoryItem> inv_item)
{
mInventoryItem = inv_item;
BOOL item_is_multi = FALSE;
if ( inv_item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS )
{
item_is_multi = TRUE;
};
LLViewerImage* item_icon = get_item_icon(inv_item->getType(),
inv_item->getInventoryType(),
inv_item->getFlags());
inv_item->getFlags(),
item_is_multi );
mCreateInventoryIcon->setImage(item_icon->getID());
mCreateInventoryIcon->setVisible(TRUE);
@ -463,7 +470,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
{
LLUUID icon_id = get_item_icon_uuid(
(LLAssetType::EType)asset_type,
LLInventoryType::IT_NONE,FALSE);
LLInventoryType::IT_NONE,FALSE, FALSE);
row["columns"][0]["type"] = "icon";
row["columns"][0]["value"] = icon_id;
}
@ -531,7 +538,7 @@ void LLPanelGroupNotices::showNotice(const char* subject,
LLViewerImage* item_icon = get_item_icon(mInventoryOffer->mType,
LLInventoryType::IT_TEXTURE,
0);
0, FALSE);
mViewInventoryIcon->setImage(item_icon->getID());
mViewInventoryIcon->setVisible(TRUE);

View File

@ -321,7 +321,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
}
U8 rotationOrder;
numRead = fread(&rotationOrder, 1, 1, fp);
numRead = fread(&rotationOrder, sizeof(U8), 1, fp);
if (numRead != 1)
{

View File

@ -1076,7 +1076,7 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
if (drawablep->getPositionGroup().magVecSquared() > MAX_MAG)
{
#ifndef LL_RELEASE_FOR_DOWNLOAD
#if 0 //ndef LL_RELEASE_FOR_DOWNLOAD
llwarns << "LLSpatialPartition::put Object out of range!" << llendl;
llinfos << drawablep->getPositionGroup() << llendl;
@ -1726,8 +1726,9 @@ void LLSpatialPartition::processImagery(LLCamera* camera)
gPipeline.mCubeBuffer->initGL();
}
S32 res = gSavedSettings.getS32("RenderReflectionRes");
gPipeline.generateReflectionMap(gPipeline.mCubeBuffer, cube_cam, 128);
gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map, 64);
gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map, res);
group->mReflectionMap = cube_map;
group->setState(LLSpatialGroup::GEOM_DIRTY);
gPipeline.markRebuild(group);
@ -2203,7 +2204,7 @@ void LLSpatialPartition::doOcclusion(LLCamera* camera)
glFlush();
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
}
class LLOctreeGet : public LLSpatialGroup::OctreeTraveler

View File

@ -36,8 +36,6 @@
// SJB: We really always want to use the GL cache;
// let GL page textures in and out of video RAM instead of trying to do so by hand.
// const U32 USE_AVATAR_GL_CACHE_THRESHOLD = 1024 * 1024 * 35; // 35 MB
BOOL gUseAvatarGLCache = TRUE; //FALSE;
LLGradientPaletteList gGradientPaletteList;
@ -218,8 +216,6 @@ BOOL LLTexLayerSetBuffer::render()
{
U8* baked_bump_data = NULL;
// gUseAvatarGLCache = ( gImageList.getMaxResidentTexMem() > USE_AVATAR_GL_CACHE_THRESHOLD );
// do we need to upload, and do we have sufficient data to create an uploadable composite?
// When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
BOOL upload_now = (gAgent.mNumPendingQueries == 0 && mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal());
@ -754,7 +750,6 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE );
glBlendFunc( GL_ONE, GL_ZERO );
if( gUseAvatarGLCache )
{
LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticAlphaFileName, TRUE );
if( image_gl )
@ -768,29 +763,6 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
success = FALSE;
}
}
else
{
LLImageRaw* image_raw = gTexStaticImageList.getImageRaw( getInfo()->mStaticAlphaFileName );
if( image_raw )
{
GLenum format = GL_ALPHA;
if( mAvatar->bindScratchTexture(format) )
{
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, image_raw->getWidth(), image_raw->getHeight(), format, GL_UNSIGNED_BYTE, image_raw->getData() );
stop_glerror();
gl_rect_2d_simple_tex( width, height );
}
else
{
success = FALSE;
}
}
else
{
success = FALSE;
}
}
LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
@ -1267,23 +1239,6 @@ BOOL LLTexLayer::parseData( LLXmlTreeNode* node )
//-----------------------------------------------------------------------------
BOOL LLTexLayer::loadStaticImageRaw()
{
if( mStaticImageRaw.isNull() && !mStaticImageInvalid)
{
mStaticImageRaw = gTexStaticImageList.getImageRaw( getInfo()->mStaticImageFileName );
// We now have something in one of our caches
LLTexLayerSet::sHasCaches |= mStaticImageRaw.notNull() ? TRUE : FALSE;
if( mStaticImageRaw.isNull() )
{
llwarns << "Unable to load static file: " << getInfo()->mStaticImageFileName << llendl;
mStaticImageInvalid = TRUE; // don't try again.
return FALSE;
}
}
return TRUE;
}
void LLTexLayer::deleteCaches()
{
for( alpha_list_t::iterator iter = mParamAlphaList.begin();
@ -1356,7 +1311,6 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly )
{
if( gUseAvatarGLCache )
{
LLImageGL* image_gl = NULL;
if( mTexLayerSet->getAvatar()->getLocalTextureGL( getInfo()->mLocalTexture, &image_gl ) )
@ -1382,29 +1336,10 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
success = FALSE;
}
}
else
{
LLPointer<LLImageRaw> image_raw = new LLImageRaw;
if( mTexLayerSet->getAvatar()->getLocalTextureRaw( getInfo()->mLocalTexture, image_raw ) )
{
success &= renderImageRaw( image_raw->getData(),
image_raw->getWidth(),
image_raw->getHeight(),
image_raw->getComponents(),
width,
height,
FALSE );
}
else
{
success = FALSE;
}
}
}
if( !getInfo()->mStaticImageFileName.empty() )
{
if( gUseAvatarGLCache )
{
LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
if( image_gl )
@ -1418,26 +1353,6 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
success = FALSE;
}
}
else
{
// Don't load the image file until we actually need it the first time. Like now.
if (!loadStaticImageRaw())
{
success = FALSE;
}
if( mStaticImageRaw.notNull() )
{
success &= renderImageRaw(
mStaticImageRaw->getData(),
mStaticImageRaw->getWidth(),
mStaticImageRaw->getHeight(),
mStaticImageRaw->getComponents(), width, height, getInfo()->mStaticImageIsMask );
}
else
{
success = FALSE;
}
}
}
if( ((-1 == getInfo()->mLocalTexture) ||
@ -1591,7 +1506,6 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
// Accumulate the alpha component of the texture
if( getInfo()->mLocalTexture != -1 )
{
if( gUseAvatarGLCache )
{
LLImageGL* image_gl = NULL;
if( mTexLayerSet->getAvatar()->getLocalTextureGL( getInfo()->mLocalTexture, &image_gl ) )
@ -1616,30 +1530,10 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
success = FALSE;
}
}
else
{
LLPointer<LLImageRaw> image_raw = new LLImageRaw;
if( mTexLayerSet->getAvatar()->getLocalTextureRaw( getInfo()->mLocalTexture, image_raw ) )
{
if(image_raw->getComponents() == 4)
{
success &= renderImageRaw(
image_raw->getData(),
image_raw->getWidth(),
image_raw->getHeight(),
image_raw->getComponents(), width, height, FALSE );
}
}
else
{
success = FALSE;
}
}
}
if( !getInfo()->mStaticImageFileName.empty() )
{
if( gUseAvatarGLCache )
{
LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
if( image_gl )
@ -1658,31 +1552,6 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
success = FALSE;
}
}
else
{
// Don't load the image file until we actually need it the first time. Like now.
if (!loadStaticImageRaw())
{
success = FALSE;
}
if( mStaticImageRaw.notNull() )
{
if( (mStaticImageRaw->getComponents() == 4) ||
( (mStaticImageRaw->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
{
success &= renderImageRaw(
mStaticImageRaw->getData(),
mStaticImageRaw->getWidth(),
mStaticImageRaw->getHeight(),
mStaticImageRaw->getComponents(), width, height, getInfo()->mStaticImageIsMask );
}
}
else
{
success = FALSE;
}
}
}
// Draw a rectangle with the layer color to multiply the alpha by that color's alpha.
@ -2087,8 +1956,7 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )
if( !mCachedProcessedImageGL ||
(mCachedProcessedImageGL->getWidth() != image_tga_width) ||
(mCachedProcessedImageGL->getHeight() != image_tga_height) ||
(weight_changed && !(gGLManager.mHasPalettedTextures && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_PALETTE))) ||
(!gUseAvatarGLCache) )
(weight_changed && !(gGLManager.mHasPalettedTextures && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_PALETTE))) )
{
// llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl;
mCachedEffectiveWeight = effective_weight;
@ -2130,7 +1998,6 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )
if( mCachedProcessedImageGL )
{
if( gUseAvatarGLCache ) // 64 MB
{
if (gGLManager.mHasPalettedTextures && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_PALETTE))
{
@ -2168,94 +2035,6 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )
}
stop_glerror();
}
else
{
if( (mCachedProcessedImageGL->getWidth() != VOAVATAR_SCRATCH_TEX_WIDTH) ||
(mCachedProcessedImageGL->getHeight() != VOAVATAR_SCRATCH_TEX_HEIGHT) )
{
if (gGLManager.mHasPalettedTextures && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_PALETTE))
{
mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw);
LLGLSNoAlphaTest gls_no_alpha_test;
mCachedProcessedImageGL->bind();
mCachedProcessedImageGL->setClamp(TRUE, TRUE);
gGradientPaletteList.setHardwarePalette( getInfo()->mDomain, effective_weight );
gl_rect_2d_simple_tex( width, height );
LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
mCachedProcessedImageGL->destroyGLTexture();
}
else
{
// Create the GL texture, bind it and draw a rect, and then immediately destroy it.
mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw);
LLGLSNoAlphaTest gls_no_alpha_test;
mCachedProcessedImageGL->bind();
mCachedProcessedImageGL->setClamp(TRUE, TRUE);
gl_rect_2d_simple_tex( width, height );
LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
mCachedProcessedImageGL->destroyGLTexture();
}
stop_glerror();
}
else
{
if (gGLManager.mHasPalettedTextures && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_PALETTE))
{
// Write into a pre-existing GL Image, and then bind and render that.
// Faster than creating a new GL Image and then destroying it.
if( mTexLayer->getTexLayerSet()->getAvatar()->bindScratchTexture( GL_COLOR_INDEX ) )
{
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0,
mCachedProcessedImageGL->getWidth(),
mCachedProcessedImageGL->getHeight(),
GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
mStaticImageRaw->getData() );
stop_glerror();
LLGLSNoAlphaTest gls_no_alpha_test;
gGradientPaletteList.setHardwarePalette( getInfo()->mDomain, effective_weight );
gl_rect_2d_simple_tex( width, height );
LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
}
else
{
success = FALSE;
}
}
else
{
// Write into a pre-existing GL Image, and then bind and render that.
// Faster than creating a new GL Image and then destroying it.
if( mTexLayer->getTexLayerSet()->getAvatar()->bindScratchTexture( GL_ALPHA ) )
{
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0,
mCachedProcessedImageGL->getWidth(),
mCachedProcessedImageGL->getHeight(),
GL_ALPHA, GL_UNSIGNED_BYTE,
mStaticImageRaw->getData() );
stop_glerror();
LLGLSNoAlphaTest gls_no_alpha_test;
gl_rect_2d_simple_tex( width, height );
LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
}
else
{
success = FALSE;
}
}
}
}
}
// Don't keep the cache for other people's avatars
@ -2606,7 +2385,6 @@ LLStringTable LLTexStaticImageList::sImageNames(16384);
LLTexStaticImageList::LLTexStaticImageList()
:
mRawBytes( 0 ),
mGLBytes( 0 ),
mTGABytes( 0 )
{}
@ -2619,36 +2397,31 @@ LLTexStaticImageList::~LLTexStaticImageList()
void LLTexStaticImageList::dumpByteCount()
{
llinfos << "Avatar Static Textures " <<
" Raw:" << (mRawBytes / 1024) <<
"KB GL:" << (mGLBytes / 1024) <<
"KB TGA:" << (mTGABytes / 1024) << "KB" << llendl;
}
void LLTexStaticImageList::deleteCachedImages()
{
if( mRawBytes || mGLBytes || mTGABytes )
if( mGLBytes || mTGABytes )
{
llinfos << "Clearing Static Textures " <<
" Raw:" << (mRawBytes / 1024) <<
"KB GL:" << (mGLBytes / 1024) <<
"KB TGA:" << (mTGABytes / 1024) << "KB" << llendl;
//mStaticImageLists uses LLPointers, clear() will cause deletion
mStaticImageListRaw.clear();
mStaticImageListTGA.clear();
mStaticImageListGL.clear();
mRawBytes = 0;
mGLBytes = 0;
mTGABytes = 0;
}
}
// Note: in general, for a given image image we'll call either getImageTga(), getImageRaw() or getImageGL().
// Note: in general, for a given image image we'll call either getImageTga() or getImageGL().
// We call getImageTga() if the image is used as an alpha gradient.
// Otherwise, we call getImageRaw() if we have 32 MB or less of video RAM or less and getImageGL() if we have
// more video RAM than that.
// Otherwise, we call getImageGL()
// Returns an LLImageTGA that contains the encoded data from a tga file named file_name.
// Caches the result to speed identical subsequent requests.
@ -2680,34 +2453,6 @@ LLImageTGA* LLTexStaticImageList::getImageTGA(const LLString& file_name)
// Returns an LLImageRaw that contains the decoded data from a tga file named file_name.
// Caches the result to speed identical subsequent requests.
LLImageRaw* LLTexStaticImageList::getImageRaw(const LLString& file_name)
{
LLPointer<LLImageRaw> image_raw;
const char *namekey = sImageNames.addString(file_name);
image_raw_map_t::iterator iter = mStaticImageListRaw.find(namekey);
if( iter != mStaticImageListRaw.end() )
{
image_raw = iter->second;
}
else
{
image_raw = new LLImageRaw();
if( loadImageRaw( file_name, image_raw ) )
{
mStaticImageListRaw[ namekey ] = image_raw;
mRawBytes += image_raw->getDataSize();
}
else
{
image_raw = NULL;
}
}
return image_raw;
}
// Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name.
// Caches the result to speed identical subsequent requests.
LLImageGL* LLTexStaticImageList::getImageGL(const LLString& file_name, BOOL is_mask )

View File

@ -321,9 +321,6 @@ public:
BOOL renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4* colorp );
BOOL hasAlphaParams() { return (!mParamAlphaList.empty());}
protected:
BOOL loadStaticImageRaw();
protected:
LLTexLayerSet* mTexLayerSet;
LLPointer<LLImageRaw> mStaticImageRaw;
@ -498,15 +495,12 @@ private:
private:
static LLStringTable sImageNames;
typedef std::map< const char *, LLPointer<LLImageRaw> > image_raw_map_t;
typedef std::map< const char *, LLPointer<LLImageGL> > image_gl_map_t;
typedef std::map< const char *, LLPointer<LLImageTGA> > image_tga_map_t;
image_raw_map_t mStaticImageListRaw;
image_gl_map_t mStaticImageListGL;
image_tga_map_t mStaticImageListTGA;
public:
S32 mRawBytes;
S32 mGLBytes;
S32 mTGABytes;
};

View File

@ -671,7 +671,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)
mWriteData = NULL; // we never owned data
mDataSize = 0;
}
mResponder->completed(success);
mCache->addCompleted(mResponder, success);
}
}
@ -705,6 +705,7 @@ LLTextureCache::LLTextureCache(bool threaded)
: LLWorkerThread("TextureCache", threaded),
mWorkersMutex(getAPRPool()),
mHeaderMutex(getAPRPool()),
mListMutex(getAPRPool()),
mFileAPRPool(NULL),
mReadOnly(FALSE),
mTexturesSizeTotal(0),
@ -726,9 +727,17 @@ S32 LLTextureCache::update(U32 max_time_ms)
S32 res;
res = LLWorkerThread::update(max_time_ms);
mListMutex.lock();
handle_list_t priorty_list = mPrioritizeWriteList; // copy list
mPrioritizeWriteList.clear();
responder_list_t completed_list = mCompletedList; // copy list
mCompletedList.clear();
mListMutex.unlock();
lockWorkers();
for (std::vector<handle_t>::iterator iter1 = mPrioritizeWriteList.begin();
iter1 != mPrioritizeWriteList.end(); ++iter1)
for (handle_list_t::iterator iter1 = priorty_list.begin();
iter1 != priorty_list.end(); ++iter1)
{
handle_t handle = *iter1;
handle_map_t::iterator iter2 = mWriters.find(handle);
@ -738,8 +747,17 @@ S32 LLTextureCache::update(U32 max_time_ms)
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mPriority);
}
}
mPrioritizeWriteList.clear();
for (responder_list_t::iterator iter1 = completed_list.begin();
iter1 != completed_list.end(); ++iter1)
{
Responder *responder = iter1->first;
bool success = iter1->second;
responder->completed(success);
}
unlockWorkers();
return res;
}
@ -1294,9 +1312,16 @@ void LLTextureCache::prioritizeWrite(handle_t handle)
{
// Don't prioritize yet, we might be working on this now
// which could create a deadlock
LLMutexLock lock(&mListMutex);
mPrioritizeWriteList.push_back(handle);
}
void LLTextureCache::addCompleted(Responder* responder, bool success)
{
LLMutexLock lock(&mListMutex);
mCompletedList.push_back(std::make_pair(responder,success));
}
//////////////////////////////////////////////////////////////////////////////
// Called from MAIN thread (endWork())

View File

@ -84,6 +84,7 @@ protected:
bool appendToTextureEntryList(const LLUUID& id, S32 size);
std::string getLocalFileName(const LLUUID& id);
std::string getTextureFileName(const LLUUID& id);
void addCompleted(Responder* responder, bool success);
private:
void setDirNames(ELLPath location);
@ -99,12 +100,18 @@ private:
// Internal
LLMutex mWorkersMutex;
LLMutex mHeaderMutex;
LLMutex mListMutex;
apr_pool_t* mFileAPRPool;
typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t;
handle_map_t mReaders;
handle_map_t mWriters;
std::vector<handle_t> mPrioritizeWriteList;
typedef std::vector<handle_t> handle_list_t;
handle_list_t mPrioritizeWriteList;
typedef std::vector<std::pair<LLPointer<Responder>, bool> > responder_list_t;
responder_list_t mCompletedList;
BOOL mReadOnly;

View File

@ -220,7 +220,6 @@ private:
U32 calcWorkPriority();
void removeFromCache();
bool processSimulatorPackets();
void startDecode();
bool decodeImage();
bool writeToCacheComplete();
@ -235,7 +234,7 @@ private:
void callbackDecoded(bool success);
private:
enum e_state
enum e_state // mState
{
// NOTE: Affects LLTextureBar::draw in lltextureview.cpp (debug hack)
INVALID = 0,
@ -252,6 +251,14 @@ private:
WAIT_ON_WRITE,
DONE
};
enum e_request_state // mSentRequest
{
UNSENT = 0,
QUEUED = 1,
SENT_SIM = 2,
SENT_URL = 3,
SENT_HTTP = 4
};
static const char* sStateDescs[];
e_state mState;
LLTextureFetch* mFetcher;
@ -261,6 +268,7 @@ private:
LLPointer<LLImageRaw> mAuxImage;
LLUUID mID;
LLHost mHost;
U8 mType;
F32 mImagePriority;
U32 mWorkPriority;
F32 mRequestedPriority;
@ -270,7 +278,7 @@ private:
S32 mLoadedDiscard;
S32 mDecodedDiscard;
LLFrameTimer mRequestedTimer;
LLFrameTimer mIdleTimer;
LLFrameTimer mFetchTimer;
LLTextureCache::handle_t mCacheReadHandle;
LLTextureCache::handle_t mCacheWriteHandle;
U8* mBuffer;
@ -280,12 +288,11 @@ private:
S32 mFileSize;
S32 mCachedSize;
BOOL mLoaded;
BOOL mRequested;
e_request_state mSentRequest;
BOOL mDecoded;
BOOL mWritten;
BOOL mNeedsAux;
BOOL mHaveAllData;
BOOL mUseHTTPGet;
BOOL mInLocalCache;
S32 mRetryAttempt;
std::string mURL;
@ -306,7 +313,6 @@ private:
S32 mLastPacket;
U16 mTotalPackets;
U8 mImageCodec;
LLFrameTimer mFetchTimer; // debug
};
//static
@ -357,12 +363,11 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mFileSize(0),
mCachedSize(0),
mLoaded(FALSE),
mRequested(FALSE),
mSentRequest(UNSENT),
mDecoded(FALSE),
mWritten(FALSE),
mNeedsAux(FALSE),
mHaveAllData(FALSE),
mUseHTTPGet(FALSE),
mInLocalCache(FALSE),
mRetryAttempt(0),
mActiveCount(0),
@ -373,10 +378,10 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mImageCodec(IMG_CODEC_INVALID)
{
calcWorkPriority();
if ((gSavedSettings.getBOOL("ImagePipelineUseHTTP")) &&
(host == LLHost::invalid))
mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
if (host == LLHost::invalid)
{
mUseHTTPGet = TRUE;
mHost = gAgent.getRegionHost();
}
if (!mFetcher->mDebugPause)
{
@ -423,8 +428,10 @@ U32 LLTextureFetchWorker::calcWorkPriority()
return mWorkPriority;
}
// mWorkMutex is locked
void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
{
bool prioritize = false;
if (mDesiredDiscard != discard)
{
if (!haveWork())
@ -438,8 +445,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
}
else if (mDesiredDiscard < discard)
{
U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
setPriority(work_priority);
prioritize = true;
}
mDesiredDiscard = discard;
mDesiredSize = size;
@ -447,6 +453,10 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
else if (size > mDesiredSize)
{
mDesiredSize = size;
prioritize = true;
}
if (prioritize && mState == INIT)
{
U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
setPriority(work_priority);
}
@ -490,9 +500,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
LLMutexLock lock(&mWorkMutex);
e_state old_state = mState;
mFetchTimer.reset();
if (mFetcher->mDebugPause)
{
return false; // debug: don't do any work
@ -502,6 +509,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
mFetcher->mDebugCount++; // for setting breakpoints
}
if (mState != DONE)
{
mFetchTimer.reset();
}
if (mState == INIT)
{
mRequestedDiscard = -1;
@ -511,7 +523,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
mFileSize = 0;
mCachedSize = 0;
mLoaded = FALSE;
mRequested = FALSE;
mSentRequest = UNSENT;
mDecoded = FALSE;
mWritten = FALSE;
delete[] mBuffer;
@ -587,21 +599,18 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == LOAD_FROM_NETWORK)
{
if (mFormattedImage.isNull())
{
mFormattedImage = new LLImageJ2C;
}
mState = mUseHTTPGet ? LOAD_FROM_HTTP_GET_URL : LOAD_FROM_SIMULATOR;
return false;
}
if (mState == LOAD_FROM_SIMULATOR)
{
if (!mRequested)
if (mSentRequest == UNSENT)
{
if (mFormattedImage.isNull())
{
mFormattedImage = new LLImageJ2C;
}
// Add this to the network queue and sit here.
// LLTextureFetch::update() will send off a request which will change our state
S32 data_size = mFormattedImage->getDataSize();
if (data_size > 0)
{
// Only used for simulator requests
mFirstPacket = (data_size - FIRST_PACKET_SIZE) / MAX_IMG_PACKET_SIZE + 1;
if (FIRST_PACKET_SIZE + (mFirstPacket-1) * MAX_IMG_PACKET_SIZE != data_size)
{
@ -616,13 +625,19 @@ bool LLTextureFetchWorker::doWork(S32 param)
mTotalPackets = (mFileSize - FIRST_PACKET_SIZE + MAX_IMG_PACKET_SIZE-1) / MAX_IMG_PACKET_SIZE + 1;
}
}
mRequested = TRUE;
mRequestedSize = mDesiredSize;
mRequestedDiscard = mDesiredDiscard;
mSentRequest = QUEUED;
mFetcher->lockQueue();
mFetcher->addToNetworkQueue(this);
mFetcher->unlockQueue();
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
}
return false;
}
if (mState == LOAD_FROM_SIMULATOR)
{
if (processSimulatorPackets())
{
mFetcher->lockQueue();
@ -644,11 +659,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
return false;
}
#if 0
if (mState == LOAD_FROM_HTTP_GET_URL)
{
if (!mRequested)
if (!mSentRequest)
{
mRequested = TRUE;
mSentRequest = TRUE;
mLoaded = FALSE;
std::string url;
LLViewerRegion* region = gAgent.getRegion();
@ -660,14 +676,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
LLSD sd;
sd = mID.asString();
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
LLHTTPClient::post(url, sd, new URLResponder(mFetcher, mID));
//*TODO:uncomment setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return false;
}
else
{
llwarns << mID << ": HTTP get url failed, requesting from simulator" << llendl;
mRequested = FALSE;
mSentRequest = FALSE;
mState = LOAD_FROM_SIMULATOR;
return false;
}
@ -679,13 +695,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (!mURL.empty())
{
mState = LOAD_FROM_HTTP_GET_DATA;
mRequested = FALSE; // reset
mSentRequest = FALSE; // reset
mLoaded = FALSE; // reset
}
else
{
llwarns << mID << ": HTTP get url is empty, requesting from simulator" << llendl;
mRequested = FALSE;
mSentRequest = FALSE;
mState = LOAD_FROM_SIMULATOR;
return false;
}
@ -696,9 +712,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == LOAD_FROM_HTTP_GET_DATA)
{
if (!mRequested)
if (!mSentRequest)
{
mRequested = TRUE;
mSentRequest = TRUE;
S32 cur_size = mFormattedImage->getDataSize(); // amount of data we already have
mRequestedSize = mDesiredSize;
mRequestedDiscard = mDesiredDiscard;
@ -724,9 +740,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
mLoaded = FALSE;
// llinfos << "HTTP GET: " << mID << " Offset: " << offset << " Bytes: " << mRequestedSize << llendl;
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
LLCurl::getByteRange(url, offset, mRequestedSize,
new HTTPGetResponder(mFetcher, mID)); // *TODO: use mWorkPriority
//*TODO:uncomment setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return false; // not done
}
@ -747,30 +763,23 @@ bool LLTextureFetchWorker::doWork(S32 param)
return false; // use what we have
}
}
llassert(mBufferSize == cur_size + mRequestedSize);
llassert_always(mBufferSize == cur_size + mRequestedSize);
if (mHaveAllData)
{
mFileSize = mBufferSize;
}
if (mRequestedSize > 0)
U8* buffer = new U8[mBufferSize];
if (cur_size > 0)
{
U8* buffer = new U8[mBufferSize];
if (cur_size > 0)
{
memcpy(buffer, mFormattedImage->getData(), cur_size);
}
memcpy(buffer + cur_size, mBuffer, mRequestedSize); // append
// NOTE: setData releases current data and owns new data (buffer)
mFormattedImage->setData(buffer, mBufferSize);
// delete temp data
delete[] mBuffer; // Note: not 'buffer' (assigned in setData())
mBuffer = NULL;
mBufferSize = 0;
}
else
{
llassert_always(cur_size);
memcpy(buffer, mFormattedImage->getData(), cur_size);
}
memcpy(buffer + cur_size, mBuffer, mRequestedSize); // append
// NOTE: setData releases current data and owns new data (buffer)
mFormattedImage->setData(buffer, mBufferSize);
// delete temp data
delete[] mBuffer; // Note: not 'buffer' (assigned in setData())
mBuffer = NULL;
mBufferSize = 0;
mLoadedDiscard = mRequestedDiscard;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
mState = DECODE_IMAGE;
@ -781,13 +790,21 @@ bool LLTextureFetchWorker::doWork(S32 param)
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return false;
}
#endif
if (mState == DECODE_IMAGE)
{
llassert_always(mFormattedImage->getDataSize() > 0);
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
startDecode();
mRawImage = NULL;
mAuxImage = NULL;
llassert_always(mImageWorker == NULL);
llassert_always(mFormattedImage.notNull());
S32 discard = mHaveAllData ? 0 : mLoadedDiscard;
U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;
mDecoded = FALSE;
mState = DECODE_IMAGE_UPDATE;
mImageWorker = new LLImageWorker(mFormattedImage, image_priority, discard, new DecodeResponder(mFetcher, mID, this));
// fall though (need to call requestDecodedData() to start work)
}
@ -828,7 +845,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WRITE_TO_CACHE)
{
if (mInLocalCache || !mFileSize || !mRequested)
if (mInLocalCache || !mFileSize || mSentRequest == UNSENT)
{
// If we're in a local cache or we didn't actually receive any new data, skip
mState = DONE;
@ -839,11 +856,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
U32 cache_priority = mWorkPriority;
mWritten = FALSE;
mState = WAIT_ON_WRITE;
CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID);
mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,
mFormattedImage->getData(), datasize,
mFileSize, responder);
mState = WAIT_ON_WRITE;
// fall through
}
@ -876,10 +893,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
return false;
}
if (old_state != DONE)
{
mIdleTimer.reset();
}
return true;
}
@ -942,12 +955,16 @@ bool LLTextureFetchWorker::deleteOK()
delete_ok = false;
}
}
// Don't delete while waiting for network requests *TODO: Need LLCurl::abort()
// Don't delete while waiting on writes
if ((mState >= LLTextureFetchWorker::LOAD_FROM_HTTP_GET_URL &&
mState <= LLTextureFetchWorker::LOAD_FROM_HTTP_GET_DATA) ||
(mState >= LLTextureFetchWorker::WRITE_TO_CACHE &&
mState <= LLTextureFetchWorker::WAIT_ON_WRITE))
const F32 MAX_IDLE_TIME = 5.f;
if ((mFetchTimer.getElapsedTimeF32() < MAX_IDLE_TIME))
{
delete_ok = false;
}
else if ((haveWork() &&
// not ok to delete from these states
((mState >= LOAD_FROM_HTTP_GET_URL && mState <= LOAD_FROM_HTTP_GET_DATA) ||
(mState >= WRITE_TO_CACHE && mState <= WAIT_ON_WRITE))))
{
delete_ok = false;
}
@ -1014,21 +1031,35 @@ bool LLTextureFetchWorker::processSimulatorPackets()
void LLTextureFetchWorker::callbackURLReceived(const LLSD& data, bool success)
{
#if 0
LLMutexLock lock(&mWorkMutex);
if (!mSentRequest || mState != LOAD_FROM_HTTP_GET_URL)
{
llwarns << "callbackURLReceived for unrequested fetch worker, req="
<< mSentRequest << " state= " << mState << llendl;
return;
}
if (success)
{
mURL = data.asString();
}
mLoaded = TRUE;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
#endif
}
//////////////////////////////////////////////////////////////////////////////
void LLTextureFetchWorker::callbackHttpGet(U8* data, S32 data_size, bool last_block)
{
#if 0
LLMutexLock lock(&mWorkMutex);
llassert_always(mRequested);
if (!mSentRequest || mState != LOAD_FROM_HTTP_GET_DATA)
{
llwarns << "callbackHttpGet for unrequested fetch worker, req="
<< mSentRequest << " state= " << mState << llendl;
return;
}
// llinfos << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << llendl;
if (mLoaded)
{
@ -1070,6 +1101,7 @@ void LLTextureFetchWorker::callbackHttpGet(U8* data, S32 data_size, bool last_bl
}
mLoaded = TRUE;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
#endif
}
//////////////////////////////////////////////////////////////////////////////
@ -1078,6 +1110,11 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima
S32 imagesize, BOOL islocal)
{
LLMutexLock lock(&mWorkMutex);
if (mState != LOAD_FROM_TEXTURE_CACHE)
{
llwarns << "Read callback for " << mID << " with state = " << mState << llendl;
return;
}
if (success)
{
llassert_always(imagesize > 0);
@ -1097,6 +1134,11 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima
void LLTextureFetchWorker::callbackCacheWrite(bool success)
{
LLMutexLock lock(&mWorkMutex);
if (mState != WAIT_ON_WRITE)
{
llwarns << "Write callback for " << mID << " with state = " << mState << llendl;
return;
}
mWritten = TRUE;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
}
@ -1105,26 +1147,17 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success)
void LLTextureFetchWorker::callbackDecoded(bool success)
{
if (mState != DECODE_IMAGE_UPDATE)
{
llwarns << "Decode callback for " << mID << " with state = " << mState << llendl;
return;
}
// llinfos << mID << " : DECODE COMPLETE " << llendl;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
}
//////////////////////////////////////////////////////////////////////////////
void LLTextureFetchWorker::startDecode()
{
mRawImage = NULL;
mAuxImage = NULL;
llassert_always(mImageWorker == NULL);
llassert_always(mFormattedImage.notNull());
S32 discard = mHaveAllData ? 0 : mLoadedDiscard;
U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;
// llinfos << mID << " : DECODE STARTED : " << discard
// << " Pri: " << priority
// << " Components:" << (S32)mFormattedImage->getComponents() << llendl;
mImageWorker = new LLImageWorker(mFormattedImage, image_priority, discard, new DecodeResponder(mFetcher, mID, this));
}
bool LLTextureFetchWorker::decodeImage()
{
llassert_always(mImageWorker);
@ -1165,12 +1198,6 @@ bool LLTextureFetchWorker::decodeImage()
mImageWorker->scheduleDelete();
mImageWorker = NULL;
}
else
{
U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;
mImageWorker->setPriority(image_priority);
//llinfos << worker->mID << " : DECODE PRIORITY : " << priority << llendl;
}
return res;
}
@ -1225,10 +1252,13 @@ bool LLTextureFetch::createRequest(const LLUUID& id, const LLHost& host, F32 pri
if (iter != mRequestMap.end())
{
worker = iter->second;
if (worker->mHost != host)
LLHost host2 = host;
if (host2 == LLHost::invalid) host2 = gAgent.getRegionHost();
if (worker->mHost != host2)
{
llwarns << "LLTextureFetch::createRequest " << id << " called with multiple hosts" << llendl;
removeRequest(worker, false);
// llwarns << "LLTextureFetch::createRequest " << id << " called with multiple hosts: "
// << host << " != " << host2 << llendl;
removeRequest(worker, true);
worker = NULL;
}
}
@ -1287,6 +1317,7 @@ void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
// i.e. a delete has not been requested
mNetworkQueue.insert(worker->mID);
}
mCancelQueue[worker->mHost].erase(worker->mID);
}
// call lockQueue() first!
@ -1401,42 +1432,6 @@ S32 LLTextureFetch::update(U32 max_time_ms)
mNetworkTimer.reset();
sendRequestListToSimulators();
}
#if 0 // Currently this logic is handled in LLViewer
{
LLMutexLock lock(&mQueueMutex);
const F32 MIN_IDLE_TIME = 1.f * 60.f; // 1 minute
const F32 MAX_IDLE_TIME = 5.f * 60.f; // 5 minutes
const S32 MIN_IDLE_COUNT = 16; // always keep last 16 idle requests
const F32 MAX_IDLE_COUNT = 1024; // max number of idle requests
// Remove any old requests (releasing their raw data)
typedef std::pair<F32, LLTextureFetchWorker*> idle_pair;
typedef std::set<idle_pair, compare_pair_greater<F32,LLTextureFetchWorker*> > idle_set;
idle_set remove_set;
for (map_t::iterator iter = mRequestMap.begin(); iter != mRequestMap.end(); ++iter)
{
LLTextureFetchWorker* worker = iter->second;
if (worker->mActiveCount > 0)
continue;
if (worker->haveWork())
continue;
F32 idletime = worker->mIdleTimer.getElapsedTimeF32();
if (idletime < MIN_IDLE_TIME)
continue;
remove_set.insert(std::make_pair(idletime, worker));
}
S32 num_left = remove_set.size();
for (idle_set::iterator iter = remove_set.begin(); iter != remove_set.end(); ++iter)
{
if (num_left <= MIN_IDLE_COUNT)
break;
if (iter->first < MAX_IDLE_TIME &&
num_left < MAX_IDLE_COUNT)
break;
num_left--;
}
}
#endif
return res;
}
@ -1466,7 +1461,7 @@ void LLTextureFetch::sendRequestListToSimulators()
if (req->mTotalPackets > 0 && req->mLastPacket >= req->mTotalPackets-1)
{
// We have all the packets... make sure this is high priority
req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);
// req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);
continue;
}
F32 elapsed = req->mRequestedTimer.getElapsedTimeF32();
@ -1478,58 +1473,79 @@ void LLTextureFetch::sendRequestListToSimulators()
requests[req->mHost].insert(req);
}
}
std::string http_url;
#if 0
if (gSavedSettings.getBOOL("ImagePipelineUseHTTP"))
{
LLViewerRegion* region = gAgent.getRegion();
if (region)
{
http_url = region->getCapability("RequestTextureDownload");
}
}
#endif
for (work_request_map_t::iterator iter1 = requests.begin();
iter1 != requests.end(); ++iter1)
{
bool use_http = http_url.empty() ? false : true;
LLHost host = iter1->first;
// invalid host = use agent host
if (host == LLHost::invalid)
if (host != gAgent.getRegionHost())
{
host = gAgent.getRegionHost();
use_http = false;
}
S32 request_count = 0;
for (request_list_t::iterator iter2 = iter1->second.begin();
iter2 != iter1->second.end(); ++iter2)
if (use_http)
{
LLTextureFetchWorker* req = *iter2;
if (0 == request_count)
}
else
{
S32 request_count = 0;
for (request_list_t::iterator iter2 = iter1->second.begin();
iter2 != iter1->second.end(); ++iter2)
{
gMessageSystem->newMessageFast(_PREHASH_RequestImage);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
}
S32 packet = req->mLastPacket + 1;
gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID);
gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mSimRequestedDiscard);
gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority);
gMessageSystem->addU32Fast(_PREHASH_Packet, packet);
U8 type = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
gMessageSystem->addU8Fast(_PREHASH_Type, type);
// llinfos << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard
// << " Packet: " << packet << " Priority: " << req->mImagePriority << llendl;
LLTextureFetchWorker* req = *iter2;
req->mSentRequest = LLTextureFetchWorker::SENT_SIM;
if (0 == request_count)
{
gMessageSystem->newMessageFast(_PREHASH_RequestImage);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
}
S32 packet = req->mLastPacket + 1;
gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID);
gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mSimRequestedDiscard);
gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority);
gMessageSystem->addU32Fast(_PREHASH_Packet, packet);
U8 type = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
gMessageSystem->addU8Fast(_PREHASH_Type, type);
// llinfos << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard
// << " Packet: " << packet << " Priority: " << req->mImagePriority << llendl;
req->lockWorkData();
req->mSimRequestedDiscard = req->mDesiredDiscard;
req->mRequestedPriority = req->mImagePriority;
req->mRequestedTimer.reset();
req->unlockWorkData();
request_count++;
if (request_count >= IMAGES_PER_REQUEST)
req->lockWorkData();
req->mSimRequestedDiscard = req->mDesiredDiscard;
req->mRequestedPriority = req->mImagePriority;
req->mRequestedTimer.reset();
req->unlockWorkData();
request_count++;
if (request_count >= IMAGES_PER_REQUEST)
{
// llinfos << "REQUESTING " << request_count << " IMAGES FROM HOST: " << host.getIPString() << llendl;
gMessageSystem->sendSemiReliable(host, NULL, NULL);
request_count = 0;
}
}
if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
{
// llinfos << "REQUESTING " << request_count << " IMAGES FROM HOST: " << host.getIPString() << llendl;
gMessageSystem->sendSemiReliable(host, NULL, NULL);
request_count = 0;
break; // only send the top requests
}
}
if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
{
// llinfos << "REQUESTING " << request_count << " IMAGES FROM HOST: " << host.getIPString() << llendl;
gMessageSystem->sendSemiReliable(host, NULL, NULL);
}
}
// Send cancelations
@ -1539,11 +1555,6 @@ void LLTextureFetch::sendRequestListToSimulators()
iter1 != mCancelQueue.end(); ++iter1)
{
LLHost host = iter1->first;
// invalid host = use agent host
if (host == LLHost::invalid)
{
host = gAgent.getRegionHost();
}
S32 request_count = 0;
for (queue_t::iterator iter2 = iter1->second.begin();
iter2 != iter1->second.end(); ++iter2)
@ -1586,12 +1597,12 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
mRequestedTimer.reset();
if (index >= mTotalPackets)
{
llwarns << "Received Image Packet " << index << " > max: " << mTotalPackets << " Skipping. " << llendl;
// llwarns << "Received Image Packet " << index << " > max: " << mTotalPackets << " for image: " << mID << llendl;
return false;
}
if (index > 0 && index < mTotalPackets-1 && size != MAX_IMG_PACKET_SIZE)
{
llwarns << "Received bad sized packet: " << index << ", " << size << " != " << MAX_IMG_PACKET_SIZE << " Skipping. " << llendl;
// llwarns << "Received bad sized packet: " << index << ", " << size << " != " << MAX_IMG_PACKET_SIZE << " for image: " << mID << llendl;
return false;
}
@ -1601,7 +1612,7 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
}
else if (mPackets[index] != NULL)
{
// llwarns << "LLTextureFetchWorker::insertPacket called for duplicate packet: " << index << llendl;
// llwarns << "Received duplicate packet: " << index << " for image: " << mID << llendl;
return false;
}
@ -1613,20 +1624,49 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
return true;
}
bool LLTextureFetch::receiveImageHeader(const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
bool LLTextureFetch::receiveImageHeader(const LLHost& host_in, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
U16 data_size, U8* data)
{
LLMutexLock lock(&mQueueMutex);
LLTextureFetchWorker* worker = getWorker(id);
LLHost host = (host_in == LLHost::invalid) ? gAgent.getRegionHost() : host_in;
bool res = true;
++mPacketCount;
if (!worker)
{
// llwarns << "receiveImageHeader for non active worker: " << id << llendl;
return false;
// llwarns << "Received header for non active worker: " << id << llendl;
res = false;
}
// check to see if we've gotten this packet before
if (worker->mLastPacket != -1)
else if (host != worker->mHost)
{
// llwarns << "Img: " << id << ":" << " Duplicate Image Header" << llendl;
// llwarns << "Received header from wrong host for: " << id << llendl;
res = false;
}
else if (worker->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK ||
worker->mSentRequest != LLTextureFetchWorker::SENT_SIM)
{
llwarns << "receiveImageHeader for worker: " << id
<< " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState]
<< " sent: " << worker->mSentRequest << llendl;
res = false;
}
else if (worker->mLastPacket != -1)
{
// check to see if we've gotten this packet before
// llwarns << "Received duplicate header for: " << id << llendl;
res = false;
}
else if (!data_size)
{
llwarns << "Img: " << id << ":" << " Empty Image Header" << llendl;
res = false;
}
if (!res)
{
++mBadPacketCount;
mCancelQueue[host].insert(id);
return false;
}
@ -1637,40 +1677,68 @@ bool LLTextureFetch::receiveImageHeader(const LLUUID& id, U8 codec, U16 packets,
worker->mTotalPackets = packets;
worker->mFileSize = (S32)totalbytes;
llassert_always(totalbytes > 0);
bool res = false;
if (data_size)
{
llassert(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
res = worker->insertPacket(0, data, data_size);
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
}
llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
res = worker->insertPacket(0, data, data_size);
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR;
worker->unlockWorkData();
return res;
}
bool LLTextureFetch::receiveImagePacket(const LLUUID& id, U16 packet_num, U16 data_size, U8* data)
bool LLTextureFetch::receiveImagePacket(const LLHost& host_in, const LLUUID& id, U16 packet_num, U16 data_size, U8* data)
{
LLMutexLock lock(&mQueueMutex);
LLTextureFetchWorker* worker = getWorker(id);
LLHost host = (host_in == LLHost::invalid) ? gAgent.getRegionHost() : host_in;
bool res = true;
++mPacketCount;
if (!worker)
{
// llwarns << "receiveImagePacket " << packet_num << " for non active worker: " << id << llendl;
return false;
// llwarns << "Received packet " << packet_num << " for non active worker: " << id << llendl;
res = false;
}
if (worker->mLastPacket == -1)
else if (host != worker->mHost)
{
// llwarns << "Img: " << id << ":" << " Image Packet " << packet_num << " received before header" << llendl;
// llwarns << "Received packet from wrong host for: " << id << llendl;
res = false;
}
else if (worker->mLastPacket == -1)
{
// llwarns << "Received packet " << packet_num << " before header for: " << id << llendl;
res = false;
}
else if (!data_size)
{
llwarns << "Img: " << id << ":" << " Empty Image Header" << llendl;
res = false;
}
if (!res)
{
++mBadPacketCount;
mCancelQueue[host].insert(id);
return false;
}
bool res = false;
if (data_size)
worker->lockWorkData();
res = worker->insertPacket(packet_num, data, data_size);
if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) ||
(worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))
{
worker->lockWorkData();
res = worker->insertPacket(packet_num, data, data_size);
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
worker->unlockWorkData();
worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR;
}
else
{
// llwarns << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id
// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] << llendl;
}
worker->unlockWorkData();
return res;
}

View File

@ -37,8 +37,8 @@ public:
LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux);
bool updateRequestPriority(const LLUUID& id, F32 priority);
bool receiveImageHeader(const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data);
bool receiveImagePacket(const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data);
bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
// Debug
S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p,
@ -63,6 +63,8 @@ public:
LLUUID mDebugID;
S32 mDebugCount;
BOOL mDebugPause;
S32 mPacketCount;
S32 mBadPacketCount;
private:
LLMutex mQueueMutex;

View File

@ -131,9 +131,7 @@ void LLTextureBar::draw()
{
S32 idx = llclamp(mHilite,1,4);
if (idx==1) color = LLColor4::yellow;
if (idx==2) color = LLColor4::cyan;
if (idx==3) color = LLColor4::magenta;
if (idx==4) color = LLColor4::blue;
else color = LLColor4::orange;
}
else if (mImagep->getBoostLevel())
{
@ -331,7 +329,7 @@ void LLTextureBar::draw()
BOOL LLTextureBar::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (mask & MASK_ALT)
if ((mask & (MASK_CONTROL|MASK_SHIFT|MASK_ALT)) == MASK_ALT)
{
gTextureFetch->mDebugID = mImagep->getID();
return TRUE;
@ -453,9 +451,10 @@ void LLGLTexMemBar::draw()
LLGLEnable tex(GL_TEXTURE_2D);
text = llformat("Textures: Count: %d Fetch: %d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d",
text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d",
gImageList.getNumImages(),
gTextureFetch->getNumRequests(), gTextureFetch->getNumDeletes(),
gTextureFetch->mPacketCount, gTextureFetch->mBadPacketCount,
gTextureCache->getNumReads(), gTextureCache->getNumWrites(),
LLLFSThread::sLocal->getPending(),
LLImageWorker::sCount, LLImageWorker::getWorkerThread()->getNumDeletes(),
@ -513,13 +512,14 @@ LLRect LLGLTexMemBar::getRequiredRect()
////////////////////////////////////////////////////////////////////////////
LLTextureView::LLTextureView(const std::string& name, const LLRect& rect)
: LLContainerView(name, rect)
: LLContainerView(name, rect),
mFreezeView(FALSE),
mOrderFetch(FALSE),
mPrintList(FALSE),
mNumTextureBars(0)
{
setVisible(FALSE);
mFreezeView = FALSE;
mOrderFetch = FALSE;
mNumTextureBars = 0;
setDisplayChildren(TRUE);
mGLTexMemBar = 0;
}
@ -567,10 +567,28 @@ void LLTextureView::draw()
typedef std::multiset<decode_pair_t, compare_decode_pair > display_list_t;
display_list_t display_image_list;
if (mPrintList)
{
llinfos << "ID\tMEM\tBOOST\tPRI\tWIDTH\tHEIGHT\tDISCARD" << llendl;
}
for (LLViewerImageList::image_priority_list_t::iterator iter = gImageList.mImageList.begin();
iter != gImageList.mImageList.end(); )
{
LLPointer<LLViewerImage> imagep = *iter++;
if (mPrintList)
{
llinfos << imagep->getID()
<< "\t" << imagep->mTextureMemory
<< "\t" << imagep->getBoostLevel()
<< "\t" << imagep->getDecodePriority()
<< "\t" << imagep->getWidth()
<< "\t" << imagep->getHeight()
<< "\t" << imagep->getDiscardLevel()
<< llendl;
}
#if 0
if (imagep->getDontDiscard())
{
@ -661,7 +679,12 @@ void LLTextureView::draw()
display_image_list.insert(std::make_pair(pri, imagep));
}
}
if (mPrintList)
{
mPrintList = FALSE;
}
static S32 max_count = 50;
S32 count = 0;
for (display_list_t::iterator iter = display_image_list.begin();
@ -687,7 +710,7 @@ void LLTextureView::draw()
sortChildren(LLTextureBar::sort_fetch());
else
sortChildren(LLTextureBar::sort());
mGLTexMemBar = new LLGLTexMemBar("gl texmem bar", this);
addChild(mGLTexMemBar);
@ -737,7 +760,12 @@ BOOL LLTextureView::addBar(LLViewerImage *imagep, S32 hilite)
BOOL LLTextureView::handleMouseDown(S32 x, S32 y, MASK mask)
{
if ((mask & MASK_CONTROL) && (mask & MASK_SHIFT))
if ((mask & (MASK_CONTROL|MASK_SHIFT|MASK_ALT)) == (MASK_ALT|MASK_SHIFT))
{
mPrintList = TRUE;
return TRUE;
}
if ((mask & (MASK_CONTROL|MASK_SHIFT|MASK_ALT)) == (MASK_CONTROL|MASK_SHIFT))
{
gTextureFetch->mDebugPause = !gTextureFetch->mDebugPause;
return TRUE;

View File

@ -18,6 +18,8 @@ class LLGLTexMemBar;
class LLTextureView : public LLContainerView
{
friend class LLTextureBar;
friend class LLGLTexMemBar;
public:
LLTextureView(const std::string& name, const LLRect& rect);
~LLTextureView();
@ -38,11 +40,11 @@ private:
BOOL addBar(LLViewerImage *image, BOOL hilight = FALSE);
void removeAllBars();
public:
private:
BOOL mFreezeView;
BOOL mOrderFetch;
BOOL mPrintList;
private:
LLTextBox *mInfoTextp;
std::vector<LLTextureBar*> mTextureBars;

View File

@ -253,7 +253,7 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass )
triangle_count += drawShape( pixelArea, FALSE );
}
// third past respects z buffer and writes color
glColorMask(TRUE, TRUE, TRUE, TRUE);
glColorMask(TRUE, TRUE, TRUE, FALSE);
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
triangle_count += drawShape( pixelArea, FALSE );

View File

@ -422,6 +422,8 @@ void handle_dump_image_list(void*);
void handle_fullscreen_debug(void*);
void handle_crash(void*);
void handle_dump_followcam(void*);
void handle_toggle_flycam(void*);
BOOL check_flycam(void*);
void handle_viewer_enable_message_log(void*);
void handle_viewer_disable_message_log(void*);
void handle_send_postcard(void*);
@ -884,6 +886,9 @@ void init_client_menu(LLMenuGL* menu)
menu->append(new LLMenuItemToggleGL("Disable Camera Constraints",
&LLViewerCamera::sDisableCameraConstraints));
menu->append(new LLMenuItemCheckGL("Joystick Flycam",
&handle_toggle_flycam,NULL,&check_flycam,NULL));
menu->append(new LLMenuItemCheckGL("Mouse Smoothing",
&menu_toggle_control,
NULL,
@ -1158,6 +1163,9 @@ void init_debug_rendering_menu(LLMenuGL* menu)
sub_menu->append(new LLMenuItemCheckGL("LightTrace",&LLPipeline::toggleRenderDebug, NULL,
&LLPipeline::toggleRenderDebugControl,
(void*)LLPipeline::RENDER_DEBUG_LIGHT_TRACE));
sub_menu->append(new LLMenuItemCheckGL("Glow",&LLPipeline::toggleRenderDebug, NULL,
&LLPipeline::toggleRenderDebugControl,
(void*)LLPipeline::RENDER_DEBUG_GLOW));
sub_menu->append(new LLMenuItemCheckGL("Show Depth Buffer",
&menu_toggle_control,
@ -6321,6 +6329,20 @@ void handle_dump_followcam(void*)
LLFollowCamMgr::dump();
}
BOOL check_flycam(void*)
{
return LLPipeline::sOverrideAgentCamera;
}
void handle_toggle_flycam(void*)
{
LLPipeline::sOverrideAgentCamera = !LLPipeline::sOverrideAgentCamera;
if (LLPipeline::sOverrideAgentCamera)
{
LLFloaterJoystick::show(NULL);
}
}
void handle_viewer_enable_message_log(void*)
{
gMessageSystem->startLogging();

View File

@ -323,7 +323,16 @@ void LLEmbeddedItems::bindEmbeddedChars( const LLFontGL* font )
}
break;
case LLAssetType::AT_CLOTHING: img_name = "inv_item_clothing.tga"; break;
case LLAssetType::AT_OBJECT: img_name = "inv_item_object.tga"; break;
case LLAssetType::AT_OBJECT:
if (item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
{
img_name = "inv_item_object_multi.tga";
}
else
{
img_name = "inv_item_object.tga";
}
break;
case LLAssetType::AT_NOTECARD: img_name = "inv_item_notecard.tga"; break;
case LLAssetType::AT_LSL_TEXT: img_name = "inv_item_script.tga"; break;
case LLAssetType::AT_BODYPART: img_name = "inv_item_bodypart.tga"; break;

View File

@ -3007,7 +3007,7 @@ void LLViewerWindow::hitObjectOrLandGlobalAsync(S32 x, S32 y_from_bot, MASK mask
glViewport(scaled_x - (PICK_HALF_WIDTH + 2), scaled_y - (PICK_HALF_WIDTH + 2), PICK_DIAMETER + 4, PICK_DIAMETER + 4);
stop_glerror();
glClearColor(0.f, 0.f, 0.f, 1.f);
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Draw the objects so the user can select them.
@ -3098,7 +3098,7 @@ void LLViewerWindow::hitUIElementAsync(S32 x, S32 y_from_bot, MASK mask, void (*
glViewport(x - (PICK_HALF_WIDTH + 2), y_from_bot - (PICK_HALF_WIDTH + 2), PICK_DIAMETER + 4, PICK_DIAMETER + 4);
stop_glerror();
glClearColor(0.f, 0.f, 0.f, 1.f);
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
// Draw the objects so the user can select them.
@ -3974,7 +3974,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
gDisplaySwapBuffers = FALSE;
if (type == SNAPSHOT_TYPE_OBJECT_ID)
{
glClearColor(0.f, 0.f, 0.f, 1.f);
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
gCamera->setZoomParameters(scale_factor, subimage_x+(subimage_y*llceil(scale_factor)));

View File

@ -1725,6 +1725,9 @@ BOOL LLVOAvatar::buildSkeleton(LLVOAvatarSkeletonInfo *info)
mScreenp = new LLViewerJoint("mScreen", NULL);
// for now, put screen at origin, as it is only used during special
// HUD rendering mode
F32 aspect = gCamera->getAspect();
LLVector3 scale(1.f, aspect, 1.f);
mScreenp->setScale(scale);
mScreenp->setWorldPosition(LLVector3::zero);
}
@ -3005,12 +3008,9 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)
{
F32 aspect = gCamera->getAspect();
LLVector3 scale(1.f, aspect, 1.f);
if (mScreenp->getScale() != scale)
{
mScreenp->setScale(scale);
mScreenp->updateWorldMatrixChildren();
resetHUDAttachments();
}
mScreenp->setScale(scale);
mScreenp->updateWorldMatrixChildren();
resetHUDAttachments();
}
// clear debug text

View File

@ -443,7 +443,7 @@ void LLSkyTex::create(const F32 brightness_scale, const LLColor3& multiscatt)
}
U32* pix = (U32*)(data + offset);
LLColor4 temp = LLColor4(col);
LLColor4 temp = LLColor4(col, 0);
LLColor4U temp1 = LLColor4U(temp);
*pix = temp1.mAll;
}

View File

@ -671,6 +671,7 @@ public:
public:
static F32 sNighttimeBrightness; // [0,2] default = 1.0
LLFace *mFace[FACE_COUNT];
protected:
LLPointer<LLViewerImage> mSunTexturep;
@ -700,8 +701,7 @@ protected:
BOOL mWeatherChange;
F32 mCloudDensity;
F32 mWind;
LLFace *mFace[FACE_COUNT];
BOOL mInitialized;
BOOL mForceUpdate; //flag to force instantaneous update of cubemap
LLVector3 mLastLightingDirection;

View File

@ -1768,7 +1768,8 @@ F32 LLVOVolume::getBinRadius()
BOOL shrink_wrap = mDrawable->isAnimating();
BOOL alpha_wrap = FALSE;
//if (!shrink_wrap)
if (!isHUDAttachment())
{
for (S32 i = 0; i < mDrawable->getNumFaces(); i++)
{
@ -1779,6 +1780,10 @@ F32 LLVOVolume::getBinRadius()
}
}
}
else
{
shrink_wrap = FALSE;
}
if (alpha_wrap)
{
@ -1959,12 +1964,15 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mVSize = facep->getVirtualSize();
draw_vec.push_back(draw_info);
LLVOVolume* volume = (LLVOVolume*) facep->getViewerObject();
LLColor3 col = volume->getLightColor();
BOOL is_light = volume->mDrawable->isLight();
U8 alpha = is_light ? 196 : 160;
LLColor3 col = is_light ? volume->getLightColor() : LLColor3(0,0,0);
LLColor4 col2 = facep->getRenderColor();
draw_info->mGlowColor.setVec((U8) (col.mV[0]*col2.mV[0]*255),
(U8) (col.mV[1]*col2.mV[1]*255),
(U8) (col.mV[2]*col2.mV[2]*255),
196);
alpha);
draw_info->mTextureMatrix = tex_mat;
validate_draw_info(*draw_info);
}
@ -2269,7 +2277,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
if (vobj->getIsLight())
if (vobj->getIsLight() ||
(LLPipeline::sRenderGlow && facep->isState(LLFace::FULLBRIGHT)))
{
registerFace(group, facep, LLRenderPass::PASS_GLOW);
}

View File

@ -25,7 +25,7 @@
#include "material_codes.h"
#include "timing.h"
#include "v3color.h"
#include "llui.h"
#include "llui.h"
#include "llglheaders.h"
// newview includes
@ -70,6 +70,7 @@
#include "llworld.h"
#include "viewer.h"
#include "llcubemap.h"
#include "lldebugmessagebox.h"
#ifdef _DEBUG
// Debug indices is disabled for now for debug performance - djs 4/24/02
@ -157,6 +158,13 @@ const char* LLPipeline::sTerrainUniforms[] =
U32 LLPipeline::sTerrainUniformCount = sizeof(LLPipeline::sTerrainUniforms)/sizeof(char*);
const char* LLPipeline::sGlowUniforms[] =
{
"delta"
};
U32 LLPipeline::sGlowUniformCount = sizeof(LLPipeline::sGlowUniforms)/sizeof(char*);
const char* LLPipeline::sShinyUniforms[] =
{
"origin"
@ -196,6 +204,14 @@ void stamp(F32 x, F32 y, F32 xs, F32 ys)
glEnd();
}
U32 nhpo2(U32 v)
{
U32 r = 1;
while (r < v) {
r *= 2;
}
return r;
}
//----------------------------------------
@ -210,10 +226,14 @@ BOOL LLPipeline::sRenderSoundBeacons = FALSE;
BOOL LLPipeline::sUseOcclusion = FALSE;
BOOL LLPipeline::sSkipUpdate = FALSE;
BOOL LLPipeline::sDynamicReflections = FALSE;
BOOL LLPipeline::sRenderGlow = FALSE;
BOOL LLPipeline::sOverrideAgentCamera = FALSE;
LLPipeline::LLPipeline() :
mScreenTex(0),
mCubeBuffer(NULL),
mCubeList(0),
mGlowMap(0),
mGlowBuffer(0),
mVertexShadersEnabled(FALSE),
mVertexShadersLoaded(0),
mLastRebuildPool(NULL),
@ -225,11 +245,14 @@ LLPipeline::LLPipeline() :
mWaterPool(NULL),
mGroundPool(NULL),
mSimplePool(NULL),
mGlowPool(NULL),
mBumpPool(NULL),
mLightMask(0),
mLightMovingMask(0)
{
mFramebuffer[0] = mFramebuffer[1] = 0;
mCubeFrameBuffer = 0;
mCubeDepth = 0;
}
void LLPipeline::init()
@ -256,6 +279,7 @@ void LLPipeline::init()
getPool(LLDrawPool::POOL_ALPHA_POST_WATER);
getPool(LLDrawPool::POOL_SIMPLE);
getPool(LLDrawPool::POOL_BUMP);
getPool(LLDrawPool::POOL_GLOW);
mTrianglesDrawnStat.reset();
resetFrameStats();
@ -339,20 +363,12 @@ void LLPipeline::cleanup()
mGroundPool = NULL;
delete mSimplePool;
mSimplePool = NULL;
delete mGlowPool;
mGlowPool = NULL;
delete mBumpPool;
mBumpPool = NULL;
if (mCubeBuffer)
{
delete mCubeBuffer;
mCubeBuffer = NULL;
}
if (mCubeList)
{
glDeleteLists(mCubeList, 1);
mCubeList = 0;
}
releaseGLBuffers();
mBloomImagep = NULL;
mBloomImage2p = NULL;
@ -395,16 +411,46 @@ void LLPipeline::destroyGL()
clearRenderMap();
resetVertexBuffers();
releaseGLBuffers();
}
void LLPipeline::releaseGLBuffers()
{
if (mGlowMap)
{
glDeleteTextures(1, &mGlowMap);
mGlowMap = 0;
}
if (mGlowBuffer)
{
glDeleteTextures(1, &mGlowBuffer);
mGlowBuffer = 0;
}
if (mScreenTex)
{
glDeleteTextures(1, &mScreenTex);
mScreenTex = 0;
}
if (mCubeBuffer)
{
delete mCubeBuffer;
mCubeBuffer = NULL;
}
if (mCubeList)
if (mCubeFrameBuffer)
{
glDeleteLists(mCubeList, 1);
mCubeList = 0;
glDeleteFramebuffersEXT(1, &mCubeFrameBuffer);
glDeleteRenderbuffersEXT(1, &mCubeDepth);
mCubeDepth = mCubeFrameBuffer = 0;
}
if (mFramebuffer[0])
{
glDeleteFramebuffersEXT(2, mFramebuffer);
mFramebuffer[0] = mFramebuffer[1] = 0;
}
}
@ -665,8 +711,16 @@ BOOL LLPipeline::validateProgramObject(GLhandleARB obj)
void LLPipeline::setShaders()
{
sDynamicReflections = gSavedSettings.getBOOL("RenderDynamicReflections");
if (gGLManager.mHasFramebufferObject)
{
sDynamicReflections = gSavedSettings.getBOOL("RenderDynamicReflections");
sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
}
else
{
sDynamicReflections = sRenderGlow = FALSE;
}
//hack to reset buffers that change behavior with shaders
resetVertexBuffers();
@ -788,6 +842,7 @@ void LLPipeline::unloadShaders()
mObjectAlphaProgram.unload();
mWaterProgram.unload();
mTerrainProgram.unload();
mGlowProgram.unload();
mGroundProgram.unload();
mAvatarProgram.unload();
mAvatarEyeballProgram.unload();
@ -913,6 +968,7 @@ BOOL LLPipeline::loadShadersEnvironment()
mWaterProgram.unload();
mGroundProgram.unload();
mTerrainProgram.unload();
mGlowProgram.unload();
return FALSE;
}
@ -977,6 +1033,26 @@ BOOL LLPipeline::loadShadersEnvironment()
}
}
if (success)
{
//load glow shader
std::string glowvertex = "environment/glowV.glsl";
std::string glowfragment = "environment/glowF.glsl";
mGlowProgram.mProgramObject = glCreateProgramObjectARB();
mGlowProgram.attachObjects(baseObjects, baseCount);
mGlowProgram.attachObject(loadShader(glowvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB));
mGlowProgram.attachObject(loadShader(glowfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB));
success = mGlowProgram.mapAttributes();
if (success)
{
success = mGlowProgram.mapUniforms(sGlowUniforms, sGlowUniformCount);
}
if (!success)
{
llwarns << "Failed to load " << glowvertex << llendl;
}
}
if( !success )
{
mVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
@ -1356,6 +1432,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0)
poolp = mSimplePool;
break;
case LLDrawPool::POOL_GLOW:
poolp = mGlowPool;
break;
case LLDrawPool::POOL_TREE:
poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 );
break;
@ -2777,8 +2857,8 @@ void LLPipeline::renderGeom(LLCamera& camera)
else
{
LLFastTimer t(LLFastTimer::FTM_POOLS);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
calcNearbyLights();
pool_set_t::iterator iter1 = mPools.begin();
while ( iter1 != mPools.end() )
{
@ -2851,12 +2931,13 @@ void LLPipeline::renderGeom(LLCamera& camera)
iter1 = iter2;
stop_glerror();
}
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
#ifndef LL_RELEASE_FOR_DOWNLOAD
LLGLState::checkStates();
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
LLGLState::checkStates();
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
#endif
if (occlude)
@ -2886,6 +2967,38 @@ void LLPipeline::renderGeom(LLCamera& camera)
// Contains a list of the faces of objects that are physical or
// have touch-handlers.
mHighlightFaces.clear();
if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) &&
!LLDrawPoolWater::sSkipScreenCopy &&
sRenderGlow &&
gGLManager.mHasFramebufferObject)
{
const U32 glow_res = nhpo2(gSavedSettings.getS32("RenderGlowResolution"));
if (mGlowMap == 0)
{
glGenTextures(1, &mGlowMap);
glBindTexture(GL_TEXTURE_2D, mGlowMap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glow_res, glow_res, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}
if (mGlowBuffer == 0)
{
glGenTextures(1, &mGlowBuffer);
glBindTexture(GL_TEXTURE_2D, mGlowBuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glow_res, glow_res, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}
bindScreenToTexture();
renderBloom(mScreenTex, mGlowMap, mGlowBuffer, glow_res, LLVector2(0,0), mScreenScale);
}
}
void LLPipeline::processGeometry(LLCamera& camera)
@ -3257,6 +3370,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
case LLDrawPool::POOL_GLOW:
if (mGlowPool)
{
llassert(0);
llwarns << "Ignoring duplicate glow pool." << llendl;
}
else
{
mGlowPool = (LLRenderPass*) new_poolp;
}
break;
case LLDrawPool::POOL_TREE:
mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ;
break;
@ -3376,6 +3501,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mSimplePool = NULL;
break;
case LLDrawPool::POOL_GLOW:
llassert(mGlowPool == poolp);
mGlowPool = NULL;
break;
case LLDrawPool::POOL_TREE:
#ifdef _DEBUG
{
@ -4445,8 +4575,6 @@ BOOL LLGLSLShader::mapUniforms(const char** uniform_names, S32 count)
mUniform.resize(count + LLPipeline::sReservedUniformCount, -1);
mTexture.resize(count + LLPipeline::sReservedUniformCount, -1);
bind();
//get the number of active uniforms
@ -4663,6 +4791,14 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam,
glGenTextures(1, &blur_tex);
}
BOOL reattach = FALSE;
if (mCubeFrameBuffer == 0)
{
glGenFramebuffersEXT(1, &mCubeFrameBuffer);
glGenRenderbuffersEXT(1, &mCubeDepth);
reattach = TRUE;
}
BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
if (toggle_ui)
{
@ -4679,6 +4815,7 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam,
(1 << LLPipeline::RENDER_TYPE_CLOUDS) |
//(1 << LLPipeline::RENDER_TYPE_STARS) |
//(1 << LLPipeline::RENDER_TYPE_AVATAR) |
(1 << LLPipeline::RENDER_TYPE_GLOW) |
(1 << LLPipeline::RENDER_TYPE_GRASS) |
(1 << LLPipeline::RENDER_TYPE_VOLUME) |
(1 << LLPipeline::RENDER_TYPE_TERRAIN) |
@ -4712,9 +4849,43 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam,
gPipeline.calcNearbyLights();
cube_map->bind();
for (S32 i = 0; i < 6; i++)
{
GLint res_x, res_y;
glGetTexLevelParameteriv(cube_face[i], 0, GL_TEXTURE_WIDTH, &res_x);
glGetTexLevelParameteriv(cube_face[i], 0, GL_TEXTURE_HEIGHT, &res_y);
if (res_x != res || res_y != res)
{
glTexImage2D(cube_face[i],0,GL_RGBA,res,res,0,GL_RGBA,GL_FLOAT,NULL);
reattach = TRUE;
}
}
cube_map->disable();
if (reattach)
{
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth);
GLint res_x, res_y;
glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &res_x);
glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_HEIGHT_EXT, &res_y);
if (res_x != res || res_y != res)
{
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT24,res,res);
}
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
for (S32 i = 0; i < 6; i++)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
cube_face[i], cube_map->getGLName(), 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, mCubeDepth);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 1.f, 0.1f, 1024.f);
@ -4723,7 +4894,6 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam,
apply_cube_face_rotation(i);
glTranslatef(-origin.mV[0], -origin.mV[1], -origin.mV[2]);
cube_cam.setOrigin(origin);
LLViewerCamera::updateFrustumPlanes(cube_cam);
@ -4731,15 +4901,12 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam,
gPipeline.updateCull(cube_cam);
gPipeline.stateSort(cube_cam);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
gPipeline.renderGeom(cube_cam);
cube_map->enable(0);
cube_map->bind();
glCopyTexImage2D(cube_face[i], 0, GL_RGB, 0, 0, res, res, 0);
cube_map->disable();
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
cube_cam.setOrigin(origin);
gPipeline.resetDrawOrders();
gPipeline.mShinyOrigin.setVec(cube_cam.getOrigin(), cube_cam.getFar()*2.f);
@ -4756,14 +4923,12 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam,
{
gPipeline.toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
LLDrawPoolWater::sSkipScreenCopy = FALSE;
}
//send cube map vertices and texture coordinates
void render_cube_map()
{
U32 idx[36];
idx[0] = 1; idx[1] = 0; idx[2] = 2; //front
@ -4810,7 +4975,7 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32
{
LLGLEnable cube(GL_TEXTURE_CUBE_MAP_ARB);
LLGLDepthTest depth(GL_FALSE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@ -4823,9 +4988,9 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32
S32 kernel = 2;
F32 step = 90.f/res;
F32 alpha = 1.f/((kernel*2+1));
F32 alpha = 1.f/((kernel*2)+1);
glColor4f(1,1,1,alpha);
glColor4f(alpha,alpha,alpha,alpha*1.25f);
S32 x = 0;
@ -4847,7 +5012,7 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32
};
glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
glBlendFunc(GL_ONE, GL_ONE);
//3-axis blur
for (U32 j = 0; j < 3; j++)
{
@ -4879,7 +5044,7 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32
}
for (U32 i = 0; i < 6; i++)
{
glCopyTexImage2D(cube_face[i], 0, GL_RGB, 0, i*res, res, res, 0);
glCopyTexImage2D(cube_face[i], 0, GL_RGBA, 0, i*res, res, res, 0);
}
}
@ -4889,6 +5054,273 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32
glPopMatrix();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClear(GL_COLOR_BUFFER_BIT);
}
void LLPipeline::bindScreenToTexture()
{
LLGLEnable gl_texture_2d(GL_TEXTURE_2D);
if (mScreenTex == 0)
{
glGenTextures(1, &mScreenTex);
glBindTexture(GL_TEXTURE_2D, mScreenTex);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
GLuint resX = nhpo2(viewport[2]);
GLuint resY = nhpo2(viewport[3]);
gImageList.updateMaxResidentTexMem(-1, resX*resY*3);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, resX, resY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
GLuint resX = nhpo2(viewport[2]);
GLuint resY = nhpo2(viewport[3]);
glBindTexture(GL_TEXTURE_2D, mScreenTex);
GLint cResX;
GLint cResY;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &cResX);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &cResY);
if (cResX != (GLint)resX || cResY != (GLint)resY)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resX, resY, 0, GL_RGB, GL_FLOAT, NULL);
gImageList.updateMaxResidentTexMem(-1, resX*resY*3);
}
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, viewport[0], viewport[1], 0, 0, viewport[2], viewport[3]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
mScreenScale.mV[0] = (float) viewport[2]/resX;
mScreenScale.mV[1] = (float) viewport[3]/resY;
LLImageGL::sBoundTextureMemory += resX * resY * 3;
}
void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res, LLVector2 tc1, LLVector2 tc2)
{
mGlowProgram.bind();
if (!gGLManager.mHasFramebufferObject)
{
llerrs << "WTF?" << llendl;
}
LLGLEnable tex(GL_TEXTURE_2D);
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
LLGLDisable cull(GL_CULL_FACE);
if (mFramebuffer[0] == 0)
{
glGenFramebuffersEXT(2, mFramebuffer);
}
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glViewport(0,0,res,res);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, source);
S32 kernel = gSavedSettings.getS32("RenderGlowSize")*2;
LLGLDisable test(GL_ALPHA_TEST);
F32 delta = 1.f/(res*gSavedSettings.getF32("RenderGlowStrength"));
for (S32 i = 0; i < kernel; i++)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebuffer[i%2]);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D,
i%2 == 0 ? buffer : dest, 0);
glBindTexture(GL_TEXTURE_2D, i == 0 ? source :
i%2==0 ? dest :
buffer);
glUniform1fARB(mGlowProgram.mUniform[LLPipeline::GLSL_GLOW_DELTA],delta);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(tc1.mV[0], tc1.mV[1]);
glVertex2f(-1,-1);
glTexCoord2f(tc1.mV[0], tc2.mV[1]);
glVertex2f(-1,1);
glTexCoord2f(tc2.mV[0], tc1.mV[1]);
glVertex2f(1,-1);
glTexCoord2f(tc2.mV[0], tc2.mV[1]);
glVertex2f(1,1);
glEnd();
tc1.setVec(0,0);
tc2.setVec(1,1);
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
mGlowProgram.unbind();
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_GLOW))
{
glClear(GL_COLOR_BUFFER_BIT);
}
glBindTexture(GL_TEXTURE_2D, dest);
{
LLGLEnable blend(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBegin(GL_TRIANGLE_STRIP);
glColor4f(1,1,1,1);
glTexCoord2f(tc1.mV[0], tc1.mV[1]);
glVertex2f(-1,-1);
glTexCoord2f(tc1.mV[0], tc2.mV[1]);
glVertex2f(-1,1);
glTexCoord2f(tc2.mV[0], tc1.mV[1]);
glVertex2f(1,-1);
glTexCoord2f(tc2.mV[0], tc2.mV[1]);
glVertex2f(1,1);
glEnd();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void LLPipeline::updateCamera()
{
LLWindow* window = gViewerWindow->getWindow();
F32 time = gFrameIntervalSeconds;
S32 axis[] =
{
gSavedSettings.getS32("JoystickAxis0"),
gSavedSettings.getS32("JoystickAxis1"),
gSavedSettings.getS32("JoystickAxis2"),
gSavedSettings.getS32("JoystickAxis3"),
gSavedSettings.getS32("JoystickAxis4"),
gSavedSettings.getS32("JoystickAxis5")
};
F32 axis_scale[] =
{
gSavedSettings.getF32("JoystickAxisScale0"),
gSavedSettings.getF32("JoystickAxisScale1"),
gSavedSettings.getF32("JoystickAxisScale2"),
gSavedSettings.getF32("JoystickAxisScale3"),
gSavedSettings.getF32("JoystickAxisScale4"),
gSavedSettings.getF32("JoystickAxisScale5")
};
F32 dead_zone[] =
{
gSavedSettings.getF32("JoystickAxisDeadZone0"),
gSavedSettings.getF32("JoystickAxisDeadZone1"),
gSavedSettings.getF32("JoystickAxisDeadZone2"),
gSavedSettings.getF32("JoystickAxisDeadZone3"),
gSavedSettings.getF32("JoystickAxisDeadZone4"),
gSavedSettings.getF32("JoystickAxisDeadZone5")
};
F32 cur_delta[6];
static F32 last_delta[] = {0,0,0,0,0,0};
static F32 delta[] = { 0,0,0,0,0,0 };
F32 feather = gSavedSettings.getF32("FlycamFeathering");
BOOL absolute = gSavedSettings.getBOOL("FlycamAbsolute");
for (U32 i = 0; i < 6; i++)
{
cur_delta[i] = window->getJoystickAxis(axis[i]);
F32 tmp = cur_delta[i];
if (absolute)
{
cur_delta[i] = cur_delta[i] - last_delta[i];
}
last_delta[i] = tmp;
if (cur_delta[i] > 0)
{
cur_delta[i] = llmax(cur_delta[i]-dead_zone[i], 0.f);
}
else
{
cur_delta[i] = llmin(cur_delta[i]+dead_zone[i], 0.f);
}
cur_delta[i] *= axis_scale[i];
if (!absolute)
{
cur_delta[i] *= time;
}
delta[i] = delta[i] + (cur_delta[i]-delta[i])*time*feather;
}
mFlyCamPosition += LLVector3(delta) * mFlyCamRotation;
LLMatrix3 rot_mat(delta[3],
delta[4],
delta[5]);
mFlyCamRotation = LLQuaternion(rot_mat)*mFlyCamRotation;
if (gSavedSettings.getBOOL("FlycamAutoLeveling"))
{
LLMatrix3 level(mFlyCamRotation);
LLVector3 x = LLVector3(level.mMatrix[0]);
LLVector3 y = LLVector3(level.mMatrix[1]);
LLVector3 z = LLVector3(level.mMatrix[2]);
y.mV[2] = 0.f;
y.normVec();
level.setRows(x,y,z);
level.orthogonalize();
LLQuaternion quat = LLQuaternion(level);
mFlyCamRotation = nlerp(llmin(feather*time,1.f), mFlyCamRotation, quat);
}
LLMatrix3 mat(mFlyCamRotation);
gCamera->setOrigin(mFlyCamPosition);
gCamera->mXAxis = LLVector3(mat.mMatrix[0]);
gCamera->mYAxis = LLVector3(mat.mMatrix[1]);
gCamera->mZAxis = LLVector3(mat.mMatrix[2]);
}

View File

@ -87,10 +87,13 @@ public:
void destroyGL();
void restoreGL();
void resetVertexBuffers();
void releaseGLBuffers();
void resetVertexBuffers(LLDrawable* drawable);
void setUseVBO(BOOL use_vbo);
void generateReflectionMap(LLCubeMap* cube_map, LLCamera& camera, GLsizei res);
void blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 res);
void bindScreenToTexture();
void renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res, LLVector2 tc1, LLVector2 tc2);
void init();
void cleanup();
@ -281,6 +284,8 @@ public:
RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA,
RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW,
// Following are object types (only used in drawable mRenderType)
RENDER_TYPE_HUD = LLDrawPool::NUM_POOL_TYPES,
RENDER_TYPE_VOLUME,
@ -327,7 +332,8 @@ public:
RENDER_DEBUG_TEXTURE_AREA = 0x08000,
RENDER_DEBUG_FACE_AREA = 0x10000,
RENDER_DEBUG_PARTICLES = 0x20000,
RENDER_DEBUG_TEXTURE_ANIM = 0x40000,
RENDER_DEBUG_GLOW = 0x40000,
RENDER_DEBUG_TEXTURE_ANIM = 0x80000,
};
LLPointer<LLViewerImage> mAlphaSizzleImagep;
@ -355,6 +361,11 @@ public:
LLSpatialPartition* getSpatialPartition(LLViewerObject* vobj);
LLSpatialPartition* getSpatialPartition(U32 index);
void updateCamera();
LLVector3 mFlyCamPosition;
LLQuaternion mFlyCamRotation;
BOOL mBackfaceCull;
S32 mTrianglesDrawn;
LLStat mTrianglesDrawnStat;
@ -378,10 +389,28 @@ public:
static BOOL sUseOcclusion;
static BOOL sSkipUpdate; //skip lod updates
static BOOL sDynamicReflections;
static BOOL sRenderGlow;
static BOOL sOverrideAgentCamera;
//cube map for anti-aliasing reflections
//screen texture
GLuint mScreenTex;
LLVector2 mScreenScale;
//texture for making the glow
GLuint mGlowMap;
GLuint mGlowBuffer;
//framebuffer objects for off-screen scratch space
GLuint mFramebuffer[2];
//dynamic cube map scratch space
LLCubeMap* mCubeBuffer;
GLuint mCubeList;
//frambuffer object for rendering dynamic cube maps
GLuint mCubeFrameBuffer;
//depth buffer object for rendering dynamic cube maps
GLuint mCubeDepth;
class LLScatterShader
{
@ -465,8 +494,18 @@ public:
GLSL_TERRAIN_ALPHARAMP
} eTerrainUniforms;
//glow parameters
static const char* sGlowUniforms[];
static U32 sGlowUniformCount;
typedef enum
{
GLSL_GLOW_DELTA = GLSL_END_RESERVED_UNIFORMS
} eGlowUniforms;
//environment shaders
LLGLSLShader mTerrainProgram;
LLGLSLShader mGlowProgram;
LLGLSLShader mGroundProgram;
LLGLSLShader mWaterProgram;
@ -627,6 +666,7 @@ protected:
LLDrawPool* mWaterPool;
LLDrawPool* mGroundPool;
LLRenderPass* mSimplePool;
LLDrawPool* mGlowPool;
LLDrawPool* mBumpPool;
// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar