From e4a0dda457039b1a04c74024d9fbcf02e071b13d Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 28 Jun 2012 14:24:04 -0400 Subject: SH-3228 WIP - always respond to processAppearance for self, convert baked textures to checkerboards --- indra/llprimitive/llprimitive.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'indra/llprimitive/llprimitive.cpp') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 30532247ac..c766d8a43c 100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -39,6 +39,7 @@ #include "lldatapacker.h" #include "llsdutil_math.h" #include "llprimtexturelist.h" +#include "imageids.h" /** * exported constants @@ -1227,12 +1228,12 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const return FALSE; } -S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name) +S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, bool fake_images) { - return(unpackTEMessage(mesgsys,block_name,-1)); + return(unpackTEMessage(mesgsys,block_name,-1,fake_images)); } -S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num) +S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images) { // use a negative block_num to indicate a single-block read (a non-variable block) S32 retval = 0; @@ -1307,7 +1308,15 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam LLColor4U coloru; for (U32 i = 0; i < face_count; i++) { - retval |= setTETexture(i, ((LLUUID*)image_data)[i]); + LLUUID& req_id = ((LLUUID*)image_data)[i]; + if (fake_images & (req_id != IMG_DEFAULT) && (req_id != IMG_DEFAULT_AVATAR) && (req_id != IMG_INVISIBLE)) + { + retval |= setTETexture(i, IMG_CHECKERBOARD_RGBA); + } + else + { + retval |= setTETexture(i, req_id); + } retval |= setTEScale(i, scale_s[i], scale_t[i]); retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF); retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); -- cgit v1.3 From 27c7b259b417d5843422e8bd4e8e480a186e44f4 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 12 Jul 2012 18:24:23 -0400 Subject: SH-3267 WIP --- indra/llprimitive/llprimitive.cpp | 107 +++++++++++++++++++++++++++++++++++++- indra/llprimitive/llprimitive.h | 31 ++++++++++- indra/newview/llappearancemgr.cpp | 8 ++- indra/newview/llappearancemgr.h | 2 + indra/newview/llvoavatar.cpp | 20 ++++++- 5 files changed, 162 insertions(+), 6 deletions(-) (limited to 'indra/llprimitive/llprimitive.cpp') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index c766d8a43c..0388e2c020 100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1228,11 +1228,113 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const return FALSE; } -S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, bool fake_images) +S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images, + LLTEContents& tec) { - return(unpackTEMessage(mesgsys,block_name,-1,fake_images)); + tec.fake_images = fake_images; + + S32 retval = 0; + + if (block_num < 0) + { + tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry); + } + else + { + tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry); + } + + if (tec.size == 0) + { + return retval; + } + + if (block_num < 0) + { + mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, 0, LLTEContents::MAX_TE_BUFFER); + } + else + { + mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER); + } + + tec.face_count = getNumTEs(); + + U8 *cur_ptr = tec.packed_buffer; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID); + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.colors, 4, tec.face_count, MVT_U8); + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_s, 4, tec.face_count, MVT_F32); + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_t, 4, tec.face_count, MVT_F32); + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_s, 2, tec.face_count, MVT_S16Array); + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_t, 2, tec.face_count, MVT_S16Array); + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_rot, 2, tec.face_count, MVT_S16Array); + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.bump, 1, tec.face_count, MVT_U8); + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.media_flags, 1, tec.face_count, MVT_U8); + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8); + + retval = 1; + return retval; +} + +S32 LLPrimitive::unpackParsedTEMessage(LLTEContents& tec) +{ + S32 retval = 0; + + LLColor4 color; + LLColor4U coloru; + for (U32 i = 0; i < tec.face_count; i++) + { + LLUUID& req_id = ((LLUUID*)tec.image_data)[i]; + if (tec.fake_images & (req_id != IMG_DEFAULT) && (req_id != IMG_DEFAULT_AVATAR) && (req_id != IMG_INVISIBLE)) + { + retval |= setTETexture(i, IMG_CHECKERBOARD_RGBA); + } + else + { + retval |= setTETexture(i, req_id); + } + retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]); + retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF); + retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); + retval |= setTEBumpShinyFullbright(i, tec.bump[i]); + retval |= setTEMediaTexGen(i, tec.media_flags[i]); + retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF); + coloru = LLColor4U(tec.colors + 4*i); + + // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) + // as all zeros. However, the subtraction and addition must be done in unsigned + // byte space, not in float space, otherwise off-by-one errors occur. JC + color.mV[VRED] = F32(255 - coloru.mV[VRED]) / 255.f; + color.mV[VGREEN] = F32(255 - coloru.mV[VGREEN]) / 255.f; + color.mV[VBLUE] = F32(255 - coloru.mV[VBLUE]) / 255.f; + color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f; + + retval |= setTEColor(i, color); + + } + + return retval; +} + +S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images) +{ + LLTEContents tec; + S32 retval = parseTEMessage(mesgsys, block_name, block_num, fake_images, tec); + if (!retval) + return retval; + return unpackParsedTEMessage(tec); } +#if 0 S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images) { // use a negative block_num to indicate a single-block read (a non-variable block) @@ -1339,6 +1441,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam return retval; } +#endif S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) { diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 1e985221c0..19ef3faf3f 100755 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -289,6 +289,34 @@ public: }; +struct LLTEContents +{ + LLTEContents() + { + } + + static const U32 MAX_TES = 32; + + U8 image_data[MAX_TES*16]; + U8 colors[MAX_TES*4]; + F32 scale_s[MAX_TES]; + F32 scale_t[MAX_TES]; + S16 offset_s[MAX_TES]; + S16 offset_t[MAX_TES]; + S16 image_rot[MAX_TES]; + U8 bump[MAX_TES]; + U8 media_flags[MAX_TES]; + U8 glow[MAX_TES]; + + static const U32 MAX_TE_BUFFER = 4096; + U8 packed_buffer[MAX_TE_BUFFER]; + + U32 size; + U32 face_count; + + bool fake_images; +}; + class LLPrimitive : public LLXform { public: @@ -360,9 +388,10 @@ public: S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type); BOOL packTEMessage(LLMessageSystem *mesgsys) const; BOOL packTEMessage(LLDataPacker &dp) const; - S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, bool fake_images = false); S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images = false); // Variable num of blocks BOOL unpackTEMessage(LLDataPacker &dp); + S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images,LLTEContents& tec); + S32 unpackParsedTEMessage(LLTEContents& tec); #ifdef CHECK_FOR_FINITE inline void setPosition(const LLVector3& pos); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 04c4220afd..eb31358000 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2623,8 +2623,11 @@ void LLAppearanceMgr::requestServerAppearanceUpdate() if (!url.empty()) { LLSD body; - body["cof_version"] = getCOFVersion(); + S32 cof_version = getCOFVersion(); + body["cof_version"] = cof_version; LLHTTPClient::post(url, body, new RequestAgentUpdateAppearanceResponder); + llassert(cof_version >= mLastUpdateRequestCOFVersion); + mLastUpdateRequestCOFVersion = cof_version; } else { @@ -2842,7 +2845,8 @@ LLAppearanceMgr::LLAppearanceMgr(): mAttachmentInvLinkEnabled(false), mOutfitIsDirty(false), mOutfitLocked(false), - mIsInUpdateAppearanceFromCOF(false) + mIsInUpdateAppearanceFromCOF(false), + mLastUpdateRequestCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) { LLOutfitObserver& outfit_observer = LLOutfitObserver::instance(); diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 954820c154..45291419c7 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -95,6 +95,8 @@ public: const LLUUID getCOF() const; S32 getCOFVersion() const; + S32 mLastUpdateRequestCOFVersion; + // Finds the folder link to the currently worn outfit const LLViewerInventoryItem *getBaseOutfitLink(); bool getBaseOutfitName(std::string &name); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 6bcb0c6882..f85b59b8c6 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7309,9 +7309,27 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl; // dumpAvatarTEs( "PRE processAvatarAppearance()" ); - unpackTEMessage(mesgsys, _PREHASH_ObjectData, FALSE); + LLTEContents tec; + parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, FALSE, tec); // dumpAvatarTEs( "POST processAvatarAppearance()" ); + // Check for stale update. + if (isSelf() && LLAppearanceMgr::instance().useServerTextureBaking()) + { + // Extract COF Version field hacked into local texture id. + LLUUID texture_id = ((LLUUID*)tec.image_data)[0]; + S32 last_update_request_cof_version = LLAppearanceMgr::instance().mLastUpdateRequestCOFVersion; + S32 *s_words = (S32*) texture_id.mData; + S32 this_update_cof_version = s_words[0]; + if (this_update_cof_version < last_update_request_cof_version) + { + llwarns << "Stale appearance update, wanted version " << last_update_request_cof_version + << ", got " << this_update_cof_version << llendl; + return; + } + } + unpackParsedTEMessage(tec); + // prevent the overwriting of valid baked textures with invalid baked textures for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++) { -- cgit v1.3 From 409be9dcc4e372385f0fb0de274a4b17913bd124 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 13 Jul 2012 16:59:57 -0400 Subject: SH-3267 WIP - extract cof version from avatar appearance message, use to reject stale updates --- indra/llprimitive/llprimitive.cpp | 131 ++------------------------------------ indra/llprimitive/llprimitive.h | 18 +++--- indra/newview/llappearancemgr.cpp | 20 +++--- indra/newview/llvoavatar.cpp | 8 ++- 4 files changed, 31 insertions(+), 146 deletions(-) (limited to 'indra/llprimitive/llprimitive.cpp') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 0388e2c020..97a382634a 100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1228,11 +1228,8 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const return FALSE; } -S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images, - LLTEContents& tec) +S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec) { - tec.fake_images = fake_images; - S32 retval = 0; if (block_num < 0) @@ -1285,7 +1282,7 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name return retval; } -S32 LLPrimitive::unpackParsedTEMessage(LLTEContents& tec) +S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec) { S32 retval = 0; @@ -1294,14 +1291,7 @@ S32 LLPrimitive::unpackParsedTEMessage(LLTEContents& tec) for (U32 i = 0; i < tec.face_count; i++) { LLUUID& req_id = ((LLUUID*)tec.image_data)[i]; - if (tec.fake_images & (req_id != IMG_DEFAULT) && (req_id != IMG_DEFAULT_AVATAR) && (req_id != IMG_INVISIBLE)) - { - retval |= setTETexture(i, IMG_CHECKERBOARD_RGBA); - } - else - { - retval |= setTETexture(i, req_id); - } + retval |= setTETexture(i, req_id); retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]); retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF); retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); @@ -1325,123 +1315,14 @@ S32 LLPrimitive::unpackParsedTEMessage(LLTEContents& tec) return retval; } -S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images) +S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num) { LLTEContents tec; - S32 retval = parseTEMessage(mesgsys, block_name, block_num, fake_images, tec); + S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec); if (!retval) return retval; - return unpackParsedTEMessage(tec); -} - -#if 0 -S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images) -{ - // use a negative block_num to indicate a single-block read (a non-variable block) - S32 retval = 0; - const U32 MAX_TES = 32; - - // Avoid construction of 32 UUIDs per call. JC - - U8 image_data[MAX_TES*16]; - U8 colors[MAX_TES*4]; - F32 scale_s[MAX_TES]; - F32 scale_t[MAX_TES]; - S16 offset_s[MAX_TES]; - S16 offset_t[MAX_TES]; - S16 image_rot[MAX_TES]; - U8 bump[MAX_TES]; - U8 media_flags[MAX_TES]; - U8 glow[MAX_TES]; - - const U32 MAX_TE_BUFFER = 4096; - U8 packed_buffer[MAX_TE_BUFFER]; - U8 *cur_ptr = packed_buffer; - - U32 size; - U32 face_count = 0; - - if (block_num < 0) - { - size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry); - } - else - { - size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry); - } - - if (size == 0) - { - return retval; - } - - if (block_num < 0) - { - mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, 0, MAX_TE_BUFFER); - } - else - { - mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, block_num, MAX_TE_BUFFER); - } - - face_count = getNumTEs(); - - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID); - cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8); - cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32); - cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32); - cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array); - cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array); - cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array); - cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8); - cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8); - cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8); - - LLColor4 color; - LLColor4U coloru; - for (U32 i = 0; i < face_count; i++) - { - LLUUID& req_id = ((LLUUID*)image_data)[i]; - if (fake_images & (req_id != IMG_DEFAULT) && (req_id != IMG_DEFAULT_AVATAR) && (req_id != IMG_INVISIBLE)) - { - retval |= setTETexture(i, IMG_CHECKERBOARD_RGBA); - } - else - { - retval |= setTETexture(i, req_id); - } - retval |= setTEScale(i, scale_s[i], scale_t[i]); - retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF); - retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); - retval |= setTEBumpShinyFullbright(i, bump[i]); - retval |= setTEMediaTexGen(i, media_flags[i]); - retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); - coloru = LLColor4U(colors + 4*i); - - // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) - // as all zeros. However, the subtraction and addition must be done in unsigned - // byte space, not in float space, otherwise off-by-one errors occur. JC - color.mV[VRED] = F32(255 - coloru.mV[VRED]) / 255.f; - color.mV[VGREEN] = F32(255 - coloru.mV[VGREEN]) / 255.f; - color.mV[VBLUE] = F32(255 - coloru.mV[VBLUE]) / 255.f; - color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f; - - retval |= setTEColor(i, color); - - } - - return retval; + return applyParsedTEMessage(tec); } -#endif S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) { diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 19ef3faf3f..d9333140a3 100755 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -289,12 +289,14 @@ public: }; +// This code is not naming-standards compliant. Leaving it like this for +// now to make the connection to code in +// BOOL packTEMessage(LLDataPacker &dp) const; +// more obvious. This should be refactored to remove the duplication, at which +// point we can fix the names as well. +// - Vir struct LLTEContents { - LLTEContents() - { - } - static const U32 MAX_TES = 32; U8 image_data[MAX_TES*16]; @@ -313,8 +315,6 @@ struct LLTEContents U32 size; U32 face_count; - - bool fake_images; }; class LLPrimitive : public LLXform @@ -388,10 +388,10 @@ public: S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type); BOOL packTEMessage(LLMessageSystem *mesgsys) const; BOOL packTEMessage(LLDataPacker &dp) const; - S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images = false); // Variable num of blocks + S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks BOOL unpackTEMessage(LLDataPacker &dp); - S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, bool fake_images,LLTEContents& tec); - S32 unpackParsedTEMessage(LLTEContents& tec); + S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec); + S32 applyParsedTEMessage(LLTEContents& tec); #ifdef CHECK_FOR_FINITE inline void setPosition(const LLVector3& pos); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index eb31358000..e27a21f7fd 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2619,20 +2619,22 @@ public: void LLAppearanceMgr::requestServerAppearanceUpdate() { - std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance"); - if (!url.empty()) + if (!gAgent.getRegion()) { - LLSD body; - S32 cof_version = getCOFVersion(); - body["cof_version"] = cof_version; - LLHTTPClient::post(url, body, new RequestAgentUpdateAppearanceResponder); - llassert(cof_version >= mLastUpdateRequestCOFVersion); - mLastUpdateRequestCOFVersion = cof_version; + llwarns << "Region not set, cannot request server appearance update" << llendl; } - else + std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance"); + if (url.empty()) { llwarns << "no cap for UpdateAvatarAppearance" << llendl; } + + LLSD body; + S32 cof_version = getCOFVersion(); + body["cof_version"] = cof_version; + LLHTTPClient::post(url, body, new RequestAgentUpdateAppearanceResponder); + llassert(cof_version >= mLastUpdateRequestCOFVersion); + mLastUpdateRequestCOFVersion = cof_version; } class LLShowCreatedOutfit: public LLInventoryCallback diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f85b59b8c6..e686948fa2 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7310,7 +7310,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl; // dumpAvatarTEs( "PRE processAvatarAppearance()" ); LLTEContents tec; - parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, FALSE, tec); + parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, tec); // dumpAvatarTEs( "POST processAvatarAppearance()" ); // Check for stale update. @@ -7321,14 +7321,16 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) S32 last_update_request_cof_version = LLAppearanceMgr::instance().mLastUpdateRequestCOFVersion; S32 *s_words = (S32*) texture_id.mData; S32 this_update_cof_version = s_words[0]; - if (this_update_cof_version < last_update_request_cof_version) + if ((this_update_cof_version > 0) && + (this_update_cof_version < last_update_request_cof_version)) { llwarns << "Stale appearance update, wanted version " << last_update_request_cof_version << ", got " << this_update_cof_version << llendl; return; } + ((LLUUID*)tec.image_data)[0].setNull(); } - unpackParsedTEMessage(tec); + applyParsedTEMessage(tec); // prevent the overwriting of valid baked textures with invalid baked textures for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++) -- cgit v1.3 From 72dfb2abce5d5635e7f81436d65c8689d161eb37 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 13 Feb 2013 17:28:05 -0500 Subject: SH-3812 WIP, SH-3852 WIP - some metrics cleanup, added rebake when needed and sb system is unavailable, to avoid stale appearance problems --- indra/llprimitive/llprimitive.cpp | 1 + indra/newview/llagent.cpp | 16 +++++--- indra/newview/llagentwearables.cpp | 1 - indra/newview/llvoavatar.cpp | 61 +++++++++++----------------- indra/newview/llvoavatar.h | 20 +--------- indra/newview/llvoavatarself.cpp | 81 ++++++++++++++++++++++++++++++++++++-- indra/newview/llvoavatarself.h | 5 +-- 7 files changed, 114 insertions(+), 71 deletions(-) mode change 100644 => 100755 indra/llprimitive/llprimitive.cpp (limited to 'indra/llprimitive/llprimitive.cpp') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp old mode 100644 new mode 100755 index 4e36723eec..faf98883d9 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1246,6 +1246,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 d10f76ea55..e15c1a5104 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -812,6 +812,8 @@ void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id) { llinfos << "called" << llendl; + + // Old-style appearance entering a server-bake region. if (isAgentAvatarValid() && !gAgentAvatarp->isUsingServerBakes() && (mRegionp->getCentralBakeVersion()>0)) @@ -819,6 +821,14 @@ 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(); + } } //----------------------------------------------------------------------------- @@ -4335,12 +4345,6 @@ void LLAgent::sendAgentSetAppearance() return; } - if (!gAgentWearables.changeInProgress()) - { - // Change is fully resolved, can close some open phases. - gAgentAvatarp->stopPhase("process_initial_wearables_update"); - } - 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/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 0c79ac0ba3..ba04991a02 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -796,7 +796,6 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs if (isAgentAvatarValid()) { - //gAgentAvatarp->clearPhases(); // reset phase timers for outfit loading. gAgentAvatarp->startPhase("process_initial_wearables_update"); gAgentAvatarp->outputRezTiming("Received initial wearables update"); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 20d598d35b..5b4d57986b 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4456,6 +4456,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()) { @@ -5872,43 +5873,15 @@ BOOL LLVOAvatar::getIsCloud() const void LLVOAvatar::updateRezzedStatusTimers() { - // 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 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; -#if 0 - 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) - { - // start cloud timer. - startPhase("cloud"); - } - else if (was_cloud && !is_cloud) - { - // stop cloud timer, which will capture stats. - stopPhase("cloud"); - } - - // 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"); - } -#endif if (mLastRezzedStatus == -1 && rez_status != -1) { @@ -5937,7 +5910,8 @@ void LLVOAvatar::updateRezzedStatusTimers() { // "fully loaded", mark any pending appearance change complete. selfStopPhase("update_appearance_from_cof"); - selfStopPhase("wear_inventory_category"); + selfStopPhase("wear_inventory_category", false); + selfStopPhase("process_initial_wearables_update", false); } } @@ -5958,7 +5932,7 @@ void LLVOAvatar::startPhase(const std::string& phase_name) { if (!completed) { - LL_DEBUGS("Avatar") << "start when started already for " << phase_name << llendl; + LL_DEBUGS("Avatar") << "no-op, start when started already for " << phase_name << llendl; return; } } @@ -5966,7 +5940,7 @@ void LLVOAvatar::startPhase(const std::string& phase_name) getPhases().startPhase(phase_name); } -void LLVOAvatar::stopPhase(const std::string& phase_name) +void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check) { F32 elapsed; bool completed; @@ -5974,19 +5948,25 @@ void LLVOAvatar::stopPhase(const std::string& phase_name) { if (!completed) { - LL_DEBUGS("Avatar") << "stopped phase " << phase_name << llendl; getPhases().stopPhase(phase_name); completed = true; logMetricsTimerRecord(phase_name, elapsed, completed); + LL_DEBUGS("Avatar") << "stopped phase " << phase_name << " elapsed " << elapsed << llendl; } else { - LL_DEBUGS("Avatar") << "stop when stopped already for " << phase_name << llendl; + if (err_check) + { + LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << llendl; + } } } else { - LL_DEBUGS("Avatar") << "stop when not started for " << phase_name << llendl; + if (err_check) + { + LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << llendl; + } } } @@ -6043,9 +6023,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()) { @@ -6264,7 +6246,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 c8915383ca..c989673cdf 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -294,7 +294,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(); @@ -316,24 +316,6 @@ private: LLFrameTimer mFullyLoadedTimer; LLFrameTimer mRuthTimer; -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 e30d62869f..2775c9442a 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -86,11 +86,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); } } @@ -179,6 +179,24 @@ 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 LLVOAvatarSelf::initInstance() { BOOL status = TRUE; @@ -214,7 +232,8 @@ void LLVOAvatarSelf::initInstance() } //doPeriodically(output_self_av_texture_diagnostics, 30.0); - doPeriodically(boost::bind(&LLVOAvatarSelf::updateAvatarRezMetrics, this, false), 5.0); + doPeriodically(update_avatar_rez_metrics, 5.0); + doPeriodically(check_for_unsupported_baked_appearance, 120.0); } // virtual @@ -2371,6 +2390,62 @@ void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics() } } +class CheckAgentAppearanceServiceResponder: public LLHTTPClient::Responder +{ +public: + CheckAgentAppearanceServiceResponder() + { + } + + virtual ~CheckAgentAppearanceServiceResponder() + { + } + + /* virtual */ void result(const LLSD& content) + { + LL_DEBUGS("Avatar") << "status OK" << llendl; + } + + // 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(boost::bind(&LLVOAvatarSelf::forceBakeAllTextures, + gAgentAvatarp.get(), true), 5.0); + } +}; + +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 04b0fb760c..78728cff20 100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -402,6 +402,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; @@ -421,9 +422,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 -- cgit v1.3 From 354ccc1640dd223ccea20908183cc05a00ecaf6f Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 15 Feb 2013 13:44:21 -0500 Subject: additional safety check for bad appearance messages --- indra/llprimitive/llprimitive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llprimitive/llprimitive.cpp') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index faf98883d9..cf6a3f97d2 100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1259,7 +1259,7 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER); } - tec.face_count = getNumTEs(); + tec.face_count = llmin((U32)getNumTEs(),LLTEContents::MAX_TES); U8 *cur_ptr = tec.packed_buffer; cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID); -- cgit v1.3 From 998c31ef9e0631eefe07e4e678032ee90c56c859 Mon Sep 17 00:00:00 2001 From: Nyx Linden Date: Tue, 26 Feb 2013 15:29:23 -0500 Subject: BUILDFIX fixing undefined reference in build --- indra/llprimitive/llprimitive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llprimitive/llprimitive.cpp') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index cf6a3f97d2..c340fc2d35 100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1259,7 +1259,7 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER); } - tec.face_count = llmin((U32)getNumTEs(),LLTEContents::MAX_TES); + tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES); U8 *cur_ptr = tec.packed_buffer; cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID); -- cgit v1.3