diff options
Diffstat (limited to 'indra/llplugin')
-rw-r--r-- | indra/llplugin/llpluginclassmedia.cpp | 58 | ||||
-rw-r--r-- | indra/llplugin/llpluginclassmedia.h | 15 | ||||
-rw-r--r-- | indra/llplugin/llpluginmessage.cpp | 23 | ||||
-rw-r--r-- | indra/llplugin/llpluginmessage.h | 4 | ||||
-rw-r--r-- | indra/llplugin/llpluginprocesschild.cpp | 35 | ||||
-rw-r--r-- | indra/llplugin/llpluginprocesschild.h | 1 | ||||
-rw-r--r-- | indra/llplugin/llpluginprocessparent.cpp | 8 | ||||
-rw-r--r-- | indra/llplugin/llpluginprocessparent.h | 3 |
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; }; |