diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index bacd4e5fb..e6f628436 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -240,7 +240,7 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, // We are using a local max buffer size here to avoid issues // if MAX_STRING size changes. const U32 PARSE_BUFFER_SIZE = 2048; - char buffer[2048]; /* Flawfinder: ignore */ + char buffer[PARSE_BUFFER_SIZE]; /* Flawfinder: ignore */ char uuid_buffer[37]; /* Flawfinder: ignore */ // This data is being generated on the viewer. @@ -254,12 +254,11 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, } // read header and version - if (!input_stream.good()) + if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) { llwarns << "Failed to read wearable asset input stream." << llendl; return LLWearable::FAILURE; } - input_stream.getline(buffer, PARSE_BUFFER_SIZE); if ( 1 != sscanf( /* Flawfinder: ignore */ buffer, "LLWearable version %d\n", @@ -299,14 +298,13 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, input_stream.getline(buffer, PARSE_BUFFER_SIZE); mDescription = buffer; - // permissions - if (!input_stream.good()) + // permissions may have extra empty lines before the correct line + if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) { llwarns << "Bad Wearable asset: early end of input stream " << "while reading permissions" << llendl; return LLWearable::FAILURE; } - input_stream.getline(buffer, PARSE_BUFFER_SIZE); S32 perm_version = -1; if ( 1 != sscanf( buffer, " permissions %d\n", &perm_version ) || perm_version != 0 ) @@ -320,13 +318,12 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, } // sale info - if (!input_stream.good()) + if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) { llwarns << "Bad Wearable asset: early end of input stream " << "while reading sale info" << llendl; return LLWearable::FAILURE; } - input_stream.getline(buffer, PARSE_BUFFER_SIZE); S32 sale_info_version = -1; if ( 1 != sscanf( buffer, " sale_info %d\n", &sale_info_version ) || sale_info_version != 0 ) @@ -355,13 +352,12 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, } // wearable type - if (!input_stream.good()) + if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) { llwarns << "Bad Wearable asset: early end of input stream " << "while reading type" << llendl; return LLWearable::FAILURE; } - input_stream.getline(buffer, PARSE_BUFFER_SIZE); S32 type = -1; if ( 1 != sscanf( buffer, "type %d\n", &type ) ) { @@ -380,13 +376,12 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, } // parameters header - if (!input_stream.good()) + if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) { llwarns << "Bad Wearable asset: early end of input stream " << "while reading parameters header" << llendl; return LLWearable::FAILURE; } - input_stream.getline(buffer, PARSE_BUFFER_SIZE); S32 num_parameters = -1; if ( 1 != sscanf( buffer, "parameters %d\n", &num_parameters ) ) { @@ -412,13 +407,12 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, S32 i; for( i = 0; i < num_parameters; i++ ) { - if (!input_stream.good()) + if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) { llwarns << "Bad Wearable asset: early end of input stream " << "while reading parameter #" << i << llendl; return LLWearable::FAILURE; } - input_stream.getline(buffer, PARSE_BUFFER_SIZE); S32 param_id = 0; F32 param_weight = 0.f; if ( 2 != sscanf( buffer, "%d %f\n", ¶m_id, ¶m_weight ) ) @@ -430,13 +424,12 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, } // textures header - if (!input_stream.good()) + if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) { llwarns << "Bad Wearable asset: early end of input stream " << "while reading textures header" << i << llendl; return LLWearable::FAILURE; } - input_stream.getline(buffer, PARSE_BUFFER_SIZE); S32 num_textures = -1; if ( 1 != sscanf( buffer, "textures %d\n", &num_textures) ) { @@ -453,13 +446,12 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, // textures for( i = 0; i < num_textures; i++ ) { - if (!input_stream.good()) + if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE)) { llwarns << "Bad Wearable asset: early end of input stream " << "while reading textures #" << i << llendl; return LLWearable::FAILURE; } - input_stream.getline(buffer, PARSE_BUFFER_SIZE); S32 te = 0; if ( 2 != sscanf( /* Flawfinder: ignore */ buffer, @@ -499,6 +491,23 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, return LLWearable::SUCCESS; } +BOOL LLWearable::getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size) +{ + if (!input_stream.good()) + { + return FALSE; + } + + do + { + input_stream.getline(buffer, buffer_size); + } + while (input_stream.good() && buffer[0]=='\0'); + + return input_stream.good(); +} + + void LLWearable::setType(LLWearableType::EType type, LLAvatarAppearance *avatarp) { mType = type; diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h index 8faf383aa..ac25cec2f 100644 --- a/indra/llappearance/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -123,6 +123,7 @@ protected: void destroyTextures(); void createVisualParams(LLAvatarAppearance *avatarp); void createLayers(S32 te, LLAvatarAppearance *avatarp); + BOOL getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size); static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml. S32 mDefinitionVersion; // Depends on the state of the avatar_lad.xml when this asset was created. diff --git a/indra/llaudio/llstreamingaudio_fmodex.cpp b/indra/llaudio/llstreamingaudio_fmodex.cpp index 535c77a7b..2f7bdf6bd 100644 --- a/indra/llaudio/llstreamingaudio_fmodex.cpp +++ b/indra/llaudio/llstreamingaudio_fmodex.cpp @@ -161,7 +161,6 @@ void LLStreamingAudio_FMODEX::update() // Reset volume to previously set volume setGain(getGain()); mFMODInternetStreamChannelp->setPaused(false); - mLastStarved.stop(); } } else if(open_state == FMOD_OPENSTATE_ERROR) @@ -200,6 +199,13 @@ void LLStreamingAudio_FMODEX::update() if(name == "Title") name = "TITLE"; else if(name == "WM/AlbumArtist") name = "ARTIST"; break; + case(FMOD_TAGTYPE_FMOD): + if (!strcmp(tag.name, "Sample Rate Change")) + { + llinfos << "Stream forced changing sample rate to " << *((float *)tag.data) << llendl; + mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)); + } + continue; default: break; } @@ -243,19 +249,19 @@ void LLStreamingAudio_FMODEX::update() } if(starving) { - if(!mLastStarved.getStarted()) + bool paused = false; + mFMODInternetStreamChannelp->getPaused(&paused); + if(!paused) { - llinfos << "Stream starvation detected! Muting stream audio until it clears." << llendl; + llinfos << "Stream starvation detected! Pausing stream until buffer nearly full." << llendl; llinfos << " (diskbusy="<setMute(true); + mFMODInternetStreamChannelp->setPaused(true); } - mLastStarved.start(); } - else if(mLastStarved.getStarted() && mLastStarved.getElapsedTimeF32() > 1.f) + else if(progress > 80) { - mLastStarved.stop(); - mFMODInternetStreamChannelp->setMute(false); + mFMODInternetStreamChannelp->setPaused(false); } } } @@ -263,7 +269,6 @@ void LLStreamingAudio_FMODEX::update() void LLStreamingAudio_FMODEX::stop() { - mLastStarved.stop(); if(mMetaData) { delete mMetaData; diff --git a/indra/llaudio/llstreamingaudio_fmodex.h b/indra/llaudio/llstreamingaudio_fmodex.h index 1b5211485..54d96e9a5 100644 --- a/indra/llaudio/llstreamingaudio_fmodex.h +++ b/indra/llaudio/llstreamingaudio_fmodex.h @@ -79,8 +79,6 @@ private: std::string mURL; F32 mGain; - LLTimer mLastStarved; - LLSD *mMetaData; }; diff --git a/indra/llcommon/llmemtype.h b/indra/llcommon/llmemtype.h index 2a411eb90..9c3c98937 100644 --- a/indra/llcommon/llmemtype.h +++ b/indra/llcommon/llmemtype.h @@ -40,7 +40,6 @@ #include -#define MEM_TYPE_NEW(T) class LL_COMMON_API LLMemType { diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index c3b79951f..1c4c1af81 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -836,6 +836,7 @@ P(blockingLLSDPost); P(blockingLLSDGet); P(blockingRawGet); P(charactersResponder); +P(checkAgentAppearanceServiceResponder); P(classifiedStatsResponder); P(consoleResponder); P2(crashLoggerResponder, transfer_5s); diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 7e45c0e96..6d7720117 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1242,6 +1242,7 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name if (tec.size == 0) { + tec.face_count = 0; return retval; } diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index aa6278417..977245b6e 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -51,11 +51,13 @@ void check_framebuffer_status() } bool LLRenderTarget::sUseFBO = false; +U32 LLRenderTarget::sCurFBO = 0; LLRenderTarget::LLRenderTarget() : mResX(0), mResY(0), mFBO(0), + mPreviousFBO(0), mDepth(0), mStencil(0), mUseDepth(false), @@ -117,6 +119,9 @@ void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer) bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo) { + resx = llmin(resx, (U32) 4096); + resy = llmin(resy, (U32) 4096); + stop_glerror(); release(); stop_glerror(); @@ -156,7 +161,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0); stop_glerror(); } - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); } stop_glerror(); @@ -173,10 +178,19 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) } U32 offset = mTex.size(); - if (offset >= 4 || - (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) + + if( offset >= 4 ) { - llerrs << "Too many color attachments!" << llendl; + llwarns << "Too many color attachments" << llendl; + llassert( offset < 4 ); + return false; + } + if( offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers) ) + { + llwarns << "FBO not used or no drawbuffers available; mFBO=" << (U32)mFBO << " gGLManager.mHasDrawBuffers=" << (U32)gGLManager.mHasDrawBuffers << llendl; + llassert( mFBO != 0 ); + llassert( gGLManager.mHasDrawBuffers ); + return false; } U32 tex; @@ -234,7 +248,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) check_framebuffer_status(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); } mTex.push_back(tex); @@ -329,7 +343,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) check_framebuffer_status(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); target.mUseDepth = true; } @@ -400,14 +414,18 @@ void LLRenderTarget::bindTarget() if (mFBO) { stop_glerror(); + mPreviousFBO = sCurFBO; if (mSampleBuffer) { mSampleBuffer->bindTarget(this); + sCurFBO = mSampleBuffer->mFBO; stop_glerror(); } else { glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + sCurFBO = mFBO; + stop_glerror(); if (gGLManager.mHasDrawBuffers) { //setup multiple render targets @@ -434,16 +452,6 @@ void LLRenderTarget::bindTarget() sBoundTarget = this; } -// static -void LLRenderTarget::unbindTarget() -{ - if (gGLManager.mHasFramebufferObject) - { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - sBoundTarget = NULL; -} - void LLRenderTarget::clear(U32 mask_in) { U32 mask = GL_COLOR_BUFFER_BIT; @@ -512,10 +520,7 @@ void LLRenderTarget::flush(bool fetch_depth) else { stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - stop_glerror(); - - if (mSampleBuffer) + if(mSampleBuffer) { LLGLEnable multisample(GL_MULTISAMPLE); stop_glerror(); @@ -570,10 +575,14 @@ void LLRenderTarget::flush(bool fetch_depth) stop_glerror(); }*/ } - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); } + glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO); + sCurFBO = mPreviousFBO; + stop_glerror(); } } + void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter) { @@ -604,7 +613,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, stop_glerror(); glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); stop_glerror(); } else @@ -627,7 +636,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, stop_glerror(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); stop_glerror(); } } @@ -661,7 +670,7 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0 if(mask) glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); stop_glerror(); } } @@ -810,7 +819,7 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth } stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); stop_glerror(); @@ -889,7 +898,7 @@ bool LLMultisampleBuffer::addColorAttachment(U32 color_fmt) glBindFramebuffer(GL_FRAMEBUFFER, mFBO); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, GL_RENDERBUFFER, tex); check_framebuffer_status(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); } mTex.push_back(tex); diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 14eea5a4a..c2696aae6 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -65,6 +65,7 @@ public: //whether or not to use FBO implementation static bool sUseFBO; static U32 sBytesAllocated; + static U32 sCurFBO; LLRenderTarget(); virtual ~LLRenderTarget(); @@ -101,9 +102,6 @@ public: //applies appropriate viewport virtual void bindTarget(); - //unbind target for rendering - static void unbindTarget(); - //clear render targer, clears depth buffer if present, //uses scissor rect if in copy-to-texture mode void clear(U32 mask = 0xFFFFFFFF); @@ -156,6 +154,7 @@ protected: std::vector mTex; std::vector mInternalFormat; U32 mFBO; + U32 mPreviousFBO; U32 mDepth; bool mStencil; bool mUseDepth; diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml index 411bc1e36..dedf2e435 100644 --- a/indra/newview/app_settings/settings_sh.xml +++ b/indra/newview/app_settings/settings_sh.xml @@ -50,7 +50,7 @@ Type U32 Value - 7000 + 15000 SHFMODExDecodeBufferSize @@ -61,7 +61,7 @@ Type U32 Value - 1000 + 2000 SHAllowScriptCommands diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 03d0c82c2..4005341c6 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -26,7 +26,7 @@ ATTRIBUTE vec4 weight4; -uniform mat4 matrixPalette[64]; +uniform mat4 matrixPalette[32]; mat4 getObjectSkinnedTransform() { diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index db622d4e3..7ee6eafef 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -783,9 +783,16 @@ void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id) llinfos << "update requested due to region transition" << llendl; LLAppearanceMgr::instance().requestServerAppearanceUpdate(); } + // new-style appearance entering a non-bake region, + // need to check for existence of the baking service. + else if (isAgentAvatarValid() && + gAgentAvatarp->isUsingServerBakes() && + mRegionp->getCentralBakeVersion()==0) + { + gAgentAvatarp->checkForUnsupportedServerBakeAppearance(); + } } - //----------------------------------------------------------------------------- // setRegion() //----------------------------------------------------------------------------- @@ -4480,13 +4487,6 @@ void LLAgent::sendAgentSetAppearance() return; } - if (!gAgentWearables.changeInProgress()) - { - // Change is fully resolved, can close some open phases. - gAgentAvatarp->stopPhase("process_initial_wearables_update"); - gAgentAvatarp->stopPhase("wear_inventory_category"); - } - if (!isAgentAvatarValid() || (getRegion() && getRegion()->getCentralBakeVersion())) return; // At this point we have a complete appearance to send and are in a non-baking region. diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e5a6356e5..a5d67e356 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2290,6 +2290,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) } BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF); + selfStartPhase("update_appearance_from_cof"); LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; @@ -3456,6 +3457,12 @@ public: void LLAppearanceMgr::requestServerAppearanceUpdate(LLHTTPClient::ResponderPtr responder_ptr) { + if (gAgentAvatarp->isEditingAppearance()) + { + // don't send out appearance updates if in appearance editing mode + return; + } + if (!gAgent.getRegion()) { llwarns << "Region not set, cannot request server appearance update" << llendl; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d83ccac39..39c580f50 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3156,7 +3156,7 @@ void LLAppViewer::requestQuit() // Try to send last batch of avatar rez metrics. if (!gDisconnected && isAgentAvatarValid()) { - LLVOAvatarSelf::updateAvatarRezMetrics(true); // force a last packet to be sent. + gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. } LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 7d133fa72..947422310 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -545,38 +545,17 @@ F32 LLDrawable::updateXform(BOOL undamped) } } } - else - { - dist_squared = dist_vec_squared(old_pos, target_pos); - dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f; - dist_squared += dist_vec_squared(old_scale, target_scale); - } - LLVector3 vec = mCurrentScale-target_scale; - - if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED) - { //scale change requires immediate rebuild + if ((mCurrentScale != target_scale) || + (!isRoot() && + (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED || + !mVObjp->getAngularVelocity().isExactlyZero() || + target_pos != mXform.getPosition() || + target_rot != mXform.getRotation()))) + { //child prim moving or scale change requires immediate rebuild mCurrentScale = target_scale; gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); } - else if (!isRoot() && - (!mVObjp->getAngularVelocity().isExactlyZero() || - dist_squared > 0.f)) - { //child prim moving relative to parent, tag as needing to be rendered atomically and rebuild - dist_squared = 1.f; //keep this object on the move list - if (!isState(LLDrawable::ANIMATED_CHILD)) - { - setState(LLDrawable::ANIMATED_CHILD); - gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); - mVObjp->dirtySpatialGroup(); - } - } - else if (!isRoot() && ( - dist_vec_squared(old_pos, target_pos) > 0.f - || old_rot != target_rot )) - { //fix for BUG-860, MAINT-2275, MAINT-1742, MAINT-2247 - gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); - } else if (!getVOVolume() && !isAvatar()) { movePartition(); @@ -666,7 +645,7 @@ BOOL LLDrawable::updateMoveUndamped() if (!isState(LLDrawable::INVISIBLE)) { - BOOL moved = (dist_squared > 0.001f && dist_squared < 255.99f); + BOOL moved = (dist_squared > 0.001f); moveUpdatePipeline(moved); mVObjp->updateText(); } @@ -701,7 +680,7 @@ BOOL LLDrawable::updateMoveDamped() if (!isState(LLDrawable::INVISIBLE)) { - BOOL moved = (dist_squared > 0.001f && dist_squared < 128.0f); + BOOL moved = (dist_squared > 0.001f); moveUpdatePipeline(moved); mVObjp->updateText(); } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index e2ea0140f..a9bec244f 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -93,7 +93,6 @@ public: } LLDrawable() { init(); } - MEM_TYPE_NEW(LLMemType::MTYPE_DRAWABLE); void markDead(); // Mark this drawable as dead BOOL isDead() const { return isState(DEAD); } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 2154c0495..91fbf7cbe 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -414,8 +414,8 @@ void LLDrawPoolWater::renderOpaqueLegacyWater() { glEnable(GL_TEXTURE_GEN_S); //texture unit 0 glEnable(GL_TEXTURE_GEN_T); //texture unit 0 - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); } // Use the fact that we know all water faces are the same size diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 8f0119f80..7aa6eea13 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -774,6 +774,8 @@ private: BOOL mForceSelection; LLAnimPauseRequest mPauseRequest; + + friend class LLObjectBackup; }; // *DEPRECATED: For callbacks or observers, use diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 0afebcbc3..8b4693c79 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -133,7 +133,6 @@ public: typedef const child_list_t const_child_list_t; LLViewerObject(const LLUUID &id, const LLPCode type, LLViewerRegion *regionp, BOOL is_global = FALSE); - MEM_TYPE_NEW(LLMemType::MTYPE_OBJECT); virtual void markDead(); // Mark this object as dead, and clean up its references BOOL isDead() const {return mDead;} diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp index 4135e88b9..49d2e25bc 100644 --- a/indra/newview/llviewerobjectbackup.cpp +++ b/indra/newview/llviewerobjectbackup.cpp @@ -1105,7 +1105,7 @@ void LLObjectBackup::primUpdate(LLViewerObject* object) // Now link LLSelectMgr::getInstance()->deselectAll(); LLSelectMgr::getInstance()->selectObjectAndFamily(mToSelect, true); - LLSelectMgr::getInstance()->linkObjects(); + LLSelectMgr::getInstance()->sendLink(); LLViewerObject* root = mToSelect.back(); root->setRotation(mRootRot); } diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 55c3a980a..2a42b7661 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1558,17 +1558,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use // Actually extract the data. if (parcel) { - if (sequence_id == SELECTED_PARCEL_SEQ_ID - && parcel->getLocalID() != INVALID_PARCEL_ID - && parcel->getLocalID() != local_id) - { - // The parcel has a valid parcel ID but it doesn't match the parcel - // for the data received. - llinfos << "Expecting data for parcel " << parcel->getLocalID() \ - << " but got data for parcel " << local_id << llendl; - return; - } - parcel->init(owner_id, FALSE, FALSE, FALSE, claim_date, claim_price_per_meter, rent_price_per_meter, diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index bce3a2726..ab6f13752 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4349,8 +4349,8 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw, // Copy screen to a buffer LLRect const window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw(); - S32 const window_width = window_rect.getWidth(); - S32 const window_height = window_rect.getHeight(); + S32 window_width = window_rect.getWidth(); + S32 window_height = window_rect.getHeight(); // SNAPSHOT @@ -4378,7 +4378,7 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw, S32 buffer_x_offset = 0; S32 buffer_y_offset = 0; - F32 scale_factor; + F32 scale_factor = 1.0f; S32 image_buffer_x; S32 image_buffer_y; @@ -4386,6 +4386,36 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw, // snapshot fits precisely inside window, it is the portion of the window with the correct aspect. F32 snapshot_width = (snapshot_aspect > window_aspect) ? (F32)window_width : window_height * snapshot_aspect; F32 snapshot_height = (snapshot_aspect < window_aspect) ? (F32)window_height : window_width / snapshot_aspect; + + //This is what I would classify as a hack. If in deferred then do not tile (window_*=snapshot_*=image_*, ratio=scale_factor=1.f) + S32 original_width = 0; + S32 original_height = 0; + bool reset_deferred = false; + LLRenderTarget scratch_space; + if ((image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui) + { + if (scratch_space.allocate(image_width, image_height, GL_RGBA, true, true)) + { + original_width = gPipeline.mDeferredScreen.getWidth(); + original_height = gPipeline.mDeferredScreen.getHeight(); + + if (gPipeline.allocateScreenBuffer(image_width, image_height)) + { + image_width = snapshot_width = window_width = scratch_space.getWidth(); + image_height = snapshot_height = window_height = scratch_space.getHeight(); + reset_deferred = true; + mWindowRectRaw.set(0, image_height, image_width, 0); + scratch_space.bindTarget(); + } + else + { + scratch_space.release(); + gPipeline.allocateScreenBuffer(original_width, original_height); + } + } + } + + // ratio is the ratio snapshot/image', where image' is a rectangle with aspect snapshot_aspect that precisely contains image. // Thus image_width' / image_height' == aspect ==> snapshot_width / image_width' == snapshot_height / image_height'. // Since image' precisely contains image, one of them is equal (ie, image_height' = image_height) and the other is larger @@ -4417,7 +4447,7 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw, S32 image_size_x = llround(snapshot_width * scale_factor); S32 image_size_y = llround(snapshot_width * scale_factor); if (llmax(image_size_x, image_size_y) > max_size && // Boundary check to avoid memory overflow. - internal_scale <= 1.f) // SHY_MOD: If supersampling... Don't care about max_size. + internal_scale <= 1.f && !reset_deferred) // SHY_MOD: If supersampling... Don't care about max_size. { // Too big, clamp. continue; @@ -4425,6 +4455,8 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw, // Done. break; } + + // Center the buffer. buffer_x_offset = llfloor(((window_width - unscaled_image_buffer_x) * scale_factor) / 2.f); buffer_y_offset = llfloor(((window_height - unscaled_image_buffer_y) * scale_factor) / 2.f); @@ -4588,6 +4620,15 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw, // objects on them. gPipeline.resetDrawOrders(); } + + if (reset_deferred) + { + mWindowRectRaw = window_rect; + scratch_space.flush(); + scratch_space.release(); + gPipeline.allocateScreenBuffer(original_width, original_height); + + } if (is_tiling) { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1ac12e15c..9b87e221e 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1119,6 +1119,9 @@ LLVOAvatar::~LLVOAvatar() debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); } } + + //logPendingPhases(); + lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl; std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer()); @@ -1153,7 +1156,12 @@ void LLVOAvatar::markDead() } mVoiceVisualizer->markDead(); LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; + + if(!isDead()) + logPendingPhases(); + LLViewerObject::markDead(); + } @@ -1217,6 +1225,7 @@ BOOL LLVOAvatar::hasGray() const S32 LLVOAvatar::getRezzedStatus() const { if (getIsCloud()) return 0; + if (isFullyTextured() && allBakedTexturesCompletelyDownloaded()) return 3; if (isFullyTextured()) return 2; llassert(hasGray()); return 1; // gray @@ -1272,7 +1281,7 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars) void LLVOAvatar::getNearbyRezzedStats(std::vector& counts) { counts.clear(); - counts.resize(3); + counts.resize(4); for (std::vector::iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) { @@ -1290,6 +1299,7 @@ std::string LLVOAvatar::rezStatusToString(S32 rez_status) if (rez_status==0) return "cloud"; if (rez_status==1) return "gray"; if (rez_status==2) return "textured"; + if (rez_status==3) return "textured_and_downloaded"; return "unknown"; } @@ -2212,13 +2222,13 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU const std::string url = getImageURL(te,uuid); if (!url.empty()) { - llinfos << "texture URL " << url << llendl; + LL_DEBUGS("Avatar") << avString() << "from URL " << url << llendl; result = LLViewerTextureManager::getFetchedTextureFromUrl( url, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid); } else { - llinfos << "get texture from host " << uuid << llendl; + LL_DEBUGS("Avatar") << avString() << "from host " << uuid << llendl; LLHost host = getObjectHost(); result = LLViewerTextureManager::getFetchedTexture( uuid, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); @@ -2232,10 +2242,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) { if (!isIndexBakedTexture((ETextureIndex)te)) { - if (!uuid.isNull()) - { - llinfos << "ignoring texture " << uuid << " in non-baked slot " << (S32)te << " - will use null " << llendl; - } + // Sim still sends some uuids for non-baked slots sometimes - ignore. return LLViewerObject::setTETexture(te, LLUUID::null); } @@ -2937,8 +2944,19 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) mVisibleChat = visible_chat; new_name = TRUE; } - - if (sRenderGroupTitles != (bool)mRenderGroupTitles) + +// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.2a) | Added: RLVa-0.2.0b + if (fRlvShowNames) + { + if (mRenderGroupTitles) + { + mRenderGroupTitles = FALSE; + new_name = TRUE; + } + } + else if (sRenderGroupTitles != (bool)mRenderGroupTitles) +// [/RLVa] + //if (sRenderGroupTitles != (bool)mRenderGroupTitles) { mRenderGroupTitles = sRenderGroupTitles; new_name = TRUE; @@ -3075,6 +3093,9 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) // Avatars must have a first and last name if (!firstname || !lastname) return; +// [RLVa:KB] - Checked: 2010-10-31 (RLVa-1.2.2a) | Added: RLVa-1.2.2a + bool fRlvShowNames = gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES); +// [/RLVa:KB] bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end(); bool is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end(); bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); @@ -3087,7 +3108,10 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) { is_muted = LLMuteList::getInstance()->isMuted(getID()); } - bool is_friend = LLAvatarTracker::instance().isBuddy(getID()); +// bool is_friend = LLAvatarTracker::instance().isBuddy(getID()); +// [RLVa:KB] - Checked: 2010-10-31 (RLVa-1.2.2a) | Added: RLVa-1.2.2a + bool is_friend = (!fRlvShowNames) && (LLAvatarTracker::instance().isBuddy(getID())); +// [/RLVa:KB] bool is_cloud = getIsCloud(); bool is_langolier = isLangolier(); @@ -3170,7 +3194,10 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) LLFontGL::getFontSansSerifSmall()); } - if (sRenderGroupTitles +// if (sRenderGroupTitles +// [RLVa:KB] - Checked: 2010-10-31 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + if (sRenderGroupTitles && !fRlvShowNames +// [/RLVa:KB] && title && title->getString() && title->getString()[0] != '\0') { std::string title_str = title->getString(); @@ -3198,6 +3225,10 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) boost::bind(&LLVOAvatar::clearNameTag, this)); } +// [RLVa:KB] - Checked: 2010-10-31 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + if ( (!fRlvShowNames) || (isSelf()) ) + { +// [/RLVa:KB] // Might be blank if name not available yet, that's OK if (show_display_names) { @@ -3218,15 +3249,35 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) //addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL, //LLFontGL::getFontSansSerifSmall()); } +// [RLVa:KB] - Checked: 2010-10-31 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + } + else + { + firstnameText = RlvStrings::getAnonym(av_name); + } +// [/RLVa:KB] } else { +// [RLVa:KB] - Checked: 2010-10-31 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + if ( (!fRlvShowNames) || (isSelf()) ) + { +// [/RLVa:KB] firstnameText=firstname->getString(); //Defer for later formatting lastnameText=lastname->getString(); //Defer for later formatting //const LLFontGL* font = LLFontGL::getFontSansSerif(); //std::string full_name = // LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); //addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font); + } +// [RLVa:KB] - Checked: 2010-10-31 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + else + { + std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); + firstnameText = RlvStrings::getAnonym(full_name); + } +// [/RLVa:KB] + } static const LLCachedControl allow_nameplate_override ("CCSAllowNameplateOverride", true); @@ -3567,7 +3618,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded(); bool all_local_downloaded = allLocalTexturesCompletelyDownloaded(); std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d", - all_local_downloaded ? "L" : "l", + isSelf() ? (all_local_downloaded ? "L" : "l") : "-", all_baked_downloaded ? "B" : "b", mUseLocalAppearance, mIsEditingAppearance, mUseServerBakes, central_bake_version); @@ -4718,7 +4769,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) return 6; } -bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set& ids) +bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set& ids) const { for (std::set::const_iterator it = ids.begin(); it != ids.end(); ++it) { @@ -4731,14 +4782,14 @@ bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set& ids) return true; } -bool LLVOAvatar::allLocalTexturesCompletelyDownloaded() +bool LLVOAvatar::allLocalTexturesCompletelyDownloaded() const { std::set local_ids; collectLocalTextureUUIDs(local_ids); return allTexturesCompletelyDownloaded(local_ids); } -bool LLVOAvatar::allBakedTexturesCompletelyDownloaded() +bool LLVOAvatar::allBakedTexturesCompletelyDownloaded() const { std::set baked_ids; collectBakedTextureUUIDs(baked_ids); @@ -4813,7 +4864,7 @@ S32 LLVOAvatar::totalTextureMemForUUIDS(std::set& ids) return result; } -void LLVOAvatar::collectLocalTextureUUIDs(std::set& ids) +void LLVOAvatar::collectLocalTextureUUIDs(std::set& ids) const { for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) { @@ -4839,7 +4890,7 @@ void LLVOAvatar::collectLocalTextureUUIDs(std::set& ids) ids.erase(IMG_INVISIBLE); } -void LLVOAvatar::collectBakedTextureUUIDs(std::set& ids) +void LLVOAvatar::collectBakedTextureUUIDs(std::set& ids) const { for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) { @@ -4875,15 +4926,15 @@ void LLVOAvatar::releaseOldTextures() std::set local_texture_ids; collectLocalTextureUUIDs(local_texture_ids); - S32 new_local_mem = totalTextureMemForUUIDS(local_texture_ids); + //S32 new_local_mem = totalTextureMemForUUIDS(local_texture_ids); std::set new_texture_ids; new_texture_ids.insert(baked_texture_ids.begin(),baked_texture_ids.end()); new_texture_ids.insert(local_texture_ids.begin(),local_texture_ids.end()); S32 new_total_mem = totalTextureMemForUUIDS(new_texture_ids); - S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs); - LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << llendl; + //S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs); + //LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << llendl; if (!isSelf() && new_total_mem > new_baked_mem) { llwarns << "extra local textures stored for non-self av" << llendl; @@ -5165,6 +5216,7 @@ void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te) const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid) { + llassert(isIndexBakedTexture(ETextureIndex(te))); std::string url = ""; if (isUsingServerBakes()) { @@ -6836,41 +6888,48 @@ BOOL LLVOAvatar::getIsCloud() const void LLVOAvatar::updateRezzedStatusTimers() { - // State machine for rezzed status. Statuses are 0 = cloud, 1 = gray, 2 = textured. - // Purpose is to collect time data for each period of cloud or cloud+gray. + // State machine for rezzed status. Statuses are -1 on startup, 0 + // = cloud, 1 = gray, 2 = textured, 3 = textured_and_downloaded. + // Purpose is to collect time data for each it takes avatar to reach + // various loading landmarks: gray, textured (partial), textured fully. + S32 rez_status = getRezzedStatus(); if (rez_status != mLastRezzedStatus) { LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL; - bool is_cloud_or_gray = (rez_status==0 || rez_status==1); - bool was_cloud_or_gray = (mLastRezzedStatus==0 || mLastRezzedStatus==1); - bool is_cloud = (rez_status==0); - bool was_cloud = (mLastRezzedStatus==0); - // Non-cloud to cloud - if (is_cloud && !was_cloud) + if (mLastRezzedStatus == -1 && rez_status != -1) { - // start cloud timer. - startPhase("cloud"); + // First time initialization, start all timers. + for (S32 i = 1; i < 4; i++) + { + startPhase("load_" + LLVOAvatar::rezStatusToString(i)); + } } - else if (was_cloud && !is_cloud) + if (rez_status < mLastRezzedStatus) { - // stop cloud timer, which will capture stats. - stopPhase("cloud"); + // load level has decreased. start phase timers for higher load levels. + for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++) + { + startPhase("load_" + LLVOAvatar::rezStatusToString(i)); + } + } + else if (rez_status > mLastRezzedStatus) + { + // load level has increased. stop phase timers for lower and equal load levels. + for (S32 i = llmax(mLastRezzedStatus+1,1); i <= rez_status; i++) + { + stopPhase("load_" + LLVOAvatar::rezStatusToString(i)); + } + if (rez_status == 3) + { + // "fully loaded", mark any pending appearance change complete. + selfStopPhase("update_appearance_from_cof"); + selfStopPhase("wear_inventory_category", false); + selfStopPhase("process_initial_wearables_update", false); + } } - // Non-cloud-or-gray to cloud-or-gray - if (is_cloud_or_gray && !was_cloud_or_gray) - { - // start cloud-or-gray timer. - startPhase("cloud-or-gray"); - } - else if (was_cloud_or_gray && !is_cloud_or_gray) - { - // stop cloud-or-gray timer, which will capture stats. - stopPhase("cloud-or-gray"); - } - mLastRezzedStatus = rez_status; } } @@ -6882,9 +6941,50 @@ void LLVOAvatar::clearPhases() void LLVOAvatar::startPhase(const std::string& phase_name) { + F32 elapsed; + bool completed; + if (getPhases().getPhaseValues(phase_name, elapsed, completed)) + { + if (!completed) + { + LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << llendl; + return; + } + } + LL_DEBUGS("Avatar") << "started phase " << phase_name << llendl; getPhases().startPhase(phase_name); } +void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check) +{ + F32 elapsed; + bool completed; + if (getPhases().getPhaseValues(phase_name, elapsed, completed)) + { + if (!completed) + { + getPhases().stopPhase(phase_name); + completed = true; + logMetricsTimerRecord(phase_name, elapsed, completed); + LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << llendl; + } + else + { + if (err_check) + { + LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << llendl; + } + } + } + else + { + if (err_check) + { + LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << llendl; + } + } +} + void LLVOAvatar::logPendingPhases() { for (LLViewerStats::phase_map_t::iterator it = getPhases().begin(); @@ -6900,10 +7000,6 @@ void LLVOAvatar::logPendingPhases() { logMetricsTimerRecord(phase_name, elapsed, completed); } - else - { - llwarns << "ignoring " << phase_name << llendl; - } } } } @@ -6927,7 +7023,6 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse { LLSD record; record["timer_name"] = phase_name; - record["agent_id"] = gAgent.getID(); record["avatar_id"] = getID(); record["elapsed"] = elapsed; record["completed"] = completed; @@ -6943,9 +7038,11 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse record["is_self"] = isSelf(); +#if 0 // verbose logging std::ostringstream ostr; ostr << LLSDNotationStreamer(record); LL_DEBUGS("Avatar") << "record\n" << ostr.str() << llendl; +#endif if (isAgentAvatarValid()) { @@ -6953,30 +7050,6 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse } } -void LLVOAvatar::stopPhase(const std::string& phase_name) -{ - F32 elapsed; - bool completed; - if (getPhases().getPhaseValues(phase_name, elapsed, completed)) - { - if (!completed) - { - getPhases().stopPhase(phase_name); - completed = true; - - } - else - { - llwarns << "stop when stopped already for " << phase_name << llendl; - } - logMetricsTimerRecord(phase_name, elapsed, completed); - } - else - { - llwarns << "stop when not started for " << phase_name << llendl; - } -} - // call periodically to keep isFullyLoaded up to date. // returns true if the value has changed. BOOL LLVOAvatar::updateIsFullyLoaded() @@ -7199,7 +7272,8 @@ void LLVOAvatar::updateMeshTextures() #ifndef LL_RELEASE_FOR_DOWNLOAD LLViewerFetchedTexture* existing_baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID); #endif - const std::string url = getImageURL(i, mBakedTextureDatas[i].mLastTextureID); + ETextureIndex te = ETextureIndex(mBakedTextureDatas[i].mTextureIndex); + const std::string url = getImageURL(te, mBakedTextureDatas[i].mLastTextureID); if (!url.empty()) { baked_img = LLViewerTextureManager::getFetchedTextureFromUrl(url, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, mBakedTextureDatas[i].mLastTextureID); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 1adf59ce8..5ceeee92b 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -178,14 +178,14 @@ public: void updateLODRiggedAttachments( void ); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. S32 totalTextureMemForUUIDS(std::set& ids); - bool allTexturesCompletelyDownloaded(std::set& ids); - bool allLocalTexturesCompletelyDownloaded(); - bool allBakedTexturesCompletelyDownloaded(); + bool allTexturesCompletelyDownloaded(std::set& ids) const; + bool allLocalTexturesCompletelyDownloaded() const; + bool allBakedTexturesCompletelyDownloaded() const; void bakedTextureOriginCounts(S32 &sb_count, S32 &host_count, S32 &both_count, S32 &neither_count); std::string bakedTextureOriginInfo(); - void collectLocalTextureUUIDs(std::set& ids); - void collectBakedTextureUUIDs(std::set& ids); + void collectLocalTextureUUIDs(std::set& ids) const; + void collectBakedTextureUUIDs(std::set& ids) const; void collectTextureUUIDs(std::set& ids); void releaseOldTextures(); /*virtual*/ void updateTextures(); @@ -331,7 +331,7 @@ public: virtual BOOL getIsCloud() const; BOOL isFullyTextured() const; BOOL hasGray() const; - S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = fully textured. + S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded. void updateRezzedStatusTimers(); bool isLangolier() const { return mFreezeTimeLangolier; } bool isFrozenDead() const { return mFreezeTimeDead; } @@ -340,7 +340,7 @@ public: void startPhase(const std::string& phase_name); - void stopPhase(const std::string& phase_name); + void stopPhase(const std::string& phase_name, bool err_check = true); void clearPhases(); void logPendingPhases(); static void logPendingPhasesAllAvatars(); @@ -364,24 +364,6 @@ private: bool mFreezeTimeLangolier; // True when this avatar was created during snapshot FreezeTime mode, and that mode is still active. bool mFreezeTimeDead; // True when the avatar was marked dead (ie, TP-ed away) while in FreezeTime mode. -public: - class ScopedPhaseSetter - { - public: - ScopedPhaseSetter(LLVOAvatar *avatarp, std::string phase_name): - mAvatar(avatarp), mPhaseName(phase_name) - { - if (mAvatar) { mAvatar->getPhases().startPhase(mPhaseName); } - } - ~ScopedPhaseSetter() - { - if (mAvatar) { mAvatar->getPhases().stopPhase(mPhaseName); } - } - private: - std::string mPhaseName; - LLVOAvatar* mAvatar; - }; - private: LLViewerStats::PhaseMap mPhases; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 590829858..eb8cec7dc 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -92,11 +92,11 @@ void selfStartPhase(const std::string& phase_name) } } -void selfStopPhase(const std::string& phase_name) +void selfStopPhase(const std::string& phase_name, bool err_check) { if (isAgentAvatarValid()) { - gAgentAvatarp->stopPhase(phase_name); + gAgentAvatarp->stopPhase(phase_name, err_check); } } @@ -105,7 +105,6 @@ void selfClearPhases() if (isAgentAvatarValid()) { gAgentAvatarp->clearPhases(); - gAgentAvatarp->mLastRezzedStatus = -1; } } @@ -189,6 +188,30 @@ bool output_self_av_texture_diagnostics() return false; } +bool update_avatar_rez_metrics() +{ + if (!isAgentAvatarValid()) + return true; + + gAgentAvatarp->updateAvatarRezMetrics(false); + return false; +} + +bool check_for_unsupported_baked_appearance() +{ + if (!isAgentAvatarValid()) + return true; + + gAgentAvatarp->checkForUnsupportedServerBakeAppearance(); + return false; +} + +void force_bake_all_textures() +{ + if (isAgentAvatarValid()) + gAgentAvatarp->forceBakeAllTextures(true); +} + void LLVOAvatarSelf::initInstance() { BOOL status = TRUE; @@ -228,7 +251,8 @@ void LLVOAvatarSelf::initInstance() } //doPeriodically(output_self_av_texture_diagnostics, 30.0); - doPeriodically(boost::bind(&LLVOAvatarSelf::updateAvatarRezMetrics, false), 5.0); + doPeriodically(update_avatar_rez_metrics, 5.0); + doPeriodically(check_for_unsupported_baked_appearance, 120.0); } // virtual @@ -1452,7 +1476,9 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) { - if (getLocalDiscardLevel(*local_tex_iter, wearable_index) > (S32)(desired_tex_discard_level)) + S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index); + if ((local_discard_level > (S32)(desired_tex_discard_level)) || + (local_discard_level < 0 )) { return FALSE; } @@ -2247,9 +2273,8 @@ private: bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send) { - //Can be called via event system after agent avatar has been removed. - //Also skip if quit has been requested, because we already send out rez metrics when entering the quit state. - if(!isAgentAvatarValid() || LLAppViewer::instance()->quitRequested()) + //Skip if quit has been requested, because we already send out rez metrics when entering the quit state. + if(LLAppViewer::instance()->quitRequested()) return false; const F32 AV_METRICS_INTERVAL_QA = 30.0; @@ -2259,13 +2284,17 @@ bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send) send_period = AV_METRICS_INTERVAL_QA; } - if (force_send || gAgentAvatarp->mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period) + if (force_send || mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period) { - // Stats for completed phases have been getting l ogged as they + // Stats for completed phases have been getting logged as they // complete. This will give us stats for any timers that // haven't finished as of the metric's being sent. - LLVOAvatar::logPendingPhasesAllAvatars(); - gAgentAvatarp->sendViewerAppearanceChangeMetrics(); + + if (force_send) + { + LLVOAvatar::logPendingPhasesAllAvatars(); + } + sendViewerAppearanceChangeMetrics(); } return false; @@ -2291,7 +2320,7 @@ bool operator<(const LLSD& a, const LLSD& b) // Given a vector of LLSD records, return an LLSD array of bucketed stats for val_field. LLSD summarize_by_buckets(std::vector in_records, std::vector by_fields, - std::string& val_field) + const std::string& val_field) { LLSD result = LLSD::emptyArray(); std::map accum; @@ -2348,10 +2377,9 @@ void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics() msg["nearby"][rez_status_name] = rez_counts[rez_stat]; } - // std::vector bucket_fields("timer_name","agent_id","is_self","grid_x","grid_y","is_using_server_bake"); + // std::vector bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake"); std::vector by_fields; by_fields.push_back("timer_name"); - by_fields.push_back("agent_id"); by_fields.push_back("completed"); by_fields.push_back("grid_x"); by_fields.push_back("grid_y"); @@ -2387,6 +2415,76 @@ void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics() } } +extern AIHTTPTimeoutPolicy checkAgentAppearanceServiceResponder_timeout; +class CheckAgentAppearanceServiceResponder: public LLHTTPClient::ResponderHeadersOnly +{ +public: + CheckAgentAppearanceServiceResponder() + { + } + + virtual ~CheckAgentAppearanceServiceResponder() + { + } + + /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + { + if (200 <= status && status < 300) + { + LL_DEBUGS("Avatar") << "status OK" << llendl; + } + else + { + if (isAgentAvatarValid()) + { + LL_DEBUGS("Avatar") << "failed, will rebake" << llendl; + forceAppearanceUpdate(); + } + } + } + + // Error + /*virtual*//* void error(U32 status, const std::string& reason) + { + if (isAgentAvatarValid()) + { + LL_DEBUGS("Avatar") << "failed, will rebake" << llendl; + forceAppearanceUpdate(); + } + } */ + + static void forceAppearanceUpdate() + { + // Trying to rebake immediately after crossing region boundary + // seems to be failure prone; adding a delay factor. Yes, this + // fix is ad-hoc and not guaranteed to work in all cases. + doAfterInterval(force_bake_all_textures, 5.0); + } + + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return checkAgentAppearanceServiceResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "CheckAgentAppearanceServiceResponder"; } +}; + +void LLVOAvatarSelf::checkForUnsupportedServerBakeAppearance() +{ + // Need to check only if we have a server baked appearance and are + // in a non-baking region. + if (!gAgentAvatarp->isUsingServerBakes()) + return; + if (!gAgent.getRegion() || gAgent.getRegion()->getCentralBakeVersion()!=0) + return; + + // if baked image service is unknown, need to refresh. + if (gSavedSettings.getString("AgentAppearanceServiceURL").empty()) + { + CheckAgentAppearanceServiceResponder::forceAppearanceUpdate(); + } + // query baked image service to check status. + std::string image_url = gAgentAvatarp->getImageURL(TEX_HEAD_BAKED, + getTE(TEX_HEAD_BAKED)->getID()); + LLHTTPClient::head(image_url, new CheckAgentAppearanceServiceResponder); +} + const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const { if (canGrabBakedTexture(baked_index)) diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index e7a59d1a3..c8c87c27b 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -380,7 +380,7 @@ public: }; LLTimer mTimeSinceLastRezMessage; - static bool updateAvatarRezMetrics(bool force_send); + bool updateAvatarRezMetrics(bool force_send); std::vector mPendingTimerRecords; void addMetricsTimerRecord(const LLSD& record); @@ -401,6 +401,7 @@ public: const std::string debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer const std::string debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD void sendViewerAppearanceChangeMetrics(); // send data associated with completing a change. + void checkForUnsupportedServerBakeAppearance(); private: LLFrameTimer mDebugSelfLoadTimer; F32 mDebugTimeWearablesLoaded; @@ -423,9 +424,7 @@ extern LLPointer gAgentAvatarp; BOOL isAgentAvatarValid(); void selfStartPhase(const std::string& phase_name); -void selfStopPhase(const std::string& phase_name); +void selfStopPhase(const std::string& phase_name, bool err_check = true); void selfClearPhases(); -void update_avatar_rez_metrics(bool force_send); - #endif // LL_VO_AVATARSELF_H diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 36c4ca309..eea72a9f7 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -473,7 +473,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, S32 vertex_count = 0; S32 i, x, y; - S32 num_vertices, num_indices; + S32 num_vertices; U32 render_stride = mLastStride; S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); @@ -491,7 +491,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, if (north_stride == render_stride) { num_vertices = 2 * length + 1; - num_indices = length * 6 - 3; facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f; @@ -542,7 +541,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, { // North stride is longer (has less vertices) num_vertices = length + length/2 + 1; - num_indices = half_length*9 - 3; facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f; @@ -601,7 +599,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, length = patch_size / north_stride; half_length = length / 2; num_vertices = length + half_length + 1; - num_indices = 9*half_length - 3; facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f; @@ -672,7 +669,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, { S32 i, x, y; - S32 num_vertices, num_indices; + S32 num_vertices; U32 render_stride = mLastStride; S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); @@ -685,7 +682,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, if (east_stride == render_stride) { num_vertices = 2 * length + 1; - num_indices = length * 6 - 3; facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f; @@ -734,7 +730,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, { // East stride is longer (has less vertices) num_vertices = length + half_length + 1; - num_indices = half_length*9 - 3; facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f; @@ -789,7 +784,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, length = patch_size / east_stride; half_length = length / 2; num_vertices = length + length/2 + 1; - num_indices = 9*(length/2) - 3; facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f; diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 5509f9ad9..a0c303bf9 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -728,8 +728,8 @@ void LLVOWLSky::updateStarColors() const F32 var = 0.15f; const F32 min = 0.5f; //0.75f; - const F32 sunclose_max = 0.6f; - const F32 sunclose_range = 1 - sunclose_max; + //const F32 sunclose_max = 0.6f; + //const F32 sunclose_range = 1 - sunclose_max; //F32 below_horizon = - llmin(0.0f, gSky.mVOSkyp->getToSunLast().mV[2]); //F32 brightness_factor = llmin(1.0f, below_horizon * 20); @@ -743,14 +743,14 @@ void LLVOWLSky::updateStarColors() U32 x; for (x = 0; x < getStarsNumVerts(); ++x) { - F32 sundir_factor = 1; + //F32 sundir_factor = 1; LLVector3 tostar = *v_p; tostar.normVec(); - const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast(); - if (how_close_to_sun > sunclose_max) - { - sundir_factor = (1 - how_close_to_sun) / sunclose_range; - } + //const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast(); + //if (how_close_to_sun > sunclose_max) + //{ + // sundir_factor = (1 - how_close_to_sun) / sunclose_range; + //} intensity = *(v_i); F32 alpha = v_c->mV[VALPHA] + (ll_frand() - 0.5f) * var * intensity; if (alpha < min * intensity) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index fff60e992..55ad60a5c 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1020,7 +1020,7 @@ void LLPipeline::createGLBuffers() { mGlow[i].bindTarget(); mGlow[i].clear(); - mGlow[i].unbindTarget(); + mGlow[i].flush(); } } @@ -6728,11 +6728,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGlowProgram.unbind(); - if (LLRenderTarget::sUseFBO) + /*if (LLRenderTarget::sUseFBO) { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); glBindFramebuffer(GL_FRAMEBUFFER, 0); - } + }*/ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; @@ -8414,8 +8414,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; - LLRenderTarget::unbindTarget(); - LLPipeline::sReflectionRender = FALSE; if (!LLRenderTarget::sUseFBO)