diff options
author | coyot@coyot-sager-PC.hsd1.ca.comcast.net <coyot@coyot-sager-PC.hsd1.ca.comcast.net> | 2017-05-05 18:07:00 +0100 |
---|---|---|
committer | coyot@coyot-sager-PC.hsd1.ca.comcast.net <coyot@coyot-sager-PC.hsd1.ca.comcast.net> | 2017-05-05 18:07:00 +0100 |
commit | a1194ce6e9faaa259821611b51d4448fea49ddc1 (patch) | |
tree | 4d1c63b64ae44a2a1855d0e10f595495971a044d /indra/media_plugins | |
parent | c15ffb40458184002ade41ff652fab3d9ffbb761 (diff) | |
parent | 322767f98e3c3164e3be03daa85580038ca6fb52 (diff) |
pull from gate
Diffstat (limited to 'indra/media_plugins')
-rw-r--r-- | indra/media_plugins/CMakeLists.txt | 3 | ||||
-rw-r--r-- | indra/media_plugins/cef/CMakeLists.txt | 20 | ||||
-rw-r--r-- | indra/media_plugins/cef/mac_volume_catcher_null.cpp | 95 | ||||
-rw-r--r-- | indra/media_plugins/cef/media_plugin_cef.cpp | 94 | ||||
-rw-r--r-- | indra/media_plugins/example/CMakeLists.txt | 6 | ||||
-rw-r--r-- | indra/media_plugins/example/media_plugin_example.cpp | 707 |
6 files changed, 492 insertions, 433 deletions
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt index 1eadce825e..1a5cc8ec9a 100644 --- a/indra/media_plugins/CMakeLists.txt +++ b/indra/media_plugins/CMakeLists.txt @@ -5,14 +5,17 @@ add_subdirectory(base) if (LINUX) add_subdirectory(gstreamer010) add_subdirectory(libvlc) + add_subdirectory(example) endif (LINUX) if (DARWIN) add_subdirectory(cef) add_subdirectory(libvlc) + add_subdirectory(example) endif (DARWIN) if (WINDOWS) add_subdirectory(cef) add_subdirectory(libvlc) + add_subdirectory(example) endif (WINDOWS) diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index 201fb44847..5452fd9d1e 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -46,6 +46,10 @@ set(media_plugin_cef_SOURCE_FILES media_plugin_cef.cpp ) +set(media_plugin_cef_HEADER_FILES + volume_catcher.h + ) + set (media_plugin_cef_LINK_LIBRARIES ${LLPLUGIN_LIBRARIES} ${MEDIA_PLUGIN_BASE_LIBRARIES} @@ -53,7 +57,21 @@ set (media_plugin_cef_LINK_LIBRARIES ${LLCOMMON_LIBRARIES} ${PLUGIN_API_WINDOWS_LIBRARIES}) - +# Select which VolumeCatcher implementation to use +if (LINUX) + message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n" + " Please create a volume_catcher implementation for this platform.") +elseif (DARWIN) + list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher_null.cpp) + find_library(CORESERVICES_LIBRARY CoreServices) + find_library(AUDIOUNIT_LIBRARY AudioUnit) + list(APPEND media_plugin_cef_LINK_LIBRARIES + ${CORESERVICES_LIBRARY} # for Component Manager calls + ${AUDIOUNIT_LIBRARY} # for AudioUnit calls + ) +elseif (WINDOWS) + list(APPEND media_plugin_cef_SOURCE_FILES windows_volume_catcher.cpp) +endif (LINUX) set_source_files_properties(${media_plugin_cef_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/indra/media_plugins/cef/mac_volume_catcher_null.cpp b/indra/media_plugins/cef/mac_volume_catcher_null.cpp new file mode 100644 index 0000000000..f4fcef71aa --- /dev/null +++ b/indra/media_plugins/cef/mac_volume_catcher_null.cpp @@ -0,0 +1,95 @@ +/** + * @file windows_volume_catcher.cpp + * @brief A null implementation of volume level control of all audio channels opened by a process. + * We are using this for the macOS version for now until we can understand how to make the + * exitising mac_volume_catcher.cpp work without the (now, non-existant) QuickTime dependency + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +#include "volume_catcher.h" +#include "llsingleton.h" +class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl> +{ + LLSINGLETON(VolumeCatcherImpl); + // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. + ~VolumeCatcherImpl(); + +public: + + void setVolume(F32 volume); + void setPan(F32 pan); + +private: + F32 mVolume; + F32 mPan; + bool mSystemIsVistaOrHigher; +}; + +VolumeCatcherImpl::VolumeCatcherImpl() +: mVolume(1.0f), // default volume is max + mPan(0.f) // default pan is centered +{ +} + +VolumeCatcherImpl::~VolumeCatcherImpl() +{ +} + +void VolumeCatcherImpl::setVolume(F32 volume) +{ + mVolume = volume; +} + +void VolumeCatcherImpl::setPan(F32 pan) +{ // remember pan for calculating individual channel levels later + mPan = pan; +} + +///////////////////////////////////////////////////// + +VolumeCatcher::VolumeCatcher() +{ + pimpl = VolumeCatcherImpl::getInstance(); +} + +VolumeCatcher::~VolumeCatcher() +{ + // Let the instance persist until exit. +} + +void VolumeCatcher::setVolume(F32 volume) +{ + pimpl->setVolume(volume); +} + +void VolumeCatcher::setPan(F32 pan) +{ + pimpl->setPan(pan); +} + +void VolumeCatcher::pump() +{ + // No periodic tasks are necessary for this implementation. +} diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 906a5ff6e7..796e262d6f 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -34,6 +34,7 @@ #include "llplugininstance.h" #include "llpluginmessage.h" #include "llpluginmessageclasses.h" +#include "volume_catcher.h" #include "media_plugin_base.h" #include <functional> @@ -55,7 +56,7 @@ public: private: bool init(); - void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height, bool is_popup); + void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height); void onCustomSchemeURLCallback(std::string url); void onConsoleMessageCallback(std::string message, std::string source, int line); void onStatusMessageCallback(std::string value); @@ -77,13 +78,14 @@ private: void unicodeInput(LLSD native_key_data); void checkEditState(); - void setVolume(F32 vol); + void setVolume(); bool mEnableMediaPluginDebugging; std::string mHostLanguage; bool mCookiesEnabled; bool mPluginsEnabled; bool mJavascriptEnabled; + bool mDisableGPU; std::string mUserAgentSubtring; std::string mAuthUsername; std::string mAuthPassword; @@ -94,13 +96,9 @@ private: std::string mCachePath; std::string mCookiePath; std::string mPickedFile; + VolumeCatcher mVolumeCatcher; + F32 mCurVolume; dullahan* mCEFLib; - - U8 *mPopupBuffer; - U32 mPopupW; - U32 mPopupH; - U32 mPopupX; - U32 mPopupY; }; //////////////////////////////////////////////////////////////////////////////// @@ -117,6 +115,7 @@ MediaPluginBase(host_send_func, host_user_data) mCookiesEnabled = true; mPluginsEnabled = false; mJavascriptEnabled = true; + mDisableGPU = true; mUserAgentSubtring = ""; mAuthUsername = ""; mAuthPassword = ""; @@ -127,20 +126,18 @@ MediaPluginBase(host_send_func, host_user_data) mCachePath = ""; mCookiePath = ""; mPickedFile = ""; + mCurVolume = 0.0; + mCEFLib = new dullahan(); - mPopupBuffer = NULL; - mPopupW = 0; - mPopupH = 0; - mPopupX = 0; - mPopupY = 0; + setVolume(); } //////////////////////////////////////////////////////////////////////////////// // MediaPluginCEF::~MediaPluginCEF() { - delete[] mPopupBuffer; + mCEFLib->shutdown(); } //////////////////////////////////////////////////////////////////////////////// @@ -161,56 +158,13 @@ void MediaPluginCEF::postDebugMessage(const std::string& msg) //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginCEF::onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height, bool is_popup) +void MediaPluginCEF::onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height) { - if( is_popup ) - { - delete mPopupBuffer; - mPopupBuffer = NULL; - mPopupH = 0; - mPopupW = 0; - mPopupX = 0; - mPopupY = 0; - } - if( mPixels && pixels ) { - if (is_popup) + if (mWidth == width && mHeight == height) { - if( width > 0 && height> 0 ) - { - mPopupBuffer = new U8[ width * height * mDepth ]; - memcpy( mPopupBuffer, pixels, width * height * mDepth ); - mPopupH = height; - mPopupW = width; - mPopupX = x; - mPopupY = mHeight - y - height; - } - } - else - { - if (mWidth == width && mHeight == height) - { - memcpy(mPixels, pixels, mWidth * mHeight * mDepth); - } - if( mPopupBuffer && mPopupH && mPopupW ) - { - U32 bufferSize = mWidth * mHeight * mDepth; - U32 popupStride = mPopupW * mDepth; - U32 bufferStride = mWidth * mDepth; - int dstY = mPopupY; - - int src = 0; - int dst = dstY * mWidth * mDepth + mPopupX * mDepth; - - for( int line = 0; dst + popupStride < bufferSize && line < mPopupH; ++line ) - { - memcpy( mPixels + dst, mPopupBuffer + src, popupStride ); - src += popupStride; - dst += bufferStride; - } - } - + memcpy(mPixels, pixels, mWidth * mHeight * mDepth); } setDirty(0, 0, mWidth, mHeight); } @@ -258,10 +212,10 @@ void MediaPluginCEF::onLoadStartCallback() // void MediaPluginCEF::onRequestExitCallback() { - mCEFLib->shutdown(); - LLPluginMessage message("base", "goodbye"); sendMessage(message); + + mDeleteMe = true; } //////////////////////////////////////////////////////////////////////////////// @@ -477,7 +431,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) if (message_name == "init") { // event callbacks from Dullahan - mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6)); + mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1)); mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1)); @@ -499,10 +453,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string) settings.cache_path = mCachePath; settings.cookie_store_path = mCookiePath; settings.cookies_enabled = mCookiesEnabled; + settings.disable_gpu = mDisableGPU; settings.flash_enabled = mPluginsEnabled; settings.flip_mouse_y = false; settings.flip_pixels_y = true; settings.frame_rate = 60; + settings.force_wave_audio = true; settings.initial_height = 1024; settings.initial_width = 1024; settings.java_enabled = false; @@ -755,13 +711,18 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { mJavascriptEnabled = message_in.getValueBoolean("enable"); } + else if (message_name == "gpu_disabled") + { + mDisableGPU = message_in.getValueBoolean("disable"); + } } else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) { if (message_name == "set_volume") { - F32 volume = (F32)message_in.getValueReal("volume"); - setVolume(volume); + F32 volume = (F32)message_in.getValueReal("volume"); + mCurVolume = volume; + setVolume(); } } else @@ -840,8 +801,9 @@ void MediaPluginCEF::checkEditState() } } -void MediaPluginCEF::setVolume(F32 vol) +void MediaPluginCEF::setVolume() { + mVolumeCatcher.setVolume(mCurVolume); } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt index d2a17b1d76..6f5b28b8e9 100644 --- a/indra/media_plugins/example/CMakeLists.txt +++ b/indra/media_plugins/example/CMakeLists.txt @@ -60,14 +60,16 @@ target_link_libraries(media_plugin_example add_dependencies(media_plugin_example ${LLPLUGIN_LIBRARIES} ${MEDIA_PLUGIN_BASE_LIBRARIES} - ${LLCOMMON_LIBRARIES} + # Using ${LLCOMMON_LIBRARIES} here drags in a whole bunch of Boost stuff + # that only produces CMake warnings about nonexistent dependencies. + llcommon ) if (WINDOWS) set_target_properties( media_plugin_example PROPERTIES - LINK_FLAGS "/MANIFEST:NO" + LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /LTCG /NODEFAULTLIB:LIBCMT" ) endif (WINDOWS) diff --git a/indra/media_plugins/example/media_plugin_example.cpp b/indra/media_plugins/example/media_plugin_example.cpp index 66c00cd58c..c296a0413d 100644 --- a/indra/media_plugins/example/media_plugin_example.cpp +++ b/indra/media_plugins/example/media_plugin_example.cpp @@ -1,30 +1,30 @@ /** - * @file media_plugin_example.cpp - * @brief Example plugin for LLMedia API plugin system - * - * @cond - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - * @endcond - */ +* @file media_plugin_example.cpp +* @brief Example plugin for LLMedia API plugin system +* +* @cond +* $LicenseInfo:firstyear=2008&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +* @endcond +*/ #include "linden_common.h" @@ -38,375 +38,354 @@ //////////////////////////////////////////////////////////////////////////////// // -class MediaPluginExample : - public MediaPluginBase +class mediaPluginExample : + public MediaPluginBase { - public: - MediaPluginExample( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ); - ~MediaPluginExample(); - - /*virtual*/ void receiveMessage( const char* message_string ); - - private: - bool init(); - void update( F64 milliseconds ); - void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ); - bool mFirstTime; - - time_t mLastUpdateTime; - enum Constants { ENumObjects = 10 }; - unsigned char* mBackgroundPixels; - int mColorR[ ENumObjects ]; - int mColorG[ ENumObjects ]; - int mColorB[ ENumObjects ]; - int mXpos[ ENumObjects ]; - int mYpos[ ENumObjects ]; - int mXInc[ ENumObjects ]; - int mYInc[ ENumObjects ]; - int mBlockSize[ ENumObjects ]; - bool mMouseButtonDown; - bool mStopAction; +public: + mediaPluginExample(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~mediaPluginExample(); + + /*virtual*/ void receiveMessage(const char* message_string); + +private: + bool init(); + void update(F64 milliseconds); + bool mFirstTime; + + time_t mLastUpdateTime; + enum Constants { ENumObjects = 64 }; + unsigned char* mBackgroundPixels; + int mColorR[ENumObjects]; + int mColorG[ENumObjects]; + int mColorB[ENumObjects]; + int mXpos[ENumObjects]; + int mYpos[ENumObjects]; + int mXInc[ENumObjects]; + int mYInc[ENumObjects]; + int mBlockSize[ENumObjects]; }; //////////////////////////////////////////////////////////////////////////////// // -MediaPluginExample::MediaPluginExample( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) : - MediaPluginBase( host_send_func, host_user_data ) +mediaPluginExample::mediaPluginExample(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : +MediaPluginBase(host_send_func, host_user_data) { - mFirstTime = true; - mWidth = 0; - mHeight = 0; - mDepth = 4; - mPixels = 0; - mMouseButtonDown = false; - mStopAction = false; - mLastUpdateTime = 0; + mFirstTime = true; + mTextureWidth = 0; + mTextureHeight = 0; + mWidth = 0; + mHeight = 0; + mDepth = 4; + mPixels = 0; + mLastUpdateTime = 0; + mBackgroundPixels = 0; } //////////////////////////////////////////////////////////////////////////////// // -MediaPluginExample::~MediaPluginExample() +mediaPluginExample::~mediaPluginExample() { } //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginExample::receiveMessage( const char* message_string ) +void mediaPluginExample::receiveMessage(const char* message_string) { -// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; - LLPluginMessage message_in; - - if(message_in.parse(message_string) >= 0) - { - std::string message_class = message_in.getClass(); - std::string message_name = message_in.getName(); - if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) - { - if(message_name == "init") - { - LLPluginMessage message("base", "init_response"); - LLSD versions = LLSD::emptyMap(); - versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; - message.setValueLLSD("versions", versions); - - std::string plugin_version = "Example plugin 1.0..0"; - message.setValue("plugin_version", plugin_version); - sendMessage(message); - } - else if(message_name == "idle") - { - // no response is necessary here. - F64 time = message_in.getValueReal("time"); - - // Convert time to milliseconds for update() - update((int)(time * 1000.0f)); - } - else if(message_name == "cleanup") - { - } - else if(message_name == "shm_added") - { - SharedSegmentInfo info; - info.mAddress = message_in.getValuePointer("address"); - info.mSize = (size_t)message_in.getValueS32("size"); - std::string name = message_in.getValue("name"); - - mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - - } - else if(message_name == "shm_remove") - { - std::string name = message_in.getValue("name"); - - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - if(mPixels == iter->second.mAddress) - { - // This is the currently active pixel buffer. Make sure we stop drawing to it. - mPixels = NULL; - mTextureSegmentName.clear(); - } - mSharedSegments.erase(iter); - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; - } - - // Send the response so it can be cleaned up. - LLPluginMessage message("base", "shm_remove_response"); - message.setValue("name", name); - sendMessage(message); - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; - } - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) - { - if(message_name == "init") - { - // Plugin gets to decide the texture parameters to use. - mDepth = 4; - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - message.setValueS32("default_width", 1024); - message.setValueS32("default_height", 1024); - message.setValueS32("depth", mDepth); - message.setValueU32("internalformat", GL_RGBA); - message.setValueU32("format", GL_RGBA); - message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", true); - sendMessage(message); - } - else if(message_name == "size_change") - { - std::string name = message_in.getValue("name"); - S32 width = message_in.getValueS32("width"); - S32 height = message_in.getValueS32("height"); - S32 texture_width = message_in.getValueS32("texture_width"); - S32 texture_height = message_in.getValueS32("texture_height"); - - if(!name.empty()) - { - // Find the shared memory region with this name - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - mPixels = (unsigned char*)iter->second.mAddress; - mWidth = width; - mHeight = height; - - mTextureWidth = texture_width; - mTextureHeight = texture_height; - }; - }; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); - message.setValue("name", name); - message.setValueS32("width", width); - message.setValueS32("height", height); - message.setValueS32("texture_width", texture_width); - message.setValueS32("texture_height", texture_height); - sendMessage(message); - - } - else if(message_name == "load_uri") - { - } - else if(message_name == "mouse_event") - { - std::string event = message_in.getValue("event"); - if(event == "down") - { - - } - else if(event == "up") - { - } - else if(event == "double_click") - { - } - } - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; - }; - } + // std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if (message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if (message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + message.setValueLLSD("versions", versions); + + std::string plugin_version = "Example plugin 0.0.0"; + message.setValue("plugin_version", plugin_version); + sendMessage(message); + } + else if (message_name == "idle") + { + // no response is necessary here. + F64 time = message_in.getValueReal("time"); + + // Convert time to milliseconds for update() + update((int)(time * 1000.0f)); + } + else if (message_name == "cleanup") + { + LLPluginMessage message("base", "goodbye"); + sendMessage(message); + + mDeleteMe = true; + } + else if (message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if (message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + if (mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + mTextureSegmentName.clear(); + } + mSharedSegments.erase(iter); + } + else + { + // std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { + // std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if (message_name == "init") + { + // Plugin gets to decide the texture parameters to use. + mDepth = 4; + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("default_width", 1024); + message.setValueS32("default_height", 1024); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueU32("format", GL_RGBA); + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", true); + sendMessage(message); + } + else if (message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + if (!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + mPixels = (unsigned char*)iter->second.mAddress; + mWidth = width; + mHeight = height; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + }; + }; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + mFirstTime = true; + mLastUpdateTime = 0; + + } + else if (message_name == "load_uri") + { + } + else if (message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + if (event == "down") + { + + } + else if (event == "up") + { + } + else if (event == "double_click") + { + } + } + } + else + { + }; + } } //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginExample::write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ) +void mediaPluginExample::update(F64 milliseconds) { - // make sure we don't write outside the buffer - if ( ( x < 0 ) || ( x >= mWidth ) || ( y < 0 ) || ( y >= mHeight ) ) - return; - - if ( mBackgroundPixels != NULL ) - { - unsigned char *pixel = mBackgroundPixels; - pixel += y * mWidth * mDepth; - pixel += ( x * mDepth ); - pixel[ 0 ] = b; - pixel[ 1 ] = g; - pixel[ 2 ] = r; - - setDirty( x, y, x + 1, y + 1 ); - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginExample::update( F64 milliseconds ) -{ - if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 ) - return; - - if ( mPixels == 0 ) - return; - - if ( mFirstTime ) - { - for( int n = 0; n < ENumObjects; ++n ) - { - mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 ); - mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 ); - - mColorR[ n ] = rand() % 0x60 + 0x60; - mColorG[ n ] = rand() % 0x60 + 0x60; - mColorB[ n ] = rand() % 0x60 + 0x60; - - mXInc[ n ] = 0; - while ( mXInc[ n ] == 0 ) - mXInc[ n ] = rand() % 7 - 3; - - mYInc[ n ] = 0; - while ( mYInc[ n ] == 0 ) - mYInc[ n ] = rand() % 9 - 4; - - mBlockSize[ n ] = rand() % 0x30 + 0x10; - }; - - delete [] mBackgroundPixels; - - mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ]; - - mFirstTime = false; - }; - - if ( mStopAction ) - return; - - if ( time( NULL ) > mLastUpdateTime + 3 ) - { - const int num_squares = rand() % 20 + 4; - int sqr1_r = rand() % 0x80 + 0x20; - int sqr1_g = rand() % 0x80 + 0x20; - int sqr1_b = rand() % 0x80 + 0x20; - int sqr2_r = rand() % 0x80 + 0x20; - int sqr2_g = rand() % 0x80 + 0x20; - int sqr2_b = rand() % 0x80 + 0x20; - - for ( int y1 = 0; y1 < num_squares; ++y1 ) - { - for ( int x1 = 0; x1 < num_squares; ++x1 ) - { - int px_start = mWidth * x1 / num_squares; - int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares; - int py_start = mHeight * y1 / num_squares; - int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares; - - for( int y2 = py_start; y2 < py_end; ++y2 ) - { - for( int x2 = px_start; x2 < px_end; ++x2 ) - { - int rowspan = mWidth * mDepth; - - if ( ( y1 % 2 ) ^ ( x1 % 2 ) ) - { - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b; - } - else - { - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b; - }; - }; - }; - }; - }; - - time( &mLastUpdateTime ); - }; - - memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth ); - - for( int n = 0; n < ENumObjects; ++n ) - { - if ( rand() % 50 == 0 ) - { - mXInc[ n ] = 0; - while ( mXInc[ n ] == 0 ) - mXInc[ n ] = rand() % 7 - 3; - - mYInc[ n ] = 0; - while ( mYInc[ n ] == 0 ) - mYInc[ n ] = rand() % 9 - 4; - }; - - if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] ) - mXInc[ n ]= -mXInc[ n ]; - - if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] ) - mYInc[ n ]= -mYInc[ n ]; - - mXpos[ n ] += mXInc[ n ]; - mYpos[ n ] += mYInc[ n ]; - - for( int y = 0; y < mBlockSize[ n ]; ++y ) - { - for( int x = 0; x < mBlockSize[ n ]; ++x ) - { - mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ]; - mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ]; - mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ]; - }; - }; - }; - - setDirty( 0, 0, mWidth, mHeight ); + if (mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048) + return; + + if (mPixels == 0) + return; + + if (mFirstTime) + { + for (int n = 0; n < ENumObjects; ++n) + { + mXpos[n] = (mWidth / 2) + rand() % (mWidth / 16) - (mWidth / 32); + mYpos[n] = (mHeight / 2) + rand() % (mHeight / 16) - (mHeight / 32); + + mColorR[n] = rand() % 0x60 + 0x60; + mColorG[n] = rand() % 0x60 + 0x60; + mColorB[n] = rand() % 0x60 + 0x60; + + mXInc[n] = 0; + while (mXInc[n] == 0) + mXInc[n] = rand() % 7 - 3; + + mYInc[n] = 0; + while (mYInc[n] == 0) + mYInc[n] = rand() % 9 - 4; + + mBlockSize[n] = rand() % 0x30 + 0x10; + }; + + delete[] mBackgroundPixels; + + mBackgroundPixels = new unsigned char[mWidth * mHeight * mDepth]; + + mFirstTime = false; + }; + + if (time(NULL) > mLastUpdateTime + 3) + { + const int num_squares = rand() % 20 + 4; + int sqr1_r = rand() % 0x80 + 0x20; + int sqr1_g = rand() % 0x80 + 0x20; + int sqr1_b = rand() % 0x80 + 0x20; + int sqr2_r = rand() % 0x80 + 0x20; + int sqr2_g = rand() % 0x80 + 0x20; + int sqr2_b = rand() % 0x80 + 0x20; + + for (int y1 = 0; y1 < num_squares; ++y1) + { + for (int x1 = 0; x1 < num_squares; ++x1) + { + int px_start = mWidth * x1 / num_squares; + int px_end = (mWidth * (x1 + 1)) / num_squares; + int py_start = mHeight * y1 / num_squares; + int py_end = (mHeight * (y1 + 1)) / num_squares; + + for (int y2 = py_start; y2 < py_end; ++y2) + { + for (int x2 = px_start; x2 < px_end; ++x2) + { + int rowspan = mWidth * mDepth; + + if ((y1 % 2) ^ (x1 % 2)) + { + mBackgroundPixels[y2 * rowspan + x2 * mDepth + 0] = sqr1_r; + mBackgroundPixels[y2 * rowspan + x2 * mDepth + 1] = sqr1_g; + mBackgroundPixels[y2 * rowspan + x2 * mDepth + 2] = sqr1_b; + } + else + { + mBackgroundPixels[y2 * rowspan + x2 * mDepth + 0] = sqr2_r; + mBackgroundPixels[y2 * rowspan + x2 * mDepth + 1] = sqr2_g; + mBackgroundPixels[y2 * rowspan + x2 * mDepth + 2] = sqr2_b; + }; + }; + }; + }; + }; + + time(&mLastUpdateTime); + }; + + memcpy(mPixels, mBackgroundPixels, mWidth * mHeight * mDepth); + + for (int n = 0; n < ENumObjects; ++n) + { + if (rand() % 50 == 0) + { + mXInc[n] = 0; + while (mXInc[n] == 0) + mXInc[n] = rand() % 7 - 3; + + mYInc[n] = 0; + while (mYInc[n] == 0) + mYInc[n] = rand() % 9 - 4; + }; + + if (mXpos[n] + mXInc[n] < 0 || mXpos[n] + mXInc[n] >= mWidth - mBlockSize[n]) + mXInc[n] = -mXInc[n]; + + if (mYpos[n] + mYInc[n] < 0 || mYpos[n] + mYInc[n] >= mHeight - mBlockSize[n]) + mYInc[n] = -mYInc[n]; + + mXpos[n] += mXInc[n]; + mYpos[n] += mYInc[n]; + + for (int y = 0; y < mBlockSize[n]; ++y) + { + for (int x = 0; x < mBlockSize[n]; ++x) + { + mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 0] = mColorR[n]; + mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 1] = mColorG[n]; + mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 2] = mColorB[n]; + }; + }; + }; + + setDirty(0, 0, mWidth, mHeight); }; //////////////////////////////////////////////////////////////////////////////// // -bool MediaPluginExample::init() +bool mediaPluginExample::init() { - LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text" ); - message.setValue( "name", "Example Plugin" ); - sendMessage( message ); + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", "Example Plugin"); + sendMessage(message); - return true; + return true; }; //////////////////////////////////////////////////////////////////////////////// // -int init_media_plugin( LLPluginInstance::sendMessageFunction host_send_func, - void* host_user_data, - LLPluginInstance::sendMessageFunction *plugin_send_func, - void **plugin_user_data ) +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, + void* host_user_data, + LLPluginInstance::sendMessageFunction *plugin_send_func, + void **plugin_user_data) { - MediaPluginExample* self = new MediaPluginExample( host_send_func, host_user_data ); - *plugin_send_func = MediaPluginExample::staticReceiveMessage; - *plugin_user_data = ( void* )self; + mediaPluginExample* self = new mediaPluginExample(host_send_func, host_user_data); + *plugin_send_func = mediaPluginExample::staticReceiveMessage; + *plugin_user_data = (void*)self; - return 0; + return 0; } - |