From 94a0040ddb3fa5bc3369ab832ec200f79d18ed4b Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 25 Feb 2013 12:53:18 -0600 Subject: [PATCH 1/9] Sunshine catchup. --- indra/llappearance/llwearable.cpp | 45 ++++--- indra/llappearance/llwearable.h | 1 + indra/llmessage/aihttptimeoutpolicy.cpp | 1 + indra/llprimitive/llprimitive.cpp | 1 + indra/newview/llagent.cpp | 16 +-- indra/newview/llappearancemgr.cpp | 7 + indra/newview/llappviewer.cpp | 2 +- indra/newview/lldrawable.cpp | 9 +- indra/newview/llviewerparcelmgr.cpp | 11 -- indra/newview/llvoavatar.cpp | 167 ++++++++++++++---------- indra/newview/llvoavatar.h | 32 +---- indra/newview/llvoavatarself.cpp | 128 +++++++++++++++--- indra/newview/llvoavatarself.h | 7 +- indra/newview/llvosurfacepatch.cpp | 10 +- indra/newview/llvowlsky.cpp | 16 +-- 15 files changed, 281 insertions(+), 172 deletions(-) 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) From 34cf0329ab3e92372e9643834fe27ec089bd8716 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 25 Feb 2013 12:55:50 -0600 Subject: [PATCH 2/9] Crahfix for avatars, as destruction can be delayed via llpointer refs, meaning the region the av was in could be long gone before the avs destructor is actually called. Calling logPendingPhases in a more reasonable place (markDead). --- indra/newview/llvoavatar.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 6e5a27a9a..dbee3884b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1120,7 +1120,7 @@ LLVOAvatar::~LLVOAvatar() } } - logPendingPhases(); + //logPendingPhases(); lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl; @@ -1156,7 +1156,12 @@ void LLVOAvatar::markDead() } mVoiceVisualizer->markDead(); LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; + + if(!isDead()) + logPendingPhases(); + LLViewerObject::markDead(); + } From fd21197d2a48c4225e048fe025ca19a9224f4c4c Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 25 Feb 2013 12:59:17 -0600 Subject: [PATCH 3/9] Wedged high-res non-tiled deferred snapshot logic into LLViewerWindow::rawRawSnapshot --- indra/llrender/llrendertarget.cpp | 61 ++++++++++++++++++------------- indra/llrender/llrendertarget.h | 5 +-- indra/newview/llviewerwindow.cpp | 49 +++++++++++++++++++++++-- indra/newview/pipeline.cpp | 8 ++-- 4 files changed, 85 insertions(+), 38 deletions(-) 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/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b44870e21..ce337fce0 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 @@ -4406,7 +4436,7 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw, image_buffer_x = llround(snapshot_width * scale_factor); image_buffer_y = llround(snapshot_height * scale_factor); if (llmax(image_buffer_x, image_buffer_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; @@ -4414,6 +4444,8 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw, // Done. break; } + + // Center the buffer. buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f); buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f); @@ -4577,6 +4609,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/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) From e187e642c00ea6737507861386ea903cfd5c1c6f Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 25 Feb 2013 13:00:07 -0600 Subject: [PATCH 4/9] Restored some RLVa shownames logic that was clobbered a while ago. --- indra/newview/llvoavatar.cpp | 52 +++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index dbee3884b..9b87e221e 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2944,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; @@ -3082,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(); @@ -3094,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(); @@ -3177,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(); @@ -3205,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) { @@ -3225,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); From d27b329afb77872027ffcfb34d07f2acaf64d0b4 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 25 Feb 2013 13:02:22 -0600 Subject: [PATCH 5/9] Minor bit of cleanup. Also now using glTexGenf instead of glTexGeni for fixed-function water texcoords. --- indra/llcommon/llmemtype.h | 1 - indra/newview/lldrawable.h | 1 - indra/newview/lldrawpoolwater.cpp | 4 ++-- indra/newview/llviewerobject.h | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) 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/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/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;} From e2659b801a4528fe4d92360e5a867f3ab00e7882 Mon Sep 17 00:00:00 2001 From: Siana Gearz Date: Mon, 25 Feb 2013 23:58:43 +0100 Subject: [PATCH 6/9] Dirty fix object import --- indra/newview/llselectmgr.h | 2 ++ indra/newview/llviewerobjectbackup.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) 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/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); } From a4b49e3fc2eaef5d22428961fd4a80aba2276903 Mon Sep 17 00:00:00 2001 From: Siana Gearz Date: Tue, 26 Feb 2013 00:00:45 +0100 Subject: [PATCH 7/9] Random stab at object updates. Tell me if it breaks anything. --- indra/newview/lldrawable.cpp | 40 +++++++++--------------------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 7d133fa72..451b9ae50 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -545,38 +545,18 @@ 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 +646,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 +681,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(); } From 6ee8cc5798a4157c28544ab4065d44363959e5b4 Mon Sep 17 00:00:00 2001 From: Siana Gearz Date: Tue, 26 Feb 2013 20:47:43 +0100 Subject: [PATCH 8/9] Unbreak skinning on low end hardware --- .../newview/app_settings/shaders/class1/avatar/objectSkinV.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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() { From c9ab38d449be8516e8efb2b4b33245f066371fdd Mon Sep 17 00:00:00 2001 From: Siana Gearz Date: Tue, 26 Feb 2013 23:13:39 +0100 Subject: [PATCH 9/9] Stream frequency change support and new anti-starvation strategy --- indra/llaudio/llstreamingaudio_fmodex.cpp | 23 +++++++++++++--------- indra/llaudio/llstreamingaudio_fmodex.h | 2 -- indra/newview/app_settings/settings_sh.xml | 4 ++-- 3 files changed, 16 insertions(+), 13 deletions(-) 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/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