diff options
author | Josh Bell <josh@lindenlab.com> | 2007-03-21 19:36:11 +0000 |
---|---|---|
committer | Josh Bell <josh@lindenlab.com> | 2007-03-21 19:36:11 +0000 |
commit | c93c38e047836e31dd34e33391a997d883777ae1 (patch) | |
tree | ccb52c02f9a3bfeb76254e128abc250e7fd5a962 | |
parent | fceae96eb171be0396512e251aab311d4e3ef9cc (diff) |
svn merge -r 59178:59364 svn+ssh://svn.lindenlab.com/svn/linden/branches/maintenance --> release
49 files changed, 1321 insertions, 732 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt index 494e3fe1d7..be5a5dda83 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -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 diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index e19604c9f0..95d9ae1288 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -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 }; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 5354de783c..00a192aca8 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -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); diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp index 514fb10b4a..451fb2e807 100644 --- a/indra/llmessage/llcircuit.cpp +++ b/indra/llmessage/llcircuit.cpp @@ -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 { diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 320719072c..1be6c21cc2 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -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; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 1fc040c7d6..9a49f32b7d 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -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); diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index d5e1e77053..ccc100a861 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -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; diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index bbe530c906..f19178d7f5 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -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; }; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 4efa173fc4..b8123096e6 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -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)) diff --git a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl index e0e79e95ba..11a057b177 100644 --- a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl @@ -132,5 +132,7 @@ void main() //apply fog applyScatter(color.rgb); + color.a = spec*0.5+fb.a; + gl_FragColor = color; } diff --git a/indra/newview/fmod_hidden_symbols.exp b/indra/newview/fmod_hidden_symbols.exp index c0d5bed859..1e790255bc 100644 --- a/indra/newview/fmod_hidden_symbols.exp +++ b/indra/newview/fmod_hidden_symbols.exp @@ -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 diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 9ab6c700ab..b2e7272336 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -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; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index f7243f369b..1a0021f62b 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -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, diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 5cb914c37e..93af956466 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -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); diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index 6376dd8d33..8835535ee7 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -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(); diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 8fc3b98908..4c09cd4095 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -9,43 +9,91 @@ #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 + void render(S32 pass = 0) { - VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD - }; - - virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + 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); + + 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(); + } + } +}; - virtual void prerender() { } +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()); - void render(S32 pass = 0) + if (gSky.mVOSkyp) { - 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); + 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(); } - void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE) + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + if (LLPipeline::sDynamicReflections) { - glColor4ubv(params.mGlowColor.mV); - LLRenderPass::pushBatch(params, mask, texture); + 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) @@ -98,20 +146,14 @@ void LLDrawPoolSimple::render(S32 pass) } { - 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); } } diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index f89230d866..1eb9b3c6eb 100644 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -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 diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index db5debc079..6e372b6f76 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -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() diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index f2981625f7..f3821a8b7a 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -47,6 +47,7 @@ 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. @@ -54,19 +55,23 @@ LLDynamicTexture::~LLDynamicTexture() } //----------------------------------------------------------------------------- -// generateGLTexture() +// releaseGLTexture() //----------------------------------------------------------------------------- -void LLDynamicTexture::generateGLTexture() +void LLDynamicTexture::releaseGLTexture() { - if (mComponents < 1 || mComponents > 4) + if (mTexture.notNull()) { - llerrs << "Bad number of components in dynamic texture: " << mComponents << llendl; +// llinfos << "RELEASING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl; + mTexture = NULL; } +} - 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() +//----------------------------------------------------------------------------- +void LLDynamicTexture::generateGLTexture() +{ + 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); } diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index 75a37aaa29..8f6ecb23b4 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -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); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 6c00874982..280abcd541 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -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) { diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index eb5a3de1de..622af2b473 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -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; diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index 155d4d6ff7..3745de6552 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -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; diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index 7eaac8887c..ecab84f5d9 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -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(); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 5f37d756fe..e9fa4cc1dd 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -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() diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index c3ec9e8f2b..0338e7f02a 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -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 diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 11573741a2..ddfc4fe791 100755 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -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; }; diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 9e26d951bc..6171971c16 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -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(); diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index e1ab8bf371..b03747c68b 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -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); diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index 4c4c15a9e2..c49fee6d4a 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -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) { diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 38c4f72fc9..98b4c4ef42 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -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 diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 33e191cc9c..fcabdc8450 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -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 ) diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index 5c1a11cdf1..bda865eb2e 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -322,9 +322,6 @@ public: 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; }; diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index cb846a43fe..1a3fe79551 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -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()) diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index f9eb8cb177..f0f2ef47a8 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -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; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 4c90c3624b..a9f660a0f5 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -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) - { - 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 + U8* buffer = new U8[mBufferSize]; + if (cur_size > 0) { - 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()); + 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) + { +// llinfos << "REQUESTING " << request_count << " IMAGES FROM HOST: " << host.getIPString() << llendl; + gMessageSystem->sendSemiReliable(host, NULL, NULL); + request_count = 0; + } } - 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) + 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; + } + else if (host != worker->mHost) + { +// 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; } - // check to see if we've gotten this packet before - if (worker->mLastPacket != -1) + else if (worker->mLastPacket != -1) { -// llwarns << "Img: " << id << ":" << " Duplicate Image Header" << llendl; + // 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; + } + else if (host != worker->mHost) + { +// llwarns << "Received packet from wrong host for: " << id << llendl; + res = false; } - if (worker->mLastPacket == -1) + else if (worker->mLastPacket == -1) { -// llwarns << "Img: " << id << ":" << " Image Packet " << packet_num << " received before header" << llendl; +// 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; } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 7cf7cb45f2..e4e94c048e 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -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; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index f051236fba..b75e379755 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -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; diff --git a/indra/newview/lltextureview.h b/indra/newview/lltextureview.h index 691438c64e..4392b382a8 100644 --- a/indra/newview/lltextureview.h +++ b/indra/newview/lltextureview.h @@ -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; diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index 0ab1fd1cbf..8efed01018 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -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 ); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index cbbc2ac6cd..9a43729195 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -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(); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 259fa09309..f9e74f31e6 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -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; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index a2dadcc438..41f937efd5 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -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))); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f9ee5064a1..5db295874c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -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 diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index eb62f8ceb0..987d2ac7cb 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -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; } diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index c705c3951e..0ded91bb80 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -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; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6619531953..b5b9e06831 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -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); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c7ecb225fb..6b7f60457d 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -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) + { + glDeleteFramebuffersEXT(1, &mCubeFrameBuffer); + glDeleteRenderbuffersEXT(1, &mCubeDepth); + mCubeDepth = mCubeFrameBuffer = 0; + } + + if (mFramebuffer[0]) { - glDeleteLists(mCubeList, 1); - mCubeList = 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]); +} diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5061ef742c..4d89b65c90 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -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; + + //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]; - //cube map for anti-aliasing reflections + //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 |