summaryrefslogtreecommitdiff
path: root/indra/llplugin
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llplugin')
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp58
-rw-r--r--indra/llplugin/llpluginclassmedia.h15
-rw-r--r--indra/llplugin/llpluginmessage.cpp23
-rw-r--r--indra/llplugin/llpluginmessage.h4
-rw-r--r--indra/llplugin/llpluginprocesschild.cpp35
-rw-r--r--indra/llplugin/llpluginprocesschild.h1
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp8
-rw-r--r--indra/llplugin/llpluginprocessparent.h3
8 files changed, 130 insertions, 17 deletions
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 54f153d182..7299ede22d 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -99,6 +99,8 @@ void LLPluginClassMedia::reset()
mSetMediaHeight = -1;
mRequestedMediaWidth = 0;
mRequestedMediaHeight = 0;
+ mFullMediaWidth = 0;
+ mFullMediaHeight = 0;
mTextureWidth = 0;
mTextureHeight = 0;
mMediaWidth = 0;
@@ -266,8 +268,16 @@ unsigned char* LLPluginClassMedia::getBitsData()
void LLPluginClassMedia::setSize(int width, int height)
{
- mSetMediaWidth = width;
- mSetMediaHeight = height;
+ if((width > 0) && (height > 0))
+ {
+ mSetMediaWidth = width;
+ mSetMediaHeight = height;
+ }
+ else
+ {
+ mSetMediaWidth = -1;
+ mSetMediaHeight = -1;
+ }
setSizeInternal();
}
@@ -279,16 +289,26 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaWidth = mSetMediaWidth;
mRequestedMediaHeight = mSetMediaHeight;
}
+ else if((mNaturalMediaWidth > 0) && (mNaturalMediaHeight > 0))
+ {
+ mRequestedMediaWidth = mNaturalMediaWidth;
+ mRequestedMediaHeight = mNaturalMediaHeight;
+ }
else
{
mRequestedMediaWidth = mDefaultMediaWidth;
mRequestedMediaHeight = mDefaultMediaHeight;
}
+ // Save these for size/interest calculations
+ mFullMediaWidth = mRequestedMediaWidth;
+ mFullMediaHeight = mRequestedMediaHeight;
+
if(mAllowDownsample)
{
switch(mPriority)
{
+ case PRIORITY_SLIDESHOW:
case PRIORITY_LOW:
// Reduce maximum texture dimension to (or below) mLowPrioritySizeLimit
while((mRequestedMediaWidth > mLowPrioritySizeLimit) || (mRequestedMediaHeight > mLowPrioritySizeLimit))
@@ -309,6 +329,12 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth);
mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
}
+
+ if(mRequestedMediaWidth > 2048)
+ mRequestedMediaWidth = 2048;
+
+ if(mRequestedMediaHeight > 2048)
+ mRequestedMediaHeight = 2048;
}
void LLPluginClassMedia::setAutoScale(bool auto_scale)
@@ -519,6 +545,10 @@ void LLPluginClassMedia::setPriority(EPriority priority)
std::string priority_string;
switch(priority)
{
+ case PRIORITY_UNLOADED:
+ priority_string = "unloaded";
+ mSleepTime = 1.0f;
+ break;
case PRIORITY_STOPPED:
priority_string = "stopped";
mSleepTime = 1.0f;
@@ -527,6 +557,10 @@ void LLPluginClassMedia::setPriority(EPriority priority)
priority_string = "hidden";
mSleepTime = 1.0f;
break;
+ case PRIORITY_SLIDESHOW:
+ priority_string = "slideshow";
+ mSleepTime = 1.0f;
+ break;
case PRIORITY_LOW:
priority_string = "low";
mSleepTime = 1.0f / 50.0f;
@@ -550,6 +584,8 @@ void LLPluginClassMedia::setPriority(EPriority priority)
mPlugin->setSleepTime(mSleepTime);
}
+ LL_DEBUGS("PluginPriority") << this << ": setting priority to " << priority_string << LL_ENDL;
+
// This may affect the calculated size, so recalculate it here.
setSizeInternal();
}
@@ -557,15 +593,27 @@ void LLPluginClassMedia::setPriority(EPriority priority)
void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
{
- if(mLowPrioritySizeLimit != size)
+ int power = nextPowerOf2(size);
+ if(mLowPrioritySizeLimit != power)
{
- mLowPrioritySizeLimit = size;
+ mLowPrioritySizeLimit = power;
// This may affect the calculated size, so recalculate it here.
setSizeInternal();
}
}
+F64 LLPluginClassMedia::getCPUUsage()
+{
+ F64 result = 0.0f;
+
+ if(mPlugin)
+ {
+ result = mPlugin->getCPUUsage();
+ }
+
+ return result;
+}
void LLPluginClassMedia::cut()
{
@@ -722,7 +770,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mNaturalMediaWidth = width;
mNaturalMediaHeight = height;
- setSize(width, height);
+ setSizeInternal();
}
else if(message_name == "size_change_response")
{
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 665a423d07..331ca5f6dc 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -66,6 +66,8 @@ public:
int getBitsHeight() const { return (mTextureHeight > 0) ? mTextureHeight : 0; };
int getTextureWidth() const;
int getTextureHeight() const;
+ int getFullWidth() const { return mFullMediaWidth; };
+ int getFullHeight() const { return mFullMediaHeight; };
// This may return NULL. Callers need to check for and handle this case.
unsigned char* getBitsData();
@@ -138,9 +140,11 @@ public:
typedef enum
{
+ PRIORITY_UNLOADED, // media plugin isn't even loaded.
PRIORITY_STOPPED, // media is not playing, shouldn't need to update at all.
PRIORITY_HIDDEN, // media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc.
- PRIORITY_LOW, // media is in the far distance, may be rendered at reduced size
+ PRIORITY_SLIDESHOW, // media is in the far distance, updates very infrequently
+ PRIORITY_LOW, // media is in the distance, may be rendered at reduced size
PRIORITY_NORMAL, // normal (default) priority
PRIORITY_HIGH // media has user focus and/or is taking up most of the screen
}EPriority;
@@ -148,6 +152,8 @@ public:
void setPriority(EPriority priority);
void setLowPrioritySizeLimit(int size);
+ F64 getCPUUsage();
+
// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
std::string getCursorName() const { return mCursorName; };
@@ -230,6 +236,7 @@ public:
void initializeUrlHistory(const LLSD& url_history);
protected:
+
LLPluginClassMediaOwner *mOwner;
// Notify this object's owner that an event has occurred.
@@ -266,7 +273,11 @@ protected:
int mSetMediaWidth;
int mSetMediaHeight;
- // Actual media size being set (may be affected by auto-scale)
+ // Full calculated media size (before auto-scale and downsample calculations)
+ int mFullMediaWidth;
+ int mFullMediaHeight;
+
+ // Actual media size being set (after auto-scale)
int mRequestedMediaWidth;
int mRequestedMediaHeight;
diff --git a/indra/llplugin/llpluginmessage.cpp b/indra/llplugin/llpluginmessage.cpp
index bfabc5b7ca..e7412a1d8f 100644
--- a/indra/llplugin/llpluginmessage.cpp
+++ b/indra/llplugin/llpluginmessage.cpp
@@ -33,6 +33,7 @@
#include "llpluginmessage.h"
#include "llsdserialize.h"
+#include "u64.h"
LLPluginMessage::LLPluginMessage()
{
@@ -93,6 +94,14 @@ void LLPluginMessage::setValueReal(const std::string &key, F64 value)
mMessage["params"][key] = value;
}
+void LLPluginMessage::setValuePointer(const std::string &key, void* value)
+{
+ std::stringstream temp;
+ // iostreams should output pointer values in hex with an initial 0x by default.
+ temp << value;
+ setValue(key, temp.str());
+}
+
std::string LLPluginMessage::getClass(void) const
{
return mMessage["class"];
@@ -189,6 +198,20 @@ F64 LLPluginMessage::getValueReal(const std::string &key) const
return result;
}
+void* LLPluginMessage::getValuePointer(const std::string &key) const
+{
+ void* result = NULL;
+
+ if(mMessage["params"].has(key))
+ {
+ std::string value = mMessage["params"][key].asString();
+
+ result = (void*)llstrtou64(value.c_str(), NULL, 16);
+ }
+
+ return result;
+}
+
std::string LLPluginMessage::generate(void) const
{
std::ostringstream result;
diff --git a/indra/llplugin/llpluginmessage.h b/indra/llplugin/llpluginmessage.h
index a17ec4bb98..f1a0e7c624 100644
--- a/indra/llplugin/llpluginmessage.h
+++ b/indra/llplugin/llpluginmessage.h
@@ -57,6 +57,7 @@ public:
void setValueU32(const std::string &key, U32 value);
void setValueBoolean(const std::string &key, bool value);
void setValueReal(const std::string &key, F64 value);
+ void setValuePointer(const std::string &key, void *value);
std::string getClass(void) const;
std::string getName(void) const;
@@ -82,6 +83,9 @@ public:
// get the value of a key as a float.
F64 getValueReal(const std::string &key) const;
+ // get the value of a key as a pointer.
+ void* getValuePointer(const std::string &key) const;
+
// Flatten the message into a string
std::string generate(void) const;
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index dc51671032..450dcb3c78 100644
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -43,6 +43,7 @@ LLPluginProcessChild::LLPluginProcessChild()
mInstance = NULL;
mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
mSleepTime = 1.0f / 100.0f; // default: send idle messages at 100Hz
+ mCPUElapsed = 0.0f;
}
LLPluginProcessChild::~LLPluginProcessChild()
@@ -130,6 +131,7 @@ void LLPluginProcessChild::idle(void)
{
mHeartbeat.start();
mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
+ mCPUElapsed = 0.0f;
setState(STATE_PLUGIN_LOADED);
}
else
@@ -158,10 +160,22 @@ void LLPluginProcessChild::idle(void)
mInstance->idle();
- if(mHeartbeat.checkExpirationAndReset(HEARTBEAT_SECONDS))
+ if(mHeartbeat.hasExpired())
{
+
// This just proves that we're not stuck down inside the plugin code.
- sendMessageToParent(LLPluginMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat"));
+ LLPluginMessage heartbeat(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat");
+
+ // Calculate the approximage CPU usage fraction (floating point value between 0 and 1) used by the plugin this heartbeat cycle.
+ // Note that this will not take into account any threads or additional processes the plugin spawns, but it's a first approximation.
+ // If we could write OS-specific functions to query the actual CPU usage of this process, that would be a better approximation.
+ heartbeat.setValueReal("cpu_usage", mCPUElapsed / mHeartbeat.getElapsedTimeF64());
+
+ sendMessageToParent(heartbeat);
+
+ mHeartbeat.reset();
+ mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
+ mCPUElapsed = 0.0f;
}
}
// receivePluginMessage will transition to STATE_UNLOADING
@@ -253,8 +267,11 @@ void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
std::string buffer = message.generate();
LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL;
-
+ LLTimer elapsed;
+
mInstance->sendMessage(buffer);
+
+ mCPUElapsed += elapsed.getElapsedTimeF64();
}
void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message)
@@ -317,12 +334,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
LLPluginMessage message("base", "shm_added");
message.setValue("name", name);
message.setValueS32("size", (S32)size);
- // shm address is split into 2x32bit values because LLSD doesn't serialize 64bit values and we need to support 64-bit addressing.
- void * address = region->getMappedAddress();
- U32 address_lo = (U32)(U64(address) & 0xFFFFFFFF); // Extract the lower 32 bits
- U32 address_hi = (U32)((U64(address)>>32) & 0xFFFFFFFF); // Extract the higher 32 bits
- message.setValueU32("address", address_lo);
- message.setValueU32("address_1", address_hi);
+ message.setValuePointer("address", region->getMappedAddress());
sendMessageToPlugin(message);
// and send the response to the parent
@@ -380,7 +392,11 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
if(passMessage && mInstance != NULL)
{
+ LLTimer elapsed;
+
mInstance->sendMessage(message);
+
+ mCPUElapsed += elapsed.getElapsedTimeF64();
}
}
@@ -454,6 +470,7 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
if(passMessage)
{
+ LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL;
writeMessageRaw(message);
}
}
diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h
index f92905e8bd..75860bdf0a 100644
--- a/indra/llplugin/llpluginprocesschild.h
+++ b/indra/llplugin/llpluginprocesschild.h
@@ -102,6 +102,7 @@ private:
LLTimer mHeartbeat;
F64 mSleepTime;
+ F64 mCPUElapsed;
};
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index f18a117dde..41784a713c 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -38,7 +38,7 @@
#include "llapr.h"
// If we don't receive a heartbeat in this many seconds, we declare the plugin locked up.
-static const F32 PLUGIN_LOCKED_UP_SECONDS = 10.0f;
+static const F32 PLUGIN_LOCKED_UP_SECONDS = 15.0f;
// Somewhat longer timeout for initial launch.
static const F32 PLUGIN_LAUNCH_SECONDS = 20.0f;
@@ -87,6 +87,7 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
{
mProcess.setExecutable(launcher_filename);
mPluginFile = plugin_filename;
+ mCPUUsage = 0.0f;
setState(STATE_INITIALIZED);
}
@@ -503,6 +504,11 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
{
// this resets our timer.
mHeartbeat.setTimerExpirySec(PLUGIN_LOCKED_UP_SECONDS);
+
+ mCPUUsage = message.getValueReal("cpu_usage");
+
+ LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL;
+
}
else if(message_name == "shm_add_response")
{
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index 545eb85c9a..0d0b047c88 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -96,6 +96,8 @@ public:
bool getDisableTimeout() { return mDisableTimeout; };
void setDisableTimeout(bool disable) { mDisableTimeout = disable; };
+ F64 getCPUUsage() { return mCPUUsage; };
+
private:
enum EState
@@ -140,6 +142,7 @@ private:
LLTimer mHeartbeat;
F64 mSleepTime;
+ F64 mCPUUsage;
bool mDisableTimeout;
};