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/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index da2a38250..cbd044c77 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/newview/llagent.cpp b/indra/newview/llagent.cpp index da48f89c8..af9bb1dc2 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 96e2503d5..af9e0032a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3158,7 +3158,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 e0df21bb3..efccfb812 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -547,9 +547,12 @@ 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); + // The following fixes MAINT-1742 but breaks vehicles similar to MAINT-2275 + // dist_squared = dist_vec_squared(old_pos, target_pos); + + // The following fixes MAINT-2247 but causes MAINT-2275 + //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; 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/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1ac12e15c..6e5a27a9a 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()); @@ -1217,6 +1220,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 +1276,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 +1294,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 +2217,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 +2237,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); } @@ -3567,7 +3569,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 +4720,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 +4733,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 +4815,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 +4841,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 +4877,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 +5167,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 +6839,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 +6892,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 +6951,6 @@ void LLVOAvatar::logPendingPhases() { logMetricsTimerRecord(phase_name, elapsed, completed); } - else - { - llwarns << "ignoring " << phase_name << llendl; - } } } } @@ -6927,7 +6974,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 +6989,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 +7001,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 +7223,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 a4ab27f8a..bad259ac6 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"); @@ -2386,6 +2414,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)