From 25be08f2368d6002585d78af6077afc6409dc551 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 18 Jul 2011 04:21:36 -0500 Subject: [PATCH 01/18] Innitial commit. Did as much as I can for llmediactrl without diving too deep into llviewermedia --- indra/llplugin/llpluginclassmedia.cpp | 194 +++++++++++ indra/llplugin/llpluginclassmedia.h | 76 ++++- indra/llplugin/llpluginclassmediaowner.h | 12 +- indra/newview/llfloatermediabrowser.cpp | 47 ++- indra/newview/llfloatermediabrowser.h | 3 + indra/newview/llmediactrl.cpp | 395 +++++++++++++++-------- indra/newview/llmediactrl.h | 16 +- indra/newview/llviewermedia.h | 3 +- indra/newview/llviewertexture.cpp | 112 ++++--- indra/newview/llviewertexture.h | 26 +- 10 files changed, 682 insertions(+), 202 deletions(-) diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index c8b903e58..de208cb44 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -122,7 +122,10 @@ void LLPluginClassMedia::reset_impl(void) mStatusText.clear(); mProgressPercent = 0; mClickURL.clear(); + mClickNavType.clear(); mClickTarget.clear(); + mClickUUID.clear(); + mStatusCode = 0; // media_time class mCurrentTime = 0.0f; @@ -393,6 +396,94 @@ std::string LLPluginClassMedia::translateModifiers(MASK modifiers) return result; } +void LLPluginClassMedia::jsEnableObject( bool enable ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_enable_object"); + message.setValueBoolean( "enable", enable ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentLocationEvent( double x, double y, double z ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_location"); + message.setValueReal( "x", x ); + message.setValueReal( "y", y ); + message.setValueReal( "z", z ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentGlobalLocationEvent( double x, double y, double z ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_global_location"); + message.setValueReal( "x", x ); + message.setValueReal( "y", y ); + message.setValueReal( "z", z ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentOrientationEvent( double angle ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_orientation"); + message.setValueReal( "angle", angle ); + + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentLanguageEvent( const std::string& language ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_language"); + message.setValue( "language", language ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentRegionEvent( const std::string& region ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_region"); + message.setValue( "region", region ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentMaturityEvent( const std::string& maturity ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_maturity"); + message.setValue( "maturity", maturity ); + sendMessage( message ); +} void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers) { if(type == MOUSE_EVENT_MOVE) @@ -568,6 +659,32 @@ F64 LLPluginClassMedia::getCPUUsage() return result; } +void LLPluginClassMedia::sendPickFileResponse(const std::string &file) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response"); + message.setValue("file", file); + if(mPlugin && mPlugin->isBlocked()) + { + // If the plugin sent a blocking pick-file request, the response should unblock it. + message.setValueBoolean("blocking_response", true); + } + sendMessage(message); +} + +void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username, const std::string &password) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_response"); + message.setValueBoolean("ok", ok); + message.setValue("username", username); + message.setValue("password", password); + if(mPlugin && mPlugin->isBlocked()) + { + // If the plugin sent a blocking pick-file request, the response should unblock it. + message.setValueBoolean("blocking_response", true); + } + sendMessage(message); +} + void LLPluginClassMedia::cut() { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut"); @@ -614,6 +731,10 @@ void LLPluginClassMedia::setJavascriptEnabled(const bool enabled) sendMessage(message); } +void LLPluginClassMedia::setTarget(const std::string &target) +{ + mTarget = target; +} /* virtual */ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { @@ -828,6 +949,16 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) mMediaName = message.getValue("name"); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAME_CHANGED); } + else if(message_name == "pick_file") + { + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST); + } + else if(message_name == "auth_request") + { + mAuthURL = message.getValue("url"); + mAuthRealm = message.getValue("realm"); + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_AUTH_REQUEST); + } else { LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; @@ -870,14 +1001,21 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { mClickURL = message.getValue("uri"); mClickTarget = message.getValue("target"); + mClickUUID = message.getValue("uuid"); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF); } else if(message_name == "click_nofollow") { mClickURL = message.getValue("uri"); + mClickNavType = message.getValue("nav_type"); mClickTarget.clear(); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW); } + else if(message_name == "navigate_error_page") + { + mStatusCode = message.getValueS32("status_code"); + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE); + } else if(message_name == "cookie_set") { if(mOwner) @@ -885,6 +1023,29 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) mOwner->handleCookieSet(this, message.getValue("cookie")); } } + else if(message_name == "close_request") + { + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST); + } + else if(message_name == "geometry_change") + { + mClickUUID = message.getValue("uuid"); + mGeometryX = message.getValueS32("x"); + mGeometryY = message.getValueS32("y"); + mGeometryWidth = message.getValueS32("width"); + mGeometryHeight = message.getValueS32("height"); + + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_GEOMETRY_CHANGE); + } + else if(message_name == "link_hovered") + { + // text is not currently used -- the tooltip hover text is taken from the "title". + mHoverLink = message.getValue("link"); + mHoverText = message.getValue("title"); + // message.getValue("text"); + + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LINK_HOVERED); + } else { LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; @@ -1025,6 +1186,39 @@ void LLPluginClassMedia::setBrowserUserAgent(const std::string& user_agent) sendMessage(message); } +void LLPluginClassMedia::proxyWindowOpened(const std::string &target, const std::string &uuid) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_opened"); + + message.setValue("target", target); + message.setValue("uuid", uuid); + + sendMessage(message); +} + +void LLPluginClassMedia::proxyWindowClosed(const std::string &uuid) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_closed"); + + message.setValue("uuid", uuid); + + sendMessage(message); +} + +void LLPluginClassMedia::ignore_ssl_cert_errors(bool ignore) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "ignore_ssl_cert_errors"); + message.setValueBoolean("ignore", ignore); + sendMessage(message); +} + +void LLPluginClassMedia::addCertificateFilePath(const std::string& path) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "add_certificate_file_path"); + message.setValue("path", path); + sendMessage(message); +} + void LLPluginClassMedia::crashPlugin() { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash"); diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 2882de180..8136e9cb7 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -36,6 +36,7 @@ #ifndef LL_LLPLUGINCLASSMEDIA_H #define LL_LLPLUGINCLASSMEDIA_H +#include "llgltypes.h" #include "llpluginclassbasic.h" #include "llrect.h" #include "v4color.h" @@ -79,6 +80,8 @@ public: void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; }; + void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; }; + // Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent. // This will initially be false, and will also be false for some time after setSize while the resize is processed. // Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values @@ -88,27 +91,36 @@ public: bool getDirty(LLRect *dirty_rect = NULL); void resetDirty(void); - enum EMouseEventType + typedef enum { MOUSE_EVENT_DOWN, MOUSE_EVENT_UP, MOUSE_EVENT_MOVE, MOUSE_EVENT_DOUBLE_CLICK - }; + }EMouseEventType; void mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers); - enum EKeyEventType + typedef enum { KEY_EVENT_DOWN, KEY_EVENT_UP, KEY_EVENT_REPEAT - }; + }EKeyEventType; bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data); void scrollEvent(int x, int y, MASK modifiers); - + + // Javascript <-> viewer events + void jsEnableObject( bool enable ); + void jsAgentLocationEvent( double x, double y, double z ); + void jsAgentGlobalLocationEvent( double x, double y, double z ); + void jsAgentOrientationEvent( double angle ); + void jsAgentLanguageEvent( const std::string& language ); + void jsAgentRegionEvent( const std::string& region_name ); + void jsAgentMaturityEvent( const std::string& maturity ); + // Text may be unicode (utf8 encoded) bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data); @@ -124,6 +136,10 @@ public: void setLowPrioritySizeLimit(int size); F64 getCPUUsage(); + + void sendPickFileResponse(const std::string &file); + + void sendAuthResponse(bool ok, const std::string &username, const std::string &password); // Valid after a MEDIA_EVENT_CURSOR_CHANGED event std::string getCursorName() const { return mCursorName; }; @@ -144,7 +160,8 @@ public: void setLanguageCode(const std::string &language_code); void setPluginsEnabled(const bool enabled); void setJavascriptEnabled(const bool enabled); - + void setTarget(const std::string &target); + /////////////////////////////////// // media browser class functions bool pluginSupportsMediaBrowser(void); @@ -161,6 +178,10 @@ public: void browse_back(); void set_status_redirect(int code, const std::string &url); void setBrowserUserAgent(const std::string& user_agent); + void proxyWindowOpened(const std::string &target, const std::string &uuid); + void proxyWindowClosed(const std::string &uuid); + void ignore_ssl_cert_errors(bool ignore); + void addCertificateFilePath(const std::string& path); // This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE std::string getNavigateURI() const { return mNavigateURI; }; @@ -183,10 +204,32 @@ public: // This is valid after MEDIA_EVENT_CLICK_LINK_HREF or MEDIA_EVENT_CLICK_LINK_NOFOLLOW std::string getClickURL() const { return mClickURL; }; + // This is valid after MEDIA_EVENT_CLICK_LINK_NOFOLLOW + std::string getClickNavType() const { return mClickNavType; }; + // This is valid after MEDIA_EVENT_CLICK_LINK_HREF std::string getClickTarget() const { return mClickTarget; }; + // This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE + std::string getClickUUID() const { return mClickUUID; }; + // This is valid after MEDIA_EVENT_NAVIGATE_ERROR_PAGE + S32 getStatusCode() const { return mStatusCode; }; + + // These are valid during MEDIA_EVENT_GEOMETRY_CHANGE + S32 getGeometryX() const { return mGeometryX; }; + S32 getGeometryY() const { return mGeometryY; }; + S32 getGeometryWidth() const { return mGeometryWidth; }; + S32 getGeometryHeight() const { return mGeometryHeight; }; + + // These are valid during MEDIA_EVENT_AUTH_REQUEST + std::string getAuthURL() const { return mAuthURL; }; + std::string getAuthRealm() const { return mAuthRealm; }; + + // These are valid during MEDIA_EVENT_LINK_HOVERED + std::string getHoverText() const { return mHoverText; }; + std::string getHoverLink() const { return mHoverLink; }; + std::string getMediaName() const { return mMediaName; }; std::string getMediaDescription() const { return mMediaDescription; }; @@ -228,12 +271,12 @@ protected: protected: LLPluginClassMediaOwner *mOwner; - + bool mTextureParamsReceived; // the mRequestedTexture* fields are only valid when this is true S32 mRequestedTextureDepth; - U32 mRequestedTextureInternalFormat; - U32 mRequestedTextureFormat; - U32 mRequestedTextureType; + LLGLenum mRequestedTextureInternalFormat; + LLGLenum mRequestedTextureFormat; + LLGLenum mRequestedTextureType; bool mRequestedTextureSwapBytes; bool mRequestedTextureCoordsOpenGL; @@ -299,6 +342,8 @@ protected: LLColor4 mBackgroundColor; + std::string mTarget; + ///////////////////////////////////////// // media_browser class std::string mNavigateURI; @@ -310,7 +355,18 @@ protected: int mProgressPercent; std::string mLocation; std::string mClickURL; + std::string mClickNavType; std::string mClickTarget; + std::string mClickUUID; + S32 mGeometryX; + S32 mGeometryY; + S32 mGeometryWidth; + S32 mGeometryHeight; + S32 mStatusCode; + std::string mAuthURL; + std::string mAuthRealm; + std::string mHoverText; + std::string mHoverLink; ///////////////////////////////////////// // media_time class diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h index 9d1f35220..0083e0c41 100644 --- a/indra/llplugin/llpluginclassmediaowner.h +++ b/indra/llplugin/llpluginclassmediaowner.h @@ -59,11 +59,19 @@ public: MEDIA_EVENT_STATUS_TEXT_CHANGED, // browser has updated the status text MEDIA_EVENT_NAME_CHANGED, // browser has updated the name of the media (typically tag) MEDIA_EVENT_LOCATION_CHANGED, // browser location (URL) has changed (maybe due to internal navagation/frames/etc) + MEDIA_EVENT_NAVIGATE_ERROR_PAGE, // browser navigated to a page that resulted in an HTTP error MEDIA_EVENT_CLICK_LINK_HREF, // I'm not entirely sure what the semantics of these two are MEDIA_EVENT_CLICK_LINK_NOFOLLOW, - + MEDIA_EVENT_CLOSE_REQUEST, // The plugin requested its window be closed (currently hooked up to javascript window.close in webkit) + MEDIA_EVENT_PICK_FILE_REQUEST, // The plugin wants the user to pick a file + MEDIA_EVENT_GEOMETRY_CHANGE, // The plugin requested its window geometry be changed (per the javascript window interface) + MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch - MEDIA_EVENT_PLUGIN_FAILED // The plugin died unexpectedly + MEDIA_EVENT_PLUGIN_FAILED, // The plugin died unexpectedly + + MEDIA_EVENT_AUTH_REQUEST, // The plugin wants to display an auth dialog + + MEDIA_EVENT_LINK_HOVERED // Got a "link hovered" event from the plugin } EMediaEvent; diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp index def015943..a90ea14f3 100644 --- a/indra/newview/llfloatermediabrowser.cpp +++ b/indra/newview/llfloatermediabrowser.cpp @@ -62,6 +62,28 @@ LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& media_data) } + +void LLFloaterMediaBrowser::geometryChanged(S32 x, S32 y, S32 width, S32 height) +{ + // Make sure the layout of the browser control is updated, so this calculation is correct. + LLLayoutStack::updateClass(); + + // TODO: need to adjust size and constrain position to make sure floaters aren't moved outside the window view, etc. + LLCoordWindow window_size; + getWindow()->getSize(&window_size); + + // Adjust width and height for the size of the chrome on the Media Browser window. + width += getRect().getWidth() - mBrowser->getRect().getWidth(); + height += getRect().getHeight() - mBrowser->getRect().getHeight(); + + LLRect geom; + geom.setOriginAndSize(x, window_size.mY - (y + height), width, height); + + lldebugs << "geometry change: " << geom << llendl; + + handleReshape(geom,false); +} + void LLFloaterMediaBrowser::draw() { childSetEnabled("go", !mAddressCombo->getValue().asString().empty()); @@ -105,6 +127,7 @@ BOOL LLFloaterMediaBrowser::postBuild() mAddressCombo = getChild<LLComboBox>("address"); mAddressCombo->setCommitCallback(onEnterAddress); mAddressCombo->setCallbackUserData(this); + mAddressCombo->sortByName(); childSetAction("back", onClickBack, this); childSetAction("forward", onClickForward, this); @@ -146,7 +169,10 @@ void LLFloaterMediaBrowser::buildURLHistory() } // initialize URL history in the plugin - mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history); + if(mBrowser && mBrowser->getMediaPlugin()) + { + mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history); + } } std::string LLFloaterMediaBrowser::getSupportURL() @@ -171,6 +197,15 @@ void LLFloaterMediaBrowser::handleMediaEvent(LLPluginClassMedia* self, EMediaEve childSetEnabled("back", self->getHistoryBackAvailable()); childSetEnabled("forward", self->getHistoryForwardAvailable()); } + else if(event == MEDIA_EVENT_CLOSE_REQUEST) + { + // The browser instance wants its window closed. + close(); + } + else if(event == MEDIA_EVENT_GEOMETRY_CHANGE) + { + geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight()); + } } void LLFloaterMediaBrowser::setCurrentURL(const std::string& url) { @@ -213,7 +248,15 @@ void LLFloaterMediaBrowser::onClickRefresh(void* user_data) LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; self->mAddressCombo->remove(0); - self->mBrowser->navigateTo(self->mCurrentURL); + if( self->mBrowser->getMediaPlugin() && self->mBrowser->getMediaPlugin()->pluginSupportsMediaBrowser()) + { + bool ignore_cache = true; + self->mBrowser->getMediaPlugin()->browse_reload( ignore_cache ); + } + else + { + self->mBrowser->navigateTo(self->mCurrentURL); + } } //static diff --git a/indra/newview/llfloatermediabrowser.h b/indra/newview/llfloatermediabrowser.h index 47a3b158d..afdd6e733 100644 --- a/indra/newview/llfloatermediabrowser.h +++ b/indra/newview/llfloatermediabrowser.h @@ -64,6 +64,9 @@ class LLFloaterMediaBrowser : public: LLFloaterMediaBrowser(const LLSD& media_data); + + void geometryChanged(S32 x, S32 y, S32 width, S32 height); + /*virtual*/ BOOL postBuild(); /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void draw(); diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index f524be097..f90037f31 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -64,6 +64,7 @@ static LLRegisterWidget<LLMediaCtrl> r("web_browser"); LLMediaCtrl::LLMediaCtrl( const std::string& name, const LLRect& rect ) : LLUICtrl( name, rect, FALSE, NULL, NULL ), + LLInstanceTracker<LLMediaCtrl, LLUUID>(LLUUID::generateNewID()), mTextureDepthBytes( 4 ), mWebBrowserImage( 0 ), mBorder(NULL), @@ -82,28 +83,26 @@ LLMediaCtrl::LLMediaCtrl( const std::string& name, const LLRect& rect ) : mLastSetCursor( UI_CURSOR_ARROW ), mStretchToFill( true ), mMaintainAspectRatio ( true ), + mDecoupleTextureSize ( false ), + mTextureWidth ( 1024 ), + mTextureHeight ( 1024 ), mHideLoading (false) { - S32 screen_width = mIgnoreUIScale ? - llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth(); - S32 screen_height = mIgnoreUIScale ? - llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight(); - - mMediaSource = LLViewerMedia::newMediaImpl(mHomePageUrl, LLUUID::null, screen_width, screen_height, false, false, "text/html"); - if ( !mMediaSource ) + if(!getDecoupleTextureSize()) { - llwarns << "media source create failed " << llendl; - return; + S32 screen_width = mIgnoreUIScale ? + llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth(); + S32 screen_height = mIgnoreUIScale ? + llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight(); + + setTextureSize(screen_width, screen_height); } - else + // We don't need to create the media source up front anymore unless we have a non-empty home URL to navigate to. + if(!mHomePageUrl.empty()) { - // create a new texture (based on LLDynamic texture) that will be used to display the output - mWebBrowserImage = new LLWebBrowserTexture( screen_width, screen_height, this, mMediaSource ); + navigateHome(); } - - mMediaSource->setVisible( getVisible() ); - - mMediaSource->addObserver( this ); + LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 ); mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN ); @@ -121,10 +120,7 @@ LLMediaCtrl::~LLMediaCtrl() mMediaSource = NULL; } - if ( mWebBrowserImage ) - { - mWebBrowserImage = NULL; - } + mWebBrowserImage = NULL; } //////////////////////////////////////////////////////////////////////////////// @@ -144,6 +140,7 @@ void LLMediaCtrl::setTakeFocusOnClick( bool take_focus ) mTakeFocusOnClick = take_focus; } + //////////////////////////////////////////////////////////////////////////////// // set flag that forces the embedded browser to open links in the external system browser void LLMediaCtrl::setOpenInExternalBrowser( bool valIn ) @@ -168,12 +165,15 @@ void LLMediaCtrl::setTrusted( bool valIn ) // BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask ) { + if (LLUICtrl::handleHover(x, y, mask)) return TRUE; convertInputCoords(x, y); if (mMediaSource) + { mMediaSource->mouseMove(x, y); - gViewerWindow->setCursor(mLastSetCursor); + gViewerWindow->setCursor(mLastSetCursor); + } return TRUE; } @@ -182,6 +182,7 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask ) // BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) { + if (LLUICtrl::handleScrollWheel(x, y, clicks)) return TRUE; if (mMediaSource && mMediaSource->hasMedia()) mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, MASK_NONE); @@ -192,19 +193,20 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) // BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) { + if (LLUICtrl::handleMouseUp(x, y, mask)) return TRUE; convertInputCoords(x, y); if (mMediaSource) { mMediaSource->mouseUp(x, y); - // *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup, + /*// *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup, // in addition to the onFocusReceived() call below. Undo this. JC if (!mTakeFocusOnClick) { mMediaSource->focus(false); gViewerWindow->focusClient(); - } + }*/ } gFocusMgr.setMouseCapture( NULL ); @@ -216,6 +218,7 @@ BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) // BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) { + if (LLUICtrl::handleMouseDown(x, y, mask)) return TRUE; convertInputCoords(x, y); if (mMediaSource) @@ -233,12 +236,60 @@ BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) //////////////////////////////////////////////////////////////////////////////// // -BOOL LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask ) +BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask ) { + /*if (LLPanel::handleRightMouseUp(x, y, mask)) return TRUE; convertInputCoords(x, y); if (mMediaSource) - mMediaSource->mouseLeftDoubleClick( x, y ); + { + mMediaSource->mouseUp(x, y, mask, 1); + + // *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup, + // in addition to the onFocusReceived() call below. Undo this. JC + if (!mTakeFocusOnClick) + { + mMediaSource->focus(false); + gViewerWindow->focusClient(); + } + } + + gFocusMgr.setMouseCapture( NULL ); + */ + return TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask ) +{ + if (LLUICtrl::handleRightMouseDown(x, y, mask)) return TRUE; + + /*S32 media_x = x, media_y = y; + convertInputCoords(media_x, media_y); + + if (mMediaSource) + mMediaSource->mouseDown(media_x, media_y); + + gFocusMgr.setMouseCapture( this ); + + if (mTakeFocusOnClick) + { + setFocus( TRUE ); + } + */ + return TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask ) +{ + if (LLUICtrl::handleDoubleClick(x, y, mask)) return TRUE; + convertInputCoords(x, y); + + if (mMediaSource) + mMediaSource->mouseLeftDoubleClick( x, y); gFocusMgr.setMouseCapture( this ); @@ -374,18 +425,18 @@ void LLMediaCtrl::onVisibilityChange ( BOOL new_visibility ) // void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) { - S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width; - S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height; - -// llinfos << "reshape called with width = " << width << ", height = " << height << llendl; - - // when floater is minimized, these sizes are negative - if ( mWebBrowserImage && screen_height > 0 && screen_width > 0 ) + if(!getDecoupleTextureSize()) { - mWebBrowserImage->resize( screen_width, screen_height ); - mForceUpdate = true; - } + S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width; + S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height; + // when floater is minimized, these sizes are negative + if ( screen_height > 0 && screen_width > 0 ) + { + setTextureSize(screen_width, screen_height); + } + } + LLUICtrl::reshape( width, height, called_from_parent ); } @@ -460,9 +511,10 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type) return; } - if (mMediaSource) + if (ensureMediaSourceExists()) { mCurrentNavUrl = url_in; + mMediaSource->setSize(mTextureWidth, mTextureHeight); mMediaSource->navigateTo(url_in, mime_type, mime_type.empty()); } } @@ -498,9 +550,10 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str return; } } - if (mMediaSource) + if (ensureMediaSourceExists()) { mCurrentNavUrl = expanded_filename; + mMediaSource->setSize(mTextureWidth, mTextureHeight); mMediaSource->navigateTo(expanded_filename, "text/html", false); } @@ -510,11 +563,11 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str // void LLMediaCtrl::navigateHome() { - if( mHomePageUrl.length() ) + if (ensureMediaSourceExists()) { - if (mMediaSource) - mMediaSource->navigateTo(mHomePageUrl); - }; + mMediaSource->setSize(mTextureWidth, mTextureHeight); + mMediaSource->navigateHome(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -522,6 +575,10 @@ void LLMediaCtrl::navigateHome() void LLMediaCtrl::setHomePageUrl( const std::string urlIn ) { mHomePageUrl = urlIn; + if (mMediaSource) + { + mMediaSource->setHomeURL(mHomePageUrl); + } } //////////////////////////////////////////////////////////////////////////////// @@ -531,6 +588,22 @@ bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned i //NOOP return false; } + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::setTextureSize(S32 width, S32 height) +{ + mTextureWidth = width; + mTextureHeight = height; + + if(mMediaSource) + { + mMediaSource->setSize(mTextureWidth, mTextureHeight); + mWebBrowserImage->resize( mTextureWidth, mTextureHeight ); + mForceUpdate = true; + } +} + //////////////////////////////////////////////////////////////////////////////// // std::string LLMediaCtrl::getHomePageUrl() @@ -538,6 +611,39 @@ std::string LLMediaCtrl::getHomePageUrl() return mHomePageUrl; } +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaCtrl::ensureMediaSourceExists() +{ + if(mMediaSource.isNull()) + { + mMediaSource = LLViewerMedia::newMediaImpl(mHomePageUrl, LLUUID::null, mTextureWidth, mTextureWidth, false, false, "text/html"); + if ( mMediaSource ) + { + // create a new texture (based on LLDynamic texture) that will be used to display the output + mWebBrowserImage = new LLWebBrowserTexture( mTextureWidth, mTextureWidth, this, mMediaSource ); + mMediaSource->setHomeURL(mHomePageUrl); + mMediaSource->setVisible( getVisible() ); + mMediaSource->addObserver( this ); + } + else + { + llwarns << "media source create failed " << llendl; + // return; + } + } + + return !mMediaSource.isNull(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::unloadMediaSource() +{ + mMediaSource = NULL; + mWebBrowserImage = NULL; //release the dynamic texture too. +} + //////////////////////////////////////////////////////////////////////////////// // LLPluginClassMedia* LLMediaCtrl::getMediaPlugin() @@ -575,111 +681,132 @@ void LLMediaCtrl::draw() LLGLSUIDefault gls_ui; LLGLDisable gls_alphaTest( GL_ALPHA_TEST ); - gGL.pushMatrix(); + bool draw_media = false; + + LLPluginClassMedia* media_plugin = NULL; + LLWebBrowserTexture* media_texture = mWebBrowserImage; + + if(mMediaSource && mMediaSource->hasMedia()) { - if (mIgnoreUIScale) - { - glLoadIdentity(); - // font system stores true screen origin, need to scale this by UI scale factor - // to get render origin for this view (with unit scale) - gGL.translatef(floorf(LLFontGL::sCurOrigin.mX * LLUI::sGLScaleFactor.mV[VX]), - floorf(LLFontGL::sCurOrigin.mY * LLUI::sGLScaleFactor.mV[VY]), - LLFontGL::sCurOrigin.mZ); - } + media_plugin = mMediaSource->getMediaPlugin(); - // scale texture to fit the space using texture coords - gGL.getTexUnit(0)->bind(mWebBrowserImage); - gGL.color4fv( LLColor4::white.mV ); - F32 max_u = ( F32 )mWebBrowserImage->getMediaWidth() / ( F32 )mWebBrowserImage->getWidth(); - F32 max_v = ( F32 )mWebBrowserImage->getMediaHeight() / ( F32 )mWebBrowserImage->getHeight(); - - LLRect r = getRect(); - S32 width, height; - S32 x_offset = 0; - S32 y_offset = 0; - - if(mStretchToFill) + if(media_plugin && (media_plugin->textureValid())) { - if(mMaintainAspectRatio) + media_texture = mWebBrowserImage; + if(media_texture) { - F32 media_aspect = (F32)(mWebBrowserImage->getMediaWidth()) / (F32)(mWebBrowserImage->getMediaHeight()); - F32 view_aspect = (F32)(r.getWidth()) / (F32)(r.getHeight()); - if(media_aspect > view_aspect) + draw_media = true; + } + } + } + if(draw_media) + { + gGL.pushMatrix(); + { + if (mIgnoreUIScale) + { + glLoadIdentity(); + // font system stores true screen origin, need to scale this by UI scale factor + // to get render origin for this view (with unit scale) + gGL.translatef(floorf(LLFontGL::sCurOrigin.mX * LLUI::sGLScaleFactor.mV[VX]), + floorf(LLFontGL::sCurOrigin.mY * LLUI::sGLScaleFactor.mV[VY]), + LLFontGL::sCurOrigin.mZ); + } + + // scale texture to fit the space using texture coords + gGL.getTexUnit(0)->bind(media_texture); + LLColor4 media_color = LLColor4::white; + gGL.color4fv( media_color.mV ); + F32 max_u = ( F32 )media_plugin->getWidth() / ( F32 )media_plugin->getTextureWidth(); + F32 max_v = ( F32 )media_plugin->getHeight() / ( F32 )media_plugin->getTextureHeight(); + + LLRect r = getRect(); + S32 width, height; + S32 x_offset = 0; + S32 y_offset = 0; + + if(mStretchToFill) + { + if(mMaintainAspectRatio) { - // max width, adjusted height - width = r.getWidth(); - height = llmin(llmax(S32(width / media_aspect), 0), r.getHeight()); + F32 media_aspect = (F32)(media_plugin->getWidth()) / (F32)(media_plugin->getHeight()); + F32 view_aspect = (F32)(r.getWidth()) / (F32)(r.getHeight()); + if(media_aspect > view_aspect) + { + // max width, adjusted height + width = r.getWidth(); + height = llmin(llmax(llround(width / media_aspect), 0), r.getHeight()); + } + else + { + // max height, adjusted width + height = r.getHeight(); + width = llmin(llmax(llround(height * media_aspect), 0), r.getWidth()); + } } else { - // max height, adjusted width + width = r.getWidth(); height = r.getHeight(); - width = llmin(llmax(S32(height * media_aspect), 0), r.getWidth()); } } else { - width = r.getWidth(); - height = r.getHeight(); + width = llmin(media_plugin->getWidth(), r.getWidth()); + height = llmin(media_plugin->getHeight(), r.getHeight()); } + + x_offset = (r.getWidth() - width) / 2; + y_offset = (r.getHeight() - height) / 2; + + if (mIgnoreUIScale) + { + x_offset = llround((F32)x_offset * LLUI::sGLScaleFactor.mV[VX]); + y_offset = llround((F32)y_offset * LLUI::sGLScaleFactor.mV[VY]); + width = llround((F32)width * LLUI::sGLScaleFactor.mV[VX]); + height = llround((F32)height * LLUI::sGLScaleFactor.mV[VY]); + } + + // draw the browser + gGL.setSceneBlendType(LLRender::BT_REPLACE); + gGL.begin( LLRender::QUADS ); + if (! media_plugin->getTextureCoordsOpenGL()) + { + // render using web browser reported width and height, instead of trying to invert GL scale + gGL.texCoord2f( max_u, 0.f ); + gGL.vertex2i( x_offset + width, y_offset + height ); + + gGL.texCoord2f( 0.f, 0.f ); + gGL.vertex2i( x_offset, y_offset + height ); + + gGL.texCoord2f( 0.f, max_v ); + gGL.vertex2i( x_offset, y_offset ); + + gGL.texCoord2f( max_u, max_v ); + gGL.vertex2i( x_offset + width, y_offset ); + } + else + { + // render using web browser reported width and height, instead of trying to invert GL scale + gGL.texCoord2f( max_u, max_v ); + gGL.vertex2i( x_offset + width, y_offset + height ); + + gGL.texCoord2f( 0.f, max_v ); + gGL.vertex2i( x_offset, y_offset + height ); + + gGL.texCoord2f( 0.f, 0.f ); + gGL.vertex2i( x_offset, y_offset ); + + gGL.texCoord2f( max_u, 0.f ); + gGL.vertex2i( x_offset + width, y_offset ); + } + gGL.end(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); } - else - { - width = llmin(mWebBrowserImage->getMediaWidth(), r.getWidth()); - height = llmin(mWebBrowserImage->getMediaHeight(), r.getHeight()); - } - - x_offset = (r.getWidth() - width) / 2; - y_offset = (r.getHeight() - height) / 2; - - if (mIgnoreUIScale) - { - width = llround((F32)width * LLUI::sGLScaleFactor.mV[VX]); - height = llround((F32)height * LLUI::sGLScaleFactor.mV[VY]); - x_offset = llround((F32)x_offset * LLUI::sGLScaleFactor.mV[VX]); - y_offset = llround((F32)y_offset * LLUI::sGLScaleFactor.mV[VY]); - } - - // draw the browser - gGL.setSceneBlendType(LLRender::BT_REPLACE); - gGL.begin( LLRender::QUADS ); - if (! mWebBrowserImage->getTextureCoordsOpenGL()) - { - // render using web browser reported width and height, instead of trying to invert GL scale - gGL.texCoord2f( max_u, 0.f ); - gGL.vertex2i( x_offset + width, y_offset + height ); - - gGL.texCoord2f( 0.f, 0.f ); - gGL.vertex2i( x_offset, y_offset + height ); - - gGL.texCoord2f( 0.f, max_v ); - gGL.vertex2i( x_offset, y_offset ); - - gGL.texCoord2f( max_u, max_v ); - gGL.vertex2i( x_offset + width, y_offset ); - } - else - { - // render using web browser reported width and height, instead of trying to invert GL scale - gGL.texCoord2f( max_u, max_v ); - gGL.vertex2i( x_offset + width, y_offset + height ); - - gGL.texCoord2f( 0.f, max_v ); - gGL.vertex2i( x_offset, y_offset + height ); - - gGL.texCoord2f( 0.f, 0.f ); - gGL.vertex2i( x_offset, y_offset ); - - gGL.texCoord2f( max_u, 0.f ); - gGL.vertex2i( x_offset + width, y_offset ); - } - gGL.end(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + gGL.popMatrix(); } - gGL.popMatrix(); - // highlight if keyboard focus here. (TODO: this needs some work) - if ( mBorder->getVisible() ) + if ( mBorder && mBorder->getVisible() ) mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) ); @@ -690,8 +817,15 @@ void LLMediaCtrl::draw() // void LLMediaCtrl::convertInputCoords(S32& x, S32& y) { + bool coords_opengl = false; + + if(mMediaSource && mMediaSource->hasMedia()) + { + coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL(); + } + x = mIgnoreUIScale ? llround((F32)x * LLUI::sGLScaleFactor.mV[VX]) : x; - if ( ! mWebBrowserImage->getTextureCoordsOpenGL() ) + if ( ! coords_opengl ) { y = mIgnoreUIScale ? llround((F32)(y) * LLUI::sGLScaleFactor.mV[VY]) : y; } @@ -930,7 +1064,6 @@ LLWebBrowserTexture::LLWebBrowserTexture( S32 width, S32 height, LLMediaCtrl* br LLWebBrowserTexture::~LLWebBrowserTexture() { mElapsedTime.stop(); - mMediaSource = NULL; } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index bbf2dfa01..bd5fa03ac 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -48,7 +48,8 @@ class LLUICtrlFactory; class LLMediaCtrl : public LLUICtrl, public LLViewerMediaObserver, - public LLViewerMediaEventEmitter + public LLViewerMediaEventEmitter, + public LLInstanceTracker<LLMediaCtrl, LLUUID> { public: LLMediaCtrl( const std::string& name, const LLRect& rect ); @@ -69,6 +70,8 @@ class LLMediaCtrl : virtual BOOL handleHover( S32 x, S32 y, MASK mask ); virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); @@ -112,10 +115,17 @@ class LLMediaCtrl : void setForceUpdate(bool force_update) { mForceUpdate = force_update; } bool getForceUpdate() { return mForceUpdate; } + bool ensureMediaSourceExists(); + void unloadMediaSource(); + LLPluginClassMedia* getMediaPlugin(); bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ); + + void setDecoupleTextureSize(bool decouple) { mDecoupleTextureSize = decouple; } + bool getDecoupleTextureSize() { return mDecoupleTextureSize; } + void setTextureSize(S32 width, S32 height); // over-rides virtual BOOL handleKeyHere( KEY key, MASK mask); @@ -143,6 +153,7 @@ class LLMediaCtrl : static bool onClickLinkExternalTarget( const LLSD&, const LLSD& ); const S32 mTextureDepthBytes; + LLUUID mMediaTextureID; LLPointer<LLWebBrowserTexture> mWebBrowserImage; LLViewBorder* mBorder; bool mFrequentUpdates; @@ -161,6 +172,9 @@ class LLMediaCtrl : bool mStretchToFill; bool mMaintainAspectRatio; bool mHideLoading; + bool mDecoupleTextureSize; + S32 mTextureWidth; + S32 mTextureHeight; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 6b8bd2217..aebfbec76 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -122,7 +122,8 @@ public: bool canNavigateForward(); bool canNavigateBack(); std::string getMediaURL() { return mMediaURL; } - std::string getMediaHomeURL() { return mHomeURL; } + std::string getHomeURL() { return mHomeURL; } + void setHomeURL(const std::string& home_url) { mHomeURL = home_url; } std::string getMimeType() { return mMimeType; } void getTextureSize(S32 *texture_width, S32 *texture_height); void scaleMouse(S32 *mouse_x, S32 *mouse_y); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index d1c3a40f2..c24959c2a 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -66,7 +66,9 @@ //#include "lltextureatlas.h" //#include "lltextureatlasmanager.h" #include "lltextureentry.h" -//#include "llmediaentry.h" +#if NEW_MEDIA_TEXTURE +#include "llmediaentry.h" +#endif //NEW_MEDIA_TEXTURE #include "llvovolume.h" #include "llviewermedia.h" /////////////////////////////////////////////////////////////////////////////// @@ -79,9 +81,11 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL; #if NEW_MEDIA_TEXTURE LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ; +#endif //NEW_MEDIA_TEXTURE +#if 0 +LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ; #endif -//LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ; -//const std::string sTesterName("TextureTester"); +const std::string sTesterName("TextureTester"); S32 LLViewerTexture::sImageCount = 0; S32 LLViewerTexture::sRawCount = 0; @@ -171,7 +175,7 @@ LLViewerMediaTexture* LLViewerTextureManager::createMediaTexture(const LLUUID &m { return new LLViewerMediaTexture(media_id, usemipmaps, gl_image) ; } -#endif +#endif //NEW_MEDIA_TEXTURE LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id) { @@ -185,7 +189,7 @@ LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id) { tex = LLViewerTextureManager::findMediaTexture(id) ; } -#endif +#endif //NEW_MEDIA_TEXTURE return tex ; } @@ -207,7 +211,7 @@ LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, return tex ; } -#endif +#endif //NEW_MEDIA_TEXTURE LLViewerFetchedTexture* LLViewerTextureManager::staticCastToFetchedTexture(LLTexture* tex, BOOL report_error) { @@ -358,7 +362,8 @@ void LLViewerTextureManager::init() LLViewerTexture::initClass() ; - /*if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) +#if 0 + if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) { sTesterp = new LLTexturePipelineTester() ; if (!sTesterp->isValid()) @@ -366,7 +371,8 @@ void LLViewerTextureManager::init() delete sTesterp; sTesterp = NULL; } - }*/ + } +#endif } void LLViewerTextureManager::cleanup() @@ -382,7 +388,7 @@ void LLViewerTextureManager::cleanup() #if NEW_MEDIA_TEXTURE LLViewerMediaTexture::cleanUpClass() ; -#endif +#endif //NEW_MEDIA_TEXTURE } //---------------------------------------------------------------------------------------------- @@ -432,14 +438,16 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity { sCurrentTime = gFrameTimeSeconds ; - /*LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +#if 0 + LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); if (tester) { tester->update() ; - }*/ + } +#endif #if NEW_MEDIA_TEXTURE LLViewerMediaTexture::updateClass() ; -#endif +#endif //NEW_MEDIA_TEXTURE sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes @@ -560,7 +568,9 @@ void LLViewerTexture::init(bool firstinit) mFaceList.clear() ; mVolumeList.clear(); +#if !NEW_MEDIA_TEXTURE mIsMediaTexture = false; +#endif //!NEW_MEDIA_TEXTURE } //virtual @@ -632,11 +642,13 @@ bool LLViewerTexture::bindDefaultImage(S32 stage) //check if there is cached raw image and switch to it if possible switchToCachedImage() ; - /*LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +#if 0 + LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); if (tester) { tester->updateGrayTextureBinding() ; - }*/ + } +#endif return res; } @@ -1096,11 +1108,13 @@ BOOL LLViewerTexture::isLargeImage() //virtual void LLViewerTexture::updateBindStatsForTester() { - /*LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +#if 0 + LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); if (tester) { tester->updateTextureBindingStats(this) ; - }*/ + } +#endif } //---------------------------------------------------------------------------------------------- @@ -1888,12 +1902,14 @@ bool LLViewerFetchedTexture::updateFetch() // We may have data ready regardless of whether or not we are finished (e.g. waiting on write) if (mRawImage.notNull()) { - /*LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +#if 0 + LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); if (tester) { mIsFetched = TRUE ; tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)) ; - }*/ + } +#endif mRawDiscardLevel = fetch_discard; if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && (current_discard < 0 || mRawDiscardLevel < current_discard)) @@ -3134,11 +3150,13 @@ void LLViewerLODTexture::scaleDown() { switchToCachedImage() ; - /*LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +#if 0 + LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); if (tester) { tester->setStablizingTime() ; - }*/ + } +#endif } } //---------------------------------------------------------------------------------------------- @@ -3154,7 +3172,7 @@ void LLViewerMediaTexture::updateClass() { static const F32 MAX_INACTIVE_TIME = 30.f ; -#if NEW_MEDIA_TEXTURE +#if 0 //force to play media. gSavedSettings.setBOOL("AudioStreamingMedia", true) ; #endif @@ -3247,7 +3265,7 @@ LLViewerMediaTexture::~LLViewerMediaTexture() tex->setParcelMedia(NULL) ; } } -#endif +#endif //NEW_MEDIA_TEXTURE void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */) { llassert(mGLTexturep.notNull()) ; @@ -3641,7 +3659,7 @@ F32 LLViewerMediaTexture::getMaxVirtualSize() return mMaxVirtualSize ; } -#endif +#endif //NEW_MEDIA_TEXTURE //---------------------------------------------------------------------------------------------- //end of LLViewerMediaTexture //---------------------------------------------------------------------------------------------- @@ -3743,22 +3761,23 @@ void LLTexturePipelineTester::reset() //virtual void LLTexturePipelineTester::outputTestRecord(LLSD *sd) { - (*sd)[mCurLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded ; - (*sd)[mCurLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache ; - (*sd)[mCurLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage ; - (*sd)[mCurLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties ; + std::string currentLabel = getCurrentLabelName(); + (*sd)[currentLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded ; + (*sd)[currentLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache ; + (*sd)[currentLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage ; + (*sd)[currentLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties ; - (*sd)[mCurLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime ; - (*sd)[mCurLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime ; - (*sd)[mCurLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime ; + (*sd)[currentLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime ; + (*sd)[currentLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime ; + (*sd)[currentLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime ; - (*sd)[mCurLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties ; - (*sd)[mCurLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties ; + (*sd)[currentLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties ; + (*sd)[currentLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties ; - (*sd)[mCurLabel]["Time"] = LLImageGL::sLastFrameTime ; - (*sd)[mCurLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed ; - (*sd)[mCurLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage ; - (*sd)[mCurLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded) ; + (*sd)[currentLabel]["Time"] = LLImageGL::sLastFrameTime ; + (*sd)[currentLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed ; + (*sd)[currentLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage ; + (*sd)[currentLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded) ; } void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep) @@ -3847,7 +3866,7 @@ void LLTexturePipelineTester::compareTestSessions(std::ofstream* os) } //compare and output the comparison - *os << llformat("%s\n", mName.c_str()) ; + *os << llformat("%s\n", getTesterName().c_str()) ; *os << llformat("AggregateResults\n") ; compareTestResults(os, "TotalFetchingTime", base_sessionp->mTotalFetchingTime, current_sessionp->mTotalFetchingTime) ; @@ -3902,7 +3921,7 @@ void LLTexturePipelineTester::compareTestSessions(std::ofstream* os) } //virtual -LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSession(LLSD* log) +LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::loadTestSession(LLSD* log) { LLTexturePipelineTester::LLTextureTestSession* sessionp = new LLTexturePipelineTester::LLTextureTestSession() ; if(!sessionp) @@ -3929,12 +3948,11 @@ LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSessi sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f ; //load a session - BOOL in_log = (*log).has(mCurLabel) ; - while(in_log) + std::string currentLabel = getCurrentLabelName(); + BOOL in_log = (*log).has(currentLabel) ; + while (in_log) { - LLSD::String label = mCurLabel ; - incLabel() ; - in_log = (*log).has(mCurLabel) ; + LLSD::String label = currentLabel ; if(sessionp->mInstantPerformanceListCounter >= (S32)sessionp->mInstantPerformanceList.size()) { @@ -4000,7 +4018,11 @@ LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSessi sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0 ; sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f ; sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f ; - } + } + // Next label + incrementCurrentCount() ; + currentLabel = getCurrentLabelName(); + in_log = (*log).has(currentLabel) ; } sessionp->mTotalFetchingTime += total_fetching_time ; @@ -4040,7 +4062,7 @@ void LLTexturePipelineTester::LLTextureTestSession::reset() mInstantPerformanceListCounter = 0 ; } -#endif //0 +#endif 0 //---------------------------------------------------------------------------------------------- //end of LLTexturePipelineTester //---------------------------------------------------------------------------------------------- diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index ad59d37c8..9bfdcd6f3 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -40,7 +40,9 @@ #include "llhost.h" #include "llgltypes.h" #include "llrender.h" -//#include "llmetricperformancetester.h" +#if 0 +#include "llmetricperformancetester.h" +#endif #include <map> #include <list> @@ -620,14 +622,16 @@ class LLViewerMediaTexture : public LLViewerTexture { #if NEW_MEDIA_TEXTURE protected: - *virtual*/ ~LLViewerMediaTexture() ; + /*virtual*/ ~LLViewerMediaTexture() ; public: LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; - /*virtual*/* S8 getType() const; -#endif + /*virtual*/ S8 getType() const; +#endif //NEW_MEDIA_TEXTURE +#if !NEW_MEDIA_TEXTURE public: +#endif //!NEW_MEDIA_TEXTURE void reinit(BOOL usemipmaps = TRUE); BOOL getUseMipMaps() {return mUseMipMaps ; } @@ -642,7 +646,7 @@ public: void invalidateMediaImpl() ; void addMediaToFace(LLFace* facep) ; - void removeMediaFromFace(LLFace* facep) ;*/ + void removeMediaFromFace(LLFace* facep) ; /*virtual*/ void addFace(LLFace* facep) ; /*virtual*/ void removeFace(LLFace* facep) ; @@ -678,7 +682,7 @@ public: private: typedef std::map< LLUUID, LLPointer<LLViewerMediaTexture> > media_map_t ; static media_map_t sMediaMap ; -#endif +#endif //NEW_MEDIA_TEXTURE }; //just an interface class, do not create instance from this class. @@ -690,7 +694,9 @@ private: public: //texture pipeline tester - //static LLTexturePipelineTester* sTesterp ; +#if 0 + static LLTexturePipelineTester* sTesterp ; +#endif //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture. static LLViewerFetchedTexture* staticCastToFetchedTexture(LLTexture* tex, BOOL report_error = FALSE) ; @@ -708,7 +714,7 @@ public: //"get-texture" will create a new texture if the texture does not exist. // static LLViewerMediaTexture* getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; -#endif +#endif //NEW_MEDIA_TEXTURE static LLPointer<LLViewerTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE); static LLPointer<LLViewerTexture> getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; @@ -839,8 +845,8 @@ private: S32 mInstantPerformanceListCounter ; }; - /*virtual*/ LLMetricPerformanceTester::LLTestSession* loadTestSession(LLSD* log) ; + /*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ; /*virtual*/ void compareTestSessions(std::ofstream* os) ; }; -#endif //0 +#endif #endif From 4f8186b17e3fa79be189f50d5bcd7385a5c7fbd1 Mon Sep 17 00:00:00 2001 From: Shyotl <Shyotl@gmail.com> Date: Tue, 2 Aug 2011 16:21:44 -0500 Subject: [PATCH 02/18] Debug symbols for llcommon.dll on windows. --- indra/newview/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b095c90d4..7109b8169 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1613,6 +1613,13 @@ endif (LL_TESTS) if (WINDOWS) get_target_property(BUILT_LLCOMMON llcommon LOCATION) + + set_target_properties(llcommon + PROPERTIES + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\"" + ) + add_custom_command( TARGET ${VIEWER_BINARY_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} From 2c489d77412877827bbf02d379b3c4e45a134eaf Mon Sep 17 00:00:00 2001 From: Shyotl <Shyotl@gmail.com> Date: Thu, 4 Aug 2011 01:38:56 -0500 Subject: [PATCH 03/18] Cleaned up polymesh (mesh vectors/normals size match VBO vectors/normals size to allow memcpy). Prep for vbo testing. --- indra/newview/llpolymesh.cpp | 82 +++---- indra/newview/llpolymesh.h | 12 +- indra/newview/llpolymorph.cpp | 65 +++--- indra/newview/llviewerjointmesh.cpp | 279 +++++++++-------------- indra/newview/llviewerjointmesh_sse.cpp | 8 +- indra/newview/llviewerjointmesh_sse2.cpp | 8 +- indra/newview/llviewerjointmesh_vec.cpp | 8 +- indra/newview/llvovolume.cpp | 35 ++- indra/newview/llvovolume.h | 4 +- indra/newview/pipeline.cpp | 11 +- 10 files changed, 235 insertions(+), 277 deletions(-) diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index 7c433cb43..180c3dd2e 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -769,29 +769,23 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_ } else { -#if 1 // Allocate memory without initializing every vector + // Allocate memory without initializing every vector // NOTE: This makes asusmptions about the size of LLVector[234] int nverts = mSharedData->mNumVertices; - int nfloats = nverts * (3*5 + 2 + 4); - mVertexData = new F32[nfloats]; + int nfloats = nverts * (2*4 + 3*3 + 2 + 4); + //use 16 byte aligned vertex data to make LLPolyMesh SSE friendly + mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4); int offset = 0; - mCoords = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; + mCoords = (LLVector4*)(mVertexData + offset); offset += 4*nverts; + mNormals = (LLVector4*)(mVertexData + offset); offset += 4*nverts; + mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts; + mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts; + + // these members don't need to be 16-byte aligned, but the first one might be + // read during an aligned memcpy of mTexCoords + mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; + mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts; - mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts; -#else - mCoords = new LLVector3[mSharedData->mNumVertices]; - mNormals = new LLVector3[mSharedData->mNumVertices]; - mScaledNormals = new LLVector3[mSharedData->mNumVertices]; - mBinormals = new LLVector3[mSharedData->mNumVertices]; - mScaledBinormals = new LLVector3[mSharedData->mNumVertices]; - mTexCoords = new LLVector2[mSharedData->mNumVertices]; - mClothingWeights = new LLVector4[mSharedData->mNumVertices]; - memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices); -#endif initializeForMorph(); } } @@ -806,19 +800,11 @@ LLPolyMesh::~LLPolyMesh() for (i = 0; i < mJointRenderData.count(); i++) { delete mJointRenderData[i]; - mJointRenderData[i] = NULL; - } -#if 0 // These are now allocated as one big uninitialized chunk - delete [] mCoords; - delete [] mNormals; - delete [] mScaledNormals; - delete [] mBinormals; - delete [] mScaledBinormals; - delete [] mClothingWeights; - delete [] mTexCoords; -#else - delete [] mVertexData; -#endif + mJointRenderData[i] = NULL; + } + + ll_aligned_free_16(mVertexData); + } @@ -1242,7 +1228,7 @@ BOOL LLPolyMesh::saveOBJ(LLFILE *fp) int nfaces = mSharedData->mNumFaces; int i; - LLVector3* coords = getWritableCoords(); + LLVector4* coords = getWritableCoords(); for ( i=0; i<nverts; i++) { std::string outstring = llformat("v %f %f %f\n", coords[i][0], @@ -1254,7 +1240,7 @@ BOOL LLPolyMesh::saveOBJ(LLFILE *fp) } } - LLVector3* normals = getWritableNormals(); + LLVector4* normals = getWritableNormals(); for ( i=0; i<nverts; i++) { std::string outstring = llformat("vn %f %f %f\n", normals[i][0], @@ -1311,8 +1297,8 @@ BOOL LLPolyMesh::loadOBJ(LLFILE *fp) int nnormals = 0; int ntexcoords = 0; - LLVector3* coords = getWritableCoords(); - LLVector3* normals = getWritableNormals(); + LLVector4* coords = getWritableCoords(); + LLVector4* normals = getWritableNormals(); LLVector3* binormals = getWritableBinormals(); LLVector2* tex = getWritableTexCoords(); LLPolyFace* faces = getFaces(); @@ -1467,8 +1453,8 @@ BOOL LLPolyMesh::setSharedFromCurrent() LLPolyMesh delta(mSharedData, NULL); U32 nverts = delta.getNumVertices(); - LLVector3 *delta_coords = delta.getWritableCoords(); - LLVector3 *delta_normals = delta.getWritableNormals(); + LLVector4 *delta_coords = delta.getWritableCoords(); + LLVector4 *delta_normals = delta.getWritableNormals(); LLVector3 *delta_binormals = delta.getWritableBinormals(); LLVector2 *delta_tex_coords = delta.getWritableTexCoords(); @@ -1497,8 +1483,8 @@ BOOL LLPolyMesh::setSharedFromCurrent() LLPolyMesh* mesh = avatarp->getMesh(mSharedData); if (mesh) { - LLVector3 *mesh_coords = mesh->getWritableCoords(); - LLVector3 *mesh_normals = mesh->getWritableNormals(); + LLVector4 *mesh_coords = mesh->getWritableCoords(); + LLVector4 *mesh_normals = mesh->getWritableNormals(); LLVector3 *mesh_binormals = mesh->getWritableBinormals(); LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords(); LLVector3 *mesh_scaled_normals = mesh->getScaledNormals(); @@ -1509,10 +1495,10 @@ BOOL LLPolyMesh::setSharedFromCurrent() mesh_coords[vert_index] -= delta_coords[vert_index]; mesh_tex_coords[vert_index] -= delta_tex_coords[vert_index]; - mesh_scaled_normals[vert_index] -= delta_normals[vert_index]; + mesh_scaled_normals[vert_index] -= LLVector3(delta_normals[vert_index]); LLVector3 normalized_normal = mesh_scaled_normals[vert_index]; normalized_normal.normVec(); - mesh_normals[vert_index] = normalized_normal; + mesh_normals[vert_index] = LLVector4(normalized_normal); mesh_scaled_binormals[vert_index] -= delta_binormals[vert_index]; LLVector3 tangent = mesh_scaled_binormals[vert_index] % normalized_normal; @@ -1616,7 +1602,7 @@ void LLPolyMesh::dumpDiagInfo(void*) //----------------------------------------------------------------------------- // getWritableCoords() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getWritableCoords() +LLVector4 *LLPolyMesh::getWritableCoords() { return mCoords; } @@ -1624,7 +1610,7 @@ LLVector3 *LLPolyMesh::getWritableCoords() //----------------------------------------------------------------------------- // getWritableNormals() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getWritableNormals() +LLVector4 *LLPolyMesh::getWritableNormals() { return mNormals; } @@ -1679,8 +1665,12 @@ void LLPolyMesh::initializeForMorph() if (!mSharedData) return; - memcpy(mCoords, mSharedData->mBaseCoords, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ + for (U32 i = 0; i < (U32)mSharedData->mNumVertices; ++i) + { + mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]); + mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]); + } + memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h index 15c284a1a..a91d88c71 100644 --- a/indra/newview/llpolymesh.h +++ b/indra/newview/llpolymesh.h @@ -240,15 +240,15 @@ public: } // Get coords - const LLVector3 *getCoords() const{ + const LLVector4 *getCoords() const{ return mCoords; } // non const version - LLVector3 *getWritableCoords(); + LLVector4 *getWritableCoords(); // Get normals - const LLVector3 *getNormals() const{ + const LLVector4 *getNormals() const{ return mNormals; } @@ -270,7 +270,7 @@ public: } // intermediate morphed normals and output normals - LLVector3 *getWritableNormals(); + LLVector4 *getWritableNormals(); LLVector3 *getScaledNormals(); LLVector3 *getWritableBinormals(); @@ -368,11 +368,11 @@ protected: // Single array of floats for allocation / deletion F32 *mVertexData; // deformed vertices (resulting from application of morph targets) - LLVector3 *mCoords; + LLVector4 *mCoords; // deformed normals (resulting from application of morph targets) LLVector3 *mScaledNormals; // output normals (after normalization) - LLVector3 *mNormals; + LLVector4 *mNormals; // deformed binormals (resulting from application of morph targets) LLVector3 *mScaledBinormals; // output binormals (after normalization) diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp index 4cf59a209..9b2a7b4a5 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/newview/llpolymorph.cpp @@ -282,16 +282,16 @@ BOOL LLPolyMorphData::saveOBJ(LLFILE *fp) LLPolyMesh mesh(mMesh, NULL); - LLVector3 *coords = mesh.getWritableCoords(); - LLVector3 *normals = mesh.getWritableNormals(); + LLVector4 *coords = mesh.getWritableCoords(); + LLVector4 *normals = mesh.getWritableNormals(); LLVector2 *tex_coords = mesh.getWritableTexCoords(); for(U32 vert_index_morph = 0; vert_index_morph < mNumIndices; vert_index_morph++) { S32 vert_index_mesh = mVertexIndices[vert_index_morph]; - coords[vert_index_mesh] += mCoords[vert_index_morph]; - normals[vert_index_mesh] += mNormals[vert_index_morph]; + coords[vert_index_mesh] += LLVector4(mCoords[vert_index_morph]); + normals[vert_index_mesh] += LLVector4(mNormals[vert_index_morph]); normals[vert_index_mesh].normVec(); tex_coords[vert_index_mesh] += mTexCoords[vert_index_morph]; } @@ -307,8 +307,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) if (!morph) return FALSE; - LLVector3 *morph_coords = morph->getWritableCoords(); - LLVector3 *morph_normals = morph->getWritableNormals(); + LLVector4 *morph_coords = morph->getWritableCoords(); + LLVector4 *morph_normals = morph->getWritableNormals(); LLVector3 *morph_binormals = morph->getWritableBinormals(); LLVector2 *morph_tex_coords = morph->getWritableTexCoords(); @@ -318,8 +318,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) LLPolyMesh delta(mMesh, NULL); U32 nverts = delta.getNumVertices(); - LLVector3 *delta_coords = delta.getWritableCoords(); - LLVector3 *delta_normals = delta.getWritableNormals(); + LLVector4 *delta_coords = delta.getWritableCoords(); + LLVector4 *delta_normals = delta.getWritableNormals(); LLVector3 *delta_binormals = delta.getWritableBinormals(); LLVector2 *delta_tex_coords = delta.getWritableTexCoords(); @@ -380,8 +380,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) { new_vertex_indices[morph_index] = vert_index; - new_coords[morph_index] = delta_coords[vert_index]; - new_normals[morph_index] = delta_normals[vert_index]; + new_coords[morph_index] = LLVector3(delta_coords[vert_index]); + new_normals[morph_index] = LLVector3(delta_normals[vert_index]); new_binormals[morph_index] = delta_binormals[vert_index]; new_tex_coords[morph_index] = delta_tex_coords[vert_index]; @@ -417,8 +417,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) { vert_index = mVertexIndices[morph_index]; - delta_coords[vert_index] -= mCoords[morph_index]; - delta_normals[vert_index] -= mNormals[morph_index]; + delta_coords[vert_index] -= LLVector4(mCoords[morph_index]); + delta_normals[vert_index] -= LLVector4(mNormals[morph_index]); delta_binormals[vert_index] -= mBinormals[morph_index]; delta_tex_coords[vert_index] -= mTexCoords[morph_index]; } @@ -456,8 +456,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) continue; } - LLVector3 *mesh_coords = mesh->getWritableCoords(); - LLVector3 *mesh_normals = mesh->getWritableNormals(); + LLVector4 *mesh_coords = mesh->getWritableCoords(); + LLVector4 *mesh_normals = mesh->getWritableNormals(); LLVector3 *mesh_binormals = mesh->getWritableBinormals(); LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords(); LLVector3 *mesh_scaled_normals = mesh->getScaledNormals(); @@ -468,10 +468,10 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) mesh_coords[vert_index] += delta_coords[vert_index] * weight; mesh_tex_coords[vert_index] += delta_tex_coords[vert_index] * weight; - mesh_scaled_normals[vert_index] += delta_normals[vert_index] * weight * NORMAL_SOFTEN_FACTOR; + mesh_scaled_normals[vert_index] += LLVector3(delta_normals[vert_index] * weight * NORMAL_SOFTEN_FACTOR); LLVector3 normalized_normal = mesh_scaled_normals[vert_index]; normalized_normal.normVec(); - mesh_normals[vert_index] = normalized_normal; + mesh_normals[vert_index] = LLVector4(normalized_normal); mesh_scaled_binormals[vert_index] += delta_binormals[vert_index] * weight * NORMAL_SOFTEN_FACTOR; LLVector3 tangent = mesh_scaled_binormals[vert_index] % normalized_normal; @@ -797,10 +797,10 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) if (delta_weight != 0.f) { llassert(!mMesh->isLOD()); - LLVector3 *coords = mMesh->getWritableCoords(); + LLVector4 *coords = mMesh->getWritableCoords(); LLVector3 *scaled_normals = mMesh->getScaledNormals(); - LLVector3 *normals = mMesh->getWritableNormals(); + LLVector4 *normals = mMesh->getWritableNormals(); LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); LLVector3 *binormals = mMesh->getWritableBinormals(); @@ -820,7 +820,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) maskWeight = maskWeightArray[vert_index_morph]; } - coords[vert_index_mesh] += mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight; + coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight); + if (getInfo()->mIsClothingMorph && clothing_weights) { LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight; @@ -835,7 +836,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; LLVector3 normalized_normal = scaled_normals[vert_index_mesh]; normalized_normal.normVec(); - normals[vert_index_mesh] = normalized_normal; + normals[vert_index_mesh] = LLVector4(normalized_normal); // calculate new binormals scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; @@ -906,31 +907,31 @@ BOOL LLPolyMorphTarget::undoMask(BOOL delete_mask) F32 *mask_weights = mVertMask->getMorphMaskWeights(); - LLVector3 *coords = mMesh->getWritableCoords(); + LLVector4 *coords = mMesh->getWritableCoords(); LLVector3 *scaled_normals = mMesh->getScaledNormals(); LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); LLVector2 *tex_coords = mMesh->getWritableTexCoords(); for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++) { - F32 mask_weight = 1.f; - if (mask_weights) - { - mask_weight = mask_weights[vert]; - } + F32 mask_weight = 1.f; + if (mask_weights) + { + mask_weight = mask_weights[vert]; + } - F32 last_mask_weight = mLastWeight * mask_weight; + F32 lastMaskWeight = mLastWeight * mask_weights[vert]; S32 out_vert = mMorphData->mVertexIndices[vert]; // remove effect of existing masked morph - coords[out_vert] -= mMorphData->mCoords[vert] * last_mask_weight; - scaled_normals[out_vert] -= mMorphData->mNormals[vert] * last_mask_weight * NORMAL_SOFTEN_FACTOR; - scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * last_mask_weight * NORMAL_SOFTEN_FACTOR; - tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * last_mask_weight; + coords[out_vert] -= LLVector4(mMorphData->mCoords[vert]) * lastMaskWeight; + scaled_normals[out_vert] -= mMorphData->mNormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; + scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; + tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight; if (clothing_weights) { - LLVector3 clothing_offset = mMorphData->mCoords[vert] * last_mask_weight; + LLVector3 clothing_offset = mMorphData->mCoords[vert] * lastMaskWeight; LLVector4* clothing_weight = &clothing_weights[out_vert]; clothing_weight->mV[VX] -= clothing_offset.mV[VX]; clothing_weight->mV[VY] -= clothing_offset.mV[VY]; diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 36e9b71f6..762218711 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -61,6 +61,7 @@ #include "v4math.h" #include "m3math.h" #include "m4math.h" +#include "llmatrix4a.h" #if !LL_DARWIN && !LL_LINUX && !LL_SOLARIS extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB; @@ -382,6 +383,7 @@ const S32 NUM_AXES = 3; // pivot parent 0-n -- child = n+1 static LLMatrix4 gJointMatUnaligned[32]; +static LLMatrix4a gJointMatAligned[32]; static LLMatrix3 gJointRotUnaligned[32]; static LLVector4 gJointPivot[32]; @@ -467,6 +469,14 @@ void LLViewerJointMesh::uploadJointMatrices() glUniform4fvARB(gAvatarMatrixParam, 45, mat); stop_glerror(); } + else + { + //load gJointMatUnaligned into gJointMatAligned + for (joint_num = 0; joint_num < reference_mesh->mJointRenderData.count(); ++joint_num) + { + gJointMatAligned[joint_num].loadu(gJointMatUnaligned[joint_num]); + } + } } //-------------------------------------------------------------------- @@ -516,6 +526,8 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) U32 triangle_count = 0; + S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel; + stop_glerror(); //---------------------------------------------------------------- @@ -531,7 +543,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) stop_glerror(); - LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), gRenderForSelect ? 0.0f : mShiny && !(mFace->getPool()->getVertexShaderLevel() > 0)); + LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getVertexShaderLevel() > 0 && !gRenderForSelect) ? 0.f : mShiny); //---------------------------------------------------------------- // setup current texture @@ -541,7 +553,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP; if (mTestImageName) { - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName); + gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName); if (mIsTransparent) { @@ -550,14 +562,14 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) else { glColor4f(0.7f, 0.6f, 0.3f, 1.f); - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); + gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); } } else if( !is_dummy && mLayerSet ) { if( mLayerSet->hasComposite() ) { - gGL.getTexUnit(0)->bind(mLayerSet->getComposite()); + gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getComposite()); } else { @@ -567,7 +579,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { llwarns << "Layerset without composite" << llendl; } - gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); + gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); } } else @@ -577,24 +589,25 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { old_mode = mTexture->getAddressMode(); } - gGL.getTexUnit(0)->bind(mTexture); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(diffuse_channel)->bind(mTexture); + gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + } else { - gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR)); + gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR)); } if (gRenderForSelect) { if (isTransparent()) { - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); - gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_CONST_ALPHA); + gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); + gGL.getTexUnit(diffuse_channel)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_CONST_ALPHA); } else { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); } } @@ -631,13 +644,13 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) if (mTestImageName) { - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + gGL.getTexUnit(diffuse_channel)->setTextureBlendType(LLTexUnit::TB_MULT); } if (mTexture.notNull() && !is_dummy) { - gGL.getTexUnit(0)->bind(mTexture.get()); - gGL.getTexUnit(0)->setTextureAddressMode(old_mode); + gGL.getTexUnit(diffuse_channel)->bind(mTexture); + gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(old_mode); } return triangle_count; @@ -648,6 +661,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) //----------------------------------------------------------------------------- void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area) { + num_vertices = (num_vertices + 0x3) & ~0x3; // Do a pre-alloc pass to determine sizes of data. if (mMesh && mValid) { @@ -676,6 +690,16 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w return; } + LLDrawPool *poolp = mFace->getPool(); + BOOL hardware_skinning = (poolp && poolp->getVertexShaderLevel() > 0) ? TRUE : FALSE; + + if (!hardware_skinning && terse_update) + { //no need to do terse updates if we're doing software vertex skinning + // since mMesh is being copied into mVertexBuffer every frame + return; + } + + LLStrider<LLVector3> verticesp; LLStrider<LLVector3> normalsp; LLStrider<LLVector2> tex_coordsp; @@ -686,111 +710,64 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w // Copy data into the faces from the polymesh data. if (mMesh && mValid) { - if (mMesh->getNumVertices()) + const U32 num_verts = mMesh->getNumVertices(); + + if (num_verts) { - stop_glerror(); face->getGeometryAvatar(verticesp, normalsp, tex_coordsp, vertex_weightsp, clothing_weightsp); - stop_glerror(); face->getVertexBuffer()->getIndexStrider(indicesp); - stop_glerror(); verticesp += mMesh->mFaceVertexOffset; - tex_coordsp += mMesh->mFaceVertexOffset; normalsp += mMesh->mFaceVertexOffset; - vertex_weightsp += mMesh->mFaceVertexOffset; - clothing_weightsp += mMesh->mFaceVertexOffset; - - const U32* __restrict coords = (U32*) mMesh->getCoords(); - const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords(); - const U32* __restrict normals = (U32*) mMesh->getNormals(); - const U32* __restrict weights = (U32*) mMesh->getWeights(); - const U32* __restrict cloth_weights = (U32*) mMesh->getClothingWeights(); - - const U32 num_verts = mMesh->getNumVertices(); - - U32 i = 0; - - const U32 skip = verticesp.getSkip()/sizeof(U32); - - U32* __restrict v = (U32*) verticesp.get(); - U32* __restrict n = (U32*) normalsp.get(); - if (terse_update) + //F32* v = (F32*) verticesp.get(); + //F32* n = (F32*) normalsp.get(); + + //U32 words = num_verts*4; + + //LLVector4a::memcpyNonAliased16(v, (F32*) mMesh->getCoords(), words*sizeof(F32)); + verticesp.assignArray((U8*)mMesh->getCoords(), sizeof(mMesh->getCoords()[0]), num_verts); + //LLVector4a::memcpyNonAliased16(n, (F32*) mMesh->getNormals(), words*sizeof(F32)); + normalsp.assignArray((U8*)mMesh->getNormals(), sizeof(mMesh->getNormals()[0]), num_verts); + + + if (!terse_update) { - for (S32 i = num_verts; i > 0; --i) - { - //morph target application only, only update positions and normals - v[0] = coords[0]; - v[1] = coords[1]; - v[2] = coords[2]; - coords += 3; - v += skip; - } + vertex_weightsp += mMesh->mFaceVertexOffset; + clothing_weightsp += mMesh->mFaceVertexOffset; + tex_coordsp += mMesh->mFaceVertexOffset; + + //F32* tc = (F32*) tex_coordsp.get(); + //F32* vw = (F32*) vertex_weightsp.get(); + //F32* cw = (F32*) clothing_weightsp.get(); - for (S32 i = num_verts; i > 0; --i) - { - n[0] = normals[0]; - n[1] = normals[1]; - n[2] = normals[2]; - normals += 3; - n += skip; - } + //LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), num_verts*2*sizeof(F32)); + tex_coordsp.assignArray((U8*)mMesh->getTexCoords(), sizeof(mMesh->getTexCoords()[0]), num_verts); + //LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), num_verts*sizeof(F32)); + vertex_weightsp.assignArray((U8*)mMesh->getWeights(), sizeof(mMesh->getWeights()[0]), num_verts); + //LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32)); + clothing_weightsp.assignArray((U8*)mMesh->getClothingWeights(), sizeof(mMesh->getClothingWeights()[0]), num_verts); } - else - { - U32* __restrict tc = (U32*) tex_coordsp.get(); - U32* __restrict vw = (U32*) vertex_weightsp.get(); - U32* __restrict cw = (U32*) clothing_weightsp.get(); - - do - { - v[0] = *(coords++); - v[1] = *(coords++); - v[2] = *(coords++); - v += skip; - - tc[0] = *(tex_coords++); - tc[1] = *(tex_coords++); - tc += skip; - - n[0] = *(normals++); - n[1] = *(normals++); - n[2] = *(normals++); - n += skip; - - vw[0] = *(weights++); - vw += skip; - - cw[0] = *(cloth_weights++); - cw[1] = *(cloth_weights++); - cw[2] = *(cloth_weights++); - cw[3] = *(cloth_weights++); - cw += skip; - } - while (++i < num_verts); - - const U32 idx_count = mMesh->getNumFaces()*3; + const U32 idx_count = mMesh->getNumFaces()*3; indicesp += mMesh->mFaceIndexOffset; - U16* __restrict idx = indicesp.get(); - S32* __restrict src_idx = (S32*) mMesh->getFaces(); + U16* __restrict idx = indicesp.get(); + S32* __restrict src_idx = (S32*) mMesh->getFaces(); - i = 0; + const S32 offset = (S32) mMesh->mFaceVertexOffset; - const S32 offset = (S32) mMesh->mFaceVertexOffset; - - do - { - *(idx++) = *(src_idx++)+offset; - } - while (++i < idx_count); + for (S32 i = 0; i < (S32)idx_count; ++i) + { + *(idx++) = *(src_idx++)+offset; } } } } + + //----------------------------------------------------------------------------- // updateLOD() //----------------------------------------------------------------------------- @@ -812,85 +789,45 @@ void LLViewerJointMesh::updateGeometryOriginal(LLFace *mFace, LLPolyMesh *mMesh) buffer->getVertexStrider(o_vertices, 0); buffer->getNormalStrider(o_normals, 0); - F32 last_weight = F32_MAX; - LLMatrix4 gBlendMat; - LLMatrix3 gBlendRotMat; + F32* __restrict vert = o_vertices[0].mV; + F32* __restrict norm = o_normals[0].mV; + + const F32* __restrict weights = mMesh->getWeights(); + const LLVector4a* __restrict coords = (LLVector4a*) mMesh->getCoords(); + const LLVector4a* __restrict normals = (LLVector4a*) mMesh->getNormals(); + + U32 offset = mMesh->mFaceVertexOffset*4; + vert += offset; + norm += offset; - const F32* weights = mMesh->getWeights(); - const LLVector3* coords = mMesh->getCoords(); - const LLVector3* normals = mMesh->getNormals(); for (U32 index = 0; index < mMesh->getNumVertices(); index++) { - U32 bidx = index + mMesh->mFaceVertexOffset; - - // blend by first matrix - F32 w = weights[index]; - - // Maybe we don't have to change gBlendMat. - // Profiles of a single-avatar scene on a Mac show this to be a very - // common case. JC - if (w == last_weight) + // equivalent to joint = floorf(weights[index]); + S32 joint = _mm_cvtt_ss2si(_mm_load_ss(weights+index)); + F32 w = weights[index] - joint; + + LLMatrix4a gBlendMat; + + if (w != 0.f) { - o_vertices[bidx] = coords[index] * gBlendMat; - o_normals[bidx] = normals[index] * gBlendRotMat; - continue; + // blend between matrices and apply + gBlendMat.setLerp(gJointMatAligned[joint+0], + gJointMatAligned[joint+1], w); + + LLVector4a res; + gBlendMat.affineTransform(coords[index], res); + res.store4a(vert+index*4); + gBlendMat.rotate(normals[index], res); + res.store4a(norm+index*4); } - - last_weight = w; - - S32 joint = llfloor(w); - w -= joint; - - // No lerp required in this case. - if (w == 1.0f) - { - gBlendMat = gJointMatUnaligned[joint+1]; - o_vertices[bidx] = coords[index] * gBlendMat; - gBlendRotMat = gJointRotUnaligned[joint+1]; - o_normals[bidx] = normals[index] * gBlendRotMat; - continue; + else + { // No lerp required in this case. + LLVector4a res; + gJointMatAligned[joint].affineTransform(coords[index], res); + res.store4a(vert+index*4); + gJointMatAligned[joint].rotate(normals[index], res); + res.store4a(norm+index*4); } - - // Try to keep all the accesses to the matrix data as close - // together as possible. This function is a hot spot on the - // Mac. JC - LLMatrix4 &m0 = gJointMatUnaligned[joint+1]; - LLMatrix4 &m1 = gJointMatUnaligned[joint+0]; - - gBlendMat.mMatrix[VX][VX] = lerp(m1.mMatrix[VX][VX], m0.mMatrix[VX][VX], w); - gBlendMat.mMatrix[VX][VY] = lerp(m1.mMatrix[VX][VY], m0.mMatrix[VX][VY], w); - gBlendMat.mMatrix[VX][VZ] = lerp(m1.mMatrix[VX][VZ], m0.mMatrix[VX][VZ], w); - - gBlendMat.mMatrix[VY][VX] = lerp(m1.mMatrix[VY][VX], m0.mMatrix[VY][VX], w); - gBlendMat.mMatrix[VY][VY] = lerp(m1.mMatrix[VY][VY], m0.mMatrix[VY][VY], w); - gBlendMat.mMatrix[VY][VZ] = lerp(m1.mMatrix[VY][VZ], m0.mMatrix[VY][VZ], w); - - gBlendMat.mMatrix[VZ][VX] = lerp(m1.mMatrix[VZ][VX], m0.mMatrix[VZ][VX], w); - gBlendMat.mMatrix[VZ][VY] = lerp(m1.mMatrix[VZ][VY], m0.mMatrix[VZ][VY], w); - gBlendMat.mMatrix[VZ][VZ] = lerp(m1.mMatrix[VZ][VZ], m0.mMatrix[VZ][VZ], w); - - gBlendMat.mMatrix[VW][VX] = lerp(m1.mMatrix[VW][VX], m0.mMatrix[VW][VX], w); - gBlendMat.mMatrix[VW][VY] = lerp(m1.mMatrix[VW][VY], m0.mMatrix[VW][VY], w); - gBlendMat.mMatrix[VW][VZ] = lerp(m1.mMatrix[VW][VZ], m0.mMatrix[VW][VZ], w); - - o_vertices[bidx] = coords[index] * gBlendMat; - - LLMatrix3 &n0 = gJointRotUnaligned[joint+1]; - LLMatrix3 &n1 = gJointRotUnaligned[joint+0]; - - gBlendRotMat.mMatrix[VX][VX] = lerp(n1.mMatrix[VX][VX], n0.mMatrix[VX][VX], w); - gBlendRotMat.mMatrix[VX][VY] = lerp(n1.mMatrix[VX][VY], n0.mMatrix[VX][VY], w); - gBlendRotMat.mMatrix[VX][VZ] = lerp(n1.mMatrix[VX][VZ], n0.mMatrix[VX][VZ], w); - - gBlendRotMat.mMatrix[VY][VX] = lerp(n1.mMatrix[VY][VX], n0.mMatrix[VY][VX], w); - gBlendRotMat.mMatrix[VY][VY] = lerp(n1.mMatrix[VY][VY], n0.mMatrix[VY][VY], w); - gBlendRotMat.mMatrix[VY][VZ] = lerp(n1.mMatrix[VY][VZ], n0.mMatrix[VY][VZ], w); - - gBlendRotMat.mMatrix[VZ][VX] = lerp(n1.mMatrix[VZ][VX], n0.mMatrix[VZ][VX], w); - gBlendRotMat.mMatrix[VZ][VY] = lerp(n1.mMatrix[VZ][VY], n0.mMatrix[VZ][VY], w); - gBlendRotMat.mMatrix[VZ][VZ] = lerp(n1.mMatrix[VZ][VZ], n0.mMatrix[VZ][VZ], w); - - o_normals[bidx] = normals[index] * gBlendRotMat; } buffer->setBuffer(0); diff --git a/indra/newview/llviewerjointmesh_sse.cpp b/indra/newview/llviewerjointmesh_sse.cpp index 2f2635246..36d6bd61a 100644 --- a/indra/newview/llviewerjointmesh_sse.cpp +++ b/indra/newview/llviewerjointmesh_sse.cpp @@ -94,8 +94,8 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh) buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); const F32* weights = mesh->getWeights(); - const LLVector3* coords = mesh->getCoords(); - const LLVector3* normals = mesh->getNormals(); + const LLVector4* coords = mesh->getCoords(); + const LLVector4* normals = mesh->getNormals(); for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) { if( weight != weights[index]) @@ -103,8 +103,8 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh) S32 joint = llfloor(weight = weights[index]); blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint); } - blend_mat.multiply(coords[index], o_vertices[index]); - ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]); + blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]); + ((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]); } buffer->setBuffer(0); diff --git a/indra/newview/llviewerjointmesh_sse2.cpp b/indra/newview/llviewerjointmesh_sse2.cpp index bfd8bb69b..5bcdb6224 100644 --- a/indra/newview/llviewerjointmesh_sse2.cpp +++ b/indra/newview/llviewerjointmesh_sse2.cpp @@ -101,8 +101,8 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh) buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); const F32* weights = mesh->getWeights(); - const LLVector3* coords = mesh->getCoords(); - const LLVector3* normals = mesh->getNormals(); + const LLVector4* coords = mesh->getCoords(); + const LLVector4* normals = mesh->getNormals(); for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) { if( weight != weights[index]) @@ -110,8 +110,8 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh) S32 joint = llfloor(weight = weights[index]); blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint); } - blend_mat.multiply(coords[index], o_vertices[index]); - ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]); + blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]); + ((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]); } buffer->setBuffer(0); diff --git a/indra/newview/llviewerjointmesh_vec.cpp b/indra/newview/llviewerjointmesh_vec.cpp index 91b97b07d..6a7bb587b 100644 --- a/indra/newview/llviewerjointmesh_vec.cpp +++ b/indra/newview/llviewerjointmesh_vec.cpp @@ -84,8 +84,8 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh) buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); const F32* weights = mesh->getWeights(); - const LLVector3* coords = mesh->getCoords(); - const LLVector3* normals = mesh->getNormals(); + const LLVector4* coords = mesh->getCoords(); + const LLVector4* normals = mesh->getNormals(); for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) { if( weight != weights[index]) @@ -93,8 +93,8 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh) S32 joint = llfloor(weight = weights[index]); blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint); } - blend_mat.multiply(coords[index], o_vertices[index]); - ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]); + blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]); + ((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]); } buffer->setBuffer(0); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b5ca840ca..d86205019 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2207,6 +2207,33 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const return mDrawable->getWorldMatrix(); } +#if MESH_ENABLED +F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes) +{ + F32 radius = getScale().length()*0.5f; + + if (isMesh()) + { + LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID()); + + return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD); + } + else + { + LLVolume* volume = getVolume(); + S32 counts[4]; + LLVolume::getLoDTriangleCounts(volume->getParams(), counts); + + LLSD header; + header["lowest_lod"]["size"] = counts[0] * 10; + header["low_lod"]["size"] = counts[1] * 10; + header["medium_lod"]["size"] = counts[2] * 10; + header["high_lod"]["size"] = counts[3] * 10; + + return LLMeshRepository::getStreamingCost(header, radius); + } +} +#endif //MESH_ENABLED U32 LLVOVolume::getTriangleCount() { @@ -3403,6 +3430,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { + llassert(group); static int warningsCount = 20; if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY)) { @@ -3414,15 +3442,16 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { LLDrawable* drawablep = *drawable_iter; - if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) + if (drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) { continue; } - if (drawablep->isState(LLDrawable::REBUILD_ALL)) + if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) ) { LLVOVolume* vobj = drawablep->getVOVolume(); vobj->preRebuild(); + LLVolume* volume = vobj->getVolume(); for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { @@ -3489,6 +3518,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } + + llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); } struct CompareBatchBreakerModified diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 3c2d5fba9..0e91880dc 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -132,7 +132,9 @@ public: const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } /*virtual*/ const LLMatrix4 getRenderMatrix() const; - +#if MESH_ENABLED + /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL); +#endif //MESH_ENABLED /*virtual*/ U32 getTriangleCount(); /*virtual*/ U32 getHighLODTriangleCount(); /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 38cd00028..8103ebefb 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7905,17 +7905,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.pushRenderTypeMask(); gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_WL_CLOUDS, LLPipeline::END_RENDER_TYPES); + static LLCullResult result; updateCull(camera, result); stateSort(camera, result); - andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, - LLPipeline::RENDER_TYPE_WL_CLOUDS, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); renderGeom(camera, TRUE); + gPipeline.popRenderTypeMask(); } @@ -7925,7 +7923,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.pushRenderTypeMask(); if (detail < 4) { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); + clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, END_RENDER_TYPES); if (detail < 3) { clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); @@ -7940,7 +7938,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_GROUND, LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, LLPipeline::RENDER_TYPE_WL_CLOUDS, LLPipeline::END_RENDER_TYPES); static const LLCachedControl<bool> skip_distortion_updates("SkipReflectOcclusionUpdates",false); From b75a28ec15888a241888f2f5e6146a35ffa434b3 Mon Sep 17 00:00:00 2001 From: Shyotl <Shyotl@gmail.com> Date: Fri, 5 Aug 2011 01:18:27 -0500 Subject: [PATCH 04/18] Cleanup. Applied http://hg.secondlife.com/mesh-development/changeset/3031f266784a --- indra/llcommon/llstrider.h | 66 ++++++++++++++++++++++++++---- indra/llprimitive/llmodel.cpp | 13 ++++++ indra/llprimitive/llmodel.h | 23 +++++------ indra/llrender/llvertexbuffer.cpp | 11 ++--- indra/llrender/llvertexbuffer.h | 2 - indra/newview/llmeshrepository.cpp | 3 +- indra/newview/llvovolume.cpp | 14 +++---- 7 files changed, 92 insertions(+), 40 deletions(-) diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h index 444820c67..2afaacf3b 100644 --- a/indra/llcommon/llstrider.h +++ b/indra/llcommon/llstrider.h @@ -42,13 +42,15 @@ template <class Object> class LLStrider U8* mBytep; }; U32 mSkip; + U32 mTypeSize; public: - LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); } + LLStrider() { mObjectp = NULL; mTypeSize = mSkip = sizeof(Object); } ~LLStrider() { } const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;} void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));} + void setTypeSize (S32 typeBytes){ mTypeSize = (typeBytes ? typeBytes : sizeof(Object)); } void skip(const U32 index) { mBytep += mSkip*index;} U32 getSkip() const { return mSkip; } @@ -58,18 +60,68 @@ public: Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; } Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; } Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); } - void assignArray(U8* buff, size_t elem_size, size_t elem_count) + void assignArray(U8* __restrict source, const size_t elem_size, const size_t elem_count) { llassert_always(sizeof(Object) <= elem_size); - if(sizeof(Object) == mSkip && sizeof(Object) == elem_size) //No stride. No difference in element size. - LLVector4a::memcpyNonAliased16((F32*) mBytep, (F32*) buff, elem_size * elem_count); + + U8* __restrict dest = mBytep; //refer to dest instead of mBytep to benefit from __restrict hint + const U32 bytes = elem_size * elem_count; //total bytes to copy from source to dest + + //stride == sizeof(element) implies entire buffer is unstrided and thus memcpy-able, provided source buffer elements match in size. + //Because LLStrider is often passed an LLVector3 even if the reprensentation is LLVector4 in the vertex buffer, mTypeSize is set to + //the TRUE vbo datatype size via VertexBufferStrider::get + if(mTypeSize == mSkip && mTypeSize == elem_size) + { + if(bytes >= sizeof(LLVector4) * 4) //Should be able to pull at least 3 16byte blocks from this. Smaller isn't really beneficial. + { + U8* __restrict aligned_source = LL_NEXT_ALIGNED_ADDRESS(source); + U8* __restrict aligned_dest = LL_NEXT_ALIGNED_ADDRESS(dest); + const U32 source_offset = aligned_source - source; //Offset to first aligned location in source buffer. + const U32 dest_offset = aligned_dest - dest; //Offset to first aligned location in dest buffer. + llassert_always(source_offset < 16); + llassert_always(dest_offset < 16); + if(source_offset == dest_offset) //delta to aligned location matches between source and destination! _mm_*_ps should be viable. + { + const U32 end_offset = (bytes - source_offset) % sizeof(LLVector4); //buffers may not neatly end on a 16byte alignment boundary. + const U32 aligned_bytes = bytes - source_offset - end_offset; //how many bytes to copy from aligned start to aligned end. + + llassert_always(aligned_bytes > 0); + + if(source_offset) //memcpy up to the aligned location if needed + memcpy(dest,source,source_offset); + LLVector4a::memcpyNonAliased16((F32*) aligned_dest, (F32*) aligned_source, aligned_bytes); + if(end_offset) //memcpy to the very end if needed. + memcpy(aligned_dest+aligned_bytes,aligned_source+aligned_bytes,end_offset); + } + else //buffers non-uniformly offset from aligned location. Using _mm_*u_ps. + { + U32 end = bytes/sizeof(LLVector4); //sizeof(LLVector4) = 16 bytes = 128 bits + + llassert_always(end > 0); + + __m128* dst = (__m128*) dest; + __m128* src = (__m128*) source; + + for (U32 i = 0; i < end; i++) //copy 128bit chunks + { + __m128 res = _mm_loadu_ps((F32*)&src[i]); + _mm_storeu_ps((F32*)&dst[i], res); + } + end*=16;//Convert to real byte offset + if(end < bytes) //just memcopy the rest + memcpy(dest+end,source+end,bytes-end); + } + } + else //Too small. just do a simple memcpy. + memcpy(dest,source,bytes); + } else { for(U32 i=0;i<elem_count;i++) { - memcpy(mBytep,buff,sizeof(Object)); - mBytep+=mSkip; - buff+=elem_size; + memcpy(dest,source,sizeof(Object)); + dest+=mSkip; + source+=elem_size; } } } diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index a7563f17c..d114b2f58 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1695,6 +1695,19 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) { + //1. If a vertex has been weighted then we'll find it via pos and return it's weight list + weight_map::iterator iterPos = mSkinWeights.begin(); + weight_map::iterator iterEnd = mSkinWeights.end(); + + for ( ; iterPos!=iterEnd; ++iterPos ) + { + if ( jointPositionalLookup( iterPos->first, pos ) ) + { + return iterPos->second; + } + } + + //2. Otherwise we'll use the older implementation weight_map::iterator iter = mSkinWeights.find(pos); if (iter != mSkinWeights.end()) diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index fe37d3420..58975e55b 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -223,20 +223,17 @@ public: }; - struct JointPositionalCompare + //Are the doubles the same w/in epsilon specified tolerance + bool areEqual( double a, double b ) { - //Are the doubles the same w/in epsilon specified tolerance - bool areEqual( double a, double b ) - { - const float epsilon = 1e-5f; - return (abs((int)(a - b)) < epsilon) && (a < b); - } - //Make sure that we return false for any values that are within the tolerance for equivalence - bool operator() ( const LLVector3& a, const LLVector3& b ) - { - return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? false : true; - } - }; + const float epsilon = 1e-5f; + return (fabs((a - b)) < epsilon) ? true : false ; + } + //Make sure that we return false for any values that are within the tolerance for equivalence + bool jointPositionalLookup( const LLVector3& a, const LLVector3& b ) + { + return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? true : false; + } //copy of position array for this model -- mPosition[idx].mV[X,Y,Z] std::vector<LLVector3> mPosition; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index e0c469544..301a3f056 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1192,12 +1192,14 @@ template <class T,S32 type> struct VertexBufferStrider strider = (T*)(ptr + index*sizeof(T)); strider.setStride(0); + strider.setTypeSize(0); return TRUE; } else if (vbo.hasDataType(type)) { S32 stride = vbo.getStride(); volatile U8* ptr = vbo.mapVertexBuffer(type); + S32 size = LLVertexBuffer::sTypeSize[type]; if (ptr == NULL) { @@ -1207,6 +1209,7 @@ template <class T,S32 type> struct VertexBufferStrider strider = (T*)(ptr + vbo.getOffset(type) + index*stride); strider.setStride(stride); + strider.setTypeSize(size); return TRUE; } else @@ -1575,11 +1578,3 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const llglassertok(); } -void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count) -{ - // TODO: use GL_APPLE_flush_buffer_range here - /*if (useVBOs() && !mFilthy) - { - - }*/ -} diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index f59f92518..fef966151 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -213,8 +213,6 @@ public: void setStride(S32 type, S32 new_stride); - void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count); - void draw(U32 mode, U32 count, U32 indices_offset) const; void drawArrays(U32 mode, U32 offset, U32 count) const; void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index c67249ebf..86500e297 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3180,7 +3180,8 @@ void LLPhysicsDecomp::doDecompositionSingleHull() return; #endif //!MESH_IMPORT #if MESH_IMPORT - + LLConvexDecomposition* decomp = LLConvexDecomposition::getInstance(); + if (decomp == NULL) { //stub. do nothing. diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d86205019..3c040c5dd 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3678,12 +3678,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: U32 te_idx = facep->getTEOffset(); - if (facep->getGeometryVolume(*volume, te_idx, - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset)) - { - buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(), - facep->getIndicesStart(), facep->getIndicesCount()); - } + facep->getGeometryVolume(*volume, te_idx, + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset); } } @@ -3709,9 +3705,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: // can we safely treat this as an alpha mask? if (facep->canRenderAsMask()) { - const LLDrawable* drawablep = facep->getDrawable(); - const LLVOVolume* vobj = drawablep ? drawablep->getVOVolume() : NULL; - if (te->getFullbright() || (vobj && vobj->isHUDAttachment())) + //const LLDrawable* drawablep = facep->getDrawable(); + //const LLVOVolume* vobj = drawablep ? drawablep->getVOVolume() : NULL; + if (te->getFullbright() /*|| (vobj && vobj->isHUDAttachment())*/) { registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); } From 9cc398e939fdc0ce2e08b3e6f4f20accc3f020e4 Mon Sep 17 00:00:00 2001 From: Shyotl <Shyotl@gmail.com> Date: Fri, 5 Aug 2011 02:55:13 -0500 Subject: [PATCH 05/18] Occlusion now using LLVertexbuffer class. --- indra/newview/llspatialpartition.cpp | 256 ++++++++++----------------- indra/newview/llspatialpartition.h | 7 +- indra/newview/llvovolume.cpp | 4 +- 3 files changed, 98 insertions(+), 169 deletions(-) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index abc281e0e..96db56418 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -115,23 +115,6 @@ void sg_assert(BOOL expr) #endif } -#if LL_DEBUG -void validate_drawable(LLDrawable* drawablep) -{ - F64 rad = drawablep->getBinRadius(); - const LLVector3* ext = drawablep->getSpatialExtents(); - - if (rad < 0 || rad > 4096 || - (ext[1]-ext[0]).magVec() > 4096) - { - llwarns << "Invalid drawable found in octree." << llendl; - } -} -#else -#define validate_drawable(x) -#endif - - S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) { return AABBSphereIntersectR2(min, max, origin, rad*rad); @@ -277,38 +260,70 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) void LLSpatialGroup::buildOcclusion() { - if (!mOcclusionVerts) + if (mOcclusionVerts.isNull()) { - mOcclusionVerts = new F32[8*3]; - } - LLVector3 bounds[2]; - bounds[0].set(mBounds[0].getF32ptr()); - bounds[1].set(mBounds[1].getF32ptr()); - LLVector3 r = bounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE); - - for (U32 k = 0; k < 3; k++) - { - r.mV[k] = llmin(bounds[1].mV[k]+0.25f, r.mV[k]); - } - - F32* v = mOcclusionVerts; - F32* c = bounds[0].mV; - F32* s = r.mV; + mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, + LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling. + mOcclusionVerts->allocateBuffer(8, 64, true); - //vertex positions are encoded so the 3 bits of their vertex index - //correspond to their axis facing, with bit position 3,2,1 matching - //axis facing x,y,z, bit set meaning positive facing, bit clear - //meaning negative facing - v[0] = c[0]-s[0]; v[1] = c[1]-s[1]; v[2] = c[2]-s[2]; // 0 - 0000 - v[3] = c[0]-s[0]; v[4] = c[1]-s[1]; v[5] = c[2]+s[2]; // 1 - 0001 - v[6] = c[0]-s[0]; v[7] = c[1]+s[1]; v[8] = c[2]-s[2]; // 2 - 0010 - v[9] = c[0]-s[0]; v[10] = c[1]+s[1]; v[11] = c[2]+s[2]; // 3 - 0011 - - v[12] = c[0]+s[0]; v[13] = c[1]-s[1]; v[14] = c[2]-s[2]; // 4 - 0100 - v[15] = c[0]+s[0]; v[16] = c[1]-s[1]; v[17] = c[2]+s[2]; // 5 - 0101 - v[18] = c[0]+s[0]; v[19] = c[1]+s[1]; v[20] = c[2]-s[2]; // 6 - 0110 - v[21] = c[0]+s[0]; v[22] = c[1]+s[1]; v[23] = c[2]+s[2]; // 7 - 0111 + LLStrider<U16> idx; + mOcclusionVerts->getIndexStrider(idx); + for (U32 i = 0; i < 64; i++) + { + *idx++ = sOcclusionIndices[i]; + } + } + + LLVector4a fudge; + fudge.splat(SG_OCCLUSION_FUDGE); + + LLVector4a r; + r.setAdd(mBounds[1], fudge); + + LLStrider<LLVector3> pos; + + { + //LLFastTimer t(LLFastTimer::FTM_BUILD_OCCLUSION); + mOcclusionVerts->getVertexStrider(pos); + } + + { + LLVector4a* v = (LLVector4a*) pos.get(); + + const LLVector4a& c = mBounds[0]; + const LLVector4a& s = r; + + static const LLVector4a octant[] = + { + LLVector4a(-1.f, -1.f, -1.f), + LLVector4a(-1.f, -1.f, 1.f), + LLVector4a(-1.f, 1.f, -1.f), + LLVector4a(-1.f, 1.f, 1.f), + + LLVector4a(1.f, -1.f, -1.f), + LLVector4a(1.f, -1.f, 1.f), + LLVector4a(1.f, 1.f, -1.f), + LLVector4a(1.f, 1.f, 1.f), + }; + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + + for (S32 i = 0; i < 8; ++i) + { + LLVector4a p; + p.setMul(s, octant[i]); + p.add(c); + v[i] = p; + } + } + + { + mOcclusionVerts->setBuffer(0); + } clearState(LLSpatialGroup::OCCLUSION_DIRTY); } @@ -374,7 +389,6 @@ LLSpatialGroup::~LLSpatialGroup() } } - delete [] mOcclusionVerts; mOcclusionVerts = NULL; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -469,52 +483,6 @@ void LLSpatialGroup::checkStates() #endif } -void validate_draw_info(LLDrawInfo& params) -{ -#if LL_OCTREE_PARANOIA_CHECK - if (!params.mVertexBuffer) - { - llerrs << "Draw batch has no vertex buffer." << llendl; - } - - //bad range - if (params.mStart >= params.mEnd) - { - llerrs << "Draw batch has invalid range." << llendl; - } - - if (params.mEnd >= (U32) params.mVertexBuffer->getNumVerts()) - { - llerrs << "Draw batch has buffer overrun error." << llendl; - } - - if (params.mOffset + params.mCount > (U32) params.mVertexBuffer->getNumIndices()) - { - llerrs << "Draw batch has index buffer ovverrun error." << llendl; - } - - //bad indices - U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer(); - if (indicesp) - { - for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++) - { - if (indicesp[i] < (U16)params.mStart) - { - llerrs << "Draw batch has vertex buffer index out of range error (index too low). " - << "indicesp["<<i<<"]="<<indicesp[i]<< llendl; - } - - if (indicesp[i] > (U16)params.mEnd) - { - llerrs << "Draw batch has vertex buffer index out of range error (index too high)." - << "indicesp["<<i<<"]="<<indicesp[i]<< llendl; - } - } - } //Complains -SG -#endif -} - void LLSpatialGroup::validateDrawMap() { #if LL_OCTREE_PARANOIA_CHECK @@ -524,8 +492,8 @@ void LLSpatialGroup::validateDrawMap() for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) { LLDrawInfo& params = **j; - - validate_draw_info(params); + + params.validate(); } } #endif @@ -536,7 +504,6 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); drawablep->updateSpatialExtents(); - validate_drawable(drawablep); OctreeNode* parent = mOctreeNode->getOctParent(); @@ -548,7 +515,6 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) unbound(); setState(OBJECT_DIRTY); //setState(GEOM_DIRTY); - validate_drawable(drawablep); return TRUE; } @@ -566,7 +532,6 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc else { drawablep->setSpatialGroup(this); - validate_drawable(drawablep); setState(OBJECT_DIRTY | GEOM_DIRTY); setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); gPipeline.markRebuild(this, TRUE); @@ -839,7 +804,7 @@ void LLSpatialGroup::shift(const LLVector4a &offset) gPipeline.markRebuild(this, TRUE); } - if (mOcclusionVerts) + if (mOcclusionVerts.notNull()) { setState(OCCLUSION_DIRTY); } @@ -874,24 +839,16 @@ void LLSpatialGroup::setState(eSpatialState state) // if (LLSpatialPartition::sFreezeState) // return; mState |= state; - - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + + llassert(state <= LLSpatialGroup::STATE_MASK); } void LLSpatialGroup::setState(eSpatialState state, S32 mode) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); -// if (LLSpatialPartition::sFreezeState) -// return; - - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); + if (mode > STATE_MODE_SINGLE) { if (mode == STATE_MODE_DIFF) @@ -937,25 +894,14 @@ public: void LLSpatialGroup::clearState(eSpatialState state) { -// if (LLSpatialPartition::sFreezeState) -// return; - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); mState &= ~state; } void LLSpatialGroup::clearState(eSpatialState state, S32 mode) { - -// if (LLSpatialPartition::sFreezeState) -// return; - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -980,10 +926,7 @@ void LLSpatialGroup::clearState(eSpatialState state, S32 mode) BOOL LLSpatialGroup::isState(eSpatialState state) const { - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "LLSpatialGroup::isState passed invalid state '" << state << "'" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); return mState & state ? TRUE : FALSE; } @@ -1121,7 +1064,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mOctreeNode(node), mSpatialPartition(part), mVertexBuffer(NULL), - mBufferUsage(GL_STATIC_DRAW_ARB), + mBufferUsage(part->mBufferUsage), mDistance(0.f), mDepth(0.f), mLastUpdateDistance(-1.f), @@ -1399,7 +1342,6 @@ void LLSpatialGroup::destroyGL() } } - delete [] mOcclusionVerts; mOcclusionVerts = NULL; for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) @@ -1573,7 +1515,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); } - if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY)) + if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY)) { buildOcclusion(); } @@ -1600,37 +1542,32 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) { //LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); + + mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); + if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) { LLGLSquashToFarClip squash(glh_get_current_projection(), 1); if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); } else { - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0])); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); } } else { if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); - + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); } else { - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0])); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); } } @@ -1689,7 +1626,6 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); drawablep->updateSpatialExtents(); - validate_drawable(drawablep); //keep drawable from being garbage collected LLPointer<LLDrawable> ptr = drawablep; @@ -1988,11 +1924,8 @@ public: virtual void processGroup(LLSpatialGroup* group) { - if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty()) - { - llerrs << "WTF?" << llendl; - } - + llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty()) + if (mRes < 2) { if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0) @@ -2356,6 +2289,8 @@ void pushVerts(LLSpatialGroup* group, U32 mask) void pushVerts(LLFace* face, U32 mask) { + llassert(face->verify()); + LLVertexBuffer* buffer = face->getVertexBuffer(); if (buffer) @@ -3159,7 +3094,6 @@ public: { renderAgentTarget(avatar); } - } for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -3550,18 +3484,9 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, mFace(NULL), mDistance(0.f) { - mDebugColor = (rand() << 16) + rand(); - if (mStart >= mVertexBuffer->getRequestedVerts() || - mEnd >= mVertexBuffer->getRequestedVerts()) - { - llerrs << "Invalid draw info vertex range." << llendl; - } + mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); - if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() || - mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices()) - { - llerrs << "Invalid draw info index range." << llendl; - } + mDebugColor = (rand() << 16) + rand(); } LLDrawInfo::~LLDrawInfo() @@ -3582,6 +3507,11 @@ LLDrawInfo::~LLDrawInfo() } } +void LLDrawInfo::validate() +{ + mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); +} + LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) { return new LLVertexBuffer(type_mask, usage); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index bc11da84d..56e5ca2e5 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -88,6 +88,7 @@ public: BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); + void validate(); LLVector4a mExtents[2]; @@ -361,9 +362,9 @@ public: F32 mBuilt; OctreeNode* mOctreeNode; LLSpatialPartition* mSpatialPartition; - + LLPointer<LLVertexBuffer> mVertexBuffer; - F32* mOcclusionVerts; + LLPointer<LLVertexBuffer> mOcclusionVerts; GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; U32 mBufferUsage; @@ -694,8 +695,6 @@ public: virtual void shift(const LLVector4a &offset); }; -void validate_draw_info(LLDrawInfo& params); - extern const F32 SG_BOX_SIDE; extern const F32 SG_BOX_OFFSET; extern const F32 SG_BOX_RAD; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3c040c5dd..6062461a5 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2942,7 +2942,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); - validate_draw_info(*draw_vec[idx]); + draw_vec[idx]->validate(); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]); } @@ -2966,7 +2966,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } draw_info->mExtents[0] = facep->mExtents[0]; draw_info->mExtents[1] = facep->mExtents[1]; - validate_draw_info(*draw_info); + draw_info->validate(); } } From 7bcd259821fa0462160ff720a1d13d1202ceb2b5 Mon Sep 17 00:00:00 2001 From: Shyotl <Shyotl@gmail.com> Date: Fri, 5 Aug 2011 19:24:17 -0500 Subject: [PATCH 06/18] Added ShyotlRenderVBOStrideMode to toggle between strided and unstrided VBOs. --- indra/llrender/llvertexbuffer.cpp | 143 +++++++++++++++--------- indra/llrender/llvertexbuffer.h | 33 +++--- indra/newview/app_settings/settings.xml | 16 ++- indra/newview/lldrawpoolavatar.cpp | 12 +- indra/newview/llviewercontrol.cpp | 1 + indra/newview/llvosurfacepatch.cpp | 72 ++++++++++-- indra/newview/llvovolume.cpp | 6 +- indra/newview/llvowlsky.cpp | 2 +- indra/newview/pipeline.cpp | 2 + 9 files changed, 197 insertions(+), 90 deletions(-) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 301a3f056..2837cd6af 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -66,6 +66,7 @@ BOOL LLVertexBuffer::sIBOActive = FALSE; U32 LLVertexBuffer::sAllocatedBytes = 0; BOOL LLVertexBuffer::sMapped = FALSE; BOOL LLVertexBuffer::sUseStreamDraw = TRUE; +U32 LLVertexBuffer::sForceStrideMode = 0; BOOL LLVertexBuffer::sOmitBlank = FALSE; BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; S32 LLVertexBuffer::sWeight4Loc = -1; @@ -263,7 +264,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm) { U32 count = pos.size(); - llassert(norm.size() >= pos.size()); + llassert_always(norm.size() >= pos.size()); + llassert_always(count > 0) ; unbind(); @@ -448,7 +450,7 @@ void LLVertexBuffer::clientCopy(F64 max_time) //---------------------------------------------------------------------------- -LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : +LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage, bool strided) : LLRefCount(), mNumVerts(0), @@ -466,7 +468,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mFilthy(FALSE), mEmpty(TRUE), mResized(FALSE), - mDynamicSize(FALSE) + mDynamicSize(FALSE), + mIsStrided(strided), + mStride(0) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (!sEnableVBOs) @@ -483,20 +487,27 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : { mUsage = GL_STREAM_DRAW_ARB; } - - S32 stride = calcStride(typemask, mOffsets); + + //zero out offsets + for (U32 i = 0; i < TYPE_MAX; i++) + { + mOffsets[i] = 0; + } mTypeMask = typemask; - mStride = stride; + mSize = 0; mAlignedOffset = 0; mAlignedIndexOffset = 0; + + if(sForceStrideMode) + mIsStrided = sForceStrideMode == 1; + sCount++; } -//static -S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets) +S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices) { - S32 stride = 0; + S32 offset = 0; for (S32 i=0; i<TYPE_MAX; i++) { U32 mask = 1<<i; @@ -504,13 +515,50 @@ S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets) { if (offsets) { - offsets[i] = stride; + offsets[i] = offset; } - stride += sTypeSize[i]; + if(mIsStrided) + { + offset += sTypeSize[i]; + } + else + { + offset += LLVertexBuffer::sTypeSize[i]*num_vertices; + offset = (offset + 0xF) & ~0xF; + } + } + } + if(mIsStrided) + { + mStride = offset; + return mStride * num_vertices + 16; + } + else + { + mStride = -1; //Stride is invalid with unstrided arrays. + return offset + 16; + } +} + +//static +S32 LLVertexBuffer::calcVertexSize(const U32& typemask) +{ + S32 size = 0; + for (S32 i = 0; i < TYPE_MAX; i++) + { + U32 mask = 1<<i; + if (typemask & mask) + { + size += LLVertexBuffer::sTypeSize[i]; } } - return stride; + return size; +} + +S32 LLVertexBuffer::getSize() const +{ + return mSize; } // protected, use unref() @@ -750,7 +798,7 @@ void LLVertexBuffer::updateNumVerts(S32 nverts) } mNumVerts = nverts; } - + mSize = calcOffsets(mTypeMask, mOffsets, mNumVerts); } void LLVertexBuffer::updateNumIndices(S32 nindices) @@ -958,7 +1006,7 @@ void LLVertexBuffer::allocateClientIndexBuffer() } // Map for data access -volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access) +volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mFinal) @@ -1031,10 +1079,10 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access) sMappedCount++; } - return mMappedData; + return mMappedData+mOffsets[type]+ (mIsStrided ? mStride : sTypeSize[type])*index; } -volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access) +volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mFinal) @@ -1065,6 +1113,9 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access) src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); } + llassert(src != NULL); + + mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src); mAlignedIndexOffset = mMappedIndexData - src; stop_glerror(); @@ -1095,7 +1146,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access) sMappedCount++; } - return mMappedIndexData ; + return mMappedIndexData + sizeof(U16)*index; } void LLVertexBuffer::unmapBuffer(S32 type) @@ -1182,7 +1233,7 @@ template <class T,S32 type> struct VertexBufferStrider { if (type == LLVertexBuffer::TYPE_INDEX) { - volatile U8* ptr = vbo.mapIndexBuffer(); + volatile U8* ptr = vbo.mapIndexBuffer(index); if (ptr == NULL) { @@ -1190,16 +1241,16 @@ template <class T,S32 type> struct VertexBufferStrider return FALSE; } - strider = (T*)(ptr + index*sizeof(T)); + strider = (T*)ptr; strider.setStride(0); strider.setTypeSize(0); return TRUE; } else if (vbo.hasDataType(type)) { - S32 stride = vbo.getStride(); - volatile U8* ptr = vbo.mapVertexBuffer(type); - S32 size = LLVertexBuffer::sTypeSize[type]; + S32 stride = vbo.getStride(type); + + volatile U8* ptr = vbo.mapVertexBuffer(type,index); if (ptr == NULL) { @@ -1207,9 +1258,11 @@ template <class T,S32 type> struct VertexBufferStrider return FALSE; } - strider = (T*)(ptr + vbo.getOffset(type) + index*stride); + + strider = (T*)ptr; + strider.setStride(stride); - strider.setTypeSize(size); + strider.setTypeSize(LLVertexBuffer::sTypeSize[type]); return TRUE; } else @@ -1272,25 +1325,6 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index); } -void LLVertexBuffer::setStride(S32 type, S32 new_stride) -{ - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - if (mNumVerts) - { - llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; - } - // This code assumes that setStride() will only be called once per VBO per type. - S32 delta = new_stride - sTypeSize[type]; - for (S32 i=type+1; i<TYPE_MAX; i++) - { - if (mTypeMask & (1<<i)) - { - mOffsets[i] += delta; - } - } - mStride += delta; -} - //---------------------------------------------------------------------------- // Set for rendering @@ -1488,7 +1522,6 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); stop_glerror(); volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; - S32 stride = mStride; if ((data_mask & mTypeMask) != data_mask) { @@ -1521,58 +1554,58 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if (data_mask & MAP_NORMAL) { - glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL])); + glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL])); } if (data_mask & MAP_TEXCOORD3) { glClientActiveTextureARB(GL_TEXTURE3_ARB); - glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD3])); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD3), (void*)(base + mOffsets[TYPE_TEXCOORD3])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } if (data_mask & MAP_TEXCOORD2) { glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2])); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD2), (void*)(base + mOffsets[TYPE_TEXCOORD2])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } if (data_mask & MAP_TEXCOORD1) { glClientActiveTextureARB(GL_TEXTURE1_ARB); - glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD1])); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD1), (void*)(base + mOffsets[TYPE_TEXCOORD1])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } if (data_mask & MAP_BINORMAL) { glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(3,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_BINORMAL])); + glTexCoordPointer(3,GL_FLOAT, getStride(TYPE_BINORMAL), (void*)(base + mOffsets[TYPE_BINORMAL])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } if (data_mask & MAP_TEXCOORD0) { - glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); } if (data_mask & MAP_COLOR) { - glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR])); + glColorPointer(4, GL_UNSIGNED_BYTE, getStride(TYPE_COLOR), (void*)(base + mOffsets[TYPE_COLOR])); } if (data_mask & MAP_WEIGHT) { - glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT])); + glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT), (void*)(base + mOffsets[TYPE_WEIGHT])); } if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) { - glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, stride, (void*)(base+mOffsets[TYPE_WEIGHT4])); + glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT4), (void*)(base+mOffsets[TYPE_WEIGHT4])); } if (data_mask & MAP_CLOTHWEIGHT) { - glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, getStride(TYPE_CLOTHWEIGHT), (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); } if (data_mask & MAP_VERTEX) { - glVertexPointer(3,GL_FLOAT, stride, (void*)(base + 0)); + glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0)); } llglassertok(); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index fef966151..8d098a1f1 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -90,6 +90,7 @@ public: static S32 sWeight4Loc; static BOOL sUseStreamDraw; + static U32 sForceStrideMode; static BOOL sOmitBlank; static BOOL sPreferStreamDraw; @@ -102,11 +103,15 @@ public: static void unbind(); //unbind any bound vertex buffer //get the size of a vertex with the given typemask - //if offsets is not NULL, its contents will be filled - //with the offset of each vertex component in the buffer, - // indexed by the following enum - static S32 calcStride(const U32& typemask, S32* offsets = NULL); + static S32 calcVertexSize(const U32& typemask); + //get the size of a buffer with the given typemask and vertex count + //fill offsets with the offset of each vertex component array into the buffer + // indexed by the following enum + //If strided, num_vertices will be ignored. + S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices); + + enum { TYPE_VERTEX, TYPE_NORMAL, @@ -162,11 +167,11 @@ protected: void allocateClientIndexBuffer() ; public: - LLVertexBuffer(U32 typemask, S32 usage); + LLVertexBuffer(U32 typemask, S32 usage, bool strided=true); // map for data access - volatile U8* mapVertexBuffer(S32 type = -1, S32 access = -1); - volatile U8* mapIndexBuffer(S32 access = -1); + volatile U8* mapVertexBuffer(S32 type, S32 index); + volatile U8* mapIndexBuffer(S32 index); // set for rendering virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0 @@ -201,17 +206,15 @@ public: volatile U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; } volatile U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; } - S32 getStride() const { return mStride; } - S32 getTypeMask() const { return mTypeMask; } - BOOL hasDataType(S32 type) const { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; } - S32 getSize() const { return mNumVerts*mStride; } + S32 getStride(S32 type) const { return mIsStrided ? mStride : sTypeSize[type]; } + U32 getTypeMask() const { return mTypeMask; } + bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); } + S32 getSize() const; S32 getIndicesSize() const { return mNumIndices * sizeof(U16); } volatile U8* getMappedData() const { return mMappedData; } volatile U8* getMappedIndices() const { return mMappedIndexData; } S32 getOffset(S32 type) const { return mOffsets[type]; } S32 getUsage() const { return mUsage; } - - void setStride(S32 type, S32 new_stride); void draw(U32 mode, U32 count, U32 indices_offset) const; void drawArrays(U32 mode, U32 offset, U32 count) const; @@ -230,7 +233,9 @@ protected: ptrdiff_t mAlignedOffset; ptrdiff_t mAlignedIndexOffset; - S32 mStride; + bool mIsStrided; + S32 mStride; // Vertex size. + S32 mSize; // Full array size U32 mTypeMask; S32 mUsage; // GL usage U32 mGLBuffer; // GL VBO handle diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ef738031e..da4f2e3bb 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -429,7 +429,21 @@ <key>Value</key> <integer>0</integer> </map> - <key>ResetFocusOnSelfClick</key> + <key>ShyotlRenderVBOStrideMode</key> + <map> + <key>Comment</key> + <string>0 = Standard behavior +1 = Force strided VBOs +2 = Force unstrided(dense) VBOs</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> + + <key>ResetFocusOnSelfClick</key> <map> <key>Comment</key> <string>Setting this to TRUE resets your camera when you left-click your avatar</string> diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 60a831472..b3cd43bc6 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1806,20 +1806,20 @@ void LLVertexBufferAvatar::setupVertexBuffer(U32 data_mask) const { volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; - glVertexPointer(3,GL_FLOAT, mStride, (void*)(base + 0)); - glNormalPointer(GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_NORMAL])); - glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0)); + glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL])); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); - set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], mStride, (F32*)(base + mOffsets[TYPE_WEIGHT])); + set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], getStride(TYPE_WEIGHT), (F32*)(base + mOffsets[TYPE_WEIGHT])); if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_BUMP) { - set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL], mStride, (LLVector3*)(base + mOffsets[TYPE_BINORMAL])); + set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL], getStride(TYPE_BINORMAL), (LLVector3*)(base + mOffsets[TYPE_BINORMAL])); } if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH) { - set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], mStride, (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], getStride(TYPE_CLOTHWEIGHT), (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT])); } } else diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index a58d38329..e19923f5a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -646,6 +646,7 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); //See LL jira VWR-3258 comment section. Implemented by LL in 2.1 -Shyotl gSavedSettings.getControl("ShyotlRenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); + gSavedSettings.getControl("ShyotlRenderVBOStrideMode")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("SianaRenderOmitBlankVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderUseFBO")->getSignal()->connect(boost::bind(&handleRenderUseFBOChanged, _2)); gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 3d36a99fe..1f0365761 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -64,23 +64,75 @@ public: mTypeMask |= MAP_TEXCOORD2 | MAP_TEXCOORD3; }; - /*// virtual + // virtual void setupVertexBuffer(U32 data_mask) const - { - if (LLDrawPoolTerrain::getDetailMode() == 0 || LLPipeline::sShadowRender) + { + volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; + + //assume tex coords 2 and 3 are present + U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3; + + if ((data_mask & type_mask) != data_mask) { - LLVertexBuffer::setupVertexBuffer(data_mask); + llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; } - else if (data_mask & LLVertexBuffer::MAP_TEXCOORD1) + + if (data_mask & MAP_NORMAL) { - LLVertexBuffer::setupVertexBuffer(data_mask); + glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL])); } - else + if (data_mask & MAP_TEXCOORD3) + { //substitute tex coord 0 for tex coord 3 + glClientActiveTextureARB(GL_TEXTURE3_ARB); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + if (data_mask & MAP_TEXCOORD2) + { //substitute tex coord 0 for tex coord 2 + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + if (data_mask & MAP_TEXCOORD1) { - LLVertexBuffer::setupVertexBuffer(data_mask); + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD1), (void*)(base + mOffsets[TYPE_TEXCOORD1])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - llglassertok(); - }*/ + if (data_mask & MAP_BINORMAL) + { + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(3,GL_FLOAT, getStride(TYPE_BINORMAL), (void*)(base + mOffsets[TYPE_BINORMAL])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + if (data_mask & MAP_TEXCOORD0) + { + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); + } + if (data_mask & MAP_COLOR) + { + glColorPointer(4, GL_UNSIGNED_BYTE, getStride(TYPE_COLOR), (void*)(base + mOffsets[TYPE_COLOR])); + } + + if (data_mask & MAP_WEIGHT) + { + glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT), (void*)(base + mOffsets[TYPE_WEIGHT])); + } + + if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) + { + glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT4), (void*)(base+mOffsets[TYPE_WEIGHT4])); + } + + if (data_mask & MAP_CLOTHWEIGHT) + { + glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, getStride(TYPE_CLOTHWEIGHT), (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + } + if (data_mask & MAP_VERTEX) + { + glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0)); + } + } }; //============================================================================ diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6062461a5..5ae0c27ba 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3048,8 +3048,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) static const LLCachedControl<S32> render_max_vbo_size("RenderMaxVBOSize", 512); static const LLCachedControl<S32> render_max_node_size("RenderMaxNodeSize",8192); - U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); - U32 max_total = (render_max_node_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); + U32 max_total = (render_max_node_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); U32 cur_total = 0; @@ -3552,7 +3552,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { //calculate maximum number of vertices to store in a single buffer static const LLCachedControl<S32> render_max_vbo_size("RenderMaxVBOSize", 512); - U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); if (!distance_sort) diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 8d63b069c..92bc8b65f 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -336,7 +336,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) { const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024; const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK; - const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcStride(data_mask); + const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask); const U32 total_stacks = getNumStacks(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 8103ebefb..e8376c57e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -372,6 +372,7 @@ void LLPipeline::init() sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); + LLVertexBuffer::sForceStrideMode = gSavedSettings.getU32("ShyotlRenderVBOStrideMode"); LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); @@ -5822,6 +5823,7 @@ void LLPipeline::resetVertexBuffers() { sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); + LLVertexBuffer::sForceStrideMode = gSavedSettings.getU32("ShyotlRenderVBOStrideMode"); LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) From f9bcbab5f3278bb62b7d2853f369f6312a55bece Mon Sep 17 00:00:00 2001 From: Shyotl <Shyotl@gmail.com> Date: Fri, 5 Aug 2011 21:39:43 -0500 Subject: [PATCH 07/18] Win compile fix. Including stdint.h explodes in vc2010, so #if'd it out for windows. --- indra/llcommon/llmemory.h | 2 ++ indra/newview/lltexturefetch.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 35cee6653..99aec9997 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -35,7 +35,9 @@ #include <new> #include <cstdlib> +#if !LL_WINDOWS #include <stdint.h> // uintptr_t +#endif #include "llerror.h" diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index d24bff56b..8caf60b02 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1276,9 +1276,9 @@ bool LLTextureFetchWorker::doWork(S32 param) // static const LLCachedControl<U32> max_http_requests("HTTPMaxRequests", 32); static const LLCachedControl<U32> min_http_requests("HTTPMinRequests", 2); - if((mFetcher->getNumHTTPRequests() > max_http_requests) || + if(((U32)mFetcher->getNumHTTPRequests() > max_http_requests) || ((mFetcher->getTextureBandwidth() > mFetcher->mMaxBandwidth) && - (mFetcher->getNumHTTPRequests() > min_http_requests)) || + ((U32)mFetcher->getNumHTTPRequests() > min_http_requests)) || !sgConnectionThrottle()) { return false ; //wait. From f1759e0a968355df9ce800a42ebb8bc0759839d8 Mon Sep 17 00:00:00 2001 From: Shyotl <Shyotl@gmail.com> Date: Sat, 6 Aug 2011 02:27:06 -0500 Subject: [PATCH 08/18] Old-code related to sim-quota cleaned up. --- indra/llcommon/CMakeLists.txt | 2 +- ...llaccountingquota.h => llaccountingcost.h} | 24 +- indra/llinventory/llparcel.cpp | 10 - indra/llinventory/llparcel.h | 11 +- indra/newview/CMakeLists.txt | 4 +- indra/newview/llaccountingcostmanager.cpp | 173 +++++++++++ ...otamanager.h => llaccountingcostmanager.h} | 20 +- indra/newview/llaccountingquotamanager.cpp | 281 ------------------ indra/newview/llfloatertools.cpp | 1 - indra/newview/llmeshrepository.cpp | 16 +- indra/newview/llviewerobject.cpp | 6 - indra/newview/llviewerobject.h | 9 - indra/newview/llviewerobjectlist.cpp | 9 - indra/newview/llviewerobjectlist.h | 1 - indra/newview/llviewerregion.cpp | 138 +++++---- 15 files changed, 296 insertions(+), 409 deletions(-) rename indra/llcommon/{llaccountingquota.h => llaccountingcost.h} (85%) create mode 100644 indra/newview/llaccountingcostmanager.cpp rename indra/newview/{llaccountingquotamanager.h => llaccountingcostmanager.h} (76%) delete mode 100644 indra/newview/llaccountingquotamanager.cpp diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index e7ce0fa9d..c72b4d277 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -96,7 +96,7 @@ set(llcommon_HEADER_FILES indra_constants.h linden_common.h linked_lists.h - llaccountingquota.h + llaccountingcost.h llagentconstants.h llavatarname.h llapp.h diff --git a/indra/llcommon/llaccountingquota.h b/indra/llcommon/llaccountingcost.h similarity index 85% rename from indra/llcommon/llaccountingquota.h rename to indra/llcommon/llaccountingcost.h index 140333de0..0ef3b50c6 100644 --- a/indra/llcommon/llaccountingquota.h +++ b/indra/llcommon/llaccountingcost.h @@ -1,5 +1,5 @@ /** - * @file llaccountingquota.h + * @file llaccountingcost.h * @ * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ @@ -58,22 +58,28 @@ struct ParcelQuota F32 mParcelCapacity; }; -struct SelectionQuota +//SelectionQuota atm does not require a id +struct SelectionCost { - SelectionQuota( LLUUID localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost ) - : mLocalId( localId) - , mRenderCost( renderCost ) - , mPhysicsCost( physicsCost ) + SelectionCost( /*LLTransactionID transactionId, */ F32 physicsCost, F32 networkCost, F32 simulationCost ) + //: mTransactionId( transactionId) + : mPhysicsCost( physicsCost ) , mNetworkCost( networkCost ) , mSimulationCost( simulationCost ) { } - SelectionQuota() {} + SelectionCost() + : mPhysicsCost( 0.0f ) + , mNetworkCost( 0.0f ) + , mSimulationCost( 0.0f ) + {} - F32 mRenderCost, mPhysicsCost, mNetworkCost, mSimulationCost; - LLUUID mLocalId; + F32 mPhysicsCost, mNetworkCost, mSimulationCost; + //LLTransactionID mTransactionId; }; +typedef enum { Roots = 0 , Prims } eSelectionType; + #endif diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 432cb3e61..c167ef194 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -1354,13 +1354,3 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s) // is a distinct option from "None" and "Other" return LLParcel::C_ANY; } - -#if MESH_ENABLED -void LLParcel::updateQuota( const LLUUID& objectId, const ParcelQuota& quota ) -{ - if ( mID == objectId ) - { - mQuota = quota; - } -} -#endif //MESH_ENABLED diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 7d92d4b37..7423229f7 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -40,9 +40,6 @@ #include "llpermissions.h" #include "lltimer.h" #include "v3math.h" -#if MESH_ENABLED -#include "llaccountingquota.h" -#endif //MESH_ENABLED // Grid out of which parcels taken is stepped every 4 meters. const F32 PARCEL_GRID_STEP_METERS = 4.f; @@ -602,10 +599,7 @@ public: BOOL getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; } BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; } -#if MESH_ENABLED - void updateQuota( const LLUUID& objectId, const ParcelQuota& quota ); - const ParcelQuota& getQuota( void ) { return mQuota; } -#endif //MESH_ENABLED + protected: LLUUID mID; LLUUID mOwnerID; @@ -678,9 +672,6 @@ protected: BOOL mRegionPushOverride; BOOL mRegionDenyAnonymousOverride; BOOL mRegionDenyAgeUnverifiedOverride; -#if MESH_ENABLED - ParcelQuota mQuota; -#endif //MESH_ENABLED public: // HACK, make private diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7109b8169..3062e3b0e 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -100,7 +100,7 @@ set(viewer_SOURCE_FILES jcfloaterareasearch.cpp chatbar_as_cmdline.cpp qtoolalign.cpp - llaccountingquotamanager.cpp + llaccountingcostmanager.cpp llagent.cpp llagentaccess.cpp llagentcamera.cpp @@ -580,7 +580,7 @@ set(viewer_HEADER_FILES lgghunspell_wrapper.h chatbar_as_cmdline.h qtoolalign.h - llaccountingquotamanager.h + llaccountingcostmanager.h llagent.h llagentaccess.h llagentcamera.h diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp new file mode 100644 index 000000000..61a0b6932 --- /dev/null +++ b/indra/newview/llaccountingcostmanager.cpp @@ -0,0 +1,173 @@ +/** + * @file LLAccountingQuotaManager.cpp + * @ Handles the setting and accessing for costs associated with mesh + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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$ + */ + +#include "llviewerprecompiledheaders.h" +#if MESH_ENABLED +#include "llaccountingcostmanager.h" +#include "llagent.h" +#include "llcurl.h" +#include "llhttpclient.h" + +//=============================================================================== +LLAccountingCostManager::LLAccountingCostManager() +{ +} +//=============================================================================== +class LLAccountingCostResponder : public LLCurl::Responder +{ +public: + LLAccountingCostResponder( const LLSD& objectIDs ) + : mObjectIDs( objectIDs ) + { + } + + void clearPendingRequests ( void ) + { + for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter ) + { + LLAccountingCostManager::getInstance()->removePendingObject( iter->asUUID() ); + } + } + + void error( U32 statusNum, const std::string& reason ) + { + llwarns << "Transport error "<<reason<<llendl; + clearPendingRequests(); + } + + void result( const LLSD& content ) + { + //Check for error + if ( !content.isMap() || content.has("error") ) + { + llwarns << "Error on fetched data"<< llendl; + clearPendingRequests(); + return; + } + + bool containsSelection = content.has("selected"); + if ( containsSelection ) + { + S32 dataCount = content["selected"].size(); + + for(S32 i = 0; i < dataCount; i++) + { + + F32 physicsCost = 0.0f; + F32 networkCost = 0.0f; + F32 simulationCost = 0.0f; + + //LLTransactionID transactionID; + + //transactionID = content["selected"][i]["local_id"].asUUID(); + physicsCost = content["selected"][i]["physics"].asReal(); + networkCost = content["selected"][i]["streaming"].asReal(); + simulationCost = content["selected"][i]["simulation"].asReal(); + + SelectionCost selectionCost( /*transactionID,*/ physicsCost, networkCost, simulationCost ); + + //How do you want to handle the updating of the invoking object/ui element? + + } + } + } + +private: + //List of posted objects + LLSD mObjectIDs; +}; +//=============================================================================== +void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const std::string& url ) +{ + // Invoking system must have already determined capability availability + if ( !url.empty() ) + { + LLSD objectList; + U32 objectIndex = 0; + + IDIt IDIter = mObjectList.begin(); + IDIt IDIterEnd = mObjectList.end(); + + for ( ; IDIter != IDIterEnd; ++IDIter ) + { + // Check to see if a request for this object has already been made. + if ( mPendingObjectQuota.find( *IDIter ) == mPendingObjectQuota.end() ) + { + mObjectList.insert( *IDIter ); + objectList[objectIndex++] = *IDIter; + } + } + + mObjectList.clear(); + + //Post results + if ( objectList.size() > 0 ) + { + std::string keystr; + if ( selectionType == Roots ) + { + keystr="selected_roots"; + } + else + if ( selectionType == Prims ) + { + keystr="prim_roots"; + } + else + { + llinfos<<"Invalid selection type "<<llendl; + mObjectList.clear(); + mPendingObjectQuota.clear(); + return; + } + + LLSD dataToPost = LLSD::emptyMap(); + dataToPost[keystr.c_str()] = objectList; + + LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList )); + } + } + else + { + //url was empty - warn & continue + llwarns<<"Supplied url is empty "<<llendl; + mObjectList.clear(); + mPendingObjectQuota.clear(); + } +} +//=============================================================================== +void LLAccountingCostManager::addObject( const LLUUID& objectID ) +{ + mObjectList.insert( objectID ); +} +//=============================================================================== +void LLAccountingCostManager::removePendingObject( const LLUUID& objectID ) +{ + mPendingObjectQuota.erase( objectID ); +} +//=============================================================================== +#endif //MESH_ENABLED + diff --git a/indra/newview/llaccountingquotamanager.h b/indra/newview/llaccountingcostmanager.h similarity index 76% rename from indra/newview/llaccountingquotamanager.h rename to indra/newview/llaccountingcostmanager.h index 9251ef935..8ae696a98 100644 --- a/indra/newview/llaccountingquotamanager.h +++ b/indra/newview/llaccountingcostmanager.h @@ -27,29 +27,29 @@ #ifndef LL_ACCOUNTINGQUOTAMANAGER_H #define LL_ACCOUNTINGQUOTAMANAGER_H //=============================================================================== -#include "llaccountingquota.h" +#include "llaccountingcost.h" //=============================================================================== -class LLAccountingQuotaManager : public LLSingleton<LLAccountingQuotaManager> +class LLAccountingCostManager : public LLSingleton<LLAccountingCostManager> { public: //Ctor - LLAccountingQuotaManager(); + LLAccountingCostManager(); //Store an object that will be eventually fetched - void updateObjectCost( const LLUUID& objectID ); + void addObject( const LLUUID& objectID ); //Request quotas for object list - void fetchQuotas( const std::string& url ); + void fetchCosts( eSelectionType selectionType, const std::string& url ); //Delete a specific object from the pending list - void removePendingObjectQuota( const LLUUID& objectID ); + void removePendingObject( const LLUUID& objectID ); private: - //Set of objects that need to update their cost - std::set<LLUUID> mUpdateObjectQuota; - //During fetchQuota we move object into a the pending set to signify that + //Set of objects that will be used to generate a cost + std::set<LLUUID> mObjectList; + //During fetchCosts we move object into a the pending set to signify that //a fetch has been instigated. std::set<LLUUID> mPendingObjectQuota; typedef std::set<LLUUID>::iterator IDIt; }; //=============================================================================== -#endif // LLACCOUNTINGQUOTAMANAGER +#endif // LLACCOUNTINGCOSTMANAGER diff --git a/indra/newview/llaccountingquotamanager.cpp b/indra/newview/llaccountingquotamanager.cpp deleted file mode 100644 index 44d5b7e71..000000000 --- a/indra/newview/llaccountingquotamanager.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/** - * @file LLAccountingQuotaManager.cpp - * @ Handles the setting and accessing for costs associated with mesh - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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$ - */ - -#include "llviewerprecompiledheaders.h" -#if MESH_ENABLED -#include "llaccountingquotamanager.h" -#include "llagent.h" -#include "llviewerregion.h" -#include "llviewerobject.h" -#include "llviewerobjectlist.h" -#include "llviewerparcelmgr.h" -#include "llparcel.h" - -//=============================================================================== -LLAccountingQuotaManager::LLAccountingQuotaManager() -{ -} -//=============================================================================== -class LLAccountingQuotaResponder : public LLCurl::Responder -{ -public: - LLAccountingQuotaResponder( const LLSD& objectIDs ) - : mObjectIDs( objectIDs ) - { - } - - void clearPendingRequests ( void ) - { - for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter ) - { - LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( iter->asUUID() ); - } - } - - void error( U32 statusNum, const std::string& reason ) - { - llwarns << "Transport error "<<reason<<llendl; - //prep#do we really want to remove all because of one failure - verify - clearPendingRequests(); - } - - void result( const LLSD& content ) - { - if ( !content.isMap() || content.has("error") ) - { - llwarns << "Error on fetched data"<< llendl; - //prep#do we really want to remove all because of one failure - verify - clearPendingRequests(); - return; - } - - //Differentiate what the incoming caps could be from the data - bool containsParcel = content.has("parcel"); - bool containsSelection = content.has("selected"); - - //Loop over the stored object ids checking against the incoming data - for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter ) - { - LLUUID objectID = iter->asUUID(); - - LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID ); - - if ( containsParcel ) - { - //Typically should be one - S32 dataCount = content["parcel"].size(); - for(S32 i = 0; i < dataCount; i++) - { - //prep#todo verify that this is safe, otherwise just add a bool - LLUUID parcelId; - //S32 parcelOwner = 0; - if ( content["parcel"][i].has("parcel_id") ) - { - parcelId = content["parcel"][i]["parcel_id"].asUUID(); - } - - //if ( content["parcel"][i].has("parcel_owner") ) - //{ - // parcelOwner = content["parcel"][i]["parcel_owner"].asInteger(); - //} - - F32 ownerRenderCost = 0; - F32 ownerPhysicsCost = 0; - F32 ownerNetworkCost = 0; - F32 ownerSimulationCost = 0; - - F32 groupRenderCost = 0; - F32 groupPhysicsCost = 0; - F32 groupNetworkCost = 0; - F32 groupSimulationCost = 0; - - F32 otherRenderCost = 0; - F32 otherPhysicsCost = 0; - F32 otherNetworkCost = 0; - F32 otherSimulationCost = 0; - - F32 tempRenderCost = 0; - F32 tempPhysicsCost = 0; - F32 tempNetworkCost = 0; - F32 tempSimulationCost = 0; - - F32 selectedRenderCost = 0; - F32 selectedPhysicsCost = 0; - F32 selectedNetworkCost = 0; - F32 selectedSimulationCost = 0; - - F32 parcelCapacity = 0; - - if ( content["parcel"][i].has("capacity") ) - { - parcelCapacity = content["parcel"][i].has("capacity"); - } - - if ( content["parcel"][i].has("owner") ) - { - ownerRenderCost = content["parcel"][i]["owner"]["rendering"].asReal(); - ownerPhysicsCost = content["parcel"][i]["owner"]["physics"].asReal(); - ownerNetworkCost = content["parcel"][i]["owner"]["streaming"].asReal(); - ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal(); - } - - if ( content["parcel"][i].has("group") ) - { - groupRenderCost = content["parcel"][i]["group"]["rendering"].asReal(); - groupPhysicsCost = content["parcel"][i]["group"]["physics"].asReal(); - groupNetworkCost = content["parcel"][i]["group"]["streaming"].asReal(); - groupSimulationCost = content["parcel"][i]["group"]["simulation"].asReal(); - - } - if ( content["parcel"][i].has("other") ) - { - otherRenderCost = content["parcel"][i]["other"]["rendering"].asReal(); - otherPhysicsCost = content["parcel"][i]["other"]["physics"].asReal(); - otherNetworkCost = content["parcel"][i]["other"]["streaming"].asReal(); - otherSimulationCost = content["parcel"][i]["other"]["simulation"].asReal(); - } - - if ( content["parcel"][i].has("temp") ) - { - tempRenderCost = content["parcel"][i]["total"]["rendering"].asReal(); - tempPhysicsCost = content["parcel"][i]["total"]["physics"].asReal(); - tempNetworkCost = content["parcel"][i]["total"]["streaming"].asReal(); - tempSimulationCost = content["parcel"][i]["total"]["simulation"].asReal(); - } - - if ( content["parcel"][i].has("selected") ) - { - selectedRenderCost = content["parcel"][i]["total"]["rendering"].asReal(); - selectedPhysicsCost = content["parcel"][i]["total"]["physics"].asReal(); - selectedNetworkCost = content["parcel"][i]["total"]["streaming"].asReal(); - selectedSimulationCost = content["parcel"][i]["total"]["simulation"].asReal(); - } - - ParcelQuota parcelQuota( ownerRenderCost, ownerPhysicsCost, ownerNetworkCost, ownerSimulationCost, - groupRenderCost, groupPhysicsCost, groupNetworkCost, groupSimulationCost, - otherRenderCost, otherPhysicsCost, otherNetworkCost, otherSimulationCost, - tempRenderCost, tempPhysicsCost, tempNetworkCost, tempSimulationCost, - selectedRenderCost, selectedPhysicsCost, selectedNetworkCost, selectedSimulationCost, - parcelCapacity ); - //Update the Parcel - LLParcel* pParcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(); - if ( pParcel ) - { - pParcel->updateQuota( objectID, parcelQuota ); - } - } - } - else - if ( containsSelection ) - { - S32 dataCount = content["selected"].size(); - for(S32 i = 0; i < dataCount; i++) - { - - F32 renderCost = 0; - F32 physicsCost = 0; - F32 networkCost = 0; - F32 simulationCost = 0; - - LLUUID objectId; - - objectId = content["selected"][i]["local_id"].asUUID(); - renderCost = content["selected"][i]["rendering"].asReal(); - physicsCost = content["selected"][i]["physics"].asReal(); - networkCost = content["selected"][i]["streaming"].asReal(); - simulationCost = content["selected"][i]["simulation"].asReal(); - - SelectionQuota selectionQuota( objectId, renderCost, physicsCost, networkCost, simulationCost ); - - //Update the objects - gObjectList.updateQuota( objectId, selectionQuota ); - - } - } - else - { - //Nothing in string - LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID ); - } - } - } - -private: - //List of posted objects - LLSD mObjectIDs; -}; -//=============================================================================== -void LLAccountingQuotaManager::fetchQuotas( const std::string& url ) -{ - // Invoking system must have already determined capability availability - if ( !url.empty() ) - { - LLSD objectList; - U32 objectIndex = 0; - IDIt IDIter = mUpdateObjectQuota.begin(); - IDIt IDIterEnd = mUpdateObjectQuota.end(); - - for ( ; IDIter != IDIterEnd; ++IDIter ) - { - // Check to see if a request for this object has already been made. - if ( mPendingObjectQuota.find( *IDIter ) == mPendingObjectQuota.end() ) - { - mPendingObjectQuota.insert( *IDIter ); - objectList[objectIndex++] = *IDIter; - } - } - - mUpdateObjectQuota.clear(); - - //Post results - if ( objectList.size() > 0 ) - { - LLSD dataToPost = LLSD::emptyMap(); - dataToPost["object_ids"] = objectList; - LLHTTPClient::post( url, dataToPost, new LLAccountingQuotaResponder( objectList )); - } - } - else - { - //url was empty - warn & continue - llwarns<<"Supplied url is empty "<<llendl; - mUpdateObjectQuota.clear(); - mPendingObjectQuota.clear(); - } -} -//=============================================================================== -void LLAccountingQuotaManager::updateObjectCost( const LLUUID& objectID ) -{ - mUpdateObjectQuota.insert( objectID ); -} -//=============================================================================== -void LLAccountingQuotaManager::removePendingObjectQuota( const LLUUID& objectID ) -{ - mPendingObjectQuota.erase( objectID ); -} -//=============================================================================== -#endif //MESH_ENABLED - diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index ac283ff57..0a9b5dd1d 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -82,7 +82,6 @@ #include "llviewerjoystick.h" #include "lluictrlfactory.h" #if MESH_ENABLED -#include "llaccountingquotamanager.h" #include "llmeshrepository.h" #endif diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 86500e297..1185fea01 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1482,6 +1482,8 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) void LLMeshUploadThread::generateHulls() { + bool has_valid_requests = false ; + for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) { LLMeshUploadData data; @@ -1501,6 +1503,10 @@ void LLMeshUploadThread::generateHulls() { physics = data.mModel[LLModel::LOD_PHYSICS]; } + else if (data.mModel[LLModel::LOD_LOW].notNull()) + { + physics = data.mModel[LLModel::LOD_LOW]; + } else if (data.mModel[LLModel::LOD_MEDIUM].notNull()) { physics = data.mModel[LLModel::LOD_MEDIUM]; @@ -1516,13 +1522,17 @@ void LLMeshUploadThread::generateHulls() if(request->isValid()) { gMeshRepo.mDecompThread->submitRequest(request); - } + has_valid_requests = true ; + } } - - while (!mPhysicsComplete) + + if(has_valid_requests) + { + while (!mPhysicsComplete) { apr_sleep(100); } + } } void LLMeshUploadThread::doWholeModelUpload() diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 57e8b5d18..856a39cb1 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5627,10 +5627,4 @@ public: LLHTTPRegistration<ObjectPhysicsProperties> gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties"); - -void LLViewerObject::updateQuota( const SelectionQuota& quota ) -{ - //update quotas - mSelectionQuota = quota; -} #endif //MESH_ENABLED diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index fadecd742..591578d78 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -49,9 +49,6 @@ #include "v3dmath.h" #include "v3math.h" #include "llvertexbuffer.h" -#if MESH_ENABLED -#include "llaccountingquota.h" -#endif //MESH_ENABLED class LLAgent; // TODO: Get rid of this. class LLAudioSource; @@ -657,11 +654,7 @@ protected: void deleteParticleSource(); void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); -#if MESH_ENABLED public: - void updateQuota( const SelectionQuota& quota ); - const SelectionQuota& getQuota( void ) { return mSelectionQuota; } -#endif //MESH_ENABLED private: void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string @@ -724,8 +717,6 @@ protected: F32 mPhysicsCost; F32 mLinksetPhysicsCost; - SelectionQuota mSelectionQuota; - bool mCostStale; mutable bool mPhysicsShapeUnknown; #endif //MESH_ENABLED diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 94f532306..ca29e5103 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1422,15 +1422,6 @@ void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id) mPendingObjectCost.erase(object_id); } -void LLViewerObjectList::updateQuota( const LLUUID& objectId, const SelectionQuota& quota ) -{ - LLViewerObject* pVO = findObject( objectId ); - if ( pVO ) - { - pVO->updateQuota( quota ); - } -} - void LLViewerObjectList::updatePhysicsFlags(const LLViewerObject* object) { mStalePhysicsFlags.insert(object->getID()); diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index c47ace52e..f38daf617 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -112,7 +112,6 @@ public: F32 restitution, F32 gravity_multiplier); - void updateQuota( const LLUUID& objectId, const SelectionQuota& costs ); #endif //MESH_ENABLED void shiftObjects(const LLVector3 &offset); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 0c57c294f..b57aa7720 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -101,6 +101,8 @@ public: { } + void buildCapabilityNames(LLSD& capabilityNames); + // The surfaces and other layers LLSurface* mLandp; @@ -1480,6 +1482,82 @@ void LLViewerRegion::unpackRegionHandshake() msg->sendReliable(host); } + +void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) +{ + //capabilityNames.append("AttachmentResources"); //Script limits (llfloaterscriptlimits.cpp) + //capabilityNames.append("AvatarPickerSearch"); //Display name/SLID lookup (llfloateravatarpicker.cpp) + capabilityNames.append("ChatSessionRequest"); + capabilityNames.append("CopyInventoryFromNotecard"); + capabilityNames.append("DispatchRegionInfo"); + capabilityNames.append("EstateChangeInfo"); + capabilityNames.append("EventQueueGet"); + /*capabilityNames.append("EnvironmentSettings"); + capabilityNames.append("ObjectMedia"); + capabilityNames.append("ObjectMediaNavigate");*/ + + if (false)//gSavedSettings.getBOOL("UseHTTPInventory")) //Caps suffixed with 2 by LL. Don't update until rest of fetch system is updated first. + { + capabilityNames.append("FetchLib"); + capabilityNames.append("FetchLibDescendents"); + capabilityNames.append("FetchInventory"); + capabilityNames.append("FetchInventoryDescendents"); + } + + capabilityNames.append("GetDisplayNames"); + capabilityNames.append("GetTexture"); +#if MESH_ENABLED + capabilityNames.append("GetMesh"); + capabilityNames.append("GetObjectCost"); + capabilityNames.append("GetObjectPhysicsData"); +#endif //MESH_ENABLED + capabilityNames.append("GroupProposalBallot"); + + capabilityNames.append("HomeLocation"); + //capabilityNames.append("LandResources"); //Script limits (llfloaterscriptlimits.cpp) + capabilityNames.append("MapLayer"); + capabilityNames.append("MapLayerGod"); +#if MESH_IMPORT + capabilityNames.append("MeshUploadFlag"); +#endif //MESH_IMPORT + capabilityNames.append("NewFileAgentInventory"); + capabilityNames.append("ParcelPropertiesUpdate"); + capabilityNames.append("ParcelMediaURLFilterList"); + capabilityNames.append("ParcelNavigateMedia"); + capabilityNames.append("ParcelVoiceInfoRequest"); + capabilityNames.append("ProductInfoRequest"); + capabilityNames.append("ProvisionVoiceAccountRequest"); + capabilityNames.append("RemoteParcelRequest"); + capabilityNames.append("RequestTextureDownload"); + capabilityNames.append("ResourceCostSelected"); //Unreferenced? + capabilityNames.append("SearchStatRequest"); + capabilityNames.append("SearchStatTracking"); + capabilityNames.append("SendPostcard"); + capabilityNames.append("SendUserReport"); + capabilityNames.append("SendUserReportWithScreenshot"); + capabilityNames.append("ServerReleaseNotes"); + //capabilityNames.append("SimConsole"); + capabilityNames.append("SimulatorFeatures"); + capabilityNames.append("SetDisplayName"); + //capabilityNames.append("SimConsoleAsync"); + capabilityNames.append("StartGroupProposal"); + capabilityNames.append("TextureStats"); + capabilityNames.append("UntrustedSimulatorMessage"); + capabilityNames.append("UpdateAgentInformation"); + capabilityNames.append("UpdateAgentLanguage"); + capabilityNames.append("UpdateGestureAgentInventory"); + capabilityNames.append("UpdateNotecardAgentInventory"); + capabilityNames.append("UpdateScriptAgent"); + capabilityNames.append("UpdateGestureTaskInventory"); + capabilityNames.append("UpdateNotecardTaskInventory"); + capabilityNames.append("UpdateScriptTask"); + capabilityNames.append("UploadBakedTexture"); + //capabilityNames.append("ViewerMetrics"); + capabilityNames.append("ViewerStartAuction"); + capabilityNames.append("ViewerStats"); + // Please add new capabilities alphabetically to reduce + // merge conflicts. +} void LLViewerRegion::setSeedCapability(const std::string& url) { if (getCapability("Seed") == url) @@ -1495,63 +1573,9 @@ void LLViewerRegion::setSeedCapability(const std::string& url) setCapability("Seed", url); LLSD capabilityNames = LLSD::emptyArray(); - capabilityNames.append("ChatSessionRequest"); - capabilityNames.append("CopyInventoryFromNotecard"); - capabilityNames.append("DispatchRegionInfo"); - capabilityNames.append("EstateChangeInfo"); - capabilityNames.append("EventQueueGet"); - if (false)//gSavedSettings.getBOOL("UseHTTPInventory")) //Caps suffixed with 2 by LL. Don't update until rest of fetch system is updated first. - { - capabilityNames.append("FetchLib"); - capabilityNames.append("FetchLibDescendents"); - capabilityNames.append("FetchInventory"); - capabilityNames.append("FetchInventoryDescendents"); - } - capabilityNames.append("GetDisplayNames"); - capabilityNames.append("GetTexture"); -#if MESH_ENABLED - capabilityNames.append("GetMesh"); - capabilityNames.append("GetObjectCost"); - capabilityNames.append("GetObjectPhysicsData"); -#endif //MESH_ENABLED - capabilityNames.append("GroupProposalBallot"); - - capabilityNames.append("HomeLocation"); - capabilityNames.append("MapLayer"); - capabilityNames.append("MapLayerGod"); - capabilityNames.append("NewFileAgentInventory"); - capabilityNames.append("ParcelPropertiesUpdate"); - capabilityNames.append("ParcelMediaURLFilterList"); - capabilityNames.append("ParcelNavigateMedia"); - capabilityNames.append("ParcelVoiceInfoRequest"); - capabilityNames.append("ProductInfoRequest"); - capabilityNames.append("ProvisionVoiceAccountRequest"); - capabilityNames.append("RemoteParcelRequest"); - capabilityNames.append("RequestTextureDownload"); - capabilityNames.append("SearchStatRequest"); - capabilityNames.append("SearchStatTracking"); - capabilityNames.append("SendPostcard"); - capabilityNames.append("SendUserReport"); - capabilityNames.append("SendUserReportWithScreenshot"); - capabilityNames.append("ServerReleaseNotes"); - capabilityNames.append("SimulatorFeatures"); - capabilityNames.append("SetDisplayName"); - capabilityNames.append("StartGroupProposal"); - capabilityNames.append("TextureStats"); - capabilityNames.append("UntrustedSimulatorMessage"); - capabilityNames.append("UpdateAgentInformation"); - capabilityNames.append("UpdateAgentLanguage"); - capabilityNames.append("UpdateGestureAgentInventory"); - capabilityNames.append("UpdateNotecardAgentInventory"); - capabilityNames.append("UpdateScriptAgent"); - capabilityNames.append("UpdateGestureTaskInventory"); - capabilityNames.append("UpdateNotecardTaskInventory"); - capabilityNames.append("UpdateScriptTask"); - capabilityNames.append("UploadBakedTexture"); - capabilityNames.append("ViewerStartAuction"); - capabilityNames.append("ViewerStats"); - // Please add new capabilities alphabetically to reduce - // merge conflicts. + + mImpl->buildCapabilityNames(capabilityNames); + llinfos << "posting to seed " << url << llendl; From 9aa26648c9d49d9de348d226fdc1c134adef534f Mon Sep 17 00:00:00 2001 From: Shyotl <Shyotl@gmail.com> Date: Sat, 6 Aug 2011 02:29:04 -0500 Subject: [PATCH 09/18] Added CurlUseMultipleThreads (requires restart to change) --- indra/llmessage/llcurl.cpp | 161 ++++++++++++++++-------- indra/llmessage/llcurl.h | 8 +- indra/newview/app_settings/settings.xml | 13 +- indra/newview/llappviewer.cpp | 2 +- 4 files changed, 126 insertions(+), 58 deletions(-) diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 524c0ef17..8192b97a9 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -92,6 +92,9 @@ std::vector<LLMutex*> LLCurl::sSSLMutex; std::string LLCurl::sCAPath; std::string LLCurl::sCAFile; +bool LLCurl::sMultiThreaded = false; +static U32 sMainThreadID = 0; + void check_curl_code(CURLcode code) { if (code != CURLE_OK) @@ -250,7 +253,7 @@ public: U32 report(CURLcode); void getTransferInfo(LLCurl::TransferInfo* info); - void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, bool post = false); + void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, S32 time_out = 0, bool post = false); const char* getErrorBuffer(); @@ -549,7 +552,7 @@ size_t curlHeaderCallback(void* data, size_t size, size_t nmemb, void* user_data void LLCurl::Easy::prepRequest(const std::string& url, const std::vector<std::string>& headers, - ResponderPtr responder, bool post) + ResponderPtr responder, S32 time_out, bool post) { resetState(); @@ -599,7 +602,7 @@ void LLCurl::Easy::prepRequest(const std::string& url, //don't verify host name so urls with scrubbed host names will work (improves DNS performance) setopt(CURLOPT_SSL_VERIFYHOST, 0); - setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT); + setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT)); setoptString(CURLOPT_URL, url); @@ -642,6 +645,7 @@ public: S32 process(); void perform(); + void doPerform(); virtual void run(); @@ -654,6 +658,7 @@ public: LLCondition* mSignal; bool mQuitting; + bool mThreaded; private: void easyFree(Easy*); @@ -675,7 +680,16 @@ LLCurl::Multi::Multi() mPerformState(PERFORM_STATE_READY) { mQuitting = false; - mSignal = new LLCondition; + + mThreaded = LLCurl::sMultiThreaded && LLThread::currentID() == sMainThreadID; + if (mThreaded) + { + mSignal = new LLCondition; + } + else + { + mSignal = NULL; + } mCurlMultiHandle = curl_multi_init(); if (!mCurlMultiHandle) @@ -722,16 +736,25 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) void LLCurl::Multi::perform() { - mSignal->lock(); - if (mPerformState == PERFORM_STATE_READY) + if (mThreaded) { - mSignal->signal(); + mSignal->lock(); + if (mPerformState == PERFORM_STATE_READY) + { + mSignal->signal(); + } + mSignal->unlock(); } - mSignal->unlock(); + else + { + doPerform(); + } } void LLCurl::Multi::run() { + llassert(mThreaded); + mSignal->lock(); while (!mQuitting) { @@ -739,26 +762,31 @@ void LLCurl::Multi::run() mPerformState = PERFORM_STATE_PERFORMING; if (!mQuitting) { - S32 q = 0; - for (S32 call_count = 0; - call_count < MULTI_PERFORM_CALL_REPEAT; - call_count += 1) - { - CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); - if (CURLM_CALL_MULTI_PERFORM != code || q == 0) - { - check_curl_multi_code(code); - break; - } - - } - mQueued = q; - mPerformState = PERFORM_STATE_COMPLETED; + doPerform(); } } mSignal->unlock(); } +void LLCurl::Multi::doPerform() +{ + S32 q = 0; + for (S32 call_count = 0; + call_count < MULTI_PERFORM_CALL_REPEAT; + call_count += 1) + { + CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); + if (CURLM_CALL_MULTI_PERFORM != code || q == 0) + { + check_curl_multi_code(code); + break; + } + + } + mQueued = q; + mPerformState = PERFORM_STATE_COMPLETED; +} + S32 LLCurl::Multi::process() { perform(); @@ -883,16 +911,21 @@ LLCurlRequest::~LLCurlRequest() for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter) { LLCurl::Multi* multi = *iter; - multi->mSignal->lock(); - multi->mQuitting = true; - while (!multi->isStopped()) - { - multi->mSignal->signal(); - multi->mSignal->unlock(); - apr_sleep(1000); + if (multi->mThreaded) multi->mSignal->lock(); + multi->mQuitting = true; + if (multi->mThreaded) + { + while (!multi->isStopped()) + { + multi->mSignal->signal(); + multi->mSignal->unlock(); + apr_sleep(1000); + multi->mSignal->lock(); + } } - multi->mSignal->unlock(); + if (multi->mThreaded) + multi->mSignal->unlock(); } for_each(mMultiSet.begin(), mMultiSet.end(), DeletePointer()); } @@ -901,7 +934,10 @@ void LLCurlRequest::addMulti() { llassert_always(mThreadID == LLThread::currentID()); LLCurl::Multi* multi = new LLCurl::Multi(); - multi->start(); + if (multi->mThreaded) + { + multi->start(); + } mMultiSet.insert(multi); mActiveMulti = multi; mActiveRequestCount = 0; @@ -963,14 +999,14 @@ bool LLCurlRequest::getByteRange(const std::string& url, bool LLCurlRequest::post(const std::string& url, const headers_t& headers, const LLSD& data, - LLCurl::ResponderPtr responder) + LLCurl::ResponderPtr responder, S32 time_out) { LLCurl::Easy* easy = allocEasy(); if (!easy) { return false; } - easy->prepRequest(url, headers, responder); + easy->prepRequest(url, headers, responder, time_out); LLSDSerialize::toXML(data, easy->getInput()); S32 bytes = easy->getInput().str().length(); @@ -990,14 +1026,14 @@ bool LLCurlRequest::post(const std::string& url, bool LLCurlRequest::post(const std::string& url, const headers_t& headers, const std::string& data, - LLCurl::ResponderPtr responder) + LLCurl::ResponderPtr responder, S32 time_out) { LLCurl::Easy* easy = allocEasy(); if (!easy) { return false; } - easy->prepRequest(url, headers, responder); + easy->prepRequest(url, headers, responder, time_out); easy->getInput().write(data.data(), data.size()); S32 bytes = easy->getInput().str().length(); @@ -1031,16 +1067,21 @@ S32 LLCurlRequest::process() if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0) { mMultiSet.erase(curiter); - multi->mSignal->lock(); + if (multi->mThreaded) + multi->mSignal->lock(); multi->mQuitting = true; - while (!multi->isStopped()) + if (multi->mThreaded) { - multi->mSignal->signal(); - multi->mSignal->unlock(); - apr_sleep(1000); - multi->mSignal->unlock(); + while (!multi->isStopped()) + { + multi->mSignal->signal(); + multi->mSignal->unlock(); + apr_sleep(1000); + multi->mSignal->unlock(); + } } - multi->mSignal->unlock(); + if (multi->mThreaded) + multi->mSignal->unlock(); delete multi; } @@ -1059,6 +1100,10 @@ S32 LLCurlRequest::getQueued() curlmulti_set_t::iterator curiter = iter++; LLCurl::Multi* multi = *curiter; queued += multi->mQueued; + if (multi->mPerformState != LLCurl::Multi::PERFORM_STATE_READY) + { + ++queued; + } } return queued; } @@ -1072,7 +1117,10 @@ LLCurlEasyRequest::LLCurlEasyRequest() mResultReturned(false) { mMulti = new LLCurl::Multi(); - mMulti->start(); + if (mMulti->mThreaded) + { + mMulti->start(); + } mEasy = mMulti->allocEasy(); if (mEasy) { @@ -1083,16 +1131,21 @@ LLCurlEasyRequest::LLCurlEasyRequest() LLCurlEasyRequest::~LLCurlEasyRequest() { - mMulti->mSignal->lock(); - mMulti->mQuitting = true; - while (!mMulti->isStopped()) - { - mMulti->mSignal->signal(); - mMulti->mSignal->unlock(); - apr_sleep(1000); + if (mMulti->mThreaded) mMulti->mSignal->lock(); + mMulti->mQuitting = true; + if (mMulti->mThreaded) + { + while (!mMulti->isStopped()) + { + mMulti->mSignal->signal(); + mMulti->mSignal->unlock(); + apr_sleep(1000); + mMulti->mSignal->lock(); + } } - mMulti->mSignal->unlock(); + if (mMulti->mThreaded) + mMulti->mSignal->unlock(); delete mMulti; } @@ -1287,8 +1340,10 @@ unsigned long LLCurl::ssl_thread_id(void) } #endif -void LLCurl::initClass() +void LLCurl::initClass(bool multi_threaded) { + sMainThreadID = LLThread::currentID(); + sMultiThreaded = multi_threaded; // Do not change this "unless you are familiar with and mean to control // internal operations of libcurl" // - http://curl.haxx.se/libcurl/c/curl_global_init.html diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 02abd7400..988205921 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -61,6 +61,8 @@ public: class Easy; class Multi; + static bool sMultiThreaded; + struct TransferInfo { TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {} @@ -164,7 +166,7 @@ public: /** * @ brief Initialize LLCurl class */ - static void initClass(); + static void initClass(bool multi_threaded = false); /** * @ brief Cleanup LLCurl class @@ -206,8 +208,8 @@ public: void get(const std::string& url, LLCurl::ResponderPtr responder); bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder); - bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder); - bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder); + bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder, S32 time_out = 0); + bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder, S32 time_out = 0); S32 process(); S32 getQueued(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ca13e4f39..2fa47eaea 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3772,10 +3772,21 @@ <key>Value</key> <integer>0</integer> </map> + <key>CurlUseMultipleThreads</key> + <map> + <key>Comment</key> + <string>Use background threads for executing curl_multi_perform (requires restart)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>Cursor3D</key> <map> <key>Comment</key> - <string>Tread Joystick values as absolute positions (not deltas).</string> + <string>Treat Joystick values as absolute positions (not deltas).</string> <key>Persist</key> <integer>1</integer> <key>Type</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e8fed149a..f621e0779 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -592,7 +592,7 @@ bool LLAppViewer::init() // *NOTE:Mani - LLCurl::initClass is not thread safe. // Called before threads are created. - LLCurl::initClass(); + LLCurl::initClass(gSavedSettings.getBOOL("CurlUseMultipleThreads")); LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ; initThreads(); From a5f38565fa46e4a57ebcbebf77a0ab24f80e79e5 Mon Sep 17 00:00:00 2001 From: Shyotl <Shyotl@gmail.com> Date: Sat, 6 Aug 2011 18:14:54 -0500 Subject: [PATCH 10/18] Henri-inspired tweakage. --- indra/newview/llworld.cpp | 4 +-- indra/newview/llworldmapview.cpp | 47 ++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index b1e42c084..171d6a9bb 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -653,8 +653,8 @@ void LLWorld::updateRegions(F32 max_update_time) BOOL did_one = FALSE; // Perform idle time updates for the regions (and associated surfaces) - for (region_list_t::iterator iter = mRegionList.begin(); - iter != mRegionList.end(); ++iter) + for (region_list_t::iterator iter = mActiveRegionList.begin()/*mRegionList.begin()*/; + iter != mActiveRegionList.end()/*mRegionList.end()*/; ++iter) { LLViewerRegion* regionp = *iter; F32 max_time = max_update_time - update_timer.getElapsedTimeF32(); diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index d4c9c7f66..575e8120b 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -484,13 +484,15 @@ void LLWorldMapView::draw() gGL.setSceneBlendType(LLRender::BT_ALPHA); // Infohubs - if (gSavedSettings.getBOOL("MapShowInfohubs")) //(sMapScale >= sThresholdB) + static const LLCachedControl<bool> map_show_infohubs("MapShowInfohubs"); + if (map_show_infohubs) //(sMapScale >= sThresholdB) { drawGenericItems(LLWorldMap::getInstance()->mInfohubs, sInfohubImage); } // Telehubs - if (gSavedSettings.getBOOL("MapShowTelehubs")) //(sMapScale >= sThresholdB) + static const LLCachedControl<bool> map_show_telehubs("MapShowTelehubs"); + if (map_show_telehubs) //(sMapScale >= sThresholdB) { drawGenericItems(LLWorldMap::getInstance()->mTelehubs, sTelehubImage); } @@ -502,7 +504,8 @@ void LLWorldMapView::draw() drawImage(home, sHomeImage); } - if (gSavedSettings.getBOOL("MapShowLandForSale")) + static const LLCachedControl<bool> map_show_land_for_sale("MapShowLandForSale"); + if (map_show_land_for_sale) { drawGenericItems(LLWorldMap::getInstance()->mLandForSale, sForSaleImage); // for 1.23, we're showing normal land and adult land in the same UI; you don't @@ -514,12 +517,7 @@ void LLWorldMapView::draw() } } - if (gSavedSettings.getBOOL("MapShowPGEvents") || - gSavedSettings.getBOOL("MapShowMatureEvents") || - gSavedSettings.getBOOL("MapShowAdultEvents") ) - { - drawEvents(); - } + drawEvents(); // Now draw your avatar after all that other stuff. LLVector3d pos_global = gAgent.getPositionGlobal(); @@ -541,7 +539,8 @@ void LLWorldMapView::draw() // Draw icons for the avatars in each region. // Drawn after your avatar so you can see nearby people. - if (gSavedSettings.getBOOL("MapShowPeople")) + static const LLCachedControl<bool> map_show_people("MapShowPeople"); + if (map_show_people) { drawAgents(); } @@ -887,7 +886,8 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.vertex3f(right, top, 0.f); gGL.end(); - if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->hasGLTexture()) + static const LLCachedControl<bool> map_show_land_for_sale("MapShowLandForSale"); + if (map_show_land_for_sale && overlayimage && overlayimage->hasGLTexture()) { gGL.getTexUnit(0)->bind(overlayimage); gGL.color4f(1.f, 1.f, 1.f, alpha); @@ -1057,9 +1057,13 @@ void LLWorldMapView::drawEvents() bool mature_enabled = gAgent.canAccessMature(); bool adult_enabled = gAgent.canAccessAdult(); - BOOL show_pg = gSavedSettings.getBOOL("MapShowPGEvents"); - BOOL show_mature = mature_enabled && gSavedSettings.getBOOL("MapShowMatureEvents"); - BOOL show_adult = adult_enabled && gSavedSettings.getBOOL("MapShowAdultEvents"); + static const LLCachedControl<bool> map_show_pg_events("MapShowPGEvents"); + static const LLCachedControl<bool> map_show_mature_events("MapShowMatureEvents"); + static const LLCachedControl<bool> map_show_adult_events("MapShowAdultEvents"); + + BOOL show_pg = map_show_pg_events; + BOOL show_mature = mature_enabled && map_show_mature_events; + BOOL show_adult = adult_enabled && map_show_adult_events; // First the non-selected events LLWorldMap::item_info_list_t::const_iterator e; @@ -1874,8 +1878,9 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, } // Select event you clicked on - if (gSavedSettings.getBOOL("MapShowPGEvents")) - { + static const LLCachedControl<bool> map_show_pg_events("MapShowPGEvents"); + if (map_show_pg_events) + { for (it = LLWorldMap::getInstance()->mPGEvents.begin(); it != LLWorldMap::getInstance()->mPGEvents.end(); ++it) { LLItemInfo& event = *it; @@ -1889,7 +1894,8 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, } } } - if (gSavedSettings.getBOOL("MapShowMatureEvents")) + static const LLCachedControl<bool> map_show_mature_events("MapShowMatureEvents"); + if (map_show_mature_events) { for (it = LLWorldMap::getInstance()->mMatureEvents.begin(); it != LLWorldMap::getInstance()->mMatureEvents.end(); ++it) { @@ -1904,7 +1910,8 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, } } } - if (gSavedSettings.getBOOL("MapShowAdultEvents")) + static const LLCachedControl<bool> map_show_adult_events("MapShowAdultEvents"); + if (map_show_adult_events) { for (it = LLWorldMap::getInstance()->mAdultEvents.begin(); it != LLWorldMap::getInstance()->mAdultEvents.end(); ++it) { @@ -1919,8 +1926,8 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, } } } - - if (gSavedSettings.getBOOL("MapShowLandForSale")) + static const LLCachedControl<bool> map_show_land_for_sale("MapShowLandForSale"); + if (map_show_land_for_sale) { for (it = LLWorldMap::getInstance()->mLandForSale.begin(); it != LLWorldMap::getInstance()->mLandForSale.end(); ++it) { From 1e7415095c9674d8004ab4b226b2ef1d04293a03 Mon Sep 17 00:00:00 2001 From: Shyotl <Shyotl@gmail.com> Date: Sat, 6 Aug 2011 18:17:55 -0500 Subject: [PATCH 11/18] mCurlGetRequest->process() kersploded. Debugger is being dumb, so adding an assertion for now. --- indra/newview/lltexturefetch.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 8caf60b02..d5e094b0f 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1144,7 +1144,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (region) { - std::string http_url = region->getCapability("GetTexture"); + std::string http_url = region->getHttpUrl() ; if (!http_url.empty()) { mUrl = http_url + "/?texture_id=" + mID.asString().c_str(); @@ -2348,6 +2348,7 @@ void LLTextureFetch::commonUpdate() #endif // Update Curl on same thread as mCurlGetRequest was constructed + llassert_always(mCurlGetRequest); S32 processed = mCurlGetRequest->process(); if (processed > 0) { From 3d1863c1b5d2b408320e3bae5e48fa7cda1ec655 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sun, 7 Aug 2011 18:47:01 +0200 Subject: [PATCH 12/18] Make sure we assign name before mStatus --- indra/llcommon/llthread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index c2b93ebed..f81b53ae2 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -102,7 +102,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap // Setting mStatus to STOPPED is done non-thread-safe, so it's // possible that the thread is deleted by another thread at // the moment it happens... therefore make a copy here. - volatile char const* name = threadp->mName.c_str(); + char const* volatile name = threadp->mName.c_str(); // We're done with the run function, this thread is done executing now. threadp->mStatus = STOPPED; From 2e88db37ad4d5fe6e5d6010a4d4259aa8d59911a Mon Sep 17 00:00:00 2001 From: Siana Gearz <siana.sg@live.de> Date: Sun, 7 Aug 2011 22:32:07 +0200 Subject: [PATCH 13/18] Signed warning in texture fetcher --- indra/newview/app_settings/settings.xml | 4 ++-- indra/newview/lltexturefetch.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index cfe10a2e2..1998eab74 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -39,7 +39,7 @@ <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>U32</string> + <string>S32</string> <key>Value</key> <integer>32</integer> </map> @@ -50,7 +50,7 @@ <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>U32</string> + <string>S32</string> <key>Value</key> <integer>2</integer> </map> diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index d24bff56b..83de34ecd 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1274,8 +1274,8 @@ bool LLTextureFetchWorker::doWork(S32 param) //1, not openning too many file descriptors at the same time; //2, control the traffic of http so udp gets bandwidth. // - static const LLCachedControl<U32> max_http_requests("HTTPMaxRequests", 32); - static const LLCachedControl<U32> min_http_requests("HTTPMinRequests", 2); + static const LLCachedControl<S32> max_http_requests("HTTPMaxRequests", 32); + static const LLCachedControl<S32> min_http_requests("HTTPMinRequests", 2); if((mFetcher->getNumHTTPRequests() > max_http_requests) || ((mFetcher->getTextureBandwidth() > mFetcher->mMaxBandwidth) && (mFetcher->getNumHTTPRequests() > min_http_requests)) || From 5f4328767b41ff2261e942f0806ff051e68362c3 Mon Sep 17 00:00:00 2001 From: Siana Gearz <siana.sg@live.de> Date: Sun, 7 Aug 2011 22:40:36 +0200 Subject: [PATCH 14/18] Debug needs SSE2 now too --- indra/cmake/00-Common.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 66abb6edb..916878ec3 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -31,10 +31,10 @@ if (WINDOWS) # Don't build DLLs. set(BUILD_SHARED_LIBS OFF) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd" + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /arch:SSE2" CACHE STRING "C++ compiler debug options" FORCE) set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP" + "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /arch:SSE2" CACHE STRING "C++ compiler release-with-debug options" FORCE) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /arch:SSE /fp:fast" From 2cb0dedbd17f581b2bf01aca097b7650f689a083 Mon Sep 17 00:00:00 2001 From: Siana Gearz <siana.sg@live.de> Date: Mon, 8 Aug 2011 02:39:29 +0200 Subject: [PATCH 15/18] This should fix KV TVs --- indra/newview/llviewermedia.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 4b086f808..b79249860 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -682,9 +682,16 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi LLURI uri(url); std::string scheme = uri.scheme(); - if(scheme.empty() || "http" == scheme || "https" == scheme) + if(scheme.empty() || ("http" == scheme || "https" == scheme)) { - LLHTTPClient::getHeaderOnly( url, new LLMimeDiscoveryResponder(this)); + if(mime_type.empty()) + { + LLHTTPClient::getHeaderOnly( url, new LLMimeDiscoveryResponder(this)); + } + else if(initializeMedia(mime_type) && (plugin = getMediaPlugin())) + { + plugin->loadURI( url ); + } } else if("data" == scheme || "file" == scheme || "about" == scheme) { From e9777f25a4f2f6303f0201d0200a99688ced345e Mon Sep 17 00:00:00 2001 From: Siana Gearz <siana.sg@live.de> Date: Wed, 10 Aug 2011 23:57:43 +0200 Subject: [PATCH 16/18] OSSL support by Fritigern, fixes #122 --- .../lscript_library/lscript_library.cpp | 156 ++++- .../skins/default/xui/en-us/strings.xml | 623 ++++++++++++++++-- 2 files changed, 719 insertions(+), 60 deletions(-) diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp index c78a72cdb..ffbb91340 100644 --- a/indra/lscript/lscript_library/lscript_library.cpp +++ b/indra/lscript/lscript_library/lscript_library.cpp @@ -1,11 +1,11 @@ -/** +/** * @file lscript_library.cpp * @brief external library interface * * $LicenseInfo:firstyear=2002&license=viewergpl$ - * + * * Copyright (c) 2002-2009, Linden Research, Inc. - * + * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 @@ -13,17 +13,17 @@ * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * + * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * + * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. - * + * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. @@ -37,7 +37,7 @@ // ## ## ## ## ## ######## ## ## ## ## ## ## ## ## #### ## ## // ## ## ## ######### ## ## ## #### ## ## #### ## ## // ## ## ## ## ## ## ## ## ### ## ## ### ## ## #### #### -// ### ### ## ## ## ## ## ## #### ## ## ###### #### #### +// ### ### ## ## ## ## ## ## #### ## ## ###### #### #### // // When adding functions, they <b>MUST</b> be appended to the end of // the init() method. The init() associates the name with a number, @@ -327,7 +327,7 @@ void LLScriptLibrary::init() addFunction(10.f, 0.2f, dummy_func, "llSetRemoteScriptAccessPin", NULL, "i"); addFunction(10.f, 3.f, dummy_func, "llRemoteLoadScriptPin", NULL, "ksiii"); - + addFunction(10.f, 1.f, dummy_func, "llOpenRemoteDataChannel", NULL, NULL); addFunction(10.f, 3.f, dummy_func, "llSendRemoteData", "k", "ksis"); addFunction(10.f, 3.f, dummy_func, "llRemoteDataReply", NULL, "kksi"); @@ -343,7 +343,7 @@ void LLScriptLibrary::init() addFunction(10.f, 0.f, dummy_func, "llLog", "f", "f"); addFunction(10.f, 0.f, dummy_func, "llGetAnimationList", "l", "k"); addFunction(10.f, 2.f, dummy_func, "llSetParcelMusicURL", NULL, "s"); - + addFunction(10.f, 0.f, dummy_func, "llGetRootPosition", "v", NULL); addFunction(10.f, 0.f, dummy_func, "llGetRootRotation", "q", NULL); @@ -362,7 +362,7 @@ void LLScriptLibrary::init() addFunction(10.f, 0.0f, dummy_func, "llBase64ToInteger", "i", "s"); addFunction(10.f, 0.f, dummy_func, "llGetGMTclock", "f", ""); addFunction(10.f, 10.f, dummy_func, "llGetSimulatorHostname", "s", ""); - + addFunction(10.f, 0.2f, dummy_func, "llSetLocalRot", NULL, "q"); addFunction(10.f, 0.f, dummy_func, "llParseStringKeepNulls", "l", "sll"); @@ -385,12 +385,12 @@ void LLScriptLibrary::init() addFunction(10.f, 2.f, dummy_func, "llParcelMediaQuery", "l", "l"); addFunction(10.f, 1.f, dummy_func, "llModPow", "i", "iii"); - + addFunction(10.f, 0.f, dummy_func, "llGetInventoryType", "i", "s"); addFunction(10.f, 0.f, dummy_func, "llSetPayPrice", NULL, "il"); addFunction(10.f, 0.f, dummy_func, "llGetCameraPos", "v", ""); addFunction(10.f, 0.f, dummy_func, "llGetCameraRot", "q", ""); - + addFunction(10.f, 20.f, dummy_func, "llSetPrimURL", NULL, "s"); addFunction(10.f, 20.f, dummy_func, "llRefreshPrimURL", NULL, ""); addFunction(10.f, 0.f, dummy_func, "llEscapeURL", "s", "s"); @@ -403,7 +403,7 @@ void LLScriptLibrary::init() addFunction(10.f, 0.f, dummy_func, "llSetCameraParams", NULL, "l"); addFunction(10.f, 0.f, dummy_func, "llClearCameraParams", NULL, NULL); - + addFunction(10.f, 0.f, dummy_func, "llListStatistics", "f", "il"); addFunction(10.f, 0.f, dummy_func, "llGetUnixTime", "i", NULL); addFunction(10.f, 0.f, dummy_func, "llGetParcelFlags", "i", "v"); @@ -425,7 +425,7 @@ void LLScriptLibrary::init() addFunction(10.f, 0.2f, dummy_func, "llSetLinkPrimitiveParams", NULL, "il"); addFunction(10.f, 0.2f, dummy_func, "llSetLinkTexture", NULL, "isi"); - + addFunction(10.f, 0.f, dummy_func, "llStringTrim", "s", "si"); addFunction(10.f, 0.f, dummy_func, "llRegionSay", NULL, "is"); addFunction(10.f, 0.f, dummy_func, "llGetObjectDetails", "l", "kl"); @@ -470,11 +470,135 @@ void LLScriptLibrary::init() addFunction(10.f, 0.f, dummy_func, "llGetEnv", "s", "s"); addFunction(10.f, 0.f, dummy_func, "llRegionSayTo", NULL, "kis"); + // Adding missing (more recent) LSL functions. + + addFunction(10.f, 0.f, dummy_func, "llCastRay", "l", "vvl"); + addFunction(10.f, 0.f, dummy_func, "llGetSPMaxMemory", "i", NULL); + addFunction(10.f, 0.f, dummy_func, "llGetUsedMemory", "i", NULL); + addFunction(10.f, 0.f, dummy_func, "llGodLikeRezObject", NULL, "kv"); + addFunction(10.f, 0.f, dummy_func, "llScriptProfiler", NULL, "i"); + addFunction(10.f, 0.f, dummy_func, "llSetInventoryPermMask", NULL, "sii"); + addFunction(10.f, 0.f, dummy_func, "llSetObjectPermMask", NULL, "ii"); + // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only // IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST. // Otherwise the bytecode numbers for each call will be wrong, and all // existing scripts will crash. + + // REGARDING OSSL FUNCTIONS + // These additions should be posted underneath the llFunctions + // These functions pertain to OpenSimulator and are in no part applicable to SecondLife by Linden Labs + // The Current State of these functions are in flux and development is ongoing. Not all the functions are presently + // documented and therefore the description may be incomplete and require further attention. + // OpenSimulator is written in C# and not CPP therefore some values for example "double = float" etc. are different. + + // OSSL corrections and syntax additions added + set in same order as found in OSSL_stub.cs of OpenSim Source (Updated PM October-21-2010 + // based on OpenSimulator Ver. 0.7.x DEV/Master Git # a7acb650d400a280a7b9edabd304376dff9c81af - a7acb65-r/14142 + // Updates by WhiteStar Magic + + addFunction(10.f, 0.f, dummy_func, "osSetRegionWaterHeight", NULL, "f"); + addFunction(10.f, 0.f, dummy_func, "osSetRegionSunSettings", NULL, "iif"); + addFunction(10.f, 0.f, dummy_func, "osSetEstateSunSettings", NULL, "if"); + addFunction(10.f, 0.f, dummy_func, "osGetCurrentSunHour", "f", NULL); + addFunction(10.f, 0.f, dummy_func, "osSunGetParam","f", "s"); // Deprecated. Use osGetSunParam instead + addFunction(10.f, 0.f, dummy_func, "osSunSetParam", "sf", NULL); // Deprecated. Use osSetSunParam instead + addFunction(10.f, 0.f, dummy_func, "osWindActiveModelPluginName", "s", NULL); + addFunction(10.f, 0.f, dummy_func, "osParcelJoin", NULL, "vv"); + addFunction(10.f, 0.f, dummy_func, "osParcelSubdivide", NULL, "vv"); + addFunction(10.f, 0.f, dummy_func, "osParcelSetDetails", NULL, "vv"); // Deprecated. Use osSetParcelDetails instead. + // addFunction(10.f, 0.f, dummy_func, "osWindParamSet", NULL, "ssf"); // This function was renamed before it was implemented. Leaving this in for now. + // addFunction(10.f, 0.f, dummy_func, "osWindParamGet", "f", "ss"); // This function was renamed before it was implemented. Leaving this in for now. + addFunction(10.f, 0.f, dummy_func, "osList2Double", "f", "li"); + addFunction(10.f, 0.f, dummy_func, "osSetDynamicTextureURL", NULL, "ksssi"); + addFunction(10.f, 0.f, dummy_func, "osSetDynamicTextureData", NULL, "ksssi"); + addFunction(10.f, 0.f, dummy_func, "osSetDynamicTextureURLBlend", NULL, "ksssii"); + addFunction(10.f, 0.f, dummy_func, "osSetDynamicTextureDataBlend", NULL, "ksssii"); + addFunction(10.f, 0.f, dummy_func, "osSetDynamicTextureURLBlendFace", NULL, "ksssfiiii"); + addFunction(10.f, 0.f, dummy_func, "osSetDynamicTextureDataBlendFace", NULL, "ksssfiiii"); + addFunction(10.f, 0.f, dummy_func, "osTerrainGetHeight", "f", "ii"); // Deprecated. Use osGetTerrainHeight instead + addFunction(10.f, 0.f, dummy_func, "osTerrainSetHeight", NULL, "iif"); // Deprecated. Use osSetTerrainHeight instead + addFunction(10.f, 0.f, dummy_func, "osTerrainFlush", NULL, NULL); + addFunction(10.f, 0.f, dummy_func, "osRegionRestart", "i", "f"); + addFunction(10.f, 0.f, dummy_func, "osRegionNotice",NULL, "s"); + addFunction(10.f, 0.f, dummy_func, "osConsoleCommand", NULL, "s"); + addFunction(10.f, 0.f, dummy_func, "osSetParcelMediaURL", NULL, "s"); + addFunction(10.f, 0.f, dummy_func, "osSetParcelSIPAddress", NULL, "s"); + addFunction(10.f, 0.f, dummy_func, "osSetPrimFloatOnWater", NULL, "i"); + addFunction(10.f, 0.f, dummy_func, "osTeleportAgent", NULL, "ksvv"); + addFunction(10.f, 0.f, dummy_func, "osGetAgentIP", "s", "k"); + addFunction(10.f, 0.f, dummy_func, "osGetAgents", "l", NULL); + addFunction(10.f, 0.f, dummy_func, "osAvatarPlayAnimation", NULL, "ks"); + addFunction(10.f, 0.f, dummy_func, "osAvatarStopAnimation", NULL, "ks"); + addFunction(10.f, 0.f, dummy_func, "osMovePen", NULL, "sii"); + addFunction(10.f, 0.f, dummy_func, "osDrawLine", NULL, "siiii"); + addFunction(10.f, 0.f, dummy_func, "osDrawText", NULL, "ss"); + addFunction(10.f, 0.f, dummy_func, "osDrawEllipse", NULL, "sii"); + addFunction(10.f, 0.f, dummy_func, "osDrawRectangle", NULL, "sii"); + addFunction(10.f, 0.f, dummy_func, "osDrawFilledRectangle", NULL, "sii"); + addFunction(10.f, 0.f, dummy_func, "osDrawPolygon", "s", "sll"); + addFunction(10.f, 0.f, dummy_func, "osDrawFilledPolygon", "s", "sll"); + addFunction(10.f, 0.f, dummy_func, "osSetFontSize", NULL, "si"); + addFunction(10.f, 0.f, dummy_func, "osSetFontName", NULL, "ss"); + addFunction(10.f, 0.f, dummy_func, "osSetPenSize", NULL, "si"); + addFunction(10.f, 0.f, dummy_func, "osSetPenCap", NULL, "sss"); + addFunction(10.f, 0.f, dummy_func, "osSetPenColour", NULL, "ss"); // Deprecated. Use osSetPenColor instead + addFunction(10.f, 0.f, dummy_func, "osDrawImage", NULL, "siis"); + addFunction(10.f, 0.f, dummy_func, "osGetDrawStringSize", "v", "sssi"); + addFunction(10.f, 0.f, dummy_func, "osSetStateEvents", NULL, "i"); + addFunction(10.f, 0.f, dummy_func, "osGetScriptEngineName", "s", NULL); + addFunction(10.f, 0.f, dummy_func, "osGetSimulatorVersion", "s", NULL); + addFunction(10.f, 0.f, dummy_func, "osParseJSON", "s", "s"); + addFunction(10.f, 0.f, dummy_func, "osMessageObject", NULL, "ks"); + addFunction(10.f, 0.f, dummy_func, "osMakeNotecard", NULL, "sl"); + addFunction(10.f, 0.f, dummy_func, "osGetNotecardLine", "s", "si"); + addFunction(10.f, 0.f, dummy_func, "osGetNotecard", "s", "s"); + addFunction(10.f, 0.f, dummy_func, "osGetNumberOfNotecardLines", "i", "s"); + addFunction(10.f, 0.f, dummy_func, "osAvatarName2Key", "k", "ss"); + addFunction(10.f, 0.f, dummy_func, "osKey2Name", "s", "k"); + addFunction(10.f, 0.f, dummy_func, "osGetGridNick", "s", NULL); + addFunction(10.f, 0.f, dummy_func, "osGetGridName", "s", NULL); + addFunction(10.f, 0.f, dummy_func, "osGetGridLoginURI", "s", NULL); + addFunction(10.f, 0.f, dummy_func, "osFormatString", "s", "sl"); + addFunction(10.f, 0.f, dummy_func, "osMatchString", "l", "ssi"); + addFunction(10.f, 0.f, dummy_func, "osLoadedCreationDate", "s", NULL); + addFunction(10.f, 0.f, dummy_func, "osLoadedCreationTime", "s", NULL); + addFunction(10.f, 0.f, dummy_func, "osLoadedCreationID", "s", NULL); + addFunction(10.f, 0.f, dummy_func, "osGetLinkPrimitiveParams", "l", "il"); + addFunction(10.f, 0.f, dummy_func, "osNpcCreate", "k", "ssvk"); + addFunction(10.f, 0.f, dummy_func, "osNpcMoveTo", NULL, "kv"); + addFunction(10.f, 0.f, dummy_func, "osNpcSay", NULL, "ks"); + addFunction(10.f, 0.f, dummy_func, "osNpcRemove", NULL, "k"); + addFunction(10.f, 0.f, dummy_func, "osGetMapTexture", "k", NULL); + addFunction(10.f, 0.f, dummy_func, "osGetRegionMapTexture", "k", "s"); + addFunction(10.f, 0.f, dummy_func, "osGetRegionStats", "l", NULL); + addFunction(10.f, 0.f, dummy_func, "osGetSimulatorMemory", "i", NULL); + addFunction(10.f, 0.f, dummy_func, "osKickAvatar", NULL, "sss"); + addFunction(10.f, 0.f, dummy_func, "osSetSpeed", NULL, "kf"); + addFunction(10.f, 0.f, dummy_func, "osCauseDamage", NULL, "kf"); + addFunction(10.f, 0.f, dummy_func, "osCauseHealing", NULL, "kf"); + addFunction(10.f, 0.f, dummy_func, "osGetPrimitiveParams", "l", "kl"); + addFunction(10.f, 0.f, dummy_func, "osSetPrimitiveParams", NULL, "kl"); + addFunction(10.f, 0.f, dummy_func, "osSetProjectionParams", NULL, "kikfff"); + addFunction(10.f, 0.f, dummy_func, "osUnixTimeToTimestamp", "s", "i"); + addFunction(10.f, 0.f, dummy_func, "osSetPenColor", NULL, "ss"); + addFunction(10.f, 0.f, dummy_func, "osGetSunParam","f", "s"); + addFunction(10.f, 0.f, dummy_func, "osSetSunParam", "sf", NULL); + addFunction(10.f, 0.f, dummy_func, "osSetParcelDetails", NULL, "vl"); + addFunction(10.f, 0.f, dummy_func, "osGetTerrainHeight", "f", "ii"); + addFunction(10.f, 0.f, dummy_func, "osSetTerrainHeight", NULL, "iif"); + addFunction(10.f, 0.f, dummy_func, "osGetAvatarList", "l", NULL); + addFunction(10.f, 0.f, dummy_func, "osTeleportOwner", NULL, "svv"); + + // LightShare functions + addFunction(10.f, 0.f, dummy_func, "cmSetWindlightScene", "i", "l"); + addFunction(10.f, 0.f, dummy_func, "cmSetWindlightSceneTargeted", "i", "lk"); + addFunction(10.f, 0.f, dummy_func, "cmGetWindlightScene", "l", "l"); + // LightShare functions - alternate versions + // don't ask me why they renamed 'em, but we need to include both versions -- MC + addFunction(10.f, 0.f, dummy_func, "lsSetWindlightScene", "i", "l"); + addFunction(10.f, 0.f, dummy_func, "lsSetWindlightSceneTargeted", "i", "lk"); + addFunction(10.f, 0.f, dummy_func, "lsGetWindlightScene", "l", "l"); } LLScriptLibraryFunction::LLScriptLibraryFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, BOOL god_only) @@ -494,7 +618,7 @@ void LLScriptLibrary::addFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibD void LLScriptLibrary::assignExec(const char *name, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &)) { - for (std::vector<LLScriptLibraryFunction>::iterator i = mFunctions.begin(); + for (std::vector<LLScriptLibraryFunction>::iterator i = mFunctions.begin(); i != mFunctions.end(); ++i) { if (!strcmp(name, i->mName)) @@ -503,7 +627,7 @@ void LLScriptLibrary::assignExec(const char *name, void (*exec_func)(LLScriptLib return; } } - + llerrs << "Unknown LSL function in assignExec: " << name << llendl; } diff --git a/indra/newview/skins/default/xui/en-us/strings.xml b/indra/newview/skins/default/xui/en-us/strings.xml index ba0074d58..83db17102 100644 --- a/indra/newview/skins/default/xui/en-us/strings.xml +++ b/indra/newview/skins/default/xui/en-us/strings.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <!-- This file contains strings that used to be hardcoded in the source. It is only for those strings which don't belong in a floater. - For example, the strings used in avatar chat bubbles, and strings + For example, the strings used in avatar chat bubbles, and strings that are returned from one component and may appear in many places--> <strings> - + <string name="hippo_label_free">free</string> <string name="hippo_label_week">week</string> <string name="TeleportOfferMaturity"> @@ -12,7 +12,7 @@ </string> <string name="TeleportLureMaturity"> [NAME]'s teleport lure is to [DESTINATION] - </string> + </string> <!-- Login --> <string name="LoginInProgress">Logging in. [APP_NAME] may appear frozen. Please wait.</string> @@ -36,8 +36,8 @@ <!-- Disconnection --> <string name="AgentLostConnection">This region may be experiencing trouble. Please check your connection to the Internet.</string> - - + + <!-- Tooltip, llhoverview.cpp --> <string name="TooltipPerson">Person</string><!-- Object under mouse pointer is an avatar --> <string name="TooltipNoName">(no name)</string> <!-- No name on an object --> @@ -63,9 +63,9 @@ <string name="TooltipFlagGroupScripts">Group Scripts</string> <string name="TooltipFlagNoScripts">No Scripts</string> <string name="TooltipLand">Land:</string> - <string name="TooltipMustSingleDrop">Only a single item can be dragged here</string> + <string name="TooltipMustSingleDrop">Only a single item can be dragged here</string> + - <!-- Indicates that an avatar's name or other similar datum is being retrieved. General usage. --> <string name="RetrievingData">Retrieving...</string> @@ -73,21 +73,21 @@ <!-- Indicates something is being loaded. Maybe should be merged with RetrievingData --> <string name="LoadingData">Loading...</string> - - + + <!-- namecache --> <!-- Avatar name: text shown for LLUUID::null --> <string name="AvatarNameNobody">(nobody)</string> - + <!-- Avatar name: text shown while fetching name --> <string name="AvatarNameWaiting">(waiting)</string> <!-- Avatar name: text shown as an alternative to AvatarNameFetching, easter egg. --> <string name="AvatarNameHippos">(hippos)</string> - + <!-- Group name: text shown for LLUUID::null --> <string name="GroupNameNone">(none)</string> - + <!-- Asset errors. Used in llassetstorage.cpp, translation from error code to error message. --> <string name="AssetErrorNone">No error</string> <string name="AssetErrorRequestFailed">Asset request: failed</string> @@ -100,7 +100,7 @@ <string name="AssetErrorCircuitGone">Circuit gone</string> <string name="AssetErrorPriceMismatch">Viewer and server do not agree on price</string> <string name="AssetErrorUnknownStatus">Unknown status</string> - + <!-- llvoavatar. Displayed in the avatar's chat bubble --> <string name="AvatarEditingApparance">(Editing Appearance)</string> <string name="AvatarAway">Away</string> @@ -177,24 +177,24 @@ <string name="anim_express_worry">Worry</string> <string name="anim_yes_happy">Yes (Happy)</string> <string name="anim_yes_head">Yes</string> - + <string name="texture_loading">Loading...</string> <string name="worldmap_offline">Offline</string> - + <!-- Chat --> <string name="whisper">whispers:</string> <string name="shout">shouts:</string> - + <!-- Sim Access labels --> <string name="SIM_ACCESS_PG">PG</string> <string name="SIM_ACCESS_MATURE">Mature</string> <string name="SIM_ACCESS_ADULT">Adult</string> <string name="SIM_ACCESS_DOWN">Offline</string> <string name="SIM_ACCESS_MIN">Unknown</string> - + <!-- For use when we do not have land type back from the server --> <string name="land_type_unknown">(unknown)</string> - + <!-- Covenant info --> <string name="covenant_never_modified">Last Modified: (never)</string> <string name="covenant_modified">Last Modified: </string> @@ -215,7 +215,7 @@ <string name="compressed_image_files">Compressed Images</string> <string name="load_files">Load Files</string> <string name="choose_the_directory">Choose Directory</string> - + <!-- LSL Usage Hover Tips --> <string name="LSLTipSleepTime"> Sleeps script for [SLEEP_TIME] seconds. @@ -1650,8 +1650,8 @@ string llGetHTTPHeader(key request_id, string header) Returns the value for header for request_id </string> <string name="LSLTipText_llSetPrimMediaParams"> - integer llSetPrimMediaParams(integer face, list params) - Returns an integer that is a STATUS_* flag which details the success/failure of the operation(s). +integer llSetPrimMediaParams(integer face, list params) +Returns an integer that is a STATUS_* flag which details the success/failure of the operation(s). </string> <string name="LSLTipText_llGetPrimMediaParams"> list llGetPrimMediaParams(integer face, list params) @@ -1659,54 +1659,589 @@ Returns the media params for a particular face on an object, given the desired l (Returns an empty list if no media exists on the face.) </string> <string name="LSLTipText_llClearPrimMedia"> - integer llClearPrimMedia(integer face) - Returns an integer that is a STATUS_* flag which details the success/failure of the operation. +integer llClearPrimMedia(integer face) +Returns an integer that is a STATUS_* flag which details the success/failure of the operation. </string> <string name="LSLTipText_llSetLinkPrimitiveParamsFast"> - llSetLinkPrimitiveParamsFast(integer linknumber, list rules) - Set primitive parameters for linknumber based on rules with no built-in script sleep. +llSetLinkPrimitiveParamsFast(integer linknumber, list rules) +Set primitive parameters for linknumber based on rules with no built-in script sleep. </string> <string name="LSLTipText_llGetLinkPrimitiveParams"> - list llGetLinkPrimitiveParams(integer linknumber,list rules) +list llGetLinkPrimitiveParams(integer linknumber,list rules) Get primitive parameters for linknumber based on rules. </string> <string name="LSLTipText_llLinkParticleSystem"> - list llLinkParticleSystem(integer linknumber, list rules) +list llLinkParticleSystem(integer linknumber, list rules) Creates a particle system based on rules. Empty list removes particle system from object. List format is [ rule1, data1, rule2, data2 . . . rulen, datan ]. </string> <string name="LSLTipText_llSetLinkTextureAnim"> - llSetLinkTextureAnim(integer link, integer mode, integer face, integer sizex, integer sizey, float start, float length, float rate) - Animate the texture on the specified face/faces of the specified prim/prims by setting the texture scale and offset. +llSetLinkTextureAnim(integer link, integer mode, integer face, integer sizex, integer sizey, float start, float length, float rate) +Animate the texture on the specified face/faces of the specified prim/prims by setting the texture scale and offset. </string> <string name="LSLTipText_llGetLinkNumberOfSides"> - integer llGetLinkNumberOfSides(integer link) - Returns the number of sides of the specified linked prim. +integer llGetLinkNumberOfSides(integer link) +Returns the number of sides of the specified linked prim. </string> <string name="LSLTipText_llGetUsername"> - string llGetUsername(key id) - Returns the single-word username of an avatar, iff the avatar is in the current region, otherwise the empty string. +string llGetUsername(key id) +Returns the single-word username of an avatar, if the avatar is in the current region, otherwise the empty string. </string> <string name="LSLTipText_llRequestUsername"> - key llRequestUsername(key id) - Requests single-word username of an avatar. When data is available the dataserver event will be raised. +key llRequestUsername(key id) +Requests single-word username of an avatar. When data is available the dataserver event will be raised. </string> <string name="LSLTipText_llGetDisplayName"> - string llGetDisplayName(key id) - Returns the name of an avatar, iff the avatar is in the current simulator, and the name has been cached, otherwise the same as llGetUsername. Use llRequestDisplayName if you absolutely must have the display name. +string llGetDisplayName(key id) +Returns the name of an avatar, if the avatar is in the current simulator, and the name has been cached, otherwise the same as llGetUsername. Use llRequestDisplayName if you absolutely must have the display name. </string> <string name="LSLTipText_llRequestDisplayName"> - key llRequestDisplayName(key id) - Requests name of an avatar. When data is available the dataserver event will be raised. +key llRequestDisplayName(key id) +Requests name of an avatar. When data is available the dataserver event will be raised. </string> -<string name="LSLTipText_llRegionSayTo"> + <string name="LSLTipText_llRegionSayTo"> llRegionSayTo(key target, integer channel, string msg) Sends msg on channel (not DEBUG_CHANNEL) directly to prim or avatar target anywhere within the region -</string> -<string name="LSLTipText_llGetEnv"> + </string> + <string name="LSLTipText_llGetEnv"> string llGetEnv(string name) Returns a string with the requested data about the region -</string> + </string> + <string name="LSLTipText_llCastRay"> +list llCastRay( Vector start, Vector end, list options ) +Returns a list consisting of the following three values for each hit: UUID, Link number, Hit position. + </string> + <string name="LSLTipText_llGetSPMaxMemory"> +integer llGetSPMaxMemory( ) +Returns the integer of the most bytes used while llScriptProfiler was last active. + </string> + <string name="LSLTipText_llGetUsedMemory"> +integer llGetUsedMemory( ) +Returns the integer of the number of bytes of memory currently in use by the script. + </string> + <string name="LSLTipText_llGodLikeRezObject"> +llGodLikeRezObject( key inventory, vector pos ) +Rez directly off of UUID if owner has god-bit set. +(Requires god mode) + </string> + <string name="LSLTipText_llScriptProfiler"> +llScriptProfiler( integer flags ) +Enables or disables the scripts profiling state. + </string> + <string name="LSLTipText_llSetInventoryPermMask"> +llSetInventoryPermMask( string item, integer mask, integer value ) +Sets the given permission mask to the new value on the inventory item. +(Requires god mode) + </string> + <string name="LSLTipText_llSetObjectPermMask"> +llSetObjectPermMask( integer mask, integer value ) +Sets the given permission mask to the new value on the root object the task is attached to. +(Requires god mode) + </string> + +<!-- Addition of OSSL commands for use in OpenSimulator based regions, including Aurora --> + <string name="LSLTipText_osSetRegionWaterHeight"> +osSetRegionWaterHeight(float height) +Adjusts water height on region. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetRegionSunSettings"> +osSetRegionSunSettings(integer useEstateSun, integer sunFixed, float sunHour) +Changes the estate sun settings, then triggers a sun update +'sunFixed' TRUE to keep the sun stationary, FALSE to use global time +'sunHour' The sun hour that is desired, 0...24, 0 is sunrise. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetEstateSunSettings"> +osSetEstateSunSettings(integer sunFixed, float sunHour) +sunFixed = TRUE or FALSE, sunHour = 00.00 to 24.00. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetCurrentSunHour"> +float osGetCurrentSunHour() +Returns float value of current sun hour 0...24 0 is sunrise. +(OpenSim only.) + </string> + <string name="LSLTipText_osSunGetParam"> +*DEPRECATED* Use osGetSunParam instead. +(OpenSim only.) + </string> + <string name="LSLTipText_osSunSetParam"> +*DEPRECATED* Use osSetSunParam instead. +(OpenSim only.) + </string> + <string name="LSLTipText_osWindActiveModelPluginName"> +string osWindActiveModelPluginName() +Returns the current working wind module installed +These are SimpleRandomWind or ConfigurableWind. +(OpenSim only.) + </string> + <string name="LSLTipText_osParcelJoin"> +osParcelJoin(vector pos1, vector pos2)) +Joins parcels @ X,Y coordinates. +(OpenSim only.) + </string> + <string name="LSLTipText_osParcelSubdivide"> +osParcelSubdivide(vector pos1, vector pos2)) +Subdivides parcels @ X,Y coordinates. +(OpenSim only.) + </string> + <string name="LSLTipText_osParcelSetDetails"> +*DEPRECATED* Use osSetParcelDetails instead. +(OpenSim only.) + </string> + <string name="LSLTipText_osWindParamSet"> +*DEPRECATED* Use osSetWindParam instead. +(OpenSim only.) + </string> + <string name="LSLTipText_osWindParamGet"> +*DEPRECATED* Use osGetWindParam instead. +(OpenSim only.) + </string> + <string name="LSLTipText_osList2Double"> +double osList2Double(list src, integer index) +Returns double-precision value from src at index. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetDynamicTextureURL"> +osSetDynamicTextureURL(key dynamicID, string contentType, string url, string extraParams, integer timer ) +Renders a web texture on the prim containing the script, and returns the UUID of the newly created texture. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetDynamicTextureData"> +osSetDynamicTextureData(key dynamicID, string contentType, string data, string extraParams, integer timer) +Writes text and vector graphics onto a prim face. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetDynamicTextureURLBlend"> +osSetDynamicTextureURLBlend(key dynamicID, string contentType, string url, string extraParams, integer timer, integer alpha) +Allows for two dynamic textures to blend on the prim containing this script. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetDynamicTextureDataBlend"> +osSetDynamicTextureDataBlend(key dynamicID, string contentType, string data, string extraParams, integer timer, integer alpha) +Allows for two dynamic textures to blend on the prim containing this script. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetDynamicTextureURLBlendFace"> +osSetDynamicTextureURLBlendFace(key dynamicID, string contentType, string url, string extraParams, integer blend, integer disp, integer timer, integer alpha, integer face) +Loads a web texture on a prim. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetDynamicTextureDataBlendFace"> +osSetDynamicTextureDataBlendFace(key dynamicID, string contentType, string data, string extraParams, integer blend, integer disp, integer timer, integer alpha, integer face) +(OpenSim only.) + </string> + <string name="LSLTipText_osTerrainGetHeight"> +*DEPRECATED* Use osGetTerrainHeight instead. +(OpenSim only.) + </string> + <string name="LSLTipText_osTerrainSetHeight"> +*DEPRECATED* Use osSetTerrainHeight instead. +(OpenSim only.) + </string> + <string name="LSLTipText_osTerrainFlush"> +osTerrainFlush() +Updates terrain data. Call this after you are done using osTerrainSetHeight. +(OpenSim only.) + </string> + <string name="LSLTipText_osRegionRestart"> +integer osRegionRestart(float seconds) +Restart the current region in the specified number of seconds from now. +(OpenSim only.) + </string> + <string name="LSLTipText_osRegionNotice"> +osRegionNotice(string msg) +Broadcasts a notification message to all agents on the current region. +(OpenSim only.) + </string> + <string name="LSLTipText_osConsoleCommand"> +osConsoleCommand(string command) +Issues commands directly to the OpenSim server console. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetParcelMediaURL"> +osSetParcelMediaURL(string url) +Sets parcel media URL. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetParcelSIPAddress"> +osSetParcelSIPAddress(string SIPAddress) +Sets parcel SIP Address for Voice. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetPrimFloatOnWater"> +osSetPrimFloatOnWater(integer floatYN) +Make physical prims float at the water level, TRUE or FALSE. +(OpenSim only.) + </string> + <string name="LSLTipText_osTeleportAgent"> +osTeleportAgent(key agent, integer regionX, integer regionY, vector position, vector lookat) + or +osTeleportAgent(key agent, string regionName, vector position, vector lookat) + or +osTeleportAgent(key agent, vector position, vector lookat) +Teleports the specified agent to a specified location in the region, the grid, or the hypergrid. See documentation for details. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetAgentIP"> +string osGetAgentIP(key agent) +Returns the Avatars IP Address +Allows in-world tools be used to coordinate out of world network services that need access to client IP addresses. +Should *ONLY* be used by Region Server Owner. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetAgents"> +list osGetAgents() +Returns a list of all avatars in the region in which the script is running. +(OpenSim only.) + </string> + <string name="LSLTipText_osAvatarPlayAnimation"> +osAvatarPlayAnimation(key UUID, string animation) +Triggers animations contained within the same prim as the script. Does not need the target avatar's permission. +(OpenSim only.) + </string> + <string name="LSLTipText_osAvatarStopAnimation"> +osAvatarStopAnimation(key UUID, string animation) +Stops specified animation on the specified avatar. +(OpenSim only.) + </string> + <string name="LSLTipText_osMovePen"> +osMovePen(string drawList, integer x, integer y) +Moves the pen's location to the coordinates specified by the x and y parameters, without drawing anything. +(OpenSim only.) + </string> + <string name="LSLTipText_osDrawLine"> +osDrawLine(string drawList, integer startX, integer startY, integer endX, integer endY) +osDrawLine(string drawList, integer endX, integer endY) +Draws a line on a dynamic texture. +(OpenSim only.) + </string> + <string name="LSLTipText_osDrawText"> +osDrawText(string drawList, string text) +Renders text on a dynamic texture. +(OpenSim only.) + </string> + <string name="LSLTipText_osDrawEllipse"> +osDrawEllipse(string drawList, integer width, integer height) +Draws an ellipse on a dynamic texture. +(OpenSim only.) + </string> + <string name="LSLTipText_osDrawRectangle"> +osDrawRectangle(string drawList, integer width, integer height) +Draws a rectangle on a dynamic texture. +(OpenSim only.) + </string> + <string name="LSLTipText_osDrawFilledRectangle"> +osDrawFilledRectangle(string drawList, integer width, integer height) +Draws a rectangle on a dynamic texture, and fills it with the current pen color. +(OpenSim only.) + </string> + <string name="LSLTipText_osDrawPolygon"> +string osDrawPolygon (string drawList, list x, list y) +Draws a polygon on a dynamic texture. +(OpenSim only.) + </string> + <string name="LSLTipText_osDrawFilledPolygon"> +string osDrawFilledPolygon (string drawList, list x, list y) +Draws a polygon on a dynamic texture, and fills it with the current pen color. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetFontSize"> +osSetFontSize(string drawList, integer fontSize) +Sets the font size to be used in osDrawText. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetFontName"> +osSetFontName(string drawList, string fontName) +Sets current font to be used by osDrawText. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetPenSize"> +osSetPenSize(string drawList, integer penSize) +Sets the pen size (line thickness) that is to be used when drawing dynamic textures. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetPenCap"> +osSetPenCap(string drawList, string direction, string type) +Apply a shape on the end of a line. This allows using arrow, diamond, round and flat caps. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetPenColour"> +*DEPRECATED* Use osSetPenColor instead +(OpenSim only.) + </string> + <string name="LSLTipText_osDrawImage"> +osDrawImage(string drawList, integer width, integer height, string imageUrl) +Retrieves an image specified by the imageUrl parameter and draws it at the specified height and width. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetDrawStringSize"> +vector osGetDrawStringSize(string contentType, string text, string fontName, integer fontSize) +Returns a vector containing the horizontal and vertical dimensions in pixels of the specified text +(OpenSim only.) + </string> + <string name="LSLTipText_osSetStateEvents"> +osSetStateEvents(integer events) +Used in the past as a workaround for a bug with Opensim, which has long since been fixed. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetScriptEngineName"> +string osGetScriptEngineName() +Returns the name of the script engine which is currently enabled on the server. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetSimulatorVersion"> +string osGetSimulatorVersion() +Returns OpenSim server version information as a string. +(OpenSim only.) + </string> + <string name="LSLTipText_osParseJSON"> +string osParseJSON(string JSON) +Returns a hashtable containing the structured JSON contents. +(OpenSim only.) + </string> + <string name="LSLTipText_osMessageObject"> +osMessageObject(key UUID, string message) +Sends a string to the object identified by UUID. +The receiving object requires a dataserver(key queryid, string data) in a contained script(s). +The queryid passed will be the id of the calling object. +(OpenSim only.) + </string> + <string name="LSLTipText_osMakeNotecard"> +osMakeNotecard(string notecardName, list contents) +Write a Notecard contained in Prim with contents of list. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetNotecardLine"> +string osGetNotecardLine(string name, integer line) +Reads the requested notecard line and return its data as a string. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetNotecard"> +string osGetNotecard(string name) +Reads the entire notecard and return its data as a string. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetNumberOfNotecardLines"> +integer osGetNumberOfNotecardLines(string name) +Returns total number of lines in a notecard. +(OpenSim only.) + </string> + <string name="LSLTipText_osAvatarName2Key"> +key osAvatarName2Key(string firstname, string lastname) +Returns the avatar's UUID from their firstname, lastname. +(OpenSim only.) + </string> + <string name="LSLTipText_osKey2Name"> +string osKey2Name(key UUID) +Returns avatar name from their UUID key. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetGridNick"> +string osGetGridNick() +Returns the grid's nickname. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetGridName"> +string osGetGridName() +Returns the grid's name. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetGridLoginURI"> +string osGetGridLoginURI() +Returns the grid's LoginURI. +(OpenSim only.) + </string> + <string name="LSLTipText_osFormatString"> +string osFormatString(string str, list strings) +Return the string with parameters substituted into it (format comes from .NET String.Format class) +Parameters are specified positionally. +(OpenSim only.) + </string> + <string name="LSLTipText_osMatchString"> +list osMatchString(string src, string pattern, integer start) +Return a list of matches for the pattern and its components inside the source string. +The pattern is a regular expression. Each match in the result is the string that matched and its position in the source. +(OpenSim only.) + </string> + <string name="LSLTipText_osLoadedCreationDate"> +string osLoadedCreationDate() +Returns Creation Date from meta data of OAR. +(OpenSim only.) + </string> + <string name="LSLTipText_osLoadedCreationTime"> +string osLoadedCreationTime() +Returns Creation Time from meta data of OAR. +(OpenSim only.) + </string> + <string name="LSLTipText_osLoadedCreationID"> +string osLoadedCreationID() +Returns creation ID from meta data of OAR. Can not be used to identify a machine. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetLinkPrimitiveParams"> +list osGetLinkPrimitiveParams(integer linknumber, list rules) +Returns the primitive parameters for the linkset prims specified by linknumber. If using linkset constants (e.g. LINK_SET, LINK_ALL_CHILDREN, etc), the requested parameters of each relevant prim are concatenated to the end of the list. Otherwise, usage is identical to llGetPrimitiveParams(). +(OpenSim only.) + </string> + <string name="LSLTipText_osNpcCreate"> +key osNpcCreate(string firstname, string lastname, vector position, key UUID) +Creates an NPC (Non Player Character) clone named firstname lastname at position from an already existing avatar specified by UUID. +(OpenSim only.) + </string> + <string name="LSLTipText_osNpcMoveTo"> +osNpcMoveTo(key npc, vector position) +Moves an NPC to a location within the region. +(OpenSim only.) + </string> + <string name="LSLTipText_osNpcSay"> +osNpcSay(key npc, string message) +Makes an NPC say something. +(OpenSim only.) + </string> + <string name="LSLTipText_osNpcRemove"> +osNpcRemove(key npc) +Removes an NPC. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetMapTexture"> +key osGetMapTexture() +Returns the map texture UUID. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetRegionMapTexture"> +key osGetRegionMapTexture(string regionName) +Returns the map texture UUID for the regionName requested. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetRegionStats"> +list osGetRegionStats() +Returns a list of float values representing a number of region statistics (21 of the values shown in the statistics bar of LL-based clients). +(OpenSim only.) + </string> + <string name="LSLTipText_osGetSimulatorMemory"> +integer osGetSimulatorMemory() +Returns the current amount of RAM used by the current OpenSim instance. +(OpenSim only.) + </string> + <string name="LSLTipText_osKickAvatar"> +osKickAvatar(string FirstName, string LastName, string alert) +Kicks avatar from region with an alert message. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetSpeed"> +osSetSpeed(key UUID, float SpeedModifier) +Multiplies the normal running, walking, and flying speed of the specified avatar. +(OpenSim only.) + </string> + <string name="LSLTipText_osCauseDamage"> +osCauseDamage(key UUID, float damage) +Causes damage to specified avatar. +(OpenSim only.) + </string> + <string name="LSLTipText_osCauseHealing"> +osCauseHealing(key UUID, float healing) +Causes healing to specified avatar. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetPrimitiveParams"> +list osGetPrimitiveParams(key prim, list rules) +Gets the parameters of the primitive, specified by key. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetPrimitiveParams"> +osSetPrimitiveParams(key prim, list rules) +Sets primitive Params. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetProjectionParams"> +osSetProjectionParams(key prim. integer projection, key texture, float fov, float focus, float amb) +Set projection paramaters for light sources. +(OpenSim only.) + </string> + <string name="LSLTipText_osUnixTimeToTimestamp"> +string osUnixTimeToTimestamp(integer unixtime) +Converts unixtime to an llGetTimeStamp() formated string. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetPenColor"> +osSetPenColor(string drawList, string color) +Sets the pen color that is to be used when drawing dynamic textures. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetSunParam"> +float osGetSunParam(string param) +Returns current float values for param, where param = day_length, year_length, day_night_offset, update_interval. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetSunParam"> +osSetSunParam(string param, float value) +Sets region's sun parameters, where param = day_length, year_length, day_night_offset, update_interval. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetParcelDetails"> +osSetParcelDetails(vector pos, list rules) +Set parcel details. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetTerrainHeight"> +float osGetTerrainHeight(integer x, integer y) +Returns current terrain height at the given coordinates. +(OpenSim only.) + </string> + <string name="LSLTipText_osSetTerrainHeight"> +osSetTerrainHeight(integer x, integer y, float val) +Sets terrain height at the given coordinates. Use osTerrainFlush() afterwards. +(OpenSim only.) + </string> + <string name="LSLTipText_osGetAvatarList"> +list osGetAvatarList() +Returns a strided list of the UUID, position, and name of each avatar in the region, except the owner. +(OpenSim only.) + </string> + <string name="LSLTipText_osTeleportOwner"> +osTeleportOwner(integer regionX, integer regionY, vector position, vector lookat) + or +osTeleportOwner(string regionName, vector position, vector lookat) + or +osTeleportOwner(vector position, vector lookat) +Teleports the owner of the object that holds the script to a specified location in the region, the grid, or the hypergrid. See documentation for details. +(OpenSim only.) + </string> + + <!-- LightShare functions --> + <string name="LSLTipText_cmSetWindlightScene"> +integer cmSetWindlightScene(list rules) +Set the current WindLight scene. Estate managers and owners only. +(Reguires LightShare) + </string> + <string name="LSLTipText_cmSetWindlightSceneTargeted"> +integer cmSetWindlightSceneTargeted(list rules, key target) +Set the current WindLight scene directed at a specific avatar. Estate managers and owners only. +(Reguires LightShare) + </string> + <string name="LSLTipText_cmGetWindlightScene"> +list cmGetWindlightScene(list rules) +Get the current WindLight settings. +(Reguires LightShare) + </string> + <!-- LightShare functions - alternate versions --> + <!-- don't ask me why they renamed 'em, but we need to include both versions - - MC --> + <string name="LSLTipText_lsSetWindlightScene"> +integer lsSetWindlightScene(list rules) +Set the current WindLight scene. Estate managers and owners only. +(Reguires LightShare) + </string> + <string name="LSLTipText_lsSetWindlightSceneTargeted"> +integer lsSetWindlightSceneTargeted(list rules, key target) +Set the current WindLight scene directed at a specific avatar. Estate managers and owners only. +(Reguires LightShare) + </string> + <string name="LSLTipText_lsGetWindlightScene"> +list lsGetWindlightScene(list rules) +Get the current WindLight settings. +(Reguires LightShare) + </string> </strings> - From 06615a580eb435a3e48d0a46dd20805f1c6fdeac Mon Sep 17 00:00:00 2001 From: Siana Gearz <siana.sg@live.de> Date: Thu, 11 Aug 2011 00:51:09 +0200 Subject: [PATCH 17/18] Silly kitty me -.- --- indra/newview/lltexturefetch.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index da4e97655..d5e094b0f 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1274,9 +1274,9 @@ bool LLTextureFetchWorker::doWork(S32 param) //1, not openning too many file descriptors at the same time; //2, control the traffic of http so udp gets bandwidth. // - static const LLCachedControl<S32> max_http_requests("HTTPMaxRequests", 32); - static const LLCachedControl<S32> min_http_requests("HTTPMinRequests", 2); - if((mFetcher->getNumHTTPRequests() > max_http_requests) || + static const LLCachedControl<U32> max_http_requests("HTTPMaxRequests", 32); + static const LLCachedControl<U32> min_http_requests("HTTPMinRequests", 2); + if(((U32)mFetcher->getNumHTTPRequests() > max_http_requests) || ((mFetcher->getTextureBandwidth() > mFetcher->mMaxBandwidth) && ((U32)mFetcher->getNumHTTPRequests() > min_http_requests)) || !sgConnectionThrottle()) From c6e0c2f323b02f18e86f8d8bf1f152b52f90c6d4 Mon Sep 17 00:00:00 2001 From: Siana Gearz <siana.sg@live.de> Date: Wed, 3 Aug 2011 17:36:21 +0200 Subject: [PATCH 18/18] This should fix the settings --- indra/newview/app_settings/settings_files.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/settings_files.xml b/indra/newview/app_settings/settings_files.xml index 6e52cfa24..ac304f759 100644 --- a/indra/newview/app_settings/settings_files.xml +++ b/indra/newview/app_settings/settings_files.xml @@ -81,7 +81,7 @@ <key>PerAccount</key> <map> <key>Name</key> - <string>settings_sg_per_account.xml</string> + <string>settings_per_account.xml</string> </map> </map> </map>