diff options
Diffstat (limited to 'linden/indra/newview/llvovolume.cpp')
-rw-r--r-- | linden/indra/newview/llvovolume.cpp | 398 |
1 files changed, 394 insertions, 4 deletions
diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp index d580d61..cb38c86 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 | |||
71 | const S32 MIN_QUIET_FRAMES_COALESCE = 30; | 74 | const S32 MIN_QUIET_FRAMES_COALESCE = 30; |
72 | const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; | 75 | const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; |
73 | const F32 FORCE_CULL_AREA = 8.f; | 76 | const F32 FORCE_CULL_AREA = 8.f; |
@@ -79,6 +82,93 @@ F32 LLVOVolume::sLODFactor = 1.f; | |||
79 | F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop | 82 | F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop |
80 | F32 LLVOVolume::sDistanceFactor = 1.0f; | 83 | F32 LLVOVolume::sDistanceFactor = 1.0f; |
81 | S32 LLVOVolume::sNumLODChanges = 0; | 84 | S32 LLVOVolume::sNumLODChanges = 0; |
85 | LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL; | ||
86 | LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL; | ||
87 | |||
88 | // Implementation class of LLMediaDataClientObject. See llmediadataclient.h | ||
89 | class LLMediaDataClientObjectImpl : public LLMediaDataClientObject | ||
90 | { | ||
91 | public: | ||
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 | |||
167 | private: | ||
168 | LLPointer<LLVOVolume> mObject; | ||
169 | bool mNew; | ||
170 | }; | ||
171 | |||
82 | 172 | ||
83 | LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) | 173 | LLVOVolume::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 |
124 | void LLVOVolume::initClass() | 214 | void 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 | ||
3038 | void LLVOVolume::requestMediaDataUpdate(bool isNew) | ||
3039 | { | ||
3040 | if (sObjectMediaClient) | ||
3041 | sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this, isNew)); | ||
3042 | } | ||
3043 | |||
3044 | void 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 | |||
3059 | void 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 | |||
3100 | void 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 | |||
3140 | void LLVOVolume::sendMediaDataUpdate() | ||
3141 | { | ||
3142 | if (sObjectMediaClient) | ||
3143 | sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this, false)); | ||
3144 | } | ||
3145 | |||
3146 | void 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 | |||
3168 | bool 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 | |||
3184 | void 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 | |||
3241 | void 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 | } | ||