summaryrefslogtreecommitdiff
path: root/indra/newview/llviewermedia.cpp
diff options
context:
space:
mode:
authorEric M. Tulla (BigPapi) <tulla@lindenlab.com>2009-11-17 17:58:17 -0500
committerEric M. Tulla (BigPapi) <tulla@lindenlab.com>2009-11-17 17:58:17 -0500
commit32178873564f86f0ab9ee06d485486fc9d609012 (patch)
tree4beae7908cbdd5e6af5241682110ac958b7c56ae /indra/newview/llviewermedia.cpp
parent064fb26092ac9f73f9d0301f1e214e27e8418839 (diff)
parent2365dbcd459b37942ddacbcb7010232113a126c1 (diff)
Merge of viewer2 into avp
--HG-- branch : avatar-pipeline
Diffstat (limited to 'indra/newview/llviewermedia.cpp')
-rw-r--r--indra/newview/llviewermedia.cpp137
1 files changed, 108 insertions, 29 deletions
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 251d7d4a13..3a7c54479b 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -32,6 +32,7 @@
#include "llviewerprecompiledheaders.h"
+#include "llagent.h"
#include "llviewermedia.h"
#include "llviewermediafocus.h"
#include "llmimetypes.h"
@@ -541,6 +542,16 @@ bool LLViewerMedia::priorityComparitor(const LLViewerMediaImpl* i1, const LLView
// The item with user focus always comes to the front of the list, period.
return false;
}
+ else if(i1->isParcelMedia())
+ {
+ // The parcel media impl sorts above all other inworld media, unless one has focus.
+ return true;
+ }
+ else if(i2->isParcelMedia())
+ {
+ // The parcel media impl sorts above all other inworld media, unless one has focus.
+ return false;
+ }
else if(i1->getUsedInUI() && !i2->getUsedInUI())
{
// i1 is a UI element, i2 is not. This makes i1 "less than" i2, so it sorts earlier in our list.
@@ -551,16 +562,21 @@ bool LLViewerMedia::priorityComparitor(const LLViewerMediaImpl* i1, const LLView
// i2 is a UI element, i1 is not. This makes i2 "less than" i1, so it sorts earlier in our list.
return false;
}
- else if(i1->isParcelMedia())
+ else if(i1->isPlayable() && !i2->isPlayable())
{
- // The parcel media impl sorts above all other inworld media, unless one has focus.
+ // Playable items sort above ones that wouldn't play even if they got high enough priority
return true;
}
- else if(i2->isParcelMedia())
+ else if(!i1->isPlayable() && i2->isPlayable())
{
- // The parcel media impl sorts above all other inworld media, unless one has focus.
+ // Playable items sort above ones that wouldn't play even if they got high enough priority
return false;
}
+ else if(i1->getInterest() == i2->getInterest())
+ {
+ // Generally this will mean both objects have zero interest. In this case, sort on distance.
+ return (i1->getProximityDistance() < i2->getProximityDistance());
+ }
else
{
// The object with the larger interest value should be earlier in the list, so we reverse the sense of the comparison here.
@@ -568,6 +584,11 @@ bool LLViewerMedia::priorityComparitor(const LLViewerMediaImpl* i1, const LLView
}
}
+static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2)
+{
+ return (i1->getProximityDistance() < i2->getProximityDistance());
+}
+
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::updateMedia()
@@ -593,12 +614,9 @@ void LLViewerMedia::updateMedia()
int impl_count_total = 0;
int impl_count_interest_low = 0;
int impl_count_interest_normal = 0;
- int i = 0;
-
-#if 0
- LL_DEBUGS("PluginPriority") << "Sorted impls:" << llendl;
-#endif
-
+
+ std::vector<LLViewerMediaImpl*> proximity_order;
+
U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal");
U32 max_normal = gSavedSettings.getU32("PluginInstancesNormal");
U32 max_low = gSavedSettings.getU32("PluginInstancesLow");
@@ -629,10 +647,12 @@ void LLViewerMedia::updateMedia()
else if(pimpl->hasFocus())
{
new_priority = LLPluginClassMedia::PRIORITY_HIGH;
+ impl_count_interest_normal++; // count this against the count of "normal" instances for priority purposes
}
else if(pimpl->getUsedInUI())
{
new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
+ impl_count_interest_normal++;
}
else
{
@@ -640,7 +660,17 @@ void LLViewerMedia::updateMedia()
// Heuristic -- if the media texture's approximate screen area is less than 1/4 of the native area of the texture,
// turn it down to low instead of normal. This may downsample for plugins that support it.
- bool media_is_small = pimpl->getInterest() < (pimpl->getApproximateTextureInterest() / 4);
+ bool media_is_small = false;
+ F64 approximate_interest = pimpl->getApproximateTextureInterest();
+ if(approximate_interest == 0.0f)
+ {
+ // this media has no current size, which probably means it's not loaded.
+ media_is_small = true;
+ }
+ else if(pimpl->getInterest() < (approximate_interest / 4))
+ {
+ media_is_small = true;
+ }
if(pimpl->getInterest() == 0.0f)
{
@@ -678,7 +708,7 @@ void LLViewerMedia::updateMedia()
}
}
- if(new_priority != LLPluginClassMedia::PRIORITY_UNLOADED)
+ if(!pimpl->getUsedInUI() && (new_priority != LLPluginClassMedia::PRIORITY_UNLOADED))
{
impl_count_total++;
}
@@ -692,23 +722,27 @@ void LLViewerMedia::updateMedia()
}
else
{
- // Other impls just get the same ordering as the priority list (for now).
- pimpl->mProximity = i;
+ proximity_order.push_back(pimpl);
}
-#if 0
- LL_DEBUGS("PluginPriority") << " " << pimpl
- << ", setting priority to " << new_priority
- << (pimpl->hasFocus()?", HAS FOCUS":"")
- << (pimpl->getUsedInUI()?", is UI":"")
- << ", cpu " << pimpl->getCPUUsage()
- << ", interest " << pimpl->getInterest()
- << ", media url " << pimpl->getMediaURL() << llendl;
-#endif
-
total_cpu += pimpl->getCPUUsage();
-
- i++;
+ }
+
+ if(gSavedSettings.getBOOL("MediaPerformanceManagerDebug"))
+ {
+ // Give impls the same ordering as the priority list
+ // they're already in the right order for this.
+ }
+ else
+ {
+ // Use a distance-based sort for proximity values.
+ std::stable_sort(proximity_order.begin(), proximity_order.end(), proximity_comparitor);
+ }
+
+ // Transfer the proximity order to the proximity fields in the objects.
+ for(int i = 0; i < (int)proximity_order.size(); i++)
+ {
+ proximity_order[i]->mProximity = i;
}
LL_DEBUGS("PluginPriority") << "Total reported CPU usage is " << total_cpu << llendl;
@@ -760,6 +794,7 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
mIsDisabled(false),
mIsParcelMedia(false),
mProximity(-1),
+ mProximityDistance(0.0f),
mMimeTypeProbe(NULL),
mIsUpdated(false)
{
@@ -1588,6 +1623,10 @@ void LLViewerMediaImpl::update()
{
// This media source should not be loaded.
}
+ else if(mPriority <= LLPluginClassMedia::PRIORITY_SLIDESHOW)
+ {
+ // Don't load new instances that are at PRIORITY_SLIDESHOW or below. They're just kept around to preserve state.
+ }
else if(mMimeTypeProbe != NULL)
{
// this media source is doing a MIME type probe -- don't try loading it again.
@@ -1816,7 +1855,7 @@ bool LLViewerMediaImpl::isMediaPaused()
//////////////////////////////////////////////////////////////////////////////////////////
//
-bool LLViewerMediaImpl::hasMedia()
+bool LLViewerMediaImpl::hasMedia() const
{
return mMediaSource != NULL;
}
@@ -1851,6 +1890,31 @@ bool LLViewerMediaImpl::isForcedUnloaded() const
}
//////////////////////////////////////////////////////////////////////////////////////////
+//
+bool LLViewerMediaImpl::isPlayable() const
+{
+ if(isForcedUnloaded())
+ {
+ // All of the forced-unloaded criteria also imply not playable.
+ return false;
+ }
+
+ if(hasMedia())
+ {
+ // Anything that's already playing is, by definition, playable.
+ return true;
+ }
+
+ if(!mMediaURL.empty())
+ {
+ // If something has navigated the instance, it's ready to be played.
+ return true;
+ }
+
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent event)
{
switch(event)
@@ -2058,6 +2122,15 @@ void LLViewerMediaImpl::calculateInterest()
mInterest = 0.0f;
}
+ // Calculate distance from the avatar, for use in the proximity calculation.
+ mProximityDistance = 0.0f;
+ if(!mObjectList.empty())
+ {
+ // Just use the first object in the list. We could go through the list and find the closest object, but this should work well enough.
+ LLVector3d global_delta = gAgent.getPositionGlobal() - (*mObjectList.begin())->getPositionGlobal();
+ mProximityDistance = global_delta.magVecSquared(); // use distance-squared because it's cheaper and sorts the same.
+ }
+
if(mNeedsMuteCheck)
{
// Check all objects this instance is associated with, and those objects' owners, against the mute list
@@ -2094,7 +2167,13 @@ F64 LLViewerMediaImpl::getApproximateTextureInterest()
result = mMediaSource->getFullWidth();
result *= mMediaSource->getFullHeight();
}
-
+ else
+ {
+ // No media source is loaded -- all we have to go on is the texture size that has been set on the impl, if any.
+ result = mMediaWidth;
+ result *= mMediaHeight;
+ }
+
return result;
}
@@ -2135,7 +2214,7 @@ void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority)
{
if(mPriority != priority)
{
- LL_INFOS("PluginPriority")
+ LL_DEBUGS("PluginPriority")
<< "changing priority of media id " << mTextureId
<< " from " << LLPluginClassMedia::priorityToString(mPriority)
<< " to " << LLPluginClassMedia::priorityToString(priority)