summaryrefslogtreecommitdiff
path: root/indra/llprimitive/lltextureentry.cpp
diff options
context:
space:
mode:
authorMark Palange (Mani) <palange@lindenlab.com>2009-10-02 10:35:42 -0700
committerMark Palange (Mani) <palange@lindenlab.com>2009-10-02 10:35:42 -0700
commit4d53e235c2445b820bb0ae7303b269648dd86037 (patch)
treec1ab3643cf257099822e7a0e1e832d76813555f6 /indra/llprimitive/lltextureentry.cpp
parent80f27013b2d2a7ca6509db033c8f0c31562e04c7 (diff)
parentdde2153014cd7d7b8fa704f7067a41344bfbb1c2 (diff)
merge of latest viewer/viewer-20
Diffstat (limited to 'indra/llprimitive/lltextureentry.cpp')
-rw-r--r--indra/llprimitive/lltextureentry.cpp196
1 files changed, 193 insertions, 3 deletions
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 2736d54cc8..2c587554a2 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -32,13 +32,31 @@
#include "linden_common.h"
+#include "lluuid.h"
+#include "llmediaentry.h"
#include "lltextureentry.h"
#include "llsdutil_math.h"
+#include "v4color.h"
const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess
const LLTextureEntry LLTextureEntry::null;
+// Some LLSD keys. Do not change these!
+#define OBJECT_ID_KEY_STR "object_id"
+#define TEXTURE_INDEX_KEY_STR "texture_index"
+#define OBJECT_MEDIA_VERSION_KEY_STR "object_media_version"
+#define OBJECT_MEDIA_DATA_KEY_STR "object_media_data"
+#define TEXTURE_MEDIA_DATA_KEY_STR "media_data"
+
+/*static*/ const char* LLTextureEntry::OBJECT_ID_KEY = OBJECT_ID_KEY_STR;
+/*static*/ const char* LLTextureEntry::OBJECT_MEDIA_DATA_KEY = OBJECT_MEDIA_DATA_KEY_STR;
+/*static*/ const char* LLTextureEntry::MEDIA_VERSION_KEY = OBJECT_MEDIA_VERSION_KEY_STR;
+/*static*/ const char* LLTextureEntry::TEXTURE_INDEX_KEY = TEXTURE_INDEX_KEY_STR;
+/*static*/ const char* LLTextureEntry::TEXTURE_MEDIA_DATA_KEY = TEXTURE_MEDIA_DATA_KEY_STR;
+
+static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:";
+
// static
LLTextureEntry* LLTextureEntry::newTextureEntry()
{
@@ -47,16 +65,19 @@ LLTextureEntry* LLTextureEntry::newTextureEntry()
//===============================================================
LLTextureEntry::LLTextureEntry()
+ : mMediaEntry(NULL)
{
init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
+ : mMediaEntry(NULL)
{
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
+ : mMediaEntry(NULL)
{
mID = rhs.mID;
mScaleS = rhs.mScaleS;
@@ -68,6 +89,10 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
+ if (rhs.mMediaEntry != NULL) {
+ // Make a copy
+ mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
+ }
}
LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
@@ -84,6 +109,16 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
+ if (mMediaEntry != NULL) {
+ delete mMediaEntry;
+ }
+ if (rhs.mMediaEntry != NULL) {
+ // Make a copy
+ mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
+ }
+ else {
+ mMediaEntry = NULL;
+ }
}
return *this;
@@ -103,10 +138,19 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
mGlow = 0;
setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
+ if (mMediaEntry != NULL) {
+ delete mMediaEntry;
+ }
+ mMediaEntry = NULL;
}
LLTextureEntry::~LLTextureEntry()
{
+ if(mMediaEntry)
+ {
+ delete mMediaEntry;
+ mMediaEntry = NULL;
+ }
}
bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
@@ -158,10 +202,17 @@ void LLTextureEntry::asLLSD(LLSD& sd) const
sd["bump"] = getBumpShiny();
sd["fullbright"] = getFullbright();
sd["media_flags"] = mMediaFlags;
+ if (hasMedia()) {
+ LLSD mediaData;
+ if (NULL != getMediaData()) {
+ getMediaData()->asLLSD(mediaData);
+ }
+ sd[TEXTURE_MEDIA_DATA_KEY] = mediaData;
+ }
sd["glow"] = mGlow;
}
-bool LLTextureEntry::fromLLSD(LLSD& sd)
+bool LLTextureEntry::fromLLSD(const LLSD& sd)
{
const char *w, *x;
w = "imageid";
@@ -206,6 +257,17 @@ bool LLTextureEntry::fromLLSD(LLSD& sd)
{
setMediaTexGen( sd[w].asInteger() );
} else goto fail;
+ // If the "has media" flag doesn't match the fact that
+ // media data exists, updateMediaData will "fix" it
+ // by either clearing or setting the flag
+ w = TEXTURE_MEDIA_DATA_KEY;
+ if (hasMedia() != sd.has(w))
+ {
+ llwarns << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() <<
+ ") does not match presence of media_data (" << sd.has(w) << "). Fixing." << llendl;
+ }
+ updateMediaData(sd[w]);
+
w = "glow";
if (sd.has(w))
{
@@ -370,7 +432,19 @@ S32 LLTextureEntry::setMediaTexGen(U8 media)
if (mMediaFlags != media)
{
mMediaFlags = media;
- return TEM_CHANGE_TEXTURE;
+
+ // Special code for media handling
+ if( hasMedia() && mMediaEntry == NULL)
+ {
+ mMediaEntry = new LLMediaEntry;
+ }
+ else if ( ! hasMedia() && mMediaEntry != NULL)
+ {
+ delete mMediaEntry;
+ mMediaEntry = NULL;
+ }
+
+ return TEM_CHANGE_MEDIA;
}
return TEM_CHANGE_NONE;
}
@@ -430,7 +504,19 @@ S32 LLTextureEntry::setMediaFlags(U8 media_flags)
{
mMediaFlags &= ~TEM_MEDIA_MASK;
mMediaFlags |= media_flags;
- return TEM_CHANGE_TEXTURE;
+
+ // Special code for media handling
+ if( hasMedia() && mMediaEntry == NULL)
+ {
+ mMediaEntry = new LLMediaEntry;
+ }
+ else if ( ! hasMedia() && mMediaEntry != NULL)
+ {
+ delete mMediaEntry;
+ mMediaEntry = NULL;
+ }
+
+ return TEM_CHANGE_MEDIA;
}
return TEM_CHANGE_NONE;
}
@@ -456,3 +542,107 @@ S32 LLTextureEntry::setGlow(F32 glow)
}
return TEM_CHANGE_NONE;
}
+
+void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
+{
+ mMediaFlags |= MF_HAS_MEDIA;
+ if (NULL != mMediaEntry)
+ {
+ delete mMediaEntry;
+ }
+ mMediaEntry = new LLMediaEntry(media_entry);
+}
+
+bool LLTextureEntry::updateMediaData(const LLSD& media_data)
+{
+ if (media_data.isUndefined())
+ {
+ // clear the media data
+ clearMediaData();
+ return false;
+ }
+ else {
+ mMediaFlags |= MF_HAS_MEDIA;
+ if (mMediaEntry == NULL)
+ {
+ mMediaEntry = new LLMediaEntry;
+ }
+ // *NOTE: this will *clobber* all of the fields in mMediaEntry
+ // with whatever fields are present (or not present) in media_data!
+ mMediaEntry->fromLLSD(media_data);
+ return true;
+ }
+}
+
+void LLTextureEntry::clearMediaData()
+{
+ mMediaFlags &= ~MF_HAS_MEDIA;
+ if (mMediaEntry != NULL) {
+ delete mMediaEntry;
+ }
+ mMediaEntry = NULL;
+}
+
+void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields)
+{
+ mMediaFlags |= MF_HAS_MEDIA;
+ if (mMediaEntry == NULL)
+ {
+ mMediaEntry = new LLMediaEntry;
+ }
+ // *NOTE: this will *merge* the data in media_fields
+ // with the data in our media entry
+ mMediaEntry->mergeFromLLSD(media_fields);
+}
+
+//static
+std::string LLTextureEntry::touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id)
+{
+ // XXX TODO: make media version string binary (base64-encoded?)
+ // Media "URL" is a representation of a version and the last-touched agent
+ // x-mv:nnnnn/agent-id
+ // where "nnnnn" is version number
+ // *NOTE: not the most efficient code in the world...
+ U32 current_version = getVersionFromMediaVersionString(in_version) + 1;
+ const size_t MAX_VERSION_LEN = 10; // 2^32 fits in 10 decimal digits
+ char buf[MAX_VERSION_LEN+1];
+ snprintf(buf, (int)MAX_VERSION_LEN+1, "%0*u", (int)MAX_VERSION_LEN, current_version); // added int cast to fix warning/breakage on mac.
+ return MEDIA_VERSION_STRING_PREFIX + buf + "/" + agent_id.asString();
+}
+
+//static
+U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string)
+{
+ U32 version = 0;
+ if (!version_string.empty())
+ {
+ size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
+ if (found != std::string::npos)
+ {
+ found = version_string.find_first_of("/", found);
+ std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found);
+ version = strtoul(v.c_str(),NULL,10);
+ }
+ }
+ return version;
+}
+
+//static
+LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string)
+{
+ LLUUID id;
+ if (!version_string.empty())
+ {
+ size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
+ if (found != std::string::npos)
+ {
+ found = version_string.find_first_of("/", found);
+ if (found != std::string::npos)
+ {
+ std::string v = version_string.substr(found + 1);
+ id.set(v);
+ }
+ }
+ }
+ return id;
+}