summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xindra/llprimitive/llprimitive.cpp110
-rwxr-xr-xindra/llprimitive/llprimitive.h33
-rwxr-xr-xindra/newview/llappearancemgr.cpp31
-rwxr-xr-xindra/newview/llappearancemgr.h3
-rwxr-xr-xindra/newview/llvoavatar.cpp22
5 files changed, 127 insertions, 72 deletions
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index c766d8a43c..97a382634a 100755
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -1228,102 +1228,77 @@ 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, LLTEContents& tec)
{
- return(unpackTEMessage(mesgsys,block_name,-1,fake_images));
-}
-
-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);
+ tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
}
else
{
- size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
+ tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
}
- if (size == 0)
+ if (tec.size == 0)
{
return retval;
}
if (block_num < 0)
{
- mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, 0, MAX_TE_BUFFER);
+ mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, 0, LLTEContents::MAX_TE_BUFFER);
}
else
{
- mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, block_num, MAX_TE_BUFFER);
+ mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER);
}
- face_count = getNumTEs();
+ tec.face_count = getNumTEs();
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID);
+ 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, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8);
+ 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, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32);
+ 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, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32);
+ 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, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array);
+ 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, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array);
+ 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, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array);
+ 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, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8);
+ 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, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
+ 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, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
-
+ 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::applyParsedTEMessage(LLTEContents& tec)
+{
+ S32 retval = 0;
+
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);
+ for (U32 i = 0; i < tec.face_count; i++)
+ {
+ LLUUID& req_id = ((LLUUID*)tec.image_data)[i];
+ 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
@@ -1340,6 +1315,15 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam
return retval;
}
+S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num)
+{
+ LLTEContents tec;
+ S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec);
+ if (!retval)
+ return retval;
+ return applyParsedTEMessage(tec);
+}
+
S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
{
// use a negative block_num to indicate a single-block read (a non-variable block)
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 1e985221c0..d9333140a3 100755
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -289,6 +289,34 @@ 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
+{
+ 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;
+};
+
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
+ 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, 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 480a8e0d73..e27a21f7fd 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -925,6 +925,18 @@ const LLUUID LLAppearanceMgr::getCOF() const
return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
}
+S32 LLAppearanceMgr::getCOFVersion() const
+{
+ LLViewerInventoryCategory *cof = gInventory.getCategory(getCOF());
+ if (cof)
+ {
+ return cof->getVersion();
+ }
+ else
+ {
+ return LLViewerInventoryCategory::VERSION_UNKNOWN;
+ }
+}
const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()
{
@@ -2607,16 +2619,22 @@ public:
void LLAppearanceMgr::requestServerAppearanceUpdate()
{
- std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance");
- if (!url.empty())
+ if (!gAgent.getRegion())
{
- LLSD body;
- LLHTTPClient::post(url, body, new RequestAgentUpdateAppearanceResponder);
+ 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
@@ -2829,7 +2847,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 46457f1dce..45291419c7 100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -93,6 +93,9 @@ public:
// Find the Current Outfit folder.
const LLUUID getCOF() const;
+ S32 getCOFVersion() const;
+
+ S32 mLastUpdateRequestCOFVersion;
// Finds the folder link to the currently worn outfit
const LLViewerInventoryItem *getBaseOutfitLink();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 9c5998b976..236cc1b089 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -7318,9 +7318,29 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
// llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl;
// dumpAvatarTEs( "PRE processAvatarAppearance()" );
- unpackTEMessage(mesgsys, _PREHASH_ObjectData, FALSE);
+ LLTEContents tec;
+ parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, 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 > 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();
+ }
+ applyParsedTEMessage(tec);
+
// prevent the overwriting of valid baked textures with invalid baked textures
for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++)
{