From da3002bd0c25cfe922db1e40e46e48de9201501f Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <gavriliuk@gmail.com> Date: Sun, 12 Feb 2023 13:37:08 +0100 Subject: SL-18964 Move creating of LLViewerFetchedTexture::sSmokeImagep to LLDrawPoolAlpha::renderDebugAlpha() --- indra/newview/lldrawpoolalpha.cpp | 7 +++++++ indra/newview/llviewertexture.cpp | 4 ++++ 2 files changed, 11 insertions(+) (limited to 'indra') diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 6c1abb24c9..d4797321bb 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -280,6 +280,13 @@ void LLDrawPoolAlpha::renderDebugAlpha() { gHighlightProgram.bind(); gGL.diffuseColor4f(1, 0, 0, 1); + + // SL-18964 : The creating of this texture was moved here from LLViewerTextureManager::init() to make the texture transparent before adding to cache + if (!LLViewerFetchedTexture::sSmokeImagep) + { + LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); + LLViewerFetchedTexture::sSmokeImagep->setNoDelete(); + } LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f * 1024.f); gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sSmokeImagep); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index e3ac56d0d3..0d82aced23 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -402,8 +402,12 @@ void LLViewerTextureManager::init() LLViewerFetchedTexture::sDefaultImagep->dontDiscard(); LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER); +#if 0 + // When called first time after clearing cache this call creates (and adds to cache) an opaque texture instead of transparent + // SL-18964 : The creating of this texture was moved to LLDrawPoolAlpha::renderDebugAlpha() LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); LLViewerFetchedTexture::sSmokeImagep->setNoDelete(); +#endif image_raw = new LLImageRaw(32,32,3); data = image_raw->getData(); -- cgit v1.2.3 From 23a781317a12e7e46124a05efd1a6849a39438b3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Tue, 14 Feb 2023 02:45:58 +0200 Subject: SL-19196 Nearby chat bar moves down every time it gains focus --- indra/newview/llfloaterimnearbychat.cpp | 2 ++ indra/newview/llfloaterimsessiontab.cpp | 6 ++++++ indra/newview/llfloaterimsessiontab.h | 1 + 3 files changed, 9 insertions(+) (limited to 'indra') diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index f1807f1c5b..0d2c6d8e4c 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -108,6 +108,8 @@ LLFloaterIMNearbyChat::LLFloaterIMNearbyChat(const LLSD& llsd) mEnableCallbackRegistrar.add("Avatar.EnableGearItem", boost::bind(&cb_do_nothing)); mCommitCallbackRegistrar.add("Avatar.GearDoToSelected", boost::bind(&cb_do_nothing)); mEnableCallbackRegistrar.add("Avatar.CheckGearItem", boost::bind(&cb_do_nothing)); + + mMinFloaterHeight = EXPANDED_MIN_HEIGHT; } //static diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 78271369d2..af4e7f5aff 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -92,6 +92,8 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2)); mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2)); mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&cb_group_do_nothing)); + + mMinFloaterHeight = getMinHeight(); } LLFloaterIMSessionTab::~LLFloaterIMSessionTab() @@ -934,10 +936,13 @@ void LLFloaterIMSessionTab::reshapeFloater(bool collapse) S32 height = mContentPanel->getRect().getHeight() + mToolbarPanel->getRect().getHeight() + mChatLayoutPanel->getRect().getHeight() - mChatLayoutPanelHeight + 2; floater_rect.mTop -= height; + + setResizeLimits(getMinWidth(), floater_rect.getHeight()); } else { floater_rect.mTop = floater_rect.mBottom + mFloaterHeight; + setResizeLimits(getMinWidth(), mMinFloaterHeight); } enableResizeCtrls(true, true, !collapse); @@ -962,6 +967,7 @@ void LLFloaterIMSessionTab::restoreFloater() setShape(floater_rect, true); mBodyStack->updateLayout(); mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon")); + setResizeLimits(getMinWidth(), mMinFloaterHeight); setMessagePaneExpanded(true); saveCollapsedState(); mInputEditor->enableSingleLineMode(false); diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 9f00917647..d478922617 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -152,6 +152,7 @@ protected: bool mMessagePaneExpanded; bool mIsParticipantListExpanded; + S32 mMinFloaterHeight; LLIMModel::LLIMSession* mSession; -- cgit v1.2.3 From 53c33ebf993a4c0424bd5ae8f5e9c42b528dc5e5 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <gavriliuk@gmail.com> Date: Thu, 16 Feb 2023 02:11:46 +0100 Subject: SL-18246 Highlight 100% transparent faces for scripted objects --- indra/newview/llvovolume.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2e7ccc8334..108f5cd1d3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5850,15 +5850,18 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { - if (te->getColor().mV[3] > 0.f || te->getGlow() > 0.f) - { //only treat as alpha in the pipeline if < 100% transparent - drawablep->setState(LLDrawable::HAS_ALPHA); - add_face(sAlphaFaces, alpha_count, facep); - } - else if (LLDrawPoolAlpha::sShowDebugAlpha) - { - add_face(sAlphaFaces, alpha_count, facep); - } + if (te->getColor().mV[3] > 0.f || te->getGlow() > 0.f) + { //only treat as alpha in the pipeline if < 100% transparent + drawablep->setState(LLDrawable::HAS_ALPHA); + add_face(sAlphaFaces, alpha_count, facep); + } + else if (LLDrawPoolAlpha::sShowDebugAlpha || + gPipeline.sRenderHighlight && + (LLPipeline::getRenderScriptedBeacons() || LLPipeline::getRenderScriptedTouchBeacons()) && + drawablep->getVObj() && drawablep->getVObj()->flagScripted()) + { //draw the transparent face for debugging purposes using a custom texture + add_face(sAlphaFaces, alpha_count, facep); + } } } else -- cgit v1.2.3 From fe21f3fdf1e98eb2393449963f6bfd97b1885d44 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko <maximnproductengine@lindenlab.com> Date: Thu, 23 Feb 2023 11:58:17 +0200 Subject: SL-19252 Remove "#ifdef _CORY_TESTING" code --- indra/newview/llfilepicker.cpp | 34 ---------------------------------- indra/newview/llfilepicker.h | 6 ------ indra/newview/llviewermenu.cpp | 4 ---- indra/newview/llviewermenufile.cpp | 7 ------- indra/newview/llvovolume.cpp | 4 ++-- 5 files changed, 2 insertions(+), 53 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index e3a695fc79..7379ac0da4 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -55,9 +55,6 @@ LLFilePicker LLFilePicker::sInstance; #define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0" #define ANIM_FILTER L"Animations (*.bvh; *.anim)\0*.bvh;*.anim\0" #define COLLADA_FILTER L"Scene (*.dae)\0*.dae\0" -#ifdef _CORY_TESTING -#define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0" -#endif #define XML_FILTER L"XML files (*.xml)\0*.xml\0" #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" @@ -197,12 +194,6 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter) mOFN.lpstrFilter = COLLADA_FILTER \ L"\0"; break; -#ifdef _CORY_TESTING - case FFLOAD_GEOMETRY: - mOFN.lpstrFilter = GEOMETRY_FILTER \ - L"\0"; - break; -#endif case FFLOAD_XML: mOFN.lpstrFilter = XML_FILTER \ L"\0"; @@ -480,18 +471,6 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, L"XAF Anim File (*.xaf)\0*.xaf\0" \ L"\0"; break; -#ifdef _CORY_TESTING - case FFSAVE_GEOMETRY: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"slg"; - mOFN.lpstrFilter = - L"SLG SL Geometry File (*.slg)\0*.slg\0" \ - L"\0"; - break; -#endif case FFSAVE_XML: if (filename.empty()) { @@ -624,11 +603,6 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF case FFLOAD_COLLADA: allowedv->push_back("dae"); break; -#ifdef _CORY_TESTING - case FFLOAD_GEOMETRY: - allowedv->push_back("slg"); - break; -#endif case FFLOAD_XML: allowedv->push_back("xml"); break; @@ -727,14 +701,6 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena creator = "\?\?\?\?"; extension = "xaf"; break; - -#ifdef _CORY_TESTING - case FFSAVE_GEOMETRY: - type = "\?\?\?\?"; - creator = "\?\?\?\?"; - extension = "slg"; - break; -#endif case FFSAVE_XML: type = "\?\?\?\?"; diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 73baeca1c0..8f2274024c 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -77,9 +77,6 @@ public: FFLOAD_WAV = 2, FFLOAD_IMAGE = 3, FFLOAD_ANIM = 4, -#ifdef _CORY_TESTING - FFLOAD_GEOMETRY = 5, -#endif FFLOAD_XML = 6, FFLOAD_SLOBJECT = 7, FFLOAD_RAW = 8, @@ -99,9 +96,6 @@ public: FFSAVE_BMP = 5, FFSAVE_AVI = 6, FFSAVE_ANIM = 7, -#ifdef _CORY_TESTING - FFSAVE_GEOMETRY = 8, -#endif FFSAVE_XML = 9, FFSAVE_COLLADA = 10, FFSAVE_RAW = 11, diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index a0223a5dbb..8177353083 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -276,10 +276,6 @@ void handle_object_owner_permissive(void*); void handle_object_lock(void*); void handle_object_asset_ids(void*); void force_take_copy(void*); -#ifdef _CORY_TESTING -void force_export_copy(void*); -void force_import_geometry(void*); -#endif void handle_force_parcel_owner_to_me(void*); void handle_force_parcel_to_content(void*); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index fdf1d04c09..f9ec1115a6 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -277,9 +277,6 @@ void LLMediaFilePicker::notify(const std::vector<std::string>& filenames) static std::string SOUND_EXTENSIONS = "wav"; static std::string IMAGE_EXTENSIONS = "tga bmp jpg jpeg png"; static std::string ANIM_EXTENSIONS = "bvh anim"; -#ifdef _CORY_TESTING -static std::string GEOMETRY_EXTENSIONS = "slg"; -#endif static std::string XML_EXTENSIONS = "xml"; static std::string SLOBJECT_EXTENSIONS = "slobject"; #endif @@ -301,10 +298,6 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter) return SLOBJECT_EXTENSIONS; case LLFilePicker::FFLOAD_MODEL: return MODEL_EXTENSIONS; -#ifdef _CORY_TESTING - case LLFilePicker::FFLOAD_GEOMETRY: - return GEOMETRY_EXTENSIONS; -#endif case LLFilePicker::FFLOAD_XML: return XML_EXTENSIONS; case LLFilePicker::FFLOAD_ALL: diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 108f5cd1d3..b910c4f93c 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5856,9 +5856,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) add_face(sAlphaFaces, alpha_count, facep); } else if (LLDrawPoolAlpha::sShowDebugAlpha || - gPipeline.sRenderHighlight && + (gPipeline.sRenderHighlight && (LLPipeline::getRenderScriptedBeacons() || LLPipeline::getRenderScriptedTouchBeacons()) && - drawablep->getVObj() && drawablep->getVObj()->flagScripted()) + drawablep->getVObj() && drawablep->getVObj()->flagScripted())) { //draw the transparent face for debugging purposes using a custom texture add_face(sAlphaFaces, alpha_count, facep); } -- cgit v1.2.3 From a6ea3fa741c90b4fe88550085f9a6b52d71447fd Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <gavriliuk@gmail.com> Date: Mon, 27 Feb 2023 08:15:29 +0100 Subject: SL-18882: Show diffuse non-alpha textures opaque on editing --- indra/llprimitive/llmaterial.cpp | 18 +++++++++--------- indra/llprimitive/llmaterial.h | 2 +- indra/newview/llvovolume.cpp | 7 ++++--- 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'indra') diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index a219ac1450..fa22145972 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -426,18 +426,18 @@ bool LLMaterial::operator != (const LLMaterial& rhs) const } -U32 LLMaterial::getShaderMask(U32 alpha_mode) +U32 LLMaterial::getShaderMask(U32 alpha_mode, BOOL is_alpha) { //NEVER incorporate this value into the message system -- this function will vary depending on viewer implementation - U32 ret = 0; - //two least significant bits are "diffuse alpha mode" - if (alpha_mode != DIFFUSE_ALPHA_MODE_DEFAULT) + //two least significant bits are "diffuse alpha mode" + U32 ret = alpha_mode; + if (ret == DIFFUSE_ALPHA_MODE_DEFAULT) { - ret = alpha_mode; - } - else - { - ret = getDiffuseAlphaMode(); + ret = getDiffuseAlphaMode(); + if (ret == DIFFUSE_ALPHA_MODE_BLEND && !is_alpha) + { + ret = DIFFUSE_ALPHA_MODE_NONE; + } } llassert(ret < SHADER_COUNT); diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index d58b7ee812..d92ef1dfba 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -126,7 +126,7 @@ public: bool operator == (const LLMaterial& rhs) const; bool operator != (const LLMaterial& rhs) const; - U32 getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT); + U32 getShaderMask(U32 alpha_mode, BOOL is_alpha); protected: LLUUID mNormalID; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b910c4f93c..086e751965 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5295,13 +5295,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (mat) { + BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (facep->getTextureEntry()->getColor().mV[3] < 0.999f) ? TRUE : FALSE; if (type == LLRenderPass::PASS_ALPHA) { - shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND); + shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND, is_alpha); } else { - shader_mask = mat->getShaderMask(); + shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT, is_alpha); } } @@ -6676,7 +6677,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace LLRenderPass::PASS_NORMSPEC_EMISSIVE, }; - U32 mask = mat->getShaderMask(); + U32 mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT, is_alpha); llassert(mask < sizeof(pass)/sizeof(U32)); -- cgit v1.2.3 From 0e837fbaad136722fbad4b59e1402df2af8e4ea4 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <gavriliuk@gmail.com> Date: Mon, 27 Feb 2023 21:46:54 +0100 Subject: Fix formatting in indra/newview/llpanelface.* files --- indra/newview/llpanelface.cpp | 131 +++-- indra/newview/llpanelface.h | 1129 ++++++++++++++++++++--------------------- 2 files changed, 627 insertions(+), 633 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 178aba11a3..cbb87f63bb 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -831,7 +831,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) { //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible) LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - if( objectp + if (objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify()) { @@ -854,7 +854,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type"); - if(radio_mat_type) + if (radio_mat_type) { if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE) { @@ -871,10 +871,10 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings")); updateVisibility(); - bool identical = true; // true because it is anded below - bool identical_diffuse = false; - bool identical_norm = false; - bool identical_spec = false; + bool identical = true; // true because it is anded below + bool identical_diffuse = false; + bool identical_norm = false; + bool identical_spec = false; LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control"); LLTextureCtrl* shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); @@ -888,12 +888,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) { getChildView("color label")->setEnabled(editable); } - LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch"); + LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch"); - LLColor4 color = LLColor4::white; - bool identical_color = false; + LLColor4 color = LLColor4::white; + bool identical_color = false; - if(color_swatch) + if (color_swatch) { LLSelectedTE::getColor(color, identical_color); LLColor4 prev_color = color_swatch->get(); @@ -927,7 +927,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess"); if (combobox_shininess) - { + { combobox_shininess->selectNthItem((S32)shiny); } @@ -947,8 +947,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical_spec); LLColorSwatchCtrl* mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch"); - if(mShinyColorSwatch) - { + if (mShinyColorSwatch) + { mShinyColorSwatch->setValid(editable); mShinyColorSwatch->setEnabled( editable ); mShinyColorSwatch->setCanApplyImmediately( editable ); @@ -956,7 +956,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) U8 bumpy = 0; // Bumpy - { + { bool identical_bumpy = false; LLSelectedTE::getBumpmap(bumpy,identical_bumpy); @@ -966,18 +966,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE; if (combobox_bumpiness) - { + { combobox_bumpiness->selectNthItem((S32)bumpy); - } + } else - { + { LL_WARNS() << "failed childGetSelectionInterface for 'combobox bumpiness'" << LL_ENDL; - } + } getChildView("combobox bumpiness")->setEnabled(editable); getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy); getChildView("label bumpiness")->setEnabled(editable); - } + } // Texture { @@ -991,25 +991,25 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bool identical_image_format = false; LLSelectedTE::getImageFormat(image_format, identical_image_format); - mIsAlpha = FALSE; - switch (image_format) - { - case GL_RGBA: - case GL_ALPHA: - { - mIsAlpha = TRUE; - } - break; - - case GL_RGB: break; - default: - { - LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; - } - break; + mIsAlpha = FALSE; + switch (image_format) + { + case GL_RGBA: + case GL_ALPHA: + { + mIsAlpha = TRUE; + } + break; + + case GL_RGB: break; + default: + { + LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; } + break; + } - if(LLViewerMedia::getInstance()->textureHasMedia(id)) + if (LLViewerMedia::getInstance()->textureHasMedia(id)) { getChildView("button align")->setEnabled(editable); } @@ -1046,7 +1046,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) updateAlphaControls(); if (texture_ctrl) - { + { if (identical_diffuse) { texture_ctrl->setTentative(FALSE); @@ -1060,8 +1060,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) texture_ctrl->setBakeTextureEnabled(TRUE); } else if (id.isNull()) - { - // None selected + { + // None selected texture_ctrl->setTentative(FALSE); texture_ctrl->setEnabled(FALSE); texture_ctrl->setImageAssetID(LLUUID::null); @@ -1071,10 +1071,10 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChildView("label maskcutoff")->setEnabled(FALSE); texture_ctrl->setBakeTextureEnabled(false); - } - else - { - // Tentative: multiple selected with different textures + } + else + { + // Tentative: multiple selected with different textures texture_ctrl->setTentative(TRUE); texture_ctrl->setEnabled(editable); texture_ctrl->setImageAssetID(id); @@ -1085,7 +1085,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) texture_ctrl->setBakeTextureEnabled(TRUE); } - } if (shinytexture_ctrl) @@ -1343,15 +1342,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1); } else - { + { LL_WARNS() << "failed childGetSelectionInterface for 'combobox texgen'" << LL_ENDL; - } + } getChildView("combobox texgen")->setEnabled(editable); getChild<LLUICtrl>("combobox texgen")->setTentative(!identical); getChildView("tex gen")->setEnabled(editable); - - } + } { U8 fullbright_flag = 0; @@ -1380,7 +1378,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen"); if (mComboTexGen) - { + { S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; BOOL enabled = editable && (index != 1); BOOL identical_repeats = true; @@ -1390,26 +1388,26 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type)); switch (material_type) - { + { default: case MATTYPE_DIFFUSE: - { + { enabled = editable && !id.isNull(); identical_repeats = identical_diff_repeats; repeats = repeats_diff; - } + } break; case MATTYPE_SPECULAR: - { + { enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull())); identical_repeats = identical_spec_repeats; repeats = repeats_spec; - } + } break; case MATTYPE_NORMAL: - { + { enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull())); identical_repeats = identical_norm_repeats; repeats = repeats_norm; @@ -1458,14 +1456,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) if (!mIsAlpha) { // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - } + } combobox_alphamode->selectNthItem(alpha_mode); - } - else - { + } + else + { LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL; - } + } getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff()); updateAlphaControls(); @@ -1477,15 +1475,15 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) texture_ctrl->setImageAssetID(material->getSpecularID()); if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE)) - { + { material->getSpecularOffset(offset_x,offset_y); material->getSpecularRepeat(repeat_x,repeat_y); if (identical_planar_texgen) - { + { repeat_x *= 2.0f; repeat_y *= 2.0f; - } + } rot = material->getSpecularRotation(); getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x); @@ -1497,7 +1495,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild<LLUICtrl>("environment")->setValue(material->getEnvironmentIntensity()); updateShinyControls(!material->getSpecularID().isNull(), true); - } + } // Assert desired colorswatch color to match material AFTER updateShinyControls // to avoid getting overwritten with the default on some UI state changes. @@ -1559,14 +1557,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) // Disable non-UICtrls LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control"); - if(texture_ctrl) + if (texture_ctrl) { texture_ctrl->setImageAssetID( LLUUID::null ); texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl. // texture_ctrl->setValid(FALSE); } LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); - if(mColorSwatch) + if (mColorSwatch) { mColorSwatch->setEnabled( FALSE ); mColorSwatch->setFallbackImage(LLUI::getUIImage("locked_image.j2c") ); @@ -1609,7 +1607,6 @@ void LLPanelFace::updateCopyTexButton() && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)); std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options"); mMenuClipboardTexture->setToolTip(tooltip); - } void LLPanelFace::refresh() diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 44bc442bbb..787eb0c51b 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -1,566 +1,563 @@ -/** - * @file llpanelface.h - * @brief Panel in the tools floater for editing face textures, colors, etc. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLPANELFACE_H -#define LL_LLPANELFACE_H - -#include "v4color.h" -#include "llpanel.h" -#include "llmaterial.h" -#include "llmaterialmgr.h" -#include "lltextureentry.h" -#include "llselectmgr.h" - -class LLButton; -class LLCheckBoxCtrl; -class LLColorSwatchCtrl; -class LLComboBox; -class LLInventoryItem; -class LLLineEditor; -class LLSpinCtrl; -class LLTextBox; -class LLTextureCtrl; -class LLUICtrl; -class LLViewerObject; -class LLFloater; -class LLMaterialID; -class LLMediaCtrl; -class LLMenuButton; - -// Represents an edit for use in replicating the op across one or more materials in the selection set. -// -// The apply function optionally performs the edit which it implements -// as a functor taking Data that calls member func MaterialFunc taking SetValueType -// on an instance of the LLMaterial class. -// -// boost who? -// -template< - typename DataType, - typename SetValueType, - void (LLMaterial::*MaterialEditFunc)(SetValueType data) > -class LLMaterialEditFunctor -{ -public: - LLMaterialEditFunctor(const DataType& data) : _data(data) {} - virtual ~LLMaterialEditFunctor() {} - virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); } - DataType _data; -}; - -template< - typename DataType, - DataType (LLMaterial::*MaterialGetFunc)() > -class LLMaterialGetFunctor -{ -public: - LLMaterialGetFunctor() {} - virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); } -}; - -template< - typename DataType, - DataType (LLTextureEntry::*TEGetFunc)() > -class LLTEGetFunctor -{ -public: - LLTEGetFunctor() {} - virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); } -}; - -class LLPanelFace : public LLPanel -{ -public: - virtual BOOL postBuild(); - LLPanelFace(); - virtual ~LLPanelFace(); - - void refresh(); - void refreshMedia(); - void unloadMedia(); - - /*virtual*/ void draw(); - - LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) - { - LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); - llassert_always(new_material); - - // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture - // - new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode()); - return new_material; - } - - LLRender::eTexIndex getTextureChannelToEdit(); - -protected: - void navigateToTitleMedia(const std::string url); - bool selectedMediaEditable(); - void clearMediaSettings(); - void updateMediaSettings(); - void updateMediaTitle(); - - void getState(); - - void sendTexture(); // applies and sends texture - void sendTextureInfo(); // applies and sends texture scale, offset, etc. - void sendColor(); // applies and sends color - void sendAlpha(); // applies and sends transparency - void sendBump(U32 bumpiness); // applies and sends bump map - void sendTexGen(); // applies and sends bump map - void sendShiny(U32 shininess); // applies and sends shininess - void sendFullbright(); // applies and sends full bright - void sendGlow(); - void sendMedia(); - void alignTestureLayer(); - - void updateCopyTexButton(); - - // this function is to return TRUE if the drag should succeed. - static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item); - - void onCommitTexture(const LLSD& data); - void onCancelTexture(const LLSD& data); - void onSelectTexture(const LLSD& data); - void onCommitSpecularTexture(const LLSD& data); - void onCancelSpecularTexture(const LLSD& data); - void onSelectSpecularTexture(const LLSD& data); - void onCommitNormalTexture(const LLSD& data); - void onCancelNormalTexture(const LLSD& data); - void onSelectNormalTexture(const LLSD& data); - void onCommitColor(const LLSD& data); - void onCommitShinyColor(const LLSD& data); - void onCommitAlpha(const LLSD& data); - void onCancelColor(const LLSD& data); - void onCancelShinyColor(const LLSD& data); - void onSelectColor(const LLSD& data); - void onSelectShinyColor(const LLSD& data); - - void onCloseTexturePicker(const LLSD& data); - - static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); - static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); - - // Make UI reflect state of currently selected material (refresh) - // and UI mode (e.g. editing normal map v diffuse map) - // - // @param force_set_values forces spinners to set value even if they are focused - void updateUI(bool force_set_values = false); - - // Convenience func to determine if all faces in selection have - // identical planar texgen settings during edits - // - bool isIdenticalPlanarTexgen(); - - // Callback funcs for individual controls - // - static void onCommitTextureInfo(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureScaleX(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureScaleY(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureRot(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureOffsetX(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureOffsetY(LLUICtrl* ctrl, void* userdata); - - static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata); - - static void syncRepeatX(LLPanelFace* self, F32 scaleU); - static void syncRepeatY(LLPanelFace* self, F32 scaleV); - static void syncOffsetX(LLPanelFace* self, F32 offsetU); - static void syncOffsetY(LLPanelFace* self, F32 offsetV); - static void syncMaterialRot(LLPanelFace* self, F32 rot, int te = -1); - - static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata); - - static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata); - - static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata); - static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata); - static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata); - static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata); - static void onCommitBump( LLUICtrl* ctrl, void* userdata); - static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); - static void onCommitShiny( LLUICtrl* ctrl, void* userdata); - static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); - static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); - static void onCommitGlow( LLUICtrl* ctrl, void *userdata); - static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); - static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); - static void onClickAutoFix(void*); - static void onAlignTexture(void*); - -public: // needs to be accessible to selection manager - void onCopyColor(); // records all selected faces - void onPasteColor(); // to specific face - void onPasteColor(LLViewerObject* objectp, S32 te); // to specific face - void onCopyTexture(); - void onPasteTexture(); - void onPasteTexture(LLViewerObject* objectp, S32 te); - -protected: - void menuDoToSelected(const LLSD& userdata); - bool menuEnableItem(const LLSD& userdata); - - static F32 valueGlow(LLViewerObject* object, S32 face); - - - -private: - - bool isAlpha() { return mIsAlpha; } - - // Convenience funcs to keep the visual flack to a minimum - // - LLUUID getCurrentNormalMap(); - LLUUID getCurrentSpecularMap(); - U32 getCurrentShininess(); - U32 getCurrentBumpiness(); - U8 getCurrentDiffuseAlphaMode(); - U8 getCurrentAlphaMaskCutoff(); - U8 getCurrentEnvIntensity(); - U8 getCurrentGlossiness(); - F32 getCurrentBumpyRot(); - F32 getCurrentBumpyScaleU(); - F32 getCurrentBumpyScaleV(); - F32 getCurrentBumpyOffsetU(); - F32 getCurrentBumpyOffsetV(); - F32 getCurrentShinyRot(); - F32 getCurrentShinyScaleU(); - F32 getCurrentShinyScaleV(); - F32 getCurrentShinyOffsetU(); - F32 getCurrentShinyOffsetV(); - - LLComboBox *mComboMatMedia; - LLMediaCtrl *mTitleMedia; - LLTextBox *mTitleMediaText; - - // Update visibility of controls to match current UI mode - // (e.g. materials vs media editing) - // - // Do NOT call updateUI from within this function. - // - void updateVisibility(); - - // Hey look everyone, a type-safe alternative to copy and paste! :) - // - - // Update material parameters by applying 'edit_func' to selected TEs - // - template< - typename DataType, - typename SetValueType, - void (LLMaterial::*MaterialEditFunc)(SetValueType data) > - static void edit(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID()) - { - LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data); - struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor - { - LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp, const LLUUID &only_for_object_id) : _panel(panel), _edit(editp), _only_for_object_id(only_for_object_id) {} - virtual ~LLSelectedTEEditMaterial() {}; - virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) - { - if (_edit && (_only_for_object_id.isNull() || _only_for_object_id == object->getID())) - { - LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material); - llassert_always(new_material); - - // Determine correct alpha mode for current diffuse texture - // (i.e. does it have an alpha channel that makes alpha mode useful) - // - // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329) - // need to get per-face answer to this question for sane alpha mode retention on updates. - // - bool is_alpha_face = object->isImageAlphaBlended(face); - - // need to keep this original answer for valid comparisons in logic below - // - U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - - U8 default_alpha_mode = original_default_alpha_mode; - - if (!current_material.isNull()) - { - default_alpha_mode = current_material->getDiffuseAlphaMode(); - } - - // Insure we don't inherit the default of blend by accident... - // this will be stomped by a legit request to change the alpha mode by the apply() below - // - new_material->setDiffuseAlphaMode(default_alpha_mode); - - // Do "It"! - // - _edit->apply(new_material); - - U32 new_alpha_mode = new_material->getDiffuseAlphaMode(); - LLUUID new_normal_map_id = new_material->getNormalID(); - LLUUID new_spec_map_id = new_material->getSpecularID(); - - if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face) - { - new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - } - - bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode); - bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); - - if (!is_need_material) - { - LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; - LLMaterialMgr::getInstance()->remove(object->getID(),face); - new_material = NULL; - } - else - { - LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL; - LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material); - } - - object->setTEMaterialParams(face, new_material); - return new_material; - } - return NULL; - } - LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit; - LLPanelFace *_panel; - const LLUUID & _only_for_object_id; - } editor(p, &edit, only_for_object_id); - LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te); - } - - template< - typename DataType, - typename ReturnType, - ReturnType (LLMaterial::* const MaterialGetFunc)() const > - static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) - { - DataType data_value; - struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType> - { - GetTEMaterialVal(DataType default_value) : _default(default_value) {} - virtual ~GetTEMaterialVal() {} - - DataType get(LLViewerObject* object, S32 face) - { - DataType ret = _default; - LLMaterialPtr material_ptr; - LLTextureEntry* tep = object ? object->getTE(face) : NULL; - if (tep) - { - material_ptr = tep->getMaterialParams(); - if (!material_ptr.isNull()) - { - ret = (material_ptr->*(MaterialGetFunc))(); - } - } - return ret; - } - DataType _default; - } GetFunc(default_value); - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance); - data_to_return = data_value; - } - - template< - typename DataType, - typename ReturnType, // some kids just have to different... - ReturnType (LLTextureEntry::* const TEGetFunc)() const > - static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) - { - DataType data_value; - struct GetTEVal : public LLSelectedTEGetFunctor<DataType> - { - GetTEVal(DataType default_value) : _default(default_value) {} - virtual ~GetTEVal() {} - - DataType get(LLViewerObject* object, S32 face) { - LLTextureEntry* tep = object ? object->getTE(face) : NULL; - return tep ? ((tep->*(TEGetFunc))()) : _default; - } - DataType _default; - } GetTEValFunc(default_value); - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance ); - data_to_return = data_value; - } - - // Update vis and enabling of specific subsets of controls based on material params - // (e.g. hide the spec controls if no spec texture is applied) - // - void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false); - void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false); - void updateAlphaControls(); - - /* - * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object. - * If agent selects texture which is not allowed to be applied for the currently selected object, - * all controls of the floater texture picker which allow to apply the texture will be disabled. - */ - void onTextureSelectionChanged(LLInventoryItem* itemp); - - LLMenuButton* mMenuClipboardColor; - LLMenuButton* mMenuClipboardTexture; - - bool mIsAlpha; - - /* These variables interlock processing of materials updates sent to - * the sim. mUpdateInFlight is set to flag that an update has been - * sent to the sim and not acknowledged yet, and cleared when an - * update is received from the sim. mUpdatePending is set when - * there's an update in flight and another UI change has been made - * that needs to be sent as a materials update, and cleared when the - * update is sent. This prevents the sim from getting spammed with - * update messages when, for example, the user holds down the - * up-arrow on a spinner, and avoids running afoul of its throttle. - */ - bool mUpdateInFlight; - bool mUpdatePending; - - LLSD mClipboardParams; - - LLSD mMediaSettings; - bool mNeedMediaTitle; - -public: - #if defined(DEF_GET_MAT_STATE) - #undef DEF_GET_MAT_STATE - #endif - - #if defined(DEF_GET_TE_STATE) - #undef DEF_GET_TE_STATE - #endif - - #if defined(DEF_EDIT_MAT_STATE) - DEF_EDIT_MAT_STATE - #endif - - // Accessors for selected TE material state - // - #define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue,HasTolerance,Tolerance) \ - static void MaterialMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance) \ - { \ - getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance); \ - } - - // Mutators for selected TE material - // - #define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc) \ - static void MaterialMemberFunc(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID()) \ - { \ - edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p, data, te, only_for_object_id); \ - } - - // Accessors for selected TE state proper (legacy settings etc) - // - #define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue,HasTolerance,Tolerance) \ - static void TexEntryMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance) \ - { \ - getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance); \ - } - - class LLSelectedTEMaterial - { - public: - static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material); - static void getMaxSpecularRepeats(F32& repeats, bool& identical); - static void getMaxNormalRepeats(F32& repeats, bool& identical); - static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); - - DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null, false, LLUUID::null) - DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null, false, LLUUID::null) - DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f, true, 0.001f) - - DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f, true, 0.001f) - - DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode); - DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); - - DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX); - DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY); - DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX); - DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY); - DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation); - - DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation); - - DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity); - DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent); - - DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); - DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); - DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); - }; - - class LLSelectedTE - { - public: - - static void getFace(class LLFace*& face_to_return, bool& identical_face); - static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face); - static void getTexId(LLUUID& id, bool& identical); - static void getObjectScaleS(F32& scale_s, bool& identical); - static void getObjectScaleT(F32& scale_t, bool& identical); - static void getMaxDiffuseRepeats(F32& repeats, bool& identical); - - DEF_GET_TE_STATE(U8,U8,getBumpmap,0, false, 0) - DEF_GET_TE_STATE(U8,U8,getShiny,0, false, 0) - DEF_GET_TE_STATE(U8,U8,getFullbright,0, false, 0) - DEF_GET_TE_STATE(F32,F32,getRotation,0.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getGlow,0.0f, true, 0.001f) - DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT, false, LLTextureEntry::TEX_GEN_DEFAULT) - DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white, false, LLColor4::black); - }; -}; - -#endif - +/** + * @file llpanelface.h + * @brief Panel in the tools floater for editing face textures, colors, etc. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELFACE_H +#define LL_LLPANELFACE_H + +#include "v4color.h" +#include "llpanel.h" +#include "llmaterial.h" +#include "llmaterialmgr.h" +#include "lltextureentry.h" +#include "llselectmgr.h" + +class LLButton; +class LLCheckBoxCtrl; +class LLColorSwatchCtrl; +class LLComboBox; +class LLInventoryItem; +class LLLineEditor; +class LLSpinCtrl; +class LLTextBox; +class LLTextureCtrl; +class LLUICtrl; +class LLViewerObject; +class LLFloater; +class LLMaterialID; +class LLMediaCtrl; +class LLMenuButton; + +// Represents an edit for use in replicating the op across one or more materials in the selection set. +// +// The apply function optionally performs the edit which it implements +// as a functor taking Data that calls member func MaterialFunc taking SetValueType +// on an instance of the LLMaterial class. +// +// boost who? +// +template< + typename DataType, + typename SetValueType, + void (LLMaterial::*MaterialEditFunc)(SetValueType data) > +class LLMaterialEditFunctor +{ +public: + LLMaterialEditFunctor(const DataType& data) : _data(data) {} + virtual ~LLMaterialEditFunctor() {} + virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); } + DataType _data; +}; + +template< + typename DataType, + DataType (LLMaterial::*MaterialGetFunc)() > +class LLMaterialGetFunctor +{ +public: + LLMaterialGetFunctor() {} + virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); } +}; + +template< + typename DataType, + DataType (LLTextureEntry::*TEGetFunc)() > +class LLTEGetFunctor +{ +public: + LLTEGetFunctor() {} + virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); } +}; + +class LLPanelFace : public LLPanel +{ +public: + virtual BOOL postBuild(); + LLPanelFace(); + virtual ~LLPanelFace(); + + void refresh(); + void refreshMedia(); + void unloadMedia(); + + /*virtual*/ void draw(); + + LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) + { + LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); + llassert_always(new_material); + + // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture + // + new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode()); + return new_material; + } + + LLRender::eTexIndex getTextureChannelToEdit(); + +protected: + void navigateToTitleMedia(const std::string url); + bool selectedMediaEditable(); + void clearMediaSettings(); + void updateMediaSettings(); + void updateMediaTitle(); + + void getState(); + + void sendTexture(); // applies and sends texture + void sendTextureInfo(); // applies and sends texture scale, offset, etc. + void sendColor(); // applies and sends color + void sendAlpha(); // applies and sends transparency + void sendBump(U32 bumpiness); // applies and sends bump map + void sendTexGen(); // applies and sends bump map + void sendShiny(U32 shininess); // applies and sends shininess + void sendFullbright(); // applies and sends full bright + void sendGlow(); + void alignTestureLayer(); + + void updateCopyTexButton(); + + // this function is to return TRUE if the drag should succeed. + static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item); + + void onCommitTexture(const LLSD& data); + void onCancelTexture(const LLSD& data); + void onSelectTexture(const LLSD& data); + void onCommitSpecularTexture(const LLSD& data); + void onCancelSpecularTexture(const LLSD& data); + void onSelectSpecularTexture(const LLSD& data); + void onCommitNormalTexture(const LLSD& data); + void onCancelNormalTexture(const LLSD& data); + void onSelectNormalTexture(const LLSD& data); + void onCommitColor(const LLSD& data); + void onCommitShinyColor(const LLSD& data); + void onCommitAlpha(const LLSD& data); + void onCancelColor(const LLSD& data); + void onCancelShinyColor(const LLSD& data); + void onSelectColor(const LLSD& data); + void onSelectShinyColor(const LLSD& data); + + void onCloseTexturePicker(const LLSD& data); + + static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); + static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); + + // Make UI reflect state of currently selected material (refresh) + // and UI mode (e.g. editing normal map v diffuse map) + // + // @param force_set_values forces spinners to set value even if they are focused + void updateUI(bool force_set_values = false); + + // Convenience func to determine if all faces in selection have + // identical planar texgen settings during edits + // + bool isIdenticalPlanarTexgen(); + + // Callback funcs for individual controls + // + static void onCommitTextureInfo(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureScaleX(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureScaleY(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureRot(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureOffsetX(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureOffsetY(LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata); + + static void syncRepeatX(LLPanelFace* self, F32 scaleU); + static void syncRepeatY(LLPanelFace* self, F32 scaleV); + static void syncOffsetX(LLPanelFace* self, F32 offsetU); + static void syncOffsetY(LLPanelFace* self, F32 offsetV); + static void syncMaterialRot(LLPanelFace* self, F32 rot, int te = -1); + + static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata); + static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata); + static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata); + static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata); + static void onCommitBump( LLUICtrl* ctrl, void* userdata); + static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); + static void onCommitShiny( LLUICtrl* ctrl, void* userdata); + static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); + static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); + static void onCommitGlow( LLUICtrl* ctrl, void *userdata); + static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); + static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); + static void onClickAutoFix(void*); + static void onAlignTexture(void*); + +public: // needs to be accessible to selection manager + void onCopyColor(); // records all selected faces + void onPasteColor(); // to specific face + void onPasteColor(LLViewerObject* objectp, S32 te); // to specific face + void onCopyTexture(); + void onPasteTexture(); + void onPasteTexture(LLViewerObject* objectp, S32 te); + +protected: + void menuDoToSelected(const LLSD& userdata); + bool menuEnableItem(const LLSD& userdata); + + static F32 valueGlow(LLViewerObject* object, S32 face); + + + +private: + bool isAlpha() { return mIsAlpha; } + + // Convenience funcs to keep the visual flack to a minimum + // + LLUUID getCurrentNormalMap(); + LLUUID getCurrentSpecularMap(); + U32 getCurrentShininess(); + U32 getCurrentBumpiness(); + U8 getCurrentDiffuseAlphaMode(); + U8 getCurrentAlphaMaskCutoff(); + U8 getCurrentEnvIntensity(); + U8 getCurrentGlossiness(); + F32 getCurrentBumpyRot(); + F32 getCurrentBumpyScaleU(); + F32 getCurrentBumpyScaleV(); + F32 getCurrentBumpyOffsetU(); + F32 getCurrentBumpyOffsetV(); + F32 getCurrentShinyRot(); + F32 getCurrentShinyScaleU(); + F32 getCurrentShinyScaleV(); + F32 getCurrentShinyOffsetU(); + F32 getCurrentShinyOffsetV(); + + LLComboBox *mComboMatMedia; + LLMediaCtrl *mTitleMedia; + LLTextBox *mTitleMediaText; + + // Update visibility of controls to match current UI mode + // (e.g. materials vs media editing) + // + // Do NOT call updateUI from within this function. + // + void updateVisibility(); + + // Hey look everyone, a type-safe alternative to copy and paste! :) + // + + // Update material parameters by applying 'edit_func' to selected TEs + // + template< + typename DataType, + typename SetValueType, + void (LLMaterial::*MaterialEditFunc)(SetValueType data) > + static void edit(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID()) + { + LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data); + struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor + { + LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp, const LLUUID &only_for_object_id) : _panel(panel), _edit(editp), _only_for_object_id(only_for_object_id) {} + virtual ~LLSelectedTEEditMaterial() {}; + virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) + { + if (_edit && (_only_for_object_id.isNull() || _only_for_object_id == object->getID())) + { + LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material); + llassert_always(new_material); + + // Determine correct alpha mode for current diffuse texture + // (i.e. does it have an alpha channel that makes alpha mode useful) + // + // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329) + // need to get per-face answer to this question for sane alpha mode retention on updates. + // + bool is_alpha_face = object->isImageAlphaBlended(face); + + // need to keep this original answer for valid comparisons in logic below + // + U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + U8 default_alpha_mode = original_default_alpha_mode; + + if (!current_material.isNull()) + { + default_alpha_mode = current_material->getDiffuseAlphaMode(); + } + + // Insure we don't inherit the default of blend by accident... + // this will be stomped by a legit request to change the alpha mode by the apply() below + // + new_material->setDiffuseAlphaMode(default_alpha_mode); + + // Do "It"! + // + _edit->apply(new_material); + + U32 new_alpha_mode = new_material->getDiffuseAlphaMode(); + LLUUID new_normal_map_id = new_material->getNormalID(); + LLUUID new_spec_map_id = new_material->getSpecularID(); + + if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face) + { + new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); + } + + bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode); + bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); + + if (!is_need_material) + { + LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; + LLMaterialMgr::getInstance()->remove(object->getID(),face); + new_material = NULL; + } + else + { + LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL; + LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material); + } + + object->setTEMaterialParams(face, new_material); + return new_material; + } + return NULL; + } + LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit; + LLPanelFace *_panel; + const LLUUID & _only_for_object_id; + } editor(p, &edit, only_for_object_id); + LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te); + } + + template< + typename DataType, + typename ReturnType, + ReturnType (LLMaterial::* const MaterialGetFunc)() const > + static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) + { + DataType data_value; + struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType> + { + GetTEMaterialVal(DataType default_value) : _default(default_value) {} + virtual ~GetTEMaterialVal() {} + + DataType get(LLViewerObject* object, S32 face) + { + DataType ret = _default; + LLMaterialPtr material_ptr; + LLTextureEntry* tep = object ? object->getTE(face) : NULL; + if (tep) + { + material_ptr = tep->getMaterialParams(); + if (!material_ptr.isNull()) + { + ret = (material_ptr->*(MaterialGetFunc))(); + } + } + return ret; + } + DataType _default; + } GetFunc(default_value); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance); + data_to_return = data_value; + } + + template< + typename DataType, + typename ReturnType, // some kids just have to different... + ReturnType (LLTextureEntry::* const TEGetFunc)() const > + static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) + { + DataType data_value; + struct GetTEVal : public LLSelectedTEGetFunctor<DataType> + { + GetTEVal(DataType default_value) : _default(default_value) {} + virtual ~GetTEVal() {} + + DataType get(LLViewerObject* object, S32 face) { + LLTextureEntry* tep = object ? object->getTE(face) : NULL; + return tep ? ((tep->*(TEGetFunc))()) : _default; + } + DataType _default; + } GetTEValFunc(default_value); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance ); + data_to_return = data_value; + } + + // Update vis and enabling of specific subsets of controls based on material params + // (e.g. hide the spec controls if no spec texture is applied) + // + void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false); + void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false); + void updateAlphaControls(); + + /* + * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object. + * If agent selects texture which is not allowed to be applied for the currently selected object, + * all controls of the floater texture picker which allow to apply the texture will be disabled. + */ + void onTextureSelectionChanged(LLInventoryItem* itemp); + + LLMenuButton* mMenuClipboardColor; + LLMenuButton* mMenuClipboardTexture; + + bool mIsAlpha; + + /* These variables interlock processing of materials updates sent to + * the sim. mUpdateInFlight is set to flag that an update has been + * sent to the sim and not acknowledged yet, and cleared when an + * update is received from the sim. mUpdatePending is set when + * there's an update in flight and another UI change has been made + * that needs to be sent as a materials update, and cleared when the + * update is sent. This prevents the sim from getting spammed with + * update messages when, for example, the user holds down the + * up-arrow on a spinner, and avoids running afoul of its throttle. + */ + bool mUpdateInFlight; + bool mUpdatePending; + + LLSD mClipboardParams; + + LLSD mMediaSettings; + bool mNeedMediaTitle; + +public: + #if defined(DEF_GET_MAT_STATE) + #undef DEF_GET_MAT_STATE + #endif + + #if defined(DEF_GET_TE_STATE) + #undef DEF_GET_TE_STATE + #endif + + #if defined(DEF_EDIT_MAT_STATE) + DEF_EDIT_MAT_STATE + #endif + + // Accessors for selected TE material state + // + #define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue,HasTolerance,Tolerance) \ + static void MaterialMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance) \ + { \ + getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance); \ + } + + // Mutators for selected TE material + // + #define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc) \ + static void MaterialMemberFunc(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID()) \ + { \ + edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p, data, te, only_for_object_id); \ + } + + // Accessors for selected TE state proper (legacy settings etc) + // + #define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue,HasTolerance,Tolerance) \ + static void TexEntryMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance) \ + { \ + getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance); \ + } + + class LLSelectedTEMaterial + { + public: + static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material); + static void getMaxSpecularRepeats(F32& repeats, bool& identical); + static void getMaxNormalRepeats(F32& repeats, bool& identical); + static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); + + DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null, false, LLUUID::null) + DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null, false, LLUUID::null) + DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f, true, 0.001f) + + DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f, true, 0.001f) + + DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode); + DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); + + DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX); + DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation); + + DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation); + + DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity); + DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent); + + DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); + DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); + DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); + }; + + class LLSelectedTE + { + public: + static void getFace(class LLFace*& face_to_return, bool& identical_face); + static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face); + static void getTexId(LLUUID& id, bool& identical); + static void getObjectScaleS(F32& scale_s, bool& identical); + static void getObjectScaleT(F32& scale_t, bool& identical); + static void getMaxDiffuseRepeats(F32& repeats, bool& identical); + + DEF_GET_TE_STATE(U8,U8,getBumpmap,0, false, 0) + DEF_GET_TE_STATE(U8,U8,getShiny,0, false, 0) + DEF_GET_TE_STATE(U8,U8,getFullbright,0, false, 0) + DEF_GET_TE_STATE(F32,F32,getRotation,0.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getGlow,0.0f, true, 0.001f) + DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT, false, LLTextureEntry::TEX_GEN_DEFAULT) + DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white, false, LLColor4::black); + }; +}; + +#endif + -- cgit v1.2.3 From 3daccc5d2344404af1b3501c35b7cff96468602f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Thu, 23 Feb 2023 22:43:53 +0200 Subject: SL-19209 WIP Switch MS Bing to MS Azure --- indra/newview/lltranslate.cpp | 117 +++++++++++++++++++++++++++++++----------- 1 file changed, 88 insertions(+), 29 deletions(-) (limited to 'indra') diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index a2c696c762..3e6bf4fe82 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -41,7 +41,7 @@ #include "llurlregistry.h" -static const std::string BING_NOTRANSLATE_OPENING_TAG("<div class=\"notranslate\">"); +static const std::string BING_NOTRANSLATE_OPENING_TAG("<div translate=\"no\">"); static const std::string BING_NOTRANSLATE_CLOSING_TAG("</div>"); /** @@ -113,6 +113,14 @@ public: void verifyKeyCoro(LLTranslate::EService service, std::string key, LLTranslate::KeyVerificationResult_fn fnc); void translateMessageCoro(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure); + + virtual void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const = 0; + virtual LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string & url, + const std::string & msg) const = 0; }; void LLTranslationAPIHandler::translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure) @@ -184,8 +192,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s LLVersionInfo::instance().getPatch(), LLVersionInfo::instance().getBuild()); - httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN); - httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); + initHttpHeader(httpHeaders, user_agent); httpOpts->setSSLVerifyPeer(false); std::string url = this->getTranslateURL(fromTo.first, fromTo.second, msg); @@ -194,8 +201,10 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s LL_INFOS("Translate") << "No translation URL" << LL_ENDL; return; } + LL_INFOS() << "Message: " << msg << LL_ENDL; + LL_INFOS() << "Requesting: " << url << LL_ENDL; - LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts, httpHeaders); + LLSD result = sendMessageAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url, msg); if (LLApp::isQuitting()) { @@ -280,6 +289,14 @@ public: /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc); + void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const override; + LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string & url, + const std::string & msg) const override; + private: static void parseErrorResponse( const Json::Value& root, @@ -417,31 +434,55 @@ void LLGoogleTranslationHandler::verifyKey(const std::string &key, LLTranslate:: this, LLTranslate::SERVICE_GOOGLE, key, fnc)); } +/*virtual*/ +void LLGoogleTranslationHandler::initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const +{ + headers->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN); + headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); +} + +LLSD LLGoogleTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string & url, + const std::string & msg) const +{ + return adapter->getRawAndSuspend(request, url, options, headers); +} //========================================================================= /// Microsoft Translator v2 API handler. -class LLBingTranslationHandler : public LLTranslationAPIHandler +class LLAzureTranslationHandler : public LLTranslationAPIHandler { - LOG_CLASS(LLBingTranslationHandler); + LOG_CLASS(LLAzureTranslationHandler); public: - /*virtual*/ std::string getTranslateURL( + std::string getTranslateURL( const std::string &from_lang, const std::string &to_lang, - const std::string &text) const; - /*virtual*/ std::string getKeyVerificationURL( - const std::string &key) const; - /*virtual*/ bool parseResponse( + const std::string &text) const override; + std::string getKeyVerificationURL( + const std::string &key) const override; + bool parseResponse( int& status, const std::string& body, std::string& translation, std::string& detected_lang, - std::string& err_msg) const; - /*virtual*/ bool isConfigured() const; + std::string& err_msg) const override; + bool isConfigured() const override; - /*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_BING; } + LLTranslate::EService getCurrentService() override { return LLTranslate::EService::SERVICE_BING; } - /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc); + void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) override; + + void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const override; + LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string & url, + const std::string & msg) const override; private: static std::string getAPIKey(); static std::string getAPILanguageCode(const std::string& lang); @@ -450,23 +491,20 @@ private: //------------------------------------------------------------------------- // virtual -std::string LLBingTranslationHandler::getTranslateURL( +std::string LLAzureTranslationHandler::getTranslateURL( const std::string &from_lang, const std::string &to_lang, const std::string &text) const { - std::string url = std::string("http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=") - + getAPIKey() + "&text=" + LLURI::escape(text) + "&to=" + getAPILanguageCode(to_lang); - if (!from_lang.empty()) - { - url += "&from=" + getAPILanguageCode(from_lang); - } + // Global service. Alternatively regional services exist. + std::string url = std::string("https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=") + + getAPILanguageCode(to_lang) + "&Subscription-Key=" + getAPIKey(); return url; } // virtual -std::string LLBingTranslationHandler::getKeyVerificationURL( +std::string LLAzureTranslationHandler::getKeyVerificationURL( const std::string& key) const { std::string url = std::string("http://api.microsofttranslator.com/v2/Http.svc/GetLanguagesForTranslate?appId=") @@ -475,7 +513,7 @@ std::string LLBingTranslationHandler::getKeyVerificationURL( } // virtual -bool LLBingTranslationHandler::parseResponse( +bool LLAzureTranslationHandler::parseResponse( int& status, const std::string& body, std::string& translation, @@ -521,30 +559,51 @@ bool LLBingTranslationHandler::parseResponse( } // virtual -bool LLBingTranslationHandler::isConfigured() const +bool LLAzureTranslationHandler::isConfigured() const { return !getAPIKey().empty(); } // static -std::string LLBingTranslationHandler::getAPIKey() +std::string LLAzureTranslationHandler::getAPIKey() { return gSavedSettings.getString("BingTranslateAPIKey"); } // static -std::string LLBingTranslationHandler::getAPILanguageCode(const std::string& lang) +std::string LLAzureTranslationHandler::getAPILanguageCode(const std::string& lang) { return lang == "zh" ? "zh-CHT" : lang; // treat Chinese as Traditional Chinese } /*virtual*/ -void LLBingTranslationHandler::verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) +void LLAzureTranslationHandler::verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) { LLCoros::instance().launch("Bing /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro, this, LLTranslate::SERVICE_BING, key, fnc)); } +/*virtual*/ +void LLAzureTranslationHandler::initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const +{ + headers->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_JSON); + // Token based autorization exists + //headers->append("Ocp-Apim-Subscription-Key", getAPIKey()); + headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); +} + +LLSD LLAzureTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string & url, + const std::string & msg) const +{ + LLSD body; + body["text"] = "Hello, what is your name?"; + return adapter->postJsonAndSuspend(request, url, body, headers); +} + //========================================================================= /*static*/ void LLTranslate::translateMessage(const std::string &from_lang, const std::string &to_lang, @@ -652,7 +711,7 @@ LLTranslationAPIHandler& LLTranslate::getPreferredHandler() LLTranslationAPIHandler& LLTranslate::getHandler(EService service) { static LLGoogleTranslationHandler google; - static LLBingTranslationHandler bing; + static LLAzureTranslationHandler bing; if (service == SERVICE_GOOGLE) { -- cgit v1.2.3 From 3fc3627f2d27b181269416f346f29d6451f7009a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Fri, 24 Feb 2023 11:59:48 +0200 Subject: SL-19209 WIP Switch MS Bing to MS Azure #2 --- indra/newview/app_settings/settings.xml | 17 +- indra/newview/llfloatertranslationsettings.cpp | 120 +++++--- indra/newview/llfloatertranslationsettings.h | 18 +- indra/newview/lltranslate.cpp | 317 +++++++++++++++------ indra/newview/lltranslate.h | 14 +- .../xui/en/floater_translation_settings.xml | 95 ++++-- 6 files changed, 420 insertions(+), 161 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 411f77e6a7..ddd4f57f3f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12929,13 +12929,13 @@ <key>TranslationService</key> <map> <key>Comment</key> - <string>Translation API to use. (google|bing)</string> + <string>Translation API to use. (google|azure)</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>String</string> <key>Value</key> - <string>bing</string> + <string>azure</string> </map> <key>GoogleTranslateAPIKey</key> <map> @@ -12951,7 +12951,7 @@ <key>BingTranslateAPIKey</key> <map> <key>Comment</key> - <string>Bing AppID to use with the Microsoft Translator API</string> + <string>(Deprecated) Bing AppID to use with the Microsoft Translator API</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -12959,6 +12959,17 @@ <key>Value</key> <string></string> </map> + <key>AzureTranslateAPIKey</key> + <map> + <key>Comment</key> + <string>Azure Translation service data to use with the MS Azure Translator API</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>LLSD</string> + <key>Value</key> + <string></string> + </map> <key>TutorialURL</key> <map> <key>Comment</key> diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index 082bb888b1..45f46aacf5 100644 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -45,14 +45,7 @@ LLFloaterTranslationSettings::LLFloaterTranslationSettings(const LLSD& key) : LLFloater(key) , mMachineTranslationCB(NULL) -, mLanguageCombo(NULL) -, mTranslationServiceRadioGroup(NULL) -, mBingAPIKeyEditor(NULL) -, mGoogleAPIKeyEditor(NULL) -, mBingVerifyBtn(NULL) -, mGoogleVerifyBtn(NULL) -, mOKBtn(NULL) -, mBingKeyVerified(false) +, mAzureKeyVerified(false) , mGoogleKeyVerified(false) { } @@ -63,9 +56,11 @@ BOOL LLFloaterTranslationSettings::postBuild() mMachineTranslationCB = getChild<LLCheckBoxCtrl>("translate_chat_checkbox"); mLanguageCombo = getChild<LLComboBox>("translate_language_combo"); mTranslationServiceRadioGroup = getChild<LLRadioGroup>("translation_service_rg"); - mBingAPIKeyEditor = getChild<LLLineEditor>("bing_api_key"); + mAzureAPIEndpointEditor = getChild<LLComboBox>("azure_api_endpoint_combo"); + mAzureAPIKeyEditor = getChild<LLLineEditor>("azure_api_key"); + mAzureAPIRegionEditor = getChild<LLLineEditor>("azure_api_region"); mGoogleAPIKeyEditor = getChild<LLLineEditor>("google_api_key"); - mBingVerifyBtn = getChild<LLButton>("verify_bing_api_key_btn"); + mAzureVerifyBtn = getChild<LLButton>("verify_azure_api_key_btn"); mGoogleVerifyBtn = getChild<LLButton>("verify_google_api_key_btn"); mOKBtn = getChild<LLButton>("ok_btn"); @@ -73,11 +68,17 @@ BOOL LLFloaterTranslationSettings::postBuild() mTranslationServiceRadioGroup->setCommitCallback(boost::bind(&LLFloaterTranslationSettings::updateControlsEnabledState, this)); mOKBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnOK, this)); getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloater::closeFloater, this, false)); - mBingVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnBingVerify, this)); + mAzureVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnAzureVerify, this)); mGoogleVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnGoogleVerify, this)); - mBingAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1)); - mBingAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onBingKeyEdited, this), NULL); + mAzureAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1)); + mAzureAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onAzureKeyEdited, this), NULL); + mAzureAPIRegionEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1)); + mAzureAPIRegionEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onAzureKeyEdited, this), NULL); + + mAzureAPIEndpointEditor->setFocusLostCallback(boost::bind(&LLFloaterTranslationSettings::onAzureKeyEdited, this)); + mAzureAPIEndpointEditor->setCommitCallback(boost::bind(&LLFloaterTranslationSettings::onAzureKeyEdited, this)); + mGoogleAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1)); mGoogleAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onGoogleKeyEdited, this), NULL); @@ -92,17 +93,27 @@ void LLFloaterTranslationSettings::onOpen(const LLSD& key) mLanguageCombo->setSelectedByValue(gSavedSettings.getString("TranslateLanguage"), TRUE); mTranslationServiceRadioGroup->setSelectedByValue(gSavedSettings.getString("TranslationService"), TRUE); - std::string bing_key = gSavedSettings.getString("BingTranslateAPIKey"); - if (!bing_key.empty()) + LLSD azure_key = gSavedSettings.getLLSD("AzureTranslateAPIKey"); + if (azure_key.isMap()) { - mBingAPIKeyEditor->setText(bing_key); - mBingAPIKeyEditor->setTentative(FALSE); - verifyKey(LLTranslate::SERVICE_BING, bing_key, false); + mAzureAPIKeyEditor->setText(azure_key["id"].asString()); + mAzureAPIKeyEditor->setTentative(false); + if (azure_key.has("region")) + { + mAzureAPIRegionEditor->setText(azure_key["region"].asString()); + mAzureAPIRegionEditor->setTentative(false); + } + else + { + mAzureAPIRegionEditor->setTentative(true); + } + mAzureAPIEndpointEditor->setValue(azure_key["endpoint"]); + verifyKey(LLTranslate::SERVICE_AZURE, azure_key, false); } else { - mBingAPIKeyEditor->setTentative(TRUE); - mBingKeyVerified = FALSE; + mAzureAPIKeyEditor->setTentative(TRUE); + mAzureKeyVerified = FALSE; } std::string google_key = gSavedSettings.getString("GoogleTranslateAPIKey"); @@ -121,14 +132,14 @@ void LLFloaterTranslationSettings::onOpen(const LLSD& key) updateControlsEnabledState(); } -void LLFloaterTranslationSettings::setBingVerified(bool ok, bool alert) +void LLFloaterTranslationSettings::setAzureVerified(bool ok, bool alert) { if (alert) { - showAlert(ok ? "bing_api_key_verified" : "bing_api_key_not_verified"); + showAlert(ok ? "azure_api_key_verified" : "azure_api_key_not_verified"); } - mBingKeyVerified = ok; + mAzureKeyVerified = ok; updateControlsEnabledState(); } @@ -148,9 +159,19 @@ std::string LLFloaterTranslationSettings::getSelectedService() const return mTranslationServiceRadioGroup->getSelectedValue().asString(); } -std::string LLFloaterTranslationSettings::getEnteredBingKey() const +LLSD LLFloaterTranslationSettings::getEnteredAzureKey() const { - return mBingAPIKeyEditor->getTentative() ? LLStringUtil::null : mBingAPIKeyEditor->getText(); + LLSD key; + if (!mAzureAPIKeyEditor->getTentative()) + { + key["endpoint"] = mAzureAPIEndpointEditor->getValue(); + key["id"] = mAzureAPIKeyEditor->getText(); + if (!mAzureAPIRegionEditor->getTentative()) + { + key["region"] = mAzureAPIRegionEditor->getText(); + } + } + return key; } std::string LLFloaterTranslationSettings::getEnteredGoogleKey() const @@ -170,27 +191,31 @@ void LLFloaterTranslationSettings::updateControlsEnabledState() // Enable/disable controls based on the checkbox value. bool on = mMachineTranslationCB->getValue().asBoolean(); std::string service = getSelectedService(); - bool bing_selected = service == "bing"; + bool azure_selected = service == "azure"; bool google_selected = service == "google"; mTranslationServiceRadioGroup->setEnabled(on); mLanguageCombo->setEnabled(on); - getChild<LLTextBox>("bing_api_key_label")->setEnabled(on); - mBingAPIKeyEditor->setEnabled(on); + getChild<LLTextBox>("azure_api_endoint_label")->setEnabled(on); + mAzureAPIEndpointEditor->setEnabled(on); + getChild<LLTextBox>("azure_api_key_label")->setEnabled(on); + mAzureAPIKeyEditor->setEnabled(on); + getChild<LLTextBox>("azure_api_region_label")->setEnabled(on); + mAzureAPIRegionEditor->setEnabled(on); getChild<LLTextBox>("google_api_key_label")->setEnabled(on); mGoogleAPIKeyEditor->setEnabled(on); - mBingAPIKeyEditor->setEnabled(on && bing_selected); + mAzureAPIKeyEditor->setEnabled(on && azure_selected); mGoogleAPIKeyEditor->setEnabled(on && google_selected); - mBingVerifyBtn->setEnabled(on && bing_selected && - !mBingKeyVerified && !getEnteredBingKey().empty()); + mAzureVerifyBtn->setEnabled(on && azure_selected && + !mAzureKeyVerified && getEnteredAzureKey().isMap()); mGoogleVerifyBtn->setEnabled(on && google_selected && !mGoogleKeyVerified && !getEnteredGoogleKey().empty()); - bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified); + bool service_verified = (azure_selected && mAzureKeyVerified) || (google_selected && mGoogleKeyVerified); gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified); mOKBtn->setEnabled(!on || service_verified); @@ -210,8 +235,8 @@ void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, b switch (service) { - case LLTranslate::SERVICE_BING: - floater->setBingVerified(ok, alert); + case LLTranslate::SERVICE_AZURE: + floater->setAzureVerified(ok, alert); break; case LLTranslate::SERVICE_GOOGLE: floater->setGoogleVerified(ok, alert); @@ -220,7 +245,7 @@ void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, b } -void LLFloaterTranslationSettings::verifyKey(int service, const std::string& key, bool alert) +void LLFloaterTranslationSettings::verifyKey(int service, const LLSD& key, bool alert) { LLTranslate::verifyKey(static_cast<LLTranslate::EService>(service), key, boost::bind(&LLFloaterTranslationSettings::setVerificationStatus, _1, _2, alert)); @@ -239,11 +264,14 @@ void LLFloaterTranslationSettings::onEditorFocused(LLFocusableElement* control) } } -void LLFloaterTranslationSettings::onBingKeyEdited() +void LLFloaterTranslationSettings::onAzureKeyEdited() { - if (mBingAPIKeyEditor->isDirty()) + if (mAzureAPIKeyEditor->isDirty() + || mAzureAPIRegionEditor->isDirty() + || mAzureAPIEndpointEditor->getValue().isString()) { - setBingVerified(false, false); + // todo: verify mAzureAPIEndpointEditor url + setAzureVerified(false, false); } } @@ -255,12 +283,12 @@ void LLFloaterTranslationSettings::onGoogleKeyEdited() } } -void LLFloaterTranslationSettings::onBtnBingVerify() +void LLFloaterTranslationSettings::onBtnAzureVerify() { - std::string key = getEnteredBingKey(); - if (!key.empty()) + LLSD key = getEnteredAzureKey(); + if (key.isMap()) { - verifyKey(LLTranslate::SERVICE_BING, key); + verifyKey(LLTranslate::SERVICE_AZURE, key); } } @@ -269,16 +297,16 @@ void LLFloaterTranslationSettings::onBtnGoogleVerify() std::string key = getEnteredGoogleKey(); if (!key.empty()) { - verifyKey(LLTranslate::SERVICE_GOOGLE, key); + verifyKey(LLTranslate::SERVICE_GOOGLE, LLSD(key)); } } void LLFloaterTranslationSettings::onClose(bool app_quitting) { std::string service = gSavedSettings.getString("TranslationService"); - bool bing_selected = service == "bing"; + bool azure_selected = service == "azure"; bool google_selected = service == "google"; - bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified); + bool service_verified = (azure_selected && mAzureKeyVerified) || (google_selected && mGoogleKeyVerified); gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified); } @@ -287,7 +315,7 @@ void LLFloaterTranslationSettings::onBtnOK() gSavedSettings.setBOOL("TranslateChat", mMachineTranslationCB->getValue().asBoolean()); gSavedSettings.setString("TranslateLanguage", mLanguageCombo->getSelectedValue().asString()); gSavedSettings.setString("TranslationService", getSelectedService()); - gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey()); + gSavedSettings.setLLSD("AzureTranslateAPIKey", getEnteredAzureKey()); gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey()); closeFloater(false); diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h index 2a15eacded..52523f4d4a 100644 --- a/indra/newview/llfloatertranslationsettings.h +++ b/indra/newview/llfloatertranslationsettings.h @@ -42,22 +42,22 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); - void setBingVerified(bool ok, bool alert); + void setAzureVerified(bool ok, bool alert); void setGoogleVerified(bool ok, bool alert); void onClose(bool app_quitting); private: std::string getSelectedService() const; - std::string getEnteredBingKey() const; + LLSD getEnteredAzureKey() const; std::string getEnteredGoogleKey() const; void showAlert(const std::string& msg_name) const; void updateControlsEnabledState(); - void verifyKey(int service, const std::string& key, bool alert = true); + void verifyKey(int service, const LLSD& key, bool alert = true); void onEditorFocused(LLFocusableElement* control); - void onBingKeyEdited(); + void onAzureKeyEdited(); void onGoogleKeyEdited(); - void onBtnBingVerify(); + void onBtnAzureVerify(); void onBtnGoogleVerify(); void onBtnOK(); @@ -65,14 +65,16 @@ private: LLCheckBoxCtrl* mMachineTranslationCB; LLComboBox* mLanguageCombo; - LLLineEditor* mBingAPIKeyEditor; + LLComboBox* mAzureAPIEndpointEditor;; + LLLineEditor* mAzureAPIKeyEditor; + LLLineEditor* mAzureAPIRegionEditor; LLLineEditor* mGoogleAPIKeyEditor; LLRadioGroup* mTranslationServiceRadioGroup; - LLButton* mBingVerifyBtn; + LLButton* mAzureVerifyBtn; LLButton* mGoogleVerifyBtn; LLButton* mOKBtn; - bool mBingKeyVerified; + bool mAzureKeyVerified; bool mGoogleKeyVerified; }; diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 3e6bf4fe82..706b4cc6ee 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -80,7 +80,18 @@ public: * @param[in] key Key to verify. */ virtual std::string getKeyVerificationURL( - const std::string &key) const = 0; + const LLSD &key) const = 0; + + /** + * Check API verification response. + * + * @param[out] bool true if valid. + * @param[in] response + * @param[in] status + */ + virtual bool checkVerificationResponse( + const LLSD &response, + int status) const = 0; /** * Parse translation response. @@ -105,22 +116,28 @@ public: virtual LLTranslate::EService getCurrentService() = 0; - virtual void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) = 0; + virtual void verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc) = 0; virtual void translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure); virtual ~LLTranslationAPIHandler() {} - void verifyKeyCoro(LLTranslate::EService service, std::string key, LLTranslate::KeyVerificationResult_fn fnc); + void verifyKeyCoro(LLTranslate::EService service, LLSD key, LLTranslate::KeyVerificationResult_fn fnc); void translateMessageCoro(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure); virtual void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const = 0; + virtual void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent, const LLSD &key) const = 0; virtual LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, LLCore::HttpRequest::ptr_t request, LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers, const std::string & url, const std::string & msg) const = 0; + virtual LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string & url) const = 0; }; void LLTranslationAPIHandler::translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure) @@ -130,8 +147,7 @@ void LLTranslationAPIHandler::translateMessage(LanguagePair_t fromTo, std::strin } - -void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std::string key, LLTranslate::KeyVerificationResult_fn fnc) +void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, LLSD key, LLTranslate::KeyVerificationResult_fn fnc) { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t @@ -148,8 +164,7 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std:: LLVersionInfo::instance().getPatch(), LLVersionInfo::instance().getBuild()); - httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN); - httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); + initHttpHeader(httpHeaders, user_agent, key); httpOpts->setFollowRedirects(true); httpOpts->setSSLVerifyPeer(false); @@ -161,17 +176,22 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std:: return; } - LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts, httpHeaders); + LLSD result = verifyAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url); LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); bool bOk = true; - if (!status) + int parseResult = status.getType(); + if (!checkVerificationResponse(httpResults, parseResult)) + { bOk = false; + } if (!fnc.empty()) + { fnc(service, bOk); + } } void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::string msg, @@ -192,7 +212,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s LLVersionInfo::instance().getPatch(), LLVersionInfo::instance().getBuild()); - initHttpHeader(httpHeaders, user_agent); + initHttpHeader(httpHeaders, user_agent); httpOpts->setSSLVerifyPeer(false); std::string url = this->getTranslateURL(fromTo.first, fromTo.second, msg); @@ -251,6 +271,11 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s } else { + if (err_msg.empty() && httpResults.has("error_body")) + { + err_msg = httpResults["error_body"].asString(); + } + if (err_msg.empty()) { err_msg = LLTrans::getString("TranslationResponseParseError"); @@ -271,25 +296,29 @@ class LLGoogleTranslationHandler : public LLTranslationAPIHandler LOG_CLASS(LLGoogleTranslationHandler); public: - /*virtual*/ std::string getTranslateURL( + std::string getTranslateURL( const std::string &from_lang, const std::string &to_lang, - const std::string &text) const; - /*virtual*/ std::string getKeyVerificationURL( - const std::string &key) const; - /*virtual*/ bool parseResponse( + const std::string &text) const override; + std::string getKeyVerificationURL( + const LLSD &key) const override; + bool checkVerificationResponse( + const LLSD &response, + int status) const override; + bool parseResponse( int& status, const std::string& body, std::string& translation, std::string& detected_lang, - std::string& err_msg) const; - /*virtual*/ bool isConfigured() const; + std::string& err_msg) const override; + bool isConfigured() const override; - /*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_GOOGLE; } + LLTranslate::EService getCurrentService() override { return LLTranslate::EService::SERVICE_GOOGLE; } - /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc); + void verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc) override; void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const override; + void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent, const LLSD &key) const override; LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, LLCore::HttpRequest::ptr_t request, LLCore::HttpOptions::ptr_t options, @@ -297,6 +326,12 @@ public: const std::string & url, const std::string & msg) const override; + LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string & url) const override; + private: static void parseErrorResponse( const Json::Value& root, @@ -328,13 +363,21 @@ std::string LLGoogleTranslationHandler::getTranslateURL( // virtual std::string LLGoogleTranslationHandler::getKeyVerificationURL( - const std::string& key) const + const LLSD& key) const { - std::string url = std::string("https://www.googleapis.com/language/translate/v2/languages?key=") - + key + "&target=en"; + std::string url = std::string("https://www.googleapis.com/language/translate/v2/languages?key=") + + key.asString() +"&target=en"; return url; } +//virtual +bool LLGoogleTranslationHandler::checkVerificationResponse( + const LLSD &response, + int status) const +{ + return status == HTTP_OK; +} + // virtual bool LLGoogleTranslationHandler::parseResponse( int& status, @@ -424,11 +467,12 @@ bool LLGoogleTranslationHandler::parseTranslation( // static std::string LLGoogleTranslationHandler::getAPIKey() { - return gSavedSettings.getString("GoogleTranslateAPIKey"); + static LLCachedControl<std::string> google_key(gSavedSettings, "GoogleTranslateAPIKey"); + return google_key; } /*virtual*/ -void LLGoogleTranslationHandler::verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) +void LLGoogleTranslationHandler::verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc) { LLCoros::instance().launch("Google /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro, this, LLTranslate::SERVICE_GOOGLE, key, fnc)); @@ -441,6 +485,16 @@ void LLGoogleTranslationHandler::initHttpHeader(LLCore::HttpHeaders::ptr_t heade headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); } +/*virtual*/ +void LLGoogleTranslationHandler::initHttpHeader( + LLCore::HttpHeaders::ptr_t headers, + const std::string& user_agent, + const LLSD &key) const +{ + headers->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN); + headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); +} + LLSD LLGoogleTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, LLCore::HttpRequest::ptr_t request, LLCore::HttpOptions::ptr_t options, @@ -451,6 +505,15 @@ LLSD LLGoogleTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCorou return adapter->getRawAndSuspend(request, url, options, headers); } +LLSD LLGoogleTranslationHandler::verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string & url) const +{ + return adapter->getAndSuspend(request, url, options, headers); +} + //========================================================================= /// Microsoft Translator v2 API handler. class LLAzureTranslationHandler : public LLTranslationAPIHandler @@ -463,7 +526,10 @@ public: const std::string &to_lang, const std::string &text) const override; std::string getKeyVerificationURL( - const std::string &key) const override; + const LLSD &key) const override; + bool checkVerificationResponse( + const LLSD &response, + int status) const override; bool parseResponse( int& status, const std::string& body, @@ -472,19 +538,26 @@ public: std::string& err_msg) const override; bool isConfigured() const override; - LLTranslate::EService getCurrentService() override { return LLTranslate::EService::SERVICE_BING; } + LLTranslate::EService getCurrentService() override { return LLTranslate::EService::SERVICE_AZURE; } - void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) override; + void verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc) override; void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const override; + void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent, const LLSD &key) const override; LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, LLCore::HttpRequest::ptr_t request, LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers, const std::string & url, const std::string & msg) const override; + + LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string & url) const override; private: - static std::string getAPIKey(); + static LLSD getAPIKey(); static std::string getAPILanguageCode(const std::string& lang); }; @@ -496,22 +569,49 @@ std::string LLAzureTranslationHandler::getTranslateURL( const std::string &to_lang, const std::string &text) const { - // Global service. Alternatively regional services exist. - std::string url = std::string("https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=") - + getAPILanguageCode(to_lang) + "&Subscription-Key=" + getAPIKey(); + std::string url; + LLSD key = getAPIKey(); + if (key.isMap()) + { + std::string endpoint = key["endpoint"].asString(); + // todo: validate url + if (*endpoint.rbegin() != '/') + { + endpoint += "/"; + } + url = endpoint + std::string("translate?api-version=3.0&to=") + + getAPILanguageCode(to_lang); + } return url; } // virtual std::string LLAzureTranslationHandler::getKeyVerificationURL( - const std::string& key) const + const LLSD& key) const { - std::string url = std::string("http://api.microsofttranslator.com/v2/Http.svc/GetLanguagesForTranslate?appId=") - + key; + std::string url; + if (key.isMap()) + { + std::string endpoint = key["endpoint"].asString(); + // todo: validate url + if (*endpoint.rbegin() != '/') + { + endpoint += "/"; + } + url = endpoint + std::string("translate?api-version=3.0&to=en"); + } return url; } +//virtual +bool LLAzureTranslationHandler::checkVerificationResponse( + const LLSD &response, + int status) const +{ + return status == HTTP_BAD_REQUEST; // would have been 401 if id was wrong +} + // virtual bool LLAzureTranslationHandler::parseResponse( int& status, @@ -522,52 +622,71 @@ bool LLAzureTranslationHandler::parseResponse( { if (status != HTTP_OK) { - static const std::string MSG_BEGIN_MARKER = "Message: "; - size_t begin = body.find(MSG_BEGIN_MARKER); - if (begin != std::string::npos) - { - begin += MSG_BEGIN_MARKER.size(); - } - else - { - begin = 0; - err_msg.clear(); - } - size_t end = body.find("</p>", begin); - err_msg = body.substr(begin, end-begin); - LLStringUtil::replaceString(err_msg, "
", ""); // strip CR return false; } - // Sample response: <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Hola</string> - size_t begin = body.find(">"); - if (begin == std::string::npos || begin >= (body.size() - 1)) - { - begin = 0; - } - else - { - ++begin; - } + //Example: + // "[{\"detectedLanguage\":{\"language\":\"en\",\"score\":1.0},\"translations\":[{\"text\":\"Hello, what is your name?\",\"to\":\"en\"}]}]" - size_t end = body.find("</string>", begin); + Json::Value root; + Json::Reader reader; - detected_lang = ""; // unsupported by this API - translation = body.substr(begin, end-begin); - LLStringUtil::replaceString(translation, "
", ""); // strip CR - return true; + if (!reader.parse(body, root)) + { + err_msg = reader.getFormatedErrorMessages(); + return false; + } + + if (!root.isArray()) // empty response? should not happen + { + return false; + } + + // Request succeeded, extract translation from the response. + + const Json::Value& data = root[0U]; + if (!data.isObject() + || !data.isMember("detectedLanguage") + || !data.isMember("translations")) + { + return false; + } + + const Json::Value& detectedLanguage = data["detectedLanguage"]; + if (!detectedLanguage.isObject() || !detectedLanguage.isMember("language")) + { + return false; + } + detected_lang = detectedLanguage["language"].asString(); + + const Json::Value& translations = data["translations"]; + if (!translations.isArray() || translations.size() == 0) + { + return false; + } + + const Json::Value& first = translations[0U]; + if (!first.isObject() || !first.isMember("text")) + { + return false; + } + + translation = first["text"].asString(); + + return true; } // virtual bool LLAzureTranslationHandler::isConfigured() const { - return !getAPIKey().empty(); + return !getAPIKey().isMap(); } // static -std::string LLAzureTranslationHandler::getAPIKey() +LLSD LLAzureTranslationHandler::getAPIKey() { - return gSavedSettings.getString("BingTranslateAPIKey"); + static LLCachedControl<LLSD> azure_key(gSavedSettings, "AzureTranslateAPIKey"); + return azure_key; } // static @@ -577,19 +696,38 @@ std::string LLAzureTranslationHandler::getAPILanguageCode(const std::string& lan } /*virtual*/ -void LLAzureTranslationHandler::verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) +void LLAzureTranslationHandler::verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc) { - LLCoros::instance().launch("Bing /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro, - this, LLTranslate::SERVICE_BING, key, fnc)); + LLCoros::instance().launch("Azure /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro, + this, LLTranslate::SERVICE_AZURE, key, fnc)); +} +/*virtual*/ +void LLAzureTranslationHandler::initHttpHeader( + LLCore::HttpHeaders::ptr_t headers, + const std::string& user_agent) const +{ + initHttpHeader(headers, user_agent, getAPIKey()); } /*virtual*/ -void LLAzureTranslationHandler::initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const +void LLAzureTranslationHandler::initHttpHeader( + LLCore::HttpHeaders::ptr_t headers, + const std::string& user_agent, + const LLSD &key) const { headers->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_JSON); - // Token based autorization exists - //headers->append("Ocp-Apim-Subscription-Key", getAPIKey()); headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); + + if (key.has("id")) + { + // Token based autorization + headers->append("Ocp-Apim-Subscription-Key", key["id"].asString()); + } + if (key.has("region")) + { + // ex: "westeurope" + headers->append("Ocp-Apim-Subscription-Region", key["region"].asString()); + } } LLSD LLAzureTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, @@ -599,9 +737,26 @@ LLSD LLAzureTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCorout const std::string & url, const std::string & msg) const { - LLSD body; - body["text"] = "Hello, what is your name?"; - return adapter->postJsonAndSuspend(request, url, body, headers); + LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray); + LLCore::BufferArrayStream outs(rawbody.get()); + outs << "[{\"text\":\""; + outs << msg; + outs << "\"}]"; + + return adapter->postRawAndSuspend(request, url, rawbody, options, headers); +} + +LLSD LLAzureTranslationHandler::verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string & url) const +{ + LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray); + LLCore::BufferArrayStream outs(rawbody.get()); + outs << "[{\"intentionally_invalid_400\"}]"; + + return adapter->postRawAndSuspend(request, url, rawbody, options, headers); } //========================================================================= @@ -616,7 +771,7 @@ void LLTranslate::translateMessage(const std::string &from_lang, const std::stri std::string LLTranslate::addNoTranslateTags(std::string mesg) { - if (getPreferredHandler().getCurrentService() != SERVICE_BING) + if (getPreferredHandler().getCurrentService() != SERVICE_AZURE) { return mesg; } @@ -637,7 +792,7 @@ std::string LLTranslate::addNoTranslateTags(std::string mesg) std::string LLTranslate::removeNoTranslateTags(std::string mesg) { - if (getPreferredHandler().getCurrentService() != SERVICE_BING) + if (getPreferredHandler().getCurrentService() != SERVICE_AZURE) { return mesg; } @@ -667,7 +822,7 @@ std::string LLTranslate::removeNoTranslateTags(std::string mesg) } /*static*/ -void LLTranslate::verifyKey(EService service, const std::string &key, KeyVerificationResult_fn fnc) +void LLTranslate::verifyKey(EService service, const LLSD &key, KeyVerificationResult_fn fnc) { LLTranslationAPIHandler& handler = getHandler(service); @@ -696,7 +851,7 @@ bool LLTranslate::isTranslationConfigured() // static LLTranslationAPIHandler& LLTranslate::getPreferredHandler() { - EService service = SERVICE_BING; + EService service = SERVICE_AZURE; std::string service_str = gSavedSettings.getString("TranslationService"); if (service_str == "google") @@ -711,12 +866,12 @@ LLTranslationAPIHandler& LLTranslate::getPreferredHandler() LLTranslationAPIHandler& LLTranslate::getHandler(EService service) { static LLGoogleTranslationHandler google; - static LLAzureTranslationHandler bing; + static LLAzureTranslationHandler azure; if (service == SERVICE_GOOGLE) { return google; } - return bing; + return azure; } diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index e0722fbd83..870fd54441 100644 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -55,7 +55,7 @@ class LLTranslate public : typedef enum e_service { - SERVICE_BING, + SERVICE_AZURE, SERVICE_GOOGLE, } EService; @@ -74,12 +74,12 @@ public : static void translateMessage(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, TranslationSuccess_fn success, TranslationFailure_fn failure); /** - * Verify given API key of a translation service. - * - * @param receiver Object to pass verification result to. - * @param key Key to verify. - */ - static void verifyKey(EService service, const std::string &key, KeyVerificationResult_fn fnc); + * Verify given API key of a translation service. + * + * @param receiver Object to pass verification result to. + * @param key Key to verify. + */ + static void verifyKey(EService service, const LLSD &key, KeyVerificationResult_fn fnc); /** * @return translation target language diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml index a212ce7889..b0e47798e9 100644 --- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater legacy_header_height="18" - height="310" + height="370" layout="topleft" name="floater_translation_settings" help_topic="translation_settings" @@ -9,10 +9,10 @@ title="CHAT TRANSLATION SETTINGS" width="485"> - <string name="bing_api_key_not_verified">Bing appID not verified. Please try again.</string> + <string name="azure_api_key_not_verified">Azure service identifier not verified. Please try again.</string> <string name="google_api_key_not_verified">Google API key not verified. Please try again.</string> - <string name="bing_api_key_verified">Bing appID verified.</string> + <string name="azure_api_key_verified">Azure service identifier verified.</string> <string name="google_api_key_verified">Google API key verified.</string> <check_box @@ -128,25 +128,67 @@ <radio_group follows="top|left" - height="80" + height="140" layout="topleft" left_delta="10" name="translation_service_rg" top_pad="20" width="320"> <radio_item - initial_value="bing" - label="Bing Translator" + initial_value="azure" + label="Azure Translator" layout="topleft" - name="bing" /> + name="azure" /> <radio_item initial_value="google" label="Google Translate" layout="topleft" name="google" - top_pad="55" /> + top_pad="115" /> </radio_group> + <text + type="string" + length="1" + follows="top|right" + height="20" + layout="topleft" + left="70" + name="azure_api_endoint_label" + top_pad="-115" + width="85"> + Endpoint: + </text> + + <combo_box + allow_text_entry="true" + follows="left|top" + name="azure_api_endpoint_combo" + height="23" + left_pad="10" + right="-10" + top_delta="-4" + max_chars="512" + value="https://api.cognitive.microsofttranslator.com" + combo_button.scale_image="true"> + <combo_box.item + label="https://api.cognitive.microsofttranslator.com" + name="global" + value="https://api.cognitive.microsofttranslator.com" /> + <combo_box.item + label="https://api-apc.cognitive.microsofttranslator.com" + name="api-apc" + value="https://api-apc.cognitive.microsofttranslator.com" /> + <combo_box.item + label="https://api-eur.cognitive.microsofttranslator.com" + name="api-eur" + value="https://api-eur.cognitive.microsofttranslator.com" /> + <combo_box.item + label="https://api-nam.cognitive.microsofttranslator.com" + name="api-nam" + value="https://api-nam.cognitive.microsofttranslator.com" /> + </combo_box> + <text type="string" length="1" @@ -154,20 +196,20 @@ height="20" layout="topleft" left="70" - name="bing_api_key_label" - top_pad="-55" + name="azure_api_key_label" + top_pad="10" width="85"> - Bing [http://www.bing.com/developers/createapp.aspx AppID]: + Azure Key: </text> <line_editor - default_text="Enter Bing AppID and click "Verify"" + default_text="Enter Translator Key and click "Verify"" follows="top|left" height="20" layout="topleft" left_pad="10" max_length_chars="50" top_delta="-4" - name="bing_api_key" + name="azure_api_key" width="210" /> <button follows="left|top" @@ -175,9 +217,30 @@ label="Verify" layout="topleft" left_pad="10" - name="verify_bing_api_key_btn" + name="verify_azure_api_key_btn" top_delta="-2" - width="90" /> + width="90" /> + <text + type="string" + length="1" + follows="top|right" + height="20" + layout="topleft" + left="70" + name="azure_api_region_label" + top_pad="10" + width="85"> + Region: + </text> + <line_editor + follows="top|left" + height="20" + layout="topleft" + left_pad="10" + max_length_chars="50" + top_delta="-4" + name="azure_api_region" + width="210" /> <text follows="top|right" @@ -186,7 +249,7 @@ left="70" length="1" name="google_api_key_label" - top_pad="50" + top_pad="55" type="string" width="85"> Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API key]: -- cgit v1.2.3 From f7210db06ee677231b93b750c205cd0317a9901f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Tue, 28 Feb 2023 00:13:31 +0200 Subject: SL-19209 Switch MS Bing to MS Azure #3 --- indra/newview/llfloatertranslationsettings.cpp | 29 ++-- indra/newview/llfloatertranslationsettings.h | 8 +- indra/newview/lltranslate.cpp | 168 ++++++++++++++++----- indra/newview/lltranslate.h | 2 +- .../xui/en/floater_translation_settings.xml | 19 ++- 5 files changed, 168 insertions(+), 58 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index 45f46aacf5..c99de47da0 100644 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -132,22 +132,22 @@ void LLFloaterTranslationSettings::onOpen(const LLSD& key) updateControlsEnabledState(); } -void LLFloaterTranslationSettings::setAzureVerified(bool ok, bool alert) +void LLFloaterTranslationSettings::setAzureVerified(bool ok, bool alert, S32 status) { if (alert) { - showAlert(ok ? "azure_api_key_verified" : "azure_api_key_not_verified"); + showAlert(ok ? "azure_api_key_verified" : "azure_api_key_not_verified", status); } mAzureKeyVerified = ok; updateControlsEnabledState(); } -void LLFloaterTranslationSettings::setGoogleVerified(bool ok, bool alert) +void LLFloaterTranslationSettings::setGoogleVerified(bool ok, bool alert, S32 status) { if (alert) { - showAlert(ok ? "google_api_key_verified" : "google_api_key_not_verified"); + showAlert(ok ? "google_api_key_verified" : "google_api_key_not_verified", status); } mGoogleKeyVerified = ok; @@ -179,10 +179,15 @@ std::string LLFloaterTranslationSettings::getEnteredGoogleKey() const return mGoogleAPIKeyEditor->getTentative() ? LLStringUtil::null : mGoogleAPIKeyEditor->getText(); } -void LLFloaterTranslationSettings::showAlert(const std::string& msg_name) const +void LLFloaterTranslationSettings::showAlert(const std::string& msg_name, S32 status) const { + LLStringUtil::format_map_t string_args; + // For now just show an http error code, whole 'reason' string might be added later + string_args["[STATUS]"] = llformat("%d", status); + std::string message = getString(msg_name, string_args); + LLSD args; - args["MESSAGE"] = getString(msg_name); + args["MESSAGE"] = message; LLNotificationsUtil::add("GenericAlert", args); } @@ -222,7 +227,7 @@ void LLFloaterTranslationSettings::updateControlsEnabledState() } /*static*/ -void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, bool alert) +void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, bool alert, S32 status) { LLFloaterTranslationSettings* floater = LLFloaterReg::getTypedInstance<LLFloaterTranslationSettings>("prefs_translation"); @@ -236,10 +241,10 @@ void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, b switch (service) { case LLTranslate::SERVICE_AZURE: - floater->setAzureVerified(ok, alert); + floater->setAzureVerified(ok, alert, status); break; case LLTranslate::SERVICE_GOOGLE: - floater->setGoogleVerified(ok, alert); + floater->setGoogleVerified(ok, alert, status); break; } } @@ -248,7 +253,7 @@ void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, b void LLFloaterTranslationSettings::verifyKey(int service, const LLSD& key, bool alert) { LLTranslate::verifyKey(static_cast<LLTranslate::EService>(service), key, - boost::bind(&LLFloaterTranslationSettings::setVerificationStatus, _1, _2, alert)); + boost::bind(&LLFloaterTranslationSettings::setVerificationStatus, _1, _2, alert, _3)); } void LLFloaterTranslationSettings::onEditorFocused(LLFocusableElement* control) @@ -271,7 +276,7 @@ void LLFloaterTranslationSettings::onAzureKeyEdited() || mAzureAPIEndpointEditor->getValue().isString()) { // todo: verify mAzureAPIEndpointEditor url - setAzureVerified(false, false); + setAzureVerified(false, false, 0); } } @@ -279,7 +284,7 @@ void LLFloaterTranslationSettings::onGoogleKeyEdited() { if (mGoogleAPIKeyEditor->isDirty()) { - setGoogleVerified(false, false); + setGoogleVerified(false, false, 0); } } diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h index 52523f4d4a..f039d90e27 100644 --- a/indra/newview/llfloatertranslationsettings.h +++ b/indra/newview/llfloatertranslationsettings.h @@ -42,15 +42,15 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); - void setAzureVerified(bool ok, bool alert); - void setGoogleVerified(bool ok, bool alert); + void setAzureVerified(bool ok, bool alert, S32 status); + void setGoogleVerified(bool ok, bool alert, S32 status); void onClose(bool app_quitting); private: std::string getSelectedService() const; LLSD getEnteredAzureKey() const; std::string getEnteredGoogleKey() const; - void showAlert(const std::string& msg_name) const; + void showAlert(const std::string& msg_name, S32 status) const; void updateControlsEnabledState(); void verifyKey(int service, const LLSD& key, bool alert = true); @@ -61,7 +61,7 @@ private: void onBtnGoogleVerify(); void onBtnOK(); - static void setVerificationStatus(int service, bool alert, bool ok); + static void setVerificationStatus(int service, bool alert, bool ok, S32 status); LLCheckBoxCtrl* mMachineTranslationCB; LLComboBox* mLanguageCombo; diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 706b4cc6ee..b0c4418ae9 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -41,8 +41,8 @@ #include "llurlregistry.h" -static const std::string BING_NOTRANSLATE_OPENING_TAG("<div translate=\"no\">"); -static const std::string BING_NOTRANSLATE_CLOSING_TAG("</div>"); +static const std::string AZURE_NOTRANSLATE_OPENING_TAG("<div translate=\"no\">"); +static const std::string AZURE_NOTRANSLATE_CLOSING_TAG("</div>"); /** * Handler of an HTTP machine translation service. @@ -103,6 +103,7 @@ public: * @param[out] err_msg Error message (in case of error). */ virtual bool parseResponse( + const LLSD& http_response, int& status, const std::string& body, std::string& translation, @@ -176,6 +177,13 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, LLSD return; } + std::string::size_type delim_pos = url.find("://"); + if (delim_pos == std::string::npos) + { + LL_INFOS("Translate") << "URL is missing a scheme" << LL_ENDL; + return; + } + LLSD result = verifyAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url); LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; @@ -190,7 +198,7 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, LLSD if (!fnc.empty()) { - fnc(service, bOk); + fnc(service, bOk, parseResult); } } @@ -221,8 +229,8 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s LL_INFOS("Translate") << "No translation URL" << LL_ENDL; return; } - LL_INFOS() << "Message: " << msg << LL_ENDL; - LL_INFOS() << "Requesting: " << url << LL_ENDL; + LL_DEBUGS("Translate") << "Message: " << msg << LL_ENDL; + LL_DEBUGS("Translate") << "Requesting: " << url << LL_ENDL; LLSD result = sendMessageAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url, msg); @@ -245,7 +253,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s try { - res = this->parseResponse(parseResult, body, translation, detected_lang, err_msg); + res = this->parseResponse(httpResults, parseResult, body, translation, detected_lang, err_msg); } catch (std::out_of_range&) { @@ -306,6 +314,7 @@ public: const LLSD &response, int status) const override; bool parseResponse( + const LLSD& http_response, int& status, const std::string& body, std::string& translation, @@ -380,6 +389,7 @@ bool LLGoogleTranslationHandler::checkVerificationResponse( // virtual bool LLGoogleTranslationHandler::parseResponse( + const LLSD& http_response, int& status, const std::string& body, std::string& translation, @@ -531,6 +541,7 @@ public: const LLSD &response, int status) const override; bool parseResponse( + const LLSD& http_response, int& status, const std::string& body, std::string& translation, @@ -557,6 +568,8 @@ public: LLCore::HttpHeaders::ptr_t headers, const std::string & url) const override; private: + static std::string parseErrorResponse( + const std::string& body); static LLSD getAPIKey(); static std::string getAPILanguageCode(const std::string& lang); @@ -574,7 +587,7 @@ std::string LLAzureTranslationHandler::getTranslateURL( if (key.isMap()) { std::string endpoint = key["endpoint"].asString(); - // todo: validate url + if (*endpoint.rbegin() != '/') { endpoint += "/"; @@ -594,7 +607,6 @@ std::string LLAzureTranslationHandler::getKeyVerificationURL( if (key.isMap()) { std::string endpoint = key["endpoint"].asString(); - // todo: validate url if (*endpoint.rbegin() != '/') { endpoint += "/"; @@ -609,11 +621,48 @@ bool LLAzureTranslationHandler::checkVerificationResponse( const LLSD &response, int status) const { - return status == HTTP_BAD_REQUEST; // would have been 401 if id was wrong + if (status == HTTP_UNAUTHORIZED) + { + LL_DEBUGS("Translate") << "Key unathorised" << LL_ENDL; + return false; + } + + if (status == HTTP_NOT_FOUND) + { + LL_DEBUGS("Translate") << "Either endpoint doesn't have requested resource" << LL_ENDL; + return false; + } + + if (status != HTTP_BAD_REQUEST) + { + LL_DEBUGS("Translate") << "Unexpected error code" << LL_ENDL; + return false; + } + + if (!response.has("error_body")) + { + LL_DEBUGS("Translate") << "Unexpected response, no error returned" << LL_ENDL; + return false; + } + + // Expected: "{\"error\":{\"code\":400000,\"message\":\"One of the request inputs is not valid.\"}}" + // But for now just verify response is a valid json with an error + + Json::Value root; + Json::Reader reader; + + if (!reader.parse(response["error_body"].asString(), root)) + { + LL_DEBUGS("Translate") << "Failed to parse error_body:" << reader.getFormatedErrorMessages() << LL_ENDL; + return false; + } + + return true; } // virtual bool LLAzureTranslationHandler::parseResponse( + const LLSD& http_response, int& status, const std::string& body, std::string& translation, @@ -622,6 +671,8 @@ bool LLAzureTranslationHandler::parseResponse( { if (status != HTTP_OK) { + if (http_response.has("error_body")) + err_msg = parseErrorResponse(http_response["error_body"].asString()); return false; } @@ -682,6 +733,36 @@ bool LLAzureTranslationHandler::isConfigured() const return !getAPIKey().isMap(); } +//static +std::string LLAzureTranslationHandler::parseErrorResponse( + const std::string& body) +{ + // Expected: "{\"error\":{\"code\":400000,\"message\":\"One of the request inputs is not valid.\"}}" + // But for now just verify response is a valid json with an error + + Json::Value root; + Json::Reader reader; + + if (!reader.parse(body, root)) + { + return std::string(); + } + + if (!root.isObject() || !root.isMember("error")) + { + return std::string(); + } + + const Json::Value& error_map = root["error"]; + + if (!error_map.isObject() || !error_map.isMember("message")) + { + return std::string(); + } + + return error_map["message"].asString(); +} + // static LLSD LLAzureTranslationHandler::getAPIKey() { @@ -771,54 +852,65 @@ void LLTranslate::translateMessage(const std::string &from_lang, const std::stri std::string LLTranslate::addNoTranslateTags(std::string mesg) { - if (getPreferredHandler().getCurrentService() != SERVICE_AZURE) + if (getPreferredHandler().getCurrentService() == SERVICE_GOOGLE) { return mesg; } - std::string upd_msg(mesg); - LLUrlMatch match; - S32 dif = 0; - //surround all links (including SLURLs) with 'no-translate' tags to prevent unnecessary translation - while (LLUrlRegistry::instance().findUrl(mesg, match)) + if (getPreferredHandler().getCurrentService() == SERVICE_AZURE) { - upd_msg.insert(dif + match.getStart(), BING_NOTRANSLATE_OPENING_TAG); - upd_msg.insert(dif + BING_NOTRANSLATE_OPENING_TAG.size() + match.getEnd() + 1, BING_NOTRANSLATE_CLOSING_TAG); - mesg.erase(match.getStart(), match.getEnd() - match.getStart()); - dif += match.getEnd() - match.getStart() + BING_NOTRANSLATE_OPENING_TAG.size() + BING_NOTRANSLATE_CLOSING_TAG.size(); + // https://learn.microsoft.com/en-us/azure/cognitive-services/translator/prevent-translation + std::string upd_msg(mesg); + LLUrlMatch match; + S32 dif = 0; + //surround all links (including SLURLs) with 'no-translate' tags to prevent unnecessary translation + while (LLUrlRegistry::instance().findUrl(mesg, match)) + { + upd_msg.insert(dif + match.getStart(), AZURE_NOTRANSLATE_OPENING_TAG); + upd_msg.insert(dif + AZURE_NOTRANSLATE_OPENING_TAG.size() + match.getEnd() + 1, AZURE_NOTRANSLATE_CLOSING_TAG); + mesg.erase(match.getStart(), match.getEnd() - match.getStart()); + dif += match.getEnd() - match.getStart() + AZURE_NOTRANSLATE_OPENING_TAG.size() + AZURE_NOTRANSLATE_CLOSING_TAG.size(); + } + return upd_msg; } - return upd_msg; + return mesg; } std::string LLTranslate::removeNoTranslateTags(std::string mesg) { - if (getPreferredHandler().getCurrentService() != SERVICE_AZURE) + if (getPreferredHandler().getCurrentService() == SERVICE_GOOGLE) { return mesg; } - std::string upd_msg(mesg); - LLUrlMatch match; - S32 opening_tag_size = BING_NOTRANSLATE_OPENING_TAG.size(); - S32 closing_tag_size = BING_NOTRANSLATE_CLOSING_TAG.size(); - S32 dif = 0; - //remove 'no-translate' tags we added to the links before - while (LLUrlRegistry::instance().findUrl(mesg, match)) + + if (getPreferredHandler().getCurrentService() == SERVICE_AZURE) { - if (upd_msg.substr(dif + match.getStart() - opening_tag_size, opening_tag_size) == BING_NOTRANSLATE_OPENING_TAG) + std::string upd_msg(mesg); + LLUrlMatch match; + S32 opening_tag_size = AZURE_NOTRANSLATE_OPENING_TAG.size(); + S32 closing_tag_size = AZURE_NOTRANSLATE_CLOSING_TAG.size(); + S32 dif = 0; + //remove 'no-translate' tags we added to the links before + while (LLUrlRegistry::instance().findUrl(mesg, match)) { - upd_msg.erase(dif + match.getStart() - opening_tag_size, opening_tag_size); - dif -= opening_tag_size; - - if (upd_msg.substr(dif + match.getEnd() + 1, closing_tag_size) == BING_NOTRANSLATE_CLOSING_TAG) + if (upd_msg.substr(dif + match.getStart() - opening_tag_size, opening_tag_size) == AZURE_NOTRANSLATE_OPENING_TAG) { - upd_msg.replace(dif + match.getEnd() + 1, closing_tag_size, " "); - dif -= closing_tag_size - 1; + upd_msg.erase(dif + match.getStart() - opening_tag_size, opening_tag_size); + dif -= opening_tag_size; + + if (upd_msg.substr(dif + match.getEnd() + 1, closing_tag_size) == AZURE_NOTRANSLATE_CLOSING_TAG) + { + upd_msg.replace(dif + match.getEnd() + 1, closing_tag_size, " "); + dif -= closing_tag_size - 1; + } } + mesg.erase(match.getStart(), match.getUrl().size()); + dif += match.getUrl().size(); } - mesg.erase(match.getStart(), match.getUrl().size()); - dif += match.getUrl().size(); + return upd_msg; } - return upd_msg; + + return mesg; } /*static*/ diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index 870fd54441..1de5c02f74 100644 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -59,7 +59,7 @@ public : SERVICE_GOOGLE, } EService; - typedef boost::function<void(EService, bool)> KeyVerificationResult_fn; + typedef boost::function<void(EService, bool, S32)> KeyVerificationResult_fn; typedef boost::function<void(std::string , std::string )> TranslationSuccess_fn; typedef boost::function<void(int, std::string)> TranslationFailure_fn; diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml index b0e47798e9..d095451685 100644 --- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml @@ -9,8 +9,8 @@ title="CHAT TRANSLATION SETTINGS" width="485"> - <string name="azure_api_key_not_verified">Azure service identifier not verified. Please try again.</string> - <string name="google_api_key_not_verified">Google API key not verified. Please try again.</string> + <string name="azure_api_key_not_verified">Azure service identifier not verified. Status: [STATUS]. Please check your settings and try again.</string> + <string name="google_api_key_not_verified">Google API key not verified. Status: [STATUS]. Please check your key and try again.</string> <string name="azure_api_key_verified">Azure service identifier verified.</string> <string name="google_api_key_verified">Google API key verified.</string> @@ -147,6 +147,19 @@ top_pad="115" /> </radio_group> + <text + follows="top|right" + height="20" + layout="topleft" + left="185" + length="1" + name="google_links_text" + top_pad="-142" + type="string" + width="100"> + [https://learn.microsoft.com/en-us/azure/cognitive-services/translator/create-translator-resource Setup] + </text> + <text type="string" length="1" @@ -155,7 +168,7 @@ layout="topleft" left="70" name="azure_api_endoint_label" - top_pad="-115" + top_pad="8" width="85"> Endpoint: </text> -- cgit v1.2.3 From b2a06908859caa3d816ab1791fe2062142e2ccce Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Tue, 28 Feb 2023 00:51:25 +0200 Subject: SL-19209 Add default text for region field --- indra/newview/llfloatertranslationsettings.cpp | 5 +++-- indra/newview/lltranslate.cpp | 4 +--- indra/newview/skins/default/xui/en/floater_translation_settings.xml | 1 + 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index c99de47da0..e14227f490 100644 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -94,11 +94,11 @@ void LLFloaterTranslationSettings::onOpen(const LLSD& key) mTranslationServiceRadioGroup->setSelectedByValue(gSavedSettings.getString("TranslationService"), TRUE); LLSD azure_key = gSavedSettings.getLLSD("AzureTranslateAPIKey"); - if (azure_key.isMap()) + if (azure_key.isMap() && !azure_key["id"].asString().empty()) { mAzureAPIKeyEditor->setText(azure_key["id"].asString()); mAzureAPIKeyEditor->setTentative(false); - if (azure_key.has("region")) + if (azure_key.has("region") && !azure_key["region"].asString().empty()) { mAzureAPIRegionEditor->setText(azure_key["region"].asString()); mAzureAPIRegionEditor->setTentative(false); @@ -113,6 +113,7 @@ void LLFloaterTranslationSettings::onOpen(const LLSD& key) else { mAzureAPIKeyEditor->setTentative(TRUE); + mAzureAPIRegionEditor->setTentative(true); mAzureKeyVerified = FALSE; } diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index b0c4418ae9..f84c660c0d 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -229,8 +229,6 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s LL_INFOS("Translate") << "No translation URL" << LL_ENDL; return; } - LL_DEBUGS("Translate") << "Message: " << msg << LL_ENDL; - LL_DEBUGS("Translate") << "Requesting: " << url << LL_ENDL; LLSD result = sendMessageAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url, msg); @@ -646,7 +644,7 @@ bool LLAzureTranslationHandler::checkVerificationResponse( } // Expected: "{\"error\":{\"code\":400000,\"message\":\"One of the request inputs is not valid.\"}}" - // But for now just verify response is a valid json with an error + // But for now just verify response is a valid json Json::Value root; Json::Reader reader; diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml index d095451685..a5154d99ec 100644 --- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml @@ -246,6 +246,7 @@ Region: </text> <line_editor + default_text="Can be left empty for global services" follows="top|left" height="20" layout="topleft" -- cgit v1.2.3 From 89afd1cd4838022267f117efb65939c04c35f3da Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Tue, 28 Feb 2023 17:43:44 +0200 Subject: D580 Fix coding policy failures --- indra/newview/llpanelface.h | 1126 +++++++++++++++++++++---------------------- 1 file changed, 563 insertions(+), 563 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 787eb0c51b..aaf8eddaf7 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -1,563 +1,563 @@ -/** - * @file llpanelface.h - * @brief Panel in the tools floater for editing face textures, colors, etc. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLPANELFACE_H -#define LL_LLPANELFACE_H - -#include "v4color.h" -#include "llpanel.h" -#include "llmaterial.h" -#include "llmaterialmgr.h" -#include "lltextureentry.h" -#include "llselectmgr.h" - -class LLButton; -class LLCheckBoxCtrl; -class LLColorSwatchCtrl; -class LLComboBox; -class LLInventoryItem; -class LLLineEditor; -class LLSpinCtrl; -class LLTextBox; -class LLTextureCtrl; -class LLUICtrl; -class LLViewerObject; -class LLFloater; -class LLMaterialID; -class LLMediaCtrl; -class LLMenuButton; - -// Represents an edit for use in replicating the op across one or more materials in the selection set. -// -// The apply function optionally performs the edit which it implements -// as a functor taking Data that calls member func MaterialFunc taking SetValueType -// on an instance of the LLMaterial class. -// -// boost who? -// -template< - typename DataType, - typename SetValueType, - void (LLMaterial::*MaterialEditFunc)(SetValueType data) > -class LLMaterialEditFunctor -{ -public: - LLMaterialEditFunctor(const DataType& data) : _data(data) {} - virtual ~LLMaterialEditFunctor() {} - virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); } - DataType _data; -}; - -template< - typename DataType, - DataType (LLMaterial::*MaterialGetFunc)() > -class LLMaterialGetFunctor -{ -public: - LLMaterialGetFunctor() {} - virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); } -}; - -template< - typename DataType, - DataType (LLTextureEntry::*TEGetFunc)() > -class LLTEGetFunctor -{ -public: - LLTEGetFunctor() {} - virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); } -}; - -class LLPanelFace : public LLPanel -{ -public: - virtual BOOL postBuild(); - LLPanelFace(); - virtual ~LLPanelFace(); - - void refresh(); - void refreshMedia(); - void unloadMedia(); - - /*virtual*/ void draw(); - - LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) - { - LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); - llassert_always(new_material); - - // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture - // - new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode()); - return new_material; - } - - LLRender::eTexIndex getTextureChannelToEdit(); - -protected: - void navigateToTitleMedia(const std::string url); - bool selectedMediaEditable(); - void clearMediaSettings(); - void updateMediaSettings(); - void updateMediaTitle(); - - void getState(); - - void sendTexture(); // applies and sends texture - void sendTextureInfo(); // applies and sends texture scale, offset, etc. - void sendColor(); // applies and sends color - void sendAlpha(); // applies and sends transparency - void sendBump(U32 bumpiness); // applies and sends bump map - void sendTexGen(); // applies and sends bump map - void sendShiny(U32 shininess); // applies and sends shininess - void sendFullbright(); // applies and sends full bright - void sendGlow(); - void alignTestureLayer(); - - void updateCopyTexButton(); - - // this function is to return TRUE if the drag should succeed. - static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item); - - void onCommitTexture(const LLSD& data); - void onCancelTexture(const LLSD& data); - void onSelectTexture(const LLSD& data); - void onCommitSpecularTexture(const LLSD& data); - void onCancelSpecularTexture(const LLSD& data); - void onSelectSpecularTexture(const LLSD& data); - void onCommitNormalTexture(const LLSD& data); - void onCancelNormalTexture(const LLSD& data); - void onSelectNormalTexture(const LLSD& data); - void onCommitColor(const LLSD& data); - void onCommitShinyColor(const LLSD& data); - void onCommitAlpha(const LLSD& data); - void onCancelColor(const LLSD& data); - void onCancelShinyColor(const LLSD& data); - void onSelectColor(const LLSD& data); - void onSelectShinyColor(const LLSD& data); - - void onCloseTexturePicker(const LLSD& data); - - static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); - static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); - - // Make UI reflect state of currently selected material (refresh) - // and UI mode (e.g. editing normal map v diffuse map) - // - // @param force_set_values forces spinners to set value even if they are focused - void updateUI(bool force_set_values = false); - - // Convenience func to determine if all faces in selection have - // identical planar texgen settings during edits - // - bool isIdenticalPlanarTexgen(); - - // Callback funcs for individual controls - // - static void onCommitTextureInfo(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureScaleX(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureScaleY(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureRot(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureOffsetX(LLUICtrl* ctrl, void* userdata); - static void onCommitTextureOffsetY(LLUICtrl* ctrl, void* userdata); - - static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata); - - static void syncRepeatX(LLPanelFace* self, F32 scaleU); - static void syncRepeatY(LLPanelFace* self, F32 scaleV); - static void syncOffsetX(LLPanelFace* self, F32 offsetU); - static void syncOffsetY(LLPanelFace* self, F32 offsetV); - static void syncMaterialRot(LLPanelFace* self, F32 rot, int te = -1); - - static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata); - - static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata); - - static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata); - static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata); - static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata); - static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata); - static void onCommitBump( LLUICtrl* ctrl, void* userdata); - static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); - static void onCommitShiny( LLUICtrl* ctrl, void* userdata); - static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); - static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); - static void onCommitGlow( LLUICtrl* ctrl, void *userdata); - static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); - static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); - static void onClickAutoFix(void*); - static void onAlignTexture(void*); - -public: // needs to be accessible to selection manager - void onCopyColor(); // records all selected faces - void onPasteColor(); // to specific face - void onPasteColor(LLViewerObject* objectp, S32 te); // to specific face - void onCopyTexture(); - void onPasteTexture(); - void onPasteTexture(LLViewerObject* objectp, S32 te); - -protected: - void menuDoToSelected(const LLSD& userdata); - bool menuEnableItem(const LLSD& userdata); - - static F32 valueGlow(LLViewerObject* object, S32 face); - - - -private: - bool isAlpha() { return mIsAlpha; } - - // Convenience funcs to keep the visual flack to a minimum - // - LLUUID getCurrentNormalMap(); - LLUUID getCurrentSpecularMap(); - U32 getCurrentShininess(); - U32 getCurrentBumpiness(); - U8 getCurrentDiffuseAlphaMode(); - U8 getCurrentAlphaMaskCutoff(); - U8 getCurrentEnvIntensity(); - U8 getCurrentGlossiness(); - F32 getCurrentBumpyRot(); - F32 getCurrentBumpyScaleU(); - F32 getCurrentBumpyScaleV(); - F32 getCurrentBumpyOffsetU(); - F32 getCurrentBumpyOffsetV(); - F32 getCurrentShinyRot(); - F32 getCurrentShinyScaleU(); - F32 getCurrentShinyScaleV(); - F32 getCurrentShinyOffsetU(); - F32 getCurrentShinyOffsetV(); - - LLComboBox *mComboMatMedia; - LLMediaCtrl *mTitleMedia; - LLTextBox *mTitleMediaText; - - // Update visibility of controls to match current UI mode - // (e.g. materials vs media editing) - // - // Do NOT call updateUI from within this function. - // - void updateVisibility(); - - // Hey look everyone, a type-safe alternative to copy and paste! :) - // - - // Update material parameters by applying 'edit_func' to selected TEs - // - template< - typename DataType, - typename SetValueType, - void (LLMaterial::*MaterialEditFunc)(SetValueType data) > - static void edit(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID()) - { - LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data); - struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor - { - LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp, const LLUUID &only_for_object_id) : _panel(panel), _edit(editp), _only_for_object_id(only_for_object_id) {} - virtual ~LLSelectedTEEditMaterial() {}; - virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) - { - if (_edit && (_only_for_object_id.isNull() || _only_for_object_id == object->getID())) - { - LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material); - llassert_always(new_material); - - // Determine correct alpha mode for current diffuse texture - // (i.e. does it have an alpha channel that makes alpha mode useful) - // - // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329) - // need to get per-face answer to this question for sane alpha mode retention on updates. - // - bool is_alpha_face = object->isImageAlphaBlended(face); - - // need to keep this original answer for valid comparisons in logic below - // - U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - - U8 default_alpha_mode = original_default_alpha_mode; - - if (!current_material.isNull()) - { - default_alpha_mode = current_material->getDiffuseAlphaMode(); - } - - // Insure we don't inherit the default of blend by accident... - // this will be stomped by a legit request to change the alpha mode by the apply() below - // - new_material->setDiffuseAlphaMode(default_alpha_mode); - - // Do "It"! - // - _edit->apply(new_material); - - U32 new_alpha_mode = new_material->getDiffuseAlphaMode(); - LLUUID new_normal_map_id = new_material->getNormalID(); - LLUUID new_spec_map_id = new_material->getSpecularID(); - - if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face) - { - new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - } - - bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode); - bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); - - if (!is_need_material) - { - LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; - LLMaterialMgr::getInstance()->remove(object->getID(),face); - new_material = NULL; - } - else - { - LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL; - LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material); - } - - object->setTEMaterialParams(face, new_material); - return new_material; - } - return NULL; - } - LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit; - LLPanelFace *_panel; - const LLUUID & _only_for_object_id; - } editor(p, &edit, only_for_object_id); - LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te); - } - - template< - typename DataType, - typename ReturnType, - ReturnType (LLMaterial::* const MaterialGetFunc)() const > - static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) - { - DataType data_value; - struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType> - { - GetTEMaterialVal(DataType default_value) : _default(default_value) {} - virtual ~GetTEMaterialVal() {} - - DataType get(LLViewerObject* object, S32 face) - { - DataType ret = _default; - LLMaterialPtr material_ptr; - LLTextureEntry* tep = object ? object->getTE(face) : NULL; - if (tep) - { - material_ptr = tep->getMaterialParams(); - if (!material_ptr.isNull()) - { - ret = (material_ptr->*(MaterialGetFunc))(); - } - } - return ret; - } - DataType _default; - } GetFunc(default_value); - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance); - data_to_return = data_value; - } - - template< - typename DataType, - typename ReturnType, // some kids just have to different... - ReturnType (LLTextureEntry::* const TEGetFunc)() const > - static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) - { - DataType data_value; - struct GetTEVal : public LLSelectedTEGetFunctor<DataType> - { - GetTEVal(DataType default_value) : _default(default_value) {} - virtual ~GetTEVal() {} - - DataType get(LLViewerObject* object, S32 face) { - LLTextureEntry* tep = object ? object->getTE(face) : NULL; - return tep ? ((tep->*(TEGetFunc))()) : _default; - } - DataType _default; - } GetTEValFunc(default_value); - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance ); - data_to_return = data_value; - } - - // Update vis and enabling of specific subsets of controls based on material params - // (e.g. hide the spec controls if no spec texture is applied) - // - void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false); - void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false); - void updateAlphaControls(); - - /* - * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object. - * If agent selects texture which is not allowed to be applied for the currently selected object, - * all controls of the floater texture picker which allow to apply the texture will be disabled. - */ - void onTextureSelectionChanged(LLInventoryItem* itemp); - - LLMenuButton* mMenuClipboardColor; - LLMenuButton* mMenuClipboardTexture; - - bool mIsAlpha; - - /* These variables interlock processing of materials updates sent to - * the sim. mUpdateInFlight is set to flag that an update has been - * sent to the sim and not acknowledged yet, and cleared when an - * update is received from the sim. mUpdatePending is set when - * there's an update in flight and another UI change has been made - * that needs to be sent as a materials update, and cleared when the - * update is sent. This prevents the sim from getting spammed with - * update messages when, for example, the user holds down the - * up-arrow on a spinner, and avoids running afoul of its throttle. - */ - bool mUpdateInFlight; - bool mUpdatePending; - - LLSD mClipboardParams; - - LLSD mMediaSettings; - bool mNeedMediaTitle; - -public: - #if defined(DEF_GET_MAT_STATE) - #undef DEF_GET_MAT_STATE - #endif - - #if defined(DEF_GET_TE_STATE) - #undef DEF_GET_TE_STATE - #endif - - #if defined(DEF_EDIT_MAT_STATE) - DEF_EDIT_MAT_STATE - #endif - - // Accessors for selected TE material state - // - #define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue,HasTolerance,Tolerance) \ - static void MaterialMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance) \ - { \ - getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance); \ - } - - // Mutators for selected TE material - // - #define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc) \ - static void MaterialMemberFunc(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID()) \ - { \ - edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p, data, te, only_for_object_id); \ - } - - // Accessors for selected TE state proper (legacy settings etc) - // - #define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue,HasTolerance,Tolerance) \ - static void TexEntryMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance) \ - { \ - getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance); \ - } - - class LLSelectedTEMaterial - { - public: - static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material); - static void getMaxSpecularRepeats(F32& repeats, bool& identical); - static void getMaxNormalRepeats(F32& repeats, bool& identical); - static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); - - DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null, false, LLUUID::null) - DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null, false, LLUUID::null) - DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f, true, 0.001f) - - DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f, true, 0.001f) - DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f, true, 0.001f) - - DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode); - DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); - - DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX); - DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY); - DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX); - DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY); - DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation); - - DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY); - DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation); - - DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity); - DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent); - - DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); - DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); - DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); - }; - - class LLSelectedTE - { - public: - static void getFace(class LLFace*& face_to_return, bool& identical_face); - static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face); - static void getTexId(LLUUID& id, bool& identical); - static void getObjectScaleS(F32& scale_s, bool& identical); - static void getObjectScaleT(F32& scale_t, bool& identical); - static void getMaxDiffuseRepeats(F32& repeats, bool& identical); - - DEF_GET_TE_STATE(U8,U8,getBumpmap,0, false, 0) - DEF_GET_TE_STATE(U8,U8,getShiny,0, false, 0) - DEF_GET_TE_STATE(U8,U8,getFullbright,0, false, 0) - DEF_GET_TE_STATE(F32,F32,getRotation,0.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f, true, 0.001f) - DEF_GET_TE_STATE(F32,F32,getGlow,0.0f, true, 0.001f) - DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT, false, LLTextureEntry::TEX_GEN_DEFAULT) - DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white, false, LLColor4::black); - }; -}; - -#endif - +/** + * @file llpanelface.h + * @brief Panel in the tools floater for editing face textures, colors, etc. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELFACE_H +#define LL_LLPANELFACE_H + +#include "v4color.h" +#include "llpanel.h" +#include "llmaterial.h" +#include "llmaterialmgr.h" +#include "lltextureentry.h" +#include "llselectmgr.h" + +class LLButton; +class LLCheckBoxCtrl; +class LLColorSwatchCtrl; +class LLComboBox; +class LLInventoryItem; +class LLLineEditor; +class LLSpinCtrl; +class LLTextBox; +class LLTextureCtrl; +class LLUICtrl; +class LLViewerObject; +class LLFloater; +class LLMaterialID; +class LLMediaCtrl; +class LLMenuButton; + +// Represents an edit for use in replicating the op across one or more materials in the selection set. +// +// The apply function optionally performs the edit which it implements +// as a functor taking Data that calls member func MaterialFunc taking SetValueType +// on an instance of the LLMaterial class. +// +// boost who? +// +template< + typename DataType, + typename SetValueType, + void (LLMaterial::*MaterialEditFunc)(SetValueType data) > +class LLMaterialEditFunctor +{ +public: + LLMaterialEditFunctor(const DataType& data) : _data(data) {} + virtual ~LLMaterialEditFunctor() {} + virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); } + DataType _data; +}; + +template< + typename DataType, + DataType (LLMaterial::*MaterialGetFunc)() > +class LLMaterialGetFunctor +{ +public: + LLMaterialGetFunctor() {} + virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); } +}; + +template< + typename DataType, + DataType (LLTextureEntry::*TEGetFunc)() > +class LLTEGetFunctor +{ +public: + LLTEGetFunctor() {} + virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); } +}; + +class LLPanelFace : public LLPanel +{ +public: + virtual BOOL postBuild(); + LLPanelFace(); + virtual ~LLPanelFace(); + + void refresh(); + void refreshMedia(); + void unloadMedia(); + + /*virtual*/ void draw(); + + LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) + { + LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); + llassert_always(new_material); + + // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture + // + new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode()); + return new_material; + } + + LLRender::eTexIndex getTextureChannelToEdit(); + +protected: + void navigateToTitleMedia(const std::string url); + bool selectedMediaEditable(); + void clearMediaSettings(); + void updateMediaSettings(); + void updateMediaTitle(); + + void getState(); + + void sendTexture(); // applies and sends texture + void sendTextureInfo(); // applies and sends texture scale, offset, etc. + void sendColor(); // applies and sends color + void sendAlpha(); // applies and sends transparency + void sendBump(U32 bumpiness); // applies and sends bump map + void sendTexGen(); // applies and sends bump map + void sendShiny(U32 shininess); // applies and sends shininess + void sendFullbright(); // applies and sends full bright + void sendGlow(); + void alignTestureLayer(); + + void updateCopyTexButton(); + + // this function is to return TRUE if the drag should succeed. + static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item); + + void onCommitTexture(const LLSD& data); + void onCancelTexture(const LLSD& data); + void onSelectTexture(const LLSD& data); + void onCommitSpecularTexture(const LLSD& data); + void onCancelSpecularTexture(const LLSD& data); + void onSelectSpecularTexture(const LLSD& data); + void onCommitNormalTexture(const LLSD& data); + void onCancelNormalTexture(const LLSD& data); + void onSelectNormalTexture(const LLSD& data); + void onCommitColor(const LLSD& data); + void onCommitShinyColor(const LLSD& data); + void onCommitAlpha(const LLSD& data); + void onCancelColor(const LLSD& data); + void onCancelShinyColor(const LLSD& data); + void onSelectColor(const LLSD& data); + void onSelectShinyColor(const LLSD& data); + + void onCloseTexturePicker(const LLSD& data); + + static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); + static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); + + // Make UI reflect state of currently selected material (refresh) + // and UI mode (e.g. editing normal map v diffuse map) + // + // @param force_set_values forces spinners to set value even if they are focused + void updateUI(bool force_set_values = false); + + // Convenience func to determine if all faces in selection have + // identical planar texgen settings during edits + // + bool isIdenticalPlanarTexgen(); + + // Callback funcs for individual controls + // + static void onCommitTextureInfo(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureScaleX(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureScaleY(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureRot(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureOffsetX(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureOffsetY(LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata); + + static void syncRepeatX(LLPanelFace* self, F32 scaleU); + static void syncRepeatY(LLPanelFace* self, F32 scaleV); + static void syncOffsetX(LLPanelFace* self, F32 offsetU); + static void syncOffsetY(LLPanelFace* self, F32 offsetV); + static void syncMaterialRot(LLPanelFace* self, F32 rot, int te = -1); + + static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata); + static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata); + static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata); + static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata); + static void onCommitBump( LLUICtrl* ctrl, void* userdata); + static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); + static void onCommitShiny( LLUICtrl* ctrl, void* userdata); + static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); + static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); + static void onCommitGlow( LLUICtrl* ctrl, void *userdata); + static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); + static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); + static void onClickAutoFix(void*); + static void onAlignTexture(void*); + +public: // needs to be accessible to selection manager + void onCopyColor(); // records all selected faces + void onPasteColor(); // to specific face + void onPasteColor(LLViewerObject* objectp, S32 te); // to specific face + void onCopyTexture(); + void onPasteTexture(); + void onPasteTexture(LLViewerObject* objectp, S32 te); + +protected: + void menuDoToSelected(const LLSD& userdata); + bool menuEnableItem(const LLSD& userdata); + + static F32 valueGlow(LLViewerObject* object, S32 face); + + + +private: + bool isAlpha() { return mIsAlpha; } + + // Convenience funcs to keep the visual flack to a minimum + // + LLUUID getCurrentNormalMap(); + LLUUID getCurrentSpecularMap(); + U32 getCurrentShininess(); + U32 getCurrentBumpiness(); + U8 getCurrentDiffuseAlphaMode(); + U8 getCurrentAlphaMaskCutoff(); + U8 getCurrentEnvIntensity(); + U8 getCurrentGlossiness(); + F32 getCurrentBumpyRot(); + F32 getCurrentBumpyScaleU(); + F32 getCurrentBumpyScaleV(); + F32 getCurrentBumpyOffsetU(); + F32 getCurrentBumpyOffsetV(); + F32 getCurrentShinyRot(); + F32 getCurrentShinyScaleU(); + F32 getCurrentShinyScaleV(); + F32 getCurrentShinyOffsetU(); + F32 getCurrentShinyOffsetV(); + + LLComboBox *mComboMatMedia; + LLMediaCtrl *mTitleMedia; + LLTextBox *mTitleMediaText; + + // Update visibility of controls to match current UI mode + // (e.g. materials vs media editing) + // + // Do NOT call updateUI from within this function. + // + void updateVisibility(); + + // Hey look everyone, a type-safe alternative to copy and paste! :) + // + + // Update material parameters by applying 'edit_func' to selected TEs + // + template< + typename DataType, + typename SetValueType, + void (LLMaterial::*MaterialEditFunc)(SetValueType data) > + static void edit(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID()) + { + LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data); + struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor + { + LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp, const LLUUID &only_for_object_id) : _panel(panel), _edit(editp), _only_for_object_id(only_for_object_id) {} + virtual ~LLSelectedTEEditMaterial() {}; + virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) + { + if (_edit && (_only_for_object_id.isNull() || _only_for_object_id == object->getID())) + { + LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material); + llassert_always(new_material); + + // Determine correct alpha mode for current diffuse texture + // (i.e. does it have an alpha channel that makes alpha mode useful) + // + // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329) + // need to get per-face answer to this question for sane alpha mode retention on updates. + // + bool is_alpha_face = object->isImageAlphaBlended(face); + + // need to keep this original answer for valid comparisons in logic below + // + U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + U8 default_alpha_mode = original_default_alpha_mode; + + if (!current_material.isNull()) + { + default_alpha_mode = current_material->getDiffuseAlphaMode(); + } + + // Insure we don't inherit the default of blend by accident... + // this will be stomped by a legit request to change the alpha mode by the apply() below + // + new_material->setDiffuseAlphaMode(default_alpha_mode); + + // Do "It"! + // + _edit->apply(new_material); + + U32 new_alpha_mode = new_material->getDiffuseAlphaMode(); + LLUUID new_normal_map_id = new_material->getNormalID(); + LLUUID new_spec_map_id = new_material->getSpecularID(); + + if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face) + { + new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); + } + + bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode); + bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); + + if (!is_need_material) + { + LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; + LLMaterialMgr::getInstance()->remove(object->getID(),face); + new_material = NULL; + } + else + { + LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL; + LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material); + } + + object->setTEMaterialParams(face, new_material); + return new_material; + } + return NULL; + } + LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit; + LLPanelFace *_panel; + const LLUUID & _only_for_object_id; + } editor(p, &edit, only_for_object_id); + LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te); + } + + template< + typename DataType, + typename ReturnType, + ReturnType (LLMaterial::* const MaterialGetFunc)() const > + static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) + { + DataType data_value; + struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType> + { + GetTEMaterialVal(DataType default_value) : _default(default_value) {} + virtual ~GetTEMaterialVal() {} + + DataType get(LLViewerObject* object, S32 face) + { + DataType ret = _default; + LLMaterialPtr material_ptr; + LLTextureEntry* tep = object ? object->getTE(face) : NULL; + if (tep) + { + material_ptr = tep->getMaterialParams(); + if (!material_ptr.isNull()) + { + ret = (material_ptr->*(MaterialGetFunc))(); + } + } + return ret; + } + DataType _default; + } GetFunc(default_value); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance); + data_to_return = data_value; + } + + template< + typename DataType, + typename ReturnType, // some kids just have to different... + ReturnType (LLTextureEntry::* const TEGetFunc)() const > + static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) + { + DataType data_value; + struct GetTEVal : public LLSelectedTEGetFunctor<DataType> + { + GetTEVal(DataType default_value) : _default(default_value) {} + virtual ~GetTEVal() {} + + DataType get(LLViewerObject* object, S32 face) { + LLTextureEntry* tep = object ? object->getTE(face) : NULL; + return tep ? ((tep->*(TEGetFunc))()) : _default; + } + DataType _default; + } GetTEValFunc(default_value); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance ); + data_to_return = data_value; + } + + // Update vis and enabling of specific subsets of controls based on material params + // (e.g. hide the spec controls if no spec texture is applied) + // + void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false); + void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false); + void updateAlphaControls(); + + /* + * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object. + * If agent selects texture which is not allowed to be applied for the currently selected object, + * all controls of the floater texture picker which allow to apply the texture will be disabled. + */ + void onTextureSelectionChanged(LLInventoryItem* itemp); + + LLMenuButton* mMenuClipboardColor; + LLMenuButton* mMenuClipboardTexture; + + bool mIsAlpha; + + /* These variables interlock processing of materials updates sent to + * the sim. mUpdateInFlight is set to flag that an update has been + * sent to the sim and not acknowledged yet, and cleared when an + * update is received from the sim. mUpdatePending is set when + * there's an update in flight and another UI change has been made + * that needs to be sent as a materials update, and cleared when the + * update is sent. This prevents the sim from getting spammed with + * update messages when, for example, the user holds down the + * up-arrow on a spinner, and avoids running afoul of its throttle. + */ + bool mUpdateInFlight; + bool mUpdatePending; + + LLSD mClipboardParams; + + LLSD mMediaSettings; + bool mNeedMediaTitle; + +public: + #if defined(DEF_GET_MAT_STATE) + #undef DEF_GET_MAT_STATE + #endif + + #if defined(DEF_GET_TE_STATE) + #undef DEF_GET_TE_STATE + #endif + + #if defined(DEF_EDIT_MAT_STATE) + DEF_EDIT_MAT_STATE + #endif + + // Accessors for selected TE material state + // + #define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue,HasTolerance,Tolerance) \ + static void MaterialMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance) \ + { \ + getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance); \ + } + + // Mutators for selected TE material + // + #define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc) \ + static void MaterialMemberFunc(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID()) \ + { \ + edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p, data, te, only_for_object_id); \ + } + + // Accessors for selected TE state proper (legacy settings etc) + // + #define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue,HasTolerance,Tolerance) \ + static void TexEntryMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance) \ + { \ + getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance); \ + } + + class LLSelectedTEMaterial + { + public: + static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material); + static void getMaxSpecularRepeats(F32& repeats, bool& identical); + static void getMaxNormalRepeats(F32& repeats, bool& identical); + static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); + + DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null, false, LLUUID::null) + DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null, false, LLUUID::null) + DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f, true, 0.001f) + + DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f, true, 0.001f) + DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f, true, 0.001f) + + DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode); + DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); + + DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX); + DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation); + + DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation); + + DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity); + DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent); + + DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); + DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); + DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); + }; + + class LLSelectedTE + { + public: + static void getFace(class LLFace*& face_to_return, bool& identical_face); + static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face); + static void getTexId(LLUUID& id, bool& identical); + static void getObjectScaleS(F32& scale_s, bool& identical); + static void getObjectScaleT(F32& scale_t, bool& identical); + static void getMaxDiffuseRepeats(F32& repeats, bool& identical); + + DEF_GET_TE_STATE(U8,U8,getBumpmap,0, false, 0) + DEF_GET_TE_STATE(U8,U8,getShiny,0, false, 0) + DEF_GET_TE_STATE(U8,U8,getFullbright,0, false, 0) + DEF_GET_TE_STATE(F32,F32,getRotation,0.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f, true, 0.001f) + DEF_GET_TE_STATE(F32,F32,getGlow,0.0f, true, 0.001f) + DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT, false, LLTextureEntry::TEX_GEN_DEFAULT) + DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white, false, LLColor4::black); + }; +}; + +#endif + -- cgit v1.2.3 From cdb3c018af9fc75064dc63537e61c5df567c331a Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Wed, 1 Mar 2023 10:26:34 -0500 Subject: SL-19336 Unload avatar and group icons from memory when not visible to reduce memory pressure on extremely large friends lists --- indra/llui/lliconctrl.cpp | 26 ++++++++++++++++++++++++++ indra/llui/lliconctrl.h | 3 +++ indra/llui/lltextbase.cpp | 4 ++-- indra/llui/llview.h | 1 + 4 files changed, 32 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp index e01aba402e..2791377a5e 100644 --- a/indra/llui/lliconctrl.cpp +++ b/indra/llui/lliconctrl.cpp @@ -37,6 +37,8 @@ #include "lluiimage.h" #include "llwindow.h" +#include "llgltexture.h" + static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon"); LLIconCtrl::Params::Params() @@ -94,6 +96,22 @@ BOOL LLIconCtrl::handleHover(S32 x, S32 y, MASK mask) return LLUICtrl::handleHover(x, y, mask); } +void LLIconCtrl::onVisibilityChange(BOOL new_visibility) +{ + LLUICtrl::onVisibilityChange(new_visibility); + if (mPriority == LLGLTexture::BOOST_ICON) + { + if (new_visibility) + { + loadImage(getValue(), mPriority); + } + else + { + mImagep = nullptr; + } + } +} + // virtual // value might be a string or a UUID void LLIconCtrl::setValue(const LLSD& value) @@ -110,6 +128,14 @@ void LLIconCtrl::setValue(const LLSD& value, S32 priority) tvalue = LLSD(LLUUID(value.asString())); } LLUICtrl::setValue(tvalue); + + loadImage(tvalue, priority); +} + +void LLIconCtrl::loadImage(const LLSD& tvalue, S32 priority) +{ + if(mPriority == LLGLTexture::BOOST_ICON && !getVisible()) return; + if (tvalue.isUUID()) { mImagep = LLUI::getUIImageByID(tvalue.asUUID(), priority); diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h index 9c3b517bca..5d6c544571 100644 --- a/indra/llui/lliconctrl.h +++ b/indra/llui/lliconctrl.h @@ -72,6 +72,7 @@ public: virtual BOOL handleHover(S32 x, S32 y, MASK mask); // lluictrl overrides + void onVisibilityChange(BOOL new_visibility); virtual void setValue(const LLSD& value ); std::string getImageName() const; @@ -95,6 +96,8 @@ protected: bool mInteractable; private: + void loadImage(const LLSD& value, S32 priority); + LLUIColor mColor; LLPointer<LLUIImage> mImagep; }; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 82a3c01c6d..3d8cf74855 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1356,9 +1356,9 @@ void LLTextBase::draw() drawCursor(); } - mDocumentView->setVisible(FALSE); + mDocumentView->setVisibleDirect(FALSE); LLUICtrl::draw(); - mDocumentView->setVisible(TRUE); + mDocumentView->setVisibleDirect(TRUE); } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index bec45df78a..8aa97aac39 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -287,6 +287,7 @@ public: void setAllChildrenEnabled(BOOL b); virtual void setVisible(BOOL visible); + void setVisibleDirect(BOOL visible) { mVisible = visible; } const BOOL& getVisible() const { return mVisible; } virtual void setEnabled(BOOL enabled); BOOL getEnabled() const { return mEnabled; } -- cgit v1.2.3 From 4885ea4fba4c998960d0817e94e69cddd7cd189a Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy <alihatskiy@productengine.com> Date: Tue, 7 Mar 2023 01:44:39 +0200 Subject: INTL-483 Fixed PT translation --- indra/newview/skins/default/xui/pt/panel_edit_hair.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/skins/default/xui/pt/panel_edit_hair.xml b/indra/newview/skins/default/xui/pt/panel_edit_hair.xml index 13f1f892f9..e9750a1c2e 100644 --- a/indra/newview/skins/default/xui/pt/panel_edit_hair.xml +++ b/indra/newview/skins/default/xui/pt/panel_edit_hair.xml @@ -7,7 +7,7 @@ <accordion name="wearable_accordion"> <accordion_tab name="hair_color_tab" title="Cor"/> <accordion_tab name="hair_style_tab" title="Estilo"/> - <accordion_tab name="hair_eyebrows_tab" title="Sombrancelhas"/> + <accordion_tab name="hair_eyebrows_tab" title="Sobrancelhas"/> <accordion_tab name="hair_facial_tab" title="Faciais"/> </accordion> </panel> -- cgit v1.2.3 From 5cbbfba46f11be76d1d5eb088f5448992d5e3bed Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko <maximnproductengine@lindenlab.com> Date: Thu, 9 Mar 2023 18:11:48 +0200 Subject: SL-19367 FIXED Failing to detach temporary mesh attachment --- indra/newview/llpanelwearing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 3347c40687..bc9f0cef83 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -566,7 +566,7 @@ void LLPanelWearing::onRemoveAttachment() { LLSelectMgr::getInstance()->deselectAll(); LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]); - LLSelectMgr::getInstance()->sendDropAttachment(); + LLSelectMgr::getInstance()->sendDetach(); } } -- cgit v1.2.3 From 1a8c03cfda1863889b21b25a1f127bc541464f5b Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> Date: Wed, 15 Mar 2023 17:23:05 +0100 Subject: SL-19085 Save Wiki-style URL as link when creating the Pick with an existing link in About Land --- indra/newview/llpanelprofilepicks.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra') diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index 45d0252e4f..db3a3c6de5 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -529,6 +529,7 @@ void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id) pick_name = parcel->getName(); pick_desc = parcel->getDesc(); snapshot_id = parcel->getSnapshotID(); + mPickDescription->setParseHTML(false); } LLViewerRegion* region = gAgent.getRegion(); -- cgit v1.2.3 From d2a8a3bd53f011b7137717ece39f01b5242bb45a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Thu, 16 Mar 2023 00:04:11 +0200 Subject: SL-18964 Smoke texture can fail to load Debt from SL-18221. Keep init together, after we got the cap; texture should finish loading before it's needed. --- indra/newview/lldrawpoolalpha.cpp | 7 +------ indra/newview/llviewertexture.cpp | 7 ------- indra/newview/llviewertexturelist.cpp | 2 ++ 3 files changed, 3 insertions(+), 13 deletions(-) (limited to 'indra') diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index d4797321bb..f91069185a 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -281,12 +281,7 @@ void LLDrawPoolAlpha::renderDebugAlpha() gHighlightProgram.bind(); gGL.diffuseColor4f(1, 0, 0, 1); - // SL-18964 : The creating of this texture was moved here from LLViewerTextureManager::init() to make the texture transparent before adding to cache - if (!LLViewerFetchedTexture::sSmokeImagep) - { - LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); - LLViewerFetchedTexture::sSmokeImagep->setNoDelete(); - } + LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f * 1024.f); gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sSmokeImagep); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 0d82aced23..df65fe8fb8 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -402,13 +402,6 @@ void LLViewerTextureManager::init() LLViewerFetchedTexture::sDefaultImagep->dontDiscard(); LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER); -#if 0 - // When called first time after clearing cache this call creates (and adds to cache) an opaque texture instead of transparent - // SL-18964 : The creating of this texture was moved to LLDrawPoolAlpha::renderDebugAlpha() - LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); - LLViewerFetchedTexture::sSmokeImagep->setNoDelete(); -#endif - image_raw = new LLImageRaw(32,32,3); data = image_raw->getData(); diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 93ae1670c8..52e6a9a2df 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -228,6 +228,8 @@ void LLViewerTextureList::doPrefetchImages() LLViewerTextureManager::getFetchedTexture(IMG_SHOT); LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF); + LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); + LLViewerFetchedTexture::sSmokeImagep->setNoDelete(); LLStandardBumpmap::addstandard(); -- cgit v1.2.3 From f5adfae1ade864d80f630855bc65bf65f5ae7ece Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> Date: Sun, 19 Mar 2023 05:07:44 +0100 Subject: SL-19099 The long name of the item is out of bounds on the Editing Tools/Content tab --- indra/llui/llfolderviewitem.cpp | 2 +- indra/llui/llpanel.h | 1 + indra/newview/llpanelobjectinventory.cpp | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index eba93beed9..e2b5279aab 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -395,7 +395,7 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height ) // it is purely visual, so it is fine to do at our laisure refreshSuffix(); } - mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight; + mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight; mLabelWidthDirty = false; } diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index b8f47ef6ba..8018365d3e 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -127,6 +127,7 @@ public: virtual void clearCtrls(); // overridden in LLPanelObject and LLPanelVolume // Border controls + const LLViewBorder* getBorder() const { return mBorder; } void addBorder( LLViewBorder::Params p); void addBorder(); void removeBorder(); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index bd40c9dd2b..6a82a3b35d 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1368,7 +1368,8 @@ void LLPanelObjectInventory::reset() LLEditMenuHandler::gEditMenuHandler = mFolders; } - LLRect scroller_rect(0, getRect().getHeight(), getRect().getWidth(), 0); + int offset = hasBorder() ? getBorder()->getBorderWidth() << 1 : 0; + LLRect scroller_rect(0, getRect().getHeight() - offset, getRect().getWidth() - offset, 0); LLScrollContainer::Params scroll_p; scroll_p.name("task inventory scroller"); scroll_p.rect(scroller_rect); -- cgit v1.2.3 From c23353cfc3f0a8c580c99332e47c288758a023c8 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> Date: Sun, 19 Mar 2023 17:50:13 +0100 Subject: SL-19417 Improve colors.xml behavior --- indra/llui/lluicolortable.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index 244f0c6f00..b84bb13edb 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -200,7 +200,6 @@ LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& defa void LLUIColorTable::setColor(const std::string& name, const LLColor4& color) { setColor(name, color, mUserSetColors); - setColor(name, color, mLoadedColors); } bool LLUIColorTable::loadFromSettings() @@ -229,6 +228,11 @@ void LLUIColorTable::saveUserSettings() const it != mUserSetColors.end(); ++it) { + // Compare user color value with the default value, skip if equal + string_color_map_t::const_iterator itd = mLoadedColors.find(it->first); + if(itd != mUserSetColors.end() && itd->second == it->second) + continue; + ColorEntryParams color_entry; color_entry.name = it->first; color_entry.color.value = it->second; -- cgit v1.2.3 From cf692c40b0b9f8d0d04cd10a02a84e3f697a2e99 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> Date: Mon, 20 Mar 2023 10:20:06 +0100 Subject: SL-18721: Faster viewer shutdown time since performance improvements can lead to perceived inventory loss due to cache corruption --- indra/llcommon/threadpool.cpp | 5 +++++ indra/llcommon/threadpool.h | 4 ++++ indra/llwindow/llwindowwin32.cpp | 3 +++ 3 files changed, 12 insertions(+) (limited to 'indra') diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index d5adf11264..4a7ead2110 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -39,6 +39,11 @@ void LL::ThreadPool::start() run(tname); }); } + + // Special workflow for LLWindowWin32Thread - it's close() should be called explicitly + if (mExplicitShutdown) + return; + // Listen on "LLApp", and when the app is shutting down, close the queue // and join the workers. LLEventPumps::instance().obtain("LLApp").listen( diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index f8eec3b457..0a5f14529b 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -59,6 +59,10 @@ namespace LL */ virtual void run(); + protected: + // LLWindowWin32Thread should set this flag to true + bool mExplicitShutdown { false }; + private: void run(const std::string& name); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 41f3042ace..afe26ec5a4 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4581,6 +4581,9 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList() inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread() : ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE) { + // Set this flag to true to avoid of implicit call of close() from start() + mExplicitShutdown = true; + ThreadPool::start(); } -- cgit v1.2.3 From e5b965c892154e5933b9cfe80ce750ff6f542620 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Mon, 20 Mar 2023 23:44:54 +0200 Subject: SL-19435 Bounce user back to login if caps are not present --- indra/newview/llstartup.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6883ead5ee..dd3b33982a 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1392,8 +1392,16 @@ bool idle_startup() } else if (regionp->capabilitiesError()) { - // Try to connect despite capabilities' error state - LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); + LL_WARNS("AppInit") << "Failed to get capabilities. Backing up to login screen!" << LL_ENDL; + if (gRememberPassword) + { + LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); + } + else + { + LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status); + } + reset_login(); } else { -- cgit v1.2.3 From b1fc17a50e9787163d8d984868050926ef7fa4dc Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> Date: Tue, 21 Mar 2023 01:17:43 +0100 Subject: SL-19348 Remove 'get mesh_rez_enabled' code in viewer --- indra/newview/llfloaterregioninfo.cpp | 14 -------------- indra/newview/llfloaterregioninfo.h | 1 - 2 files changed, 15 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 07d4dcae38..9fb4040f5f 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -317,7 +317,6 @@ void LLFloaterRegionInfo::onOpen(const LLSD& key) } refreshFromRegion(gAgent.getRegion()); requestRegionInfo(); - requestMeshRezInfo(); if (!mGodLevelChangeSlot.connected()) { @@ -1008,19 +1007,6 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L return false; } -void LLFloaterRegionInfo::requestMeshRezInfo() -{ - std::string sim_console_url = gAgent.getRegionCapability("SimConsoleAsync"); - - if (!sim_console_url.empty()) - { - std::string request_str = "get mesh_rez_enabled"; - - LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(sim_console_url, LLSD(request_str), - "Requested mesh_rez_enabled", "Error requesting mesh_rez_enabled"); - } -} - // setregioninfo // strings[0] = 'Y' - block terraform, 'N' - not // strings[1] = 'Y' - block fly, 'N' - not diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index c34dbb62e8..3eb39b250f 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -102,7 +102,6 @@ public: void onRegionChanged(); void requestRegionInfo(); - void requestMeshRezInfo(); void enableTopButtons(); void disableTopButtons(); -- cgit v1.2.3 From 275ad3fdabf8417376e01a4a994d4a78dba6f15f Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> Date: Tue, 21 Mar 2023 01:37:51 +0100 Subject: SL-19266 Potential Use-After-Free in LLImageGL::setImage --- indra/llrender/llimagegl.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 9dc140b5b9..465f30a343 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -859,9 +859,16 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32 stop_glerror(); if (prev_mip_data) - delete[] prev_mip_data; + { + if (prev_mip_data != cur_mip_data) + delete[] prev_mip_data; + prev_mip_data = nullptr; + } if (cur_mip_data) + { delete[] cur_mip_data; + cur_mip_data = nullptr; + } mGLTextureCreated = false; return FALSE; -- cgit v1.2.3 From d1b414e48b4faa8f0b6b68fc6cb16701137478fd Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> Date: Fri, 24 Mar 2023 21:10:12 +0100 Subject: SL-17045 LSL editor cursor position desynchronization --- indra/llrender/llfontgl.cpp | 24 +++++++++++++++--------- indra/llrender/llfontgl.h | 2 +- indra/llui/lltextbase.cpp | 6 +++--- indra/llui/lltextbase.h | 2 +- indra/newview/llscripteditor.cpp | 2 +- 5 files changed, 21 insertions(+), 15 deletions(-) (limited to 'indra') diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 1bf061bc8d..6f4f2ec62c 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -494,7 +494,7 @@ F32 LLFontGL::getWidthF32(const std::string& utf8text, S32 begin_offset, S32 max return getWidthF32(wtext.c_str(), begin_offset, max_chars); } -F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars) const +F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars, bool no_padding) const { const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL; @@ -517,12 +517,15 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars F32 advance = mFontFreetype->getXAdvance(fgi); - // for the last character we want to measure the greater of its width and xadvance values - // so keep track of the difference between these values for the each character we measure - // so we can fix things up at the end - width_padding = llmax( 0.f, // always use positive padding amount - width_padding - advance, // previous padding left over after advance of current character - (F32)(fgi->mWidth + fgi->mXBearing) - advance); // difference between width of this character and advance to next character + if (!no_padding) + { + // for the last character we want to measure the greater of its width and xadvance values + // so keep track of the difference between these values for the each character we measure + // so we can fix things up at the end + width_padding = llmax(0.f, // always use positive padding amount + width_padding - advance, // previous padding left over after advance of current character + (F32)(fgi->mWidth + fgi->mXBearing) - advance); // difference between width of this character and advance to next character + } cur_x += advance; llwchar next_char = wchars[i+1]; @@ -539,8 +542,11 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars cur_x = (F32)ll_round(cur_x); } - // add in extra pixels for last character's width past its xadvance - cur_x += width_padding; + if (!no_padding) + { + // add in extra pixels for last character's width past its xadvance + cur_x += width_padding; + } return cur_x / sScaleX; } diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 3b58a37d33..93c6b78ce8 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -138,7 +138,7 @@ public: F32 getWidthF32(const std::string& utf8text) const; F32 getWidthF32(const llwchar* wchars) const; F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars ) const; - F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars) const; + F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars, bool no_padding = false) const; // The following are called often, frequently with large buffers, so do not use a string interface diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 3d8cf74855..8732a7ce45 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -361,7 +361,7 @@ void LLTextBase::onValueChange(S32 start, S32 end) { } -std::vector<LLRect> LLTextBase::getSelctionRects() +std::vector<LLRect> LLTextBase::getSelectionRects() { // Nor supposed to be called without selection llassert(hasSelection()); @@ -458,7 +458,7 @@ void LLTextBase::drawSelectionBackground() // Draw selection even if we don't have keyboard focus for search/replace if (hasSelection() && !mLineInfoList.empty()) { - std::vector<LLRect> selection_rects = getSelctionRects(); + std::vector<LLRect> selection_rects = getSelectionRects(); // Draw the selection box (we're using a box instead of reversing the colors on the selected text). gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -3464,7 +3464,7 @@ bool LLNormalTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& w height = mFontHeight; const LLWString &text = getWText(); // if last character is a newline, then return true, forcing line break - width = mStyle->getFont()->getWidthF32(text.c_str(), mStart + first_char, num_chars); + width = mStyle->getFont()->getWidthF32(text.c_str(), mStart + first_char, num_chars, true); } return false; } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index e3cf56a5ee..3611ab0499 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -638,7 +638,7 @@ protected: return mLabel.getString() + getToolTip(); } - std::vector<LLRect> getSelctionRects(); + std::vector<LLRect> getSelectionRects(); protected: // text segmentation and flow diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 140cbbedbe..3278bd3aa9 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -187,7 +187,7 @@ void LLScriptEditor::drawSelectionBackground() // Draw selection even if we don't have keyboard focus for search/replace if( hasSelection() && !mLineInfoList.empty()) { - std::vector<LLRect> selection_rects = getSelctionRects(); + std::vector<LLRect> selection_rects = getSelectionRects(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); const LLColor4& color = mReadOnly ? mReadOnlyFgColor : mFgColor; -- cgit v1.2.3 From 01fd1cdddedc11cb6d9803a6606f54d069994a45 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Wed, 5 Apr 2023 22:32:12 +0300 Subject: SL-19522 Some .anim files fail to upload --- indra/llcharacter/llkeyframemotion.cpp | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 403d5bcf49..6cc4295fc8 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1399,6 +1399,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo // get number of joint motions //------------------------------------------------------------------------- U32 num_motions = 0; + S32 rotation_dupplicates = 0; + S32 position_dupplicates = 0; if (!dp.unpackU32(num_motions, "num_joints")) { LL_WARNS() << "can't read number of joints" @@ -1629,6 +1631,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo rCurve->mKeys[time] = rot_key; } + if (joint_motion->mRotationCurve.mNumKeys > joint_motion->mRotationCurve.mKeys.size()) + { + rotation_dupplicates++; + LL_INFOS() << "Motion: " << asset_id << " had dupplicate rotation keys that were removed" << LL_ENDL; + } + //--------------------------------------------------------------------- // scan position curve header //--------------------------------------------------------------------- @@ -1731,9 +1739,24 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo } } + if (joint_motion->mPositionCurve.mNumKeys > joint_motion->mPositionCurve.mKeys.size()) + { + position_dupplicates++; + } + joint_motion->mUsage = joint_state->getUsage(); } + if (rotation_dupplicates > 0) + { + LL_INFOS() << "Motion: " << asset_id << " had " << rotation_dupplicates << " dupplicate rotation keys that were removed" << LL_ENDL; + } + + if (position_dupplicates > 0) + { + LL_INFOS() << "Motion: " << asset_id << " had " << position_dupplicates << " dupplicate position keys that were removed" << LL_ENDL; + } + //------------------------------------------------------------------------- // get number of constraints //------------------------------------------------------------------------- @@ -2013,9 +2036,12 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const JointMotion* joint_motionp = mJointMotionList->getJointMotion(i); success &= dp.packString(joint_motionp->mJointName, "joint_name"); success &= dp.packS32(joint_motionp->mPriority, "joint_priority"); - success &= dp.packS32(joint_motionp->mRotationCurve.mNumKeys, "num_rot_keys"); + success &= dp.packS32(joint_motionp->mRotationCurve.mKeys.size(), "num_rot_keys"); - LL_DEBUGS("BVH") << "Joint " << joint_motionp->mJointName << LL_ENDL; + LL_DEBUGS("BVH") << "Joint " << i + << " name: " << joint_motionp->mJointName + << " Rotation keys: " << joint_motionp->mRotationCurve.mKeys.size() + << " Position keys: " << joint_motionp->mPositionCurve.mKeys.size() << LL_ENDL; for (RotationCurve::key_map_t::iterator iter = joint_motionp->mRotationCurve.mKeys.begin(); iter != joint_motionp->mRotationCurve.mKeys.end(); ++iter) { @@ -2037,7 +2063,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const LL_DEBUGS("BVH") << " rot: t " << rot_key.mTime << " angles " << rot_angles.mV[VX] <<","<< rot_angles.mV[VY] <<","<< rot_angles.mV[VZ] << LL_ENDL; } - success &= dp.packS32(joint_motionp->mPositionCurve.mNumKeys, "num_pos_keys"); + success &= dp.packS32(joint_motionp->mPositionCurve.mKeys.size(), "num_pos_keys"); for (PositionCurve::key_map_t::iterator iter = joint_motionp->mPositionCurve.mKeys.begin(); iter != joint_motionp->mPositionCurve.mKeys.end(); ++iter) { -- cgit v1.2.3 From 99a8c612d008531f64b2ff94713866adf2e91243 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Thu, 6 Apr 2023 01:20:51 +0300 Subject: SL-19536 Inventory isn't fetched automatically Just a 'hotfix' that won't conflict with further changes, should be properly resolved in DRTVWR-567 --- indra/newview/llstartup.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra') diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index dd3b33982a..c52fdf4bc1 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1905,6 +1905,7 @@ bool idle_startup() LLNotificationsUtil::add("InventoryUnusable"); } + LLInventoryModelBackgroundFetch::instance().start(); gInventory.createCommonSystemCategories(); // It's debatable whether this flag is a good idea - sets all -- cgit v1.2.3 From d7690a3f211949e9e3958902531424fc22e56542 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Thu, 6 Apr 2023 19:57:33 +0300 Subject: SL-19545 Shift Azure's 'Verify' button --- .../xui/en/floater_translation_settings.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'indra') diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml index a5154d99ec..dc3e072adf 100644 --- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml @@ -224,15 +224,6 @@ top_delta="-4" name="azure_api_key" width="210" /> - <button - follows="left|top" - height="23" - label="Verify" - layout="topleft" - left_pad="10" - name="verify_azure_api_key_btn" - top_delta="-2" - width="90" /> <text type="string" length="1" @@ -241,7 +232,7 @@ layout="topleft" left="70" name="azure_api_region_label" - top_pad="10" + top_pad="11" width="85"> Region: </text> @@ -255,6 +246,15 @@ top_delta="-4" name="azure_api_region" width="210" /> + <button + follows="left|top" + height="23" + label="Verify" + layout="topleft" + left_pad="10" + name="verify_azure_api_key_btn" + top_delta="-2" + width="90" /> <text follows="top|right" @@ -263,7 +263,7 @@ left="70" length="1" name="google_api_key_label" - top_pad="55" + top_pad="53" type="string" width="85"> Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API key]: -- cgit v1.2.3 From 6bef1ed8c336468519c9f5459445aeec26890f35 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Sat, 8 Apr 2023 15:17:19 +0300 Subject: SL-19204 Fix voice's coroutine crash Need to find a way to kill coroutines or to fobid using non static functions/members inside coroutines --- indra/newview/llvoicevivox.cpp | 48 +++++++++++++++++++++++------------------- indra/newview/llvoicevivox.h | 7 +++--- 2 files changed, 30 insertions(+), 25 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index c73f96da2d..3725510b6a 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -276,13 +276,13 @@ static void killGateway() /////////////////////////////////////////////////////////////////////////////////////////////// bool LLVivoxVoiceClient::sShuttingDown = false; +bool LLVivoxVoiceClient::sConnected = false; +LLPumpIO *LLVivoxVoiceClient::sPump = nullptr; LLVivoxVoiceClient::LLVivoxVoiceClient() : mSessionTerminateRequested(false), mRelogRequested(false), - mConnected(false), mTerminateDaemon(false), - mPump(NULL), mSpatialJoiningNum(0), mTuningMode(false), @@ -350,7 +350,11 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mIsProcessingChannels(false), mIsCoroutineActive(false), mVivoxPump("vivoxClientPump") -{ +{ + sShuttingDown = false; + sConnected = false; + sPump = nullptr; + mSpeakerVolume = scale_speaker_volume(0); mVoiceVersion.serverVersion = ""; @@ -392,7 +396,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient() void LLVivoxVoiceClient::init(LLPumpIO *pump) { // constructor will set up LLVoiceClient::getInstance() - mPump = pump; + sPump = pump; // LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro", // boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance())); @@ -413,10 +417,10 @@ void LLVivoxVoiceClient::terminate() logoutOfVivox(false); } - if(mConnected) + if(sConnected) { breakVoiceConnection(false); - mConnected = false; + sConnected = false; } else { @@ -425,7 +429,7 @@ void LLVivoxVoiceClient::terminate() } sShuttingDown = true; - mPump = NULL; + sPump = NULL; } //--------------------------------------------------- @@ -471,7 +475,7 @@ bool LLVivoxVoiceClient::writeString(const std::string &str) bool result = false; LL_DEBUGS("LowVoice") << "sending:\n" << str << LL_ENDL; - if(mConnected) + if(sConnected) { apr_status_t err; apr_size_t size = (apr_size_t)str.size(); @@ -1051,7 +1055,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() int retryCount(0); LLVoiceVivoxStats::getInstance()->reset(); - while (!mConnected && !sShuttingDown && retryCount++ <= DAEMON_CONNECT_RETRY_MAX) + while (!sConnected && !sShuttingDown && retryCount++ <= DAEMON_CONNECT_RETRY_MAX) { LLVoiceVivoxStats::getInstance()->connectionAttemptStart(); LL_DEBUGS("Voice") << "Attempting to connect to vivox daemon: " << mDaemonHost << LL_ENDL; @@ -1061,23 +1065,23 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); } - mConnected = mSocket->blockingConnect(mDaemonHost); - LLVoiceVivoxStats::getInstance()->connectionAttemptEnd(mConnected); - if (!mConnected) + sConnected = mSocket->blockingConnect(mDaemonHost); + LLVoiceVivoxStats::getInstance()->connectionAttemptEnd(sConnected); + if (!sConnected) { llcoro::suspendUntilTimeout(DAEMON_CONNECT_THROTTLE_SECONDS); } } //--------------------------------------------------------------------- - if (sShuttingDown && !mConnected) + if (sShuttingDown && !sConnected) { return false; } llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); - while (!mPump && !sShuttingDown) + while (!sPump && !sShuttingDown) { // Can't use the pump until we have it available. llcoro::suspend(); } @@ -1099,7 +1103,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() readChain.push_back(LLIOPipe::ptr_t(new LLVivoxProtocolParser())); - mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS); + sPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS); //--------------------------------------------------------------------- @@ -1321,9 +1325,9 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait) // the message, yet we need to receive "connector shutdown response". // Either wait a bit and emulate it or check gMessageSystem for specific message _sleep(1000); - if (mConnected) + if (sConnected) { - mConnected = false; + sConnected = false; LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false))); mVivoxPump.post(vivoxevent); } @@ -1335,7 +1339,7 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait) LL_DEBUGS("Voice") << "closing SLVoice socket" << LL_ENDL; closeSocket(); // Need to do this now -- bad things happen if the destructor does it later. cleanUp(); - mConnected = false; + sConnected = false; return retval; } @@ -2516,7 +2520,7 @@ bool LLVivoxVoiceClient::performMicTuning() void LLVivoxVoiceClient::closeSocket(void) { mSocket.reset(); - mConnected = false; + sConnected = false; mConnectorEstablished = false; mAccountLoggedIn = false; } @@ -3017,7 +3021,7 @@ bool LLVivoxVoiceClient::deviceSettingsAvailable() { bool result = true; - if(!mConnected) + if(!sConnected) result = false; if(mRenderDevices.empty()) @@ -3816,7 +3820,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string & // Should this ever fail? do we care if it does? } - mConnected = false; + sConnected = false; mShutdownComplete = true; LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false))); @@ -7389,7 +7393,7 @@ LLIOPipe::EStatus LLVivoxProtocolParser::process_impl( LL_DEBUGS("VivoxProtocolParser") << "at end, mInput is: " << mInput << LL_ENDL; - if(!LLVivoxVoiceClient::getInstance()->mConnected) + if(!LLVivoxVoiceClient::sConnected) { // If voice has been disabled, we just want to close the socket. This does so. LL_INFOS("Voice") << "returning STATUS_STOP" << LL_ENDL; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 0a785401c1..e3ab99c675 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -666,12 +666,10 @@ private: LLHost mDaemonHost; LLSocket::ptr_t mSocket; - bool mConnected; // We should kill the voice daemon in case of connection alert bool mTerminateDaemon; - LLPumpIO *mPump; friend class LLVivoxProtocolParser; std::string mAccountName; @@ -916,7 +914,10 @@ private: bool mIsProcessingChannels; bool mIsCoroutineActive; - static bool sShuttingDown; // corutines can last longer than vivox so we need a static variable as a shutdown flag + // This variables can last longer than vivox in coroutines so we need them as static + static bool sShuttingDown; + static bool sConnected; + static LLPumpIO* sPump; LLEventMailDrop mVivoxPump; }; -- cgit v1.2.3 From 107b1d00ed5d272cd87a6ca333cd719151208eaa Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Sat, 22 Apr 2023 00:31:42 +0300 Subject: SL-19636 Profile badges --- indra/newview/llavatarpropertiesprocessor.h | 1 + indra/newview/llpanelprofile.cpp | 60 ++++++++++++++++++++- .../default/textures/icons/profile_badge_beta.png | Bin 0 -> 3223 bytes .../textures/icons/profile_badge_beta_lifetime.png | Bin 0 -> 3221 bytes .../textures/icons/profile_badge_lifetime.png | Bin 0 -> 3302 bytes .../textures/icons/profile_badge_linden.png | Bin 0 -> 3521 bytes .../icons/profile_badge_pplus_lifetime.png | Bin 0 -> 3311 bytes .../icons/profile_badge_premium_lifetime.png | Bin 0 -> 3301 bytes indra/newview/skins/default/textures/textures.xml | 8 ++- .../default/xui/en/panel_profile_secondlife.xml | 56 +++++++++++++++++-- 10 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 indra/newview/skins/default/textures/icons/profile_badge_beta.png create mode 100644 indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png create mode 100644 indra/newview/skins/default/textures/icons/profile_badge_lifetime.png create mode 100644 indra/newview/skins/default/textures/icons/profile_badge_linden.png create mode 100644 indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png create mode 100644 indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png (limited to 'indra') diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index f778634d25..10cde35f9c 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -85,6 +85,7 @@ struct LLAvatarData std::string profile_url; U8 caption_index; std::string caption_text; + std::string customer_type; U32 flags; BOOL allow_publish; }; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 708ff26ced..34e1fd09d8 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -159,6 +159,7 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) avatar_data->fl_about_text = result["fl_about_text"].asString(); avatar_data->born_on = result["member_since"].asDate(); avatar_data->profile_url = getProfileURL(agent_id.asString()); + avatar_data->customer_type = result["customer_type"].asString(); avatar_data->flags = 0; @@ -1051,6 +1052,8 @@ void LLPanelProfileSecondLife::resetData() mCantEditObjectsIcon->setEnabled(false); childSetVisible("partner_layout", FALSE); + childSetVisible("badge_layout", FALSE); + childSetVisible("partner_spacer_layout", TRUE); } void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) @@ -1258,6 +1261,59 @@ void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data std::string caption_text = getString("CaptionTextAcctInfo", args); getChild<LLUICtrl>("account_info")->setValue(caption_text); + + const S32 LINDEN_EMPLOYEE_INDEX = 3; + LLDate sl_release; + sl_release.fromYMDHMS(2003, 6, 23, 0, 0, 0); + std::string customer_lower = avatar_data->customer_type; + LLStringUtil::toLower(customer_lower); + if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) + { + getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Linden"); + getChild<LLUICtrl>("badge_text")->setValue(getString("BadgeLinden")); + childSetVisible("badge_layout", TRUE); + childSetVisible("partner_spacer_layout", FALSE); + } + else if (avatar_data->born_on < sl_release) + { + getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Beta"); + getChild<LLUICtrl>("badge_text")->setValue(getString("BadgeBeta")); + childSetVisible("badge_layout", TRUE); + childSetVisible("partner_spacer_layout", FALSE); + } + else if (customer_lower == "beta_lifetime") + { + getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Beta_Lifetime"); + getChild<LLUICtrl>("badge_text")->setValue(getString("BadgeBetaLifetime")); + childSetVisible("badge_layout", TRUE); + childSetVisible("partner_spacer_layout", FALSE); + } + else if (customer_lower == "lifetime") + { + getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Lifetime"); + getChild<LLUICtrl>("badge_text")->setValue(getString("BadgeLifetime")); + childSetVisible("badge_layout", TRUE); + childSetVisible("partner_spacer_layout", FALSE); + } + else if (customer_lower == "premium_lifetime") + { + getChild<LLUICtrl>("badge_icon")->setValue("Profile_Premium_Lifetime"); + getChild<LLUICtrl>("badge_text")->setValue(getString("BadgePremiumLifetime")); + childSetVisible("badge_layout", TRUE); + childSetVisible("partner_spacer_layout", FALSE); + } + else if (customer_lower == "pplus_lifetime" || customer_lower == "premium_plus_lifetime") + { + getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Pplus_Lifetime"); + getChild<LLUICtrl>("badge_text")->setValue(getString("BadgePremiumPlusLifetime")); + childSetVisible("badge_layout", TRUE); + childSetVisible("partner_spacer_layout", FALSE); + } + else + { + childSetVisible("badge_layout", FALSE); + childSetVisible("partner_spacer_layout", TRUE); + } } void LLPanelProfileSecondLife::fillRightsData() @@ -1412,7 +1468,7 @@ void LLPanelProfileSecondLife::updateOnlineStatus() } else { - childSetVisible("frind_layout", false); + childSetVisible("friend_layout", false); childSetVisible("online_layout", false); childSetVisible("offline_layout", false); } @@ -1420,7 +1476,7 @@ void LLPanelProfileSecondLife::updateOnlineStatus() void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online) { - childSetVisible("frind_layout", is_friend); + childSetVisible("friend_layout", is_friend); childSetVisible("online_layout", online && show_online); childSetVisible("offline_layout", !online && show_online); } diff --git a/indra/newview/skins/default/textures/icons/profile_badge_beta.png b/indra/newview/skins/default/textures/icons/profile_badge_beta.png new file mode 100644 index 0000000000..7c8a723c47 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/profile_badge_beta.png differ diff --git a/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png new file mode 100644 index 0000000000..7c38e9e2ae Binary files /dev/null and b/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png differ diff --git a/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png new file mode 100644 index 0000000000..475edd080e Binary files /dev/null and b/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png differ diff --git a/indra/newview/skins/default/textures/icons/profile_badge_linden.png b/indra/newview/skins/default/textures/icons/profile_badge_linden.png new file mode 100644 index 0000000000..1b6ac03e86 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/profile_badge_linden.png differ diff --git a/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png new file mode 100644 index 0000000000..4286995202 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png differ diff --git a/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png new file mode 100644 index 0000000000..47e93c4fac Binary files /dev/null and b/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 1f2c0867c4..03fc00b8f9 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -510,7 +510,13 @@ with the same filename but different name <texture name="Play_Off" file_name="icons/Play_Off.png" preload="false" /> <texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" /> <texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" /> - + + <texture name="Profile_Badge_Beta" file_name="icons/profile_badge_beta.png" preload="true"/> + <texture name="Profile_Badge_Beta_Lifetime" file_name="icons/profile_badge_beta_lifetime.png" preload="true"/> + <texture name="Profile_Badge_Lifetime" file_name="icons/profile_badge_lifetime.png" preload="true"/> + <texture name="Profile_Badge_Linden" file_name="icons/profile_badge_linden.png" preload="true"/> + <texture name="Profile_Badge_Pplus_Lifetime" file_name="icons/profile_badge_pplus_lifetime.png" preload="true"/> + <texture name="Profile_Badge_Premium_Lifetime" file_name="icons/profile_badge_premium_lifetime.png" preload="true"/> <texture name="Profile_Group_Visibility_Off" file_name="icons/profile_group_visibility_eye_off.png" preload="true"/> <texture name="Profile_Group_Visibility_Off_Pressed" file_name="icons/profile_group_visibility_eye_off_pressed.png" preload="true"/> <texture name="Profile_Group_Visibility_On" file_name="icons/profile_group_visibility_eye_on.png" preload="true"/> diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml index 777b37d666..07cdd6d71e 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml @@ -27,6 +27,26 @@ Account: [ACCTTYPE] [PAYMENTINFO] </string> + + <!--Badges--> + <string + name="BadgeBeta" + value="Original Beta Tester" /> + <string + name="BadgeBetaLifetime" + value="Beta Lifetime member" /> + <string + name="BadgeLifetime" + value="Lifetime member" /> + <string + name="BadgeLinden" + value="Linden Lab employee" /> + <string + name="BadgePremiumLifetime" + value="Premium lifetime" /> + <string + name="BadgePremiumPlusLifetime" + value="Premium Plus lifetime" /> <layout_stack name="image_stack" @@ -156,9 +176,39 @@ Account: [ACCTTYPE] user_resize="false" visible="true"> </layout_panel> - + + <layout_panel + name="badge_layout" + follows="all" + layout="topleft" + height="40" + auto_resize="false" + user_resize="false" + visible="false"> + <icon + name="badge_icon" + image_name="Beta_Tester" + layout="topleft" + follows="left|top" + top="10" + left="5" + height="18" + width="18"/> + <text + name="badge_text" + value="Badge Tester" + top="13" + left_pad="3" + right="-1" + height="16" + follows="left|top|right" + layout="topleft" + translate="false" + visible="true"/> + </layout_panel> + <layout_panel - name="frind_layout" + name="friend_layout" follows="all" layout="topleft" height="16" @@ -166,7 +216,7 @@ Account: [ACCTTYPE] user_resize="false" visible="false"> <text - name="frind_text" + name="friend_text" value="You are friends" text_color="ConversationFriendColor" top="0" -- cgit v1.2.3 From 1491eea28c9355ba3d69ce566ae5263e69db3daf Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Tue, 25 Apr 2023 22:47:31 +0300 Subject: SL-19652 Folder fetch dupplicate protection and over limit handling --- indra/newview/llinventorymodelbackgroundfetch.cpp | 44 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 4a9b471a47..0bb56c7d0c 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -408,6 +408,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() // *TODO: Think I'd like to get a shared pointer to this and share it // among all the folder requests. uuid_vec_t recursive_cats; + uuid_vec_t all_cats; // dupplicate avoidance LLSD folder_request_body; LLSD folder_request_body_lib; @@ -436,7 +437,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() { const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); - if (cat) + if (cat && std::find(all_cats.begin(), all_cats.end(), cat_id) == all_cats.end()) { if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) { @@ -477,6 +478,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() { recursive_cats.push_back(cat_id); } + all_cats.push_back(cat_id); } else { @@ -796,6 +798,46 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL; // Could use a 404 test here to try to detect revoked caps... + + if(status == LLCore::HttpStatus(HTTP_FORBIDDEN)) + { + // too large, split into two, assume that this isn't the library + const std::string url(gAgent.getRegionCapability("FetchInventoryDescendents2")); + S32 size = mRequestSD["folders"].size(); + + if (!gDisconnected && !LLApp::isExiting() && !url.empty() && size > 1) + { + LLSD folders; + uuid_vec_t recursive_cats; + LLSD::array_iterator iter = mRequestSD["folders"].beginArray(); + LLSD::array_iterator end = mRequestSD["folders"].endArray(); + while (iter != end) + { + folders.append(*iter); + LLUUID fodler_id = iter->get("folder_id").asUUID(); + if (std::find(mRecursiveCatUUIDs.begin(), mRecursiveCatUUIDs.end(), fodler_id) != mRecursiveCatUUIDs.end()) + { + recursive_cats.push_back(fodler_id); + } + if (folders.size() == (S32)(size / 2)) + { + LLSD request_body; + request_body["folders"] = folders; + LLCore::HttpHandler::ptr_t handler(new BGFolderHttpHandler(request_body, recursive_cats)); + gInventory.requestPost(false, url, request_body, handler, "Inventory Folder"); + recursive_cats.clear(); + folders.clear(); + } + iter++; + } + + LLSD request_body; + request_body["folders"] = folders; + LLCore::HttpHandler::ptr_t handler(new BGFolderHttpHandler(request_body, recursive_cats)); + gInventory.requestPost(false, url, request_body, handler, "Inventory Folder"); + return; + } + } // This was originally the request retry logic for the inventory // request which tested on HTTP_INTERNAL_ERROR status. This -- cgit v1.2.3 From 895ce616ea71b2001ec4e826b80310da80db9a0e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Thu, 6 Apr 2023 21:19:44 +0300 Subject: SL-19652 Fixed 'working' cursor flicker --- indra/llwindow/llwindow.h | 3 ++- indra/newview/llinventorypanel.cpp | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 0edf39f6ef..802a3b5213 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -118,7 +118,8 @@ public: // Sets cursor, may set to arrow+hourglass virtual void setCursor(ECursorType cursor) { mNextCursor = cursor; }; - virtual ECursorType getCursor() const; + virtual ECursorType getCursor() const; + virtual ECursorType getNextCursor() const { return mNextCursor; }; virtual void updateCursor() = 0; virtual void captureMouse() = 0; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 8029486d6f..2799cb4cdf 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1268,8 +1268,10 @@ BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask) { BOOL handled = LLView::handleHover(x, y, mask); if(handled) - { - ECursorType cursor = getWindow()->getCursor(); + { + // getCursor gets current cursor, setCursor sets next cursor + // check that children didn't set own 'next' cursor + ECursorType cursor = getWindow()->getNextCursor(); if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() && cursor == UI_CURSOR_ARROW) { // replace arrow cursor with arrow and hourglass cursor -- cgit v1.2.3 From d1e3959fef60d70c5f928422b9895b11e36ef343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pantera=20P=C3=B3=C5=82nocy?= <panterapolnocy@gmail.com> Date: Tue, 2 May 2023 19:19:03 +0200 Subject: Update floater_scene_load_stats.xml Reducing the packet loss... --- .../skins/default/xui/en/floater_scene_load_stats.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indra') diff --git a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml index 37efbe654e..b757f4eab8 100644 --- a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml @@ -414,7 +414,7 @@ name="frame_stats" label="Frame breakdown" show_label="true"> - <stat_bar name="packet_loss" + <stat_bar name="scenery_frame_pct" label="Scenery" orientation="horizontal" unit_label=" %" @@ -422,7 +422,7 @@ bar_max="100" tick_spacing="0.5" show_bar="false"/> - <stat_bar name="packet_loss" + <stat_bar name="avatar_frame_pct" label="Avatar" orientation="horizontal" unit_label=" %" @@ -430,7 +430,7 @@ bar_max="100" tick_spacing="0.5" show_bar="false"/> - <stat_bar name="packet_loss" + <stat_bar name="ui_frame_pct" label="UI" orientation="horizontal" unit_label=" %" @@ -438,7 +438,7 @@ bar_max="100" tick_spacing="0.5" show_bar="false"/> - <stat_bar name="packet_loss" + <stat_bar name="huds_frame_pct" label="HUDs" orientation="horizontal" unit_label=" %" @@ -446,7 +446,7 @@ bar_max="100" tick_spacing="0.5" show_bar="false"/> - <stat_bar name="packet_loss" + <stat_bar name="swap_frame_pct" label="Swap" orientation="horizontal" unit_label=" %" @@ -454,7 +454,7 @@ bar_max="100" tick_spacing="0.5" show_bar="false"/> - <stat_bar name="packet_loss" + <stat_bar name="idle_frame_pct" label="Tasks" orientation="horizontal" unit_label=" %" -- cgit v1.2.3 From 534d3abd2a93ed2df429b8cdbba84a10f26b0add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pantera=20P=C3=B3=C5=82nocy?= <panterapolnocy@gmail.com> Date: Tue, 2 May 2023 19:35:14 +0200 Subject: Fixing a small typo in llviewerstats.cpp --- indra/newview/llviewerstats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 519166af63..1607296194 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -124,7 +124,7 @@ SimMeasurement<> SIM_TIME_DILATION("simtimedilation", "Simulator time scale", SIM_MAIN_AGENTS("simmainagents", "Number of avatars in current region", LL_SIM_STAT_NUMAGENTMAIN), SIM_CHILD_AGENTS("simchildagents", "Number of avatars in neighboring regions", LL_SIM_STAT_NUMAGENTCHILD), SIM_OBJECTS("simobjects", "", LL_SIM_STAT_NUMTASKS), - SIM_ACTIVE_OBJECTS("simactiveobjects", "Number of scripted and/or mocing objects", LL_SIM_STAT_NUMTASKSACTIVE), + SIM_ACTIVE_OBJECTS("simactiveobjects", "Number of scripted and/or moving objects", LL_SIM_STAT_NUMTASKSACTIVE), SIM_ACTIVE_SCRIPTS("simactivescripts", "Number of scripted objects", LL_SIM_STAT_NUMSCRIPTSACTIVE), SIM_IN_PACKETS_PER_SEC("siminpps", "", LL_SIM_STAT_INPPS), SIM_OUT_PACKETS_PER_SEC("simoutpps", "", LL_SIM_STAT_OUTPPS), -- cgit v1.2.3 From 42f16180a985fc0e4704a4e25489ada9d662631a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Wed, 10 May 2023 18:41:55 +0300 Subject: SL-19536 SL-19652 Fix inventory fetching --- indra/newview/llinventorymodelbackgroundfetch.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 0bb56c7d0c..6b88d0aaf7 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -437,9 +437,10 @@ void LLInventoryModelBackgroundFetch::bulkFetch() { const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); - if (cat && std::find(all_cats.begin(), all_cats.end(), cat_id) == all_cats.end()) + if (cat) { - if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) + if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion() + && std::find(all_cats.begin(), all_cats.end(), cat_id) == all_cats.end()) { LLSD folder_sd; folder_sd["folder_id"] = cat->getUUID(); -- cgit v1.2.3 From d28e2c03a76151b7e6ba47fc892fb7c2c164c1e2 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko <maximnproductengine@lindenlab.com> Date: Fri, 12 May 2023 16:35:27 +0300 Subject: SL-19649 reduce logging out time for larger inventories --- indra/llui/llview.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 9ba71913d0..3344300635 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -576,8 +576,10 @@ void LLView::deleteAllChildren() while (!mChildList.empty()) { - LLView* viewp = mChildList.front(); - delete viewp; // will remove the child from mChildList + LLView* viewp = mChildList.front(); + viewp->mParentView = NULL; + delete viewp; + mChildList.pop_front(); } } -- cgit v1.2.3 From cc8af5f37df1e200bc0b55740887a99157066e35 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Fri, 12 May 2023 18:26:02 +0300 Subject: SL-19649 Adjust other classes for new deleteAllChildren mechanics --- indra/llui/lllayoutstack.cpp | 19 ++++++++++++++++--- indra/llui/lllayoutstack.h | 1 + indra/llui/llmenugl.cpp | 7 +++++++ indra/llui/llmenugl.h | 1 + indra/newview/llinspecttoast.cpp | 7 +++++++ indra/newview/llinventorymodel.cpp | 6 +++++- 6 files changed, 37 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 77938edf27..ae9dba5945 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -282,6 +282,17 @@ void LLLayoutStack::draw() } } +void LLLayoutStack::deleteAllChildren() +{ + mPanels.clear(); + LLView::deleteAllChildren(); + + // Not really needed since nothing is left to + // display, but for the sake of consistency + updateFractionalSizes(); + mNeedsLayout = true; +} + void LLLayoutStack::removeChild(LLView* view) { LLLayoutPanel* embedded_panelp = findEmbeddedPanel(dynamic_cast<LLPanel*>(view)); @@ -289,12 +300,14 @@ void LLLayoutStack::removeChild(LLView* view) if (embedded_panelp) { mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp)); - delete embedded_panelp; + LLView::removeChild(view); updateFractionalSizes(); mNeedsLayout = true; } - - LLView::removeChild(view); + else + { + LLView::removeChild(view); + } } BOOL LLLayoutStack::postBuild() diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index f772dbc6b4..22f11eb20f 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -67,6 +67,7 @@ public: virtual ~LLLayoutStack(); /*virtual*/ void draw(); + /*virtual*/ void deleteAllChildren(); /*virtual*/ void removeChild(LLView*); /*virtual*/ BOOL postBuild(); /*virtual*/ bool addChild(LLView* child, S32 tab_group = 0); diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 5cb840fd61..33c4b6ec73 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1882,6 +1882,13 @@ bool LLMenuGL::addContextChild(LLView* view, S32 tab_group) return false; } + +void LLMenuGL::deleteAllChildren() +{ + mItems.clear(); + LLUICtrl::deleteAllChildren(); +} + void LLMenuGL::removeChild( LLView* ctrl) { // previously a dynamic_cast with if statement to check validity diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index f84c4d41eb..9d3be8d94f 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -442,6 +442,7 @@ public: /*virtual*/ void drawBackground(LLMenuItemGL* itemp, F32 alpha); /*virtual*/ void setVisible(BOOL visible); /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0); + /*virtual*/ void deleteAllChildren(); /*virtual*/ void removeChild( LLView* ctrl); /*virtual*/ BOOL postBuild(); diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp index 68801b0895..6f93a78ca6 100644 --- a/indra/newview/llinspecttoast.cpp +++ b/indra/newview/llinspecttoast.cpp @@ -47,6 +47,7 @@ public: /*virtual*/ void onOpen(const LLSD& notification_id); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); + /*virtual*/ void deleteAllChildren(); /*virtual*/ void removeChild(LLView* child); private: void onToastDestroy(LLToast * toast); @@ -122,6 +123,12 @@ BOOL LLInspectToast::handleToolTip(S32 x, S32 y, MASK mask) return LLFloater::handleToolTip(x, y, mask); } +void LLInspectToast::deleteAllChildren() +{ + mPanel = NULL; + LLInspect::deleteAllChildren(); +} + // virtual void LLInspectToast::removeChild(LLView* child) { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 0bbf201dc6..b4727de77f 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -594,7 +594,11 @@ const LLUUID LLInventoryModel::findCategoryUUIDForTypeInRoot( } } - if(rv.isNull() && create_folder && root_id.notNull()) + if(rv.isNull() + && root_id.notNull() + && create_folder + && preferred_type != LLFolderType::FT_MARKETPLACE_LISTINGS + && preferred_type != LLFolderType::FT_OUTBOX) { if (isInventoryUsable()) -- cgit v1.2.3 From a10c876ae4db901ab60f58f0df82663b855b3d45 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy <alihatskiy@productengine.com> Date: Fri, 19 May 2023 02:20:48 +0300 Subject: DRTVWR-580 Post-merge fix --- indra/llcharacter/llkeyframemotion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 9cb30882dd..3cef382bbf 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -2054,7 +2054,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const LL_DEBUGS("BVH") << " rot: t " << rot_key.mTime << " angles " << rot_angles.mV[VX] <<","<< rot_angles.mV[VY] <<","<< rot_angles.mV[VZ] << LL_ENDL; } - success &= dp.packS32(joint_motionp->mPositionCurve.mNumKeys, "num_pos_keys"); + success &= dp.packS32(joint_motionp->mPositionCurve.mKeys.size(), "num_pos_keys"); for (PositionCurve::key_map_t::value_type& pos_pair : joint_motionp->mPositionCurve.mKeys) { PositionKey& pos_key = pos_pair.second; -- cgit v1.2.3 From 7140640b6963dacfa012dfec679798fc4dd13a17 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy <alihatskiy@productengine.com> Date: Fri, 19 May 2023 02:31:28 +0300 Subject: DRTVWR-580 Post-merge fix - unused code --- indra/newview/llfilepicker.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index ab5f88e210..f1f156c2e0 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -745,14 +745,6 @@ void set_nav_save_data(LLFilePicker::ESaveFilter filter, std::string &extension, creator = "\?\?\?\?"; extension = "xaf"; break; - -#ifdef _CORY_TESTING - case LLFilePicker::FFSAVE_GEOMETRY: - type = "\?\?\?\?"; - creator = "\?\?\?\?"; - extension = "slg"; - break; -#endif case LLFilePicker::FFSAVE_XML: type = "\?\?\?\?"; -- cgit v1.2.3 From 1d1a63abe4a3d3a6191172c1693ffbdb0ffb2d71 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Fri, 19 May 2023 19:56:57 +0300 Subject: SL-19635 Implement DeepL tranlation support --- indra/newview/app_settings/settings.xml | 11 + indra/newview/llfloatertranslationsettings.cpp | 132 +++++++-- indra/newview/llfloatertranslationsettings.h | 10 +- indra/newview/lltranslate.cpp | 311 ++++++++++++++++++++- indra/newview/lltranslate.h | 1 + .../xui/en/floater_translation_settings.xml | 97 ++++++- 6 files changed, 527 insertions(+), 35 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index fa241dc30c..ca1b1e2f20 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -13014,6 +13014,17 @@ <key>Value</key> <string></string> </map> + <key>DeepLTranslateAPIKey</key> + <map> + <key>Comment</key> + <string>DeepL Translation service data to use with the DeepL Translator API</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>LLSD</string> + <key>Value</key> + <string></string> + </map> <key>TutorialURL</key> <map> <key>Comment</key> diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index e14227f490..d29ecbbf95 100644 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -47,6 +47,7 @@ LLFloaterTranslationSettings::LLFloaterTranslationSettings(const LLSD& key) , mMachineTranslationCB(NULL) , mAzureKeyVerified(false) , mGoogleKeyVerified(false) +, mDeepLKeyVerified(false) { } @@ -60,8 +61,11 @@ BOOL LLFloaterTranslationSettings::postBuild() mAzureAPIKeyEditor = getChild<LLLineEditor>("azure_api_key"); mAzureAPIRegionEditor = getChild<LLLineEditor>("azure_api_region"); mGoogleAPIKeyEditor = getChild<LLLineEditor>("google_api_key"); + mDeepLAPIDomainCombo = getChild<LLComboBox>("deepl_api_domain_combo"); + mDeepLAPIKeyEditor = getChild<LLLineEditor>("deepl_api_key"); mAzureVerifyBtn = getChild<LLButton>("verify_azure_api_key_btn"); mGoogleVerifyBtn = getChild<LLButton>("verify_google_api_key_btn"); + mDeepLVerifyBtn = getChild<LLButton>("verify_deepl_api_key_btn"); mOKBtn = getChild<LLButton>("ok_btn"); mMachineTranslationCB->setCommitCallback(boost::bind(&LLFloaterTranslationSettings::updateControlsEnabledState, this)); @@ -70,18 +74,37 @@ BOOL LLFloaterTranslationSettings::postBuild() getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloater::closeFloater, this, false)); mAzureVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnAzureVerify, this)); mGoogleVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnGoogleVerify, this)); + mDeepLVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnDeepLVerify, this)); mAzureAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1)); mAzureAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onAzureKeyEdited, this), NULL); mAzureAPIRegionEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1)); mAzureAPIRegionEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onAzureKeyEdited, this), NULL); - mAzureAPIEndpointEditor->setFocusLostCallback(boost::bind(&LLFloaterTranslationSettings::onAzureKeyEdited, this)); - mAzureAPIEndpointEditor->setCommitCallback(boost::bind(&LLFloaterTranslationSettings::onAzureKeyEdited, this)); + mAzureAPIEndpointEditor->setFocusLostCallback([this](LLFocusableElement*) + { + setAzureVerified(false, false, 0); + }); + mAzureAPIEndpointEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) + { + setAzureVerified(false, false, 0); + }); mGoogleAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1)); mGoogleAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onGoogleKeyEdited, this), NULL); + mDeepLAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1)); + mDeepLAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onDeepLKeyEdited, this), NULL); + + mDeepLAPIDomainCombo->setFocusLostCallback([this](LLFocusableElement*) + { + setDeepLVerified(false, false, 0); + }); + mDeepLAPIDomainCombo->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) + { + setDeepLVerified(false, false, 0); + }); + center(); return TRUE; } @@ -130,6 +153,20 @@ void LLFloaterTranslationSettings::onOpen(const LLSD& key) mGoogleKeyVerified = FALSE; } + LLSD deepl_key = gSavedSettings.getLLSD("DeepLTranslateAPIKey"); + if (deepl_key.isMap() && !deepl_key["id"].asString().empty()) + { + mDeepLAPIKeyEditor->setText(deepl_key["id"].asString()); + mDeepLAPIKeyEditor->setTentative(false); + mDeepLAPIDomainCombo->setValue(deepl_key["domain"]); + verifyKey(LLTranslate::SERVICE_DEEPL, deepl_key, false); + } + else + { + mDeepLAPIKeyEditor->setTentative(TRUE); + mDeepLKeyVerified = FALSE; + } + updateControlsEnabledState(); } @@ -155,6 +192,17 @@ void LLFloaterTranslationSettings::setGoogleVerified(bool ok, bool alert, S32 st updateControlsEnabledState(); } +void LLFloaterTranslationSettings::setDeepLVerified(bool ok, bool alert, S32 status) +{ + if (alert) + { + showAlert(ok ? "deepl_api_key_verified" : "deepl_api_key_not_verified", status); + } + + mDeepLKeyVerified = ok; + updateControlsEnabledState(); +} + std::string LLFloaterTranslationSettings::getSelectedService() const { return mTranslationServiceRadioGroup->getSelectedValue().asString(); @@ -180,6 +228,17 @@ std::string LLFloaterTranslationSettings::getEnteredGoogleKey() const return mGoogleAPIKeyEditor->getTentative() ? LLStringUtil::null : mGoogleAPIKeyEditor->getText(); } +LLSD LLFloaterTranslationSettings::getEnteredDeepLKey() const +{ + LLSD key; + if (!mDeepLAPIKeyEditor->getTentative()) + { + key["domain"] = mDeepLAPIDomainCombo->getValue(); + key["id"] = mDeepLAPIKeyEditor->getText(); + } + return key; +} + void LLFloaterTranslationSettings::showAlert(const std::string& msg_name, S32 status) const { LLStringUtil::format_map_t string_args; @@ -199,29 +258,42 @@ void LLFloaterTranslationSettings::updateControlsEnabledState() std::string service = getSelectedService(); bool azure_selected = service == "azure"; bool google_selected = service == "google"; + bool deepl_selected = service == "deepl"; mTranslationServiceRadioGroup->setEnabled(on); mLanguageCombo->setEnabled(on); - getChild<LLTextBox>("azure_api_endoint_label")->setEnabled(on); - mAzureAPIEndpointEditor->setEnabled(on); + // MS Azure + getChild<LLTextBox>("azure_api_endoint_label")->setEnabled(on); + mAzureAPIEndpointEditor->setEnabled(on && azure_selected); getChild<LLTextBox>("azure_api_key_label")->setEnabled(on); - mAzureAPIKeyEditor->setEnabled(on); + mAzureAPIKeyEditor->setEnabled(on && azure_selected); getChild<LLTextBox>("azure_api_region_label")->setEnabled(on); - mAzureAPIRegionEditor->setEnabled(on); + mAzureAPIRegionEditor->setEnabled(on && azure_selected); - getChild<LLTextBox>("google_api_key_label")->setEnabled(on); - mGoogleAPIKeyEditor->setEnabled(on); + mAzureVerifyBtn->setEnabled(on && azure_selected && + !mAzureKeyVerified && getEnteredAzureKey().isMap()); - mAzureAPIKeyEditor->setEnabled(on && azure_selected); - mGoogleAPIKeyEditor->setEnabled(on && google_selected); + // Google + getChild<LLTextBox>("google_api_key_label")->setEnabled(on); + mGoogleAPIKeyEditor->setEnabled(on && google_selected); - mAzureVerifyBtn->setEnabled(on && azure_selected && - !mAzureKeyVerified && getEnteredAzureKey().isMap()); mGoogleVerifyBtn->setEnabled(on && google_selected && !mGoogleKeyVerified && !getEnteredGoogleKey().empty()); - bool service_verified = (azure_selected && mAzureKeyVerified) || (google_selected && mGoogleKeyVerified); + // DeepL + getChild<LLTextBox>("deepl_api_domain_label")->setEnabled(on); + mDeepLAPIDomainCombo->setEnabled(on && deepl_selected); + getChild<LLTextBox>("deepl_api_key_label")->setEnabled(on); + mDeepLAPIKeyEditor->setEnabled(on && deepl_selected); + + mDeepLVerifyBtn->setEnabled(on && deepl_selected && + !mDeepLKeyVerified && getEnteredDeepLKey().isMap()); + + bool service_verified = + (azure_selected && mAzureKeyVerified) + || (google_selected && mGoogleKeyVerified) + || (deepl_selected && mDeepLKeyVerified); gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified); mOKBtn->setEnabled(!on || service_verified); @@ -247,6 +319,9 @@ void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, b case LLTranslate::SERVICE_GOOGLE: floater->setGoogleVerified(ok, alert, status); break; + case LLTranslate::SERVICE_DEEPL: + floater->setDeepLVerified(ok, alert, status); + break; } } @@ -273,8 +348,7 @@ void LLFloaterTranslationSettings::onEditorFocused(LLFocusableElement* control) void LLFloaterTranslationSettings::onAzureKeyEdited() { if (mAzureAPIKeyEditor->isDirty() - || mAzureAPIRegionEditor->isDirty() - || mAzureAPIEndpointEditor->getValue().isString()) + || mAzureAPIRegionEditor->isDirty()) { // todo: verify mAzureAPIEndpointEditor url setAzureVerified(false, false, 0); @@ -289,6 +363,14 @@ void LLFloaterTranslationSettings::onGoogleKeyEdited() } } +void LLFloaterTranslationSettings::onDeepLKeyEdited() +{ + if (mDeepLAPIKeyEditor->isDirty()) + { + setDeepLVerified(false, false, 0); + } +} + void LLFloaterTranslationSettings::onBtnAzureVerify() { LLSD key = getEnteredAzureKey(); @@ -306,15 +388,28 @@ void LLFloaterTranslationSettings::onBtnGoogleVerify() verifyKey(LLTranslate::SERVICE_GOOGLE, LLSD(key)); } } + +void LLFloaterTranslationSettings::onBtnDeepLVerify() +{ + LLSD key = getEnteredDeepLKey(); + if (key.isMap()) + { + verifyKey(LLTranslate::SERVICE_DEEPL, key); + } +} + void LLFloaterTranslationSettings::onClose(bool app_quitting) { std::string service = gSavedSettings.getString("TranslationService"); bool azure_selected = service == "azure"; bool google_selected = service == "google"; + bool deepl_selected = service == "deepl"; - bool service_verified = (azure_selected && mAzureKeyVerified) || (google_selected && mGoogleKeyVerified); - gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified); - + bool service_verified = + (azure_selected && mAzureKeyVerified) + || (google_selected && mGoogleKeyVerified) + || (deepl_selected && mDeepLKeyVerified); + gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified); } void LLFloaterTranslationSettings::onBtnOK() { @@ -323,6 +418,7 @@ void LLFloaterTranslationSettings::onBtnOK() gSavedSettings.setString("TranslationService", getSelectedService()); gSavedSettings.setLLSD("AzureTranslateAPIKey", getEnteredAzureKey()); gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey()); + gSavedSettings.setLLSD("DeepLTranslateAPIKey", getEnteredDeepLKey()); closeFloater(false); } diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h index f039d90e27..eff0803fdd 100644 --- a/indra/newview/llfloatertranslationsettings.h +++ b/indra/newview/llfloatertranslationsettings.h @@ -44,12 +44,14 @@ public: void setAzureVerified(bool ok, bool alert, S32 status); void setGoogleVerified(bool ok, bool alert, S32 status); + void setDeepLVerified(bool ok, bool alert, S32 status); void onClose(bool app_quitting); private: std::string getSelectedService() const; LLSD getEnteredAzureKey() const; std::string getEnteredGoogleKey() const; + LLSD getEnteredDeepLKey() const; void showAlert(const std::string& msg_name, S32 status) const; void updateControlsEnabledState(); void verifyKey(int service, const LLSD& key, bool alert = true); @@ -57,25 +59,31 @@ private: void onEditorFocused(LLFocusableElement* control); void onAzureKeyEdited(); void onGoogleKeyEdited(); + void onDeepLKeyEdited(); void onBtnAzureVerify(); void onBtnGoogleVerify(); + void onBtnDeepLVerify(); void onBtnOK(); static void setVerificationStatus(int service, bool alert, bool ok, S32 status); LLCheckBoxCtrl* mMachineTranslationCB; LLComboBox* mLanguageCombo; - LLComboBox* mAzureAPIEndpointEditor;; + LLComboBox* mAzureAPIEndpointEditor; LLLineEditor* mAzureAPIKeyEditor; LLLineEditor* mAzureAPIRegionEditor; LLLineEditor* mGoogleAPIKeyEditor; + LLComboBox* mDeepLAPIDomainCombo; + LLLineEditor* mDeepLAPIKeyEditor; LLRadioGroup* mTranslationServiceRadioGroup; LLButton* mAzureVerifyBtn; LLButton* mGoogleVerifyBtn; + LLButton* mDeepLVerifyBtn; LLButton* mOKBtn; bool mAzureKeyVerified; bool mGoogleKeyVerified; + bool mDeepLKeyVerified; }; #endif // LL_LLFLOATERTRANSLATIONSETTINGS_H diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 6589ce06c4..70a40921ef 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -133,7 +133,9 @@ public: LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers, const std::string & url, - const std::string & msg) const = 0; + const std::string & msg, + const std::string& from_lang, + const std::string& to_lang) const = 0; virtual LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, LLCore::HttpRequest::ptr_t request, LLCore::HttpOptions::ptr_t options, @@ -230,7 +232,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s return; } - LLSD result = sendMessageAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url, msg); + LLSD result = sendMessageAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url, msg, fromTo.first, fromTo.second); if (LLApp::isQuitting()) { @@ -331,7 +333,9 @@ public: LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers, const std::string & url, - const std::string & msg) const override; + const std::string & msg, + const std::string& from_lang, + const std::string& to_lang) const override; LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, LLCore::HttpRequest::ptr_t request, @@ -508,7 +512,9 @@ LLSD LLGoogleTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCorou LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers, const std::string & url, - const std::string & msg) const + const std::string & msg, + const std::string& from_lang, + const std::string& to_lang) const { return adapter->getRawAndSuspend(request, url, options, headers); } @@ -558,7 +564,9 @@ public: LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers, const std::string & url, - const std::string & msg) const override; + const std::string & msg, + const std::string& from_lang, + const std::string& to_lang) const override; LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, LLCore::HttpRequest::ptr_t request, @@ -728,7 +736,7 @@ bool LLAzureTranslationHandler::parseResponse( // virtual bool LLAzureTranslationHandler::isConfigured() const { - return !getAPIKey().isMap(); + return getAPIKey().isMap(); } //static @@ -814,7 +822,9 @@ LLSD LLAzureTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCorout LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers, const std::string & url, - const std::string & msg) const + const std::string & msg, + const std::string& from_lang, + const std::string& to_lang) const { LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray); LLCore::BufferArrayStream outs(rawbody.get()); @@ -838,6 +848,259 @@ LLSD LLAzureTranslationHandler::verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAd return adapter->postRawAndSuspend(request, url, rawbody, options, headers); } +//========================================================================= +/// DeepL Translator API handler. +class LLDeepLTranslationHandler: public LLTranslationAPIHandler +{ + LOG_CLASS(LLDeepLTranslationHandler); + +public: + std::string getTranslateURL( + const std::string& from_lang, + const std::string& to_lang, + const std::string& text) const override; + std::string getKeyVerificationURL( + const LLSD& key) const override; + bool checkVerificationResponse( + const LLSD& response, + int status) const override; + bool parseResponse( + const LLSD& http_response, + int& status, + const std::string& body, + std::string& translation, + std::string& detected_lang, + std::string& err_msg) const override; + bool isConfigured() const override; + + LLTranslate::EService getCurrentService() override + { + return LLTranslate::EService::SERVICE_DEEPL; + } + + void verifyKey(const LLSD& key, LLTranslate::KeyVerificationResult_fn fnc) override; + + void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const override; + void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent, const LLSD& key) const override; + LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string& url, + const std::string& msg, + const std::string& from_lang, + const std::string& to_lang) const override; + + LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string& url) const override; +private: + static std::string parseErrorResponse( + const std::string& body); + static LLSD getAPIKey(); + static std::string getAPILanguageCode(const std::string& lang); +}; + +//------------------------------------------------------------------------- +// virtual +std::string LLDeepLTranslationHandler::getTranslateURL( + const std::string& from_lang, + const std::string& to_lang, + const std::string& text) const +{ + std::string url; + LLSD key = getAPIKey(); + if (key.isMap()) + { + url = key["domain"].asString(); + + if (*url.rbegin() != '/') + { + url += "/"; + } + url += std::string("v2/translate"); + } + return url; +} + + +// virtual +std::string LLDeepLTranslationHandler::getKeyVerificationURL( + const LLSD& key) const +{ + std::string url; + if (key.isMap()) + { + url = key["domain"].asString(); + + if (*url.rbegin() != '/') + { + url += "/"; + } + url += std::string("v2/translate"); + } + return url; +} + +//virtual +bool LLDeepLTranslationHandler::checkVerificationResponse( + const LLSD& response, + int status) const +{ + return status == HTTP_OK; +} + +// virtual +bool LLDeepLTranslationHandler::parseResponse( + const LLSD& http_response, + int& status, + const std::string& body, + std::string& translation, + std::string& detected_lang, + std::string& err_msg) const +{ + if (status != HTTP_OK) + { + if (http_response.has("error_body")) + err_msg = parseErrorResponse(http_response["error_body"].asString()); + return false; + } + + //Example: + // "{\"translations\":[{\"detected_source_language\":\"EN\",\"text\":\"test\"}]}" + + Json::Value root; + Json::Reader reader; + + if (!reader.parse(body, root)) + { + err_msg = reader.getFormatedErrorMessages(); + return false; + } + + if (!root.isObject() + || !root.isMember("translations")) // empty response? should not happen + { + return false; + } + + // Request succeeded, extract translation from the response. + const Json::Value& translations = root["translations"]; + if (!translations.isArray() || translations.size() == 0) + { + return false; + } + + const Json::Value& data= translations[0U]; + if (!data.isObject() + || !data.isMember("detected_source_language") + || !data.isMember("text")) + { + return false; + } + + + detected_lang = data["detected_source_language"].asString(); + LLStringUtil::toLower(detected_lang); + translation = data["text"].asString(); + + return true; +} + +// virtual +bool LLDeepLTranslationHandler::isConfigured() const +{ + return getAPIKey().isMap(); +} + +//static +std::string LLDeepLTranslationHandler::parseErrorResponse( + const std::string& body) +{ + // DeepL doesn't seem to have any error handling beyoun http codes + return std::string(); +} + +// static +LLSD LLDeepLTranslationHandler::getAPIKey() +{ + static LLCachedControl<LLSD> deepl_key(gSavedSettings, "DeepLTranslateAPIKey"); + return deepl_key; +} + +// static +std::string LLDeepLTranslationHandler::getAPILanguageCode(const std::string& lang) +{ + return lang == "zh" ? "zh-CHT" : lang; // treat Chinese as Traditional Chinese +} + +/*virtual*/ +void LLDeepLTranslationHandler::verifyKey(const LLSD& key, LLTranslate::KeyVerificationResult_fn fnc) +{ + LLCoros::instance().launch("DeepL /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro, + this, LLTranslate::SERVICE_DEEPL, key, fnc)); +} +/*virtual*/ +void LLDeepLTranslationHandler::initHttpHeader( + LLCore::HttpHeaders::ptr_t headers, + const std::string& user_agent) const +{ + initHttpHeader(headers, user_agent, getAPIKey()); +} + +/*virtual*/ +void LLDeepLTranslationHandler::initHttpHeader( + LLCore::HttpHeaders::ptr_t headers, + const std::string& user_agent, + const LLSD& key) const +{ + headers->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded"); + headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); + + if (key.has("id")) + { + std::string authkey = "DeepL-Auth-Key " + key["id"].asString(); + headers->append(HTTP_OUT_HEADER_AUTHORIZATION, authkey); + } +} + +LLSD LLDeepLTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string& url, + const std::string& msg, + const std::string& from_lang, + const std::string& to_lang) const +{ + LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray); + LLCore::BufferArrayStream outs(rawbody.get()); + outs << "text="; + std::string escaped_string = LLURI::escape(msg); + outs << escaped_string; + outs << "&target_lang="; + std::string lang = to_lang; + LLStringUtil::toUpper(lang); + outs << lang; + + return adapter->postRawAndSuspend(request, url, rawbody, options, headers); +} + +LLSD LLDeepLTranslationHandler::verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, + LLCore::HttpRequest::ptr_t request, + LLCore::HttpOptions::ptr_t options, + LLCore::HttpHeaders::ptr_t headers, + const std::string& url) const +{ + LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray); + LLCore::BufferArrayStream outs(rawbody.get()); + outs << "text=&target_lang=EN"; + + return adapter->postRawAndSuspend(request, url, rawbody, options, headers); +} + //========================================================================= LLTranslate::LLTranslate(): mCharsSeen(0), @@ -867,6 +1130,11 @@ std::string LLTranslate::addNoTranslateTags(std::string mesg) return mesg; } + if (getPreferredHandler().getCurrentService() == SERVICE_DEEPL) + { + return mesg; + } + if (getPreferredHandler().getCurrentService() == SERVICE_AZURE) { // https://learn.microsoft.com/en-us/azure/cognitive-services/translator/prevent-translation @@ -892,6 +1160,10 @@ std::string LLTranslate::removeNoTranslateTags(std::string mesg) { return mesg; } + if (getPreferredHandler().getCurrentService() == SERVICE_DEEPL) + { + return mesg; + } if (getPreferredHandler().getCurrentService() == SERVICE_AZURE) { @@ -997,6 +1269,14 @@ LLTranslationAPIHandler& LLTranslate::getPreferredHandler() { service = SERVICE_GOOGLE; } + if (service_str == "azure") + { + service = SERVICE_AZURE; + } + if (service_str == "deepl") + { + service = SERVICE_DEEPL; + } return getHandler(service); } @@ -1006,11 +1286,18 @@ LLTranslationAPIHandler& LLTranslate::getHandler(EService service) { static LLGoogleTranslationHandler google; static LLAzureTranslationHandler azure; + static LLDeepLTranslationHandler deepl; - if (service == SERVICE_GOOGLE) - { - return google; - } + switch (service) + { + case SERVICE_AZURE: + return azure; + case SERVICE_GOOGLE: + return google; + case SERVICE_DEEPL: + return deepl; + } + + return azure; - return azure; } diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index ffbbb05e62..4a5d80737c 100644 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -61,6 +61,7 @@ public : typedef enum e_service { SERVICE_AZURE, SERVICE_GOOGLE, + SERVICE_DEEPL, } EService; typedef boost::function<void(EService, bool, S32)> KeyVerificationResult_fn; diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml index dc3e072adf..8a97d5e5d9 100644 --- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater legacy_header_height="18" - height="370" + height="470" layout="topleft" name="floater_translation_settings" help_topic="translation_settings" @@ -11,9 +11,11 @@ <string name="azure_api_key_not_verified">Azure service identifier not verified. Status: [STATUS]. Please check your settings and try again.</string> <string name="google_api_key_not_verified">Google API key not verified. Status: [STATUS]. Please check your key and try again.</string> + <string name="deepl_api_key_not_verified">DeepL Auth Key key not verified. Status: [STATUS]. Please check your key and try again.</string> <string name="azure_api_key_verified">Azure service identifier verified.</string> <string name="google_api_key_verified">Google API key verified.</string> + <string name="deepl_api_key_verified">DeepL API key verified.</string> <check_box height="16" @@ -128,7 +130,7 @@ <radio_group follows="top|left" - height="140" + height="260" layout="topleft" left_delta="10" name="translation_service_rg" @@ -145,6 +147,12 @@ layout="topleft" name="google" top_pad="115" /> + <radio_item + initial_value="deepl" + label="DeepL Translator" + layout="topleft" + name="deepl" + top_pad="61" /> </radio_group> <text @@ -154,7 +162,7 @@ left="185" length="1" name="google_links_text" - top_pad="-142" + top_pad="-262" type="string" width="100"> [https://learn.microsoft.com/en-us/azure/cognitive-services/translator/create-translator-resource Setup] @@ -286,7 +294,7 @@ left_pad="10" name="verify_google_api_key_btn" top_delta="-2" - width="90" /> + width="90" /> <text follows="top|right" @@ -301,6 +309,87 @@ [http://code.google.com/apis/language/translate/v2/pricing.html Pricing] | [https://code.google.com/apis/console Stats] </text> + <text + type="string" + length="1" + follows="top|right" + height="20" + layout="topleft" + left="70" + name="deepl_api_domain_label" + top_pad="80" + width="85"> + Domain: + </text> + + <combo_box + allow_text_entry="false" + follows="left|top" + name="deepl_api_domain_combo" + height="23" + left_pad="10" + width="140" + top_delta="-4" + max_chars="512" + value="https://api-free.deepl.com" + combo_button.scale_image="true"> + <combo_box.item + label="DeepL Free" + name="global" + value="https://api-free.deepl.com" /> + <combo_box.item + label="DeepL Pro" + name="api-apc" + value="https://api.deepl.com" /> + </combo_box> + + <text + follows="top|right" + height="20" + layout="topleft" + left="70" + length="1" + name="deepl_api_key_label" + top_pad="11" + type="string" + width="85"> + DeepL API key: + </text> + + <line_editor + default_text="Enter DeepL API key and click "Verify"" + follows="top|left" + height="20" + layout="topleft" + left_pad="10" + max_length_chars="50" + top_delta="-4" + name="deepl_api_key" + width="210" /> + + <button + follows="left|top" + height="23" + label="Verify" + layout="topleft" + left_pad="10" + name="verify_deepl_api_key_btn" + top_delta="-2" + width="90" /> + + <text + follows="top|right" + height="20" + layout="topleft" + left="185" + length="1" + name="deepl_links_text" + top_delta="-53" + type="string" + width="100"> + [https://www.deepl.com/pro/select-country?cta=header-prices Pricing] + </text> + <button follows="left|top" height="23" -- cgit v1.2.3 From 27ee831e38b66bb3415c3df02fd2c518463ba404 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed <nat@lindenlab.com> Date: Fri, 19 May 2023 15:35:09 -0400 Subject: SL-19744: Remove LLErrorThread and LLAppViewer::handleViewerCrash() --- indra/llcommon/llapp.cpp | 38 +-------- indra/llcommon/llapp.h | 16 +--- indra/llcommon/llerror.h | 1 - indra/llcommon/llerrorthread.cpp | 133 ------------------------------ indra/llcommon/llerrorthread.h | 46 ----------- indra/newview/llappviewer.cpp | 159 ------------------------------------ indra/newview/llappviewer.h | 1 - indra/newview/llappviewerlinux.cpp | 2 - indra/newview/llappviewermacosx.cpp | 2 - indra/newview/llappviewerwin32.cpp | 2 - 10 files changed, 5 insertions(+), 395 deletions(-) delete mode 100644 indra/llcommon/llerrorthread.cpp delete mode 100644 indra/llcommon/llerrorthread.h (limited to 'indra') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index d839b19c99..89917b6324 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -39,7 +39,6 @@ #include "llcommon.h" #include "llapr.h" #include "llerrorcontrol.h" -#include "llerrorthread.h" #include "llframetimer.h" #include "lllivefile.h" #include "llmemory.h" @@ -108,12 +107,7 @@ LLAppErrorHandler LLApp::sErrorHandler = NULL; BOOL LLApp::sErrorThreadRunning = FALSE; -LLApp::LLApp() : mThreadErrorp(NULL) -{ - commonCtor(); -} - -void LLApp::commonCtor() +LLApp::LLApp() { // Set our status to running setStatus(APP_STATUS_RUNNING); @@ -143,12 +137,6 @@ void LLApp::commonCtor() mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe"; } -LLApp::LLApp(LLErrorThread *error_thread) : - mThreadErrorp(error_thread) -{ - commonCtor(); -} - LLApp::~LLApp() { @@ -158,13 +146,6 @@ LLApp::~LLApp() mLiveFiles.clear(); setStopped(); - // HACK: wait for the error thread to clean itself - ms_sleep(20); - if (mThreadErrorp) - { - delete mThreadErrorp; - mThreadErrorp = NULL; - } SUBSYSTEM_CLEANUP_DBG(LLCommon); } @@ -401,21 +382,6 @@ void LLApp::setupErrorHandling(bool second_instance) #endif } -void LLApp::startErrorThread() -{ - // - // Start the error handling thread, which is responsible for taking action - // when the app goes into the APP_STATUS_ERROR state - // - if(!mThreadErrorp) - { - LL_INFOS() << "Starting error thread" << LL_ENDL; - mThreadErrorp = new LLErrorThread(); - mThreadErrorp->setUserData((void *) this); - mThreadErrorp->start(); - } -} - void LLApp::setErrorHandler(LLAppErrorHandler handler) { LLApp::sErrorHandler = handler; @@ -476,7 +442,7 @@ void LLApp::setStatus(EAppStatus status) // static void LLApp::setError() { - // set app status to ERROR so that the LLErrorThread notices + // set app status to ERROR setStatus(APP_STATUS_ERROR); } diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index c65fe21c9c..436bc5437e 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -34,7 +34,6 @@ #include <atomic> #include <chrono> // Forward declarations -class LLErrorThread; class LLLiveFile; #if LL_LINUX #include <signal.h> @@ -53,7 +52,6 @@ void clear_signals(); class LL_COMMON_API LLApp { - friend class LLErrorThread; public: typedef enum e_app_status { @@ -67,11 +65,6 @@ public: LLApp(); virtual ~LLApp(); -protected: - LLApp(LLErrorThread* error_thread); - void commonCtor(); -public: - /** * @brief Return the static app instance if one was created. */ @@ -257,14 +250,14 @@ public: void setupErrorHandling(bool mSecondInstance=false); void setErrorHandler(LLAppErrorHandler handler); - static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred. + static void runErrorHandler(); // run shortly after we detect an error //@} - + // the maximum length of the minidump filename returned by getMiniDumpFilename() static const U32 MAX_MINDUMP_PATH_LENGTH = 256; // change the directory where Breakpad minidump files are written to - void setDebugFileNames(const std::string &path); + void setDebugFileNames(const std::string &path); // Return the Google Breakpad minidump filename after a crash. char *getMiniDumpFilename() { return mMinidumpPath; } @@ -324,9 +317,6 @@ private: typedef int(*signal_handler_func)(int signum); static LLAppErrorHandler sErrorHandler; - // Default application threads - LLErrorThread* mThreadErrorp; // Waits for app to go to status ERROR, then runs the error callback - // This is the application level runnable scheduler. LLRunner mRunner; diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index d06c0e2132..020f05e8f5 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -274,7 +274,6 @@ namespace LLError // used to indicate no class info known for logging //LLCallStacks keeps track of call stacks and output the call stacks to log file - //when LLAppViewer::handleViewerCrash() is triggered. // //Note: to be simple, efficient and necessary to keep track of correct call stacks, //LLCallStacks is designed not to be thread-safe. diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp deleted file mode 100644 index f6bc68b5c1..0000000000 --- a/indra/llcommon/llerrorthread.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @file llerrorthread.cpp - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "llerrorthread.h" - -#include "llapp.h" -#include "lltimer.h" // ms_sleep() - -LLErrorThread::LLErrorThread() - : LLThread("Error"), - mUserDatap(NULL) -{ -} - -LLErrorThread::~LLErrorThread() -{ -} - -void LLErrorThread::setUserData(void* user_data) -{ - mUserDatap = user_data; -} - - -void* LLErrorThread::getUserData() const -{ - return mUserDatap; -} - -#if !LL_WINDOWS -// -// Various signal/error handling functions that can't be put into the class -// -void get_child_status(const int waitpid_status, int &process_status, bool &exited, bool do_logging) -{ - exited = false; - process_status = -1; - // The child process exited. Call its callback, and then clean it up - if (WIFEXITED(waitpid_status)) - { - process_status = WEXITSTATUS(waitpid_status); - exited = true; - if (do_logging) - { - LL_INFOS() << "get_child_status - Child exited cleanly with return of " << process_status << LL_ENDL; - } - return; - } - else if (WIFSIGNALED(waitpid_status)) - { - process_status = WTERMSIG(waitpid_status); - exited = true; - if (do_logging) - { - LL_INFOS() << "get_child_status - Child died because of uncaught signal " << process_status << LL_ENDL; -#ifdef WCOREDUMP - if (WCOREDUMP(waitpid_status)) - { - LL_INFOS() << "get_child_status - Child dumped core" << LL_ENDL; - } - else - { - LL_INFOS() << "get_child_status - Child didn't dump core" << LL_ENDL; - } -#endif - } - return; - } - else if (do_logging) - { - // This is weird. I just dump the waitpid status into the status code, - // not that there's any way of telling what it is... - LL_INFOS() << "get_child_status - Got SIGCHILD but child didn't exit" << LL_ENDL; - process_status = waitpid_status; - } - -} -#endif - -void LLErrorThread::run() -{ - LLApp::sErrorThreadRunning = TRUE; - // This thread sits and waits for the sole purpose - // of waiting for the signal/exception handlers to flag the - // application state as APP_STATUS_ERROR. - LL_INFOS() << "thread_error - Waiting for an error" << LL_ENDL; - - S32 counter = 0; - while (! (LLApp::isError() || LLApp::isStopped())) - { - ms_sleep(10); - counter++; - } - if (LLApp::isError()) - { - // The app is in an error state, run the application's error handler. - //LL_INFOS() << "thread_error - An error has occurred, running error callback!" << LL_ENDL; - // Run the error handling callback - LLApp::runErrorHandler(); - } - else - { - // Everything is okay, a clean exit. - //LL_INFOS() << "thread_error - Application exited cleanly" << LL_ENDL; - } - - //LL_INFOS() << "thread_error - Exiting" << LL_ENDL; - LLApp::sErrorThreadRunning = FALSE; -} - diff --git a/indra/llcommon/llerrorthread.h b/indra/llcommon/llerrorthread.h deleted file mode 100644 index 474cef3a50..0000000000 --- a/indra/llcommon/llerrorthread.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @file llerrorthread.h - * @brief Specialized thread to handle runtime errors. - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLERRORTHREAD_H -#define LL_LLERRORTHREAD_H - -#include "llthread.h" - -class LL_COMMON_API LLErrorThread : public LLThread -{ -public: - LLErrorThread(); - ~LLErrorThread(); - - /*virtual*/ void run(void); - void setUserData(void *user_data); - void *getUserData() const; - -protected: - void* mUserDatap; // User data associated with this thread -}; - -#endif // LL_LLERRORTHREAD_H diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8235e4466c..e70fcb6e86 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3582,8 +3582,6 @@ void LLAppViewer::writeSystemInfo() // "CrashNotHandled" is set here, while things are running well, // in case of a freeze. If there is a freeze, the crash logger will be launched // and can read this value from the debug_info.log. - // If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze, - // then the value of "CrashNotHandled" will be set to true. gDebugInfo["CrashNotHandled"] = LLSD::Boolean(true); #else // LL_BUGSPLAT // "CrashNotHandled" is obsolete; it used (not very successsfully) @@ -3675,163 +3673,6 @@ void getFileList() } #endif -void LLAppViewer::handleViewerCrash() -{ - LL_INFOS("CRASHREPORT") << "Handle viewer crash entry." << LL_ENDL; - - LL_INFOS("CRASHREPORT") << "Last render pool type: " << LLPipeline::sCurRenderPoolType << LL_ENDL ; - - LLMemory::logMemoryInfo(true) ; - - //print out recorded call stacks if there are any. - LLError::LLCallStacks::print(); - - LLAppViewer* pApp = LLAppViewer::instance(); - if (pApp->beingDebugged()) - { - // This will drop us into the debugger. - abort(); - } - - if (LLApp::isCrashloggerDisabled()) - { - abort(); - } - - // Returns whether a dialog was shown. - // Only do the logic in here once - if (pApp->mReportedCrash) - { - return; - } - pApp->mReportedCrash = TRUE; - - // Insert crash host url (url to post crash log to) if configured. - std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl"); - if(crashHostUrl != "") - { - gDebugInfo["Dynamic"]["CrashHostUrl"] = crashHostUrl; - } - - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if ( parcel && parcel->getMusicURL()[0]) - { - gDebugInfo["Dynamic"]["ParcelMusicURL"] = parcel->getMusicURL(); - } - if ( parcel && parcel->getMediaURL()[0]) - { - gDebugInfo["Dynamic"]["ParcelMediaURL"] = parcel->getMediaURL(); - } - - gDebugInfo["Dynamic"]["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds()); - gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = LLSD::Integer(LLMemory::getCurrentRSS() / 1024); - - if(gLogoutInProgress) - { - gDebugInfo["Dynamic"]["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH; - } - else - { - gDebugInfo["Dynamic"]["LastExecEvent"] = gLLErrorActivated ? LAST_EXEC_LLERROR_CRASH : LAST_EXEC_OTHER_CRASH; - } - - if(gAgent.getRegion()) - { - gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegion()->getSimHostName(); - gDebugInfo["Dynamic"]["CurrentRegion"] = gAgent.getRegion()->getName(); - - const LLVector3& loc = gAgent.getPositionAgent(); - gDebugInfo["Dynamic"]["CurrentLocationX"] = loc.mV[0]; - gDebugInfo["Dynamic"]["CurrentLocationY"] = loc.mV[1]; - gDebugInfo["Dynamic"]["CurrentLocationZ"] = loc.mV[2]; - } - - if(LLAppViewer::instance()->mMainloopTimeout) - { - gDebugInfo["Dynamic"]["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); - } - - // The crash is being handled here so set this value to false. - // Otherwise the crash logger will think this crash was a freeze. - gDebugInfo["Dynamic"]["CrashNotHandled"] = LLSD::Boolean(false); - - //Write out the crash status file - //Use marker file style setup, as that's the simplest, especially since - //we're already in a crash situation - if (gDirUtilp) - { - std::string crash_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - gLLErrorActivated - ? LLERROR_MARKER_FILE_NAME - : ERROR_MARKER_FILE_NAME); - LLAPRFile crash_marker_file ; - crash_marker_file.open(crash_marker_file_name, LL_APR_WB); - if (crash_marker_file.getFileHandle()) - { - LL_INFOS("MarkerFile") << "Created crash marker file " << crash_marker_file_name << LL_ENDL; - recordMarkerVersion(crash_marker_file); - } - else - { - LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_marker_file_name << LL_ENDL; - } - } - else - { - LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL; - } - -#ifdef LL_WINDOWS - Sleep(200); -#endif - - char *minidump_file = pApp->getMiniDumpFilename(); - LL_DEBUGS("CRASHREPORT") << "minidump file name " << minidump_file << LL_ENDL; - if(minidump_file && minidump_file[0] != 0) - { - gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file; - } - else - { -#ifdef LL_WINDOWS - getFileList(); -#else - LL_WARNS("CRASHREPORT") << "no minidump file?" << LL_ENDL; -#endif - } - gDebugInfo["Dynamic"]["CrashType"]="crash"; - - if (gMessageSystem && gDirUtilp) - { - std::string filename; - filename = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "stats.log"); - LL_DEBUGS("CRASHREPORT") << "recording stats " << filename << LL_ENDL; - llofstream file(filename.c_str(), std::ios_base::binary); - if(file.good()) - { - gMessageSystem->summarizeLogs(file); - file.close(); - } - else - { - LL_WARNS("CRASHREPORT") << "problem recording stats" << LL_ENDL; - } - } - - if (gMessageSystem) - { - gMessageSystem->getCircuitInfo(gDebugInfo["CircuitInfo"]); - gMessageSystem->stopLogging(); - } - - if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo["Dynamic"]); - - gDebugInfo["FatalMessage"] = LLError::getFatalMessage(); - - // Close the debug file - pApp->writeDebugInfo(false); //false answers the isStatic question with the least overhead. -} - // static void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file) { diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index f28a90c703..bc4dec6bec 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -119,7 +119,6 @@ public: virtual bool restoreErrorTrap() = 0; // Require platform specific override to reset error handling mechanism. // return false if the error trap needed restoration. - static void handleViewerCrash(); // Hey! The viewer crashed. Do this, soon. void checkForCrash(); // Thread accessors diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index dc487967fc..9f58f90326 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -80,8 +80,6 @@ int main( int argc, char **argv ) // install unexpected exception handler gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); - // install crash handlers - viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); bool ok = viewer_app_ptr->init(); if(!ok) diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index cb5cac6f2d..8b313a321b 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -83,8 +83,6 @@ void constructViewer() } gViewerAppPtr = new LLAppViewerMacOSX(); - - gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash); } bool initViewer() diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index d22fb7a4e6..298d841934 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -428,8 +428,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); - viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); - // Set a debug info flag to indicate if multiple instances are running. bool found_other_instance = !create_app_mutex(); gDebugInfo["FoundOtherInstanceAtStartup"] = LLSD::Boolean(found_other_instance); -- cgit v1.2.3 From 863e7f22a75e9d9c9d5c1f826eac6cd0000edac0 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed <nat@lindenlab.com> Date: Fri, 19 May 2023 16:19:42 -0400 Subject: SL-19744: Remove LLApp::startErrorThread() and references. --- indra/llcommon/CMakeLists.txt | 2 -- indra/llcommon/llapp.cpp | 6 ------ indra/llcommon/llapp.h | 6 ++---- 3 files changed, 2 insertions(+), 12 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 54020a4231..ef4899978e 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -39,7 +39,6 @@ set(llcommon_SOURCE_FILES lldependencies.cpp lldictionary.cpp llerror.cpp - llerrorthread.cpp llevent.cpp lleventapi.cpp lleventcoro.cpp @@ -151,7 +150,6 @@ set(llcommon_HEADER_FILES llendianswizzle.h llerror.h llerrorcontrol.h - llerrorthread.h llevent.h lleventapi.h lleventcoro.h diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 89917b6324..b99166991f 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -374,12 +374,6 @@ void LLApp::setupErrorHandling(bool second_instance) #endif // ! LL_BUGSPLAT #endif // ! LL_WINDOWS - -#ifdef LL_BUGSPLAT - // do not start our own error thread -#else // ! LL_BUGSPLAT - startErrorThread(); -#endif } void LLApp::setErrorHandler(LLAppErrorHandler handler) diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 436bc5437e..c832c8b142 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -303,13 +303,11 @@ protected: void stepFrame(); private: - void startErrorThread(); - // Contains the filename of the minidump file after a crash. char mMinidumpPath[MAX_MINDUMP_PATH_LENGTH]; - std::string mStaticDebugFileName; - std::string mDynamicDebugFileName; + std::string mStaticDebugFileName; + std::string mDynamicDebugFileName; // *NOTE: On Windows, we need a routine to reset the structured // exception handler when some evil driver has taken it over for -- cgit v1.2.3 From 6f7cba0f9111c85d32d9ec4e9f52be5e7fbaaf9e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Tue, 23 May 2023 23:06:41 +0300 Subject: SL-19635 Better error handling --- indra/newview/lltranslate.cpp | 21 ++++++++++++++++++--- .../default/xui/en/floater_translation_settings.xml | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 70a40921ef..c37c955e8d 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -949,6 +949,8 @@ bool LLDeepLTranslationHandler::checkVerificationResponse( const LLSD& response, int status) const { + // Might need to parse body to make sure we got + // a valid response and not a message return status == HTTP_OK; } @@ -1000,7 +1002,6 @@ bool LLDeepLTranslationHandler::parseResponse( { return false; } - detected_lang = data["detected_source_language"].asString(); LLStringUtil::toLower(detected_lang); @@ -1019,8 +1020,22 @@ bool LLDeepLTranslationHandler::isConfigured() const std::string LLDeepLTranslationHandler::parseErrorResponse( const std::string& body) { - // DeepL doesn't seem to have any error handling beyoun http codes - return std::string(); + // Example: "{\"message\":\"One of the request inputs is not valid.\"}" + + Json::Value root; + Json::Reader reader; + + if (!reader.parse(body, root)) + { + return std::string(); + } + + if (!root.isObject() || !root.isMember("message")) + { + return std::string(); + } + + return root["message"].asString(); } // static diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml index 8a97d5e5d9..3f3331b468 100644 --- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml @@ -319,7 +319,7 @@ name="deepl_api_domain_label" top_pad="80" width="85"> - Domain: + Endpoint: </text> <combo_box -- cgit v1.2.3 From 6586055320922b4219d382f24383b00e20387e03 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Mon, 29 May 2023 21:04:52 +0300 Subject: SL-19787 Crash at LLUIColor::operator --- indra/llui/lluicolortable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index b84bb13edb..096336045c 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -230,7 +230,7 @@ void LLUIColorTable::saveUserSettings() const { // Compare user color value with the default value, skip if equal string_color_map_t::const_iterator itd = mLoadedColors.find(it->first); - if(itd != mUserSetColors.end() && itd->second == it->second) + if(itd != mLoadedColors.end() && itd->second == it->second) continue; ColorEntryParams color_entry; -- cgit v1.2.3 From 5b9b4fcf6657ce2cfa5fde85012fe24213df37b5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Mon, 29 May 2023 23:37:58 +0300 Subject: SL-17429 Message user when their inventory hits AIS2 limits --- indra/newview/llinventorymodelbackgroundfetch.cpp | 25 +++++++++++++++++++--- .../newview/skins/default/xui/en/notifications.xml | 8 +++++++ 2 files changed, 30 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 6b88d0aaf7..f544b318d6 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -30,8 +30,10 @@ #include "llagent.h" #include "llappviewer.h" #include "llcallbacklist.h" -#include "llinventorypanel.h" #include "llinventorymodel.h" +#include "llinventorypanel.h" +#include "llnotificationsutil.h" +#include "llstartup.h" #include "llviewercontrol.h" #include "llviewerinventory.h" #include "llviewermessage.h" @@ -802,12 +804,24 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http if(status == LLCore::HttpStatus(HTTP_FORBIDDEN)) { - // too large, split into two, assume that this isn't the library + // Too large, split into two if possible + if (gDisconnected || LLApp::isExiting()) + { + return; + } + const std::string url(gAgent.getRegionCapability("FetchInventoryDescendents2")); + if (url.empty()) + { + LL_WARNS(LOG_INV) << "Failed to get AIS2 cap" << LL_ENDL; + return; + } + S32 size = mRequestSD["folders"].size(); - if (!gDisconnected && !LLApp::isExiting() && !url.empty() && size > 1) + if (size > 1) { + // Can split, assume that this isn't the library LLSD folders; uuid_vec_t recursive_cats; LLSD::array_iterator iter = mRequestSD["folders"].beginArray(); @@ -838,6 +852,11 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http gInventory.requestPost(false, url, request_body, handler, "Inventory Folder"); return; } + else + { + // Can't split + LLNotificationsUtil::add("InventoryLimitReachedAIS"); + } } // This was originally the request retry logic for the inventory diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f9211600ea..a216ef7c0d 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6369,6 +6369,14 @@ Your trash is overflowing. This may cause problems logging in. yestext="Check trash folder"/> </notification> + <notification + icon="notifytip.tga" + name="InventoryLimitReachedAIS" + type="notifytip"> +Your inventory is experiencing issues. Please, contact support. + <tag>fail</tag> + </notification> + <notification icon="alertmodal.tga" name="ConfirmClearBrowserCache" -- cgit v1.2.3 From 6e30df2f370dd3b382a7404484e72a47adaf921e Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine <mnikolenko@productengine.com> Date: Thu, 1 Jun 2023 17:37:10 +0300 Subject: SL-19762 fix for cropped label text --- indra/llui/lltextbox.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index c567451973..521dabf9d4 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -171,7 +171,8 @@ void LLTextBox::reshapeToFitText(BOOL called_from_parent) S32 width = getTextPixelWidth(); S32 height = getTextPixelHeight(); - reshape( width + 2 * mHPad, height + 2 * mVPad, called_from_parent ); + //consider investigating reflow() to find missing width pixel (see SL-17045 changes) + reshape( width + 2 * mHPad + 1, height + 2 * mVPad, called_from_parent ); } -- cgit v1.2.3 From d134d155e2ddaf07ba1cdac50c1e31781e451ee5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Thu, 1 Jun 2023 22:15:33 +0300 Subject: SL-19806 Crash at vobj --- indra/newview/lldrawpool.cpp | 12 ++++++------ indra/newview/lldrawpoolalpha.cpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'indra') diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 594cfe513d..3fd15d36df 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -402,7 +402,7 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t if(pparams->mFace) { LLViewerObject* vobj = pparams->mFace->getViewerObject(); - if(vobj->isAttachment()) + if(vobj && vobj->isAttachment()) { trackAttachments(vobj, false, &ratPtr); } @@ -429,7 +429,7 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, if(pparams->mFace) { LLViewerObject* vobj = pparams->mFace->getViewerObject(); - if(vobj->isAttachment()) + if(vobj && vobj->isAttachment()) { trackAttachments( vobj, true ,&ratPtr); } @@ -459,7 +459,7 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text if(pparams->mFace) { LLViewerObject* vobj = pparams->mFace->getViewerObject(); - if(vobj->isAttachment()) + if(vobj && vobj->isAttachment()) { trackAttachments( vobj, false, &ratPtr); } @@ -484,7 +484,7 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc if(pparams->mFace) { LLViewerObject* vobj = pparams->mFace->getViewerObject(); - if(vobj->isAttachment()) + if(vobj && vobj->isAttachment()) { trackAttachments( vobj, true, &ratPtr); } @@ -514,7 +514,7 @@ void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_ if((*pparams).mFace) { LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); - if(vobj->isAttachment()) + if(vobj && vobj->isAttachment()) { trackAttachments( vobj, false, &ratPtr); } @@ -539,7 +539,7 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL if((*pparams).mFace) { LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); - if(vobj->isAttachment()) + if(vobj && vobj->isAttachment()) { trackAttachments( vobj, true, &ratPtr); } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index edd0afe357..ab1ac7e30c 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -349,7 +349,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) if(params.mFace) { LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); - if(vobj->isAttachment()) + if(vobj && vobj->isAttachment()) { trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); } @@ -622,7 +622,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) { LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); - if(vobj->isAttachment()) + if(vobj && vobj->isAttachment()) { trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); } -- cgit v1.2.3 From 85967398ff8591170d89374652a6998ff6cd3d69 Mon Sep 17 00:00:00 2001 From: RunitaiLinden <davep@lindenlab.com> Date: Wed, 21 Jun 2023 20:50:50 -0500 Subject: SL-19792 Fix for visible gaps in water between region water and void water. --- indra/newview/app_settings/settings.xml | 27 +++++++++----- .../shaders/class1/windlight/atmosphericsF.glsl | 2 -- indra/newview/llreflectionmapmanager.cpp | 5 +-- indra/newview/llsettingsvo.cpp | 8 +++-- indra/newview/llvowater.cpp | 41 +++++++++++----------- 5 files changed, 48 insertions(+), 35 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2b2a2d9d1b..f3065d12b8 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10590,27 +10590,38 @@ <key>Value</key> <integer>3</integer> </map> - <key>RenderSkyHDRScale</key> + <key>RenderSkyAutoAdjustLegacy</key> <map> <key>Comment</key> - <string>Amount to over-brighten sun for HDR effect during the day</string> + <string>If true, automatically adjust legacy skies (those without a probe ambiance value) to take advantage of probes and HDR. This is the "opt-out" button for HDR and tonemapping when coupled with a sky setting that predates PBR.</string> <key>Persist</key> - <integer>0</integer> + <integer>1</integer> <key>Type</key> - <string>F32</string> + <string>Boolean</string> <key>Value</key> - <real>1.0</real> + <integer>1</integer> </map> - <key>RenderSkyAutoAdjustLegacy</key> + <key>RenderSkyAutoAdjustAmbientScale</key> <map> <key>Comment</key> - <string>If true, automatically adjust legacy skies (those without a probe ambiance value) to take advantage of probes and HDR. This is the "opt-out" button for HDR and tonemapping when coupled with a sky setting that predates PBR.</string> + <string>Amount to scale ambient when auto-adjusting legacy skies</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>Boolean</string> + <string>F32</string> <key>Value</key> + <real>0.5</real> + </map> + <key>RenderSkyAutoAdjustHDRScale</key> + <map> + <key>Comment</key> + <string>HDR Scale value to use when auto-adjusting legacy skies</string> + <key>Persist</key> <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>2.0</real> </map> <key>RenderReflectionProbeMaxLocalLightAmbiance</key> <map> diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl index 48cf234aa0..41a848a14f 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl @@ -36,8 +36,6 @@ vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten) { light *= atten.r; additive = srgb_to_linear(additive*2.0); - // magic 1.25 here is to match the default RenderSkyHDRScale -- this parameter needs to be plumbed into sky settings or something - // so it's available to all shaders that call atmosFragLighting instead of just softenLightF.glsl additive *= sky_hdr_scale; light += additive; return light; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index e30aba3df7..779fe8bfd9 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -924,8 +924,9 @@ void LLReflectionMapManager::updateUniforms() static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale, should_auto_adjust); - F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f; - F32 radscale = gCubeSnapshot && !isRadiancePass() ? 0.5f : 1.f; + bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass(); + F32 ambscale = is_ambiance_pass ? 0.f : 1.f; + F32 radscale = is_ambiance_pass ? 0.5f : 1.f; for (auto* refmap : mReflectionMaps) { diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 258cc1c7b2..264359a3a9 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -719,6 +719,8 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) F32 g = getGamma(); static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + static LLCachedControl<F32> auto_adjust_ambient_scale(gSavedSettings, "RenderSkyAutoAdjustAmbientScale", 0.75f); + static LLCachedControl<F32> auto_adjust_hdr_scale(gSavedSettings, "RenderSkyAutoAdjustHDRScale", 2.f); static LLCachedControl<F32> cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f); F32 probe_ambiance = getTotalReflectionProbeAmbiance(cloud_shadow_scale); @@ -736,9 +738,9 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) } else if (psky->canAutoAdjust() && should_auto_adjust) { // auto-adjust legacy sky to take advantage of probe ambiance - shader->uniform3fv(LLShaderMgr::AMBIENT, (ambient * 0.5f).mV); - shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, 2.f); - probe_ambiance = 1.f; + shader->uniform3fv(LLShaderMgr::AMBIENT, (ambient * auto_adjust_ambient_scale).mV); + shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, auto_adjust_hdr_scale); + probe_ambiance = 1.f; // NOTE -- must match LLSettingsSky::getReflectionProbeAmbiance value for "auto_adjust" true } else { diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 608d2cb799..77ad967cef 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -142,9 +142,14 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) static const unsigned int vertices_per_quad = 4; static const unsigned int indices_per_quad = 6; - const S32 size = LLPipeline::sRenderTransparentWater ? 16 : 1; + S32 size_x = LLPipeline::sRenderTransparentWater ? 8 : 1; + S32 size_y = LLPipeline::sRenderTransparentWater ? 8 : 1; - const S32 num_quads = size * size; + const LLVector3& scale = getScale(); + size_x *= llmin(llround(scale.mV[0] / 256.f), 8); + size_y *= llmin(llround(scale.mV[1] / 256.f), 8); + + const S32 num_quads = size_x * size_y; face->setSize(vertices_per_quad * num_quads, indices_per_quad * num_quads); @@ -175,41 +180,37 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) face->mCenterLocal = position_agent; S32 x, y; - F32 step_x = getScale().mV[0] / size; - F32 step_y = getScale().mV[1] / size; + F32 step_x = getScale().mV[0] / size_x; + F32 step_y = getScale().mV[1] / size_y; const LLVector3 up(0.f, step_y * 0.5f, 0.f); const LLVector3 right(step_x * 0.5f, 0.f, 0.f); const LLVector3 normal(0.f, 0.f, 1.f); - F32 size_inv = 1.f / size; - - F32 z_fudge = 0.f; + F32 size_inv_x = 1.f / size_x; + F32 size_inv_y = 1.f / size_y; - if (getIsEdgePatch()) - { //bump edge patches down 10 cm to prevent aliasing along edges - z_fudge = -0.1f; - } - - for (y = 0; y < size; y++) + for (y = 0; y < size_y; y++) { - for (x = 0; x < size; x++) + for (x = 0; x < size_x; x++) { - S32 toffset = index_offset + 4*(y*size + x); + S32 toffset = index_offset + 4*(y*size_x + x); position_agent = getPositionAgent() - getScale() * 0.5f; position_agent.mV[VX] += (x + 0.5f) * step_x; position_agent.mV[VY] += (y + 0.5f) * step_y; - position_agent.mV[VZ] += z_fudge; + + position_agent.mV[VX] = llround(position_agent.mV[VX]); + position_agent.mV[VY] = llround(position_agent.mV[VY]); *verticesp++ = position_agent - right + up; *verticesp++ = position_agent - right - up; *verticesp++ = position_agent + right + up; *verticesp++ = position_agent + right - up; - *texCoordsp++ = LLVector2(x*size_inv, (y+1)*size_inv); - *texCoordsp++ = LLVector2(x*size_inv, y*size_inv); - *texCoordsp++ = LLVector2((x+1)*size_inv, (y+1)*size_inv); - *texCoordsp++ = LLVector2((x+1)*size_inv, y*size_inv); + *texCoordsp++ = LLVector2(x*size_inv_x, (y+1)*size_inv_y); + *texCoordsp++ = LLVector2(x*size_inv_x, y*size_inv_y); + *texCoordsp++ = LLVector2((x+1)*size_inv_x, (y+1)*size_inv_y); + *texCoordsp++ = LLVector2((x+1)*size_inv_x, y*size_inv_y); *normalsp++ = normal; *normalsp++ = normal; -- cgit v1.2.3 From 4e6303792a49e4db7a30ab5774668eb54b6a50b2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Thu, 22 Jun 2023 00:53:18 +0300 Subject: SL-5161 Don't render meshes that are waiting for skin data --- indra/newview/llmeshrepository.cpp | 54 ++++++++++++++++++++++++++++++++ indra/newview/llmeshrepository.h | 4 +++ indra/newview/llvovolume.cpp | 63 ++++++++++++++++++++++++++++---------- indra/newview/llvovolume.h | 3 +- 4 files changed, 107 insertions(+), 17 deletions(-) (limited to 'indra') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 67bf6827ad..9f90e132f8 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4255,6 +4255,37 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) return false; } +bool LLMeshRepository::hasSkinInfo(const LLUUID& mesh_id) +{ + if (mesh_id.isNull()) + { + return false; + } + + if (mThread->hasSkinInfoInHeader(mesh_id)) + { + return true; + } + + const LLMeshSkinInfo* skininfo = getSkinInfo(mesh_id); + if (skininfo) + { + return true; + } + + return false; +} + +bool LLMeshRepository::hasHeader(const LLUUID& mesh_id) +{ + if (mesh_id.isNull()) + { + return false; + } + + return mThread->hasHeader(mesh_id); +} + bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) { LLMutexLock lock(mHeaderMutex); @@ -4271,6 +4302,29 @@ bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) return false; } +bool LLMeshRepoThread::hasSkinInfoInHeader(const LLUUID& mesh_id) +{ + LLMutexLock lock(mHeaderMutex); + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); + if (iter != mMeshHeader.end() && iter->second.first > 0) + { + LLMeshHeader& mesh = iter->second.second; + if (mesh.mSkinOffset >= 0 + && mesh.mSkinSize > 0) + { + return true; + } + } + + return false; +} + +bool LLMeshRepoThread::hasHeader(const LLUUID& mesh_id) +{ + LLMutexLock lock(mHeaderMutex); + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); + return iter != mMeshHeader.end(); +} void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 619e076fa6..89cd2d867f 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -401,6 +401,8 @@ public: bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size); EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); bool hasPhysicsShapeInHeader(const LLUUID& mesh_id); + bool hasSkinInfoInHeader(const LLUUID& mesh_id); + bool hasHeader(const LLUUID& mesh_id); void notifyLoadedMeshes(); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); @@ -650,6 +652,8 @@ public: LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id); void fetchPhysicsShape(const LLUUID& mesh_id); bool hasPhysicsShape(const LLUUID& mesh_id); + bool hasSkinInfo(const LLUUID& mesh_id); + bool hasHeader(const LLUUID& mesh_id); void buildHull(const LLVolumeParams& params, S32 detail); void buildPhysicsMesh(LLModel::Decomposition& decomp); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8160785d75..805eb47431 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -230,7 +230,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mColorChanged = FALSE; mSpotLightPriority = 0.f; - mSkinInfoFailed = false; + mSkinInfoUnavaliable = false; mSkinInfo = NULL; mMediaImplList.resize(getNumTEs()); @@ -1132,7 +1132,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID()) { mSkinInfo = NULL; - mSkinInfoFailed = false; + mSkinInfoUnavaliable = false; } if (!getVolume()->isMeshAssetLoaded()) @@ -1145,13 +1145,24 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } - if (!mSkinInfo && !mSkinInfoFailed) + if (!mSkinInfo && !mSkinInfoUnavaliable) { - const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(volume_params.getSculptID(), this); - if (skin_info) - { - notifySkinInfoLoaded(skin_info); - } + LLUUID mesh_id = volume_params.getSculptID(); + if (gMeshRepo.hasHeader(mesh_id) && !gMeshRepo.hasSkinInfo(mesh_id)) + { + // If header is present but has no data about skin, + // no point fetching + mSkinInfoUnavaliable = true; + } + + if (!mSkinInfoUnavaliable) + { + const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(mesh_id, this); + if (skin_info) + { + notifySkinInfoLoaded(skin_info); + } + } } } else // otherwise is sculptie @@ -1186,7 +1197,7 @@ void LLVOVolume::updateSculptTexture() mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); } - mSkinInfoFailed = false; + mSkinInfoUnavaliable = false; mSkinInfo = NULL; } else @@ -1227,6 +1238,16 @@ void LLVOVolume::notifyMeshLoaded() mSculptChanged = TRUE; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); + if (!mSkinInfo && !mSkinInfoUnavaliable) + { + // Header was loaded, update skin info state from header + LLUUID mesh_id = getVolume()->getParams().getSculptID(); + if (!gMeshRepo.hasSkinInfo(mesh_id)) + { + mSkinInfoUnavaliable = true; + } + } + LLVOAvatar *av = getAvatar(); if (av && !isAnimatedObject()) { @@ -1244,7 +1265,7 @@ void LLVOVolume::notifyMeshLoaded() void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin) { - mSkinInfoFailed = false; + mSkinInfoUnavaliable = false; mSkinInfo = skin; notifyMeshLoaded(); @@ -1252,7 +1273,7 @@ void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin) void LLVOVolume::notifySkinInfoUnavailable() { - mSkinInfoFailed = true; + mSkinInfoUnavaliable = true; mSkinInfo = nullptr; } @@ -5589,11 +5610,21 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) std::string vobj_name = llformat("Vol%p", vobj); bool is_mesh = vobj->isMesh(); - if (is_mesh && - ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled())) - { - continue; - } + if (is_mesh) + { + if ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) + || !gMeshRepo.meshRezEnabled()) + { + // Waiting for asset to fetch + continue; + } + + if (!vobj->getSkinInfo() && !vobj->isSkinInfoUnavaliable()) + { + // Waiting for skin info to fetch + continue; + } + } LLVolume* volume = vobj->getVolume(); if (volume) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index acba18383f..aadc1fbcf3 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -330,6 +330,7 @@ public: BOOL setIsFlexible(BOOL is_flexible); const LLMeshSkinInfo* getSkinInfo() const; + const bool isSkinInfoUnavaliable() const { return mSkinInfoUnavaliable; } //convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons) const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); } @@ -480,7 +481,7 @@ private: LLPointer<LLRiggedVolume> mRiggedVolume; - bool mSkinInfoFailed; + bool mSkinInfoUnavaliable; LLConstPointer<LLMeshSkinInfo> mSkinInfo; // statics public: -- cgit v1.2.3 From 3a1b60b2baa80218a79bf33cf983bd28df4f2343 Mon Sep 17 00:00:00 2001 From: RunitaiLinden <davep@lindenlab.com> Date: Thu, 22 Jun 2023 17:10:24 -0500 Subject: SL-19785 Fix for blown out skies from Glow Focus. Add notification when editing legacy skies. --- indra/llinventory/llsettingssky.cpp | 1 + .../app_settings/shaders/class1/deferred/cloudsF.glsl | 2 +- indra/newview/llfloaterenvironmentadjust.cpp | 7 +++++-- indra/newview/llfloaterfixedenvironment.cpp | 6 ++++++ indra/newview/llpaneleditsky.cpp | 5 ++++- indra/newview/skins/default/xui/en/notifications.xml | 12 ++++++++++++ 6 files changed, 29 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 6521ec8b43..8338245897 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -1142,6 +1142,7 @@ void LLSettingsSky::setSkyIceLevel(F32 ice_level) void LLSettingsSky::setReflectionProbeAmbiance(F32 ambiance) { + mCanAutoAdjust = false; // we've now touched this sky in a "new" way, it can no longer auto adjust setValue(SETTING_REFLECTION_PROBE_AMBIANCE, ambiance); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl index e0e97bb938..f6870c3ff0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl @@ -110,7 +110,7 @@ void main() // Combine vec3 color; color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient); - color.rgb= max(vec3(0), color.rgb); + color.rgb = clamp(color.rgb, vec3(0), vec3(1)); color.rgb *= 2.0; /// Gamma correct for WL (soft clip effect). diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp index f9e8963479..18be4fffda 100644 --- a/indra/newview/llfloaterenvironmentadjust.cpp +++ b/indra/newview/llfloaterenvironmentadjust.cpp @@ -174,7 +174,8 @@ void LLFloaterEnvironmentAdjust::refresh() getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setValue(mLiveSky->getCloudNoiseTextureId()); getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setValue(mLiveWater->getNormalMapID()); - getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(mLiveSky->getReflectionProbeAmbiance()); + static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(mLiveSky->getReflectionProbeAmbiance(should_auto_adjust)); LLColor3 glow(mLiveSky->getGlow()); @@ -488,7 +489,9 @@ void LLFloaterEnvironmentAdjust::onReflectionProbeAmbianceChanged() void LLFloaterEnvironmentAdjust::updateGammaLabel() { if (!mLiveSky) return; - F32 ambiance = mLiveSky->getReflectionProbeAmbiance(); + + static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + F32 ambiance = mLiveSky->getReflectionProbeAmbiance(should_auto_adjust); if (ambiance != 0.f) { childSetValue("scene_gamma_label", getString("hdr_string")); diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index b9dc14ac1a..bb6584302d 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -182,6 +182,12 @@ void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::p syncronizeTabs(); refresh(); LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT); + + // teach user about HDR settings + if (mSettings && ((LLSettingsSky*)mSettings.get())->canAutoAdjust()) + { + LLNotificationsUtil::add("AutoAdjustHDRSky"); + } } void LLFloaterFixedEnvironment::syncronizeTabs() diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp index a14af27e59..761d856aae 100644 --- a/indra/newview/llpaneleditsky.cpp +++ b/indra/newview/llpaneleditsky.cpp @@ -36,6 +36,7 @@ #include "llsettingssky.h" #include "llenvironment.h" #include "llatmosphere.h" +#include "llviewercontrol.h" namespace { @@ -207,7 +208,9 @@ void LLPanelSettingsSkyAtmosTab::refresh() F32 moisture_level = mSkySettings->getSkyMoistureLevel(); F32 droplet_radius = mSkySettings->getSkyDropletRadius(); F32 ice_level = mSkySettings->getSkyIceLevel(); - F32 rp_ambiance = mSkySettings->getReflectionProbeAmbiance(); + + static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + F32 rp_ambiance = mSkySettings->getReflectionProbeAmbiance(should_auto_adjust); getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setValue(moisture_level); getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setValue(droplet_radius); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 4949075f2d..f77b235408 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -12097,5 +12097,17 @@ Material successfully created. Asset ID: [ASSET_ID] notext="Cancel" yestext="OK"/> </notification> + + <notification + icon="notifytip.tga" + name="AutoAdjustHDRSky" + persist="true" + type="alertmodal"> + You are editing a non-HDR sky that has been automatically converted to HDR. To remove HDR and tone mapping, set Reflection Probe Ambiance to zero. + <usetemplate + ignoretext="HDR Sky adjustment warning" + name="okignore" + yestext="OK"/> + </notification> </notifications> -- cgit v1.2.3 From ca84e0e0c0b4b2844f478a549cb2cb1fbb52c898 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Thu, 22 Jun 2023 22:09:42 +0300 Subject: SL-5161 Avatars should stay hidden longer if they are waiting for meshes or skin data --- indra/llmath/llvolume.cpp | 25 ++++++++++-- indra/llmath/llvolume.h | 9 +++-- indra/newview/llmeshrepository.cpp | 8 +++- indra/newview/llvoavatar.cpp | 80 ++++++++++++++++++++++++++++++++++++++ indra/newview/llvoavatar.h | 1 + 5 files changed, 116 insertions(+), 7 deletions(-) (limited to 'indra') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 91e463cc32..0e3792fda3 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2056,7 +2056,8 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mDetail = detail; mSculptLevel = -2; mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims - mIsMeshAssetLoaded = FALSE; + mIsMeshAssetLoaded = false; + mIsMeshAssetUnavaliable = false; mLODScaleBias.setVec(1,1,1); mHullPoints = NULL; mHullIndices = NULL; @@ -2804,14 +2805,32 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) } -BOOL LLVolume::isMeshAssetLoaded() +bool LLVolume::isMeshAssetLoaded() { return mIsMeshAssetLoaded; } -void LLVolume::setMeshAssetLoaded(BOOL loaded) +void LLVolume::setMeshAssetLoaded(bool loaded) { mIsMeshAssetLoaded = loaded; + if (loaded) + { + mIsMeshAssetUnavaliable = false; + } +} + +void LLVolume::setMeshAssetUnavaliable(bool unavaliable) +{ + // Don't set it if at least one lod loaded + if (!mIsMeshAssetLoaded) + { + mIsMeshAssetUnavaliable = unavaliable; + } +} + +bool LLVolume::isMeshAssetUnavaliable() +{ + return mIsMeshAssetUnavaliable; } void LLVolume::copyFacesTo(std::vector<LLVolumeFace> &faces) const diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index ad6a669531..afed98ff36 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1111,15 +1111,18 @@ private: bool unpackVolumeFacesInternal(const LLSD& mdl); public: - virtual void setMeshAssetLoaded(BOOL loaded); - virtual BOOL isMeshAssetLoaded(); + virtual void setMeshAssetLoaded(bool loaded); + virtual bool isMeshAssetLoaded(); + virtual void setMeshAssetUnavaliable(bool unavaliable); + virtual bool isMeshAssetUnavaliable(); protected: BOOL mUnique; F32 mDetail; S32 mSculptLevel; F32 mSurfaceArea; //unscaled surface area - BOOL mIsMeshAssetLoaded; + bool mIsMeshAssetLoaded; + bool mIsMeshAssetUnavaliable; const LLVolumeParams mParams; LLPath *mPathp; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 9f90e132f8..57ac111fdf 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4067,7 +4067,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol if (sys_volume) { sys_volume->copyVolumeFaces(volume); - sys_volume->setMeshAssetLoaded(TRUE); + sys_volume->setMeshAssetLoaded(true); LLPrimitive::getVolumeManager()->unrefVolume(sys_volume); } else @@ -4099,6 +4099,12 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, { F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); + LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, detail); + if (sys_volume) + { + sys_volume->setMeshAssetUnavaliable(true); + } + for (LLVOVolume* vobj : obj_iter->second) { if (vobj) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index c7a2cea627..22cd9f71b3 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7574,6 +7574,85 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) } } +bool LLVOAvatar::hasPendingAttachedMeshes() +{ + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* objectp = attachment_iter->get(); + if (objectp) + { + LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); + iter1 != child_list.end(); ++iter1) + { + LLViewerObject* objectchild = *iter1; + if (objectchild && objectchild->getVolume()) + { + const LLUUID& mesh_id = objectchild->getVolume()->getParams().getSculptID(); + if (mesh_id.isNull()) + { + // No mesh nor skin info needed + continue; + } + + if (objectchild->getVolume()->isMeshAssetUnavaliable()) + { + // Mesh failed to load, do not expect it + continue; + } + + if (objectchild->mDrawable) + { + LLVOVolume* pvobj = objectchild->mDrawable->getVOVolume(); + if (pvobj) + { + if (!pvobj->isMesh()) + { + // Not a mesh + continue; + } + + if (!objectchild->getVolume()->isMeshAssetLoaded()) + { + // Waiting for mesh + return true; + } + + const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo(); + if (skin_data) + { + // Skin info present, done + continue; + } + + if (pvobj->isSkinInfoUnavaliable()) + { + // Load failed or info not present, don't expect it + continue; + } + } + + // objectchild is not ready + return true; + } + } + } + } + } + } + } + return false; +} + //----------------------------------------------------------------------------- // detachObject() //----------------------------------------------------------------------------- @@ -8150,6 +8229,7 @@ BOOL LLVOAvatar::updateIsFullyLoaded() || (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC) || !mPendingAttachment.empty() || (rez_status < 3 && !isFullyBaked()) + || hasPendingAttachedMeshes() ); } updateRezzedStatusTimers(rez_status); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index f1dc503c9e..48bfd5293a 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -917,6 +917,7 @@ public: virtual BOOL detachObject(LLViewerObject *viewer_object); static bool getRiggedMeshID( LLViewerObject* pVO, LLUUID& mesh_id ); void cleanupAttachedMesh( LLViewerObject* pVO ); + bool hasPendingAttachedMeshes(); static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const; LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const; -- cgit v1.2.3 From f137e04c38ece6a26709378f4adbe15d54f023a1 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> Date: Fri, 23 Jun 2023 02:09:35 +0200 Subject: SL-19805 Second Life Viewer last update made invisible parts visible --- indra/newview/llvovolume.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 7a73ee1339..efcb049c3f 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5864,9 +5864,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) add_face(sAlphaFaces, alpha_count, facep); } else if (LLDrawPoolAlpha::sShowDebugAlpha || - (gPipeline.sRenderHighlight && - (LLPipeline::getRenderScriptedBeacons() || LLPipeline::getRenderScriptedTouchBeacons()) && - drawablep->getVObj() && drawablep->getVObj()->flagScripted())) + (gPipeline.sRenderHighlight && !drawablep->getParent() && + drawablep->getVObj() && drawablep->getVObj()->flagScripted() && + (LLPipeline::getRenderScriptedBeacons() || + LLPipeline::getRenderScriptedTouchBeacons() && drawablep->getVObj()->flagHandleTouch()))) { //draw the transparent face for debugging purposes using a custom texture add_face(sAlphaFaces, alpha_count, facep); } -- cgit v1.2.3 From 22eecf1018d8adbf214b9f1072b3cd6d3ab3d5ae Mon Sep 17 00:00:00 2001 From: RunitaiLinden <davep@lindenlab.com> Date: Fri, 23 Jun 2023 11:46:09 -0500 Subject: SL-19897 Fix for 100% transparent objects not showing up in highlight transparent until LoD switch. --- indra/newview/llspatialpartition.cpp | 37 ++---------------------------------- indra/newview/llspatialpartition.h | 5 +++-- indra/newview/llviewermenu.cpp | 7 +++---- indra/newview/pipeline.cpp | 34 ++++++++++++++++++++++++++++++--- indra/newview/pipeline.h | 5 ++++- 5 files changed, 43 insertions(+), 45 deletions(-) (limited to 'indra') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 978cb78083..f52f1a925d 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -777,7 +777,8 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c assert_states_valid(this); } -void LLSpatialGroup::destroyGL(bool keep_occlusion) + +void LLSpatialGroup::destroyGLState(bool keep_occlusion) { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); @@ -1290,45 +1291,11 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size) drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size)); } -class LLOctreeDirty : public OctreeTraveler -{ -public: - virtual void visit(const OctreeNode* state) - { - LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); - group->destroyGL(); - - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(!drawable) - { - continue; - } - if (drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup) - { - gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL); - } - } - - for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) - { - LLSpatialBridge* bridge = *i; - traverse(bridge->mOctree); - } - } -}; void LLSpatialPartition::restoreGL() { } -void LLSpatialPartition::resetVertexBuffers() -{ - LLOctreeDirty dirty; - dirty.traverse(mOctree); -} - BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) { LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 053ce9e60b..88584f535a 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -295,7 +295,9 @@ public: BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE); BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group void shift(const LLVector4a &offset); - void destroyGL(bool keep_occlusion = false); + + // TODO: this no longer appears to be called, figure out if it's important and if not remove it + void destroyGLState(bool keep_occlusion = false); void updateDistance(LLCamera& camera); F32 getUpdateUrgency() const; @@ -419,7 +421,6 @@ public: void renderDebug(); void renderIntersectingBBoxes(LLCamera* camera); void restoreGL(); - void resetVertexBuffers(); BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b9042b3496..6e5c268c00 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7826,10 +7826,6 @@ class LLToggleShaderControl : public view_listener_t BOOL checked = gSavedSettings.getBOOL( control_name ); gSavedSettings.setBOOL( control_name, !checked ); LLPipeline::refreshCachedSettings(); - //gPipeline.updateRenderDeferred(); - //gPipeline.releaseGLBuffers(); - //gPipeline.createGLBuffers(); - //gPipeline.resetVertexBuffers(); LLViewerShaderMgr::instance()->setShaders(); return !checked; } @@ -8560,6 +8556,9 @@ class LLViewHighlightTransparent : public view_listener_t bool handleEvent(const LLSD& userdata) { LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha; + + // invisible objects skip building their render batches unless sShowDebugAlpha is true, so rebuild batches whenever toggling this flag + gPipeline.rebuildDrawInfo(); return true; } }; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 38f27d4dfa..e64ef6d555 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -10593,8 +10593,36 @@ void LLPipeline::handleShadowDetailChanged() } } -void LLPipeline::overrideEnvironmentMap() +class LLOctreeDirty : public OctreeTraveler { - //mReflectionMapManager.mProbes.clear(); - //mReflectionMapManager.addProbe(LLViewerCamera::instance().getOrigin()); +public: + virtual void visit(const OctreeNode* state) + { + LLSpatialGroup* group = (LLSpatialGroup*)state->getListener(0); + + group->setState(LLSpatialGroup::GEOM_DIRTY); + gPipeline.markRebuild(group); + + for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) + { + LLSpatialBridge* bridge = *i; + traverse(bridge->mOctree); + } + } +}; + + +void LLPipeline::rebuildDrawInfo() +{ + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + LLOctreeDirty dirty; + + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME); + dirty.traverse(part->mOctree); + } } + diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 19c8b06a46..961a55330a 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -131,6 +131,10 @@ public: bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples); bool allocateShadowBuffer(U32 resX, U32 resY); + // rebuild all LLVOVolume render batches + void rebuildDrawInfo(); + + // Clear LLFace mVertexBuffer pointers void resetVertexBuffers(LLDrawable* drawable); // perform a profile of the given avatar @@ -449,7 +453,6 @@ public: void handleShadowDetailChanged(); LLReflectionMapManager mReflectionMapManager; - void overrideEnvironmentMap(); private: void unloadShaders(); -- cgit v1.2.3 From 5eef9143d0272c969337a3db191b07ffd396139e Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy <alihatskiy@productengine.com> Date: Fri, 23 Jun 2023 22:26:52 +0300 Subject: SL-19805 Follow-up fix --- indra/newview/llvovolume.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index efcb049c3f..d1bae2f68a 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5866,8 +5866,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) else if (LLDrawPoolAlpha::sShowDebugAlpha || (gPipeline.sRenderHighlight && !drawablep->getParent() && drawablep->getVObj() && drawablep->getVObj()->flagScripted() && - (LLPipeline::getRenderScriptedBeacons() || - LLPipeline::getRenderScriptedTouchBeacons() && drawablep->getVObj()->flagHandleTouch()))) + (LLPipeline::getRenderScriptedBeacons() || LLPipeline::getRenderScriptedTouchBeacons()) && + drawablep->getVObj()->flagHandleTouch())) { //draw the transparent face for debugging purposes using a custom texture add_face(sAlphaFaces, alpha_count, facep); } -- cgit v1.2.3 From 7d3750c15bde9527e182513124cfd72818c1a282 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> Date: Sat, 24 Jun 2023 00:17:48 +0200 Subject: SL-19805 Fix touch handling logic --- indra/newview/llvovolume.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d1bae2f68a..bf9a4dfa12 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5865,9 +5865,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else if (LLDrawPoolAlpha::sShowDebugAlpha || (gPipeline.sRenderHighlight && !drawablep->getParent() && + //only root objects are highlighted with red color in this case drawablep->getVObj() && drawablep->getVObj()->flagScripted() && - (LLPipeline::getRenderScriptedBeacons() || LLPipeline::getRenderScriptedTouchBeacons()) && - drawablep->getVObj()->flagHandleTouch())) + (LLPipeline::getRenderScriptedBeacons() || + (LLPipeline::getRenderScriptedTouchBeacons() && drawablep->getVObj()->flagHandleTouch())))) { //draw the transparent face for debugging purposes using a custom texture add_face(sAlphaFaces, alpha_count, facep); } -- cgit v1.2.3 From 21b67896e9d1d181f39b8e44b9efe2b4c153d22b Mon Sep 17 00:00:00 2001 From: RunitaiLinden <davep@lindenlab.com> Date: Mon, 26 Jun 2023 15:37:18 -0500 Subject: SL-19909 Fix for reflection probes on vehicles blocking mouse clicks. Incidental instrumentation and decruft. --- indra/newview/llappviewer.cpp | 2 -- indra/newview/llreflectionmap.cpp | 2 +- indra/newview/llviewerobject.cpp | 2 ++ indra/newview/llviewerobjectlist.cpp | 4 ++++ indra/newview/llviewerregion.cpp | 7 +++++++ indra/newview/llvovolume.cpp | 9 ++++++++- indra/newview/llworld.cpp | 3 ++- 7 files changed, 24 insertions(+), 5 deletions(-) (limited to 'indra') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index abef25e34f..cf84094aa4 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4675,7 +4675,6 @@ public: static LLTrace::BlockTimerStatHandle FTM_AUDIO_UPDATE("Update Audio"); static LLTrace::BlockTimerStatHandle FTM_CLEANUP("Cleanup"); static LLTrace::BlockTimerStatHandle FTM_CLEANUP_DRAWABLES("Drawables"); -static LLTrace::BlockTimerStatHandle FTM_CLEANUP_OBJECTS("Objects"); static LLTrace::BlockTimerStatHandle FTM_IDLE_CB("Idle Callbacks"); static LLTrace::BlockTimerStatHandle FTM_LOD_UPDATE("Update LOD"); static LLTrace::BlockTimerStatHandle FTM_OBJECTLIST_UPDATE("Update Objectlist"); @@ -4972,7 +4971,6 @@ void LLAppViewer::idle() { LL_RECORD_BLOCK_TIME(FTM_CLEANUP); { - LL_RECORD_BLOCK_TIME(FTM_CLEANUP_OBJECTS); gObjectList.cleanDeadObjects(); } { diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 72dab0cba8..efaf068bd2 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -117,7 +117,7 @@ void LLReflectionMap::autoAdjustOrigin() { int face = -1; LLVector4a intersection; - LLDrawable* drawable = mGroup->lineSegmentIntersect(bounds[0], corners[i], true, false, true, &face, &intersection); + LLDrawable* drawable = mGroup->lineSegmentIntersect(bounds[0], corners[i], false, false, true, &face, &intersection); if (drawable != nullptr) { hit = true; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e67750af7c..628a787b9d 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -418,6 +418,7 @@ void LLViewerObject::markDead() { if (!mDead) { + LL_PROFILE_ZONE_SCOPED; //LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL; // Root object of this hierarchy unlinks itself. @@ -1153,6 +1154,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, const EObjectUpdateType update_type, LLDataPacker *dp) { + LL_PROFILE_ZONE_SCOPED; LL_DEBUGS_ONCE("SceneLoadTiming") << "Received viewer object data" << LL_ENDL; LL_DEBUGS("ObjectUpdate") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index e576784db8..ce4f9b7e64 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1353,6 +1353,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) { + LL_PROFILE_ZONE_SCOPED; // Don't ever kill gAgentAvatarp, just force it to the agent's region // unless region is NULL which is assumed to mean you are logging out. if ((objectp == gAgentAvatarp) && gAgent.getRegion()) @@ -1379,6 +1380,7 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) void LLViewerObjectList::killObjects(LLViewerRegion *regionp) { + LL_PROFILE_ZONE_SCOPED; LLViewerObject *objectp; @@ -1438,6 +1440,8 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) return; } + LL_PROFILE_ZONE_SCOPED; + S32 num_removed = 0; LLViewerObject *objectp; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index d60fae4bd6..6b92b16ef4 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -716,6 +716,7 @@ static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache"); LLViewerRegion::~LLViewerRegion() { + LL_PROFILE_ZONE_SCOPED; mDead = TRUE; mImpl->mActiveSet.clear(); mImpl->mVisibleEntries.clear(); @@ -1590,6 +1591,7 @@ void LLViewerRegion::lightIdleUpdate() void LLViewerRegion::idleUpdate(F32 max_update_time) { + LL_PROFILE_ZONE_SCOPED; LLTimer update_timer; F32 max_time; @@ -1693,6 +1695,10 @@ BOOL LLViewerRegion::isViewerCameraStatic() void LLViewerRegion::killInvisibleObjects(F32 max_time) { +#if 1 // TODO: kill this. This is ill-conceived, objects that aren't in the camera frustum should not be deleted from memory. + // because of this, every time you turn around the simulator sends a swarm of full object update messages from cache + // probe misses and objects have to be reloaded from scratch. From some reason, disabling this causes holes to + // appear in the scene when flying back and forth between regions if(!sVOCacheCullingEnabled) { return; @@ -1769,6 +1775,7 @@ void LLViewerRegion::killInvisibleObjects(F32 max_time) } return; +#endif } void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8160785d75..de1d3fc012 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -244,6 +244,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re LLVOVolume::~LLVOVolume() { + LL_PROFILE_ZONE_SCOPED; delete mTextureAnimp; mTextureAnimp = NULL; delete mVolumeImpl; @@ -267,6 +268,7 @@ void LLVOVolume::markDead() { if (!mDead) { + LL_PROFILE_ZONE_SCOPED; if (getVolume()) { LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID()); @@ -4676,7 +4678,12 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end_face = face+1; } pick_transparent |= isHiglightedOrBeacon(); - bool special_cursor = specialHoverCursor(); + + // we *probably* shouldn't care about special cursor at all, but we *definitely* + // don't care about special cursor for reflection probes -- makes alt-zoom + // go through reflection probes on vehicles + bool special_cursor = mReflectionProbe.isNull() && specialHoverCursor(); + for (S32 i = start_face; i < end_face; ++i) { if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f) diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 0e0dbdc071..709a457862 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -111,7 +111,7 @@ LLWorld::LLWorld() : gGL.getTexUnit(0)->bind(mDefaultWaterTexturep); mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("RequestFullRegionCache") && gSavedSettings.getBOOL("ObjectCacheEnabled"); + LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("RequestFullRegionCache") && gSavedSettings.getBOOL("ObjectCacheEnabled"); } @@ -681,6 +681,7 @@ static LLTrace::SampleStatHandle<> sNumActiveCachedObjects("numactivecachedobjec void LLWorld::updateRegions(F32 max_update_time) { + LL_PROFILE_ZONE_SCOPED; LLTimer update_timer; mNumOfActiveCachedObjects = 0; -- cgit v1.2.3 From 77ea8eedb8dab989043fed4d7db6938a8c6cf54d Mon Sep 17 00:00:00 2001 From: Brad Linden <brad@lindenlab.com> Date: Mon, 26 Jun 2023 14:07:16 -0700 Subject: Fix for SL-19620 & SL-19768 material overrides incorrectly affecting other faces --- indra/newview/llvocache.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 7081ecaa4b..a4070a513c 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -105,7 +105,7 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data) std::string error, warn; if (override_mat->fromJSON(gltf_json_str, warn, error)) { - mGLTFMaterial[i] = override_mat; + mGLTFMaterial[side_idx] = override_mat; } else { @@ -126,6 +126,16 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data) LL_WARNS_IF(sides.size() != 0, "GLTF") << "broken override cache entry" << LL_ENDL; } } + + llassert(mSides.size() == mGLTFMaterial.size()); +#ifdef SHOW_ASSERT + for (auto const & side : mSides) + { + // check that mSides and mGLTFMaterial have exactly the same keys present + llassert(mGLTFMaterial.count(side.first) == 1); + } +#endif + return true; } @@ -141,8 +151,11 @@ LLSD LLGLTFOverrideCacheEntry::toLLSD() const data["object_id"] = mObjectId; data["local_id"] = (LLSD::Integer) mLocalId; + llassert(mSides.size() == mGLTFMaterial.size()); for (auto const & side : mSides) { + // check that mSides and mGLTFMaterial have exactly the same keys present + llassert(mGLTFMaterial.count(side.first) == 1); data["sides"].append(LLSD::Integer(side.first)); data["gltf_json"].append(side.second); } -- cgit v1.2.3 From d35ef7e5d8f3968479543819501bd201e6321355 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Tue, 27 Jun 2023 20:20:56 +0300 Subject: SL-19924 Update profile type names --- indra/newview/llpanelprofile.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 34e1fd09d8..8ac1efe8e7 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1295,14 +1295,14 @@ void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data childSetVisible("badge_layout", TRUE); childSetVisible("partner_spacer_layout", FALSE); } - else if (customer_lower == "premium_lifetime") + else if (customer_lower == "secondlifetime_premium") { - getChild<LLUICtrl>("badge_icon")->setValue("Profile_Premium_Lifetime"); + getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Premium_Lifetime"); getChild<LLUICtrl>("badge_text")->setValue(getString("BadgePremiumLifetime")); childSetVisible("badge_layout", TRUE); childSetVisible("partner_spacer_layout", FALSE); } - else if (customer_lower == "pplus_lifetime" || customer_lower == "premium_plus_lifetime") + else if (customer_lower == "secondlifetime_premium_plus") { getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Pplus_Lifetime"); getChild<LLUICtrl>("badge_text")->setValue(getString("BadgePremiumPlusLifetime")); -- cgit v1.2.3 From 8032aa20c8c421da6996a92ffb2f567256e23b66 Mon Sep 17 00:00:00 2001 From: RunitaiLinden <davep@lindenlab.com> Date: Tue, 27 Jun 2023 13:35:57 -0500 Subject: SL-19925 Make high graphics default to shadows on. --- indra/newview/featuretable.txt | 10 +++++----- indra/newview/featuretable_mac.txt | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'indra') diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index ec2467200a..39f7996c7c 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 57 +version 58 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -163,7 +163,7 @@ RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 1 // -// Medium High Graphics Settings (deferred enabled) +// Medium High Graphics Settings // list MidHigh RenderAnisotropic 1 1 @@ -192,7 +192,7 @@ RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 2 // -// High Graphics Settings (deferred + SSAO) +// High Graphics Settings (SSAO + sun shadows) // list High RenderAnisotropic 1 1 @@ -212,7 +212,7 @@ RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.5 RenderDeferredSSAO 1 1 RenderUseAdvancedAtmospherics 1 0 -RenderShadowDetail 1 0 +RenderShadowDetail 1 1 WLSkyDetail 1 96 RenderFSAASamples 1 2 RenderReflectionsEnabled 1 1 @@ -221,7 +221,7 @@ RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 3 // -// High Ultra Graphics Settings (deferred + SSAO + shadows) +// High Ultra Graphics Settings (deferred + SSAO + all shadows) // list HighUltra RenderAnisotropic 1 1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 0687a3cea1..cce403c7aa 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 52 +version 53 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -161,7 +161,7 @@ RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 0 // -// Medium High Graphics Settings (deferred enabled) +// Medium High Graphics Settings // list MidHigh RenderAnisotropic 1 1 @@ -190,7 +190,7 @@ RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 0 // -// High Graphics Settings (deferred + SSAO) +// High Graphics Settings (SSAO + sun shadows) // list High RenderAnisotropic 1 1 @@ -210,7 +210,7 @@ RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.5 RenderDeferredSSAO 1 1 RenderUseAdvancedAtmospherics 1 0 -RenderShadowDetail 1 0 +RenderShadowDetail 1 1 WLSkyDetail 1 96 RenderFSAASamples 1 2 RenderReflectionsEnabled 1 1 @@ -219,7 +219,7 @@ RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 1 // -// High Ultra Graphics Settings (deferred + SSAO + shadows) +// High Ultra Graphics Settings (SSAO + all shadows) // list HighUltra RenderAnisotropic 1 1 -- cgit v1.2.3 From 298109864503d9c1e00d41dd1556f9dfea988e14 Mon Sep 17 00:00:00 2001 From: RunitaiLinden <davep@lindenlab.com> Date: Tue, 27 Jun 2023 14:01:42 -0500 Subject: SL-19897 Followup -- handle 100% transparent objects that are "active" --- indra/newview/pipeline.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e64ef6d555..0c767e7767 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -10600,8 +10600,11 @@ public: { LLSpatialGroup* group = (LLSpatialGroup*)state->getListener(0); - group->setState(LLSpatialGroup::GEOM_DIRTY); - gPipeline.markRebuild(group); + if (group->getSpatialPartition()->mRenderByGroup) + { + group->setState(LLSpatialGroup::GEOM_DIRTY); + gPipeline.markRebuild(group); + } for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) { @@ -10623,6 +10626,9 @@ void LLPipeline::rebuildDrawInfo() LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME); dirty.traverse(part->mOctree); + + part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE); + dirty.traverse(part->mOctree); } } -- cgit v1.2.3 From ed63ef3c0b6ceddf9ed667c1d69441d132b34983 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Wed, 28 Jun 2023 00:34:15 +0300 Subject: SL-19572 Fix some obscure cases of residents bypasing mute list --- indra/llmessage/llcachename.cpp | 4 +++- indra/newview/llmutelist.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 66bd85f4e6..a2e85cf6c2 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -552,7 +552,9 @@ std::string LLCacheName::buildUsername(const std::string& full_name) // if the input wasn't a correctly formatted legacy name, just return it // cleaned up from a potential terminal "Resident" - return cleanFullName(full_name); + std::string clean_name = cleanFullName(full_name); + LLStringUtil::toLower(clean_name); + return clean_name; } //static diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 2c45014321..14840f1b2e 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -99,6 +99,7 @@ public: BOOL isMuted(const LLUUID& id, const std::string& name = LLStringUtil::null, U32 flags = 0) const; // Workaround for username-based mute search, a lot of string conversions so use cautiously + // Expects lower case username BOOL isMuted(const std::string& username, U32 flags = 0) const; // Alternate (convenience) form for places we don't need to pass the name, but do need flags -- cgit v1.2.3 From 8d17467f7f70aa28d7ad012426ca59dc760bc43f Mon Sep 17 00:00:00 2001 From: RunitaiLinden <davep@lindenlab.com> Date: Tue, 27 Jun 2023 18:49:36 -0500 Subject: SL-19884 Fix for garbled rigged meshes in model import preview window. --- .../shaders/class1/objects/previewV.glsl | 24 +++-- indra/newview/llmodelpreview.cpp | 115 ++++++++++++--------- indra/newview/llviewershadermgr.cpp | 12 +-- 3 files changed, 86 insertions(+), 65 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl index b474a5803f..f51b0f4d9e 100644 --- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl @@ -25,7 +25,6 @@ uniform mat3 normal_matrix; uniform mat4 texture_matrix0; -uniform mat4 modelview_matrix; uniform mat4 modelview_projection_matrix; in vec3 position; @@ -54,14 +53,27 @@ float calcDirectionalLight(vec3 n, vec3 l) //==================================================================================================== +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 modelview_matrix; +uniform mat4 projection_matrix; +#endif + void main() { - //transform vertex - vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vec3 norm; +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec4 pos = mat * vec4(position.xyz, 1.0); + gl_Position = projection_matrix * pos; + norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#else + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + norm = normalize(normal_matrix * normal); +#endif + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - - vec3 norm = normalize(normal_matrix * normal); vec4 col = vec4(0,0,0,1); diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index c98e0e1bbe..6ceffd452e 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -2751,6 +2751,16 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) base_iter++; + bool skinned = include_skin_weights && !mdl->mSkinWeights.empty(); + + LLMatrix4a mat_normal; + if (skinned) + { + glh::matrix4f m((F32*)mdl->mSkinInfo.mBindShapeMatrix.getF32ptr()); + m = m.inverse().transpose(); + mat_normal.loadu(m.m); + } + S32 num_faces = mdl->getNumVolumeFaces(); for (S32 i = 0; i < num_faces; ++i) { @@ -2765,7 +2775,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) LLVertexBuffer* vb = NULL; - bool skinned = include_skin_weights && !mdl->mSkinWeights.empty(); + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; @@ -2803,6 +2813,15 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) LLVector4a::memcpyNonAliased16((F32*)vertex_strider.get(), (F32*)vf.mPositions, num_vertices * 4 * sizeof(F32)); + if (skinned) + { + for (U32 i = 0; i < num_vertices; ++i) + { + LLVector4a* v = (LLVector4a*)vertex_strider.get(); + mdl->mSkinInfo.mBindShapeMatrix.affineTransform(*v, *v); + vertex_strider++; + } + } if (vf.mTexCoords) { vb->getTexCoord0Strider(tc_strider); @@ -2813,7 +2832,25 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) if (vf.mNormals) { vb->getNormalStrider(normal_strider); - LLVector4a::memcpyNonAliased16((F32*)normal_strider.get(), (F32*)vf.mNormals, num_vertices * 4 * sizeof(F32)); + + if (skinned) + { + F32* normals = (F32*)normal_strider.get(); + LLVector4a* src = vf.mNormals; + LLVector4a* end = src + num_vertices; + + while (src < end) + { + LLVector4a normal; + mat_normal.rotate(*src++, normal); + normal.store4a(normals); + normals += 4; + } + } + else + { + LLVector4a::memcpyNonAliased16((F32*)normal_strider.get(), (F32*)vf.mNormals, num_vertices * 4 * sizeof(F32)); + } } if (skinned) @@ -3276,7 +3313,7 @@ BOOL LLModelPreview::render() refresh(); } - gObjectPreviewProgram.bind(); + gObjectPreviewProgram.bind(skin_weight); gGL.loadIdentity(); gPipeline.enableLightsPreview(); @@ -3351,11 +3388,11 @@ BOOL LLModelPreview::render() } gGL.pushMatrix(); + LLMatrix4 mat = instance.mTransform; gGL.multMatrix((GLfloat*)mat.mMatrix); - - + U32 num_models = mVertexBuffer[mPreviewLOD][model].size(); for (U32 i = 0; i < num_models; ++i) { @@ -3685,65 +3722,41 @@ BOOL LLModelPreview::render() { LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; - const LLVolumeFace& face = model->getVolumeFace(i); - - LLStrider<LLVector3> position; - buffer->getVertexStrider(position); - - LLStrider<LLVector4> weight; - buffer->getWeight4Strider(weight); + model->mSkinInfo.updateHash(); + LLRenderPass::uploadMatrixPalette(mPreviewAvatar, &model->mSkinInfo); - //quick 'n dirty software vertex skinning - - //build matrix palette - - LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - LLSkinningUtil::initSkinningMatrixPalette(mat, joint_count, - skin, getPreviewAvatar()); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix; - U32 max_joints = LLSkinningUtil::getMaxJointCount(); - for (U32 j = 0; j < buffer->getNumVerts(); ++j) + if (textures) { - LLMatrix4a final_mat; - F32 *wptr = weight[j].mV; - LLSkinningUtil::getPerVertexSkinMatrix(wptr, mat, true, final_mat, max_joints); - - //VECTORIZE THIS - LLVector4a& v = face.mPositions[j]; + int materialCnt = instance.mModel->mMaterialList.size(); + if (i < materialCnt) + { + const std::string& binding = instance.mModel->mMaterialList[i]; + const LLImportMaterial& material = instance.mMaterial[binding]; - LLVector4a t; - LLVector4a dst; - bind_shape_matrix.affineTransform(v, t); - final_mat.affineTransform(t, dst); + gGL.diffuseColor4fv(material.mDiffuseColor.mV); - position[j][0] = dst[0]; - position[j][1] = dst[1]; - position[j][2] = dst[2]; + // Find the tex for this material, bind it, and add it to our set + // + LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material); + if (tex) + { + mTextureSet.insert(tex); + } + } } - - llassert(model->mMaterialList.size() > i); - const std::string& binding = instance.mModel->mMaterialList[i]; - const LLImportMaterial& material = instance.mMaterial[binding]; - - buffer->unmapBuffer(); - - buffer->setBuffer(); - gGL.diffuseColor4fv(material.mDiffuseColor.mV); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // Find the tex for this material, bind it, and add it to our set - // - LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material); - if (tex) + else { - mTextureSet.insert(tex); + gGL.diffuseColor4fv(PREVIEW_BASE_COL.mV); } + buffer->setBuffer(); buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); if (edges) { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV); glLineWidth(PREVIEW_EDGE_WIDTH); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5eae1dfb18..4559d71d6d 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -92,6 +92,7 @@ LLGLSLShader gCopyDepthProgram; //object shaders LLGLSLShader gObjectPreviewProgram; +LLGLSLShader gSkinnedObjectPreviewProgram; LLGLSLShader gPhysicsPreviewProgram; LLGLSLShader gObjectFullbrightAlphaMaskProgram; LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram; @@ -251,7 +252,6 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gWaterProgram); mShaderList.push_back(&gWaterEdgeProgram); mShaderList.push_back(&gAvatarEyeballProgram); - mShaderList.push_back(&gObjectPreviewProgram); mShaderList.push_back(&gImpostorProgram); mShaderList.push_back(&gObjectBumpProgram); mShaderList.push_back(&gSkinnedObjectBumpProgram); @@ -2876,20 +2876,16 @@ BOOL LLViewerShaderMgr::loadShadersObject() if (success) { - gObjectPreviewProgram.mName = "Simple Shader"; - gObjectPreviewProgram.mFeatures.calculatesLighting = false; - gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false; - gObjectPreviewProgram.mFeatures.hasGamma = false; - gObjectPreviewProgram.mFeatures.hasAtmospherics = false; - gObjectPreviewProgram.mFeatures.hasLighting = false; - gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectPreviewProgram.mName = "Object Preview Shader"; gObjectPreviewProgram.mFeatures.disableTextureIndex = true; gObjectPreviewProgram.mShaderFiles.clear(); gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER)); gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER)); gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = make_rigged_variant(gObjectPreviewProgram, gSkinnedObjectPreviewProgram); success = gObjectPreviewProgram.createShader(NULL, NULL); gObjectPreviewProgram.mFeatures.hasLighting = true; + gSkinnedObjectPreviewProgram.mFeatures.hasLighting = true; } if (success) -- cgit v1.2.3 From ca47c7ff44ed0f5f1582f3a3dc5a31fcb3454885 Mon Sep 17 00:00:00 2001 From: RunitaiLinden <davep@lindenlab.com> Date: Tue, 27 Jun 2023 20:11:01 -0500 Subject: DRTVWR-559 Fix for manual probes not updating as often as they should when nearby (bad distance calculation) --- indra/newview/llreflectionmapmanager.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra') diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 779fe8bfd9..bb0bb04797 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -253,6 +253,10 @@ void LLReflectionMapManager::update() if (probe != mDefaultProbe) { + if (probe->mViewerObject) //make sure probes track the viewer objects they are attached to + { + probe->mOrigin.load3(probe->mViewerObject->getPositionAgent().mV); + } d.setSub(camera_pos, probe->mOrigin); probe->mDistance = d.getLength3().getF32() - probe->mRadius; } -- cgit v1.2.3 From 36949692b63031f70451317445a1a368efbfcaff Mon Sep 17 00:00:00 2001 From: RunitaiLinden <davep@lindenlab.com> Date: Wed, 28 Jun 2023 11:00:10 -0500 Subject: SL-19842 Nudge dynamic exposure coefficient and soften indirect lighting. --- indra/newview/app_settings/settings.xml | 2 +- .../shaders/class3/deferred/reflectionProbeF.glsl | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f3065d12b8..09eda2534c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10643,7 +10643,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.4</real> + <real>0.5</real> </map> <key>RenderShaderLODThreshold</key> <map> diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 1b2a34ef01..41821def8e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -364,7 +364,8 @@ return texCUBE(envMap, ReflDirectionWS); // dir - ray direction in clip space // i - probe index in refBox/refSphere // d - distance to nearest wall in clip space -vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d) +// scale - scale of box, default 1.0 +vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale) { // Intersection with OBB convert to unit box space // Transform in local unit parallax cube space (scaled and rotated) @@ -375,7 +376,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d) d = 1.0-max(max(abs(PositionLS.x), abs(PositionLS.y)), abs(PositionLS.z)); - vec3 Unitary = vec3(1.0f, 1.0f, 1.0f); + vec3 Unitary = vec3(scale); vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS; vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS; vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect); @@ -387,6 +388,11 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d) return IntersectPositionCS; } +vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d) +{ + return boxIntersect(origin, dir, i, d, 1.0); +} + void debugBoxCol(vec3 ro, vec3 rd, float t, vec3 p, inout vec4 col) { vec3 v = ro + rd * t; @@ -531,7 +537,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int if (refIndex[i].w < 0) { float d = 0.0; - v = boxIntersect(pos, dir, i, d); + v = boxIntersect(pos, dir, i, d, 3.0); w = max(d, 0.001); } else -- cgit v1.2.3 From 79223b63a2d1d5947b7955ebfa79054b897265d9 Mon Sep 17 00:00:00 2001 From: RunitaiLinden <davep@lindenlab.com> Date: Wed, 28 Jun 2023 13:47:14 -0500 Subject: SL-19842 Sanity clamp sky brightness. --- indra/newview/app_settings/shaders/class1/deferred/skyF.glsl | 1 + 1 file changed, 1 insertion(+) (limited to 'indra') diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index cc4c3b5dce..9d9ba49d82 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -84,6 +84,7 @@ void main() color.rgb += rainbow(optic_d); color.rgb += halo_22; color.rgb *= 2.; + color.rgb = clamp(color.rgb, vec3(0), vec3(5)); frag_data[0] = vec4(0); frag_data[1] = vec4(0); -- cgit v1.2.3 From f7134beb405cd080765fd5cf905ee6cc503e9074 Mon Sep 17 00:00:00 2001 From: Cosmic Linden <cosmic@lindenlab.com> Date: Wed, 28 Jun 2023 09:40:26 -0700 Subject: SL-17405 (Part 2): Fix viewer not requesting land impact when a non-root prim in a link set gets a GLTF material ID update --- indra/newview/llviewerobject.cpp | 22 +++++++++++++++++++--- indra/newview/llviewerobject.h | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e67750af7c..004674997b 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1269,7 +1269,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, LL_INFOS() << "Full:" << getID() << LL_ENDL; #endif //clear cost and linkset cost - mCostStale = true; + setObjectCostStale(); if (isSelected()) { gFloaterTools->dirty(); @@ -1825,7 +1825,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #ifdef DEBUG_UPDATE_TYPE LL_INFOS() << "CompFull:" << getID() << LL_ENDL; #endif - mCostStale = true; + setObjectCostStale(); if (isSelected()) { @@ -3779,6 +3779,16 @@ void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped) } } +void LLViewerObject::setObjectCostStale() +{ + mCostStale = true; + // *NOTE: This is harmlessly redundant for Blinn-Phong material updates, as + // the root prim currently gets set stale anyway due to other property + // updates. But it is needed for GLTF material ID updates. + // -Cosmic,2023-06-27 + getRootEdit()->mCostStale = true; +} + void LLViewerObject::setObjectCost(F32 cost) { mObjectCost = cost; @@ -6796,7 +6806,7 @@ void LLViewerObject::setPhysicsShapeType(U8 type) if (type != mPhysicsShapeType) { mPhysicsShapeType = type; - mCostStale = true; + setObjectCostStale(); } } @@ -7303,6 +7313,12 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat LLGLTFMaterialList::queueApply(this, te, id); } } + + if (!update_server) + { + // Land impact may have changed + setObjectCostStale(); + } } void LLViewerObject::setRenderMaterialIDs(const LLUUID& id) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bf82c43cd3..3665c64965 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -637,6 +637,7 @@ public: std::vector<LLVector3> mUnselectedChildrenPositions ; private: + void setObjectCostStale(); bool isAssetInInventory(LLViewerInventoryItem* item); ExtraParameter* createNewParameterEntry(U16 param_type); -- cgit v1.2.3 From 79198eddf76dfa69e8161f7646d8da19853a8a5a Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy <alihatskiy@productengine.com> Date: Fri, 7 Jul 2023 20:24:49 +0300 Subject: SL-19966 Reverted "SL-18721: Faster viewer shutdown time since performance improvements can lead to perceived inventory loss due to cache corruption" This reverts commit cf692c40b0b9f8d0d04cd10a02a84e3f697a2e99. --- indra/llcommon/threadpool.cpp | 5 ----- indra/llcommon/threadpool.h | 4 ---- indra/llwindow/llwindowwin32.cpp | 3 --- 3 files changed, 12 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index 4a7ead2110..d5adf11264 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -39,11 +39,6 @@ void LL::ThreadPool::start() run(tname); }); } - - // Special workflow for LLWindowWin32Thread - it's close() should be called explicitly - if (mExplicitShutdown) - return; - // Listen on "LLApp", and when the app is shutting down, close the queue // and join the workers. LLEventPumps::instance().obtain("LLApp").listen( diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index 0a5f14529b..f8eec3b457 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -59,10 +59,6 @@ namespace LL */ virtual void run(); - protected: - // LLWindowWin32Thread should set this flag to true - bool mExplicitShutdown { false }; - private: void run(const std::string& name); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 2f1a631585..2e560ddb0a 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4592,9 +4592,6 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList() inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread() : ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE) { - // Set this flag to true to avoid of implicit call of close() from start() - mExplicitShutdown = true; - ThreadPool::start(); } -- cgit v1.2.3 From 4aa44bdfc9bae011bdfbb01bd888f7ab92e18215 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko <maximnproductengine@lindenlab.com> Date: Thu, 6 Jul 2023 21:46:19 +0300 Subject: SL-19702 restore previous double clicking behavior for objects --- indra/newview/llviewerinput.cpp | 5 +++-- indra/newview/llviewerwindow.cpp | 3 ++- indra/newview/llviewerwindow.h | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index 6bab2c2100..226e0a9a56 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -1597,7 +1597,8 @@ bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) { - BOOL handled = gViewerWindow->handleAnyMouseClick(window_impl, pos, mask, clicktype, down); + bool is_toolmgr_action = false; + BOOL handled = gViewerWindow->handleAnyMouseClick(window_impl, pos, mask, clicktype, down, is_toolmgr_action); if (clicktype != CLICK_NONE) { @@ -1616,7 +1617,7 @@ BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, // If the first LMB click is handled by the menu, skip the following double click static bool skip_double_click = false; - if (clicktype == CLICK_LEFT && down ) + if (clicktype == CLICK_LEFT && down && !is_toolmgr_action) { skip_double_click = handled; } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b9fcc25310..e8fd74b37b 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1050,7 +1050,7 @@ void LLViewerWindow::handlePieMenu(S32 x, S32 y, MASK mask) } } -BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) +BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down, bool& is_toolmgr_action) { const char* buttonname = ""; const char* buttonstatestr = ""; @@ -1199,6 +1199,7 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) ) { LLViewerEventRecorder::instance().clear_xui(); + is_toolmgr_action = true; return TRUE; } diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 1927e01ddb..92905ef21a 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -179,7 +179,7 @@ public: void reshapeStatusBarContainer(); - BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); + BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down, bool &is_toolmgr_action); // // LLWindowCallback interface implementation -- cgit v1.2.3 From bce11a1fa03b95782378ecb431850f77f762a348 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Fri, 7 Jul 2023 23:13:04 +0300 Subject: SL-19958 An inventory material without asset should default to a blank material A New Material created in Inventory should be immediately usable. --- indra/newview/lltooldraganddrop.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 6633951db3..4705970c7b 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -40,6 +40,7 @@ #include "llfloatertools.h" #include "llgesturemgr.h" #include "llgiveinventory.h" +#include "llgltfmateriallist.h" #include "llhudmanager.h" #include "llhudeffecttrail.h" #include "llimview.h" @@ -1095,12 +1096,17 @@ void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj, LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no material item." << LL_ENDL; return; } - LLUUID asset_id = item->getAssetUUID(); BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id); if (!success) { return; } + LLUUID asset_id = item->getAssetUUID(); + if (asset_id.isNull()) + { + // use blank material + asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID; + } hit_obj->setRenderMaterialID(hit_face, asset_id); @@ -1121,13 +1127,19 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj, LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no material item." << LL_ENDL; return; } - LLUUID asset_id = item->getAssetUUID(); BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id); if (!success) { return; } + LLUUID asset_id = item->getAssetUUID(); + if (asset_id.isNull()) + { + // use blank material + asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID; + } + hit_obj->setRenderMaterialIDs(asset_id); dialog_refresh_all(); // send the update to the simulator -- cgit v1.2.3 From ba4b596894e8eb9b9eb51169b9b3f88c21173c29 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <andreykproductengine@lindenlab.com> Date: Tue, 11 Jul 2023 01:24:22 +0300 Subject: SL-19141 Fixed applying a no-copy texture to two objects failing silently --- indra/newview/llpanelface.cpp | 22 ++++++++++++++++---- indra/newview/llselectmgr.cpp | 24 ++++++++++++++-------- indra/newview/llselectmgr.h | 4 ++-- .../newview/skins/default/xui/en/notifications.xml | 20 ++++++++++++++++++ 4 files changed, 56 insertions(+), 14 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 7d6015f557..702a8a82e2 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -520,7 +520,11 @@ void LLPanelFace::sendTexture() { id = mTextureCtrl->getImageAssetID(); } - LLSelectMgr::getInstance()->selectionSetImage(id); + if (!LLSelectMgr::getInstance()->selectionSetImage(id)) + { + // need to refresh value in texture ctrl + refresh(); + } } } @@ -3032,7 +3036,11 @@ void LLPanelFace::onCommitPbr(const LLSD& data) { id = pbr_ctrl->getImageAssetID(); } - LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id); + if (!LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id)) + { + // If failed to set material, refresh pbr_ctrl's value + refresh(); + } } } @@ -3056,8 +3064,14 @@ void LLPanelFace::onSelectPbr(const LLSD& data) { id = pbr_ctrl->getImageAssetID(); } - LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id); - LLSelectedTEMaterial::setMaterialID(this, id); + if (LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id)) + { + LLSelectedTEMaterial::setMaterialID(this, id); + } + else + { + refresh(); + } } } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index dca341e5a2..3b20ed1e00 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1821,7 +1821,7 @@ void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item) // selectionSetImage() //----------------------------------------------------------------------------- // *TODO: re-arch texture applying out of lltooldraganddrop -void LLSelectMgr::selectionSetImage(const LLUUID& imageid) +bool LLSelectMgr::selectionSetImage(const LLUUID& imageid) { // First for (no copy) textures and multiple object selection LLViewerInventoryItem* item = gInventory.getItem(imageid); @@ -1829,9 +1829,11 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) && (mSelectedObjects->getNumNodes() > 1) ) { - LL_WARNS() << "Attempted to apply no-copy texture to multiple objects" - << LL_ENDL; - return; + LL_DEBUGS() << "Attempted to apply no-copy texture " << imageid + << " to multiple objects" << LL_ENDL; + + LLNotificationsUtil::add("FailedToApplyTextureNoCopyToMultiple"); + return false; } struct f : public LLSelectedTEFunctor @@ -1896,12 +1898,14 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) } } sendfunc(item); getSelection()->applyToObjects(&sendfunc); + + return true; } //----------------------------------------------------------------------------- // selectionSetGLTFMaterial() //----------------------------------------------------------------------------- -void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) +bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) { // First for (no copy) textures and multiple object selection LLViewerInventoryItem* item = gInventory.getItem(mat_id); @@ -1909,9 +1913,11 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) && (mSelectedObjects->getNumNodes() > 1)) { - LL_WARNS() << "Attempted to apply no-copy material to multiple objects" - << LL_ENDL; - return; + LL_DEBUGS() << "Attempted to apply no-copy material " << mat_id + << "to multiple objects" << LL_ENDL; + + LLNotificationsUtil::add("FailedToApplyGLTFNoCopyToMultiple"); + return false; } struct f : public LLSelectedTEFunctor @@ -1983,6 +1989,8 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) getSelection()->applyToObjects(&sendfunc); LLGLTFMaterialList::flushUpdates(); + + return true; } //----------------------------------------------------------------------------- diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index ca9a32f0db..327134a487 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -634,8 +634,8 @@ public: void selectionSetDensity(F32 density); void selectionSetRestitution(F32 restitution); void selectionSetMaterial(U8 material); - void selectionSetImage(const LLUUID& imageid); // could be item or asset id - void selectionSetGLTFMaterial(const LLUUID& mat_id); // could be item or asset id + bool selectionSetImage(const LLUUID& imageid); // could be item or asset id + bool selectionSetGLTFMaterial(const LLUUID& mat_id); // could be item or asset id void selectionSetColor(const LLColor4 &color); void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f77b235408..c4abd27a01 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -9211,6 +9211,26 @@ Paste failed. [REASON] yestext="OK"/> </notification> + <notification + icon="alertmodal.tga" + name="FailedToApplyTextureNoCopyToMultiple" + type="alertmodal"> +Failed to apply texture. You can not apply a no-copy texture to multiple objects. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="FailedToApplyGLTFNoCopyToMultiple" + type="alertmodal"> +Failed to apply GLTF material. You can not apply a no-copy material to multiple objects. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification icon="alertmodal.tga" name="FacePasteTexturePermissions" -- cgit v1.2.3 From 59a626c2a22aa7cbccf87ce435012583d7610cd4 Mon Sep 17 00:00:00 2001 From: Cosmic Linden <cosmic@lindenlab.com> Date: Tue, 11 Jul 2023 16:08:03 -0700 Subject: SL-19992: Fix assert in LLVolumeLODGroup::refLOD when LLMeshRepository::notifyMeshUnavailable is called on the highest LOD --- indra/llmath/llvolumemgr.cpp | 18 +++++++++--------- indra/newview/llmeshrepository.cpp | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'indra') diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index 89cdb1c6b9..9399504529 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -89,7 +89,7 @@ BOOL LLVolumeMgr::cleanup() // Note however that LLVolumeLODGroup that contains the volume // also holds a LLPointer so the volume will only go away after // anything holding the volume and the LODGroup are destroyed -LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 detail) +LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 lod) { LLVolumeLODGroup* volgroupp; if (mDataMutex) @@ -109,7 +109,7 @@ LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 { mDataMutex->unlock(); } - return volgroupp->refLOD(detail); + return volgroupp->refLOD(lod); } // virtual @@ -287,18 +287,18 @@ bool LLVolumeLODGroup::cleanupRefs() return res; } -LLVolume* LLVolumeLODGroup::refLOD(const S32 detail) +LLVolume* LLVolumeLODGroup::refLOD(const S32 lod) { - llassert(detail >=0 && detail < NUM_LODS); - mAccessCount[detail]++; + llassert(lod >=0 && lod < NUM_LODS); + mAccessCount[lod]++; mRefs++; - if (mVolumeLODs[detail].isNull()) + if (mVolumeLODs[lod].isNull()) { - mVolumeLODs[detail] = new LLVolume(mVolumeParams, mDetailScales[detail]); + mVolumeLODs[lod] = new LLVolume(mVolumeParams, mDetailScales[lod]); } - mLODRefs[detail]++; - return mVolumeLODs[detail]; + mLODRefs[lod]++; + return mVolumeLODs[lod]; } BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 57ac111fdf..2118ee74d3 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3021,7 +3021,7 @@ S32 LLMeshRepository::getActualMeshLOD(LLMeshHeader& header, S32 lod) } //search up to find then ext available higher lod - for (S32 i = lod+1; i < 4; ++i) + for (S32 i = lod+1; i < LLVolumeLODGroup::NUM_LODS; ++i) { if (header.mLodSize[i] > 0) { @@ -3183,7 +3183,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status) // Can't get the header so none of the LODs will be available LLMutexLock lock(gMeshRepo.mThread->mMutex); - for (int i(0); i < 4; ++i) + for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i) { gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } @@ -3212,7 +3212,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b // Can't get the header so none of the LODs will be available LLMutexLock lock(gMeshRepo.mThread->mMutex); - for (int i(0); i < 4; ++i) + for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i) { gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } @@ -3293,7 +3293,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b // headerReceived() parsed header, but header's data is invalid so none of the LODs will be available LLMutexLock lock(gMeshRepo.mThread->mMutex); - for (int i(0); i < 4; ++i) + for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i) { gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } @@ -3654,7 +3654,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para // Manage time-to-load metrics for mesh download operations. metricsProgress(1); - if (detail < 0 || detail >= 4) + if (detail < 0 || detail >= LLVolumeLODGroup::NUM_LODS) { return detail; } @@ -3717,7 +3717,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para } //no lower LOD is a available, is a higher lod available? - for (S32 i = detail+1; i < 4; ++i) + for (S32 i = detail+1; i < LLVolumeLODGroup::NUM_LODS; ++i) { LLVolume* lod = group->refLOD(i); if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0) @@ -3918,7 +3918,7 @@ void LLMeshRepository::notifyLoadedMeshes() //create score map std::map<LLUUID, F32> score_map; - for (U32 i = 0; i < 4; ++i) + for (U32 i = 0; i < LLVolumeLODGroup::NUM_LODS; ++i) { for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) { @@ -4099,7 +4099,7 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, { F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); - LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, detail); + LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, lod); if (sys_volume) { sys_volume->setMeshAssetUnavaliable(true); @@ -4480,7 +4480,7 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by { LL_WARNS() << mesh_id << "bytes mismatch " << *bytes << " " << data.getSizeTotal() << LL_ENDL; } - if (bytes_visible && (lod >=0) && (lod < 4) && (*bytes_visible != data.getSizeByLOD(lod))) + if (bytes_visible && (lod >=0) && (lod < LLVolumeLODGroup::NUM_LODS) && (*bytes_visible != data.getSizeByLOD(lod))) { LL_WARNS() << mesh_id << "bytes_visible mismatch " << *bytes_visible << " " << data.getSizeByLOD(lod) << LL_ENDL; } @@ -4640,7 +4640,7 @@ bool LLMeshCostData::init(const LLMeshHeader& header) static LLCachedControl<U32> minimum_size(gSavedSettings, "MeshMinimumByteSize", 16); //make sure nothing is "free" static LLCachedControl<U32> bytes_per_triangle(gSavedSettings, "MeshBytesPerTriangle", 16); - for (S32 i=0; i<4; i++) + for (S32 i=0; i<LLVolumeLODGroup::NUM_LODS; i++) { mEstTrisByLOD[i] = llmax((F32)mSizeByLOD[i] - (F32)metadata_discount, (F32)minimum_size) / (F32)bytes_per_triangle; } -- cgit v1.2.3 From 0a93c3e22d8df03a9989ebd89e85c4f5a578a2ce Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine <mnikolenko@productengine.com> Date: Wed, 12 Jul 2023 15:21:28 +0300 Subject: SL-19990 Brightness slider should be named HDR Scale unless Reflection Probe Ambiance (HDR) is 0 --- indra/newview/llpaneleditsky.cpp | 6 +++--- indra/newview/llpaneleditsky.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp index 761d856aae..0a7a4763be 100644 --- a/indra/newview/llpaneleditsky.cpp +++ b/indra/newview/llpaneleditsky.cpp @@ -217,7 +217,7 @@ void LLPanelSettingsSkyAtmosTab::refresh() getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setValue(ice_level); getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(rp_ambiance); - updateGammaLabel(); + updateGammaLabel(should_auto_adjust); } //------------------------------------------------------------------------- @@ -335,10 +335,10 @@ void LLPanelSettingsSkyAtmosTab::onReflectionProbeAmbianceChanged() } -void LLPanelSettingsSkyAtmosTab::updateGammaLabel() +void LLPanelSettingsSkyAtmosTab::updateGammaLabel(bool auto_adjust) { if (!mSkySettings) return; - F32 ambiance = mSkySettings->getReflectionProbeAmbiance(); + F32 ambiance = mSkySettings->getReflectionProbeAmbiance(auto_adjust); if (ambiance != 0.f) { childSetValue("scene_gamma_label", getString("hdr_string")); diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h index 33af667ab7..523cc134a8 100644 --- a/indra/newview/llpaneleditsky.h +++ b/indra/newview/llpaneleditsky.h @@ -80,7 +80,7 @@ private: void onDropletRadiusChanged(); void onIceLevelChanged(); void onReflectionProbeAmbianceChanged(); - void updateGammaLabel(); + void updateGammaLabel(bool auto_adjust = false); }; -- cgit v1.2.3 From 162f10e021d778e499836bd1f9d1f88b004b8017 Mon Sep 17 00:00:00 2001 From: Brad Linden <brad@lindenlab.com> Date: Wed, 12 Jul 2023 14:18:20 -0700 Subject: added info log lines for assistance diagnosing SL-19968 --- indra/newview/llvocache.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 55fc663496..8d1f5b5f5b 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -1086,6 +1086,8 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version) readCacheHeader(); + LL_INFOS() << "Viewer Object Cache Versions - expected: " << cache_version << " found: " << mMetaInfo.mVersion << LL_ENDL; + if( mMetaInfo.mVersion != cache_version || mMetaInfo.mAddressSize != expected_address) { @@ -1096,7 +1098,8 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version) clearCacheInMemory(); } else //delete the current cache if the format does not match. - { + { + LL_INFOS() << "Viewer Object Cache Versions unmatched. clearing cache." << LL_ENDL; removeCache(); } } -- cgit v1.2.3 From afcb421bdc666d9b45fb5adb7098b7e433042823 Mon Sep 17 00:00:00 2001 From: Cosmic Linden <cosmic@lindenlab.com> Date: Thu, 6 Jul 2023 12:53:42 -0700 Subject: SL-19567: (WIP) Add options to use higher precision for glow and post-process buffers. Disabled by default. --- indra/newview/app_settings/settings.xml | 22 ++++++++++++++++++++++ indra/newview/llviewercontrol.cpp | 2 ++ indra/newview/pipeline.cpp | 8 ++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 09eda2534c..9f3a5bd5b9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9340,6 +9340,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderPostProcessingHDR</key> + <map> + <key>Comment</key> + <string>Enable HDR for post processing buffer</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderMaxOpenGLVersion</key> <map> <key>Comment</key> @@ -10155,6 +10166,17 @@ <key>Value</key> <integer>9</integer> </map> + <key>RenderGlowHDR</key> + <map> + <key>Comment</key> + <string>Enable HDR for glow map</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderGlowStrength</key> <map> <key>Comment</key> diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index aae4409167..9707a2a7e6 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -700,6 +700,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized); setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderPostProcessingHDR", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged); @@ -708,6 +709,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGlowHDR", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged); setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0c767e7767..4183990261 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -840,7 +840,9 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) mSceneMap.allocate(resX, resY, GL_RGB, true); } - mPostMap.allocate(resX, resY, GL_RGBA); + const bool post_hdr = gSavedSettings.getBOOL("RenderPostProcessingHDR"); + const U32 post_color_fmt = post_hdr ? GL_RGBA16F : GL_RGBA; + mPostMap.allocate(resX, resY, post_color_fmt); //HACK make screenbuffer allocations start failing after 30 seconds if (gSavedSettings.getBOOL("SimulateFBOFailure")) @@ -1163,9 +1165,11 @@ void LLPipeline::createGLBuffers() // allocate screen space glow buffers const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); + const bool glow_hdr = gSavedSettings.getBOOL("RenderGlowHDR"); + const U32 glow_color_fmt = glow_hdr ? GL_RGBA16F : GL_RGBA; for (U32 i = 0; i < 3; i++) { - mGlow[i].allocate(512, glow_res, GL_RGBA); + mGlow[i].allocate(512, glow_res, glow_color_fmt); } allocateScreenBuffer(resX, resY); -- cgit v1.2.3 From 66283201301b0e55336f4b20407fed811acdc739 Mon Sep 17 00:00:00 2001 From: Cosmic Linden <cosmic@lindenlab.com> Date: Tue, 11 Jul 2023 09:51:14 -0700 Subject: SL-19567: Add option RenderGlowNoise for low precision glow dithering, enabled by default --- indra/llrender/llshadermgr.cpp | 3 ++- indra/llrender/llshadermgr.h | 1 + indra/newview/app_settings/settings.xml | 11 +++++++++++ .../shaders/class1/effects/glowExtractF.glsl | 15 ++++++++++++++- indra/newview/llviewercontrol.cpp | 1 + indra/newview/llviewershadermgr.cpp | 11 ++++++++++- indra/newview/pipeline.cpp | 16 ++++++++++++++++ indra/newview/pipeline.h | 1 + 8 files changed, 56 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 75d6ef6c46..22940dc703 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1300,8 +1300,9 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("warmthAmount"); mReservedUniforms.push_back("glowStrength"); mReservedUniforms.push_back("glowDelta"); + mReservedUniforms.push_back("glowNoiseMap"); - llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_DELTA+1); + llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_NOISE_MAP+1); mReservedUniforms.push_back("minimum_alpha"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 46f352aa58..ac4b393fb7 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -131,6 +131,7 @@ public: GLOW_WARMTH_AMOUNT, // "warmthAmount" GLOW_STRENGTH, // "glowStrength" GLOW_DELTA, // "glowDelta" + GLOW_NOISE_MAP, // "glowNoiseMap" MINIMUM_ALPHA, // "minimum_alpha" EMISSIVE_BRIGHTNESS, // "emissive_brightness" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9f3a5bd5b9..8e5e092250 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10225,6 +10225,17 @@ <key>Value</key> <real>1.3</real> </map> + <key>RenderGlowNoise</key> + <map> + <key>Comment</key> + <string>Enables glow noise (dithering). Reduces banding from glow in certain cases.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <real>1</real> + </map> <key>DisableAllRenderTypes</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl index 7a5e14566b..b5437d43d2 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl @@ -28,6 +28,10 @@ out vec4 frag_color; uniform sampler2D diffuseMap; +#if HAS_NOISE +uniform sampler2D glowNoiseMap; +uniform vec2 screen_res; +#endif uniform float minLuminance; uniform float maxExtractAlpha; uniform vec3 lumWeights; @@ -44,7 +48,16 @@ void main() float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) ); float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) ); - frag_color.rgb = col.rgb; +#if HAS_NOISE + float TRUE_NOISE_RES = 128; // See mTrueNoiseMap + // *NOTE: Usually this is vary_fragcoord not vary_texcoord0, but glow extraction is in screen space + vec3 glow_noise = texture(glowNoiseMap, vary_texcoord0.xy * (screen_res / TRUE_NOISE_RES)).xyz; + // Dithering. Reduces banding effects in the reduced precision glow buffer. + float NOISE_DEPTH = 64.0; + col.rgb += glow_noise / NOISE_DEPTH; + col.rgb = max(col.rgb, vec3(0)); +#endif + frag_color.rgb = col.rgb; frag_color.a = max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha); } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 9707a2a7e6..9f4287c23d 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -710,6 +710,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlowHDR", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGlowNoise", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged); setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 4559d71d6d..82b16d67bd 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -898,11 +898,20 @@ BOOL LLViewerShaderMgr::loadShadersEffects() if (success) { - gGlowExtractProgram.mName = "Glow Extract Shader (Post)"; + const bool use_glow_noise = gSavedSettings.getBOOL("RenderGlowNoise"); + const std::string glow_noise_label = use_glow_noise ? " (+Noise)" : ""; + + gGlowExtractProgram.mName = llformat("Glow Extract Shader (Post)%s", glow_noise_label.c_str()); gGlowExtractProgram.mShaderFiles.clear(); gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER)); gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER)); gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT]; + + if (use_glow_noise) + { + gGlowExtractProgram.addPermutation("HAS_NOISE", "1"); + } + success = gGlowExtractProgram.createShader(NULL, NULL); if (!success) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4183990261..d50e671e05 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -157,6 +157,7 @@ S32 LLPipeline::RenderGlowResolutionPow; S32 LLPipeline::RenderGlowIterations; F32 LLPipeline::RenderGlowWidth; F32 LLPipeline::RenderGlowStrength; +bool LLPipeline::RenderGlowNoise; bool LLPipeline::RenderDepthOfField; bool LLPipeline::RenderDepthOfFieldInEditMode; F32 LLPipeline::CameraFocusTransitionTime; @@ -517,6 +518,7 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderGlowIterations"); connectRefreshCachedSettingsSafe("RenderGlowWidth"); connectRefreshCachedSettingsSafe("RenderGlowStrength"); + connectRefreshCachedSettingsSafe("RenderGlowNoise"); connectRefreshCachedSettingsSafe("RenderDepthOfField"); connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode"); connectRefreshCachedSettingsSafe("CameraFocusTransitionTime"); @@ -1007,6 +1009,7 @@ void LLPipeline::refreshCachedSettings() RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations"); RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth"); RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength"); + RenderGlowNoise = gSavedSettings.getBOOL("RenderGlowNoise"); RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField"); RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode"); CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime"); @@ -6886,6 +6889,19 @@ void LLPipeline::generateGlow(LLRenderTarget* src) warmthWeights.mV[2]); gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); + if (RenderGlowNoise) + { + S32 channel = gGlowExtractProgram.enableTexture(LLShaderMgr::GLOW_NOISE_MAP); + if (channel > -1) + { + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + gGlowExtractProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, + mGlow[2].getWidth(), + mGlow[2].getHeight()); + } + { LLGLEnable blend_on(GL_BLEND); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 961a55330a..c0559ce83b 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -1001,6 +1001,7 @@ public: static S32 RenderGlowIterations; static F32 RenderGlowWidth; static F32 RenderGlowStrength; + static bool RenderGlowNoise; static bool RenderDepthOfField; static bool RenderDepthOfFieldInEditMode; static F32 CameraFocusTransitionTime; -- cgit v1.2.3 From 5ce4d42f55187e710fac64efbd34947900ef2d58 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko <maximnproductengine@lindenlab.com> Date: Thu, 13 Jul 2023 18:52:45 +0300 Subject: SL-19993 Warn of automatic changes to Day Cycle when it's opened --- indra/newview/llfloatereditextdaycycle.cpp | 24 ++++++++++++++++++++++++ indra/newview/llfloatereditextdaycycle.h | 2 ++ 2 files changed, 26 insertions(+) (limited to 'indra') diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index 6e8143384a..bb47feaa95 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -475,6 +475,8 @@ void LLFloaterEditExtDayCycle::refresh() void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) { setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings)); + + showHDRNotification(std::dynamic_pointer_cast<LLSettingsDay>(settings)); } void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday) @@ -1710,6 +1712,28 @@ void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track) } } +void LLFloaterEditExtDayCycle::showHDRNotification(const LLSettingsDay::ptr_t &pday) +{ + for (U32 i = LLSettingsDay::TRACK_GROUND_LEVEL; i <= LLSettingsDay::TRACK_MAX; i++) + { + LLSettingsDay::CycleTrack_t &day_track = pday->getCycleTrack(i); + + LLSettingsDay::CycleTrack_t::iterator iter = day_track.begin(); + LLSettingsDay::CycleTrack_t::iterator end = day_track.end(); + + while (iter != end) + { + LLSettingsSky::ptr_t sky = std::static_pointer_cast<LLSettingsSky>(iter->second); + if (sky && sky->canAutoAdjust()) + { + LLNotificationsUtil::add("AutoAdjustHDRSky"); + return; + } + iter++; + } + } +} + void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 source_track, S32 dest_track, LLSettingsBase::TrackPosition frame) { std::function<void()> cb = [this, settings, frame, source_track, dest_track]() diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h index ab5d12fa36..025a2ee5d1 100644 --- a/indra/newview/llfloatereditextdaycycle.h +++ b/indra/newview/llfloatereditextdaycycle.h @@ -188,6 +188,8 @@ private: bool isRemovingFrameAllowed(); bool isAddingFrameAllowed(); + void showHDRNotification(const LLSettingsDay::ptr_t &pday); + LLSettingsDay::ptr_t mEditDay; // edited copy LLSettingsDay::Seconds mDayLength; U32 mCurrentTrack; -- cgit v1.2.3 From df1eb38b2109bf9cb57b42e2c361c4143276ae5a Mon Sep 17 00:00:00 2001 From: Brad Linden <brad@lindenlab.com> Date: Thu, 13 Jul 2023 10:08:19 -0700 Subject: SL-19999 stop outputing debug info about created material asset id unnecessarily --- indra/newview/llmaterialeditor.cpp | 4 +--- indra/newview/skins/default/xui/en/notifications.xml | 7 ------- 2 files changed, 1 insertion(+), 10 deletions(-) (limited to 'indra') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 609d8ea5d7..3a0e64985c 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1327,9 +1327,7 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { // done callback - LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; - LLSD params = llsd::map("ASSET_ID", new_asset_id); - LLNotificationsUtil::add("MaterialCreated", params); + LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; }, nullptr // failure callback, floater already closed ); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index c4abd27a01..3d151a9868 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -12098,13 +12098,6 @@ Would you like to save them first? yestext="Yes"/> </notification> -<notification - icon="notifytip.tga" - name="MaterialCreated" - type="notifytip"> -Material successfully created. Asset ID: [ASSET_ID] -</notification> - <notification icon="notifytip.tga" name="ReflectionProbeApplied" -- cgit v1.2.3 From d192d91db95ec9ed3ad47039e126134bc05ad5f4 Mon Sep 17 00:00:00 2001 From: Brad Linden <brad@lindenlab.com> Date: Thu, 13 Jul 2023 11:28:36 -0700 Subject: Fixed failure to open Material Editor when creating or uploading a new material found this warning found while working on SL-19999 --- indra/newview/llviewermessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index f14e3ed737..b756d3d87f 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1532,7 +1532,7 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam LLFloaterReg::showInstance("preview_sound", LLSD(obj_id), take_focus); break; case LLAssetType::AT_MATERIAL: - LLFloaterReg::showInstance("material editor", LLSD(obj_id), take_focus); + LLFloaterReg::showInstance("material_editor", LLSD(obj_id), take_focus); break; default: LL_DEBUGS("Messaging") << "No preview method for previewable asset type : " << LLAssetType::lookupHumanReadable(asset_type) << LL_ENDL; -- cgit v1.2.3 From 2f8f1c7a44f45490db5b5f040914e42aef2f5280 Mon Sep 17 00:00:00 2001 From: Brad Linden <brad@lindenlab.com> Date: Fri, 14 Jul 2023 12:46:20 -0700 Subject: Fix crash SL-20013 crash when applying nocopy material via drag-and-drop --- indra/newview/lltooldraganddrop.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 4705970c7b..1918d11964 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1096,12 +1096,16 @@ void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj, LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no material item." << LL_ENDL; return; } + + // SL-20013 must save asset_id before handleDropMaterialProtections since our item instance + // may be deleted if it is moved into task inventory + LLUUID asset_id = item->getAssetUUID(); BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id); if (!success) { return; } - LLUUID asset_id = item->getAssetUUID(); + if (asset_id.isNull()) { // use blank material @@ -1127,13 +1131,17 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj, LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no material item." << LL_ENDL; return; } + + // SL-20013 must save asset_id before handleDropMaterialProtections since our item instance + // may be deleted if it is moved into task inventory + LLUUID asset_id = item->getAssetUUID(); BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id); + if (!success) { return; } - LLUUID asset_id = item->getAssetUUID(); if (asset_id.isNull()) { // use blank material -- cgit v1.2.3 From ec4135da63a3f3877222fba4ecb59b15650371fe Mon Sep 17 00:00:00 2001 From: Nat Goodspeed <nat@lindenlab.com> Date: Mon, 17 Jul 2023 16:12:39 -0400 Subject: Increment viewer version to 6.6.14 following promotion of DRTVWR-580 --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 97154f804c..e9d5f8c17f 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.6.13 +6.6.14 -- cgit v1.2.3