aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvovolume.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llvovolume.cpp')
-rw-r--r--linden/indra/newview/llvovolume.cpp398
1 files changed, 394 insertions, 4 deletions
diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp
index d580d61..2b9f94c 100644
--- a/linden/indra/newview/llvovolume.cpp
+++ b/linden/indra/newview/llvovolume.cpp
@@ -68,6 +68,9 @@
68#include "rlvhandler.h" 68#include "rlvhandler.h"
69// [/RLVa:KB] 69// [/RLVa:KB]
70 70
71#include "llmediaentry.h"
72#include "llmediadataclient.h"
73
71const S32 MIN_QUIET_FRAMES_COALESCE = 30; 74const S32 MIN_QUIET_FRAMES_COALESCE = 30;
72const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; 75const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
73const F32 FORCE_CULL_AREA = 8.f; 76const F32 FORCE_CULL_AREA = 8.f;
@@ -79,6 +82,93 @@ F32 LLVOVolume::sLODFactor = 1.f;
79F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop 82F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop
80F32 LLVOVolume::sDistanceFactor = 1.0f; 83F32 LLVOVolume::sDistanceFactor = 1.0f;
81S32 LLVOVolume::sNumLODChanges = 0; 84S32 LLVOVolume::sNumLODChanges = 0;
85LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL;
86LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL;
87
88// Implementation class of LLMediaDataClientObject. See llmediadataclient.h
89class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
90{
91public:
92 LLMediaDataClientObjectImpl(LLVOVolume *obj, bool isNew) : mObject(obj), mNew(isNew) {}
93 LLMediaDataClientObjectImpl() { mObject = NULL; }
94
95 virtual U8 getMediaDataCount() const
96 { return mObject->getNumTEs(); }
97
98 virtual LLSD getMediaDataLLSD(U8 index) const
99 {
100 LLSD result;
101 LLTextureEntry *te = mObject->getTE(index);
102 if (NULL != te)
103 {
104 llassert((te->getMediaData() != NULL) == te->hasMedia());
105 if (te->getMediaData() != NULL)
106 {
107 result = te->getMediaData()->asLLSD();
108 // XXX HACK: workaround bug in asLLSD() where whitelist is not set properly
109 // See DEV-41949
110 if (!result.has(LLMediaEntry::WHITELIST_KEY))
111 {
112 result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray();
113 }
114 }
115 }
116 return result;
117 }
118
119 virtual LLUUID getID() const
120 { return mObject->getID(); }
121
122 virtual void mediaNavigateBounceBack(U8 index)
123 { mObject->mediaNavigateBounceBack(index); }
124
125 virtual bool hasMedia() const
126 { return mObject->hasMedia();}
127
128 virtual void updateObjectMediaData(LLSD const &data, const std::string &version_string)
129 { mObject->updateObjectMediaData(data, version_string); }
130
131 virtual F64 getMediaInterest() const
132 {
133 //F64 interest = mObject->getTotalMediaInterest();
134 //FIXME
135 F64 interest = 1024;
136 if (interest < (F64)0.0)
137 {
138 // media interest not valid yet, try pixel area
139 interest = mObject->getPixelArea();
140 // HACK: force recalculation of pixel area if interest is the "magic default" of 1024.
141 if (interest == 1024.f)
142 {
143 const_cast<LLVOVolume*>(static_cast<LLVOVolume*>(mObject))->setPixelAreaAndAngle(gAgent);
144 interest = mObject->getPixelArea();
145 }
146 }
147 return interest;
148 }
149
150 virtual bool isInterestingEnough() const
151 {
152 return true; //FUCKEDUP --> LLViewerMedia::isInterestingEnough(mObject, getMediaInterest());
153 }
154
155 virtual std::string getCapabilityUrl(const std::string &name) const
156 { return mObject->getRegion()->getCapability(name); }
157
158 virtual bool isDead() const
159 { return mObject->isDead(); }
160
161 virtual U32 getMediaVersion() const
162 { return LLTextureEntry::getVersionFromMediaVersionString(mObject->getMediaURL()); }
163
164 virtual bool isNew() const
165 { return mNew; }
166
167private:
168 LLPointer<LLVOVolume> mObject;
169 bool mNew;
170};
171
82 172
83LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) 173LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
84 : LLViewerObject(id, pcode, regionp), 174 : LLViewerObject(id, pcode, regionp),
@@ -123,6 +213,18 @@ void LLVOVolume::markDead()
123// static 213// static
124void LLVOVolume::initClass() 214void LLVOVolume::initClass()
125{ 215{
216 // gSavedSettings better be around
217 if (gSavedSettings.getBOOL("PrimMediaMasterEnabled"))
218 {
219 const F32 queue_timer_delay = gSavedSettings.getF32("PrimMediaRequestQueueDelay");
220 const F32 retry_timer_delay = gSavedSettings.getF32("PrimMediaRetryTimerDelay");
221 const U32 max_retries = gSavedSettings.getU32("PrimMediaMaxRetries");
222 const U32 max_sorted_queue_size = gSavedSettings.getU32("PrimMediaMaxSortedQueueSize");
223 const U32 max_round_robin_queue_size = gSavedSettings.getU32("PrimMediaMaxRoundRobinQueueSize");
224
225 sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries,
226 max_sorted_queue_size, max_round_robin_queue_size);
227 }
126} 228}
127 229
128 230
@@ -132,6 +234,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
132 LLDataPacker *dp) 234 LLDataPacker *dp)
133{ 235{
134 LLColor4U color; 236 LLColor4U color;
237 const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
135 238
136 // Do base class updates... 239 // Do base class updates...
137 U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); 240 U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
@@ -199,10 +302,15 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
199 // 302 //
200 // Unpack texture entry data 303 // Unpack texture entry data
201 // 304 //
202 if (unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num) & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR)) 305 S32 result =unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
306 if (result & teDirtyBits)
203 { 307 {
204 updateTEData(); 308 updateTEData();
205 } 309 }
310 if (result & TEM_CHANGE_MEDIA)
311 {
312 retval |= MEDIA_FLAGS_CHANGED;
313 }
206 } 314 }
207 else 315 else
208 { 316 {
@@ -235,9 +343,16 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
235// llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl; 343// llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl;
236 llwarns << "Bogus TE data in " << getID() << llendl; 344 llwarns << "Bogus TE data in " << getID() << llendl;
237 } 345 }
238 else if (res2 & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR)) 346 else
239 { 347 {
240 updateTEData(); 348 if (res2 & teDirtyBits)
349 {
350 updateTEData();
351 }
352 if (res2 & TEM_CHANGE_MEDIA)
353 {
354 retval |= MEDIA_FLAGS_CHANGED;
355 }
241 } 356 }
242 357
243 U32 value = dp->getPassFlags(); 358 U32 value = dp->getPassFlags();
@@ -275,13 +390,39 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
275 U8 tdpbuffer[1024]; 390 U8 tdpbuffer[1024];
276 LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024); 391 LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024);
277 mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num); 392 mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num);
278 if ( unpackTEMessage(tdp) & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR)) 393 S32 result = unpackTEMessage(tdp);
394 if (result & teDirtyBits)
279 { 395 {
280 updateTEData(); 396 updateTEData();
281 } 397 }
398 if (result & TEM_CHANGE_MEDIA)
399 {
400 retval |= MEDIA_FLAGS_CHANGED;
401 }
282 } 402 }
283 } 403 }
284 } 404 }
405
406 if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED))
407 {
408 // If only the media URL changed, and it isn't a media version URL,
409 // ignore it
410 if ( ! ( retval & (MEDIA_URL_ADDED | MEDIA_URL_UPDATED) &&
411 mMedia && ! mMedia->mMediaURL.empty() &&
412 ! LLTextureEntry::isMediaVersionString(mMedia->mMediaURL) ) )
413 {
414 // If the media changed at all, request new media data
415 LL_DEBUGS("MediaOnAPrim") << "Media update: " << getID() << ": retval=" << retval << " Media URL: " <<
416 ((mMedia) ? mMedia->mMediaURL : std::string("")) << LL_ENDL;
417 requestMediaDataUpdate(retval & MEDIA_FLAGS_CHANGED);
418 }
419 else {
420 LL_INFOS("MediaOnAPrim") << "Ignoring media update for: " << getID() << " Media URL: " <<
421 ((mMedia) ? mMedia->mMediaURL : std::string("")) << LL_ENDL;
422 }
423 }
424 // ...and clean up any media impls
425 cleanUpMediaImpls();
285 426
286 return retval; 427 return retval;
287} 428}
@@ -2894,4 +3035,253 @@ void LLHUDPartition::shift(const LLVector3 &offset)
2894 //HUD objects don't shift with region crossing. That would be silly. 3035 //HUD objects don't shift with region crossing. That would be silly.
2895} 3036}
2896 3037
3038void LLVOVolume::requestMediaDataUpdate(bool isNew)
3039{
3040 if (sObjectMediaClient)
3041 sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this, isNew));
3042}
3043
3044void LLVOVolume::cleanUpMediaImpls()
3045{
3046 // Iterate through our TEs and remove any Impls that are no longer used
3047 const U8 numTEs = getNumTEs();
3048 for (U8 i = 0; i < numTEs; i++)
3049 {
3050 const LLTextureEntry* te = getTE(i);
3051 if( ! te->hasMedia())
3052 {
3053 // Delete the media IMPL!
3054 removeMediaImpl(i) ;
3055 }
3056 }
3057}
3058
3059void LLVOVolume::removeMediaImpl(S32 texture_index)
3060{
3061 if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull())
3062 {
3063 return ;
3064 }
3065
3066 //make the face referencing to mMediaImplList[texture_index] to point back to the old texture.
3067 if(mDrawable)
3068 {
3069 LLFace* facep = mDrawable->getFace(texture_index) ;
3070 if(facep)
3071 {
3072 //LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
3073 //if(media_tex)
3074 //{
3075 // media_tex->removeMediaFromFace(facep) ;
3076 //}
3077 }
3078 }
3079
3080 //check if some other face(s) of this object reference(s)to this media impl.
3081 S32 i ;
3082 S32 end = (S32)mMediaImplList.size() ;
3083 for(i = 0; i < end ; i++)
3084 {
3085 if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index])
3086 {
3087 break ;
3088 }
3089 }
3090
3091 if(i == end) //this object does not need this media impl.
3092 {
3093 //mMediaImplList[texture_index]->removeObject(this) ;
3094 }
3095
3096 mMediaImplList[texture_index] = NULL ;
3097 return ;
3098}
3099
3100void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index)
3101{
3102 if((S32)mMediaImplList.size() < texture_index + 1)
3103 {
3104 mMediaImplList.resize(texture_index + 1) ;
3105 }
3106
3107 if(mMediaImplList[texture_index].notNull())
3108 {
3109 if(mMediaImplList[texture_index] == media_impl)
3110 {
3111 return ;
3112 }
3113
3114 removeMediaImpl(texture_index) ;
3115 }
3116
3117 mMediaImplList[texture_index] = media_impl;
3118 //media_impl->addObject(this) ;
3119
3120 //add the face to show the media if it is in playing
3121 if(mDrawable)
3122 {
3123 LLFace* facep = mDrawable->getFace(texture_index) ;
3124 if(facep)
3125 {
3126 //LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
3127 //if(media_tex)
3128 //{
3129 // media_tex->addMediaToFace(facep) ;
3130 //}
3131 }
3132 else //the face is not available now, start media on this face later.
3133 {
3134 //media_impl->setUpdated(TRUE) ;
3135 }
3136 }
3137 return ;
3138}
3139
3140void LLVOVolume::sendMediaDataUpdate()
3141{
3142 if (sObjectMediaClient)
3143 sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this, false));
3144}
3145
3146void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version)
3147{
3148 // media_data_array is an array of media entry maps
3149 // media_version is the version string in the response.
3150 U32 fetched_version = LLTextureEntry::getVersionFromMediaVersionString(media_version);
3151
3152 // Only update it if it is newer!
3153 if ( (S32)fetched_version > mLastFetchedMediaVersion)
3154 {
3155 mLastFetchedMediaVersion = fetched_version;
3156 //llinfos << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << llendl;
3157
3158 LLSD::array_const_iterator iter = media_data_array.beginArray();
3159 LLSD::array_const_iterator end = media_data_array.endArray();
3160 U8 texture_index = 0;
3161 for (; iter != end; ++iter, ++texture_index)
3162 {
3163 syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/);
3164 }
3165 }
3166}
3167
3168bool LLVOVolume::hasMedia() const
3169{
3170 bool result = false;
3171 const U8 numTEs = getNumTEs();
3172 for (U8 i = 0; i < numTEs; i++)
3173 {
3174 const LLTextureEntry* te = getTE(i);
3175 if(te->hasMedia())
3176 {
3177 result = true;
3178 break;
3179 }
3180 }
3181 return result;
3182}
3183
3184void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool merge, bool ignore_agent)
3185{
3186 if(mDead)
3187 {
3188 // If the object has been marked dead, don't process media updates.
3189 return;
3190 }
3191
3192 LLTextureEntry *te = getTE(texture_index);
3193// LL_DEBUGS("MediaOnAPrim") << "BEFORE: texture_index = " << texture_index
3194// << " hasMedia = " << te->hasMedia() << " : "
3195// << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;
2897 3196
3197 std::string previous_url;
3198 LLMediaEntry* mep = te->getMediaData();
3199 if(mep)
3200 {
3201 // Save the "current url" from before the update so we can tell if
3202 // it changes.
3203 previous_url = mep->getCurrentURL();
3204 }
3205
3206 if (merge)
3207 {
3208 te->mergeIntoMediaData(media_data);
3209 }
3210 else {
3211 // XXX Question: what if the media data is undefined LLSD, but the
3212 // update we got above said that we have media flags?? Here we clobber
3213 // that, assuming the data from the service is more up-to-date.
3214 te->updateMediaData(media_data);
3215 }
3216
3217 mep = te->getMediaData();
3218 if(mep)
3219 {
3220 //bool update_from_self = false;
3221 if (!ignore_agent)
3222 {
3223 LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL());
3224 //update_from_self = (updating_agent == gAgent.getID());
3225 }
3226 //viewer_media_t media_impl = LLViewerMedia::updateMediaImpl(mep, previous_url, update_from_self);
3227
3228 //addMediaImpl(media_impl, texture_index) ;
3229 }
3230 else
3231 {
3232 //removeMediaImpl(texture_index);
3233 }
3234
3235// LL_DEBUGS("MediaOnAPrim") << "AFTER: texture_index = " << texture_index
3236// << " hasMedia = " << te->hasMedia() << " : "
3237// << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;
3238}
3239
3240
3241void LLVOVolume::mediaNavigateBounceBack(U8 texture_index)
3242{
3243 /*
3244 // Find the media entry for this navigate
3245 const LLMediaEntry* mep = NULL;
3246 viewer_media_t impl = getMediaImpl(texture_index);
3247 LLTextureEntry *te = getTE(texture_index);
3248 if(te)
3249 {
3250 mep = te->getMediaData();
3251 }
3252
3253 if (mep && impl)
3254 {
3255 std::string url = mep->getCurrentURL();
3256 // Look for a ":", if not there, assume "http://"
3257 if (!url.empty() && std::string::npos == url.find(':'))
3258 {
3259 url = "http://" + url;
3260 }
3261 // If the url we're trying to "bounce back" to is either empty or not
3262 // allowed by the whitelist, try the home url. If *that* doesn't work,
3263 // set the media as failed and unload it
3264 if (url.empty() || !mep->checkCandidateUrl(url))
3265 {
3266 url = mep->getHomeURL();
3267 // Look for a ":", if not there, assume "http://"
3268 if (!url.empty() && std::string::npos == url.find(':'))
3269 {
3270 url = "http://" + url;
3271 }
3272 }
3273 if (url.empty() || !mep->checkCandidateUrl(url))
3274 {
3275 // The url to navigate back to is not good, and we have nowhere else
3276 // to go.
3277 LL_WARNS("MediaOnAPrim") << "FAILED to bounce back URL \"" << url << "\" -- unloading impl" << LL_ENDL;
3278 impl->setMediaFailed(true);
3279 }
3280 else {
3281 // Okay, navigate now
3282 LL_INFOS("MediaOnAPrim") << "bouncing back to URL: " << url << LL_ENDL;
3283 impl->navigateTo(url, "", false, true);
3284 }
3285 }
3286 */
3287}