summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Kundiman <erik@megapahit.org>2026-03-07 14:55:05 +0800
committerErik Kundiman <erik@megapahit.org>2026-03-07 14:55:05 +0800
commiteac10375e294cd24c21c09497e838e70dcf4d74a (patch)
tree4b53b1ebc1582e3323c80953236dca6b3a92ab65
parent8142dd11b4cae8d4768a2d985a24340163a42a5c (diff)
parent3529bc5f9d29a71355f3a3666540abff57dc1a4c (diff)
Merge tag 'Second_Life_Release#3529bc5f-2026.02' into 2026.02
-rw-r--r--.github/workflows/build.yaml26
-rw-r--r--.github/workflows/cla.yaml2
-rw-r--r--.github/workflows/pre-commit.yaml2
-rw-r--r--autobuild.xml138
-rw-r--r--indra/cmake/Boost.cmake38
-rw-r--r--indra/cmake/Python.cmake67
-rw-r--r--indra/llappearance/lltexlayer.cpp18
-rw-r--r--indra/llaudio/llaudioengine.cpp1
-rw-r--r--indra/llcharacter/CMakeLists.txt4
-rw-r--r--indra/llcharacter/llkeyframemotionparam.cpp436
-rw-r--r--indra/llcharacter/llkeyframemotionparam.h169
-rw-r--r--indra/llcharacter/llmotioncontroller.h1
-rw-r--r--indra/llcharacter/llstatemachine.cpp384
-rw-r--r--indra/llcharacter/llstatemachine.h147
-rw-r--r--indra/llcommon/CMakeLists.txt1
-rw-r--r--indra/llcommon/indra_constants.h22
-rw-r--r--indra/llcommon/llapp.cpp1
-rw-r--r--indra/llcommon/llapp.h2
-rw-r--r--indra/llcommon/lldate.cpp7
-rw-r--r--indra/llcommon/llerror.cpp6
-rw-r--r--indra/llcommon/llerrorcontrol.h1
-rw-r--r--indra/llcommon/llfile.cpp29
-rw-r--r--indra/llcommon/llheteromap.cpp2
-rw-r--r--indra/llcommon/llheteromap.h27
-rw-r--r--indra/llcommon/llinitparam.h129
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llpointer.cpp (renamed from indra/newview/llfloatersounddevices.h)44
-rw-r--r--indra/llcommon/llpointer.h291
-rw-r--r--indra/llcommon/llpounceable.h4
-rw-r--r--indra/llcommon/llprocess.cpp13
-rw-r--r--indra/llcommon/llregistry.h26
-rw-r--r--indra/llcommon/llsd.cpp162
-rw-r--r--indra/llcommon/llsd.h39
-rw-r--r--indra/llcommon/llsdjson.cpp4
-rw-r--r--indra/llcommon/llsdserialize.cpp52
-rw-r--r--indra/llcommon/llsdserialize_xml.cpp32
-rw-r--r--indra/llcommon/llsingleton.h4
-rw-r--r--indra/llcommon/llstaticstringtable.h5
-rw-r--r--indra/llcommon/llstl.h38
-rw-r--r--indra/llcommon/lluuid.h19
-rw-r--r--indra/llcommon/llwatchdog.cpp1
-rw-r--r--indra/llcommon/workqueue.cpp22
-rw-r--r--indra/llfilesystem/lldir.cpp56
-rw-r--r--indra/llfilesystem/lldir.h3
-rw-r--r--indra/llfilesystem/lldiskcache.cpp14
-rw-r--r--indra/llfilesystem/llfilesystem.cpp18
-rw-r--r--indra/llimage/llimage.h5
-rw-r--r--indra/llinventory/llinventory.cpp18
-rw-r--r--indra/llkdu/llimagej2ckdu.cpp5
-rw-r--r--indra/llmath/llvolume.cpp31
-rw-r--r--indra/llmath/llvolumemgr.cpp1
-rw-r--r--indra/llmath/v3math.h9
-rw-r--r--indra/llmeshoptimizer/llmeshoptimizer.cpp1
-rw-r--r--indra/llmessage/llavatarnamecache.cpp18
-rw-r--r--indra/llmessage/llavatarnamecache.h10
-rw-r--r--indra/llmessage/llcachename.cpp15
-rw-r--r--indra/llmessage/llcachename.h3
-rw-r--r--indra/llmessage/llcorehttputil.cpp132
-rw-r--r--indra/llmessage/llcorehttputil.h9
-rw-r--r--indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp165
-rw-r--r--indra/llphysicsextensionsos/llconvexdecompositionvhacd.h20
-rw-r--r--indra/llprimitive/llgltfmaterial.cpp92
-rw-r--r--indra/llprimitive/llgltfmaterial.h8
-rw-r--r--indra/llprimitive/llmaterialid.h30
-rw-r--r--indra/llprimitive/llprimitive.h9
-rw-r--r--indra/llrender/llfontfreetype.h5
-rw-r--r--indra/llrender/llgl.cpp6
-rw-r--r--indra/llrender/llgl.h4
-rw-r--r--indra/llrender/llimagegl.cpp2
-rw-r--r--indra/llrender/llrender.cpp63
-rw-r--r--indra/llrender/llrender.h13
-rw-r--r--indra/llrender/lltexturemanagerbridge.cpp2
-rw-r--r--indra/llui/llcallbackmap.h6
-rw-r--r--indra/llui/llfloater.cpp2
-rw-r--r--indra/llui/llfloaterreg.cpp19
-rw-r--r--indra/llui/llfloaterreg.h13
-rw-r--r--indra/llui/llfolderviewitem.cpp13
-rw-r--r--indra/llui/llfunctorregistry.h5
-rw-r--r--indra/llui/llkeywords.h2
-rw-r--r--indra/llui/lllineeditor.cpp1
-rw-r--r--indra/llui/lllineeditor.h2
-rw-r--r--indra/llui/llnotifications.cpp7
-rw-r--r--indra/llui/llnotifications.h5
-rw-r--r--indra/llui/llpanel.h4
-rw-r--r--indra/llui/llradiogroup.cpp2
-rw-r--r--indra/llui/llrngwriter.cpp2
-rw-r--r--indra/llui/llscrolllistcolumn.cpp2
-rw-r--r--indra/llui/llscrolllistctrl.cpp1
-rw-r--r--indra/llui/lltabcontainer.cpp13
-rw-r--r--indra/llui/lltabcontainer.h1
-rw-r--r--indra/llui/lltextbase.cpp2
-rw-r--r--indra/llui/lltexteditor.cpp2
-rw-r--r--indra/llui/lltooltip.cpp2
-rw-r--r--indra/llui/lltrans.h2
-rw-r--r--indra/llui/llui.cpp2
-rw-r--r--indra/llui/llui.h2
-rw-r--r--indra/llui/lluicolortable.cpp9
-rw-r--r--indra/llui/lluicolortable.h4
-rw-r--r--indra/llui/lluictrlfactory.cpp2
-rw-r--r--indra/llui/lluictrlfactory.h12
-rw-r--r--indra/llui/llxuiparser.cpp46
-rw-r--r--indra/llui/llxuiparser.h6
-rw-r--r--indra/llwebrtc/llwebrtc.cpp64
-rw-r--r--indra/llwebrtc/llwebrtc.h6
-rw-r--r--indra/llwebrtc/llwebrtc_impl.h2
-rw-r--r--indra/llxml/llcontrol.cpp31
-rw-r--r--indra/llxml/llcontrol.h6
-rw-r--r--indra/newview/CMakeLists.txt12
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml110
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl9
-rw-r--r--indra/newview/gltf/asset.cpp6
-rw-r--r--indra/newview/gltf/buffer_util.h44
-rw-r--r--indra/newview/gltf/llgltfloader.cpp112
-rw-r--r--indra/newview/installers/windows/installer_template.nsi33
-rw-r--r--indra/newview/llagent.cpp23
-rw-r--r--indra/newview/llagent.h1
-rw-r--r--indra/newview/llagentcamera.cpp8
-rw-r--r--indra/newview/llaisapi.cpp28
-rw-r--r--indra/newview/llaisapi.h14
-rw-r--r--indra/newview/llappcorehttp.cpp2
-rw-r--r--indra/newview/llappviewer.cpp52
-rw-r--r--indra/newview/llappviewer.h2
-rw-r--r--indra/newview/llavataractions.cpp2
-rw-r--r--indra/newview/llavatarlistitem.cpp2
-rw-r--r--indra/newview/llcallingcard.cpp2
-rw-r--r--indra/newview/llcapabilityprovider.h4
-rw-r--r--indra/newview/llcofwearables.cpp2
-rw-r--r--indra/newview/llconversationview.cpp47
-rw-r--r--indra/newview/llconversationview.h3
-rw-r--r--indra/newview/lldrawable.cpp8
-rw-r--r--indra/newview/lldrawpoolalpha.cpp2
-rw-r--r--indra/newview/llface.cpp101
-rw-r--r--indra/newview/llface.h2
-rw-r--r--indra/newview/llfilepicker_mac.mm7
-rw-r--r--indra/newview/llfloater360capture.cpp2
-rw-r--r--indra/newview/llfloaterbigpreview.cpp110
-rw-r--r--indra/newview/llfloaterbigpreview.h54
-rw-r--r--indra/newview/llfloatereditenvironmentbase.cpp2
-rw-r--r--indra/newview/llfloaterexperiences.cpp5
-rw-r--r--indra/newview/llfloaterimcontainer.cpp111
-rw-r--r--indra/newview/llfloaterimcontainer.h1
-rw-r--r--indra/newview/llfloaterimsession.cpp2
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp18
-rw-r--r--indra/newview/llfloaterimsessiontab.h2
-rw-r--r--indra/newview/llfloaterlinkreplace.cpp31
-rw-r--r--indra/newview/llfloatermarketplace.cpp36
-rw-r--r--indra/newview/llfloatermarketplace.h3
-rw-r--r--indra/newview/llfloatermarketplacelistings.cpp24
-rw-r--r--indra/newview/llfloaterobjectweights.cpp2
-rw-r--r--indra/newview/llfloaterpay.cpp2
-rw-r--r--indra/newview/llfloaterpostprocess.cpp229
-rw-r--r--indra/newview/llfloaterpostprocess.h72
-rw-r--r--indra/newview/llfloaterpreference.cpp17
-rw-r--r--indra/newview/llfloaterpreference.h1
-rw-r--r--indra/newview/llfloaterregioninfo.cpp15
-rw-r--r--indra/newview/llfloatersearch.cpp21
-rw-r--r--indra/newview/llfloatersnapshot.cpp2
-rw-r--r--indra/newview/llfloatersounddevices.cpp86
-rw-r--r--indra/newview/llfloatervoiceeffect.cpp289
-rw-r--r--indra/newview/llfloatervoiceeffect.h72
-rw-r--r--indra/newview/llgltfmateriallist.cpp2
-rw-r--r--indra/newview/llgrouplist.cpp2
-rw-r--r--indra/newview/llhudnametag.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp22
-rw-r--r--indra/newview/llinventoryfunctions.cpp16
-rw-r--r--indra/newview/llinventorygallery.cpp10
-rw-r--r--indra/newview/llinventorygallerymenu.cpp8
-rw-r--r--indra/newview/llinventorylistitem.cpp2
-rw-r--r--indra/newview/llinventorymodel.cpp81
-rw-r--r--indra/newview/llinventorymodel.h12
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.cpp2
-rw-r--r--indra/newview/llinventorypanel.cpp19
-rw-r--r--indra/newview/llinventorypanel.h2
-rw-r--r--indra/newview/lllocalbitmaps.cpp2
-rw-r--r--indra/newview/llmachineid.cpp2
-rw-r--r--indra/newview/llmarketplacefunctions.cpp4
-rw-r--r--indra/newview/llmaterialmgr.h76
-rw-r--r--indra/newview/llmeshrepository.cpp64
-rw-r--r--indra/newview/llmeshrepository.h14
-rw-r--r--indra/newview/llmodelpreview.cpp2
-rw-r--r--indra/newview/llmutelist.cpp4
-rw-r--r--indra/newview/llnavigationbar.cpp9
-rw-r--r--indra/newview/llnearbyvoicemoderation.cpp220
-rw-r--r--indra/newview/llnearbyvoicemoderation.h50
-rw-r--r--indra/newview/llnetmap.cpp36
-rw-r--r--indra/newview/lloutfitgallery.cpp19
-rw-r--r--indra/newview/lloutfitgallery.h2
-rw-r--r--indra/newview/lloutfitslist.cpp17
-rw-r--r--indra/newview/lloutfitslist.h13
-rw-r--r--indra/newview/llpanelface.cpp21
-rw-r--r--indra/newview/llpanelgenerictip.cpp8
-rw-r--r--indra/newview/llpanelgroup.cpp34
-rw-r--r--indra/newview/llpanelgroup.h9
-rw-r--r--indra/newview/llpanellogin.cpp42
-rw-r--r--indra/newview/llpanellogin.h6
-rw-r--r--indra/newview/llpanelmaininventory.cpp54
-rw-r--r--indra/newview/llpanelmaininventory.h1
-rw-r--r--indra/newview/llpanelobject.cpp37
-rw-r--r--indra/newview/llpanelobjectinventory.cpp2
-rw-r--r--indra/newview/llpanelobjectinventory.h2
-rw-r--r--indra/newview/llpanelpermissions.cpp4
-rw-r--r--indra/newview/llpanelvoiceeffect.cpp165
-rw-r--r--indra/newview/llpanelvoiceeffect.h67
-rw-r--r--indra/newview/llpanelvolume.cpp10
-rw-r--r--indra/newview/llperfstats.h2
-rw-r--r--indra/newview/llpreviewnotecard.cpp3
-rw-r--r--indra/newview/llscriptruntimeperms.h13
-rw-r--r--indra/newview/llselectmgr.cpp9
-rw-r--r--indra/newview/llspatialpartition.cpp8
-rw-r--r--indra/newview/llspatialpartition.h2
-rw-r--r--indra/newview/lltexturecache.cpp70
-rw-r--r--indra/newview/lltexturecache.h3
-rw-r--r--indra/newview/lltoastscriptquestion.cpp73
-rw-r--r--indra/newview/lltooldraganddrop.cpp2
-rw-r--r--indra/newview/lltoolselect.cpp9
-rw-r--r--indra/newview/llvieweraudio.cpp59
-rw-r--r--indra/newview/llviewercontrol.cpp1
-rw-r--r--indra/newview/llviewerdisplay.cpp4
-rw-r--r--indra/newview/llviewerfloaterreg.cpp10
-rw-r--r--indra/newview/llviewermedia.cpp14
-rw-r--r--indra/newview/llviewermenu.cpp175
-rw-r--r--indra/newview/llviewermessage.cpp24
-rw-r--r--indra/newview/llviewerobject.cpp231
-rw-r--r--indra/newview/llviewerobject.h70
-rw-r--r--indra/newview/llviewerobjectlist.cpp5
-rw-r--r--indra/newview/llviewerobjectlist.h4
-rw-r--r--indra/newview/llvieweroctree.h1
-rw-r--r--indra/newview/llviewerparcelmgr.cpp13
-rw-r--r--indra/newview/llviewerparcelmgr.h6
-rwxr-xr-xindra/newview/llviewerparceloverlay.cpp235
-rw-r--r--indra/newview/llviewerparceloverlay.h5
-rw-r--r--indra/newview/llviewerprecompiledheaders.h2
-rwxr-xr-xindra/newview/llviewerregion.cpp40
-rw-r--r--indra/newview/llviewerregion.h10
-rw-r--r--indra/newview/llviewerstats.cpp14
-rw-r--r--indra/newview/llviewerstats.h3
-rw-r--r--indra/newview/llviewertexture.cpp62
-rw-r--r--indra/newview/llviewertexturelist.cpp20
-rw-r--r--indra/newview/llviewerwearable.cpp1
-rw-r--r--indra/newview/llviewerwindow.cpp68
-rw-r--r--indra/newview/llviewerwindow.h7
-rw-r--r--indra/newview/llvlmanager.cpp6
-rw-r--r--indra/newview/llvoavatar.cpp27
-rw-r--r--indra/newview/llvoavatar.h4
-rw-r--r--indra/newview/llvoiceclient.cpp8
-rw-r--r--indra/newview/llvoicevivox.cpp2
-rw-r--r--indra/newview/llvoicewebrtc.cpp195
-rw-r--r--indra/newview/llvoicewebrtc.h6
-rw-r--r--indra/newview/llvovolume.cpp153
-rw-r--r--indra/newview/llvovolume.h5
-rw-r--r--indra/newview/llwearableitemslist.cpp10
-rw-r--r--indra/newview/llweb.cpp13
-rw-r--r--indra/newview/llworldmap.cpp1
-rw-r--r--indra/newview/llworldmap.h12
-rwxr-xr-xindra/newview/llworldmapview.cpp40
-rw-r--r--indra/newview/pipeline.cpp6
-rw-r--r--indra/newview/skins/default/xui/da/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/da/floater_voice_effect.xml30
-rw-r--r--indra/newview/skins/default/xui/da/panel_voice_effect.xml15
-rw-r--r--indra/newview/skins/default/xui/de/floater_big_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_post_process.xml53
-rw-r--r--indra/newview/skins/default/xui/de/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/de/floater_voice_effect.xml159
-rw-r--r--indra/newview/skins/default/xui/de/panel_voice_effect.xml15
-rw-r--r--indra/newview/skins/default/xui/en/floater_big_preview.xml25
-rw-r--r--indra/newview/skins/default/xui/en/floater_post_process.xml426
-rw-r--r--indra/newview/skins/default/xui/en/floater_sound_devices.xml48
-rw-r--r--indra/newview/skins/default/xui/en/floater_stats.xml58
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_combobox.xml32
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_effect.xml162
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml30
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_self.xml22
-rw-r--r--indra/newview/skins/default/xui/en/menu_conversation.xml107
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_view_default.xml48
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml19
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml55
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml9
-rw-r--r--indra/newview/skins/default/xui/en/panel_notification.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_general.xml54
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_general.xml55
-rw-r--r--indra/newview/skins/default/xui/en/panel_script_question_toast.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_voice_effect.xml33
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/es/floater_big_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_post_process.xml53
-rw-r--r--indra/newview/skins/default/xui/es/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/es/floater_voice_effect.xml138
-rw-r--r--indra/newview/skins/default/xui/es/panel_voice_effect.xml15
-rw-r--r--indra/newview/skins/default/xui/fr/floater_big_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_post_process.xml54
-rw-r--r--indra/newview/skins/default/xui/fr/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/fr/floater_voice_effect.xml159
-rw-r--r--indra/newview/skins/default/xui/fr/panel_voice_effect.xml15
-rw-r--r--indra/newview/skins/default/xui/it/floater_big_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_post_process.xml53
-rw-r--r--indra/newview/skins/default/xui/it/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/it/floater_voice_effect.xml159
-rw-r--r--indra/newview/skins/default/xui/it/panel_voice_effect.xml15
-rw-r--r--indra/newview/skins/default/xui/ja/floater_big_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_post_process.xml53
-rw-r--r--indra/newview/skins/default/xui/ja/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/ja/floater_voice_effect.xml159
-rw-r--r--indra/newview/skins/default/xui/ja/panel_voice_effect.xml15
-rw-r--r--indra/newview/skins/default/xui/pl/floater_big_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/floater_post_process.xml49
-rw-r--r--indra/newview/skins/default/xui/pl/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/pl/floater_voice_effect.xml98
-rw-r--r--indra/newview/skins/default/xui/pl/panel_voice_effect.xml15
-rw-r--r--indra/newview/skins/default/xui/pt/floater_big_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_post_process.xml53
-rw-r--r--indra/newview/skins/default/xui/pt/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/pt/floater_voice_effect.xml159
-rw-r--r--indra/newview/skins/default/xui/pt/panel_voice_effect.xml15
-rw-r--r--indra/newview/skins/default/xui/ru/floater_big_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_post_process.xml53
-rw-r--r--indra/newview/skins/default/xui/ru/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/ru/floater_voice_effect.xml159
-rw-r--r--indra/newview/skins/default/xui/ru/panel_voice_effect.xml15
-rw-r--r--indra/newview/skins/default/xui/tr/floater_big_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_post_process.xml53
-rw-r--r--indra/newview/skins/default/xui/tr/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/tr/floater_voice_effect.xml159
-rw-r--r--indra/newview/skins/default/xui/tr/panel_voice_effect.xml15
-rw-r--r--indra/newview/skins/default/xui/zh/floater_big_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_post_process.xml53
-rw-r--r--indra/newview/skins/default/xui/zh/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/zh/floater_voice_effect.xml159
-rw-r--r--indra/newview/skins/default/xui/zh/panel_voice_effect.xml15
-rw-r--r--indra/newview/tests/lldateutil_test.cpp6
330 files changed, 4603 insertions, 7207 deletions
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 4c8d98ce2f..2101b9b5e8 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -86,7 +86,7 @@ jobs:
variants: ${{ matrix.configuration }}
steps:
- name: Checkout code
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
@@ -95,14 +95,14 @@ jobs:
with:
python-version: "3.11"
- name: Checkout build variables
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
repository: secondlife/build-variables
ref: master
path: .build-variables
- name: Checkout master-message-template
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
repository: secondlife/master-message-template
path: .master-message-template
@@ -112,7 +112,7 @@ jobs:
- name: Cache autobuild packages
id: cache-installables
- uses: actions/cache@v4
+ uses: actions/cache@v5
with:
path: .autobuild-installables
key: ${{ runner.os }}-64-${{ matrix.configuration }}-${{ hashFiles('autobuild.xml') }}
@@ -265,7 +265,7 @@ jobs:
- name: Upload executable
if: steps.build.outputs.viewer_app
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v6
with:
name: "${{ steps.build.outputs.artifact }}-app"
path: |
@@ -275,13 +275,13 @@ jobs:
# artifact for that too.
- name: Upload symbol file
if: steps.build.outputs.symbolfile
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v6
with:
name: "${{ steps.build.outputs.artifact }}-symbols"
path: ${{ steps.build.outputs.symbolfile }}
- name: Upload metadata
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v6
with:
name: "${{ steps.build.outputs.artifact }}-metadata"
# emitted by build.sh, possibly multiple lines
@@ -289,7 +289,7 @@ jobs:
${{ steps.build.outputs.metadata }}
- name: Upload physics package
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v6
# should only be set for viewer-private
if: matrix.configuration == 'Release' && steps.build.outputs.physicstpv
with:
@@ -370,13 +370,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download viewer exe
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v7
with:
name: Windows-app
path: _artifacts
- name: Download Windows Symbols
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v7
with:
name: Windows-symbols
- name: Extract viewer pdb
@@ -409,7 +409,7 @@ jobs:
steps:
- name: Download Mac Symbols
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v7
with:
name: macOS-symbols
- name: Post Mac symbols
@@ -431,11 +431,11 @@ jobs:
runs-on: ubuntu-latest
if: needs.setup.outputs.release_run
steps:
- - uses: actions/download-artifact@v4
+ - uses: actions/download-artifact@v7
with:
pattern: "*-installer"
- - uses: actions/download-artifact@v4
+ - uses: actions/download-artifact@v7
with:
pattern: "*-metadata"
diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml
index 5b31c584d5..800f3c42d1 100644
--- a/.github/workflows/cla.yaml
+++ b/.github/workflows/cla.yaml
@@ -23,4 +23,4 @@ jobs:
path-to-signatures: signatures.json
remote-organization-name: secondlife
remote-repository-name: cla-signatures
- allowlist: callum@mbp.localdomain,rye@lindenlab.com,rye,bot*
+ allowlist: callum@mbp.localdomain,rye@lindenlab.com,rye,signal@lindenlab.com,dependabot*,bot*
diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml
index 8f942fa11b..93bcafdea8 100644
--- a/.github/workflows/pre-commit.yaml
+++ b/.github/workflows/pre-commit.yaml
@@ -11,7 +11,7 @@ jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x
diff --git a/autobuild.xml b/autobuild.xml
index 8f9226e301..cb367a03d1 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -138,11 +138,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>a4553df5b8fde2e9cd54ebb94c6efb8eb5fe3c38</string>
+ <string>61cc299413a32350175cf7139f64388d3d096ec7</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-boost/releases/download/v1.86.0-be1a669/boost-1.86-darwin64-13246092114.tar.zst</string>
+ <string>https://github.com/secondlife/3p-boost/releases/download/v1.90.0-c7a9feb/boost-1.90-darwin64-20977261894.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -152,11 +152,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>4a2a19dc5cb555e157ad894ba917f5a83a35b20d</string>
+ <string>6b93e323284bfab8ec20a7f3bc740c6915980bf8</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-boost/releases/download/v1.86.0-be1a669/boost-1.86-linux64-13246092114.tar.zst</string>
+ <string>https://github.com/secondlife/3p-boost/releases/download/v1.90.0-c7a9feb/boost-1.90-linux64-20977261894.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -166,11 +166,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>8a1fa9366bfe49009286e4805d7aaedb7c3df82e</string>
+ <string>c543437ca30a63dcd2538fffa89a43ef43f625fb</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-boost/releases/download/v1.86.0-be1a669/boost-1.86-windows64-13246092114.tar.zst</string>
+ <string>https://github.com/secondlife/3p-boost/releases/download/v1.90.0-c7a9feb/boost-1.90-windows64-20977261894.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -183,7 +183,7 @@
<key>copyright</key>
<string>(see individual source files)</string>
<key>version</key>
- <string>1.86</string>
+ <string>1.90.0-c7a9feb</string>
<key>name</key>
<string>boost</string>
<key>description</key>
@@ -244,11 +244,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>bf2fe4e8272e990bc8687b3b37bf4bb2b2ad6eb4</string>
+ <string>9710f82a237b95aaafbbcf708b89f6015b80d85f</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r10/colladadom-2.3.0-r10-darwin64-13259816660.tar.zst</string>
+ <string>https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r11/colladadom-2.3.0-r11-darwin64-20980076767.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -258,11 +258,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>118e509ca464182ef4b94ee8c4aa5b14a6c52a94</string>
+ <string>6a1725b1bc13634eb4dd872a4f83c3f16497475f</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r10/colladadom-2.3.0-r10-linux64-13259816660.tar.zst</string>
+ <string>https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r11/colladadom-2.3.0-r11-linux64-20980076767.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -272,11 +272,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>d7aee1b2ec17bd88a2c27359281b58a11ec52d48</string>
+ <string>ba9eeb62ae3046d91f9e061db823c1863623b017</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r10/colladadom-2.3.0-r10-windows64-13259816660.tar.zst</string>
+ <string>https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r11/colladadom-2.3.0-r11-windows64-20980076767.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -289,7 +289,7 @@
<key>copyright</key>
<string>Copyright 2006 Sony Computer Entertainment Inc.</string>
<key>version</key>
- <string>2.3.0-r10</string>
+ <string>2.3.0-r11</string>
<key>name</key>
<string>colladadom</string>
</map>
@@ -360,11 +360,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>e742b1e2d0a58d607b023bf55411041ac65e8a76</string>
+ <string>5eab8167cec442e8c156bb653012d7544cca6037</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r3/curl-7.54.1-13259824618-darwin64-13259824618.tar.zst</string>
+ <string>https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r4/curl-7.54.1-20982000504-darwin64-20982000504.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -374,11 +374,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>49621c70f385d37c95bcb69a9a24d86ac25f4781</string>
+ <string>3465bbe70cfba2814b1fd52094c62804f4067490</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r3/curl-7.54.1-13259824618-linux64-13259824618.tar.zst</string>
+ <string>https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r4/curl-7.54.1-20982000504-linux64-20982000504.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -388,11 +388,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>2522201692116cf0adb7203e169be9126885108c</string>
+ <string>0e64e20945eeb19259abf8e78400eb492e31eda7</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r3/curl-7.54.1-13259824618-windows64-13259824618.tar.zst</string>
+ <string>https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r4/curl-7.54.1-20982000504-windows64-20982000504.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -405,7 +405,7 @@
<key>copyright</key>
<string>Copyright (c) 1996 - 2014, Daniel Stenberg, (daniel@haxx.se).</string>
<key>version</key>
- <string>7.54.1-13259824618</string>
+ <string>7.54.1-20982000504</string>
<key>name</key>
<string>curl</string>
<key>description</key>
@@ -666,11 +666,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>5e6c7b9aaf73d90d7feab846a4024193c48eff6c</string>
+ <string>550a90bca35bdbbd615afb1a1c02383cb3b6edbe</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-r3/freetype-2.13.3-r3-darwin64-13259804885.tar.zst</string>
+ <string>https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-r4/freetype-2.13.3-r4-darwin64-20935810762.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -680,11 +680,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>a9a3c371958e64a49b07d7be8f59218dfd6b0352</string>
+ <string>f52b05392962cb6a8e5f534d8687faa525d4960a</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-r3/freetype-2.13.3-r3-linux64-13259804885.tar.zst</string>
+ <string>https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-r4/freetype-2.13.3-r4-linux64-20935810762.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -694,11 +694,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>ad7fbc4a01607ec43d86035a49dadd43d6f2a4e5</string>
+ <string>3c30052adcbfec572562bb1e7927d7a8f4d93f3d</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-r3/freetype-2.13.3-r3-windows64-13259804885.tar.zst</string>
+ <string>https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-r4/freetype-2.13.3-r4-windows64-20935810762.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -711,7 +711,7 @@
<key>copyright</key>
<string>Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg.</string>
<key>version</key>
- <string>2.13.3-r3</string>
+ <string>2.13.3-r4</string>
<key>name</key>
<string>freetype</string>
<key>description</key>
@@ -1234,11 +1234,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>a453355ee032f79aea4142218a957085a22c7656</string>
+ <string>6fa10d5f44601dda6efc3eda1a9dab22525e7a9a</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-libpng/releases/download/v1.6.44-r2/libpng-1.6.44-r2-darwin64-13246065198.tar.zst</string>
+ <string>https://github.com/secondlife/3p-libpng/releases/download/v1.6.53-eea12b7/libpng-1.6.44-dev1.geea12b7-darwin64-20934739343.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -1248,11 +1248,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>75c7608646c9f5b99b1a9e3946326e2804a304d7</string>
+ <string>112b7f46f5923e6418dfa4bc13ebe2db6911c9b9</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-libpng/releases/download/v1.6.44-r2/libpng-1.6.44-r2-linux64-13246065198.tar.zst</string>
+ <string>https://github.com/secondlife/3p-libpng/releases/download/v1.6.53-eea12b7/libpng-1.6.44-dev1.geea12b7-linux64-20934739343.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -1262,11 +1262,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>09af51774c4ee7c03fe67a87dfc52e846aa625ea</string>
+ <string>2731c45f1e62e33b8612b3ee2b9c4cb39dafbfe2</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-libpng/releases/download/v1.6.44-r2/libpng-1.6.44-r2-windows64-13246065198.tar.zst</string>
+ <string>https://github.com/secondlife/3p-libpng/releases/download/v1.6.53-eea12b7/libpng-1.6.44-dev1.geea12b7-windows64-20934739343.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -1279,7 +1279,7 @@
<key>copyright</key>
<string>Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson</string>
<key>version</key>
- <string>1.6.44-r2</string>
+ <string>1.6.53-eea12b7</string>
<key>name</key>
<string>libpng</string>
<key>description</key>
@@ -1324,11 +1324,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>372c92936d940b1cfb5ba34310691d4bb435c161</string>
+ <string>c1ad7ff9ec91049c93d2dcd832f81a00f8f4b4b9</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.5-r2/libxml2-2.13.5-r2-darwin64-13246071272.tar.zst</string>
+ <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.9-d53cd6f/libxml2-2.13.9-d53cd6f-darwin64-20936141417.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -1338,11 +1338,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>ba6fbc34112b1acab1c8615dcd13de983f3678d3</string>
+ <string>7fc2df91648661468a82754b26fd7dedfbef1d39</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.5-r2/libxml2-2.13.5-r2-linux64-13246071272.tar.zst</string>
+ <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.9-d53cd6f/libxml2-2.13.9-d53cd6f-linux64-20936141417.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -1352,11 +1352,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>71968c4b621636e8ae0c5680e631f4aa67561944</string>
+ <string>84828c26b67c33f0d3e565718943aa339582b34f</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.5-r2/libxml2-2.13.5-r2-windows64-13246071272.tar.zst</string>
+ <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.9-d53cd6f/libxml2-2.13.9-d53cd6f-windows64-20936141417.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -1369,7 +1369,7 @@
<key>copyright</key>
<string>Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved.</string>
<key>version</key>
- <string>2.13.5-r2</string>
+ <string>2.13.9-d53cd6f</string>
<key>name</key>
<string>libxml2</string>
<key>description</key>
@@ -1543,11 +1543,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>874a7d2bc843554aa4facd03b3a6d681f2b5150c</string>
+ <string>3692af717636da9c2b1e0f13eb084ce022b67f6c</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-meshoptimizer/releases/download/v220-r1/meshoptimizer-220.0.0-r1-darwin64-11968851109.tar.zst</string>
+ <string>https://github.com/secondlife/3p-meshoptimizer/releases/download/v1.0.1-9d6a006/meshoptimizer-1.0.1-9d6a006-darwin64-20867041007.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -1557,11 +1557,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>31a537f1a3d38ef85443214315111dd56a534d9a</string>
+ <string>22ad1be39a1196a1ca3902ba936460cb69252b9c</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-meshoptimizer/releases/download/v220-r1/meshoptimizer-220.0.0-r1-linux64-11968851109.tar.zst</string>
+ <string>https://github.com/secondlife/3p-meshoptimizer/releases/download/v1.0.1-9d6a006/meshoptimizer-1.0.1-9d6a006-linux64-20867041007.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -1571,11 +1571,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>6fd727a9ccb3e7a6c6b4ffef8179e266c032eb3e</string>
+ <string>2c9769f31da5de3920d7ee400d280398c911a30f</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-meshoptimizer/releases/download/v220-r1/meshoptimizer-220.0.0-r1-windows64-11968851109.tar.zst</string>
+ <string>https://github.com/secondlife/3p-meshoptimizer/releases/download/v1.0.1-9d6a006/meshoptimizer-1.0.1-9d6a006-windows64-20867041007.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -1667,11 +1667,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>b628d088e1f368a0cd51a6b66292aaf9a025e2d4</string>
+ <string>85179317015c5c91986000d69c9f61a01af7617f</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r3/minizip_ng-4.0.7-r3-darwin64-13246046977.tar.zst</string>
+ <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r4/minizip_ng-4.0.7-r4-darwin64-20933148061.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -1681,11 +1681,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>492ce9175b730d43df63821c4481685e035af623</string>
+ <string>ef1524f507f44fed6f1c1f00ae274ddb8a1ac359</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r3/minizip_ng-4.0.7-r3-linux64-13246046977.tar.zst</string>
+ <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r4/minizip_ng-4.0.7-r4-linux64-20933148061.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -1695,11 +1695,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>58773e707ff3490822b7b8217d7729ade2186632</string>
+ <string>90be39cf789b596377458f1ea78f415a9c281a8c</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r3/minizip_ng-4.0.7-r3-windows64-13246046977.tar.zst</string>
+ <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r4/minizip_ng-4.0.7-r4-windows64-20933148061.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -1712,7 +1712,7 @@
<key>copyright</key>
<string>This project uses the zlib license. Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler</string>
<key>version</key>
- <string>4.0.7-r3</string>
+ <string>4.0.7-r4</string>
<key>name</key>
<string>minizip-ng</string>
<key>canonical_repo</key>
@@ -2092,11 +2092,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>157193699127ac5056c5fc1a410f9c98d39731e2</string>
+ <string>e08f640fb423f878c288426c836189b30b0c8ad0</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r3/openssl-1.1.1w-r3-darwin64-13246054022.tar.zst</string>
+ <string>https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r4/openssl-1.1.1w-r4-darwin64-20981673556.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -2106,11 +2106,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>2e29c127dbd002d64ae55bc000f8b6ed0249fad7</string>
+ <string>d83a1e910762b792c90550ce2b8f51f9aaec7570</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r3/openssl-1.1.1w-r3-linux64-13246054022.tar.zst</string>
+ <string>https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r4/openssl-1.1.1w-r4-linux64-20981673556.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -2120,11 +2120,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>ae9ced89051e03a99628c99b9ac78530fdea1e5a</string>
+ <string>eec78c22e2d1eecf375aa0c6eff08fe67d2316f4</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r3/openssl-1.1.1w-r3-windows64-13246054022.tar.zst</string>
+ <string>https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r4/openssl-1.1.1w-r4-windows64-20981673556.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -2137,7 +2137,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>copyright</key>
<string>Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved; Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)</string>
<key>version</key>
- <string>1.1.1w-r3</string>
+ <string>1.1.1w-r4</string>
<key>name</key>
<string>openssl</string>
<key>description</key>
@@ -2744,11 +2744,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>e363e3b889c52fda7601d7aeaa9832307034651e</string>
+ <string>4906257288c61b14d2e16116fc3139af35d3374f</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-darwin64-13183604450.tar.zst</string>
+ <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.5-0d88d03/zlib_ng-2.2.5-dev0.g0d88d03.d20260112-darwin64-20930307098.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -2758,11 +2758,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>3cdd52f7fb3691789d50f0b40ed6f5642321ff32</string>
+ <string>2b81a6a4ebd9ae5555d48b52eea7c2d875d68f60</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-linux64-13183604450.tar.zst</string>
+ <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.5-0d88d03/zlib_ng-2.2.5-dev0.g0d88d03.d20260112-linux64-20930307098.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -2772,11 +2772,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>e802a28139328bb2421ad39e13d996d350d8106d</string>
+ <string>e2e0f964ba44fe2e6428e1e7ca262a3f80d92e65</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-windows64-13183604450.tar.zst</string>
+ <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.5-0d88d03/zlib_ng-2.2.5-dev0.g0d88d03.d20260112-windows64-20930307098.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -2789,7 +2789,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>copyright</key>
<string>Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler</string>
<key>version</key>
- <string>2.2.3-dev0.g8aa13e3.d20250206</string>
+ <string>2.2.5-0d88d03</string>
<key>name</key>
<string>zlib-ng</string>
<key>canonical_repo</key>
diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake
index e754918c5b..961973f3fe 100644
--- a/indra/cmake/Boost.cmake
+++ b/indra/cmake/Boost.cmake
@@ -55,48 +55,42 @@ if (WINDOWS)
find_library(BOOST_CONTEXT_LIBRARY
NAMES
+ libboost_context
libboost_context-mt
libboost_context-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
find_library(BOOST_FIBER_LIBRARY
NAMES
+ libboost_fiber
libboost_fiber-mt
libboost_fiber-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
find_library(BOOST_FILESYSTEM_LIBRARY
NAMES
+ libboost_filesystem
libboost_filesystem-mt
libboost_filesystem-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
find_library(BOOST_PROGRAMOPTIONS_LIBRARY
NAMES
+ libboost_program_options
libboost_program_options-mt
libboost_program_options-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- find_library(BOOST_REGEX_LIBRARY
- NAMES
- libboost_regex-mt
- libboost_regex-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_SYSTEM_LIBRARY
- NAMES
- libboost_system-mt
- libboost_system-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
find_library(BOOST_THREAD_LIBRARY
NAMES
+ libboost_thread
libboost_thread-mt
libboost_thread-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
find_library(BOOST_URL_LIBRARY
NAMES
+ libboost_url
libboost_url-mt
libboost_url-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
@@ -105,48 +99,42 @@ else (WINDOWS)
find_library(BOOST_CONTEXT_LIBRARY
NAMES
+ boost_context
boost_context-mt
boost_context-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
find_library(BOOST_FIBER_LIBRARY
NAMES
+ boost_fiber
boost_fiber-mt
boost_fiber-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
find_library(BOOST_FILESYSTEM_LIBRARY
NAMES
+ boost_filesystem
boost_filesystem-mt
boost_filesystem-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
find_library(BOOST_PROGRAMOPTIONS_LIBRARY
NAMES
+ boost_program_options
boost_program_options-mt
boost_program_options-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- find_library(BOOST_REGEX_LIBRARY
- NAMES
- boost_regex-mt
- boost_regex-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_SYSTEM_LIBRARY
- NAMES
- boost_system-mt
- boost_system-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
find_library(BOOST_THREAD_LIBRARY
NAMES
+ boost_thread
boost_thread-mt
boost_thread-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
find_library(BOOST_URL_LIBRARY
NAMES
+ boost_url
boost_url-mt
boost_url-mt${addrsfx}
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
@@ -158,8 +146,6 @@ target_link_libraries(ll::boost INTERFACE
${BOOST_CONTEXT_LIBRARY}
${BOOST_FILESYSTEM_LIBRARY}
${BOOST_PROGRAMOPTIONS_LIBRARY}
- ${BOOST_REGEX_LIBRARY}
- ${BOOST_SYSTEM_LIBRARY}
${BOOST_THREAD_LIBRARY}
${BOOST_URL_LIBRARY})
diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake
index 7cce190f6a..428f9e3326 100644
--- a/indra/cmake/Python.cmake
+++ b/indra/cmake/Python.cmake
@@ -1,57 +1,18 @@
-# -*- cmake -*-
+# Allow explicit Python path via environment variable
+if(DEFINED ENV{PYTHON})
+ set(Python3_ROOT_DIR "$ENV{PYTHON}")
+endif()
-set(PYTHONINTERP_FOUND)
+# On Windows, prefer registry entries to avoid Cygwin/MSYS Python
+# The registry is searched first by default, which finds native Windows Python
+# installations rather than Cygwin/MSYS Python
+if(WINDOWS)
+ set(Python3_FIND_REGISTRY FIRST CACHE STRING "Python search order")
+endif()
-if (DEFINED ENV{PYTHON})
- # Allow python executable to be explicitly set
- set(python "$ENV{PYTHON}")
- set(PYTHONINTERP_FOUND ON)
-elseif (WINDOWS)
- # On Windows, explicitly avoid Cygwin Python.
+# Find Python 3 interpreter
+find_package(Python3 REQUIRED COMPONENTS Interpreter)
- # if the user has their own version of Python installed, prefer that
- foreach(hive HKEY_CURRENT_USER HKEY_LOCAL_MACHINE)
- # prefer more recent Python versions to older ones, if multiple versions
- # are installed
- foreach(pyver 3.13 3.12 3.11 3.10 3.9 3.8 3.7)
- list(APPEND regpaths "[${hive}\\SOFTWARE\\Python\\PythonCore\\${pyver}\\InstallPath]")
- endforeach()
- endforeach()
-
- # TODO: This logic has the disadvantage that if you have multiple versions
- # of Python installed, the selected path won't necessarily be the newest -
- # e.g. this GLOB will prefer Python310 to Python311. But since pymaybe is
- # checked AFTER the registry entries, this will only surface as a problem if
- # no installed Python appears in the registry.
- file(GLOB pymaybe
- "$ENV{PROGRAMFILES}/Python*"
-## "$ENV{PROGRAMFILES(X86)}/Python*"
- # The Windows environment variable is in fact as shown above, but CMake
- # disallows querying an environment variable containing parentheses -
- # thanks, Windows. Fudge by just appending " (x86)" to $PROGRAMFILES and
- # hoping for the best.
- "$ENV{PROGRAMFILES} (x86)/Python*"
- "c:/Python*")
-
- find_program(python
- NAMES python3.exe python.exe
- NO_DEFAULT_PATH # added so that cmake does not find cygwin python
- PATHS
- ${regpaths}
- ${pymaybe}
- )
- find_package(Python3 COMPONENTS Interpreter)
-else()
- find_program(python python3)
-
- if (python)
- set(PYTHONINTERP_FOUND ON)
- endif (python)
-endif (DEFINED ENV{PYTHON})
-
-if (NOT python)
- message(FATAL_ERROR "No Python interpreter found")
-endif (NOT python)
-
-set(PYTHON_EXECUTABLE "${python}" CACHE FILEPATH "Python interpreter for builds")
+# Set legacy variable name for compatibility with existing code
+set(PYTHON_EXECUTABLE "${Python3_EXECUTABLE}" CACHE FILEPATH "Python interpreter for builds")
mark_as_advanced(PYTHON_EXECUTABLE)
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index bcb00e6afd..2452352097 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -1424,6 +1424,12 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
size_t mem_size = pixels * bytes_per_pixel;
alpha_data = (U8*)ll_aligned_malloc_32(mem_size);
+ if (!alpha_data)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS() << "Failed to allocate memory for morph texture: " << (S32)(mem_size) << LL_ENDL;
+ return;
+ }
bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels
@@ -1433,6 +1439,12 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
{ // work-around for broken intel drivers which cannot do glReadPixels on an RGBA FBO
// returning only the alpha portion without locking up downstream
U8* temp = (U8*)ll_aligned_malloc_32(mem_size << 2); // allocate same size, but RGBA
+ if (!temp)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS() << "Failed to allocate temporary memory for morph texture readback: " << (S32)(mem_size << 2) << LL_ENDL;
+ return;
+ }
if (bound_target)
{
@@ -1471,6 +1483,12 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
// We just want GL_ALPHA, but that isn't supported in OGL core profile 4.
static const size_t TEMP_BYTES_PER_PIXEL = 4;
U8* temp_data = (U8*)ll_aligned_malloc_32(mem_size * TEMP_BYTES_PER_PIXEL);
+ if (!temp_data)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS() << "Failed to allocate temporary memory for morph texture: " << (S32)(mem_size * TEMP_BYTES_PER_PIXEL) << LL_ENDL;
+ return;
+ }
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_data);
for (size_t pixel = 0; pixel < pixels; pixel++) {
alpha_data[pixel] = temp_data[(pixel * TEMP_BYTES_PER_PIXEL) + 3];
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index 613c408157..6f2f7eae61 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -225,6 +225,7 @@ void LLAudioEngine::updateChannels()
void LLAudioEngine::idle()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
// "Update" all of our audio sources, clean up dead ones.
// Primarily does position updating, cleanup of unused audio sources.
// Also does regeneration of the current priority of each audio source.
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt
index 7c158c4ff9..6795652136 100644
--- a/indra/llcharacter/CMakeLists.txt
+++ b/indra/llcharacter/CMakeLists.txt
@@ -17,14 +17,12 @@ set(llcharacter_SOURCE_FILES
lljointsolverrp3.cpp
llkeyframefallmotion.cpp
llkeyframemotion.cpp
- llkeyframemotionparam.cpp
llkeyframestandmotion.cpp
llkeyframewalkmotion.cpp
llmotioncontroller.cpp
llmotion.cpp
llmultigesture.cpp
llpose.cpp
- llstatemachine.cpp
lltargetingmotion.cpp
llvisualparam.cpp
)
@@ -45,14 +43,12 @@ set(llcharacter_HEADER_FILES
lljointstate.h
llkeyframefallmotion.h
llkeyframemotion.h
- llkeyframemotionparam.h
llkeyframestandmotion.h
llkeyframewalkmotion.h
llmotion.h
llmotioncontroller.h
llmultigesture.h
llpose.h
- llstatemachine.h
lltargetingmotion.h
llvisualparam.h
)
diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp
deleted file mode 100644
index e4552b96c9..0000000000
--- a/indra/llcharacter/llkeyframemotionparam.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/**
- * @file llkeyframemotionparam.cpp
- * @brief Implementation of LLKeyframeMotion class.
- *
- * $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$
- */
-
-//-----------------------------------------------------------------------------
-// Header Files
-//-----------------------------------------------------------------------------
-#include "linden_common.h"
-
-#include "llkeyframemotionparam.h"
-#include "llcharacter.h"
-#include "llmath.h"
-#include "m3math.h"
-#include "lldir.h"
-#include "llanimationstates.h"
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam class
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam()
-// Class Constructor
-//-----------------------------------------------------------------------------
-LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id)
-{
- mDefaultKeyframeMotion = NULL;
- mCharacter = NULL;
-
- mEaseInDuration = 0.f;
- mEaseOutDuration = 0.f;
- mDuration = 0.f;
- mPriority = LLJoint::LOW_PRIORITY;
-}
-
-
-//-----------------------------------------------------------------------------
-// ~LLKeyframeMotionParam()
-// Class Destructor
-//-----------------------------------------------------------------------------
-LLKeyframeMotionParam::~LLKeyframeMotionParam()
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- delete paramMotion.mMotion;
- }
- motionList.clear();
- }
- mParameterizedMotions.clear();
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onInitialize(LLCharacter *character)
-//-----------------------------------------------------------------------------
-LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character)
-{
- mCharacter = character;
-
- if (!loadMotions())
- {
- return STATUS_FAILURE;
- }
-
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- LLMotion* motion = paramMotion.mMotion;
- motion->onInitialize(character);
-
- if (motion->getDuration() > mEaseInDuration)
- {
- mEaseInDuration = motion->getEaseInDuration();
- }
-
- if (motion->getEaseOutDuration() > mEaseOutDuration)
- {
- mEaseOutDuration = motion->getEaseOutDuration();
- }
-
- if (motion->getDuration() > mDuration)
- {
- mDuration = motion->getDuration();
- }
-
- if (motion->getPriority() > mPriority)
- {
- mPriority = motion->getPriority();
- }
-
- LLPose *pose = motion->getPose();
-
- mPoseBlender.addMotion(motion);
- for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
- {
- LLPose *blendedPose = mPoseBlender.getBlendedPose();
- blendedPose->addJointState(jsp);
- }
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onActivate()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::onActivate()
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- paramMotion.mMotion->activate(mActivationTimestamp);
- }
- }
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onUpdate()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
-{
- LL_PROFILE_ZONE_SCOPED;
- F32 weightFactor = 1.f / (F32)mParameterizedMotions.size();
-
- // zero out all pose weights
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
-// LL_INFOS() << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << LL_ENDL;
- paramMotion.mMotion->getPose()->setWeight(0.f);
- }
- }
-
-
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- const std::string& paramName = motion_pair.first;
- F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName);
- if (NULL == paramValue) // unexpected, but...
- {
- LL_WARNS() << "paramValue == NULL" << LL_ENDL;
- continue;
- }
-
- // DANGER! Do not modify mParameterizedMotions while using these pointers!
- const ParameterizedMotion* firstMotion = NULL;
- const ParameterizedMotion* secondMotion = NULL;
-
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- paramMotion.mMotion->onUpdate(time, joint_mask);
-
- F32 distToParam = paramMotion.mParam - *paramValue;
-
- if ( distToParam <= 0.f)
- {
- // keep track of the motion closest to the parameter value
- firstMotion = &paramMotion;
- }
- else
- {
- // we've passed the parameter value
- // so store the first motion we find as the second one we want to blend...
- if (firstMotion && !secondMotion )
- {
- secondMotion = &paramMotion;
- }
- //...or, if we've seen no other motion so far, make sure we blend to this only
- else if (!firstMotion)
- {
- firstMotion = &paramMotion;
- secondMotion = &paramMotion;
- }
- }
- }
-
- LLPose *firstPose;
- LLPose *secondPose;
-
- if (firstMotion)
- firstPose = firstMotion->mMotion->getPose();
- else
- firstPose = NULL;
-
- if (secondMotion)
- secondPose = secondMotion->mMotion->getPose();
- else
- secondPose = NULL;
-
- // now modify weight of the subanim (only if we are blending between two motions)
- if (firstMotion && secondMotion)
- {
- if (firstMotion == secondMotion)
- {
- firstPose->setWeight(weightFactor);
- }
- else if (firstMotion->mParam == secondMotion->mParam)
- {
- firstPose->setWeight(0.5f * weightFactor);
- secondPose->setWeight(0.5f * weightFactor);
- }
- else
- {
- F32 first_weight = 1.f -
- ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) /
- (secondMotion->mParam - firstMotion->mParam));
- first_weight = llclamp(first_weight, 0.f, 1.f);
-
- F32 second_weight = 1.f - first_weight;
-
- firstPose->setWeight(first_weight * weightFactor);
- secondPose->setWeight(second_weight * weightFactor);
-
-// LL_INFOS() << "Parameter " << *paramName << ": " << *paramValue << LL_ENDL;
-// LL_INFOS() << "Weights " << firstPose->getWeight() << " " << secondPose->getWeight() << LL_ENDL;
- }
- }
- else if (firstMotion && !secondMotion)
- {
- firstPose->setWeight(weightFactor);
- }
- }
-
- // blend poses
- mPoseBlender.blendAndApply();
-
- LL_INFOS() << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << LL_ENDL;
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onDeactivate()
-//-----------------------------------------------------------------------------
-void LLKeyframeMotionParam::onDeactivate()
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- paramMotion.mMotion->onDeactivate();
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::addKeyframeMotion()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value)
-{
- LLMotion *newMotion = mCharacter->createMotion( id );
-
- if (!newMotion)
- {
- return false;
- }
-
- newMotion->setName(name);
-
- // now add motion to this list
- mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value));
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::setDefaultKeyframeMotion()
-//-----------------------------------------------------------------------------
-void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name)
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- if (paramMotion.mMotion->getName() == name)
- {
- mDefaultKeyframeMotion = paramMotion.mMotion;
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// loadMotions()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::loadMotions()
-{
- //-------------------------------------------------------------------------
- // Load named file by concatenating the character prefix with the motion name.
- // Load data into a buffer to be parsed.
- //-------------------------------------------------------------------------
- //std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix())
- // + "_" + getName() + ".llp";
- //RN: deprecated unused reference to "motion" directory
- std::string path;
-
-
- //-------------------------------------------------------------------------
- // open the file
- //-------------------------------------------------------------------------
- S32 fileSize = 0;
- LLAPRFile infile ;
- infile.open(path, LL_APR_R, NULL, &fileSize);
- apr_file_t* fp = infile.getFileHandle() ;
- if (!fp || fileSize == 0)
- {
- LL_INFOS() << "ERROR: can't open: " << path << LL_ENDL;
- return false;
- }
-
- // allocate a text buffer
- std::vector<char> text(fileSize+1);
-
- //-------------------------------------------------------------------------
- // load data from file into buffer
- //-------------------------------------------------------------------------
- bool error = false;
- char *p = &text[0];
- while ( 1 )
- {
- if (apr_file_eof(fp) == APR_EOF)
- {
- break;
- }
- if (apr_file_gets(p, 1024, fp) != APR_SUCCESS)
- {
- error = true;
- break;
- }
- while ( *(++p) )
- ;
- }
-
- //-------------------------------------------------------------------------
- // close the file
- //-------------------------------------------------------------------------
- infile.close();
-
- //-------------------------------------------------------------------------
- // check for error
- //-------------------------------------------------------------------------
- llassert( p <= (&text[0] + fileSize) );
-
- if ( error )
- {
- LL_INFOS() << "ERROR: error while reading from " << path << LL_ENDL;
- return false;
- }
-
- LL_INFOS() << "Loading parametric keyframe data for: " << getName() << LL_ENDL;
-
- //-------------------------------------------------------------------------
- // parse the text and build keyframe data structures
- //-------------------------------------------------------------------------
- p = &text[0];
- S32 num;
- char strA[80]; /* Flawfinder: ignore */
- char strB[80]; /* Flawfinder: ignore */
- F32 floatA = 0.0f;
-
-
- //-------------------------------------------------------------------------
- // get priority
- //-------------------------------------------------------------------------
- bool isFirstMotion = true;
- num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
-
- while(1)
- {
- if (num == 0 || num == EOF) break;
- if ((num != 3))
- {
- LL_INFOS() << "WARNING: can't read parametric motion" << LL_ENDL;
- return false;
- }
-
- addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA);
- if (isFirstMotion)
- {
- isFirstMotion = false;
- setDefaultKeyframeMotion(strA);
- }
-
- p = strstr(p, "\n");
- if (!p)
- {
- break;
- }
-
- p++;
- num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
- }
-
- return true;
-}
-
-// End
diff --git a/indra/llcharacter/llkeyframemotionparam.h b/indra/llcharacter/llkeyframemotionparam.h
deleted file mode 100644
index 8c57766e9b..0000000000
--- a/indra/llcharacter/llkeyframemotionparam.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * @file llkeyframemotionparam.h
- * @brief Implementation of LLKeframeMotionParam class.
- *
- * $LicenseInfo:firstyear=2002&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_LLKEYFRAMEMOTIONPARAM_H
-#define LL_LLKEYFRAMEMOTIONPARAM_H
-
-//-----------------------------------------------------------------------------
-// Header files
-//-----------------------------------------------------------------------------
-
-#include <string>
-
-#include "llmotion.h"
-#include "lljointstate.h"
-#include "v3math.h"
-#include "llquaternion.h"
-#include "llkeyframemotion.h"
-
-//-----------------------------------------------------------------------------
-// class LLKeyframeMotionParam
-//-----------------------------------------------------------------------------
-class LLKeyframeMotionParam :
- public LLMotion
-{
-public:
- // Constructor
- LLKeyframeMotionParam(const LLUUID &id);
-
- // Destructor
- virtual ~LLKeyframeMotionParam();
-
-public:
- //-------------------------------------------------------------------------
- // functions to support MotionController and MotionRegistry
- //-------------------------------------------------------------------------
-
- // static constructor
- // all subclasses must implement such a function and register it
- static LLMotion *create(const LLUUID &id) { return new LLKeyframeMotionParam(id); }
-
-public:
- //-------------------------------------------------------------------------
- // animation callbacks to be implemented by subclasses
- //-------------------------------------------------------------------------
-
- // motions must specify whether or not they loop
- virtual bool getLoop() {
- return true;
- }
-
- // motions must report their total duration
- virtual F32 getDuration() {
- return mDuration;
- }
-
- // motions must report their "ease in" duration
- virtual F32 getEaseInDuration() {
- return mEaseInDuration;
- }
-
- // motions must report their "ease out" duration.
- virtual F32 getEaseOutDuration() {
- return mEaseOutDuration;
- }
-
- // motions must report their priority
- virtual LLJoint::JointPriority getPriority() {
- return mPriority;
- }
-
- virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; }
-
- // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
- virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_KEYFRAME; }
-
- // run-time (post constructor) initialization,
- // called after parameters have been set
- // must return true to indicate success and be available for activation
- virtual LLMotionInitStatus onInitialize(LLCharacter *character);
-
- // called when a motion is activated
- // must return true to indicate success, or else
- // it will be deactivated
- virtual bool onActivate();
-
- // called per time step
- // must return true while it is active, and
- // must return false when the motion is completed.
- virtual bool onUpdate(F32 time, U8* joint_mask);
-
- // called when a motion is deactivated
- virtual void onDeactivate();
-
- virtual LLPose* getPose() { return mPoseBlender.getBlendedPose();}
-
-protected:
- //-------------------------------------------------------------------------
- // new functions defined by this subclass
- //-------------------------------------------------------------------------
- struct ParameterizedMotion
- {
- ParameterizedMotion(LLMotion* motion, F32 param) : mMotion(motion), mParam(param) {}
- LLMotion* mMotion;
- F32 mParam;
- };
-
- // add a motion and associated parameter triplet
- bool addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value);
-
- // set default motion for LOD and retrieving blend constants
- void setDefaultKeyframeMotion(char *);
-
- bool loadMotions();
-
-protected:
- //-------------------------------------------------------------------------
- // Member Data
- //-------------------------------------------------------------------------
-
- struct compare_motions
- {
- bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const
- {
- if (a.mParam != b.mParam)
- return (a.mParam < b.mParam);
- else
- return a.mMotion < b.mMotion;
- }
- };
-
- typedef std::set < ParameterizedMotion, compare_motions > motion_list_t;
- typedef std::map <std::string, motion_list_t > motion_map_t;
- motion_map_t mParameterizedMotions;
- LLMotion* mDefaultKeyframeMotion;
- LLCharacter* mCharacter;
- LLPoseBlender mPoseBlender;
-
- F32 mEaseInDuration;
- F32 mEaseOutDuration;
- F32 mDuration;
- LLJoint::JointPriority mPriority;
-
- LLUUID mTransactionID;
-};
-
-#endif // LL_LLKEYFRAMEMOTIONPARAM_H
diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h
index 0c262bf24a..c2cb174821 100644
--- a/indra/llcharacter/llmotioncontroller.h
+++ b/indra/llcharacter/llmotioncontroller.h
@@ -37,7 +37,6 @@
#include "llmotion.h"
#include "llpose.h"
#include "llframetimer.h"
-#include "llstatemachine.h"
#include "llstring.h"
//-----------------------------------------------------------------------------
diff --git a/indra/llcharacter/llstatemachine.cpp b/indra/llcharacter/llstatemachine.cpp
deleted file mode 100644
index 38e9ef444c..0000000000
--- a/indra/llcharacter/llstatemachine.cpp
+++ /dev/null
@@ -1,384 +0,0 @@
-/**
- * @file llstatemachine.cpp
- * @brief LLStateMachine implementation file.
- *
- * $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$
- */
-
-#include "linden_common.h"
-
-#include "llstatemachine.h"
-#include "llapr.h"
-
-#define FSM_PRINT_STATE_TRANSITIONS (0)
-
-U32 LLUniqueID::sNextID = 0;
-
-bool operator==(const LLUniqueID &a, const LLUniqueID &b)
-{
- return (a.mId == b.mId);
-}
-
-bool operator!=(const LLUniqueID &a, const LLUniqueID &b)
-{
- return (a.mId != b.mId);
-}
-
-//-----------------------------------------------------------------------------
-// LLStateDiagram
-//-----------------------------------------------------------------------------
-LLStateDiagram::LLStateDiagram()
-{
- mDefaultState = NULL;
- mUseDefaultState = false;
-}
-
-LLStateDiagram::~LLStateDiagram()
-{
-
-}
-
-// add a state to the state graph
-bool LLStateDiagram::addState(LLFSMState *state)
-{
- mStates[state] = Transitions();
- return true;
-}
-
-// add a directed transition between 2 states
-bool LLStateDiagram::addTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition)
-{
- StateMap::iterator state_it;
- state_it = mStates.find(&start_state);
- Transitions* state_transitions = NULL;
- if (state_it == mStates.end() )
- {
- addState(&start_state);
- state_transitions = &mStates[&start_state];
- }
- else
- {
- state_transitions = &state_it->second;
- }
- state_it = mStates.find(&end_state);
- if (state_it == mStates.end() )
- {
- addState(&end_state);
- }
-
- Transitions::iterator transition_it = state_transitions->find(&transition);
- if (transition_it != state_transitions->end())
- {
- LL_ERRS() << "LLStateTable::addDirectedTransition() : transition already exists" << LL_ENDL;
- return false; // transition already exists
- }
-
- (*state_transitions)[&transition] = &end_state;
- return true;
-}
-
-// add an undirected transition between 2 states
-bool LLStateDiagram::addUndirectedTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition)
-{
- bool result;
- result = addTransition(start_state, end_state, transition);
- if (result)
- {
- result = addTransition(end_state, start_state, transition);
- }
- return result;
-}
-
-// add a transition that exists for every state
-void LLStateDiagram::addDefaultTransition(LLFSMState& end_state, LLFSMTransition& transition)
-{
- mDefaultTransitions[&transition] = &end_state;
-}
-
-// process a possible transition, and get the resulting state
-LLFSMState* LLStateDiagram::processTransition(LLFSMState& start_state, LLFSMTransition& transition)
-{
- // look up transition
- //LLFSMState** dest_state = (mStates.getValue(&start_state))->getValue(&transition);
- LLFSMState* dest_state = NULL;
- StateMap::iterator state_it = mStates.find(&start_state);
- if (state_it == mStates.end())
- {
- return NULL;
- }
- Transitions::iterator transition_it = state_it->second.find(&transition);
-
- // try default transitions if state-specific transition not found
- if (transition_it == state_it->second.end())
- {
- dest_state = mDefaultTransitions[&transition];
- }
- else
- {
- dest_state = transition_it->second;
- }
-
- // if we have a destination state...
- if (NULL != dest_state)
- {
- // ...return it...
- return dest_state;
- }
- // ... otherwise ...
- else
- {
- // ...look for default state...
- if (mUseDefaultState)
- {
- // ...return it if we have it...
- return mDefaultState;
- }
- else
- {
- // ...or else we're still in the same state.
- return &start_state;
- }
- }
-}
-
-void LLStateDiagram::setDefaultState(LLFSMState& default_state)
-{
- mUseDefaultState = true;
- mDefaultState = &default_state;
-}
-
-S32 LLStateDiagram::numDeadendStates()
-{
- S32 numDeadends = 0;
- for (StateMap::value_type& state_pair : mStates)
- {
- if (state_pair.second.size() == 0)
- {
- numDeadends++;
- }
- }
- return numDeadends;
-}
-
-bool LLStateDiagram::stateIsValid(LLFSMState& state)
-{
- if (mStates.find(&state) != mStates.end())
- {
- return true;
- }
- return false;
-}
-
-LLFSMState* LLStateDiagram::getState(U32 state_id)
-{
- for (StateMap::value_type& state_pair : mStates)
- {
- if (state_pair.first->getID() == state_id)
- {
- return state_pair.first;
- }
- }
- return NULL;
-}
-
-bool LLStateDiagram::saveDotFile(const std::string& filename)
-{
- LLAPRFile outfile ;
- outfile.open(filename, LL_APR_W);
- apr_file_t* dot_file = outfile.getFileHandle() ;
-
- if (!dot_file)
- {
- LL_WARNS() << "LLStateDiagram::saveDotFile() : Couldn't open " << filename << " to save state diagram." << LL_ENDL;
- return false;
- }
- apr_file_printf(dot_file, "digraph StateMachine {\n\tsize=\"100,100\";\n\tfontsize=40;\n\tlabel=\"Finite State Machine\";\n\torientation=landscape\n\tratio=.77\n");
-
- for (StateMap::value_type& state_pair : mStates)
- {
- apr_file_printf(dot_file, "\t\"%s\" [fontsize=28,shape=box]\n", state_pair.first->getName().c_str());
- }
- apr_file_printf(dot_file, "\t\"All States\" [fontsize=30,style=bold,shape=box]\n");
-
- for (Transitions::value_type& transition_pair : mDefaultTransitions)
- {
- apr_file_printf(dot_file, "\t\"All States\" -> \"%s\" [label = \"%s\",fontsize=24];\n", transition_pair.second->getName().c_str(),
- transition_pair.second->getName().c_str());
- }
-
- if (mDefaultState)
- {
- apr_file_printf(dot_file, "\t\"All States\" -> \"%s\";\n", mDefaultState->getName().c_str());
- }
-
-
- for (StateMap::value_type& state_pair : mStates)
- {
- LLFSMState *state = state_pair.first;
-
- for (Transitions::value_type& transition_pair : state_pair.second)
- {
- std::string state_name = state->getName();
- std::string target_name = transition_pair.second->getName();
- std::string transition_name = transition_pair.first->getName();
- apr_file_printf(dot_file, "\t\"%s\" -> \"%s\" [label = \"%s\",fontsize=24];\n", state->getName().c_str(),
- target_name.c_str(),
- transition_name.c_str());
- }
- }
-
- apr_file_printf(dot_file, "}\n");
-
- return true;
-}
-
-std::ostream& operator<<(std::ostream &s, LLStateDiagram &FSM)
-{
- if (FSM.mDefaultState)
- {
- s << "Default State: " << FSM.mDefaultState->getName() << "\n";
- }
-
- for (LLStateDiagram::Transitions::value_type& transition_pair : FSM.mDefaultTransitions)
- {
- s << "Any State -- " << transition_pair.first->getName()
- << " --> " << transition_pair.second->getName() << "\n";
- }
-
- for (LLStateDiagram::StateMap::value_type& state_pair : FSM.mStates)
- {
- for (LLStateDiagram::Transitions::value_type& transition_pair : state_pair.second)
- {
- s << state_pair.first->getName() << " -- " << transition_pair.first->getName()
- << " --> " << transition_pair.second->getName() << "\n";
- }
- s << "\n";
- }
-
- return s;
-}
-
-//-----------------------------------------------------------------------------
-// LLStateMachine
-//-----------------------------------------------------------------------------
-
-LLStateMachine::LLStateMachine()
-{
- // we haven't received a starting state yet
- mCurrentState = NULL;
- mLastState = NULL;
- mLastTransition = NULL;
- mStateDiagram = NULL;
-}
-
-LLStateMachine::~LLStateMachine()
-{
-
-}
-
-// returns current state
-LLFSMState* LLStateMachine::getCurrentState() const
-{
- return mCurrentState;
-}
-
-// executes current state
-void LLStateMachine::runCurrentState(void *data)
-{
- mCurrentState->execute(data);
-}
-
-// set current state
-bool LLStateMachine::setCurrentState(LLFSMState *initial_state, void* user_data, bool skip_entry)
-{
- llassert(mStateDiagram);
-
- if (mStateDiagram->stateIsValid(*initial_state))
- {
- mLastState = mCurrentState = initial_state;
- if (!skip_entry)
- {
- initial_state->onEntry(user_data);
- }
- return true;
- }
-
- return false;
-}
-
-bool LLStateMachine::setCurrentState(U32 state_id, void* user_data, bool skip_entry)
-{
- llassert(mStateDiagram);
-
- LLFSMState* state = mStateDiagram->getState(state_id);
-
- if (state)
- {
- mLastState = mCurrentState = state;
- if (!skip_entry)
- {
- state->onEntry(user_data);
- }
- return true;
- }
-
- return false;
-}
-
-void LLStateMachine::processTransition(LLFSMTransition& transition, void* user_data)
-{
- llassert(mStateDiagram);
-
- if (NULL == mCurrentState)
- {
- LL_WARNS() << "mCurrentState == NULL; aborting processTransition()" << LL_ENDL;
- return;
- }
-
- LLFSMState* new_state = mStateDiagram->processTransition(*mCurrentState, transition);
-
- if (NULL == new_state)
- {
- LL_WARNS() << "new_state == NULL; aborting processTransition()" << LL_ENDL;
- return;
- }
-
- mLastTransition = &transition;
- mLastState = mCurrentState;
-
- if (*mCurrentState != *new_state)
- {
- mCurrentState->onExit(user_data);
- mCurrentState = new_state;
- mCurrentState->onEntry(user_data);
-#if FSM_PRINT_STATE_TRANSITIONS
- LL_INFOS() << "Entering state " << mCurrentState->getName() <<
- " on transition " << transition.getName() << " from state " <<
- mLastState->getName() << LL_ENDL;
-#endif
- }
-}
-
-void LLStateMachine::setStateDiagram(LLStateDiagram* diagram)
-{
- mStateDiagram = diagram;
-}
diff --git a/indra/llcharacter/llstatemachine.h b/indra/llcharacter/llstatemachine.h
deleted file mode 100644
index 9a33798d96..0000000000
--- a/indra/llcharacter/llstatemachine.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * @file llstatemachine.h
- * @brief LLStateMachine class header file.
- *
- * $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_LLSTATEMACHINE_H
-#define LL_LLSTATEMACHINE_H
-
-#include <string>
-
-#include "llerror.h"
-#include <map>
-
-class LLUniqueID
-{
- friend bool operator==(const LLUniqueID &a, const LLUniqueID &b);
- friend bool operator!=(const LLUniqueID &a, const LLUniqueID &b);
-protected:
- static U32 sNextID;
- U32 mId;
-public:
- LLUniqueID(){mId = sNextID++;}
- virtual ~LLUniqueID(){}
- U32 getID() {return mId;}
-};
-
-class LLFSMTransition : public LLUniqueID
-{
-public:
- LLFSMTransition() : LLUniqueID(){};
- virtual std::string getName()const { return "unnamed"; }
-};
-
-class LLFSMState : public LLUniqueID
-{
-public:
- LLFSMState() : LLUniqueID(){};
- virtual void onEntry(void *){};
- virtual void onExit(void *){};
- virtual void execute(void *){};
- virtual std::string getName() const { return "unnamed"; }
-};
-
-class LLStateDiagram
-{
-typedef std::map<LLFSMTransition*, LLFSMState*> Transitions;
-
-friend std::ostream& operator<<(std::ostream &s, LLStateDiagram &FSM);
-friend class LLStateMachine;
-
-protected:
- typedef std::map<LLFSMState*, Transitions> StateMap;
- StateMap mStates;
- Transitions mDefaultTransitions;
- LLFSMState* mDefaultState;
- bool mUseDefaultState;
-
-public:
- LLStateDiagram();
- virtual ~LLStateDiagram();
-
-protected:
- // add a state to the state graph, executed implicitly when adding transitions
- bool addState(LLFSMState *state);
-
- // add a directed transition between 2 states
- bool addTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition);
-
- // add an undirected transition between 2 states
- bool addUndirectedTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition);
-
- // add a transition that is taken if none other exist
- void addDefaultTransition(LLFSMState& end_state, LLFSMTransition& transition);
-
- // process a possible transition, and get the resulting state
- LLFSMState* processTransition(LLFSMState& start_state, LLFSMTransition& transition);
-
- // add a transition that exists for every state
- void setDefaultState(LLFSMState& default_state);
-
- // return total number of states with no outgoing transitions
- S32 numDeadendStates();
-
- // does this state exist in the state diagram?
- bool stateIsValid(LLFSMState& state);
-
- // get a state pointer by ID
- LLFSMState* getState(U32 state_id);
-
-public:
- // save the graph in a DOT file for rendering and visualization
- bool saveDotFile(const std::string& filename);
-};
-
-class LLStateMachine
-{
-protected:
- LLFSMState* mCurrentState;
- LLFSMState* mLastState;
- LLFSMTransition* mLastTransition;
- LLStateDiagram* mStateDiagram;
-
-public:
- LLStateMachine();
- virtual ~LLStateMachine();
-
- // set state diagram
- void setStateDiagram(LLStateDiagram* diagram);
-
- // process this transition
- void processTransition(LLFSMTransition &transition, void* user_data);
-
- // returns current state
- LLFSMState* getCurrentState() const;
-
- // execute current state
- void runCurrentState(void *data);
-
- // set state by state pointer
- bool setCurrentState(LLFSMState *initial_state, void* user_data, bool skip_entry = true);
-
- // set state by unique ID
- bool setCurrentState(U32 state_id, void* user_data, bool skip_entry = true);
-};
-
-#endif //_LL_LLSTATEMACHINE_H
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 2bafef5d1e..0aaa7433ce 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -66,6 +66,7 @@ set(llcommon_SOURCE_FILES
llmetricperformancetester.cpp
llmortician.cpp
llmutex.cpp
+ llpointer.cpp
llptrto.cpp
llpredicate.cpp
llprocess.cpp
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index a0394da281..404e0c71ce 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -163,6 +163,28 @@ constexpr U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only
constexpr U8 SIM_ACCESS_DOWN = 254;
constexpr U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
+// map item types
+constexpr U32 MAP_ITEM_TELEHUB = 0x01;
+constexpr U32 MAP_ITEM_PG_EVENT = 0x02;
+constexpr U32 MAP_ITEM_MATURE_EVENT = 0x03;
+// constexpr U32 MAP_ITEM_POPULAR = 0x04; // No longer supported, 2009-03-02 KLW
+// constexpr U32 MAP_ITEM_AGENT_COUNT = 0x05;
+constexpr U32 MAP_ITEM_AGENT_LOCATIONS = 0x06;
+constexpr U32 MAP_ITEM_LAND_FOR_SALE = 0x07;
+constexpr U32 MAP_ITEM_CLASSIFIED = 0x08;
+constexpr U32 MAP_ITEM_ADULT_EVENT = 0x09;
+constexpr U32 MAP_ITEM_LAND_FOR_SALE_ADULT = 0x0a;
+
+// Region map layer numbers
+constexpr S32 MAP_SIM_OBJECTS = 0;
+constexpr S32 MAP_SIM_TERRAIN = 1;
+constexpr S32 MAP_SIM_LAND_FOR_SALE = 2; // Transparent alpha overlay of land for sale
+constexpr S32 MAP_SIM_IMAGE_TYPES = 3; // Number of map layers
+constexpr S32 MAP_SIM_INFO_MASK = 0x00FFFFFF; // Agent access may be stuffed into upper byte
+constexpr S32 MAP_SIM_LAYER_MASK = 0x0000FFFF; // Layer info is in lower 16 bits
+constexpr S32 MAP_SIM_RETURN_NULL_SIMS = 0x00010000;
+constexpr S32 MAP_SIM_PRELUDE = 0x00020000;
+
// attachment constants
constexpr U8 ATTACHMENT_ADD = 0x80;
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index c532620daa..f92bb98ba6 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -93,6 +93,7 @@ bool LLApp::sDisableCrashlogger = false;
LLScalarCond<LLApp::EAppStatus> LLApp::sStatus{LLApp::APP_STATUS_STOPPED};
LLAppErrorHandler LLApp::sErrorHandler = NULL;
+bool gDisconnected = false;
LLApp::LLApp()
{
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index 57f5a112d9..ce09c566a9 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -50,6 +50,8 @@ void clear_signals();
#endif
+extern bool gDisconnected;
+
class LL_COMMON_API LLApp
{
public:
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 5205699b92..5545bb71af 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -41,6 +41,9 @@
#include "llstring.h"
#include "llfasttimer.h"
+#include <boost/iostreams/device/array.hpp>
+#include <boost/iostreams/stream.hpp>
+
static const F64 LL_APR_USEC_PER_SEC = 1000000.0;
// should be APR_USEC_PER_SEC, but that relies on INT64_C which
// isn't defined in glib under our build set up for some reason
@@ -64,7 +67,7 @@ std::string LLDate::asString() const
{
std::ostringstream stream;
toStream(stream);
- return stream.str();
+ return std::move(stream).str();
}
//@ brief Converts time in seconds since EPOCH
@@ -184,7 +187,7 @@ bool LLDate::split(S32 *year, S32 *month, S32 *day, S32 *hour, S32 *min, S32 *se
bool LLDate::fromString(const std::string& iso8601_date)
{
- std::istringstream stream(iso8601_date);
+ boost::iostreams::stream<boost::iostreams::array_source> stream(iso8601_date.data(), iso8601_date.size());
return fromStream(stream);
}
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index b14464382b..6f5e57c3de 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -480,7 +480,7 @@ namespace
}
- typedef std::map<std::string, LLError::ELevel> LevelMap;
+ typedef std::unordered_map<std::string, LLError::ELevel> LevelMap;
typedef std::vector<LLError::RecorderPtr> Recorders;
typedef std::vector<LLError::CallSite*> CallSiteVector;
@@ -501,7 +501,7 @@ namespace
LevelMap mClassLevelMap;
LevelMap mFileLevelMap;
LevelMap mTagLevelMap;
- std::map<std::string, unsigned int> mUniqueLogMessages;
+ std::unordered_map<std::string, unsigned int> mUniqueLogMessages;
LLError::FatalFunction mCrashFunction;
LLError::TimeFunction mTimeFunction;
@@ -1404,7 +1404,7 @@ namespace LLError
{
std::ostringstream message_stream;
- std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message);
+ auto messageIter = s->mUniqueLogMessages.find(message);
if (messageIter != s->mUniqueLogMessages.end())
{
messageIter->second++;
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index d254fa5407..3c58d1df22 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -70,7 +70,6 @@ namespace LLError
Setting a level means log messages at that level or above.
*/
- LL_COMMON_API void setPrintLocation(bool);
LL_COMMON_API void setDefaultLevel(LLError::ELevel);
LL_COMMON_API ELevel getDefaultLevel();
LL_COMMON_API void setAlwaysFlush(bool flush);
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index a539e4fe28..f752e31563 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -187,13 +187,34 @@ static unsigned short get_fileattr(const std::wstring& utf16path, bool dontFollo
CloseHandle(file_handle);
return st_mode;
}
+ // Retrieve last error before calling CloseHandle()
+ DWORD last_error = GetLastError();
+ CloseHandle(file_handle);
+ set_errno_from_oserror(last_error);
+ }
+ else
+ {
+ set_errno_from_oserror(GetLastError());
}
- // Retrieve last error and set errno before calling CloseHandle()
- set_errno_from_oserror(GetLastError());
- if (file_handle != INVALID_HANDLE_VALUE)
+ // If CreateFileW approach failed (e.g., exFAT), try the simpler GetFileAttributesW()
+ // GetFileAttributesW() always follows symlinks, so we skip this fallback when dontFollowSymLink is true.
+ if (!dontFollowSymLink)
{
- CloseHandle(file_handle);
+ DWORD attributes = GetFileAttributesW(utf16path.c_str());
+ if (attributes != INVALID_FILE_ATTRIBUTES)
+ {
+ bool is_directory = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+ unsigned short st_mode = is_directory ? S_IFDIR : S_IFREG;
+ st_mode |= (attributes & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE;
+
+ // propagate user bits to group/other fields:
+ st_mode |= (st_mode & 0700) >> 3;
+ st_mode |= (st_mode & 0700) >> 6;
+
+ return st_mode;
+ }
+ set_errno_from_oserror(GetLastError());
}
return 0;
}
diff --git a/indra/llcommon/llheteromap.cpp b/indra/llcommon/llheteromap.cpp
index 823bea7a3c..03dd7856b6 100644
--- a/indra/llcommon/llheteromap.cpp
+++ b/indra/llcommon/llheteromap.cpp
@@ -27,6 +27,6 @@ LLHeteroMap::~LLHeteroMap()
// pair.second is the std::pair; pair.second.first is the void*;
// pair.second.second points to the deleter function
(pair.second.second)(pair.second.first);
- pair.second.first = NULL;
+ pair.second.first = nullptr;
}
}
diff --git a/indra/llcommon/llheteromap.h b/indra/llcommon/llheteromap.h
index d8e6fefb17..211dfaae83 100644
--- a/indra/llcommon/llheteromap.h
+++ b/indra/llcommon/llheteromap.h
@@ -12,9 +12,10 @@
#if ! defined(LL_LLHETEROMAP_H)
#define LL_LLHETEROMAP_H
+#include <typeindex>
#include <typeinfo>
#include <utility> // std::pair
-#include <map>
+#include <unordered_map>
/**
* LLHeteroMap addresses an odd requirement. Usually when you want to put
@@ -43,7 +44,7 @@ public:
// Look up map entry by typeid(T). We don't simply use mMap[typeid(T)]
// because that requires default-constructing T on every lookup. For
// some kinds of T, that could be expensive.
- TypeMap::iterator found = mMap.find(&typeid(T));
+ TypeMap::iterator found = mMap.find(typeid(T));
if (found == mMap.end())
{
// Didn't find typeid(T). Create an entry. Because we're storing
@@ -52,8 +53,8 @@ public:
void* ptr = new T();
void (*dlfn)(void*) = &deleter<T>;
std::pair<TypeMap::iterator, bool> inserted =
- mMap.insert(TypeMap::value_type(&typeid(T),
- TypeMap::mapped_type(ptr, dlfn)));
+ mMap.emplace(typeid(T),
+ TypeMap::mapped_type(ptr, dlfn));
// Okay, now that we have an entry, claim we found it.
found = inserted.first;
}
@@ -71,23 +72,9 @@ private:
delete static_cast<T*>(p);
}
- // Comparing two std::type_info* values is tricky, because the standard
- // does not guarantee that there will be only one type_info instance for a
- // given type. In other words, &typeid(A) in one part of the program may
- // not always equal &typeid(A) in some other part. Use special comparator.
- struct type_info_ptr_comp
- {
- bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
- {
- return lhs->before(*rhs);
- }
- };
-
- // What we actually store is a map from std::type_info (permitting lookup
+ // What we actually store is a map from std::type_index (permitting lookup
// by object type) to a void* pointer to the object PLUS its deleter.
- typedef std::map<
- const std::type_info*, std::pair<void*, void (*)(void*)>,
- type_info_ptr_comp>
+ typedef std::unordered_map<std::type_index, std::pair<void*, void (*)(void*)>>
TypeMap;
TypeMap mMap;
};
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index b01ea0bfb1..b220afadfc 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -34,7 +34,6 @@
#include <list>
#include <unordered_map>
#include <boost/function.hpp>
-#include <boost/unordered_map.hpp>
#include "llerror.h"
#include "llstl.h"
@@ -267,7 +266,7 @@ namespace LLInitParam
private:
struct Inaccessable{};
public:
- typedef std::map<std::string, T> value_name_map_t;
+ typedef std::unordered_map<std::string, T> value_name_map_t;
typedef Inaccessable name_t;
typedef TypeValues<T> type_value_t;
typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
@@ -294,7 +293,7 @@ namespace LLInitParam
static std::vector<std::string>* getPossibleValues()
{
- return NULL;
+ return nullptr;
}
void assignNamedValue(const Inaccessable& name)
@@ -310,7 +309,7 @@ namespace LLInitParam
return param_value_t::getValue();
}
- static value_name_map_t* getValueNames() {return NULL;}
+ static value_name_map_t* getValueNames() { return nullptr; }
};
// helper class to implement name value lookups
@@ -321,7 +320,7 @@ namespace LLInitParam
{
typedef TypeValuesHelper<T, DERIVED_TYPE, IS_SPECIALIZED> self_t;
public:
- typedef typename std::map<std::string, T> value_name_map_t;
+ typedef typename std::unordered_map<std::string, T> value_name_map_t;
typedef std::string name_t;
typedef self_t type_value_t;
typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
@@ -497,9 +496,9 @@ namespace LLInitParam
typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&);
typedef std::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
- typedef std::map<const std::type_info*, parser_read_func_t> parser_read_func_map_t;
- typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t;
- typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t;
+ typedef std::unordered_map<std::type_index, parser_read_func_t> parser_read_func_map_t;
+ typedef std::unordered_map<std::type_index, parser_write_func_t> parser_write_func_map_t;
+ typedef std::unordered_map<std::type_index, parser_inspect_func_t> parser_inspect_func_map_t;
public:
@@ -514,7 +513,7 @@ namespace LLInitParam
template <typename T> bool readValue(T& param, typename std::enable_if_t<!std::is_enum_v<T>>* dummy = 0)
{
- parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+ parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(typeid(T));
if (found_it != mParserReadFuncs->end())
{
return found_it->second(*this, (void*)&param);
@@ -525,14 +524,14 @@ namespace LLInitParam
template <typename T> bool readValue(T& param, typename std::enable_if_t<std::is_enum_v<T> >* dummy = 0)
{
- parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+ parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(typeid(T));
if (found_it != mParserReadFuncs->end())
{
return found_it->second(*this, (void*)&param);
}
else
{
- found_it = mParserReadFuncs->find(&typeid(S32));
+ found_it = mParserReadFuncs->find(typeid(S32));
if (found_it != mParserReadFuncs->end())
{
S32 int_value;
@@ -546,7 +545,7 @@ namespace LLInitParam
template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
{
- parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
+ parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(typeid(T));
if (found_it != mParserWriteFuncs->end())
{
return found_it->second(*this, (const void*)&param, name_stack);
@@ -557,7 +556,7 @@ namespace LLInitParam
// dispatch inspection to registered inspection functions, for each parameter in a param block
template <typename T> bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
{
- parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T));
+ parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(typeid(T));
if (found_it != mParserInspectFuncs->end())
{
found_it->second(name_stack, min_count, max_count, possible_values);
@@ -574,16 +573,16 @@ namespace LLInitParam
protected:
template <typename T>
- void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL)
+ void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = nullptr)
{
- mParserReadFuncs->insert(std::make_pair(&typeid(T), read_func));
- mParserWriteFuncs->insert(std::make_pair(&typeid(T), write_func));
+ mParserReadFuncs->emplace(typeid(T), read_func);
+ mParserWriteFuncs->emplace(typeid(T), write_func);
}
template <typename T>
void registerInspectFunc(parser_inspect_func_t inspect_func)
{
- mParserInspectFuncs->insert(std::make_pair(&typeid(T), inspect_func));
+ mParserInspectFuncs->emplace(typeid(T), inspect_func);
}
bool mParseSilently;
@@ -614,7 +613,7 @@ namespace LLInitParam
{
struct UserData
{
- virtual ~UserData() {}
+ virtual ~UserData() = default;
};
typedef bool(*merge_func_t)(Param&, const Param&, bool);
@@ -665,7 +664,7 @@ namespace LLInitParam
void aggregateBlockData(BlockDescriptor& src_block_data);
void addParam(ParamDescriptorPtr param, const char* name);
- typedef boost::unordered_map<const std::string, ParamDescriptorPtr> param_map_t;
+ typedef std::unordered_map<std::string, ParamDescriptorPtr, ll::string_hash, std::equal_to<>> param_map_t;
typedef std::vector<ParamDescriptorPtr> param_list_t;
typedef std::list<ParamDescriptorPtr> all_params_list_t;
typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
@@ -679,38 +678,26 @@ namespace LLInitParam
class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
};
- //TODO: implement in terms of owned_ptr
- template<typename T>
+ // TODO: implement in terms of owned_ptr
+ template<typename T>
class LazyValue
- {
- public:
- LazyValue()
- : mPtr(NULL)
- {}
+ {
+ public:
+ LazyValue() = default;
- ~LazyValue()
- {
- delete mPtr;
- }
+ ~LazyValue() { delete mPtr; }
- LazyValue(const T& value)
- {
- mPtr = new T(value);
- }
+ LazyValue(const T& value) { mPtr = new T(value); }
- LazyValue(const LazyValue& other)
- : mPtr(NULL)
- {
- *this = other;
- }
+ LazyValue(const LazyValue& other) : mPtr(nullptr) { *this = other; }
- LazyValue& operator = (const LazyValue& other)
- {
+ LazyValue& operator=(const LazyValue& other)
+ {
if (!other.mPtr)
{
delete mPtr;
- mPtr = NULL;
- }
+ mPtr = nullptr;
+ }
else
{
if (!mPtr)
@@ -721,23 +708,21 @@ namespace LLInitParam
{
*mPtr = *(other.mPtr);
}
- }
- return *this;
}
+ return *this;
+ }
bool operator==(const LazyValue& other) const
{
- if (empty() || other.empty()) return false;
+ if (empty() || other.empty())
+ return false;
return *mPtr == *other.mPtr;
}
- bool empty() const
- {
- return mPtr == NULL;
- }
+ bool empty() const { return mPtr == nullptr; }
- void set(const T& other)
- {
+ void set(const T& other)
+ {
if (!mPtr)
{
mPtr = new T(other);
@@ -748,36 +733,26 @@ namespace LLInitParam
}
}
- const T& get() const
- {
- return *ensureInstance();
- }
+ const T& get() const { return *ensureInstance(); }
- T& get()
- {
- return *ensureInstance();
- }
+ T& get() { return *ensureInstance(); }
- operator const T&() const
- {
- return get();
- }
+ operator const T&() const { return get(); }
- private:
- // lazily allocate an instance of T
- T* ensureInstance() const
+ private:
+ // lazily allocate an instance of T
+ T* ensureInstance() const
+ {
+ if (mPtr == nullptr)
{
- if (mPtr == NULL)
- {
- mPtr = new T();
- }
- return mPtr;
+ mPtr = new T();
}
+ return mPtr;
+ }
- private:
-
- mutable T* mPtr;
- };
+ private:
+ mutable T* mPtr = nullptr;
+ };
// root class of all parameter blocks
@@ -864,7 +839,7 @@ namespace LLInitParam
mParamProvided(false)
{}
- virtual ~BaseBlock() {}
+ virtual ~BaseBlock() = default;
bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
param_handle_t getHandleFromParam(const Param* param) const;
diff --git a/indra/newview/llfloatersounddevices.h b/indra/llcommon/llpointer.cpp
index 9b21b62747..1bb7055b3a 100644..100755
--- a/indra/newview/llfloatersounddevices.h
+++ b/indra/llcommon/llpointer.cpp
@@ -1,11 +1,12 @@
/**
- * @file llfloatersounddevices.h
- * @author Leyla Farazha
- * @brief Sound Preferences used for minimal skin
+ * @file llpointer.cpp
+ * @author Nat Goodspeed
+ * @date 2024-09-26
+ * @brief Implementation for llpointer.
*
-* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2024, 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
@@ -25,25 +26,18 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLFLOATERSOUNDDEVICES_H
-#define LL_LLFLOATERSOUNDDEVICES_H
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llpointer.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llerror.h"
-#include "lltransientdockablefloater.h"
-
-class LLFloaterSoundDevices : public LLTransientDockableFloater
+void LLPointerBase::wild_dtor(std::string_view msg)
{
-public:
-
- LOG_CLASS(LLFloaterSoundDevices);
-
- LLFloaterSoundDevices(const LLSD& key);
- ~LLFloaterSoundDevices();
-
- bool postBuild() override;
- void setDocked(bool docked, bool pop_on_undock = true) override;
- void setFocus(bool b) override;
-};
-
-
-#endif //LL_LLFLOATERSOUNDDEVICES_H
-
+// LL_WARNS() << msg << LL_ENDL;
+ llassert_msg(false, msg);
+}
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
index 048547e4cc..d2dcf530e5 100644
--- a/indra/llcommon/llpointer.h
+++ b/indra/llcommon/llpointer.h
@@ -26,8 +26,9 @@
#ifndef LLPOINTER_H
#define LLPOINTER_H
-#include "llerror.h" // *TODO: consider eliminating this
-#include "llmutex.h"
+#include <functional>
+#include <string_view>
+#include <utility> // std::swap()
//----------------------------------------------------------------------------
// RefCount objects should generally only be accessed by way of LLPointer<>'s
@@ -42,8 +43,18 @@
//----------------------------------------------------------------------------
+class LLPointerBase
+{
+protected:
+ // alert the coder that a referenced type's destructor did something very
+ // strange -- this is in a non-template base class so we can hide the
+ // implementation in llpointer.cpp
+ static void wild_dtor(std::string_view msg);
+};
+
// Note: relies on Type having ref() and unref() methods
-template <class Type> class LLPointer
+template <class Type>
+class LLPointer: public LLPointerBase
{
public:
template<typename Subclass>
@@ -60,6 +71,13 @@ public:
ref();
}
+ // Even though the template constructors below accepting
+ // (const LLPointer<Subclass>&) and (LLPointer<Subclass>&&) appear to
+ // subsume these specific (const LLPointer<Type>&) and (LLPointer<Type>&&)
+ // constructors, the compiler recognizes these as The Copy Constructor and
+ // The Move Constructor, respectively. In other words, even in the
+ // presence of the LLPointer<Subclass> constructors, we still must specify
+ // the LLPointer<Type> constructors.
LLPointer(const LLPointer<Type>& ptr) :
mPointer(ptr.mPointer)
{
@@ -98,39 +116,52 @@ public:
const Type& operator*() const { return *mPointer; }
Type& operator*() { return *mPointer; }
- operator BOOL() const { return (mPointer != nullptr); }
operator bool() const { return (mPointer != nullptr); }
bool operator!() const { return (mPointer == nullptr); }
bool isNull() const { return (mPointer == nullptr); }
bool notNull() const { return (mPointer != nullptr); }
operator Type*() const { return mPointer; }
- bool operator !=(Type* ptr) const { return (mPointer != ptr); }
- bool operator ==(Type* ptr) const { return (mPointer == ptr); }
- bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
- bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
- bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
+ template <typename Type1>
+ bool operator !=(Type1* ptr) const { return (mPointer != ptr); }
+ template <typename Type1>
+ bool operator ==(Type1* ptr) const { return (mPointer == ptr); }
+ template <typename Type1>
+ bool operator !=(const LLPointer<Type1>& ptr) const { return (mPointer != ptr.mPointer); }
+ template <typename Type1>
+ bool operator ==(const LLPointer<Type1>& ptr) const { return (mPointer == ptr.mPointer); }
+ bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
+ bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
LLPointer<Type>& operator =(Type* ptr)
{
- assign(ptr);
+ // copy-and-swap idiom, see http://gotw.ca/gotw/059.htm
+ LLPointer temp(ptr);
+ using std::swap; // per Swappable convention
+ swap(*this, temp);
return *this;
}
+ // Even though the template assignment operators below accepting
+ // (const LLPointer<Subclass>&) and (LLPointer<Subclass>&&) appear to
+ // subsume these specific (const LLPointer<Type>&) and (LLPointer<Type>&&)
+ // assignment operators, the compiler recognizes these as Copy Assignment
+ // and Move Assignment, respectively. In other words, even in the presence
+ // of the LLPointer<Subclass> assignment operators, we still must specify
+ // the LLPointer<Type> operators.
LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
{
- assign(ptr);
+ LLPointer temp(ptr);
+ using std::swap; // per Swappable convention
+ swap(*this, temp);
return *this;
}
LLPointer<Type>& operator =(LLPointer<Type>&& ptr)
{
- if (mPointer != ptr.mPointer)
- {
- unref();
- mPointer = ptr.mPointer;
- ptr.mPointer = nullptr;
- }
+ LLPointer temp(std::move(ptr));
+ using std::swap; // per Swappable convention
+ swap(*this, temp);
return *this;
}
@@ -138,28 +169,32 @@ public:
template<typename Subclass>
LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
{
- assign(ptr.get());
+ LLPointer temp(ptr);
+ using std::swap; // per Swappable convention
+ swap(*this, temp);
return *this;
}
template<typename Subclass>
LLPointer<Type>& operator =(LLPointer<Subclass>&& ptr)
{
- if (mPointer != ptr.mPointer)
- {
- unref();
- mPointer = ptr.mPointer;
- ptr.mPointer = nullptr;
- }
+ LLPointer temp(std::move(ptr));
+ using std::swap; // per Swappable convention
+ swap(*this, temp);
return *this;
}
// Just exchange the pointers, which will not change the reference counts.
static void swap(LLPointer<Type>& a, LLPointer<Type>& b)
{
- Type* temp = a.mPointer;
- a.mPointer = b.mPointer;
- b.mPointer = temp;
+ using std::swap; // per Swappable convention
+ swap(a.mPointer, b.mPointer);
+ }
+
+ // Put swap() overload in the global namespace, per Swappable convention
+ friend void swap(LLPointer<Type>& a, LLPointer<Type>& b)
+ {
+ LLPointer<Type>::swap(a, b);
}
protected:
@@ -184,191 +219,19 @@ protected:
temp->unref();
if (mPointer != nullptr)
{
- LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
+ wild_dtor("Unreference did assignment to non-NULL because of destructor");
unref();
}
}
}
#endif // LL_LIBRARY_INCLUDE
- void assign(const LLPointer<Type>& ptr)
- {
- if (mPointer != ptr.mPointer)
- {
- unref();
- mPointer = ptr.mPointer;
- ref();
- }
- }
-
protected:
Type* mPointer;
};
-template <class Type> class LLConstPointer
-{
- template<typename Subclass>
- friend class LLConstPointer;
-public:
- LLConstPointer() :
- mPointer(nullptr)
- {
- }
-
- LLConstPointer(const Type* ptr) :
- mPointer(ptr)
- {
- ref();
- }
-
- LLConstPointer(const LLConstPointer<Type>& ptr) :
- mPointer(ptr.mPointer)
- {
- ref();
- }
-
- LLConstPointer(LLConstPointer<Type>&& ptr) noexcept
- {
- mPointer = ptr.mPointer;
- ptr.mPointer = nullptr;
- }
-
- // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
- template<typename Subclass>
- LLConstPointer(const LLConstPointer<Subclass>& ptr) :
- mPointer(ptr.get())
- {
- ref();
- }
-
- template<typename Subclass>
- LLConstPointer(LLConstPointer<Subclass>&& ptr) noexcept :
- mPointer(ptr.get())
- {
- ptr.mPointer = nullptr;
- }
-
- ~LLConstPointer()
- {
- unref();
- }
-
- const Type* get() const { return mPointer; }
- const Type* operator->() const { return mPointer; }
- const Type& operator*() const { return *mPointer; }
-
- operator BOOL() const { return (mPointer != nullptr); }
- operator bool() const { return (mPointer != nullptr); }
- bool operator!() const { return (mPointer == nullptr); }
- bool isNull() const { return (mPointer == nullptr); }
- bool notNull() const { return (mPointer != nullptr); }
-
- operator const Type*() const { return mPointer; }
- bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
- bool operator ==(const Type* ptr) const { return (mPointer == ptr); }
- bool operator ==(const LLConstPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
- bool operator < (const LLConstPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
- bool operator > (const LLConstPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
-
- LLConstPointer<Type>& operator =(const Type* ptr)
- {
- if( mPointer != ptr )
- {
- unref();
- mPointer = ptr;
- ref();
- }
-
- return *this;
- }
-
- LLConstPointer<Type>& operator =(const LLConstPointer<Type>& ptr)
- {
- if( mPointer != ptr.mPointer )
- {
- unref();
- mPointer = ptr.mPointer;
- ref();
- }
- return *this;
- }
-
- LLConstPointer<Type>& operator =(LLConstPointer<Type>&& ptr)
- {
- if (mPointer != ptr.mPointer)
- {
- unref();
- mPointer = ptr.mPointer;
- ptr.mPointer = nullptr;
- }
- return *this;
- }
-
- // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
- template<typename Subclass>
- LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)
- {
- if( mPointer != ptr.get() )
- {
- unref();
- mPointer = ptr.get();
- ref();
- }
- return *this;
- }
-
- template<typename Subclass>
- LLConstPointer<Type>& operator =(LLConstPointer<Subclass>&& ptr)
- {
- if (mPointer != ptr.mPointer)
- {
- unref();
- mPointer = ptr.mPointer;
- ptr.mPointer = nullptr;
- }
- return *this;
- }
-
- // Just exchange the pointers, which will not change the reference counts.
- static void swap(LLConstPointer<Type>& a, LLConstPointer<Type>& b)
- {
- const Type* temp = a.mPointer;
- a.mPointer = b.mPointer;
- b.mPointer = temp;
- }
-
-protected:
-#ifdef LL_LIBRARY_INCLUDE
- void ref();
- void unref();
-#else // LL_LIBRARY_INCLUDE
- void ref()
- {
- if (mPointer)
- {
- mPointer->ref();
- }
- }
-
- void unref()
- {
- if (mPointer)
- {
- const Type *temp = mPointer;
- mPointer = nullptr;
- temp->unref();
- if (mPointer != nullptr)
- {
- LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
- unref();
- }
- }
- }
-#endif // LL_LIBRARY_INCLUDE
-
-protected:
- const Type* mPointer;
-};
+template <typename Type>
+using LLConstPointer = LLPointer<const Type>;
template<typename Type>
class LLCopyOnWritePointer : public LLPointer<Type>
@@ -418,38 +281,26 @@ private:
bool mStayUnique;
};
-template<typename Type>
-bool operator!=(Type* lhs, const LLPointer<Type>& rhs)
+template<typename Type0, typename Type1>
+bool operator!=(Type0* lhs, const LLPointer<Type1>& rhs)
{
return (lhs != rhs.get());
}
-template<typename Type>
-bool operator==(Type* lhs, const LLPointer<Type>& rhs)
+template<typename Type0, typename Type1>
+bool operator==(Type0* lhs, const LLPointer<Type1>& rhs)
{
return (lhs == rhs.get());
}
-// boost hash adapter
-template <class Type>
-struct boost::hash<LLPointer<Type>>
-{
- typedef LLPointer<Type> argument_type;
- typedef std::size_t result_type;
- result_type operator()(argument_type const& s) const
- {
- return (std::size_t) s.get();
- }
-};
-
-// Adapt boost hash to std hash
+// Specialize for std::hash
namespace std
{
template<class Type> struct hash<LLPointer<Type>>
{
std::size_t operator()(LLPointer<Type> const& s) const noexcept
{
- return boost::hash<LLPointer<Type>>()(s);
+ return std::hash<Type*>()(s.get());
}
};
}
diff --git a/indra/llcommon/llpounceable.h b/indra/llcommon/llpounceable.h
index e86098f20b..20561b0c65 100644
--- a/indra/llcommon/llpounceable.h
+++ b/indra/llcommon/llpounceable.h
@@ -38,9 +38,9 @@
#include "llsingleton.h"
#include <boost/call_traits.hpp>
#include <boost/utility/value_init.hpp>
-#include <boost/unordered_map.hpp>
#include <boost/signals2/signal.hpp>
+#include <unordered_map>
#include <type_traits>
// Forward declare the user template, since we want to be able to point to it
@@ -86,7 +86,7 @@ class LLPounceableQueueSingleton:
// instance will call on the SAME LLPounceableQueueSingleton instance --
// given how class statics work. We must keep a separate queue for each
// LLPounceable instance. Use a hash map for that.
- typedef boost::unordered_map<owner_ptr, signal_t> map_t;
+ typedef std::unordered_map<owner_ptr, signal_t> map_t;
public:
// Disambiguate queues belonging to different LLPounceables.
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp
index 3120fa0100..cbba2ceb87 100644
--- a/indra/llcommon/llprocess.cpp
+++ b/indra/llcommon/llprocess.cpp
@@ -176,13 +176,13 @@ public:
// In general, our streambuf might contain a number of different
// physical buffers; iterate over those.
bool keepwriting = true;
- for (auto bufi = buffer_sequence_begin(bufs), bufend = buffer_sequence_end(bufs);
+ for (auto bufi(boost::asio::buffer_sequence_begin(bufs)), bufend(boost::asio::buffer_sequence_end(bufs));
bufi != bufend && keepwriting; ++bufi)
{
// http://www.boost.org/doc/libs/1_49_0_beta1/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.accessing_buffer_contents
// Although apr_file_write() accepts const void*, we
// manipulate const char* so we can increment the pointer.
- const char* remainptr = static_cast<const char*>((*bufi).data());
+ const char* remainptr = static_cast<const char*>(bufi->data());
std::size_t remainlen = boost::asio::buffer_size(*bufi);
while (remainlen)
{
@@ -377,14 +377,14 @@ public:
// In general, the mutable_buffer_sequence returned by prepare() might
// contain a number of different physical buffers; iterate over those.
std::size_t tocommit(0);
- for (auto bufi = buffer_sequence_begin(bufs), bufend = buffer_sequence_end(bufs);
+ for (auto bufi(boost::asio::buffer_sequence_begin(bufs)), bufend(boost::asio::buffer_sequence_end(bufs));
bufi != bufend; ++bufi)
{
// http://www.boost.org/doc/libs/1_49_0_beta1/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.accessing_buffer_contents
std::size_t toread(boost::asio::buffer_size(*bufi));
apr_size_t gotten(toread);
apr_status_t err = apr_file_read(mPipe,
- static_cast<void*>((*bufi).data()),
+ bufi->data(),
&gotten);
// EAGAIN is exactly what we want from a nonblocking pipe.
// Rather than waiting for data, it should return immediately.
@@ -657,10 +657,7 @@ LLProcess::LLProcess(const LLSDOrParams& params):
// case), e.g. by calling operator(), returns a reference to *the same
// instance* of the wrapped type that's stored in our Block subclass.
// That's important! We know 'params' persists throughout this method
- // call; but without that guarantee, we'd have to assume that converting
- // one of its members to std::string might return a different (temp)
- // instance. Capturing the c_str() from a temporary std::string is Bad Bad
- // Bad. But armed with this knowledge, when you see params.cwd().c_str(),
+ // call; but without that guarantee, when you see params.cwd().c_str(),
// grit your teeth and smile and carry on.
if (params.cwd.isProvided())
diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h
index 35335e1213..92f8ae3245 100644
--- a/indra/llcommon/llregistry.h
+++ b/indra/llcommon/llregistry.h
@@ -32,21 +32,11 @@
#include "llsingleton.h"
#include "llstl.h"
-template <typename T>
-struct LLRegistryDefaultComparator
-{
- bool operator()(const T& lhs, const T& rhs) const
- {
- using std::less;
- return less<T>()(lhs, rhs);
- }
-};
-
-template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
+template <typename KEY, typename VALUE>
class LLRegistry
{
public:
- typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
+ typedef LLRegistry<KEY, VALUE> registry_t;
typedef const KEY& ref_const_key_t;
typedef const VALUE& ref_const_value_t;
typedef const VALUE* ptr_const_value_t;
@@ -54,9 +44,9 @@ public:
class Registrar
{
- friend class LLRegistry<KEY, VALUE, COMPARATOR>;
+ friend class LLRegistry<KEY, VALUE>;
public:
- typedef std::map<KEY, VALUE, COMPARATOR> registry_map_t;
+ typedef std::map<KEY, VALUE> registry_map_t;
bool add(ref_const_key_t key, ref_const_value_t value)
{
@@ -234,9 +224,9 @@ private:
Registrar mDefaultRegistrar;
};
-template <typename KEY, typename VALUE, typename DERIVED_TYPE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
+template <typename KEY, typename VALUE, typename DERIVED_TYPE>
class LLRegistrySingleton
- : public LLRegistry<KEY, VALUE, COMPARATOR>,
+ : public LLRegistry<KEY, VALUE>,
public LLSingleton<DERIVED_TYPE>
{
// This LLRegistrySingleton doesn't use LLSINGLETON(LLRegistrySingleton)
@@ -244,7 +234,7 @@ class LLRegistrySingleton
// LLRegistrySingleton. So each concrete subclass needs
// LLSINGLETON(whatever) -- not this intermediate base class.
public:
- typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
+ typedef LLRegistry<KEY, VALUE> registry_t;
typedef const KEY& ref_const_key_t;
typedef const VALUE& ref_const_value_t;
typedef VALUE* ptr_value_t;
@@ -309,7 +299,7 @@ public:
};
// convenience functions
- typedef typename LLRegistry<KEY, VALUE, COMPARATOR>::Registrar& ref_registrar_t;
+ typedef typename LLRegistry<KEY, VALUE>::Registrar& ref_registrar_t;
static ref_registrar_t currentRegistrar()
{
return singleton_t::instance().registry_t::currentRegistrar();
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 77fe545c3f..ce39bc7af3 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -39,6 +39,9 @@
#include <limits>
+#include <boost/iostreams/device/array.hpp>
+#include <boost/iostreams/stream.hpp>
+
// Defend against a caller forcibly passing a negative number into an unsigned
// size_t index param
inline
@@ -103,6 +106,9 @@ protected:
U32 mUseCount;
public:
+ static void destruct(Impl*& var);
+ ///< safely decrement or destroy var
+
static void reset(Impl*& var, Impl* impl);
///< safely set var to refer to the new impl (possibly shared)
@@ -166,7 +172,7 @@ public:
virtual const LLSD& ref(size_t) const { return undef(); }
virtual LLSD::map_const_iterator beginMap() const { return endMap(); }
- virtual LLSD::map_const_iterator endMap() const { static const std::map<String, LLSD> empty; return empty.end(); }
+ virtual LLSD::map_const_iterator endMap() const { static const LLSD::llsd_map_t empty; return empty.end(); }
virtual LLSD::array_const_iterator beginArray() const { return endArray(); }
virtual LLSD::array_const_iterator endArray() const { static const std::vector<LLSD> empty; return empty.end(); }
@@ -345,18 +351,7 @@ namespace
LLSD::Real ImplString::asReal() const
{
- F64 v = 0.0;
- std::istringstream i_stream(mValue);
- i_stream >> v;
-
- // we would probably like to ignore all trailing whitespace as
- // well, but for now, simply eat the next character, and make
- // sure we reached the end of the string.
- // *NOTE: gcc 2.95 does not generate an eof() event on the
- // stream operation above, so we manually get here to force it
- // across platforms.
- int c = i_stream.get();
- return ((EOF ==c) ? v : 0.0);
+ return llsd::string_to_real(mValue);
}
@@ -431,7 +426,7 @@ namespace
class ImplMap final : public LLSD::Impl
{
private:
- typedef std::map<LLSD::String, LLSD, std::less<>> DataMap;
+ using DataMap = LLSD::llsd_map_t;
DataMap mData;
@@ -457,7 +452,7 @@ namespace
<< it.second.asXMLRPCValue() << "</member>";
}
os << "</struct>";
- return os.str();
+ return std::move(os).str();
}
virtual bool has(std::string_view) const;
@@ -467,8 +462,13 @@ namespace
using LLSD::Impl::ref; // Unhiding ref(size_t)
virtual LLSD get(std::string_view) const;
virtual LLSD getKeys() const;
+ void insert(std::string&& k, const LLSD& v);
+ void insert(std::string&& k, LLSD&& v);
void insert(std::string_view k, const LLSD& v);
+ void insert(std::string_view k, LLSD&& v);
virtual void erase(const LLSD::String&);
+ LLSD& ref(std::string&&);
+ virtual const LLSD& ref(std::string&&) const;
LLSD& ref(std::string_view);
virtual const LLSD& ref(std::string_view) const;
@@ -525,18 +525,58 @@ namespace
return keys;
}
+ void ImplMap::insert(std::string&& k, const LLSD& v)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
+ mData.emplace(std::move(k), v);
+ }
+
+ void ImplMap::insert(std::string&& k, LLSD&& v)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
+ mData.emplace(std::move(k), std::move(v));
+ }
+
void ImplMap::insert(std::string_view k, const LLSD& v)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
mData.emplace(k, v);
}
+ void ImplMap::insert(std::string_view k, LLSD&& v)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
+ mData.emplace(k, std::move(v));
+ }
+
void ImplMap::erase(const LLSD::String& k)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
mData.erase(k);
}
+ LLSD& ImplMap::ref(std::string&& k)
+ {
+ DataMap::iterator i = mData.lower_bound(k);
+ if (i == mData.end() || mData.key_comp()(k, i->first))
+ {
+ return mData.emplace_hint(i, std::make_pair(std::move(k), LLSD()))->second;
+ }
+
+ return i->second;
+ }
+
+ const LLSD& ImplMap::ref(std::string&& k) const
+ {
+ DataMap::const_iterator i = mData.lower_bound(k);
+ if (i == mData.end() || mData.key_comp()(k, i->first))
+ {
+ return undef();
+ }
+
+ return i->second;
+ }
+
LLSD& ImplMap::ref(std::string_view k)
{
DataMap::iterator i = mData.lower_bound(k);
@@ -598,7 +638,7 @@ namespace
ImplArray(const DataVector& data) : mData(data) { }
public:
- ImplArray() { }
+ ImplArray() = default;
virtual ImplArray& makeArray(Impl*&);
@@ -615,7 +655,7 @@ namespace
os << it.asXMLRPCValue();
}
os << "</data></array>";
- return os.str();
+ return std::move(os).str();
}
using LLSD::Impl::get; // Unhiding get(LLSD::String)
@@ -625,10 +665,13 @@ namespace
virtual LLSD get(size_t) const;
void set(size_t, const LLSD&);
void insert(size_t, const LLSD&);
+ void insert(size_t, LLSD&&);
LLSD& append(const LLSD&);
+ LLSD& append(LLSD&&);
virtual void erase(size_t);
LLSD& ref(size_t);
virtual const LLSD& ref(size_t) const;
+ void reserve(size_t size) { mData.reserve(size); }
LLSD::array_iterator beginArray() { return mData.begin(); }
LLSD::array_iterator endArray() { return mData.end(); }
@@ -690,12 +733,31 @@ namespace
mData.insert(mData.begin() + index, v);
}
+ void ImplArray::insert(size_t i, LLSD&& v)
+ {
+ NEGATIVE_EXIT(i);
+ DataVector::size_type index = i;
+
+ if (index >= mData.size()) // tbd - sanity check limit for index ?
+ {
+ mData.resize(index + 1);
+ }
+
+ mData.insert(mData.begin() + index, std::move(v));
+ }
+
LLSD& ImplArray::append(const LLSD& v)
{
mData.push_back(v);
return mData.back();
}
+ LLSD& ImplArray::append(LLSD&& v)
+ {
+ mData.push_back(std::move(v));
+ return mData.back();
+ }
+
void ImplArray::erase(size_t i)
{
NEGATIVE_EXIT(i);
@@ -763,6 +825,14 @@ LLSD::Impl::~Impl()
--sOutstandingCount;
}
+void LLSD::Impl::destruct(Impl*& var)
+{
+ if (var && var->mUseCount != STATIC_USAGE_COUNT && --var->mUseCount == 0)
+ {
+ delete var;
+ }
+}
+
void LLSD::Impl::reset(Impl*& var, Impl* impl)
{
if (impl && impl->mUseCount != STATIC_USAGE_COUNT)
@@ -961,7 +1031,7 @@ namespace
LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; }
-LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); }
+LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::destruct(impl); }
LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); }
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
@@ -1037,13 +1107,31 @@ LLSD LLSD::emptyMap()
bool LLSD::has(const std::string_view k) const { return safe(impl).has(k); }
LLSD LLSD::get(const std::string_view k) const { return safe(impl).get(k); }
LLSD LLSD::getKeys() const { return safe(impl).getKeys(); }
+void LLSD::insert(std::string&& k, const LLSD& v) { makeMap(impl).insert(std::move(k), v); }
+void LLSD::insert(std::string&& k, LLSD&& v) { makeMap(impl).insert(std::move(k), std::move(v)); }
void LLSD::insert(std::string_view k, const LLSD& v) { makeMap(impl).insert(k, v); }
+void LLSD::insert(std::string_view k, LLSD&& v) { makeMap(impl).insert(k, std::move(v)); }
+LLSD& LLSD::with(std::string&& k, const LLSD& v)
+ {
+ makeMap(impl).insert(std::move(k), v);
+ return *this;
+ }
+LLSD& LLSD::with(std::string&& k, LLSD&& v)
+ {
+ makeMap(impl).insert(std::move(k), std::move(v));
+ return *this;
+ }
LLSD& LLSD::with(std::string_view k, const LLSD& v)
{
makeMap(impl).insert(k, v);
return *this;
}
+LLSD& LLSD::with(std::string_view k, LLSD&& v)
+ {
+ makeMap(impl).insert(k, std::move(v));
+ return *this;
+ }
void LLSD::erase(const String& k) { makeMap(impl).erase(k); }
LLSD& LLSD::operator[](const std::string_view k)
@@ -1051,6 +1139,13 @@ LLSD& LLSD::operator[](const std::string_view k)
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
return makeMap(impl).ref(k);
}
+
+LLSD& LLSD::operator[](std::string&& k)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
+ return makeMap(impl).ref(std::move(k));
+}
+
const LLSD& LLSD::operator[](const std::string_view k) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
@@ -1064,18 +1159,33 @@ LLSD LLSD::emptyArray()
return v;
}
+LLSD LLSD::emptyReservedArray(size_t size)
+{
+ LLSD v;
+ makeArray(v.impl).reserve(size);
+ return v;
+}
+
size_t LLSD::size() const { return safe(impl).size(); }
LLSD LLSD::get(Integer i) const { return safe(impl).get(i); }
void LLSD::set(Integer i, const LLSD& v){ makeArray(impl).set(i, v); }
+void LLSD::set(Integer i, LLSD&& v) { makeArray(impl).set(i, std::move(v)); }
void LLSD::insert(Integer i, const LLSD& v) { makeArray(impl).insert(i, v); }
+void LLSD::insert(Integer i, LLSD&& v) { makeArray(impl).insert(i, std::move(v)); }
LLSD& LLSD::with(Integer i, const LLSD& v)
{
makeArray(impl).insert(i, v);
return *this;
}
+LLSD& LLSD::with(Integer i, LLSD&& v)
+ {
+ makeArray(impl).insert(i, std::move(v));
+ return *this;
+ }
LLSD& LLSD::append(const LLSD& v) { return makeArray(impl).append(v); }
+LLSD& LLSD::append(LLSD&& v) { return makeArray(impl).append(std::move(v)); }
void LLSD::erase(Integer i) { makeArray(impl).erase(i); }
LLSD& LLSD::operator[](size_t i)
@@ -1143,6 +1253,22 @@ LLSD::reverse_array_iterator LLSD::rendArray() { return makeArray(impl)
namespace llsd
{
+LLSD::Real string_to_real(std::string_view in_string)
+{
+ LLSD::Real v = 0.0;
+ boost::iostreams::stream<boost::iostreams::array_source> i_stream(in_string.data(), in_string.size());
+ i_stream >> v;
+
+ // we would probably like to ignore all trailing whitespace as
+ // well, but for now, simply eat the next character, and make
+ // sure we reached the end of the string.
+ // *NOTE: gcc 2.95 does not generate an eof() event on the
+ // stream operation above, so we manually get here to force it
+ // across platforms.
+ int c = i_stream.get();
+ return ((EOF == c) ? v : 0.0);
+}
+
U32 allocationCount() { return LLSD::Impl::sAllocationCount; }
U32 outstandingCount() { return LLSD::Impl::sOutstandingCount; }
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index d2b3548831..afe35a65ba 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -34,6 +34,7 @@
#include "stdtypes.h"
#include "lldate.h"
+#include "llstl.h"
#include "lluri.h"
#include "lluuid.h"
@@ -321,11 +322,34 @@ public:
bool has(const std::string_view) const;
LLSD get(const std::string_view) const;
LLSD getKeys() const; // Return an LLSD array with keys as strings
+ void insert(const char* k, const LLSD& v)
+ {
+ return insert(std::string_view(k), v);
+ }
+ void insert(const char* k , LLSD&& v)
+ {
+ return insert(std::string_view(k), std::move(v));
+ }
+ void insert(std::string&&, const LLSD&);
+ void insert(std::string&&, LLSD&&);
void insert(std::string_view, const LLSD&);
+ void insert(std::string_view, LLSD&&);
void erase(const String&);
+ LLSD& with(const char* k, const LLSD& v)
+ {
+ return with(std::string_view(k), v);
+ }
+ LLSD& with(const char* k, LLSD&& v)
+ {
+ return with(std::string_view(k), std::move(v));
+ }
+ LLSD& with(std::string&&, const LLSD&);
+ LLSD& with(std::string&&, LLSD&&);
LLSD& with(std::string_view, const LLSD&);
+ LLSD& with(std::string_view, LLSD&&);
LLSD& operator[](const std::string_view);
+ LLSD& operator[](std::string&&);
LLSD& operator[](const char* c)
{
return c ? (*this)[std::string_view(c)] : *this;
@@ -339,14 +363,22 @@ public:
/** @name Array Values */
//@{
+ // Allocate an empty array
static LLSD emptyArray();
+ // Allocate an array with internal storage reserved but not initialized like a std::vector
+ static LLSD emptyReservedArray(size_t size);
+
LLSD get(Integer) const;
void set(Integer, const LLSD&);
+ void set(Integer, LLSD&&);
void insert(Integer, const LLSD&);
+ void insert(Integer, LLSD&&);
LLSD& append(const LLSD&);
+ LLSD& append(LLSD&&);
void erase(Integer);
LLSD& with(Integer, const LLSD&);
+ LLSD& with(Integer, LLSD&&);
// accept size_t so we can index relative to size()
const LLSD& operator[](size_t) const;
@@ -366,8 +398,9 @@ public:
//@{
size_t size() const;
- typedef std::map<String, LLSD>::iterator map_iterator;
- typedef std::map<String, LLSD>::const_iterator map_const_iterator;
+ using llsd_map_t = std::map<String, LLSD, std::less<>>;
+ typedef llsd_map_t::iterator map_iterator;
+ typedef llsd_map_t::const_iterator map_const_iterator;
map_iterator beginMap();
map_iterator endMap();
@@ -512,6 +545,8 @@ LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLSD& llsd);
namespace llsd
{
+ // Used by LLSD::ImplString to convert string type to real
+ LLSD::Real string_to_real(std::string_view in_string);
#ifdef LLSD_DEBUG_INFO
/** @name Unit Testing Interface */
diff --git a/indra/llcommon/llsdjson.cpp b/indra/llcommon/llsdjson.cpp
index a4b45ed80d..71f35802c5 100644
--- a/indra/llcommon/llsdjson.cpp
+++ b/indra/llcommon/llsdjson.cpp
@@ -70,7 +70,7 @@ LLSD LlsdFromJson(const boost::json::value& val)
const boost::json::array& array = val.as_array();
size_t size = array.size();
// allocate elements 0 .. (size() - 1) to avoid incremental allocation
- if (! array.empty())
+ if (!array.empty())
{
result[size - 1] = LLSD();
}
@@ -84,7 +84,7 @@ LLSD LlsdFromJson(const boost::json::value& val)
result = LLSD::emptyMap();
for (const auto& element : val.as_object())
{
- result[element.key()] = LlsdFromJson(element.value());
+ result[std::string_view(element.key())] = LlsdFromJson(element.value());
}
break;
}
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 68a7bf0adf..f850238dff 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -775,7 +775,8 @@ S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) c
// There must be a value for every key, thus
// child_count must be greater than 0.
parse_count += count;
- map.insert(name, child);
+ map.insert(std::move(name), std::move(child)); // Move as name will be filled on next iteration
+ name.clear();
}
else
{
@@ -822,7 +823,7 @@ S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_dept
else
{
parse_count += count;
- array.append(child);
+ array.append(std::move(child));
}
c = get(istr);
}
@@ -841,7 +842,7 @@ bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
auto count = deserialize_string(istr, value, mMaxBytesLeft);
if(PARSE_FAILURE == count) return false;
account(count);
- data = value;
+ data = std::move(value);
return true;
}
@@ -872,10 +873,10 @@ bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
if(len)
{
value.resize(len);
- account(fullread(istr, (char *)&value[0], len));
+ account(fullread(istr, (char*)value.data(), len));
}
c = get(istr); // strip off the trailing double-quote
- data = value;
+ data = std::move(value);
}
else if(0 == strncmp("b64", buf, 3))
{
@@ -885,7 +886,7 @@ bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
std::stringstream coded_stream;
get(istr, *(coded_stream.rdbuf()), '\"');
c = get(istr);
- std::string encoded(coded_stream.str());
+ std::string encoded(std::move(coded_stream).str());
S32 len = apr_base64_decode_len(encoded.c_str());
std::vector<U8> value;
if(len)
@@ -894,7 +895,7 @@ bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
len = apr_base64_decode_binary(&value[0], encoded.c_str());
value.resize(len);
}
- data = value;
+ data = std::move(value);
}
else if(0 == strncmp("b16", buf, 3))
{
@@ -925,7 +926,7 @@ bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
// copy the data out of the byte buffer
value.insert(value.end(), byte_buffer, write);
}
- data = value;
+ data = std::move(value);
}
else
{
@@ -1077,7 +1078,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) con
}
else
{
- data = value;
+ data = std::move(value);
account(cnt);
}
if(istr.fail())
@@ -1094,7 +1095,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) con
std::string value;
if(parseString(istr, value))
{
- data = value;
+ data = std::move(value);
}
else
{
@@ -1159,7 +1160,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) con
value.resize(size);
account(fullread(istr, (char*)&value[0], size));
}
- data = value;
+ data = std::move(value);
}
if(istr.fail())
{
@@ -1218,7 +1219,7 @@ S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) con
// There must be a value for every key, thus child_count
// must be greater than 0.
parse_count += child_count;
- map.insert(name, child);
+ map.insert(std::move(name), std::move(child));
}
else
{
@@ -1238,13 +1239,12 @@ S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) con
S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array, S32 max_depth) const
{
- array = LLSD::emptyArray();
U32 value_nbo = 0;
read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/
S32 size = (S32)ntohl(value_nbo);
- // *FIX: This would be a good place to reserve some space in the
- // array...
+ // Preallocate array to avoid incremental allocation
+ array = LLSD::emptyReservedArray(size);
S32 parse_count = 0;
S32 count = 0;
@@ -1260,7 +1260,7 @@ S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array, S32 max_depth)
if(child_count)
{
parse_count += child_count;
- array.append(child);
+ array.append(std::move(child));
}
++count;
c = istr.peek();
@@ -1279,18 +1279,15 @@ bool LLSDBinaryParser::parseString(
std::istream& istr,
std::string& value) const
{
- // *FIX: This is memory inefficient.
U32 value_nbo = 0;
read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/
S32 size = (S32)ntohl(value_nbo);
if(mCheckLimits && (size > mMaxBytesLeft)) return false;
if(size < 0) return false;
- std::vector<char> buf;
if(size)
{
- buf.resize(size);
- account(fullread(istr, &buf[0], size));
- value.assign(buf.begin(), buf.end());
+ value.resize(size);
+ account(fullread(istr, value.data(), size));
}
return true;
}
@@ -1785,7 +1782,7 @@ llssize deserialize_string_delim(
}
}
- value = write_buffer.str();
+ value = std::move(write_buffer).str();
return count;
}
@@ -1806,15 +1803,12 @@ llssize deserialize_string_raw(
{
// We probably have a valid raw string. determine
// the size, and read it.
- // *FIX: This is memory inefficient.
- auto len = strtol(buf + 1, NULL, 0);
+ auto len = strtol(buf + 1, nullptr, 0);
if((max_bytes>0)&&(len>max_bytes)) return LLSDParser::PARSE_FAILURE;
- std::vector<char> buf;
if(len)
{
- buf.resize(len);
- count += fullread(istr, (char *)&buf[0], len);
- value.assign(buf.begin(), buf.end());
+ value.resize(len);
+ count += fullread(istr, value.data(), len);
}
c = istr.get();
++count;
@@ -2170,7 +2164,7 @@ std::string zip_llsd(LLSD& data)
return std::string();
}
- std::string source = llsd_strm.str();
+ std::string source = std::move(llsd_strm).str();
U8 out[CHUNK];
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index ce416baa04..afe4fd63a6 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -31,6 +31,8 @@
#include <deque>
#include "apr_base64.h"
+#include <boost/iostreams/device/array.hpp>
+#include <boost/iostreams/stream.hpp>
#include <boost/regex.hpp>
extern "C"
@@ -645,7 +647,7 @@ void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Ch
if (mCurrentKey.empty()) { return startSkipping(); }
LLSD& map = *mStack.back();
- LLSD& newElement = map[mCurrentKey];
+ LLSD& newElement = map[std::move(mCurrentKey)];
mStack.push_back(&newElement);
mCurrentKey.clear();
@@ -709,7 +711,8 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)
return;
case ELEMENT_KEY:
- mCurrentKey = mCurrentContent;
+ mCurrentKey = std::move(mCurrentContent); // This is safe to move as we are in the end element handler
+ mCurrentContent.clear(); // Ensure mCurrentContent is empty for subsequent use
return;
default:
@@ -742,14 +745,22 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)
}
else
{
- value = LLSD(mCurrentContent).asInteger();
+ // This must treat "1.23" not as an error, but as a number, which is
+ // then truncated down to an integer. Hence, this code doesn't call
+ // std::istringstream::operator>>(int&), which would not consume the
+ // ".23" portion.
+
+ // Utilizes implementation used internally by LLSD::ImplString::asInteger
+ value = (int)llsd::string_to_real(mCurrentContent);
}
}
break;
case ELEMENT_REAL:
{
- value = LLSD(mCurrentContent).asReal();
+ // Utilizes implementation used internally by LLSD::ImplString::asReal
+ value = llsd::string_to_real(mCurrentContent);
+
// removed since this breaks when locale has decimal separator that isn't '.'
// investigated changing local to something compatible each time but deemed higher
// risk that just using LLSD.asReal() each time.
@@ -766,19 +777,19 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)
break;
case ELEMENT_STRING:
- value = mCurrentContent;
+ value = std::move(mCurrentContent); // This is safe to move as we are in the end element handler and this is cleared below
break;
case ELEMENT_UUID:
- value = LLSD(mCurrentContent).asUUID();
+ value = LLUUID(mCurrentContent);
break;
case ELEMENT_DATE:
- value = LLSD(mCurrentContent).asDate();
+ value = LLDate(mCurrentContent);
break;
case ELEMENT_URI:
- value = LLSD(mCurrentContent).asURI();
+ value = LLURI(mCurrentContent);
break;
case ELEMENT_BINARY:
@@ -787,15 +798,14 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)
// created by python and other non-linden systems - DEV-39358
// Fortunately we have very little binary passing now,
// so performance impact shold be negligible. + poppy 2009-09-04
- boost::regex r;
- r.assign("\\s");
+ static const boost::regex r("\\s");
std::string stripped = boost::regex_replace(mCurrentContent, r, "");
S32 len = apr_base64_decode_len(stripped.c_str());
std::vector<U8> data;
data.resize(len);
len = apr_base64_decode_binary(&data[0], stripped.c_str());
data.resize(len);
- value = data;
+ value = std::move(data);
break;
}
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 3fba8602ee..e6989211ae 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -25,10 +25,10 @@
#ifndef LLSINGLETON_H
#define LLSINGLETON_H
-#include <boost/unordered_set.hpp>
#include <initializer_list>
#include <list>
#include <typeinfo>
+#include <unordered_set>
#include <vector>
#include "mutex.h"
#include "lockstatic.h"
@@ -61,7 +61,7 @@ private:
static vec_t dep_sort();
// we directly depend on these other LLSingletons
- typedef boost::unordered_set<LLSingletonBase*> set_t;
+ typedef std::unordered_set<LLSingletonBase*> set_t;
set_t mDepends;
protected:
diff --git a/indra/llcommon/llstaticstringtable.h b/indra/llcommon/llstaticstringtable.h
index 66ba3487c4..edff955ee7 100644
--- a/indra/llcommon/llstaticstringtable.h
+++ b/indra/llcommon/llstaticstringtable.h
@@ -29,9 +29,10 @@
#define LL_STATIC_STRING_TABLE_H
#include "lldefs.h"
-#include <boost/unordered_map.hpp>
#include "llstl.h"
+#include <unordered_map>
+
class LLStaticHashedString
{
public:
@@ -74,7 +75,7 @@ struct LLStaticStringHasher
template< typename MappedObject >
class LL_COMMON_API LLStaticStringTable
- : public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher >
+ : public std::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher >
{
};
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index 7d41c42ba7..7a1c7caf82 100644
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -34,6 +34,7 @@
#include <vector>
#include <list>
#include <set>
+#include <typeindex>
#include <typeinfo>
#ifdef LL_LINUX
@@ -229,12 +230,10 @@ void delete_and_clear_array(T*& ptr)
template <typename T>
inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_type const& key)
{
- // Typedef here avoids warnings because of new c++ naming rules.
- typedef typename T::const_iterator map_iter;
- map_iter iter = inmap.find(key);
+ auto iter = inmap.find(key);
if(iter == inmap.end())
{
- return NULL;
+ return nullptr;
}
else
{
@@ -243,8 +242,8 @@ inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_ty
};
// helper function which returns true if key is in inmap.
-template <typename K, typename T>
-inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
+template <typename T>
+inline bool is_in_map(const T& inmap, typename T::key_type const& key)
{
if(inmap.find(key) == inmap.end())
{
@@ -260,12 +259,10 @@ inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
// To replace LLSkipMap getIfThere, use:
// get_if_there(map, key, 0)
// WARNING: Make sure default_value (generally 0) is not a valid map entry!
-template <typename K, typename T>
-inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
+template <typename T>
+inline typename T::mapped_type get_if_there(const T& inmap, typename T::key_type const& key, typename T::mapped_type default_value)
{
- // Typedef here avoids warnings because of new c++ naming rules.
- typedef typename std::map<K,T>::const_iterator map_iter;
- map_iter iter = inmap.find(key);
+ auto iter = inmap.find(key);
if(iter == inmap.end())
{
return default_value;
@@ -709,5 +706,24 @@ struct ll_template_cast_impl<DEST, SOURCE> \
} \
}
+// Transparent string hashing helper for use with std::unordered_*
+// std::unordered_map<std::string, val, ll::string_hash, std::equal_to<>>
+namespace ll
+{
+ struct string_hash
+ {
+ using is_transparent = void;
+ [[nodiscard]] size_t operator()(char const* rhs) const { return std::hash<std::string_view>{}(rhs); }
+ [[nodiscard]] size_t operator()(std::string_view rhs) const { return std::hash<std::string_view>{}(rhs); }
+ [[nodiscard]] size_t operator()(const std::string& rhs) const { return std::hash<std::string>{}(rhs); }
+ };
+} // namespace ll
+
+// Specialize ostream for std::type_index to allow log output
+inline std::ostream& operator<<(std::ostream& s, std::type_index type)
+{
+ s << type.name();
+ return s;
+}
#endif // LL_LLSTL_H
diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h
index ca1cf03c4d..f91aadccc0 100644
--- a/indra/llcommon/lluuid.h
+++ b/indra/llcommon/lluuid.h
@@ -26,6 +26,7 @@
#ifndef LL_LLUUID_H
#define LL_LLUUID_H
+#include <functional>
#include <iostream>
#include <set>
#include <vector>
@@ -176,15 +177,27 @@ namespace std
{
inline size_t operator()(const LLUUID& id) const noexcept
{
- return (size_t)id.getDigest64();
+ size_t h = 0;
+ // Golden ratio hash with avalanche mixing
+ // Process 8 bytes at a time by manually constructing 64-bit values
+ // Shift by 31: mixes upper half into lower half for better bit distribution
+ // Shift by 47: ensures highest bits influence final hash output
+ for (int i = 0; i < UUID_BYTES; i += 8) {
+ size_t chunk = (size_t)id.mData[i] | ((size_t)id.mData[i+1] << 8) |
+ ((size_t)id.mData[i+2] << 16) | ((size_t)id.mData[i+3] << 24) |
+ ((size_t)id.mData[i+4] << 32) | ((size_t)id.mData[i+5] << 40) |
+ ((size_t)id.mData[i+6] << 48) | ((size_t)id.mData[i+7] << 56);
+ h ^= (chunk * 0x9e3779b97f4a7c15ULL) ^ (h >> 31) ^ (h >> 47);
+ }
+ return h;
}
};
}
-// For use with boost containers.
+// For use with boost::container_hash
inline size_t hash_value(const LLUUID& id) noexcept
{
- return (size_t)id.getDigest64();
+ return std::hash<LLUUID>{}(id);
}
#endif // LL_LLUUID_H
diff --git a/indra/llcommon/llwatchdog.cpp b/indra/llcommon/llwatchdog.cpp
index fa240a9ed7..1bc1283d0b 100644
--- a/indra/llcommon/llwatchdog.cpp
+++ b/indra/llcommon/llwatchdog.cpp
@@ -28,6 +28,7 @@
#include "linden_common.h"
#include "llwatchdog.h"
+#include "llmutex.h"
#include "llthread.h"
constexpr U32 WATCHDOG_SLEEP_TIME_USEC = 1000000U;
diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp
index 0407d6c3e9..67c23358ed 100644
--- a/indra/llcommon/workqueue.cpp
+++ b/indra/llcommon/workqueue.cpp
@@ -281,12 +281,30 @@ bool LL::WorkQueue::done()
bool LL::WorkQueue::post(const Work& callable)
{
- return mQueue.pushIfOpen(callable);
+ try
+ {
+ return mQueue.pushIfOpen(callable);
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("LLCoros") << "Bad memory allocation in WorkQueue::post" << LL_ENDL;
+ return false;
+ }
}
bool LL::WorkQueue::tryPost(const Work& callable)
{
- return mQueue.tryPush(callable);
+ try
+ {
+ return mQueue.tryPush(callable);
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("LLCoros") << "Bad memory allocation in WorkQueue::tryPost" << LL_ENDL;
+ return false;
+ }
}
LL::WorkQueue::Work LL::WorkQueue::pop_()
diff --git a/indra/llfilesystem/lldir.cpp b/indra/llfilesystem/lldir.cpp
index c6d8db8d48..bc3f09c1e5 100644
--- a/indra/llfilesystem/lldir.cpp
+++ b/indra/llfilesystem/lldir.cpp
@@ -44,6 +44,7 @@
#include "stringize.h"
#include "llstring.h"
#include <boost/filesystem.hpp>
+#include "llprocess.h"
#include <boost/bind.hpp>
#include <algorithm>
@@ -1104,6 +1105,61 @@ LLDir::SepOff LLDir::needSep(const std::string& path, const std::string& name) c
return SepOff(false, 0);
}
+void LLDir::openDir(const std::string& filepath)
+{
+ if (filepath.empty())
+ {
+ LL_WARNS() << "Cannot open file browser: filepath is empty" << LL_ENDL;
+ return;
+ }
+
+ // Extract directory path from full filepath
+ std::string dir_path = getDirName(filepath);
+
+ LLProcess::Params params;
+
+#if LL_WINDOWS
+ // Windows: Use explorer.exe with /select flag to highlight the file
+ std::string system_root = LLStringUtil::getenv("SystemRoot");
+ if (system_root.empty())
+ {
+ system_root = LLStringUtil::getenv("WINDIR");
+ }
+ if (system_root.empty())
+ {
+ LL_WARNS() << "Neither SystemRoot nor WINDIR environment variable is set" << LL_ENDL;
+ system_root = "C:\\Windows"; // Last resort fallback
+ }
+ params.executable = system_root + "\\explorer.exe";
+ params.args.add("/select,");
+ params.args.add(filepath);
+#elif LL_DARWIN
+ // macOS: Use 'open' command with -R flag to reveal in Finder
+ params.executable = "/usr/bin/open";
+ params.args.add("-R");
+ params.args.add(filepath);
+#elif LL_LINUX
+ // Linux: Use xdg-open to open the directory
+ // Note: Most file managers don't support file selection, so we open the directory
+ params.executable = "/usr/bin/xdg-open";
+ params.args.add(dir_path);
+#else
+ LL_WARNS() << "Platform not supported for file browser opening" << LL_ENDL;
+ return;
+#endif
+
+ params.autokill = false; // Don't kill the file browser when viewer exits
+
+ if (!LLProcess::create(params))
+ {
+ LL_WARNS() << "Failed to open file browser for: " << filepath << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Opened file browser for: " << filepath << LL_ENDL;
+ }
+}
+
void dir_exists_or_crash(const std::string &dir_name)
{
#if LL_WINDOWS
diff --git a/indra/llfilesystem/lldir.h b/indra/llfilesystem/lldir.h
index b0d2b6aada..3c8e2e2da6 100644
--- a/indra/llfilesystem/lldir.h
+++ b/indra/llfilesystem/lldir.h
@@ -194,6 +194,9 @@ class LLDir
virtual void dumpCurrentDirectories(LLError::ELevel level = LLError::LEVEL_DEBUG);
+ // Open the system file browser to reveal a file or directory
+ void openDir(const std::string& filepath);
+
// Utility routine
std::string buildSLOSCacheDir() const;
diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp
index 82e9e18918..fafe959ac6 100644
--- a/indra/llfilesystem/lldiskcache.cpp
+++ b/indra/llfilesystem/lldiskcache.cpp
@@ -91,6 +91,8 @@ LLDiskCache::LLDiskCache(const std::string& cache_dir,
// asset will have to be re-requested.
void LLDiskCache::purge()
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (mEnableCacheDebugInfo)
{
LL_INFOS() << "Total dir size before purge is " << dirFileSize(sCacheDir) << LL_ENDL;
@@ -112,6 +114,10 @@ void LLDiskCache::purge()
boost::filesystem::directory_iterator iter(cache_path, ec);
while (iter != boost::filesystem::directory_iterator() && !ec.failed())
{
+ if(!LLApp::isRunning())
+ {
+ return;
+ }
if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
{
#if LL_WINDOWS
@@ -158,6 +164,10 @@ void LLDiskCache::purge()
uintmax_t file_size_total = 0;
for (file_info_t& entry : file_info)
{
+ if (!LLApp::isRunning())
+ {
+ return;
+ }
file_size_total += entry.second.first;
bool should_remove = file_size_total > mMaxSizeBytes;
@@ -190,6 +200,10 @@ void LLDiskCache::purge()
// Logging thousands of file results can take hundreds of milliseconds
for (size_t i = 0; i < file_info.size(); ++i)
{
+ if (!LLApp::isRunning())
+ {
+ return;
+ }
const file_info_t& entry = file_info[i];
const bool removed = file_removed[i];
const std::string action = removed ? "DELETE:" : "KEEP:";
diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp
index 541266af4f..728ff396ef 100644
--- a/indra/llfilesystem/llfilesystem.cpp
+++ b/indra/llfilesystem/llfilesystem.cpp
@@ -77,11 +77,10 @@ bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType fil
LL_PROFILE_ZONE_SCOPED;
const std::string filename = LLDiskCache::metaDataToFilepath(file_id, file_type);
- llifstream file(filename, std::ios::binary);
- if (file.is_open())
+ boost::system::error_code ec;
+ if (boost::filesystem::exists(filename, ec) && boost::filesystem::is_regular_file(filename, ec))
{
- file.seekg(0, std::ios::end);
- return file.tellg() > 0;
+ return boost::filesystem::file_size(filename, ec) > 0;
}
return false;
}
@@ -120,15 +119,12 @@ S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType fi
{
const std::string filename = LLDiskCache::metaDataToFilepath(file_id, file_type);
- S32 file_size = 0;
- llifstream file(filename, std::ios::binary);
- if (file.is_open())
+ boost::system::error_code ec;
+ if (boost::filesystem::exists(filename, ec) && boost::filesystem::is_regular_file(filename, ec))
{
- file.seekg(0, std::ios::end);
- file_size = (S32)file.tellg();
+ return static_cast<S32>(boost::filesystem::file_size(filename, ec));
}
-
- return file_size;
+ return 0;
}
bool LLFileSystem::read(U8* buffer, S32 bytes)
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 6b14b68c78..1fb61673bd 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -27,10 +27,11 @@
#ifndef LL_LLIMAGE_H
#define LL_LLIMAGE_H
-#include "lluuid.h"
-#include "llstring.h"
+#include "llmutex.h"
#include "llpointer.h"
+#include "llstring.h"
#include "lltrace.h"
+#include "lluuid.h"
constexpr S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
constexpr S32 MAX_IMAGE_MIP = 12; // 4096x4096
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 3defad8f3b..f126accfb8 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -1017,10 +1017,9 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
if (i->first == INV_THUMBNAIL_LABEL)
{
const LLSD &thumbnail_map = i->second;
- const std::string w = INV_ASSET_ID_LABEL;
- if (thumbnail_map.has(w))
+ if (thumbnail_map.has(INV_ASSET_ID_LABEL))
{
- mThumbnailUUID = thumbnail_map[w];
+ mThumbnailUUID = thumbnail_map[INV_ASSET_ID_LABEL];
}
/* Example:
<key> asset_id </key>
@@ -1033,7 +1032,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
<integer> 1 </key>
*/
continue;
- }
+ }
if (i->first == INV_THUMBNAIL_ID_LABEL)
{
@@ -1044,10 +1043,9 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
if (i->first == INV_FAVORITE_LABEL)
{
const LLSD& favorite_map = i->second;
- const std::string w = INV_TOGGLED_LABEL;
- if (favorite_map.has(w))
+ if (favorite_map.has(INV_TOGGLED_LABEL))
{
- mFavorite = favorite_map[w].asBoolean();
+ mFavorite = favorite_map[INV_TOGGLED_LABEL].asBoolean();
}
continue;
}
@@ -1111,7 +1109,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
LLSD const &label = i->second;
if (label.isString())
{
- mType = LLAssetType::lookup(label.asString().c_str());
+ mType = LLAssetType::lookup(label.asStringRef().c_str());
}
else if (label.isInteger())
{
@@ -1126,7 +1124,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
LLSD const &label = i->second;
if (label.isString())
{
- mInventoryType = LLInventoryType::lookup(label.asString().c_str());
+ mInventoryType = LLInventoryType::lookup(label.asStringRef().c_str());
}
else if (label.isInteger())
{
@@ -1290,7 +1288,7 @@ void LLInventoryCategory::packMessage(LLMessageSystem* msg) const
bool LLInventoryCategory::fromLLSD(const LLSD& sd)
{
- std::string w;
+ std::string_view w;
w = INV_FOLDER_ID_LABEL_WS;
if (sd.has(w))
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 7eba9494a6..e7ac6bdb31 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -615,6 +615,11 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
return false;
}
}
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS() << "Bad memory allocation in J2C KDU" << LL_ENDL;
+ }
catch (const KDUError& msg)
{
base.setLastError(msg.what());
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 0cf5ecd3d0..4660026d40 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -912,7 +912,7 @@ bool LLProfile::generate(const LLProfileParams& params, bool path_open,F32 detai
case LL_PCODE_HOLE_CIRCLE:
case LL_PCODE_HOLE_SAME:
default:
- addHole(params, true, circle_detail, 0, hollow, 1.f);
+ addHole(params, false, circle_detail, 0, hollow, 1.f);
break;
}
}
@@ -4943,9 +4943,17 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
mOctree(NULL),
mOctreeTriangles(NULL)
{
- mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
- mCenter = mExtents+2;
- *this = src;
+ try
+ {
+ mExtents = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a) * 3);
+ mCenter = mExtents + 2;
+ *this = src;
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("LLVolume") << "Bad memory allocation in LLVolumeFace" << LL_ENDL;
+ }
}
LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
@@ -5163,7 +5171,7 @@ void LLVolumeFace::remap()
// Documentation for meshopt_generateVertexRemapMulti claims that remap should use vertice count
// but all examples use indice count. There are out of bounds crashes when using vertice count.
// To be on the safe side use bigger of the two.
- std::vector<unsigned int> remap(llmax(mNumIndices, mNumVertices));
+ std::vector<unsigned int> remap(llmax(mNumIndices, mNumVertices), 0);
S32 remap_vertices_count = static_cast<S32>(LLMeshOptimizer::generateRemapMultiU16(&remap[0],
mIndices,
mNumIndices,
@@ -5681,7 +5689,12 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
catch (std::bad_alloc&)
{
LLError::LLUserWarningMsg::showOutOfMemory();
- LL_ERRS("LLCoros") << "Bad memory allocation in MikktData::genTangSpace" << LL_ENDL;
+ LL_ERRS("LLVolume") << "Bad memory allocation in MikktData::genTangSpace" << LL_ENDL;
+ }
+ catch (...)
+ {
+ LL_WARNS_ONCE("LLVolume") << "Mikktspace::genTangSpace() failed" << LL_ENDL;
+ return false;
}
@@ -5703,7 +5716,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
catch (std::bad_alloc&)
{
LLError::LLUserWarningMsg::showOutOfMemory();
- LL_ERRS("LLCoros") << "Failed to allocate memory for remap: " << (S32)data.p.size() << LL_ENDL;
+ LL_ERRS("LLVOLUME") << "Failed to allocate memory for remap: " << (S32)data.p.size() << LL_ENDL;
}
U32 stream_count = data.w.empty() ? 4 : 5;
@@ -5720,7 +5733,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
catch (std::bad_alloc&)
{
LLError::LLUserWarningMsg::showOutOfMemory();
- LL_ERRS("LLCoros") << "Failed to allocate memory for VertexRemap: " << (S32)data.p.size() << LL_ENDL;
+ LL_ERRS("LLVolume") << "Failed to allocate memory for VertexRemap: " << (S32)data.p.size() << LL_ENDL;
}
}
@@ -5732,7 +5745,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
if (mNumVertices == 0)
{
LLError::LLUserWarningMsg::showOutOfMemory();
- LL_ERRS("LLCoros") << "Failed to allocate memory for resizeVertices(" << vert_count << ")" << LL_ENDL;
+ LL_ERRS("LLVolume") << "Failed to allocate memory for resizeVertices(" << vert_count << ")" << LL_ENDL;
}
if (!data.w.empty())
diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp
index bb0c94d513..d8f649140f 100644
--- a/indra/llmath/llvolumemgr.cpp
+++ b/indra/llmath/llvolumemgr.cpp
@@ -25,6 +25,7 @@
#include "linden_common.h"
+#include "llmutex.h"
#include "llvolumemgr.h"
#include "llvolume.h"
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index 196ecdcf7d..0e11dca876 100644
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -155,6 +155,7 @@ class LLVector3
friend const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b); // Returns a * b;
friend const LLVector3& operator*=(LLVector3 &a, F32 k); // Return a times scaler k
friend const LLVector3& operator/=(LLVector3 &a, F32 k); // Return a divided by scaler k
+ friend const LLVector3& operator/=(LLVector3& a, const LLVector3& b);
friend const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &b); // Returns a * b;
friend LLVector3 operator-(const LLVector3 &a); // Return vector -a
@@ -460,6 +461,14 @@ inline const LLVector3& operator/=(LLVector3& a, F32 k)
return a;
}
+inline const LLVector3& operator/=(LLVector3& a, const LLVector3& b)
+{
+ a.mV[VX] /= b.mV[VX];
+ a.mV[VY] /= b.mV[VY];
+ a.mV[VZ] /= b.mV[VZ];
+ return a;
+}
+
inline LLVector3 operator-(const LLVector3& a)
{
return LLVector3(-a.mV[VX], -a.mV[VY], -a.mV[VZ]);
diff --git a/indra/llmeshoptimizer/llmeshoptimizer.cpp b/indra/llmeshoptimizer/llmeshoptimizer.cpp
index 7339454367..76d51fdad0 100644
--- a/indra/llmeshoptimizer/llmeshoptimizer.cpp
+++ b/indra/llmeshoptimizer/llmeshoptimizer.cpp
@@ -171,7 +171,6 @@ size_t LLMeshOptimizer::generateRemapMultiU32(
// but providing indices helps with removing unused vertices
U64 indeces_cmp = indices ? index_count : vertex_count;
- // meshopt_generateVertexRemapMulti will throw an assert if (indices[i] >= vertex_count)
return meshopt_generateVertexRemapMulti(&remap[0], indices, indeces_cmp, vertex_count, streams, sizeof(streams) / sizeof(streams[0]));
}
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index ebafc53a4d..86b36315dc 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -276,7 +276,7 @@ void LLAvatarNameCache::handleAvNameCacheSuccess(const LLSD &data, const LLSD &h
// Provide some fallback for agents that return errors
void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
{
- std::map<LLUUID,LLAvatarName>::iterator existing = mCache.find(agent_id);
+ cache_t::iterator existing = mCache.find(agent_id);
if (existing == mCache.end())
{
// there is no existing cache entry, so make a temporary name from legacy
@@ -311,7 +311,7 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName&
bool updated_account = true; // assume obsolete value for new arrivals by default
- std::map<LLUUID, LLAvatarName>::iterator it = mCache.find(agent_id);
+ cache_t::iterator it = mCache.find(agent_id);
if (it != mCache.end()
&& (*it).second.getAccountName() == av_name.getAccountName())
{
@@ -418,7 +418,7 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
// Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy
// protocol, we do not get an expiration date for each name and there's no reason to ask the
// data again and again so we set the expiration time to the largest value admissible.
- std::map<LLUUID,LLAvatarName>::iterator av_record = LLAvatarNameCache::getInstance()->mCache.find(agent_id);
+ cache_t::iterator av_record = LLAvatarNameCache::getInstance()->mCache.find(agent_id);
LLAvatarName& av_name = av_record->second;
av_name.setExpires(MAX_UNREFRESHED_TIME);
}
@@ -631,7 +631,7 @@ bool LLAvatarNameCache::getName(const LLUUID& agent_id, LLAvatarName *av_name)
if (mRunning)
{
// ...only do immediate lookups when cache is running
- std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id);
+ cache_t::iterator it = mCache.find(agent_id);
if (it != mCache.end())
{
*av_name = it->second;
@@ -682,7 +682,7 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::getNameCallback(cons
if (mRunning)
{
// ...only do immediate lookups when cache is running
- std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id);
+ cache_t::iterator it = mCache.find(agent_id);
if (it != mCache.end())
{
const LLAvatarName& av_name = it->second;
@@ -753,13 +753,11 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na
LLUUID LLAvatarNameCache::findIdByName(const std::string& name)
{
- std::map<LLUUID, LLAvatarName>::iterator it;
- std::map<LLUUID, LLAvatarName>::iterator end = mCache.end();
- for (it = mCache.begin(); it != end; ++it)
+ for (const auto& [id, avatar_name] : mCache)
{
- if (it->second.getUserName() == name)
+ if (avatar_name.getUserName() == name)
{
- return it->first;
+ return id;
}
}
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 0ddaee2aa1..6743943495 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -30,8 +30,10 @@
#include "llavatarname.h" // for convenience
#include "llsingleton.h"
+#include "lluuid.h"
#include <boost/signals2.hpp>
#include <set>
+#include <unordered_map>
class LLSD;
class LLUUID;
@@ -161,23 +163,23 @@ private:
std::string mNameLookupURL;
// Accumulated agent IDs for next query against service
- typedef std::set<LLUUID> ask_queue_t;
+ using ask_queue_t = std::set<LLUUID>;
ask_queue_t mAskQueue;
// Agent IDs that have been requested, but with no reply.
// Maps agent ID to frame time request was made.
- typedef std::map<LLUUID, F64> pending_queue_t;
+ using pending_queue_t = std::unordered_map<LLUUID, F64>;
pending_queue_t mPendingQueue;
// Callbacks to fire when we received a name.
// May have multiple callbacks for a single ID, which are
// represented as multiple slots bound to the signal.
// Avoid copying signals via pointers.
- typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
+ using signal_map_t = std::unordered_map<LLUUID, callback_signal_t*>;
signal_map_t mSignalMap;
// The cache at last, i.e. avatar names we know about.
- typedef std::map<LLUUID, LLAvatarName> cache_t;
+ using cache_t = std::unordered_map<LLUUID, LLAvatarName>;
cache_t mCache;
// Time when unrefreshed cached names were checked last.
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 56dfaef873..95b7bb8c3d 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -179,12 +179,11 @@ void ReplySender::flush()
}
}
-
-typedef std::set<LLUUID> AskQueue;
-typedef std::list<PendingReply*> ReplyQueue;
-typedef std::map<LLUUID,U32> PendingQueue;
-typedef std::map<LLUUID, LLCacheNameEntry*> Cache;
-typedef std::map<std::string, LLUUID> ReverseCache;
+using AskQueue = std::set<LLUUID>;
+using ReplyQueue = std::list<PendingReply*>;
+using PendingQueue = std::unordered_map<LLUUID, U32>;
+using Cache = std::unordered_map<LLUUID, LLCacheNameEntry*>;
+using ReverseCache = std::unordered_map<std::string, LLUUID>;
class LLCacheName::Impl
{
@@ -214,7 +213,7 @@ public:
Impl(LLMessageSystem* msg);
~Impl();
- bool getName(const LLUUID& id, std::string& first, std::string& last, std::map<std::string, std::string>& default_names);
+ bool getName(const LLUUID& id, std::string& first, std::string& last, cache_map_t& default_names);
boost::signals2::connection addPending(const LLUUID& id, const LLCacheNameCallback& callback);
void addPending(const LLUUID& id, const LLHost& host);
@@ -401,7 +400,7 @@ void LLCacheName::exportFile(std::ostream& ostr)
}
-bool LLCacheName::Impl::getName(const LLUUID& id, std::string& first, std::string& last, std::map<std::string, std::string>& default_names)
+bool LLCacheName::Impl::getName(const LLUUID& id, std::string& first, std::string& last, cache_map_t &default_names)
{
if(id.isNull())
{
diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h
index 609387b6de..a333eac0f5 100644
--- a/indra/llmessage/llcachename.h
+++ b/indra/llmessage/llcachename.h
@@ -136,7 +136,8 @@ public:
void localizeCacheName(std::string key, std::string value);
private:
- std::map<std::string, std::string> mCacheName;
+ using cache_map_t = std::unordered_map<std::string, std::string>;
+ cache_map_t mCacheName;
class Impl;
Impl& impl;
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index b24e5e4fcc..647064f607 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -37,6 +37,7 @@
#include "llsdserialize.h"
#include "boost/json.hpp" // Boost.Json
#include "llfilesystem.h"
+#include "workqueue.h"
#include "message.h" // for getting the port
@@ -295,41 +296,73 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
}
else
{
- try
+ constexpr size_t MAX_BODY_SIZE_THRESHOLD = 65536;
+ bool posted = false;
+ // Some messsages (ex: AISAPI) can return large bodies.
+ // If the body is larger than our threshold, post the
+ // parsing to the general queue to avoid stalling the
+ // main thread.
+ if (response->getBodySize() > MAX_BODY_SIZE_THRESHOLD)
{
- result = this->handleSuccess(response, status);
- }
- catch (std::bad_alloc&)
- {
- LLError::LLUserWarningMsg::showOutOfMemory();
- LL_ERRS("CoreHTTP") << "Failed to allocate memory for response handling." << LL_ENDL;
- }
- }
+ response->addRef();
- buildStatusEntry(response, status, result);
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+ posted = main_queue->postTo(
+ general_queue,
+ [handler = shared_from_this(), response, status]() // Work done on general queue
+ {
+ std::pair<LLSD, LLCore::HttpStatus> result;
+ result.second = status;
+ try
+ {
+ result.first = handler->handleSuccess(response, result.second);
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("CoreHTTP") << "Failed to allocate memory for response handling (threaded)." << LL_ENDL;
+ }
+ // LLSD is not thread safe! Be carefull with moving the result around.
+ return result;
+ },
+ [handler = shared_from_this(), response](std::pair<LLSD, LLCore::HttpStatus> result) mutable // Callback to main thread
+ {
+ handler->replyPost(response, result.second, result.first);
+ response->release();
+ });
- if (!status)
- {
- LLSD &httpStatus = result[HttpCoroutineAdapter::HTTP_RESULTS];
+ if (posted)
+ {
+ // Thread will do the cleanup and notify the pump. Done.
+ return;
+ }
+ else
+ {
+ // For whatever reason, failed to post, clean up and
+ // do the work on the main thread.
+ response->release();
+ }
+ }
- LLCore::BufferArray *body = response->getBody();
- LLCore::BufferArrayStream bas(body);
- LLSD::String bodyData;
- bodyData.reserve(response->getBodySize());
- bas >> std::noskipws;
- bodyData.assign(std::istream_iterator<U8>(bas), std::istream_iterator<U8>());
- httpStatus["error_body"] = LLSD(bodyData);
- if (getBoolSetting(HTTP_LOGBODY_KEY))
+ if (!posted)
{
- // commenting out, but keeping since this can be useful for debugging
- LL_WARNS("CoreHTTP") << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL;
+ try
+ {
+ result = this->handleSuccess(response, status);
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("CoreHTTP") << "Failed to allocate memory for response handling." << LL_ENDL;
+ }
}
}
- mReplyPump.post(result);
+ replyPost(response, status, result);
}
-void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result)
+void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result) const
{
LLSD httpresults = LLSD::emptyMap();
@@ -357,6 +390,31 @@ void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::H
result[HttpCoroutineAdapter::HTTP_RESULTS] = httpresults;
}
+void HttpCoroHandler::replyPost(LLCore::HttpResponse* response, LLCore::HttpStatus &status, LLSD& result)
+{
+ buildStatusEntry(response, status, result);
+
+ if (!status)
+ {
+ LLSD& httpStatus = result[HttpCoroutineAdapter::HTTP_RESULTS];
+
+ LLCore::BufferArray* body = response->getBody();
+ LLCore::BufferArrayStream bas(body);
+ LLSD::String bodyData;
+ bodyData.reserve(response->getBodySize());
+ bas >> std::noskipws;
+ bodyData.assign(std::istream_iterator<U8>(bas), std::istream_iterator<U8>());
+ httpStatus["error_body"] = LLSD(bodyData);
+ if (getBoolSetting(HTTP_LOGBODY_KEY))
+ {
+ // commenting out, but keeping since this can be useful for debugging
+ LL_WARNS("CoreHTTP") << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL;
+ }
+ }
+
+ mReplyPump.post(result);
+}
+
void HttpCoroHandler::writeStatusCodes(LLCore::HttpStatus status, const std::string &url, LLSD &result)
{
result[HttpCoroutineAdapter::HTTP_RESULTS_SUCCESS] = static_cast<LLSD::Boolean>(status);
@@ -389,8 +447,8 @@ public:
HttpCoroLLSDHandler(LLEventStream &reply);
protected:
- virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status);
- virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success);
+ virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const;
+ virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success) const;
};
//-------------------------------------------------------------------------
@@ -400,7 +458,7 @@ HttpCoroLLSDHandler::HttpCoroLLSDHandler(LLEventStream &reply):
}
-LLSD HttpCoroLLSDHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status)
+LLSD HttpCoroLLSDHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const
{
LLSD result;
@@ -465,7 +523,7 @@ LLSD HttpCoroLLSDHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:
return result;
}
-LLSD HttpCoroLLSDHandler::parseBody(LLCore::HttpResponse *response, bool &success)
+LLSD HttpCoroLLSDHandler::parseBody(LLCore::HttpResponse *response, bool &success) const
{
success = true;
if (response->getBodySize() == 0)
@@ -496,8 +554,8 @@ class HttpCoroRawHandler : public HttpCoroHandler
public:
HttpCoroRawHandler(LLEventStream &reply);
- virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status);
- virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success);
+ virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const;
+ virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success) const;
};
//-------------------------------------------------------------------------
@@ -506,7 +564,7 @@ HttpCoroRawHandler::HttpCoroRawHandler(LLEventStream &reply):
{
}
-LLSD HttpCoroRawHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status)
+LLSD HttpCoroRawHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const
{
LLSD result = LLSD::emptyMap();
@@ -552,7 +610,7 @@ LLSD HttpCoroRawHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::
return result;
}
-LLSD HttpCoroRawHandler::parseBody(LLCore::HttpResponse *response, bool &success)
+LLSD HttpCoroRawHandler::parseBody(LLCore::HttpResponse *response, bool &success) const
{
success = true;
return LLSD();
@@ -571,8 +629,8 @@ class HttpCoroJSONHandler : public HttpCoroHandler
public:
HttpCoroJSONHandler(LLEventStream &reply);
- virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status);
- virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success);
+ virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const;
+ virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success) const;
};
//-------------------------------------------------------------------------
@@ -581,7 +639,7 @@ HttpCoroJSONHandler::HttpCoroJSONHandler(LLEventStream &reply) :
{
}
-LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status)
+LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const
{
LLSD result = LLSD::emptyMap();
@@ -607,7 +665,7 @@ LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:
return result;
}
-LLSD HttpCoroJSONHandler::parseBody(LLCore::HttpResponse *response, bool &success)
+LLSD HttpCoroJSONHandler::parseBody(LLCore::HttpResponse *response, bool &success) const
{
success = true;
BufferArray * body(response->getBody());
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index 3dbfd6f00d..3072f78911 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -259,7 +259,7 @@ inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & requ
/// +- ["url"] - The URL used to make the call.
/// +- ["headers"] - A map of name name value pairs with the HTTP headers.
///
-class HttpCoroHandler : public LLCore::HttpHandler
+class HttpCoroHandler : public LLCore::HttpHandler, public std::enable_shared_from_this<HttpCoroHandler>
{
public:
@@ -279,11 +279,12 @@ public:
protected:
/// this method may modify the status value
- virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) = 0;
- virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success) = 0;
+ virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) const = 0;
+ virtual LLSD parseBody(LLCore::HttpResponse *response, bool &success) const = 0;
private:
- void buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result);
+ void buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result) const;
+ void replyPost(LLCore::HttpResponse* response, LLCore::HttpStatus& status, LLSD& result);
LLEventStream &mReplyPump;
};
diff --git a/indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp
index 78876f9f36..b7c4b5e591 100644
--- a/indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp
+++ b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp
@@ -75,10 +75,7 @@ LLCDResult LLConvexDecompositionVHACD::quitSystem()
LLConvexDecompositionVHACD::LLConvexDecompositionVHACD()
{
- //Create our vhacd instance and setup default parameters
- mVHACD = VHACD::CreateVHACD();
-
- mVHACDParameters.m_callback = &mVHACDCallback;
+ // Setup default parameters
mVHACDParameters.m_logger = &mVHACDLogger;
mDecompStages[0].mName = "Analyze";
@@ -206,27 +203,33 @@ LLConvexDecompositionVHACD::LLConvexDecompositionVHACD()
LLConvexDecompositionVHACD::~LLConvexDecompositionVHACD()
{
- mBoundDecomp = nullptr;
- mDecompData.clear();
-
- mVHACD->Release();
+ {
+ LLMutexLock lock(&mDecompDataMutex);
+ mBoundDecompID = INVALID_DECOMP_ID;
+ mDecompData.clear();
+ }
}
void LLConvexDecompositionVHACD::genDecomposition(int& decomp)
{
- int new_decomp_id = static_cast<int>(mDecompData.size()) + 1;
- mDecompData[new_decomp_id] = LLDecompData();
- decomp = new_decomp_id;
+ LLMutexLock lock(&mDecompDataMutex);
+
+ mDecompData[mNextDecompID] = std::make_shared<LLDecompData>();
+ decomp = mNextDecompID;
+
+ ++mNextDecompID; // Increment decomposition ID. Never reuse to protect downstream consumers from misuse
}
void LLConvexDecompositionVHACD::deleteDecomposition(int decomp)
{
+ LLMutexLock lock(&mDecompDataMutex);
+
auto iter = mDecompData.find(decomp);
if (iter != mDecompData.end())
{
- if (mBoundDecomp == &iter->second)
+ if (mBoundDecompID == decomp)
{
- mBoundDecomp = nullptr;
+ mBoundDecompID = INVALID_DECOMP_ID;
}
mDecompData.erase(iter);
}
@@ -234,29 +237,48 @@ void LLConvexDecompositionVHACD::deleteDecomposition(int decomp)
void LLConvexDecompositionVHACD::bindDecomposition(int decomp)
{
- auto iter = mDecompData.find(decomp);
- if (iter != mDecompData.end())
+ LLMutexLock lock(&mDecompDataMutex);
+
+ if (mDecompData.contains(decomp))
{
- mBoundDecomp = &iter->second;
+ mBoundDecompID = decomp;
}
else
{
LL_WARNS() << "Failed to bind unknown decomposition: " << decomp << LL_ENDL;
- mBoundDecomp = nullptr;
+ mBoundDecompID = INVALID_DECOMP_ID;
}
}
+LLConvexDecompositionVHACD::data_ptr_t LLConvexDecompositionVHACD::getBoundDecomp()
+{
+ data_ptr_t bound_decomp;
+ {
+ LLMutexLock lock(&mDecompDataMutex);
+ auto it = mDecompData.find(mBoundDecompID);
+ if (it != mDecompData.end())
+ {
+ bound_decomp = it->second; // Take a copy of the shared_ptr to avoid potential deletion
+ }
+ }
+ return bound_decomp;
+}
+
LLCDResult LLConvexDecompositionVHACD::setParam(const char* name, float val)
{
- if (name == std::string("Num Hulls"))
+ LLMutexLock lock(&mParamsMutex);
+
+ using namespace std::literals;
+
+ if (name == "Num Hulls"sv)
{
mVHACDParameters.m_maxConvexHulls = llclamp(ll_round(val), 1, MAX_HULLS);
}
- else if (name == std::string("Num Vertices"))
+ else if (name == "Num Vertices"sv)
{
mVHACDParameters.m_maxNumVerticesPerCH = llclamp(ll_round(val), 3, MAX_VERTICES_PER_HULL);
}
- else if (name == std::string("Error Tolerance"))
+ else if (name == "Error Tolerance"sv)
{
mVHACDParameters.m_minimumVolumePercentErrorAllowed = val;
}
@@ -270,11 +292,15 @@ LLCDResult LLConvexDecompositionVHACD::setParam(const char* name, bool val)
LLCDResult LLConvexDecompositionVHACD::setParam(const char* name, int val)
{
- if (name == std::string("Fill Mode"))
+ LLMutexLock lock(&mParamsMutex);
+
+ using namespace std::literals;
+
+ if (name == "Fill Mode"sv)
{
mVHACDParameters.m_fillMode = (VHACD::FillMode)val;
}
- else if (name == std::string("Voxel Resolution"))
+ else if (name == "Voxel Resolution"sv)
{
mVHACDParameters.m_resolution = val;
}
@@ -283,19 +309,21 @@ LLCDResult LLConvexDecompositionVHACD::setParam(const char* name, int val)
LLCDResult LLConvexDecompositionVHACD::setMeshData( const LLCDMeshData* data, bool vertex_based )
{
- if (!mBoundDecomp)
+ data_ptr_t bound_decomp = getBoundDecomp();
+ if (!bound_decomp)
{
return LLCD_NULL_PTR;
}
- return mBoundDecomp->mSourceMesh.from(data, vertex_based);
+ return bound_decomp->mSourceMesh.from(data, vertex_based);
}
LLCDResult LLConvexDecompositionVHACD::registerCallback(int stage, llcdCallbackFunc callback )
{
if (stage == 0)
{
- mVHACDCallback.setCallbackFunc(callback);
+ LLMutexLock lock(&mParamsMutex);
+ mCurrentCallbackFunc = callback;
return LLCD_OK;
}
else
@@ -306,44 +334,68 @@ LLCDResult LLConvexDecompositionVHACD::registerCallback(int stage, llcdCallbackF
LLCDResult LLConvexDecompositionVHACD::executeStage(int stage)
{
- if (!mBoundDecomp)
+ if (stage != 0)
+ {
+ return LLCD_INVALID_STAGE;
+ }
+
+ data_ptr_t bound_decomp = getBoundDecomp();
+ if (!bound_decomp)
{
return LLCD_NULL_PTR;
}
- if (stage != 0)
+ bound_decomp->mDecomposedHulls.clear();
+
+ const auto& decomp_mesh = bound_decomp->mSourceMesh;
+
+ VHACDCallback callbacks;
+ VHACD::IVHACD::Parameters current_params;
{
- return LLCD_INVALID_STAGE;
+ LLMutexLock lock(&mParamsMutex);
+
+ current_params = mVHACDParameters;
+ callbacks.setCallbackFunc(mCurrentCallbackFunc);
+ }
+ current_params.m_callback = &callbacks;
+
+ auto vhacd_impl = VHACD::CreateVHACD();
+ if (!vhacd_impl)
+ {
+ LL_WARNS() << "Failed to create VHACD instance" << LL_ENDL;
+ return LLCD_NULL_PTR;
}
- mBoundDecomp->mDecomposedHulls.clear();
- const auto& decomp_mesh = mBoundDecomp->mSourceMesh;
- if (!mVHACD->Compute((const double* const)decomp_mesh.mVertices.data(), static_cast<uint32_t>(decomp_mesh.mVertices.size()), (const uint32_t* const)decomp_mesh.mIndices.data(), static_cast<uint32_t>(decomp_mesh.mIndices.size()), mVHACDParameters))
+ if (!vhacd_impl->Compute((const double*)decomp_mesh.mVertices.data(), static_cast<uint32_t>(decomp_mesh.mVertices.size()),
+ (const uint32_t*)decomp_mesh.mIndices.data(), static_cast<uint32_t>(decomp_mesh.mIndices.size()),
+ current_params))
{
+ vhacd_impl->Release();
return LLCD_INVALID_HULL_DATA;
}
- uint32_t num_nulls = mVHACD->GetNConvexHulls();
- if (num_nulls == 0)
+ uint32_t num_convex_hulls = vhacd_impl->GetNConvexHulls();
+ if (num_convex_hulls == 0)
{
+ vhacd_impl->Release();
return LLCD_INVALID_HULL_DATA;
}
- for (uint32_t i = 0; num_nulls > i; ++i)
+ for (uint32_t i = 0; num_convex_hulls > i; ++i)
{
VHACD::IVHACD::ConvexHull ch;
- if (!mVHACD->GetConvexHull(i, ch))
+ if (!vhacd_impl->GetConvexHull(i, ch))
continue;
LLConvexMesh out_mesh;
out_mesh.setVertices(ch.m_points);
out_mesh.setIndices(ch.m_triangles);
- mBoundDecomp->mDecomposedHulls.push_back(std::move(out_mesh));
+ bound_decomp->mDecomposedHulls.push_back(std::move(out_mesh));
}
- mVHACD->Clean();
+ vhacd_impl->Release();
return LLCD_OK;
}
@@ -351,19 +403,21 @@ LLCDResult LLConvexDecompositionVHACD::executeStage(int stage)
LLCDResult LLConvexDecompositionVHACD::buildSingleHull()
{
LL_INFOS() << "Building single hull mesh" << LL_ENDL;
- if (!mBoundDecomp || mBoundDecomp->mSourceMesh.mVertices.empty())
+
+ data_ptr_t bound_decomp = getBoundDecomp();
+ if (!bound_decomp || bound_decomp->mSourceMesh.mVertices.empty())
{
return LLCD_NULL_PTR;
}
- mBoundDecomp->mSingleHullMesh.clear();
+ bound_decomp->mSingleHullMesh.clear();
VHACD::QuickHull quickhull;
- uint32_t num_tris = quickhull.ComputeConvexHull(mBoundDecomp->mSourceMesh.mVertices, MAX_VERTICES_PER_HULL);
+ uint32_t num_tris = quickhull.ComputeConvexHull(bound_decomp->mSourceMesh.mVertices, MAX_VERTICES_PER_HULL);
if (num_tris > 0)
{
- mBoundDecomp->mSingleHullMesh.setVertices(quickhull.GetVertices());
- mBoundDecomp->mSingleHullMesh.setIndices(quickhull.GetIndices());
+ bound_decomp->mSingleHullMesh.setVertices(quickhull.GetVertices());
+ bound_decomp->mSingleHullMesh.setIndices(quickhull.GetIndices());
return LLCD_OK;
}
@@ -373,29 +427,31 @@ LLCDResult LLConvexDecompositionVHACD::buildSingleHull()
int LLConvexDecompositionVHACD::getNumHullsFromStage(int stage)
{
- if (!mBoundDecomp || stage != 0)
+ data_ptr_t bound_decomp = getBoundDecomp();
+ if (!bound_decomp || stage != 0)
{
return 0;
}
- return narrow(mBoundDecomp->mDecomposedHulls.size());
+ return narrow(bound_decomp->mDecomposedHulls.size());
}
LLCDResult LLConvexDecompositionVHACD::getSingleHull( LLCDHull* hullOut )
{
memset( hullOut, 0, sizeof(LLCDHull) );
- if (!mBoundDecomp)
+ data_ptr_t bound_decomp = getBoundDecomp();
+ if (!bound_decomp)
{
return LLCD_NULL_PTR;
}
- if (mBoundDecomp->mSingleHullMesh.vertices.empty())
+ if (bound_decomp->mSingleHullMesh.vertices.empty())
{
return LLCD_INVALID_HULL_DATA;
}
- mBoundDecomp->mSingleHullMesh.to(hullOut);
+ bound_decomp->mSingleHullMesh.to(hullOut);
return LLCD_OK;
}
@@ -403,7 +459,8 @@ LLCDResult LLConvexDecompositionVHACD::getHullFromStage( int stage, int hull, LL
{
memset( hullOut, 0, sizeof(LLCDHull) );
- if (!mBoundDecomp)
+ data_ptr_t bound_decomp = getBoundDecomp();
+ if (!bound_decomp)
{
return LLCD_NULL_PTR;
}
@@ -413,19 +470,21 @@ LLCDResult LLConvexDecompositionVHACD::getHullFromStage( int stage, int hull, LL
return LLCD_INVALID_STAGE;
}
- if (mBoundDecomp->mDecomposedHulls.empty() || mBoundDecomp->mDecomposedHulls.size() <= hull)
+ if (bound_decomp->mDecomposedHulls.empty() || S32(bound_decomp->mDecomposedHulls.size()) <= hull)
{
return LLCD_REQUEST_OUT_OF_RANGE;
}
- mBoundDecomp->mDecomposedHulls[hull].to(hullOut);
+ bound_decomp->mDecomposedHulls[hull].to(hullOut);
return LLCD_OK;
}
LLCDResult LLConvexDecompositionVHACD::getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut )
{
memset( meshDataOut, 0, sizeof(LLCDMeshData));
- if (!mBoundDecomp)
+
+ data_ptr_t bound_decomp = getBoundDecomp();
+ if (!bound_decomp)
{
return LLCD_NULL_PTR;
}
@@ -435,12 +494,12 @@ LLCDResult LLConvexDecompositionVHACD::getMeshFromStage( int stage, int hull, LL
return LLCD_INVALID_STAGE;
}
- if (mBoundDecomp->mDecomposedHulls.empty() || mBoundDecomp->mDecomposedHulls.size() <= hull)
+ if (bound_decomp->mDecomposedHulls.empty() || S32(bound_decomp->mDecomposedHulls.size()) <= hull)
{
return LLCD_REQUEST_OUT_OF_RANGE;
}
- mBoundDecomp->mDecomposedHulls[hull].to(meshDataOut);
+ bound_decomp->mDecomposedHulls[hull].to(meshDataOut);
return LLCD_OK;
}
diff --git a/indra/llphysicsextensionsos/llconvexdecompositionvhacd.h b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.h
index 675356629c..27c867704e 100644
--- a/indra/llphysicsextensionsos/llconvexdecompositionvhacd.h
+++ b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.h
@@ -31,6 +31,7 @@
#include "llconvexdecomposition.h"
#include "llsingleton.h"
#include "llmath.h"
+#include "llmutex.h"
#include <vector>
@@ -323,14 +324,25 @@ private:
std::vector<LLConvexMesh> mDecomposedHulls;
};
- std::unordered_map<int, LLDecompData> mDecompData;
+ using data_ptr_t = std::shared_ptr<LLDecompData>;
- LLDecompData* mBoundDecomp = nullptr;
+ data_ptr_t getBoundDecomp();
+
+ // MUST lock before accessing mDecompData mBoundDecompID or mNextDecompID
+ LLMutex mDecompDataMutex;
+
+ static constexpr int INVALID_DECOMP_ID = -1;
+
+ int mBoundDecompID = INVALID_DECOMP_ID;
+ int mNextDecompID = 0; // Only for use inside genDecomposition.
+
+ std::unordered_map<int, data_ptr_t> mDecompData;
- VHACD::IVHACD* mVHACD = nullptr;
- VHACDCallback mVHACDCallback;
VHACDLogger mVHACDLogger;
+
+ LLMutex mParamsMutex;
VHACD::IVHACD::Parameters mVHACDParameters;
+ llcdCallbackFunc mCurrentCallbackFunc;
LLConvexMesh mMeshFromHullData;
LLConvexMesh mSingleHullMeshFromMeshData;
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index 930222e3db..1c47001272 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -214,7 +214,7 @@ std::string LLGLTFMaterial::asJSON(bool prettyprint) const
// to WriteGltfSceneToStream in the viewer.
gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false);
- return str.str();
+ return std::move(str).str();
}
void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index)
@@ -924,6 +924,25 @@ void LLGLTFMaterial::updateTextureTracking()
// for material overrides editor will set it
}
+// Test cases:
+// Case 1.
+// Input: scale 1.0,1.0; Offset horizontal 0.0, Offset vertical 0.0 Rotation 0.349066;
+// Expected output: scale 1.0,1.0; Offset horizontal 0.201, Offset vertical -0.141 Rotation -0.349066;
+// Case 2.
+// Input: scale 1.0,1.0; Offset horizontal 0.5, Offset vertical 0.1 Rotation 0;
+// Expected output: scale 1.0,1.0; Offset horizontal 0.5, Offset vertical -0.1 Rotation -0;
+// Case 3.
+// Input: scale 1.0,1.0; Offset horizontal 0.1, Offset vertical 0.2 Rotation 0.349066;
+// Expected output: scale 1.0,1.0; Offset horizontal 0.295, Offset vertical -0.345 Rotation -0.349066;
+// Case 4.
+// Input: scale 1.0,1.0; Offset horizontal 0.5, Offset vertical 0.0 Rotation 0.349066;
+// Expected output: scale 1.0,1.0; Offset horizontal 0.701, Offset vertical -0.141 Rotation -0.349066;
+//
+// Legacy offsets are right to left and top to bottom.
+// PBR offsets are right to left and bottom to top.
+//
+// Legacy rotation is relative to face's center counter clockwise,
+// PBR rotation is relative to top-left corner, clockwise
void LLGLTFMaterial::convertTextureTransformToPBR(
F32 tex_scale_s,
F32 tex_scale_t,
@@ -935,22 +954,65 @@ void LLGLTFMaterial::convertTextureTransformToPBR(
F32& pbr_rotation)
{
pbr_scale.set(tex_scale_s, tex_scale_t);
- pbr_rotation = -(tex_rotation) / 2.f;
- const F32 adjusted_offset_s = tex_offset_s;
- const F32 adjusted_offset_t = -tex_offset_t;
+ pbr_rotation = -tex_rotation;
+
+ // Center of the tile
+ const F32 center_s = 0.5f;
+ const F32 center_t = 0.5f;
+
+ // Center adjustment for scale
F32 center_adjust_s = 0.5f * (1.0f - tex_scale_s);
F32 center_adjust_t = 0.5f * (1.0f - tex_scale_t);
- if (pbr_rotation != 0.0f)
- {
- const F32 c = cosf(pbr_rotation);
- const F32 s = sinf(pbr_rotation);
- const F32 tmp_s = center_adjust_s * c - center_adjust_t * s;
- const F32 tmp_t = center_adjust_s * s + center_adjust_t * c;
- center_adjust_s = tmp_s;
- center_adjust_t = tmp_t;
- }
+ // 2. Offset from center
+ F32 pos_s = center_adjust_s - center_s;
+ F32 pos_t = center_adjust_t - center_t;
+
+ // 3. Rotate around center (clockwise, as per GLTF spec)
+ F32 c = cosf(pbr_rotation);
+ F32 s = sinf(pbr_rotation);
+ F32 rot_s = pos_s * c + pos_t * s;
+ F32 rot_t = -pos_s * s + pos_t * c;
+
+ // 4. Move back to top-left and apply offset
+ pbr_offset.set(rot_s + center_s + tex_offset_s, rot_t + center_t - tex_offset_t);
+}
+
+// Convert PBR transform values back to legacy TE transform values.
+// This is the reverse of convertTextureTransformToPBR.
+void LLGLTFMaterial::convertPBRTransformToTexture(
+ const LLVector2& pbr_scale,
+ const LLVector2& pbr_offset,
+ F32 pbr_rotation,
+ F32& tex_scale_s,
+ F32& tex_scale_t,
+ F32& tex_offset_s,
+ F32& tex_offset_t,
+ F32& tex_rotation)
+{
+ tex_scale_s = pbr_scale.mV[0];
+ tex_scale_t = pbr_scale.mV[1];
+ tex_rotation = -pbr_rotation;
+
+ // Center of the tile
+ const F32 center_s = 0.5f;
+ const F32 center_t = 0.5f;
+
+ // Center adjustment for scale
+ F32 center_adjust_s = 0.5f * (1.0f - tex_scale_s);
+ F32 center_adjust_t = 0.5f * (1.0f - tex_scale_t);
+
+ // 2. Offset from center
+ F32 pos_s = center_adjust_s - center_s;
+ F32 pos_t = center_adjust_t - center_t;
+
+ // 3. Rotate around center (clockwise, as per GLTF spec)
+ F32 c = cosf(pbr_rotation);
+ F32 s = sinf(pbr_rotation);
+ F32 rot_s = pos_s * c + pos_t * s;
+ F32 rot_t = -pos_s * s + pos_t * c;
- pbr_offset.set(adjusted_offset_s + center_adjust_s,
- adjusted_offset_t + center_adjust_t);
+ // 3. Recover legacy offset
+ tex_offset_s = pbr_offset.mV[0] - rot_s - center_s;
+ tex_offset_t = -(pbr_offset.mV[1] - rot_t - center_t);
}
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index 6bb021254b..64b585aacf 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -223,6 +223,14 @@ public:
LLVector2& pbr_scale,
LLVector2& pbr_offset,
F32& pbr_rotation);
+
+ // Convert PBR transform values to legacy TE transform values.
+ static void convertPBRTransformToTexture(const LLVector2& pbr_scale,
+ const LLVector2& pbr_offset,
+ F32 pbr_rotation,
+ F32& tex_scale_s, F32& tex_scale_t,
+ F32& tex_offset_s, F32& tex_offset_t,
+ F32& tex_rotation);
protected:
static LLVector2 vec2FromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const LLVector2& default_value);
static F32 floatFromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const F32 default_value);
diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h
index bd6256d961..41dd5a8710 100644
--- a/indra/llprimitive/llmaterialid.h
+++ b/indra/llprimitive/llmaterialid.h
@@ -67,15 +67,11 @@ public:
static const LLMaterialID null;
- // Returns a 64 bits digest of the material Id, by XORing its two 64 bits
- // long words. HB
- inline U64 getDigest64() const
- {
- U64* tmp = (U64*)mID;
- return tmp[0] ^ tmp[1];
- }
-
private:
+ // definitions follow class
+ friend std::hash<LLMaterialID>;
+ friend size_t hash_value(const LLMaterialID&) noexcept;
+
void parseFromBinary(const LLSD::Binary& pMaterialID);
void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID);
int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const;
@@ -90,15 +86,27 @@ namespace std
{
inline size_t operator()(const LLMaterialID& id) const noexcept
{
- return (size_t)id.getDigest64();
+ size_t h = 0;
+ // Golden ratio hash with avalanche mixing
+ // Process 8 bytes at a time by manually constructing 64-bit values
+ // Shift by 31: mixes upper half into lower half for better bit distribution
+ // Shift by 47: ensures highest bits influence final hash output
+ for (int i = 0; i < MATERIAL_ID_SIZE; i += 8) {
+ size_t chunk = (size_t)id.mID[i] | ((size_t)id.mID[i + 1] << 8) |
+ ((size_t)id.mID[i+2] << 16) | ((size_t)id.mID[i+3] << 24) |
+ ((size_t)id.mID[i+4] << 32) | ((size_t)id.mID[i+5] << 40) |
+ ((size_t)id.mID[i + 6] << 48) | ((size_t)id.mID[i + 7] << 56);
+ h ^= (chunk * 0x9e3779b97f4a7c15ULL) ^ (h >> 31) ^ (h >> 47);
+ }
+ return h;
}
};
}
-// For use with boost containers.
+// For use with boost::container_hash
inline size_t hash_value(const LLMaterialID& id) noexcept
{
- return (size_t)id.getDigest64();
+ return std::hash<LLMaterialID>{}(id);
}
#endif // LL_LLMATERIALID_H
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 31bc76344c..c3e3e19ee9 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -109,11 +109,12 @@ public:
PARAMS_EXTENDED_MESH = 0x70,
PARAMS_RENDER_MATERIAL = 0x80,
PARAMS_REFLECTION_PROBE = 0x90,
+ PARAMS_MAX = PARAMS_REFLECTION_PROBE,
};
public:
U16 mType;
- virtual ~LLNetworkData() {};
+ virtual ~LLNetworkData() = default;
virtual bool pack(LLDataPacker &dp) const = 0;
virtual bool unpack(LLDataPacker &dp) = 0;
virtual bool operator==(const LLNetworkData& data) const = 0;
@@ -319,7 +320,7 @@ public:
bool fromLLSD(LLSD& sd);
void setSculptTexture(const LLUUID& texture_id, U8 sculpt_type);
- LLUUID getSculptTexture() const { return mSculptTexture; }
+ const LLUUID& getSculptTexture() const { return mSculptTexture; }
U8 getSculptType() const { return mSculptType; }
};
@@ -340,10 +341,10 @@ public:
bool fromLLSD(LLSD& sd);
void setLightTexture(const LLUUID& id) { mLightTexture = id; }
- LLUUID getLightTexture() const { return mLightTexture; }
+ const LLUUID& getLightTexture() const { return mLightTexture; }
bool isLightSpotlight() const { return mLightTexture.notNull(); }
void setParams(const LLVector3& params) { mParams = params; }
- LLVector3 getParams() const { return mParams; }
+ const LLVector3& getParams() const { return mParams; }
};
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index a9b3a944ee..f7600e40a3 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -27,13 +27,14 @@
#ifndef LL_LLFONTFREETYPE_H
#define LL_LLFONTFREETYPE_H
-#include <boost/unordered_map.hpp>
#include "llpointer.h"
#include "llstl.h"
#include "llimagegl.h"
#include "llfontbitmapcache.h"
+#include <unordered_map>
+
// Hack. FT_Face is just a typedef for a pointer to a struct,
// but there's no simple forward declarations file for FreeType,
// and the main include file is 200K.
@@ -184,7 +185,7 @@ private:
fallback_font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
// *NOTE: the same glyph can be present with multiple representations (but the pointer is always unique)
- typedef boost::unordered_multimap<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
+ typedef std::unordered_multimap<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
mutable LLFontBitmapCache* mFontBitmapCachep;
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index b002d183ef..3a36e49029 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -2386,7 +2386,7 @@ void clear_glerror()
//
// Static members
-boost::unordered_map<LLGLenum, LLGLboolean> LLGLState::sStateMap;
+std::unordered_map<LLGLenum, LLGLboolean> LLGLState::sStateMap;
GLboolean LLGLDepthTest::sDepthEnabled = GL_FALSE; // OpenGL default
GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default
@@ -2433,7 +2433,7 @@ void LLGLState::resetTextureStates()
void LLGLState::dumpStates()
{
LL_INFOS("RenderState") << "GL States:" << LL_ENDL;
- for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
+ for (std::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)
{
LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"true":"false") << LL_ENDL;
@@ -2465,7 +2465,7 @@ void LLGLState::checkStates(GLboolean writeAlpha)
//llassert_always(colorMask[2]);
// llassert_always(colorMask[3] == writeAlpha);
- for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
+ for (std::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)
{
LLGLenum state = iter->first;
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 414c28481f..a7dced3753 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -31,7 +31,7 @@
#include <functional>
#include <string>
-#include <boost/unordered_map.hpp>
+#include <unordered_map>
#include <list>
#include "llerror.h"
@@ -248,7 +248,7 @@ public:
static void checkStates(GLboolean writeAlpha = GL_TRUE);
protected:
- static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
+ static std::unordered_map<LLGLenum, LLGLboolean> sStateMap;
public:
enum { CURRENT_STATE = -2, DISABLED_STATE = 0, ENABLED_STATE = 1 };
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index bc80bd9556..4901cb423b 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -2300,7 +2300,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
{
- if(sSkipAnalyzeAlpha || !mNeedsAlphaAndPickMask)
+ if(!data_in || sSkipAnalyzeAlpha || !mNeedsAlphaAndPickMask)
{
return ;
}
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 658947d531..8aacba00ac 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1846,25 +1846,64 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
return;
}
- if (mUIOffset.empty())
+ LLVector4a vert(x, y, z);
+ transform(vert);
+ mVerticesp[mCount] = vert;
+
+ mCount++;
+ mVerticesp[mCount] = mVerticesp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+}
+
+void LLRender::transform(LLVector3& vert)
+{
+ if (!mUIOffset.empty())
{
- mVerticesp[mCount].set(x,y,z);
+ vert += LLVector3(mUIOffset.back().getF32ptr());
+ vert *= LLVector3(mUIScale.back().getF32ptr());
}
- else
+}
+
+void LLRender::transform(LLVector4a& vert)
+{
+ if (!mUIOffset.empty())
{
- LLVector4a vert(x, y, z);
vert.add(mUIOffset.back());
vert.mul(mUIScale.back());
- mVerticesp[mCount] = vert;
}
+}
- mCount++;
- mVerticesp[mCount] = mVerticesp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+void LLRender::untransform(LLVector3& vert)
+{
+ if (!mUIOffset.empty())
+ {
+ vert /= LLVector3(mUIScale.back().getF32ptr());
+ vert -= LLVector3(mUIOffset.back().getF32ptr());
+ }
+}
+
+void LLRender::batchTransform(LLVector4a* verts, U32 vert_count)
+{
+ if (!mUIOffset.empty())
+ {
+ const LLVector4a& offset = mUIOffset.back();
+ const LLVector4a& scale = mUIScale.back();
+
+ for (U32 i = 0; i < vert_count; ++i)
+ {
+ verts[i].add(offset);
+ verts[i].mul(scale);
+ }
+ }
+}
+
+void LLRender::vertexBatchPreTransformed(const std::vector<LLVector4a>& verts)
+{
+ vertexBatchPreTransformed(verts.data(), narrow(verts.size()));
}
-void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(const LLVector4a* verts, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
@@ -1885,7 +1924,7 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count)
mVerticesp[mCount] = mVerticesp[mCount-1];
}
-void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(const LLVector4a* verts, const LLVector2* uvs, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
@@ -1909,7 +1948,7 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32
}
}
-void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(const LLVector4a* verts, const LLVector2* uvs, const LLColor4U* colors, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index e6ae3baac6..4ca63e7f1f 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -462,9 +462,16 @@ public:
void diffuseColor4ubv(const U8* c);
void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);
- void vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count);
- void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count);
- void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
+ void transform(LLVector3& vert);
+ void transform(LLVector4a& vert);
+ void untransform(LLVector3& vert);
+
+ void batchTransform(LLVector4a* verts, U32 vert_count);
+
+ void vertexBatchPreTransformed(const std::vector<LLVector4a>& verts);
+ void vertexBatchPreTransformed(const LLVector4a* verts, S32 vert_count);
+ void vertexBatchPreTransformed(const LLVector4a* verts, const LLVector2* uvs, S32 vert_count);
+ void vertexBatchPreTransformed(const LLVector4a* verts, const LLVector2* uvs, const LLColor4U*, S32 vert_count);
void setColorMask(bool writeColor, bool writeAlpha);
void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);
diff --git a/indra/llrender/lltexturemanagerbridge.cpp b/indra/llrender/lltexturemanagerbridge.cpp
index c243f0697a..67838418bf 100644
--- a/indra/llrender/lltexturemanagerbridge.cpp
+++ b/indra/llrender/lltexturemanagerbridge.cpp
@@ -24,6 +24,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "lltexturemanagerbridge.h"
// Define a null texture manager bridge. Applications must provide their own bridge implementaton.
diff --git a/indra/llui/llcallbackmap.h b/indra/llui/llcallbackmap.h
index 3115606d91..69b80db1e8 100644
--- a/indra/llui/llcallbackmap.h
+++ b/indra/llui/llcallbackmap.h
@@ -27,9 +27,11 @@
#ifndef LLCALLBACKMAP_H
#define LLCALLBACKMAP_H
-#include <map>
+#include "llstl.h"
+
#include <string>
#include <functional>
+#include <unordered_map>
class LLCallbackMap
{
@@ -37,7 +39,7 @@ public:
// callback definition.
typedef std::function<void* (void* data)> callback_t;
- typedef std::map<std::string, LLCallbackMap> map_t;
+ typedef std::unordered_map<std::string, LLCallbackMap> map_t;
typedef map_t::iterator map_iter_t;
typedef map_t::const_iterator map_const_iter_t;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 52a5e3dbd6..c60253e7fe 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -239,7 +239,7 @@ void LLFloater::initClass()
}
// defaults for floater param block pulled from widgets/floater.xml
-static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFloater::Params), "floater");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(typeid(LLFloater::Params), "floater");
LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
: LLPanel(), // intentionally do not pass params here, see initFromParams
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index a818e72f59..c18495ce71 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -40,9 +40,9 @@
LLFloaterReg::instance_list_t LLFloaterReg::sNullInstanceList;
LLFloaterReg::instance_map_t LLFloaterReg::sInstanceMap;
LLFloaterReg::build_map_t LLFloaterReg::sBuildMap;
-std::map<std::string, std::string, std::less<>> LLFloaterReg::sGroupMap;
+LLFloaterReg::group_map_t LLFloaterReg::sGroupMap;
bool LLFloaterReg::sBlockShowFloaters = false;
-std::set<std::string, std::less<>> LLFloaterReg::sAlwaysShowableList;
+LLFloaterReg::always_showable_t LLFloaterReg::sAlwaysShowableList;
static LLFloaterRegListener sFloaterRegListener;
@@ -96,11 +96,8 @@ LLFloater* LLFloaterReg::getLastFloaterCascading()
candidate_rect.mTop = 100000;
LLFloater* candidate_floater = NULL;
- std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
- for( ; it != it_end; ++it)
+ for (const auto& [floater_name, group_name] : sGroupMap)
{
- const std::string& group_name = it->second;
-
instance_list_t& instances = sInstanceMap[group_name];
for (LLFloater* inst : instances)
@@ -604,17 +601,11 @@ U32 LLFloaterReg::getVisibleFloaterInstanceCount()
{
U32 count = 0;
- std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
- for( ; it != it_end; ++it)
+ for (const auto& [floater_name, group_name] : sGroupMap)
{
- const std::string& group_name = it->second;
-
instance_list_t& instances = sInstanceMap[group_name];
-
- for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
+ for (LLFloater* inst : instances)
{
- LLFloater* inst = *iter;
-
if (inst->getVisible() && !inst->isMinimized())
{
count++;
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index 24d1476dda..71a11b6f42 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -29,9 +29,11 @@
/// llcommon
#include "llrect.h"
#include "llsd.h"
+#include "llstl.h"
#include <functional>
#include <list>
+#include <unordered_set>
//*******************************************************
//
@@ -51,26 +53,29 @@ public:
// 2) We can change the key of a floater without altering the list.
typedef std::list<LLFloater*> instance_list_t;
typedef const instance_list_t const_instance_list_t;
- typedef std::map<std::string, instance_list_t, std::less<>> instance_map_t;
+ typedef std::unordered_map<std::string, instance_list_t, ll::string_hash, std::equal_to<>> instance_map_t;
struct BuildData
{
LLFloaterBuildFunc mFunc;
std::string mFile;
};
- typedef std::map<std::string, BuildData, std::less<>> build_map_t;
+ typedef std::unordered_map<std::string, BuildData, ll::string_hash, std::equal_to<>> build_map_t;
private:
friend class LLFloaterRegListener;
static instance_list_t sNullInstanceList;
static instance_map_t sInstanceMap;
static build_map_t sBuildMap;
- static std::map<std::string, std::string, std::less<>> sGroupMap;
+
+ using group_map_t = std::unordered_map<std::string, std::string, ll::string_hash, std::equal_to<>>;
+ static group_map_t sGroupMap;
static bool sBlockShowFloaters;
/**
* Defines list of floater names that can be shown despite state of sBlockShowFloaters.
*/
- static std::set<std::string, std::less<>> sAlwaysShowableList;
+ using always_showable_t = std::unordered_set<std::string, ll::string_hash, std::equal_to<>>;
+ static always_showable_t sAlwaysShowableList;
public:
// Registration
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 878f1cb856..dafbca7433 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -28,6 +28,7 @@
#include "llflashtimer.h"
#include "linden_common.h"
+#include "llapp.h"
#include "llfolderviewitem.h"
#include "llfolderview.h"
#include "llfolderviewmodel.h"
@@ -1884,6 +1885,11 @@ void LLFolderViewFolder::updateHasFavorites(bool new_childs_value)
void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
{
LLFolderViewFolder* self = reinterpret_cast<LLFolderViewFolder*>(data);
+ if (gDisconnected || !self)
+ {
+ return;
+ }
+
if (self->mFavoritesDirtyFlags == FAVORITE_CLEANUP)
{
// parent or child already processed the update, clean the callback
@@ -2359,9 +2365,10 @@ bool LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
{
// navigating is going to destroy views and change children
// delay it untill handleDoubleClick processing is complete
- doOnIdleOneTime([this]()
- {
- getViewModelItem()->navigateToFolder(false);
+ LLPointer<LLFolderViewModelItem> view_model_item = getViewModelItem();
+ doOnIdleOneTime([view_model_item]() mutable
+ {;
+ view_model_item->navigateToFolder(false);
});
}
return true;
diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h
index 953963b683..40a3e439a6 100644
--- a/indra/llui/llfunctorregistry.h
+++ b/indra/llui/llfunctorregistry.h
@@ -29,8 +29,9 @@
#define LL_LLFUNCTORREGISTRY_H
#include <string>
-#include <map>
+#include <unordered_map>
+#include "llstring.h"
#include "llsd.h"
#include "llsingleton.h"
@@ -56,7 +57,7 @@ class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> >
public:
typedef FUNCTOR_TYPE ResponseFunctor;
- typedef typename std::map<std::string, FUNCTOR_TYPE> FunctorMap;
+ typedef typename std::unordered_map<std::string, FUNCTOR_TYPE, ll::string_hash, std::equal_to<>> FunctorMap;
bool registerFunctor(const std::string& name, ResponseFunctor f)
{
diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h
index 5892238593..53b5435324 100644
--- a/indra/llui/llkeywords.h
+++ b/indra/llui/llkeywords.h
@@ -194,7 +194,7 @@ protected:
token_list_t mLineTokenList;
token_list_t mDelimiterTokenList;
- typedef std::map<std::string, std::string, std::less<>> element_attributes_t;
+ typedef std::unordered_map<std::string, std::string, ll::string_hash, std::equal_to<>> element_attributes_t;
typedef element_attributes_t::const_iterator attribute_iterator_t;
element_attributes_t mAttributes;
std::string getAttribute(std::string_view key);
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index b534c8d4e8..ef62666918 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -122,6 +122,7 @@ LLLineEditor::Params::Params()
LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
: LLUICtrl(p),
+ mDefaultText(p.default_text),
mMaxLengthBytes(p.max_length.bytes),
mMaxLengthChars(p.max_length.chars),
mCursorPos( 0 ),
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 3f762822ee..6384bfdc5f 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -202,6 +202,7 @@ public:
void setLabel(const LLStringExplicit &new_label) { mLabel = new_label; }
const std::string& getLabel() { return mLabel.getString(); }
+ void setDefaultText() { setText(mDefaultText); }
void setText(const LLStringExplicit &new_text);
const std::string& getText() const override { return mText.getString(); }
@@ -347,6 +348,7 @@ protected:
LLFontVertexBuffer mFontBufferSelection;
LLFontVertexBuffer mFontBufferPostSelection;
LLFontVertexBuffer mFontBufferLabel;
+ std::string mDefaultText;
S32 mMaxLengthBytes; // Max length of the UTF8 string in bytes
S32 mMaxLengthChars; // Maximum number of characters in the string
S32 mCursorPos; // I-beam is just after the mCursorPos-th character.
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 0ffe6cff5e..56475a2d8d 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1424,6 +1424,7 @@ LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelN
// this function is called once at construction time, after the object is constructed.
void LLNotifications::initSingleton()
{
+ LL_PROFILE_ZONE_SCOPED;
loadTemplates();
loadVisibilityRules();
createDefaultChannels();
@@ -1436,6 +1437,8 @@ void LLNotifications::cleanupSingleton()
void LLNotifications::createDefaultChannels()
{
+ LL_PROFILE_ZONE_SCOPED;
+
LL_INFOS("Notifications") << "Generating default notification channels" << LL_ENDL;
// now construct the various channels AFTER loading the notifications,
// because the history channel is going to rewrite the stored notifications file
@@ -1578,6 +1581,8 @@ void addPathIfExists(const std::string& new_path, std::vector<std::string>& path
bool LLNotifications::loadTemplates()
{
+ LL_PROFILE_ZONE_SCOPED;
+
LL_INFOS("Notifications") << "Reading notifications template" << LL_ENDL;
// Passing findSkinnedFilenames(constraint=LLDir::ALL_SKINS) makes it
// output all relevant pathnames instead of just the ones from the most
@@ -1663,6 +1668,8 @@ bool LLNotifications::loadTemplates()
bool LLNotifications::loadVisibilityRules()
{
+ LL_PROFILE_ZONE_SCOPED;
+
const std::string xml_filename = "notification_visibility.xml";
// Note that here we're looking for the "en" version, the default
// language, rather than the most localized version of this file.
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index d56c459560..ea1cb7f638 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -93,6 +93,7 @@
#include "llinitparam.h"
#include "llinstancetracker.h"
#include "llmortician.h"
+#include "llmutex.h"
#include "llnotificationptr.h"
#include "llpointer.h"
#include "llrefcount.h"
@@ -945,7 +946,7 @@ public:
typedef std::vector<std::string> TemplateNames;
TemplateNames getTemplateNames() const; // returns a list of notification names
- typedef std::map<std::string, LLNotificationTemplatePtr, std::less<>> TemplateMap;
+ typedef std::unordered_map<std::string, LLNotificationTemplatePtr, ll::string_hash, std::equal_to<>> TemplateMap;
TemplateMap::const_iterator templatesBegin() { return mTemplates.begin(); }
TemplateMap::const_iterator templatesEnd() { return mTemplates.end(); }
@@ -991,7 +992,7 @@ private:
LLNotificationMap mUniqueNotifications;
- typedef std::map<std::string, std::string, std::less<>> GlobalStringMap;
+ typedef std::unordered_map<std::string, std::string, ll::string_hash, std::equal_to<>> GlobalStringMap;
GlobalStringMap mGlobalStrings;
bool mIgnoreAllNotifications;
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index fe861dc719..a928997c7d 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -250,7 +250,7 @@ private:
LLButton* mDefaultBtn;
LLUIString mLabel;
- typedef std::map<std::string, std::string, std::less<>> ui_string_map_t;
+ typedef std::unordered_map<std::string, std::string, ll::string_hash, std::equal_to<>> ui_string_map_t;
ui_string_map_t mUIStrings;
@@ -292,7 +292,7 @@ public:
}
private:
- typedef std::map< std::string, LLPanelClassCreatorFunc, std::less<>> param_name_map_t;
+ typedef std::unordered_map<std::string, LLPanelClassCreatorFunc, ll::string_hash, std::equal_to<>> param_name_map_t;
param_name_map_t mPanelClassesNames;
};
diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp
index 2aff434612..1dbd9f5b0c 100644
--- a/indra/llui/llradiogroup.cpp
+++ b/indra/llui/llradiogroup.cpp
@@ -67,7 +67,7 @@ protected:
LLSD mPayload; // stores data that this item represents in the radio group
};
-static LLWidgetNameRegistry::StaticRegistrar register_radio_item(&typeid(LLRadioGroup::ItemParams), "radio_item");
+static LLWidgetNameRegistry::StaticRegistrar register_radio_item(typeid(LLRadioGroup::ItemParams), "radio_item");
LLRadioGroup::Params::Params()
: allow_deselect("allow_deselect"),
diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp
index 1b4008cff2..5b0d2315c1 100644
--- a/indra/llui/llrngwriter.cpp
+++ b/indra/llui/llrngwriter.cpp
@@ -94,7 +94,7 @@ void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam:
block.inspectBlock(*this);
// add includes for all possible children
- const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name);
+ const std::type_index& type = *LLWidgetTypeRegistry::instance().getValue(type_name);
const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type);
// add include declarations for all valid children
diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp
index a4510d1fc2..b5ba466750 100644
--- a/indra/llui/llscrolllistcolumn.cpp
+++ b/indra/llui/llscrolllistcolumn.cpp
@@ -39,7 +39,7 @@
const S32 MIN_COLUMN_WIDTH = 20;
// defaults for LLScrollColumnHeader param block pulled from widgets/scroll_column_header.xml
-static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(&typeid(LLScrollColumnHeader::Params), "scroll_column_header");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(typeid(LLScrollColumnHeader::Params), "scroll_column_header");
//---------------------------------------------------------------------------
// LLScrollColumnHeader
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index b459c67dad..558ce6a7fd 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -3185,6 +3185,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS
if (cell_p.width.isProvided())
{
new_column.width.pixel_width = cell_p.width;
+ new_column.width.pixel_width.choose();
}
addColumn(new_column);
columnp = mColumns[column];
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 5e0985c79c..48e42d9fc0 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -2202,3 +2202,16 @@ void LLTabContainer::setTabVisibility( LLPanel const *aPanel, bool aVisible )
updateMaxScrollPos();
}
+
+bool LLTabContainer::getTabVisibility(const LLPanel* panel) const
+{
+ for (tuple_list_t::const_iterator itr = mTabList.begin(); itr != mTabList.end(); ++itr)
+ {
+ LLTabTuple const* pTT = *itr;
+ if (pTT->mTabPanel == panel)
+ {
+ return pTT->mVisible;
+ }
+ }
+ return false;
+}
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index 4ac7e73d25..cbf56dc653 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -225,6 +225,7 @@ public:
S32 getMaxTabWidth() const { return mMaxTabWidth; }
void setTabVisibility( LLPanel const *aPanel, bool );
+ bool getTabVisibility(const LLPanel* panel) const;
void startDragAndDropDelayTimer() { mDragAndDropDelayTimer.start(); }
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 2079ff17fc..24ae5c09e9 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -129,7 +129,7 @@ struct LLTextBase::line_end_compare
//
// register LLTextBase::Params under name "textbase"
-static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(&typeid(LLTextBase::Params), "textbase");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(typeid(LLTextBase::Params), "textbase");
LLTextBase::LineSpacingParams::LineSpacingParams()
: multiple("multiple", 1.f),
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index fcdf3782ae..7689b93374 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -581,7 +581,7 @@ S32 LLTextEditor::indentLine( S32 pos, S32 spaces )
LLWString wtext = getWText();
if (wtext[pos] == ' ')
{
- delta_spaces += remove( pos, 1, false );
+ delta_spaces -= remove( pos, 1, false );
}
}
}
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index 74f03618cf..c5b1b5ba1d 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -129,7 +129,7 @@ void LLToolTipView::drawStickyRect()
}
// defaults for floater param block pulled from widgets/floater.xml
-static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(&typeid(LLInspector::Params), "inspector");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(typeid(LLInspector::Params), "inspector");
//
// LLToolTip
diff --git a/indra/llui/lltrans.h b/indra/llui/lltrans.h
index c5d01e6f8d..4dba4c5c3e 100644
--- a/indra/llui/lltrans.h
+++ b/indra/llui/lltrans.h
@@ -125,7 +125,7 @@ public:
}
private:
- typedef std::map<std::string, LLTransTemplate, std::less<>> template_map_t;
+ typedef std::unordered_map<std::string, LLTransTemplate, ll::string_hash, std::equal_to<>> template_map_t;
static template_map_t sStringTemplates;
static template_map_t sDefaultStringTemplates;
static LLStringUtil::format_map_t sDefaultArgs;
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 179d1dcaff..5e01cffe38 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -65,7 +65,6 @@
// for XUIParse
#include "llquaternion.h"
-#include <boost/tokenizer.hpp>
#include <boost/algorithm/string/find_iterator.hpp>
#include <boost/algorithm/string/finder.hpp>
@@ -157,6 +156,7 @@ mWindow(NULL), // set later in startup
mRootView(NULL),
mHelpImpl(NULL)
{
+ LL_PROFILE_ZONE_SCOPED;
LLRender2D::createInstance(image_provider);
LLSpellChecker::createInstance();
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 2ef64baaf6..091e0ab1cf 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -114,7 +114,7 @@ class LLUI : public LLSimpleton<LLUI>
{
LOG_CLASS(LLUI);
public:
- typedef std::map<std::string, LLControlGroup*, std::less<> > settings_map_t;
+ typedef std::unordered_map<std::string, LLControlGroup*, ll::string_hash, std::equal_to<>> settings_map_t;
LLUI(const settings_map_t &settings,
LLImageProviderInterface* image_provider,
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp
index a792cb8103..7a4f72fe4f 100644
--- a/indra/llui/lluicolortable.cpp
+++ b/indra/llui/lluicolortable.cpp
@@ -198,8 +198,8 @@ LLUIColor LLUIColorTable::getColor(std::string_view name, const LLColor4& defaul
// update user color, loaded colors are parsed on initialization
void LLUIColorTable::setColor(std::string_view name, const LLColor4& color)
{
- auto it = mUserSetColors.lower_bound(name);
- if(it != mUserSetColors.end() && !(mUserSetColors.key_comp()(name, it->first)))
+ auto it = mUserSetColors.find(name);
+ if(it != mUserSetColors.end())
{
it->second = color;
}
@@ -330,9 +330,8 @@ void LLUIColorTable::clearTable(string_color_map_t& table)
// if the color already exists it changes the color
void LLUIColorTable::setColor(std::string_view name, const LLColor4& color, string_color_map_t& table)
{
- string_color_map_t::iterator it = table.lower_bound(name);
- if(it != table.end()
- && !(table.key_comp()(name, it->first)))
+ string_color_map_t::iterator it = table.find(name);
+ if(it != table.end())
{
it->second = color;
}
diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h
index 0c6286e5eb..aff6f59db6 100644
--- a/indra/llui/lluicolortable.h
+++ b/indra/llui/lluicolortable.h
@@ -27,7 +27,7 @@
#ifndef LL_LLUICOLORTABLE_H_
#define LL_LLUICOLORTABLE_H_
-#include <map>
+#include <unordered_map>
#include "llinitparam.h"
#include "llsingleton.h"
@@ -42,7 +42,7 @@ class LLUIColorTable : public LLSingleton<LLUIColorTable>
LOG_CLASS(LLUIColorTable);
// consider using sorted vector, can be much faster
- typedef std::map<std::string, LLUIColor, std::less<>> string_color_map_t;
+ typedef std::unordered_map<std::string, LLUIColor, ll::string_hash, std::equal_to<>> string_color_map_t;
public:
struct ColorParams : LLInitParam::ChoiceBlock<ColorParams>
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 9abccfd9a0..33ffc3dfc6 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -253,7 +253,7 @@ const LLInitParam::BaseBlock& get_empty_param_block()
// adds a widget and its param block to various registries
//static
-void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& name)
+void LLUICtrlFactory::registerWidget(std::type_index widget_type, std::type_index param_block_type, const std::string& name)
{
// associate parameter block type with template .xml file
std::string* existing_name = LLWidgetNameRegistry::instance().getValue(param_block_type);
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index fc069c078f..f44b4ba4dc 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -65,7 +65,7 @@ class LLDefaultChildRegistry : public LLChildRegistry<LLDefaultChildRegistry>
// lookup widget name by type
class LLWidgetNameRegistry
-: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry>
+: public LLRegistrySingleton<std::type_index, std::string, LLWidgetNameRegistry>
{
LLSINGLETON_EMPTY_CTOR(LLWidgetNameRegistry);
};
@@ -74,7 +74,7 @@ class LLWidgetNameRegistry
// this is used for schema generation
//typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)();
//class LLDefaultParamBlockRegistry
-//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry>
+//: public LLRegistrySingleton<std::type_index, empty_param_block_func_t, LLDefaultParamBlockRegistry>
//{
// LLSINGLETON(LLDefaultParamBlockRegistry);
//};
@@ -202,7 +202,7 @@ private:
static void copyName(LLXMLNodePtr src, LLXMLNodePtr dest);
// helper function for adding widget type info to various registries
- static void registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag);
+ static void registerWidget(std::type_index widget_type, std::type_index param_block_type, const std::string& tag);
static void loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block);
@@ -290,7 +290,7 @@ template <typename PARAM_BLOCK, int DUMMY>
LLUICtrlFactory::ParamDefaults<PARAM_BLOCK, DUMMY>::ParamDefaults()
{
// look up template file for this param block...
- const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK));
+ const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(typeid(PARAM_BLOCK));
if (param_block_tag)
{ // ...and if it exists, back fill values using the most specific template first
PARAM_BLOCK params;
@@ -314,12 +314,12 @@ LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreator
: LLChildRegistry<DERIVED>::StaticRegistrar(tag, func == nullptr ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func)
{
// add this widget to various registries
- LLUICtrlFactory::instance().registerWidget(&typeid(T), &typeid(typename T::Params), tag);
+ LLUICtrlFactory::instance().registerWidget(typeid(T), typeid(typename T::Params), tag);
// since registry_t depends on T, do this in line here
// TODO: uncomment this for schema generation
//typedef typename T::child_registry_t registry_t;
- //LLChildRegistryRegistry::instance().defaultRegistrar().add(&typeid(T), registry_t::instance());
+ //LLChildRegistryRegistry::instance().defaultRegistrar().add(typeid(T), registry_t::instance());
}
#endif //LLUICTRLFACTORY_H
diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index 8cd11b86b3..52afac430e 100644
--- a/indra/llui/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
@@ -602,7 +602,7 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p
LLXSDWriter::writeXSD(type_name, root_nodep, block, "http://www.lindenlab.com/xui");
// add includes for all possible children
- const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name);
+ const std::type_index& type = *LLWidgetTypeRegistry::instance().getValue(type_name);
const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type);
// add choices for valid children
@@ -1459,7 +1459,7 @@ void LLSimpleXUIParser::characterDataHandler(void *userData, const char *s, int
void LLSimpleXUIParser::characterData(const char *s, int len)
{
- mTextContents += std::string(s, len);
+ mTextContents.append(s, len);
}
void LLSimpleXUIParser::startElement(const char *name, const char **atts)
@@ -1480,24 +1480,24 @@ void LLSimpleXUIParser::startElement(const char *name, const char **atts)
mOutputStack.back().second++;
S32 num_tokens_pushed = 0;
- std::string child_name(name);
+ std::string_view child_name(name);
if (mOutputStack.back().second == 1)
{ // root node for this block
- mScope.push_back(child_name);
+ mScope.emplace_back(child_name);
}
else
{ // compound attribute
if (child_name.find(".") == std::string::npos)
{
- mNameStack.push_back(std::make_pair(child_name, true));
+ mNameStack.emplace_back(child_name, true);
num_tokens_pushed++;
- mScope.push_back(child_name);
+ mScope.emplace_back(child_name);
}
else
{
// parse out "dotted" name into individual tokens
- tokenizer name_tokens(child_name, sep);
+ tokenizer name_tokens(std::string(child_name), sep);
tokenizer::iterator name_token_it = name_tokens.begin();
if(name_token_it == name_tokens.end())
@@ -1603,8 +1603,8 @@ bool LLSimpleXUIParser::processText()
LLStringUtil::trim(mTextContents);
if (!mTextContents.empty())
{
- mNameStack.push_back(std::make_pair(std::string("value"), true));
- mCurAttributeValueBegin = mTextContents.c_str();
+ mNameStack.emplace_back("value", true);
+ mCurAttributeValueBegin = std::move(mTextContents);
mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
mNameStack.pop_back();
}
@@ -1648,12 +1648,12 @@ bool LLSimpleXUIParser::readFlag(Parser& parser, void* val_ptr)
bool LLSimpleXUIParser::readBoolValue(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- if (!strcmp(self.mCurAttributeValueBegin, "true"))
+ if (!strcmp(self.mCurAttributeValueBegin.c_str(), "true"))
{
*((bool*)val_ptr) = true;
return true;
}
- else if (!strcmp(self.mCurAttributeValueBegin, "false"))
+ else if (!strcmp(self.mCurAttributeValueBegin.c_str(), "false"))
{
*((bool*)val_ptr) = false;
return true;
@@ -1665,56 +1665,56 @@ bool LLSimpleXUIParser::readBoolValue(Parser& parser, void* val_ptr)
bool LLSimpleXUIParser::readStringValue(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- *((std::string*)val_ptr) = self.mCurAttributeValueBegin;
+ *((std::string*)val_ptr) = std::move(self.mCurAttributeValueBegin);
return true;
}
bool LLSimpleXUIParser::readU8Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U8*)val_ptr)]).full;
+ return parse(self.mCurAttributeValueBegin.c_str(), uint_p[assign_a(*(U8*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readS8Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S8*)val_ptr)]).full;
+ return parse(self.mCurAttributeValueBegin.c_str(), int_p[assign_a(*(S8*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readU16Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U16*)val_ptr)]).full;
+ return parse(self.mCurAttributeValueBegin.c_str(), uint_p[assign_a(*(U16*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readS16Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S16*)val_ptr)]).full;
+ return parse(self.mCurAttributeValueBegin.c_str(), int_p[assign_a(*(S16*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readU32Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U32*)val_ptr)]).full;
+ return parse(self.mCurAttributeValueBegin.c_str(), uint_p[assign_a(*(U32*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readS32Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S32*)val_ptr)]).full;
+ return parse(self.mCurAttributeValueBegin.c_str(), int_p[assign_a(*(S32*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readF32Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F32*)val_ptr)]).full;
+ return parse(self.mCurAttributeValueBegin.c_str(), real_p[assign_a(*(F32*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readF64Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F64*)val_ptr)]).full;
+ return parse(self.mCurAttributeValueBegin.c_str(), real_p[assign_a(*(F64*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readColor4Value(Parser& parser, void* val_ptr)
@@ -1722,7 +1722,7 @@ bool LLSimpleXUIParser::readColor4Value(Parser& parser, void* val_ptr)
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
LLColor4 value;
- if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
+ if (parse(self.mCurAttributeValueBegin.c_str(), real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
{
*(LLColor4*)(val_ptr) = value;
return true;
@@ -1736,7 +1736,7 @@ bool LLSimpleXUIParser::readUIColorValue(Parser& parser, void* val_ptr)
LLColor4 value;
LLUIColor* colorp = (LLUIColor*)val_ptr;
- if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
+ if (parse(self.mCurAttributeValueBegin.c_str(), real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
{
colorp->set(value);
return true;
@@ -1749,7 +1749,7 @@ bool LLSimpleXUIParser::readUUIDValue(Parser& parser, void* val_ptr)
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
LLUUID temp_id;
// LLUUID::set is destructive, so use temporary value
- if (temp_id.set(std::string(self.mCurAttributeValueBegin)))
+ if (temp_id.set(self.mCurAttributeValueBegin))
{
*(LLUUID*)(val_ptr) = temp_id;
return true;
diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h
index 2179ae54d3..3cc564772e 100644
--- a/indra/llui/llxuiparser.h
+++ b/indra/llui/llxuiparser.h
@@ -40,7 +40,7 @@ class LLView;
// lookup widget type by name
class LLWidgetTypeRegistry
-: public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry>
+: public LLRegistrySingleton<std::string, std::type_index, LLWidgetTypeRegistry>
{
LLSINGLETON_EMPTY_CTOR(LLWidgetTypeRegistry);
};
@@ -52,7 +52,7 @@ typedef std::function<LLView* (LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o
typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t;
class LLChildRegistryRegistry
-: public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry>
+: public LLRegistrySingleton<std::type_index, widget_registry_t, LLChildRegistryRegistry>
{
LLSINGLETON_EMPTY_CTOR(LLChildRegistryRegistry);
};
@@ -247,7 +247,7 @@ private:
S32 mCurReadDepth;
std::string mCurFileName;
std::string mTextContents;
- const char* mCurAttributeValueBegin;
+ std::string mCurAttributeValueBegin;
std::vector<S32> mTokenSizeStack;
std::vector<std::string> mScope;
std::vector<bool> mEmptyLeafNode;
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index d780b1d606..72e0b4fdf6 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -749,12 +749,17 @@ void LLWebRTCImpl::intSetMute(bool mute, int delay_ms)
{
mPeerCustomProcessor->setGain(mMute ? 0.0f : mGain);
}
+
+ // Sequence counter to prevent race conditions from rapid requests to mute/unmute
+ static std::atomic<uint32_t> mute_sequence(0);
+ uint32_t current_sequence = ++mute_sequence;
+
if (mMute)
{
mWorkerThread->PostDelayedTask(
- [this]
+ [this, current_sequence]
{
- if (mDeviceModule)
+ if (mDeviceModule && (current_sequence == mute_sequence.load()))
{
mDeviceModule->ForceStopRecording();
}
@@ -764,9 +769,9 @@ void LLWebRTCImpl::intSetMute(bool mute, int delay_ms)
else
{
mWorkerThread->PostTask(
- [this]
+ [this, current_sequence]
{
- if (mDeviceModule)
+ if (mDeviceModule && (current_sequence == mute_sequence.load()))
{
mDeviceModule->InitRecording();
mDeviceModule->ForceStartRecording();
@@ -1547,6 +1552,57 @@ void LLWebRTCPeerConnectionImpl::unsetDataObserver(LLWebRTCDataObserver* observe
}
}
+class LLStatsCollectorCallback : public webrtc::RTCStatsCollectorCallback
+{
+public:
+ typedef std::function<void(const LLWebRTCStatsMap&)> StatsCallback;
+
+ LLStatsCollectorCallback(StatsCallback callback) : callback_(callback) {}
+
+ void OnStatsDelivered(const webrtc::scoped_refptr<const webrtc::RTCStatsReport>& report) override
+ {
+ if (callback_)
+ {
+ // Transform RTCStatsReport stats to simple map
+ LLWebRTCStatsMap stats_map;
+ for (const auto& stats : *report)
+ {
+ std::map<std::string, std::string> stat_attributes;
+
+ // Convert each attribute to string format
+ for (const auto& attribute : stats.Attributes())
+ {
+ stat_attributes[attribute.name()] = attribute.ToString();
+ }
+ stats_map[stats.id()] = stat_attributes;
+ }
+ callback_(stats_map);
+ }
+ }
+
+private:
+ StatsCallback callback_;
+};
+
+void LLWebRTCPeerConnectionImpl::gatherConnectionStats()
+{
+ if (!mPeerConnection)
+ {
+ return;
+ }
+
+ auto stats_callback = webrtc::make_ref_counted<LLStatsCollectorCallback>(
+ [this](const LLWebRTCStatsMap& generic_stats)
+ {
+ for (auto& observer : mSignalingObserverList)
+ {
+ observer->OnStatsDelivered(generic_stats);
+ }
+ });
+
+ mPeerConnection->GetStats(stats_callback.get());
+}
+
LLWebRTCImpl * gWebRTCImpl = nullptr;
LLWebRTCDeviceInterface * getDeviceInterface()
{
diff --git a/indra/llwebrtc/llwebrtc.h b/indra/llwebrtc/llwebrtc.h
index 7d06b7d2b4..e76e708f0c 100644
--- a/indra/llwebrtc/llwebrtc.h
+++ b/indra/llwebrtc/llwebrtc.h
@@ -38,6 +38,7 @@
#ifndef LLWEBRTC_H
#define LLWEBRTC_H
+#include <map>
#include <string>
#include <vector>
@@ -55,6 +56,7 @@
namespace llwebrtc
{
+typedef std::map<std::string, std::map<std::string, std::string>> LLWebRTCStatsMap;
class LLWebRTCLogCallback
{
@@ -240,6 +242,8 @@ class LLWebRTCSignalingObserver
// Called when the data channel has been established and data
// transfer can begin.
virtual void OnDataChannelReady(LLWebRTCDataInterface *data_interface) = 0;
+
+ virtual void OnStatsDelivered(const LLWebRTCStatsMap& stats_data) {}
};
// LLWebRTCPeerConnectionInterface representsd a connection to a peer,
@@ -273,6 +277,8 @@ class LLWebRTCPeerConnectionInterface
virtual void unsetSignalingObserver(LLWebRTCSignalingObserver* observer) = 0;
virtual void AnswerAvailable(const std::string &sdp) = 0;
+
+ virtual void gatherConnectionStats() = 0;
};
// The following define the dynamic linked library
diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h
index 9d3af985ef..ab77c6c997 100644
--- a/indra/llwebrtc/llwebrtc_impl.h
+++ b/indra/llwebrtc/llwebrtc_impl.h
@@ -658,6 +658,8 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
void enableSenderTracks(bool enable);
void enableReceiverTracks(bool enable);
+ void gatherConnectionStats() override;
+
protected:
LLWebRTCImpl * mWebRTCImpl;
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 562a30e8d1..34643d5f5c 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -157,9 +157,12 @@ LLControlVariable::LLControlVariable(const std::string& name, eControlType type,
{
if ((persist != PERSIST_NO) && mComment.empty())
{
- // File isn't actually missing, but something is wrong with it
- // so the main point is to warn user to reinstall
- LLError::LLUserWarningMsg::showMissingFiles();
+ std::string error_string =
+ "Second Life failed to initialize settings. Setting " + mName + " is invalid. "
+ "Either settings' files were supplied incorrectly or default files were corrupted."
+ "\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and "
+ "contact https://support.secondlife.com if issue persists after reinstall.";
+ LLError::LLUserWarningMsg::show(error_string);
LL_ERRS() << "Must supply a comment for control " << mName << LL_ENDL;
}
//Push back versus setValue'ing here, since we don't want to call a signal yet
@@ -758,6 +761,7 @@ void LLControlGroup::setUntypedValue(std::string_view name, const LLSD& val)
// Returns number of controls loaded, so 0 if failure
U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, bool require_declaration, eControlType declare_as)
{
+ LL_PROFILE_ZONE_SCOPED;
std::string name;
LLXmlTree xml_controls;
@@ -990,8 +994,9 @@ U32 LLControlGroup::saveToFile(const std::string& filename, bool nondefault_only
return num_saved;
}
-U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values)
+U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values, bool error_when_no_comment)
{
+ LL_PROFILE_ZONE_SCOPED;
LLSD settings;
llifstream infile;
infile.open(filename.c_str());
@@ -1105,10 +1110,26 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
}
}
+ std::string comment = control_map["Comment"].asString();
+ if (!error_when_no_comment
+ && !set_default_values
+ && comment.empty())
+ {
+ // Only error for default settings that should remind the developer to provide comments
+ // and otherwise indicate a problem with viewer's files.
+ // But permit this minor transgression in user's files.
+ // Otherwise user might have a hard time figuring out source of the error or how to fix it.
+ // Instead make setting to not persist so that unrecognized invalid settings won't be saved
+ // for the next run.
+ persist = LLControlVariable::PERSIST_NO;
+ comment = "Comment not provided, setting won't persist";
+ LL_WARNS() << "Control " << name << " is missing a comment value. Setting will be marked as PERSIST_NO" << LL_ENDL;
+ }
+
declareControl(name,
typeStringToEnum(control_map["Type"].asString()),
control_map["Value"],
- control_map["Comment"].asString(),
+ comment,
persist,
hidefromsettingseditor
);
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index da7268bf45..5aa2b9715e 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -33,8 +33,10 @@
#include "llrect.h"
#include "llrefcount.h"
#include "llinstancetracker.h"
+#include "llstl.h"
#include <functional>
+#include <unordered_map>
#include <vector>
#include <boost/signals2.hpp>
@@ -165,7 +167,7 @@ class LLControlGroup : public LLInstanceTracker<LLControlGroup, std::string>
LOG_CLASS(LLControlGroup);
protected:
- typedef std::map<std::string, LLControlVariablePtr, std::less<> > ctrl_name_table_t;
+ using ctrl_name_table_t = std::unordered_map<std::string, LLControlVariablePtr, ll::string_hash, std::equal_to<>>;
ctrl_name_table_t mNameTable;
static const std::string mTypeString[TYPE_COUNT];
@@ -278,7 +280,7 @@ public:
// as the given type.
U32 loadFromFileLegacy(const std::string& filename, bool require_declaration = true, eControlType declare_as = TYPE_STRING);
U32 saveToFile(const std::string& filename, bool nondefault_only);
- U32 loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true);
+ U32 loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true, bool error_when_no_comment = true);
void resetToDefaults();
void incrCount(std::string_view name);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e609416dc1..e364c91e6d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -205,7 +205,6 @@ set(viewer_SOURCE_FILES
llfloateravatartextures.cpp
llfloaterbanduration.cpp
llfloaterbeacons.cpp
- llfloaterbigpreview.cpp
llfloaterbuildoptions.cpp
llfloaterbulkpermission.cpp
llfloaterbulkupload.cpp
@@ -289,7 +288,6 @@ set(viewer_SOURCE_FILES
llfloaterpay.cpp
llfloaterperformance.cpp
llfloaterperms.cpp
- llfloaterpostprocess.cpp
llfloaterprofile.cpp
llfloaterpreference.cpp
llfloaterpreferencesgraphicsadvanced.cpp
@@ -314,7 +312,6 @@ set(viewer_SOURCE_FILES
llfloatersidepanelcontainer.cpp
llfloaterslapptest.cpp
llfloatersnapshot.cpp
- llfloatersounddevices.cpp
llfloaterspellchecksettings.cpp
llfloatertelehub.cpp
llfloatertestinspectors.cpp
@@ -326,7 +323,6 @@ set(viewer_SOURCE_FILES
llfloatertranslationsettings.cpp
llfloateruipreview.cpp
llfloaterurlentry.cpp
- llfloatervoiceeffect.cpp
llfloatervoicevolume.cpp
llfloaterwebcontent.cpp
llfloaterwhitelistentry.cpp
@@ -429,6 +425,7 @@ set(viewer_SOURCE_FILES
llfloaterimnearbychat.cpp
llfloaterimnearbychathandler.cpp
llfloaterimnearbychatlistener.cpp
+ llnearbyvoicemoderation.cpp
llnetmap.cpp
llnotificationalerthandler.cpp
llnotificationgrouphandler.cpp
@@ -522,7 +519,6 @@ set(viewer_SOURCE_FILES
llpanelsnapshotprofile.cpp
llpanelteleporthistory.cpp
llpaneltiptoast.cpp
- llpanelvoiceeffect.cpp
llpaneltopinfobar.cpp
llpanelpulldown.cpp
llpanelvoicedevicesettings.cpp
@@ -899,7 +895,6 @@ set(viewer_HEADER_FILES
llfloateravatartextures.h
llfloaterbanduration.h
llfloaterbeacons.h
- llfloaterbigpreview.h
llfloaterbuildoptions.h
llfloaterbulkpermission.h
llfloaterbulkupload.h
@@ -987,7 +982,6 @@ set(viewer_HEADER_FILES
llfloaterpay.h
llfloaterperformance.h
llfloaterperms.h
- llfloaterpostprocess.h
llfloaterprofile.h
llfloaterpreference.h
llfloaterpreferencesgraphicsadvanced.h
@@ -1012,7 +1006,6 @@ set(viewer_HEADER_FILES
llfloatersidepanelcontainer.h
llfloaterslapptest.h
llfloatersnapshot.h
- llfloatersounddevices.h
llfloaterspellchecksettings.h
llfloatertelehub.h
llfloatertestinspectors.h
@@ -1024,7 +1017,6 @@ set(viewer_HEADER_FILES
llfloatertranslationsettings.h
llfloateruipreview.h
llfloaterurlentry.h
- llfloatervoiceeffect.h
llfloatervoicevolume.h
llfloaterwebcontent.h
llfloaterwhitelistentry.h
@@ -1121,6 +1113,7 @@ set(viewer_HEADER_FILES
llnameeditor.h
llnamelistctrl.h
llnavigationbar.h
+ llnearbyvoicemoderation.h
llnetmap.h
llnotificationhandler.h
llnotificationlistitem.h
@@ -1206,7 +1199,6 @@ set(viewer_HEADER_FILES
llpaneltiptoast.h
llpanelpulldown.h
llpanelvoicedevicesettings.h
- llpanelvoiceeffect.h
llpaneltopinfobar.h
llpanelvolume.h
llpanelvolumepulldown.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 2aaedf9944..b7397ce158 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-26.1.0
+26.2.0
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index dd644b6e30..6d006997c5 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -511,6 +511,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RecentJumpThresholdSecs</key>
+ <map>
+ <key>Comment</key>
+ <string>Seconds after a jump input during which finish-anim is suppressed to avoid interrupting rapid successive jumps.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
<key>AvatarAxisDeadZone0</key>
<map>
<key>Comment</key>
@@ -4624,6 +4635,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>MapShowGridCoords</key>
+ <map>
+ <key>Comment</key>
+ <string>Shows/hides the grid coordinates of each region on the world map.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>MiniMapAutoCenter</key>
<map>
<key>Comment</key>
@@ -6137,6 +6159,39 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>OpenDebugStatVoice</key>
+ <map>
+ <key>Comment</key>
+ <string>Expand Voice (WebRTC) stats display</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>OpenDebugStatVoiceOutgoing</key>
+ <map>
+ <key>Comment</key>
+ <string>Expand Outgoing audio (Voice) stats display</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>OpenDebugStatVoiceIncoming</key>
+ <map>
+ <key>Comment</key>
+ <string>Expand Incoming audio (Voice) stats display</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>OutBandwidth</key>
<map>
<key>Comment</key>
@@ -10767,6 +10822,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>GroupTitlesTagMode</key>
+ <map>
+ <key>Comment</key>
+ <string>Select Group Titles tag mode: 0 - no group tags, 1 - only my group tag, 2 - all group tags</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>2</integer>
+ </map>
<key>ShowAxes</key>
<map>
<key>Comment</key>
@@ -17127,6 +17193,39 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>InventoryShowRecentTab</key>
+ <map>
+ <key>Comment</key>
+ <string>Show/hide Recent tab in the Inventory floater</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>InventoryShowWornTab</key>
+ <map>
+ <key>Comment</key>
+ <string>Show/hide Worn tab in the Inventory floater</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>InventoryShowFavoritesTab</key>
+ <map>
+ <key>Comment</key>
+ <string>Show/hide Favorites tab in the Inventory floater</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>StatsReportMaxDuration</key>
<map>
<key>Comment</key>
@@ -17281,5 +17380,16 @@
<key>Value</key>
<integer>2</integer>
</map>
+ <key>PurgeDiskCacheOnStartup</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not to LRU purge the disk cache during startup on main thread</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
index dd9e883fdf..abe61fe892 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
@@ -146,6 +146,9 @@ vec3 srgb_to_linear(vec3 c);
void main()
{
vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
+
+ basecolor.a *= vertex_color.a;
+
if (basecolor.a < minimum_alpha)
{
discard;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index 50b40e9c20..b08193a7dd 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -51,9 +51,7 @@ in vec3 vary_norm;
in vec4 vertex_color; //vertex color should be treated as sRGB
#endif
-#ifdef HAS_ALPHA_MASK
uniform float minimum_alpha;
-#endif
uniform mat4 proj_mat;
uniform mat4 inv_proj;
@@ -225,6 +223,13 @@ void main()
float final_alpha = diffuse_linear.a;
+#ifdef IS_AVATAR_SKIN
+ if(final_alpha < minimum_alpha)
+ {
+ discard;
+ }
+#endif
+
#ifdef USE_VERTEX_COLOR
final_alpha *= vertex_color.a;
diff --git a/indra/newview/gltf/asset.cpp b/indra/newview/gltf/asset.cpp
index a2f9cd2852..d44aa9d72c 100644
--- a/indra/newview/gltf/asset.cpp
+++ b/indra/newview/gltf/asset.cpp
@@ -1027,6 +1027,12 @@ bool Image::prepImpl(Asset& asset, const LLUUID& id)
std::string dir = gDirUtilp->getDirName(asset.mFilename);
std::string img_file = dir + gDirUtilp->getDirDelimiter() + mUri;
+ if (!gDirUtilp->fileExists(img_file))
+ {
+ // URI might be escaped, unescape.
+ img_file = dir + gDirUtilp->getDirDelimiter() + LLURI::unescape(mUri);
+ }
+
LLUUID tracking_id = LLLocalBitmapMgr::getInstance()->addUnit(img_file);
if (tracking_id.notNull() && mLoadIntoTexturePipe)
{
diff --git a/indra/newview/gltf/buffer_util.h b/indra/newview/gltf/buffer_util.h
index c231443a9e..53dee98cd1 100644
--- a/indra/newview/gltf/buffer_util.h
+++ b/indra/newview/gltf/buffer_util.h
@@ -141,6 +141,42 @@ namespace LL
}
template<>
+ inline void copyScalar<U32, LLVector4a>(U32* src, LLVector4a& dst)
+ {
+ dst.set((F32)*src, 0.f, 0.f, 0.f);
+ }
+
+ template<>
+ inline void copyScalar<U16, LLVector4a>(U16* src, LLVector4a& dst)
+ {
+ dst.set((F32)*src, 0.f, 0.f, 0.f);
+ }
+
+ template<>
+ inline void copyScalar<U8, LLVector4a>(U8* src, LLVector4a& dst)
+ {
+ dst.set((F32)*src, 0.f, 0.f, 0.f);
+ }
+
+ template<>
+ inline void copyScalar<U32, LLVector2>(U32* src, LLVector2& dst)
+ {
+ dst.set((F32)*src, 0.f);
+ }
+
+ template<>
+ inline void copyScalar<U16, LLVector2>(U16* src, LLVector2& dst)
+ {
+ dst.set((F32)*src, 0.f);
+ }
+
+ template<>
+ inline void copyScalar<U8, LLVector2>(U8* src, LLVector2& dst)
+ {
+ dst.set((F32)*src, 0.f);
+ }
+
+ template<>
inline void copyVec2<F32, LLVector2>(F32* src, LLVector2& dst)
{
dst.set(src[0], src[1]);
@@ -221,6 +257,12 @@ namespace LL
}
template<>
+ inline void copyVec4<U32, LLVector4a>(U32* src, LLVector4a& dst)
+ {
+ dst.set((F32)src[0], (F32)src[1], (F32)src[2], (F32)src[3]);
+ }
+
+ template<>
inline void copyVec4<U16, LLVector4a>(U16* src, LLVector4a& dst)
{
dst.set(src[0], src[1], src[2], src[3]);
@@ -373,7 +415,7 @@ namespace LL
}
else
{
- LL_ERRS("GLTF") << "Unsupported accessor type" << LL_ENDL;
+ LL_ERRS("GLTF") << "Unsupported accessor type " << (S32)accessor.mType << LL_ENDL;
}
}
diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp
index 3a1d8079a9..5a94a2c6c6 100644
--- a/indra/newview/gltf/llgltfloader.cpp
+++ b/indra/newview/gltf/llgltfloader.cpp
@@ -440,7 +440,25 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>
(LLModel::NO_ERRORS == pModel->getStatus()) &&
validate_model(pModel))
{
- mTransform.setIdentity();
+ // Build the scene transform.
+ // Non-skinned meshes: scene transform carries coord rotation + hierarchy,
+ // preserving the object's rotation/position/scale for upload.
+ // Skinned meshes: transform is already baked into vertices, so scene is identity.
+ if (node.mSkin >= 0)
+ {
+ mTransform.setIdentity();
+ }
+ else
+ {
+ glm::mat4 hierarchy_transform;
+ computeCombinedNodeTransform(mGLTFAsset, node_idx, hierarchy_transform);
+ glm::mat4 combined = coord_system_rotation * hierarchy_transform;
+ if (mApplyXYRotation)
+ {
+ combined = coord_system_rotationxy * combined;
+ }
+ mTransform = LLMatrix4(glm::value_ptr(combined));
+ }
transformation = mTransform;
// adjust the transformation to compensate for mesh normalization
@@ -684,7 +702,12 @@ std::string LLGLTFLoader::processTexture(std::string& full_path_out, S32 texture
// Process embedded textures
if (image.mBufferView >= 0)
{
- return extractTextureToTempFile(texture_index, texture_type);
+ std::string temp_path = extractTextureToTempFile(texture_index, texture_type);
+ if (!temp_path.empty())
+ {
+ full_path_out = temp_path;
+ }
+ return temp_path;
}
return "";
@@ -734,23 +757,47 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const std::string& bas
S32 skinIdx = nodeno.mSkin;
- // Compute final combined transform matrix (hierarchy + coordinate rotation)
+ // Compute the vertex transform for this mesh.
+ // Non-skinned meshes: vertices are left untransformed; the node's hierarchy transform
+ // (rotation, translation, scale) is stored in the scene transform instead, matching
+ // the DAE loader. This ensures the uploaded object's bounding box and transform
+ // properties are correct. See: https://github.com/secondlife/viewer/issues/5431
+ // Skinned meshes: coord rotation + hierarchy are baked into vertex positions because
+ // inverse bind matrices and skin weights are already computed in that space.
+ // TODO: consider aligning skinned meshes with the DAE loader (scene transform instead
+ // of vertex baking), which would require adjusting inverse bind matrices, bind shape
+ // matrix, and weight keying to match.
S32 node_index = static_cast<S32>(&nodeno - &mGLTFAsset.mNodes[0]);
glm::mat4 hierarchy_transform;
computeCombinedNodeTransform(mGLTFAsset, node_index, hierarchy_transform);
- // Combine transforms: coordinate rotation applied to hierarchy transform
- glm::mat4 final_transform = coord_system_rotation * hierarchy_transform;
- if (mApplyXYRotation)
+ glm::mat4 vertex_transform;
+ if (skinIdx >= 0)
{
- final_transform = coord_system_rotationxy * final_transform;
+ // Skinned mesh: bake coord rotation + hierarchy into vertices.
+ // Inverse bind matrices and skin weights depend on this transform being applied.
+ vertex_transform = coord_system_rotation * hierarchy_transform;
+ if (mApplyXYRotation)
+ {
+ vertex_transform = coord_system_rotationxy * vertex_transform;
+ }
+ }
+ else
+ {
+ // Non-skinned mesh: don't apply any transform to vertices.
+ // The hierarchy transform will be stored in the scene transform matrix.
+ vertex_transform = glm::mat4(1.0f); // identity
}
// Check if we have a negative scale (flipped coordinate system)
- bool hasNegativeScale = glm::determinant(final_transform) < 0.0f;
+ // coord_system_rotation and coord_system_rotationxy are pure rotations (det=1),
+ // so negative scale depends only on the hierarchy transform.
+ bool hasNegativeScale = glm::determinant(hierarchy_transform) < 0.0f;
+
+ bool hasVertexTransform = (vertex_transform != glm::mat4(1.0f));
// Pre-compute normal transform matrix (transpose of inverse of upper-left 3x3)
- const glm::mat3 normal_transform = glm::transpose(glm::inverse(glm::mat3(final_transform)));
+ const glm::mat3 normal_transform = glm::transpose(glm::inverse(glm::mat3(vertex_transform)));
// Mark unsuported joints with '-1' so that they won't get added into weights
// GLTF maps all joints onto all meshes. Gather use count per mesh to cut unused ones.
@@ -803,30 +850,49 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const std::string& bas
return false; // Skip this primitive
}
- // Apply the global scale and center offset to all vertices
+ // Apply vertex transform (if any) to all vertices.
+ // Skinned meshes: this bakes coord rotation + hierarchy into vertices.
+ // Non-skinned meshes: vertex_transform is identity (no baking).
for (U32 i = 0; i < prim.getVertexCount(); i++)
{
- // Use pre-computed final_transform
- glm::vec4 pos(prim.mPositions[i][0], prim.mPositions[i][1], prim.mPositions[i][2], 1.0f);
- glm::vec4 transformed_pos = final_transform * pos;
-
GLTFVertex vert;
- vert.position = glm::vec3(transformed_pos);
- if (!prim.mNormals.empty())
+ if (hasVertexTransform)
{
- // Use pre-computed normal_transform
- glm::vec3 normal_vec(prim.mNormals[i][0], prim.mNormals[i][1], prim.mNormals[i][2]);
- vert.normal = glm::normalize(normal_transform * normal_vec);
+ glm::vec4 pos(prim.mPositions[i][0], prim.mPositions[i][1], prim.mPositions[i][2], 1.0f);
+ glm::vec4 transformed_pos = vertex_transform * pos;
+ vert.position = glm::vec3(transformed_pos);
+
+ if (!prim.mNormals.empty())
+ {
+ glm::vec3 normal_vec(prim.mNormals[i][0], prim.mNormals[i][1], prim.mNormals[i][2]);
+ vert.normal = glm::normalize(normal_transform * normal_vec);
+ }
+ else
+ {
+ vert.normal = glm::normalize(normal_transform * glm::vec3(0.0f, 0.0f, 1.0f));
+ LL_DEBUGS("GLTF_IMPORT") << "No normals found for primitive, using default normal." << LL_ENDL;
+ }
}
else
{
- // Use default normal (pointing up in model space)
- vert.normal = glm::normalize(normal_transform * glm::vec3(0.0f, 0.0f, 1.0f));
- LL_DEBUGS("GLTF_IMPORT") << "No normals found for primitive, using default normal." << LL_ENDL;
+ // No transform: store raw GLTF positions and normals.
+ // The scene transform will carry coord rotation + hierarchy.
+ vert.position = glm::vec3(prim.mPositions[i][0], prim.mPositions[i][1], prim.mPositions[i][2]);
+
+ if (!prim.mNormals.empty())
+ {
+ vert.normal = glm::vec3(prim.mNormals[i][0], prim.mNormals[i][1], prim.mNormals[i][2]);
+ }
+ else
+ {
+ vert.normal = glm::vec3(0.0f, 0.0f, 1.0f);
+ LL_DEBUGS("GLTF_IMPORT") << "No normals found for primitive, using default normal." << LL_ENDL;
+ }
}
- vert.uv0 = glm::vec2(prim.mTexCoords0[i][0], -prim.mTexCoords0[i][1]);
+ // Flip texture V coordinate
+ vert.uv0 = glm::vec2(prim.mTexCoords0[i][0], 1.f - prim.mTexCoords0[i][1]);
if (skinIdx >= 0)
{
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 0e36698018..ae40e8830f 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -767,8 +767,21 @@ Function un.UserSettingsFiles
StrCmp $DO_UNINSTALL_V2 "true" Keep # Don't remove user's settings files on auto upgrade
-# Ask if user wants to keep data files or not
-MessageBox MB_YESNO|MB_ICONQUESTION $(RemoveDataFilesMB) IDYES Remove IDNO Keep
+ClearErrors
+Push $0
+${GetParameters} $COMMANDLINE
+${GetOptionsS} $COMMANDLINE "/clrusrfiles" $0
+# GetOptionsS returns an error if option does not exist, jump past Goto.
+IfErrors +3 0
+ Pop $0
+ Goto Remove
+
+Pop $0
+ClearErrors
+
+ifSilent Keep 0
+ # Ask if user wants to keep data files or not
+ MessageBox MB_YESNO|MB_ICONQUESTION $(RemoveDataFilesMB) IDYES Remove IDNO Keep
Remove:
Push $0
@@ -864,11 +877,25 @@ RMDir "$INSTDIR"
IfFileExists "$INSTDIR" FOLDERFOUND NOFOLDER
FOLDERFOUND:
+ifSilent NOFOLDER 0
MessageBox MB_OK $(DeleteProgramFilesMB) /SD IDOK IDOK NOFOLDER
NOFOLDER:
-MessageBox MB_YESNO $(DeleteRegistryKeysMB) IDYES DeleteKeys IDNO NoDelete
+ClearErrors
+Push $0
+${GetParameters} $COMMANDLINE
+${GetOptionsS} $COMMANDLINE "/clearreg" $0
+# GetOptionsS returns an error if option does not exist, jump past Goto.
+IfErrors +3 0
+ Pop $0
+ Goto DeleteKeys
+
+Pop $0
+ClearErrors
+
+ifSilent NoDelete 0
+ MessageBox MB_YESNO $(DeleteRegistryKeysMB) IDYES DeleteKeys IDNO NoDelete
DeleteKeys:
DeleteRegKey SHELL_CONTEXT "SOFTWARE\Classes\x-grid-location-info"
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index aa620625ea..23647487b0 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -430,6 +430,7 @@ LLAgent::LLAgent() :
mIsDoNotDisturb(false),
mControlFlags(0x00000000),
+ mLastJumpInputTime(0.0),
mAutoPilot(false),
mAutoPilotFlyOnStop(false),
@@ -784,6 +785,10 @@ void LLAgent::moveUp(S32 direction)
if (direction > 0)
{
+ if (!getFlying())
+ {
+ mLastJumpInputTime = LLTimer::getTotalSeconds();
+ }
setControlFlags(AGENT_CONTROL_UP_POS | AGENT_CONTROL_FAST_UP);
}
else if (direction < 0)
@@ -2677,7 +2682,21 @@ void LLAgent::onAnimStop(const LLUUID& id)
}
else if (id == ANIM_AGENT_PRE_JUMP || id == ANIM_AGENT_LAND || id == ANIM_AGENT_MEDIUM_LAND)
{
- setControlFlags(AGENT_CONTROL_FINISH_ANIM);
+ // FIRE-34049/FIRE-34273/https://github.com/secondlife/viewer/issues/4218
+ // Avoid forcing AGENT_CONTROL_FINISH_ANIM, which can short-circuit the next pre-jump
+ // during rapid successive jumps.
+ // TODO: a more robust fix would require knowing which specific animation finished,
+ // information that is not currently provided by the simulator.
+ const bool up_pos = (mControlFlags & AGENT_CONTROL_UP_POS) != 0;
+ const F64 now = LLTimer::getTotalSeconds();
+ const F64 elapsed = now - mLastJumpInputTime;
+ static LLCachedControl<F32> recent_jump_threshold_secs(gSavedSettings, "RecentJumpThresholdSecs");
+ const bool recent_jump = (mLastJumpInputTime > 0.0) && (elapsed < recent_jump_threshold_secs);
+
+ if (!up_pos && !recent_jump)
+ {
+ setControlFlags(AGENT_CONTROL_FINISH_ANIM);
+ }
}
}
@@ -4864,6 +4883,8 @@ const std::string& LLAgent::getTeleportStateName() const
void LLAgent::parseTeleportMessages(const std::string& xml_filename)
{
+ LL_PROFILE_ZONE_SCOPED;
+
LLXMLNodePtr root;
bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index f5d928a1be..ddaa8dd68c 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -500,6 +500,7 @@ private:
S32 mControlsTakenCount[TOTAL_CONTROLS];
S32 mControlsTakenPassedOnCount[TOTAL_CONTROLS];
U32 mControlFlags; // Replacement for the mFooKey's
+ F64 mLastJumpInputTime; // Time of last jump input (key-down) in seconds from LLTimer::getTotalSeconds()
//--------------------------------------------------------------------
// Animations
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index b6d31c0cae..369a6d3697 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -975,6 +975,10 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM);
}
}
+ else
+ {
+ new_distance = llmin(new_distance, getCameraMaxZoomDistance());
+ }
mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
}
@@ -1035,6 +1039,10 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters)
new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM);
}
}
+ else
+ {
+ new_distance = llmin(new_distance, getCameraMaxZoomDistance());
+ }
// Compute new camera offset
mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index 9c76f56ef3..f67f2688a1 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -1019,6 +1019,9 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
}
//-------------------------------------------------------------------------
+U32 AISUpdate::sBatchFrameCount = 0;
+LLTimer AISUpdate::sBatchTimer;
+
AISUpdate::AISUpdate(const LLSD& update, AISAPI::COMMAND_TYPE type, const LLSD& request_body)
: mType(type)
{
@@ -1036,8 +1039,16 @@ AISUpdate::AISUpdate(const LLSD& update, AISAPI::COMMAND_TYPE type, const LLSD&
mFetchDepth = request_body["depth"].asInteger();
}
- mTimer.setTimerExpirySec(AIS_EXPIRY_SECONDS);
- mTimer.start();
+ mTaskTimer.setTimerExpirySec(AIS_TASK_EXPIRY_SECONDS);
+ mTaskTimer.start();
+
+ U32 current_frame = LLFrameTimer::getFrameCount();
+ if (sBatchFrameCount != current_frame)
+ {
+ sBatchTimer.setTimerExpirySec(AIS_BATCH_EXPIRY_SECONDS);
+ sBatchTimer.start();
+ sBatchFrameCount = current_frame;
+ }
parseUpdate(update);
}
@@ -1058,7 +1069,7 @@ void AISUpdate::clearParseResults()
void AISUpdate::checkTimeout()
{
- if (mTimer.hasExpired())
+ if (mTaskTimer.hasExpired() || sBatchTimer.hasExpired())
{
// If we are taking too long, don't starve other tasks,
// yield to mainloop.
@@ -1067,7 +1078,16 @@ void AISUpdate::checkTimeout()
// a chance, so wait for a frame tick instead.
llcoro::suspendUntilNextFrame();
LLCoros::checkStop();
- mTimer.setTimerExpirySec(AIS_EXPIRY_SECONDS);
+ mTaskTimer.setTimerExpirySec(AIS_TASK_EXPIRY_SECONDS);
+
+ U32 current_frame = LLFrameTimer::getFrameCount();
+ if (sBatchFrameCount != current_frame)
+ {
+ // To give other tasks a chance batch timer
+ // has a longer delay.
+ sBatchTimer.setTimerExpirySec(AIS_BATCH_EXPIRY_SECONDS);
+ sBatchFrameCount = current_frame;
+ }
}
}
diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h
index cfc286da2e..1dab0dd1f9 100644
--- a/indra/newview/llaisapi.h
+++ b/indra/newview/llaisapi.h
@@ -130,9 +130,13 @@ private:
void clearParseResults();
void checkTimeout();
- // Fetch can return large packets of data, throttle it to not cause lags
- // Todo: make throttle work over all fetch requests isntead of per-request
- const F32 AIS_EXPIRY_SECONDS = 0.008f;
+ // Fetches can return large packets of data,
+ // throttle them individually to not get stuck
+ // on a single large task. And throttle sum total
+ // to not cause lags when multiple large fetches
+ // returned results.
+ const F32 AIS_TASK_EXPIRY_SECONDS = 0.008f;
+ const F32 AIS_BATCH_EXPIRY_SECONDS = 0.010f;
typedef std::map<LLUUID,size_t> uuid_int_map_t;
uuid_int_map_t mCatDescendentDeltas;
@@ -154,7 +158,9 @@ private:
uuid_list_t mCategoryIds;
bool mFetch;
S32 mFetchDepth;
- LLTimer mTimer;
+ LLTimer mTaskTimer;
+ static LLTimer sBatchTimer;
+ static U32 sBatchFrameCount;
AISAPI::COMMAND_TYPE mType;
};
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index f3265afebd..ece18fb5cc 100644
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -144,6 +144,8 @@ LLAppCoreHttp::~LLAppCoreHttp()
void LLAppCoreHttp::init()
{
+ LL_PROFILE_ZONE_SCOPED;
+
LLCoreHttpUtil::setPropertyMethods(
std::bind(&LLControlGroup::getBOOL, std::ref(gSavedSettings), std::placeholders::_1),
std::bind(&LLControlGroup::declareBOOL, std::ref(gSavedSettings), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, LLControlVariable::PERSIST_NONDFT));
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 05be94b488..7653ffe424 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -356,9 +356,6 @@ F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
S32 gPendingMetricsUploads = 0;
-
-bool gDisconnected = false;
-
// Used to restore texture state after a mode switch
LLFrameTimer gRestoreGLTimer;
bool gRestoreGL = false;
@@ -758,6 +755,8 @@ public:
bool LLAppViewer::init()
{
+ LL_PROFILE_ZONE_SCOPED;
+
setupErrorHandling(mSecondInstance);
//
@@ -959,6 +958,7 @@ bool LLAppViewer::init()
// Early out from user choice.
LL_WARNS("InitInfo") << "initHardwareTest() failed." << LL_ENDL;
// quit immediately
+ LL_PROFILER_FRAME_END;
return false;
}
LL_INFOS("InitInfo") << "Hardware test initialization done." << LL_ENDL ;
@@ -977,6 +977,7 @@ bool LLAppViewer::init()
OSMessageBox(msg.c_str(), LLStringUtil::null, OSMB_OK);
LL_WARNS("InitInfo") << "Failed to init cache" << LL_ENDL;
// quit immediately
+ LL_PROFILER_FRAME_END;
return false;
}
LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ;
@@ -1012,6 +1013,7 @@ bool LLAppViewer::init()
// Already handled with a MBVideoDrvErr
LL_WARNS("InitInfo") << "gGLManager.mHasRequirements is false." << LL_ENDL;
// quit immediately
+ LL_PROFILER_FRAME_END;
return false;
}
@@ -1025,6 +1027,7 @@ bool LLAppViewer::init()
OSMessageBox(msg.c_str(), LLStringUtil::null, OSMB_OK);
LL_WARNS("InitInfo") << "SSE2 is not supported" << LL_ENDL;
// quit immediately
+ LL_PROFILER_FRAME_END;
return false;
}
#endif
@@ -1295,7 +1298,7 @@ bool LLAppViewer::init()
gDirUtilp->deleteDirAndContents(gDirUtilp->getDumpLogsDirPath());
}
#endif
-
+ LL_PROFILER_FRAME_END;
return true;
}
@@ -2265,6 +2268,8 @@ void LLAppViewer::initGeneralThread()
bool LLAppViewer::initThreads()
{
+ LL_PROFILE_ZONE_SCOPED;
+
static const bool enable_threads = true;
LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
@@ -2544,7 +2549,10 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, file.file_name());
}
- if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent))
+ // Be softer for files in the user's folders, user can't just reinstall those
+ bool error_when_no_comment = !set_defaults && location_key != "User";
+
+ if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent, error_when_no_comment))
{ // success!
LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL;
}
@@ -3109,6 +3117,8 @@ bool LLAppViewer::initConfiguration()
// keeps growing, necessitating a method all its own.
void LLAppViewer::initStrings()
{
+ LL_PROFILE_ZONE_SCOPED;
+
std::string strings_file = "strings.xml";
std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);
if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))
@@ -3198,6 +3208,7 @@ void LLAppViewer::sendOutOfDiskSpaceNotification()
bool LLAppViewer::initWindow()
{
+ LL_PROFILE_ZONE_SCOPED;
LL_INFOS("AppInit") << "Initializing window..." << LL_ENDL;
// store setting in a global for easy access and modification
@@ -4440,6 +4451,7 @@ U32 LLAppViewer::getObjectCacheVersion()
bool LLAppViewer::initCache()
{
+ LL_PROFILE_ZONE_SCOPED;
mPurgeCache = false;
bool read_only = mSecondInstance;
LLAppViewer::getTextureCache()->setReadOnly(read_only) ;
@@ -4533,19 +4545,22 @@ bool LLAppViewer::initCache()
if (mPurgeCache)
{
- LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
- purgeCache();
+ LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
+ purgeCache();
// clear the new C++ file system based cache
LLDiskCache::getInstance()->clearCache();
- }
- else
+ }
+ else if (gSavedSettings.getBOOL("PurgeDiskCacheOnStartup"))
{
// purge excessive files from the new file system based cache
LLDiskCache::getInstance()->purge();
}
+
+ // Start disk cache purge thread to
+ // purge excessive files from the file system based cache
+ LLAppViewer::getPurgeDiskCacheThread()->start();
}
- LLAppViewer::getPurgeDiskCacheThread()->start();
LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache"));
@@ -4588,6 +4603,7 @@ void LLAppViewer::loadKeyBindings()
// As per GHI #4498, remove old, stale CEF cache folders from previous sessions
void LLAppViewer::purgeCefStaleCaches()
{
+ LL_PROFILE_ZONE_SCOPED;
// TODO: we really shouldn't use a hard coded name for the cache folder here...
const std::string browser_parent_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache");
if (LLFile::isdir(browser_parent_cache))
@@ -4615,7 +4631,19 @@ void LLAppViewer::purgeCacheImmediate()
{
LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL;
LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false);
- LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true);
+ if (LLVOCache::instanceExists())
+ {
+ LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true);
+ }
+ else if (!mSecondInstance)
+ {
+ // LLVOCache requires parameters to be initialized, if it's not there, try manually
+ std::string mask = "*";
+ std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "objectcache");
+ LL_INFOS() << "Removing cache at " << cache_dir << LL_ENDL;
+ gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files
+ LLFile::rmdir(cache_dir);
+ }
}
std::string LLAppViewer::getSecondLifeTitle() const
@@ -4783,6 +4811,8 @@ std::string get_name_cache_filename(const std::string &base_file, const std::str
void LLAppViewer::loadNameCache()
{
+ LL_PROFILE_ZONE_SCOPED;
+
// display names cache
std::string filename = get_name_cache_filename("avatar_name_cache", "xml");
LL_INFOS("AvNameCache") << filename << LL_ENDL;
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 6b0d3e0b27..e1119419af 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -417,8 +417,6 @@ extern S32 gPendingMetricsUploads;
extern F32 gSimLastTime;
extern F32 gSimFrames;
-extern bool gDisconnected;
-
extern LLFrameTimer gRestoreGLTimer;
extern bool gRestoreGL;
extern bool gUseWireframe;
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 6f6b89ea81..fb1426a235 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -29,8 +29,6 @@
#include "llavataractions.h"
-#include "boost/lambda/lambda.hpp" // for lambda::constant
-
#include "llavatarnamecache.h" // IDEVO
#include "llsd.h"
#include "llnotifications.h"
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index f6bc59c748..409952c496 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -47,7 +47,7 @@ S32 LLAvatarListItem::sLeftPadding = 0;
S32 LLAvatarListItem::sNameRightPadding = 0;
S32 LLAvatarListItem::sChildrenWidths[LLAvatarListItem::ALIC_COUNT];
-static LLWidgetNameRegistry::StaticRegistrar sRegisterAvatarListItemParams(&typeid(LLAvatarListItem::Params), "avatar_list_item");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterAvatarListItemParams(typeid(LLAvatarListItem::Params), "avatar_list_item");
LLAvatarListItem::Params::Params()
: default_style("default_style"),
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 76e308a966..2c9d74ed97 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -680,6 +680,8 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
LLNotifications::instance().add("RevokedModifyRights",args, payload);
}
}
+ // update modify permissions flags for affected objects
+ LLViewerObject::markObjectsForUpdate(agent_id);
(mBuddyInfo[agent_id])->setRightsFrom(new_rights);
}
}
diff --git a/indra/newview/llcapabilityprovider.h b/indra/newview/llcapabilityprovider.h
index 484bd2ef04..acc752588d 100644
--- a/indra/newview/llcapabilityprovider.h
+++ b/indra/newview/llcapabilityprovider.h
@@ -37,12 +37,12 @@
class LLCapabilityProvider
{
public:
- virtual ~LLCapabilityProvider() {}
+ virtual ~LLCapabilityProvider() = default;
/**
* Get a capability URL, given a capability name. Returns empty string if
* no such capability is defined on this provider.
*/
- virtual std::string getCapability(const std::string& name) const = 0;
+ virtual std::string getCapability(std::string_view name) const = 0;
/**
* Get host to which to send that capability request.
*/
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 47803edc73..6bd15d4b61 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -647,7 +647,7 @@ void LLCOFWearables::addClothingTypesDummies(const LLAppearanceMgr::wearables_by
for (U32 type = LLWearableType::WT_SHIRT; type < LLWearableType::WT_COUNT; type++)
{
- if (clothing_by_type[type].empty())
+ if (!clothing_by_type[type].empty())
continue;
LLWearableType::EType w_type = static_cast<LLWearableType::EType>(type);
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 99d770b6e2..2297fddf0c 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -59,11 +59,18 @@ public:
virtual void onChange(EStatusType status, const LLSD& channelInfo, bool proximal)
{
+ bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
conversation->showVoiceIndicator(conversation
&& status != STATUS_JOINING
&& status != STATUS_LEFT_CHANNEL
- && LLVoiceClient::getInstance()->voiceEnabled()
- && LLVoiceClient::getInstance()->isVoiceWorking());
+ && voice_enabled);
+
+ static bool s_voice_enabled(false);
+ if (s_voice_enabled != voice_enabled)
+ {
+ s_voice_enabled = voice_enabled;
+ conversation->updateConversationIndicators();
+ }
}
private:
@@ -509,11 +516,25 @@ void LLConversationViewSession::refresh()
// Update all speaking indicators
LLSpeakingIndicatorManager::updateSpeakingIndicators();
+ updateConversationIndicators();
+
+ requestArrange();
+ if (vmi)
+ {
+ // Do the regular upstream refresh
+ LLFolderViewFolder::refresh();
+ }
+}
+
+void LLConversationViewSession::updateConversationIndicators()
+{
+ bool is_active_channel = isInActiveVoiceChannel();
+
// we should show indicator for specified voice session only if this is current channel. EXT-5562.
if (mSpeakingIndicator)
{
- mSpeakingIndicator->setIsActiveChannel(mIsInActiveVoiceChannel);
- mSpeakingIndicator->setShowParticipantsSpeaking(mIsInActiveVoiceChannel);
+ mSpeakingIndicator->setIsActiveChannel(is_active_channel);
+ mSpeakingIndicator->setShowParticipantsSpeaking(is_active_channel);
}
LLConversationViewParticipant* participant = NULL;
@@ -523,16 +544,9 @@ void LLConversationViewSession::refresh()
participant = dynamic_cast<LLConversationViewParticipant*>(*iter);
if (participant)
{
- participant->allowSpeakingIndicator(mIsInActiveVoiceChannel);
+ participant->allowSpeakingIndicator(is_active_channel);
}
}
-
- requestArrange();
- if (vmi)
- {
- // Do the regular upstream refresh
- LLFolderViewFolder::refresh();
- }
}
void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& session_id)
@@ -543,7 +557,7 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
{
bool old_value = mIsInActiveVoiceChannel;
mIsInActiveVoiceChannel = vmi->getUUID() == session_id;
- mCallIconLayoutPanel->setVisible(mIsInActiveVoiceChannel && !LLVoiceChannel::isSuspended());
+ mCallIconLayoutPanel->setVisible(isInActiveVoiceChannel() && !LLVoiceChannel::isSuspended());
if (old_value != mIsInActiveVoiceChannel)
{
refresh();
@@ -567,6 +581,13 @@ bool LLConversationViewSession::highlightFriendTitle(LLConversationItem* vmi)
return false;
}
+bool LLConversationViewSession::isInActiveVoiceChannel()
+{
+ return mIsInActiveVoiceChannel &&
+ LLVoiceClient::getInstance()->voiceEnabled() &&
+ LLVoiceClient::getInstance()->isVoiceWorking();
+}
+
//
// Implementation of conversations list participant (avatar) widgets
//
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index a6d240ed84..5844041127 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -94,7 +94,8 @@ public:
void setHighlightState(bool hihglight_state);
LLFloater* getSessionFloater();
- bool isInActiveVoiceChannel() { return mIsInActiveVoiceChannel; }
+ bool isInActiveVoiceChannel();
+ void updateConversationIndicators();
bool highlightFriendTitle(LLConversationItem* vmi);
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 322ee90541..da9378ad12 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -723,9 +723,13 @@ F32 LLDrawable::updateXform(bool undamped)
mXform.setRotation(target_rot);
mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!)
mXform.updateMatrix();
- if (isRoot() && mVObjp->isAnimatedObject() && mVObjp->getControlAvatar())
+ if (isRoot() && mVObjp->isAnimatedObject())
{
- mVObjp->getControlAvatar()->matchVolumeTransform();
+ LLControlAvatar* cav = mVObjp->getControlAvatar();
+ if (cav)
+ {
+ cav->matchVolumeTransform();
+ }
}
if (mSpatialBridge)
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index bc45734e66..9d1b11880b 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -267,7 +267,7 @@ void LLDrawPoolAlpha::forwardRender(bool rigged)
gGL.setColorMask(true, false);
- if (!rigged)
+ if (!rigged && getType() == LLDrawPoolAlpha::POOL_ALPHA_POST_WATER)
{ //render "highlight alpha" on final non-rigged pass
// NOTE -- hacky call here protected by !rigged instead of alongside "forwardRender"
// so renderDebugAlpha is executed while gls_pipeline_alpha and depth GL state
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index d2b862eb58..20cc89b7bd 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1071,6 +1071,91 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs
return true;
}
+F32 dot_product(const LLVector3& a, const LLVector3& b)
+{
+ return a.mV[VX] * b.mV[VX] + a.mV[VY] * b.mV[VY] + a.mV[VZ] * b.mV[VZ];
+}
+
+bool LLFace::calcAlignedPlanarGLTF(
+ const LLFace* align_to,
+ LLVector2* res_st_offset,
+ LLVector2* res_st_scale,
+ F32* res_st_rot,
+ S32 gltf_info_index) const
+{
+ if (!align_to)
+ {
+ return false;
+ }
+
+ const LLTextureEntry* orig_tep = align_to->getTextureEntry();
+ const LLTextureEntry* tep = getTextureEntry();
+ if (!orig_tep || !tep)
+ {
+ return false;
+ }
+
+ // Only support planar mapping for now
+ if (orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR ||
+ tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR)
+ {
+ return false;
+ }
+
+ LLGLTFMaterial* orig_mat = orig_tep->getGLTFRenderMaterial();
+ LLGLTFMaterial* this_mat = tep->getGLTFRenderMaterial();
+ if (!orig_mat || !this_mat)
+ {
+ return false;
+ }
+
+ // Get the original GLTF transform for the specified channel
+ const auto& orig_tt = orig_mat->mTextureTransform[gltf_info_index];
+
+ // Convert GLTF transform to legacy TE transform
+ F32 map_scaleS, map_scaleT, map_offsS, map_offsT, map_rot;
+ LLGLTFMaterial::convertPBRTransformToTexture(
+ orig_tt.mScale,
+ orig_tt.mOffset,
+ orig_tt.mRotation,
+ map_scaleS, map_scaleT, map_offsS, map_offsT, map_rot);
+
+ // Calculate aligments
+ LLVector3 orig_pos, this_pos;
+ LLQuaternion orig_face_rot, this_face_rot;
+ F32 orig_proj_scale, this_proj_scale;
+ align_to->getPlanarProjectedParams(&orig_face_rot, &orig_pos, &orig_proj_scale);
+ getPlanarProjectedParams(&this_face_rot, &this_pos, &this_proj_scale);
+
+ // The rotation of "this face's" texture:
+ LLQuaternion orig_st_rot = LLQuaternion(map_rot, LLVector3::z_axis) * orig_face_rot;
+ LLQuaternion this_st_rot = orig_st_rot * ~this_face_rot;
+ F32 x_ang, y_ang, z_ang;
+ this_st_rot.getEulerAngles(&x_ang, &y_ang, &z_ang);
+
+ // Offset and scale of "this face's" texture:
+ LLVector3 centers_dist = (this_pos - orig_pos) * ~orig_st_rot;
+ LLVector3 st_scale(map_scaleS, map_scaleT, 1.f);
+ st_scale *= orig_proj_scale;
+ centers_dist.scaleVec(st_scale);
+ LLVector2 orig_st_offset(map_offsS, map_offsT);
+
+ LLVector2 tex_res_st_offset = orig_st_offset + (LLVector2)centers_dist;
+ tex_res_st_offset.mV[VX] -= (S32)tex_res_st_offset.mV[VX];
+ tex_res_st_offset.mV[VY] -= (S32)tex_res_st_offset.mV[VY];
+
+ st_scale /= this_proj_scale;
+
+ // Convert aligned legacy TE transform back to GLTF transform
+ LLGLTFMaterial::convertTextureTransformToPBR(
+ st_scale.mV[0], st_scale.mV[1],
+ tex_res_st_offset.mV[0], tex_res_st_offset.mV[1],
+ z_ang,
+ *res_st_scale, *res_st_offset, *res_st_rot);
+
+ return true;
+}
+
void LLFace::updateRebuildFlags()
{
if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
@@ -1405,11 +1490,11 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
// They are used only to display a face selection marker
// (white square with a rounded cross at the center)
const auto& tt = gltf_mat->mTextureTransform[gltf_info_index];
- r = -tt.mRotation * 2;
- ms = tt.mScale[VX];
- mt = tt.mScale[VY];
- os += tt.mOffset[VX] + (ms - 1) / 2;
- ot -= tt.mOffset[VY] + (mt - 1) / 2;
+ LLGLTFMaterial::convertPBRTransformToTexture(
+ tt.mScale,
+ tt.mOffset,
+ tt.mRotation,
+ ms, mt, os, ot, r);
}
else
{
@@ -2382,7 +2467,11 @@ F32 LLFace::adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius
//the above calculation is too expensive
//the below is a good estimation: bounding box of the bounding sphere:
- F32 alpha = 0.5f * (radius + screen_radius - d) / radius ;
+ F32 alpha = 1.f;
+ if (!is_approx_zero(radius)) // radius can be something like -1e-10
+ {
+ alpha = 0.5f * (radius + screen_radius - d) / radius;
+ }
alpha = llclamp(alpha, 0.f, 1.f) ;
return alpha * alpha ;
}
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index df31e9ea90..6e9d23c3a2 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -103,6 +103,8 @@ public:
LLVector3 getPositionAgent() const;
LLVector2 surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal);
void getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const;
+ bool calcAlignedPlanarGLTF(const LLFace* align_to, LLVector2* res_st_offset,
+ LLVector2* res_st_scale, F32* res_st_rot, S32 gltf_info_index = 0) const;
bool calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset,
LLVector2* st_scale, F32* st_rot, LLRender::eTexIndex map = LLRender::DIFFUSE_MAP) const;
diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm
index 6921cd6101..7262d18483 100644
--- a/indra/newview/llfilepicker_mac.mm
+++ b/indra/newview/llfilepicker_mac.mm
@@ -241,8 +241,13 @@ void doSaveDialogModeless(const std::string* file,
NSURL* url = [NSURL fileURLWithPath:fileName];
[panel setNameFieldStringValue: fileName];
- [panel setDirectoryURL: url];
+ NSURL *last_url = [[NSUserDefaults standardUserDefaults] URLForKey:@"NSNavLastRootDirectory"];
+ if(!last_url)
+ {
+ NSURL *documents_url = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;
+ [panel setDirectoryURL:documents_url];
+ }
[panel beginWithCompletionHandler:^(NSModalResponse result)
{
diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index 95e7b9af41..ed07d49ac1 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -403,7 +403,7 @@ void LLFloater360Capture::suspendForAFrame()
U32 curr_frame_count = LLFrameTimer::getFrameCount();
while (LLFrameTimer::getFrameCount() <= curr_frame_count + frame_count_delta)
{
- llcoro::suspend();
+ llcoro::suspendUntilNextFrame();
}
}
diff --git a/indra/newview/llfloaterbigpreview.cpp b/indra/newview/llfloaterbigpreview.cpp
deleted file mode 100644
index ba682494bb..0000000000
--- a/indra/newview/llfloaterbigpreview.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
-* @file llfloaterbigpreview.cpp
-* @brief Display of extended (big) preview for snapshots and SL Share
-* @author merov@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterbigpreview.h"
-#include "llsnapshotlivepreview.h"
-
-///////////////////////
-//LLFloaterBigPreview//
-///////////////////////
-
-LLFloaterBigPreview::LLFloaterBigPreview(const LLSD& key) : LLFloater(key),
- mPreviewPlaceholder(NULL),
- mFloaterOwner(NULL)
-{
-}
-
-LLFloaterBigPreview::~LLFloaterBigPreview()
-{
- if (mPreviewHandle.get())
- {
- mPreviewHandle.get()->die();
- }
-}
-
-void LLFloaterBigPreview::onCancel()
-{
- closeFloater();
-}
-
-void LLFloaterBigPreview::closeOnFloaterOwnerClosing(LLFloater* floaterp)
-{
- if (isFloaterOwner(floaterp))
- {
- closeFloater();
- }
-}
-
-bool LLFloaterBigPreview::postBuild()
-{
- mPreviewPlaceholder = getChild<LLUICtrl>("big_preview_placeholder");
- return LLFloater::postBuild();
-}
-
-void LLFloaterBigPreview::draw()
-{
- LLFloater::draw();
-
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
-
- // Display the preview if one is available
- if (previewp && previewp->getBigThumbnailImage())
- {
- // Get the preview rect
- const LLRect& preview_rect = mPreviewPlaceholder->getRect();
-
- // Get the preview texture size
- S32 thumbnail_w = previewp->getBigThumbnailWidth();
- S32 thumbnail_h = previewp->getBigThumbnailHeight();
-
- // Compute the scaling ratio and the size of the final texture in the rect: we want to prevent anisotropic scaling (distorted in x and y)
- F32 ratio = llmax((F32)(thumbnail_w)/(F32)(preview_rect.getWidth()), (F32)(thumbnail_h)/(F32)(preview_rect.getHeight()));
- thumbnail_w = (S32)((F32)(thumbnail_w)/ratio);
- thumbnail_h = (S32)((F32)(thumbnail_h)/ratio);
-
- // Compute the preview offset within the preview rect: we want to center that preview in the available rect
- const S32 local_offset_x = (preview_rect.getWidth() - thumbnail_w) / 2 ;
- const S32 local_offset_y = (preview_rect.getHeight() - thumbnail_h) / 2 ;
-
- // Compute preview offset within the floater rect
- S32 offset_x = preview_rect.mLeft + local_offset_x;
- S32 offset_y = preview_rect.mBottom + local_offset_y;
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- // Apply floater transparency to the texture unless the floater is focused.
- F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
- LLColor4 color = LLColor4::white;
-
- // Draw the preview texture
- gl_draw_scaled_image(offset_x, offset_y,
- thumbnail_w, thumbnail_h,
- previewp->getBigThumbnailImage(), color % alpha);
- }
-}
-
diff --git a/indra/newview/llfloaterbigpreview.h b/indra/newview/llfloaterbigpreview.h
deleted file mode 100644
index 1d5804acf5..0000000000
--- a/indra/newview/llfloaterbigpreview.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
-* @file llfloaterbigpreview.h
-* @brief Display of extended (big) preview for snapshots
-* @author merov@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, 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_LLFLOATERBIGPREVIEW_H
-#define LL_LLFLOATERBIGPREVIEW_H
-
-#include "llfloater.h"
-
-class LLFloaterBigPreview : public LLFloater
-{
-public:
- LLFloaterBigPreview(const LLSD& key);
- ~LLFloaterBigPreview();
-
- bool postBuild();
- void draw();
- void onCancel();
-
- void setPreview(LLView* previewp) { mPreviewHandle = previewp->getHandle(); }
- void setFloaterOwner(LLFloater* floaterp) { mFloaterOwner = floaterp; }
- bool isFloaterOwner(LLFloater* floaterp) const { return (mFloaterOwner == floaterp); }
- void closeOnFloaterOwnerClosing(LLFloater* floaterp);
-
-private:
- LLHandle<LLView> mPreviewHandle;
- LLUICtrl* mPreviewPlaceholder;
- LLFloater* mFloaterOwner;
-};
-
-#endif // LL_LLFLOATERBIGPREVIEW_H
-
diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp
index a42c94f049..bc1f3045bb 100644
--- a/indra/newview/llfloatereditenvironmentbase.cpp
+++ b/indra/newview/llfloatereditenvironmentbase.cpp
@@ -262,7 +262,7 @@ void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, cons
}
else if (mInventoryItem)
{
- const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
LLUUID parent_id = mInventoryItem->getParentUUID();
if (marketplacelistings_id == parent_id || gInventory.isObjectDescendentOf(mInventoryItem->getUUID(), gInventory.getLibraryRootFolderID()))
{
diff --git a/indra/newview/llfloaterexperiences.cpp b/indra/newview/llfloaterexperiences.cpp
index 999a473a49..79d74093a2 100644
--- a/indra/newview/llfloaterexperiences.cpp
+++ b/indra/newview/llfloaterexperiences.cpp
@@ -385,8 +385,11 @@ void LLFloaterExperiences::retrieveExperienceListCoro(std::string url,
if (!status)
{
+ LL_WARNS("Experience") << "Failed to retrieve list. Error: " << status.toTerseString()
+ << ". Type: " << errorNotify << " Message: " << status.getMessage() << LL_ENDL;
+
LLSD subs;
- subs["ERROR_MESSAGE"] = status.getType();
+ subs["ERROR_MESSAGE"] = llformat(" %d\n %s", (S32)status.getType(), status.getMessage().c_str());
LLNotificationsUtil::add(errorNotify, subs);
return;
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 143781a225..04327e30bd 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -57,6 +57,8 @@
#include "llsdserialize.h"
#include "llviewermenu.h" // is_agent_mappable
#include "llviewerobjectlist.h"
+#include "llvoavatar.h"
+#include "llnearbyvoicemoderation.h"
const S32 EVENTS_PER_IDLE_LOOP_CURRENT_SESSION = 80;
@@ -90,6 +92,7 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param
mAutoResize = false;
LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
+ LLNearbyVoiceModeration::getInstance();
}
LLFloaterIMContainer::~LLFloaterIMContainer()
@@ -530,6 +533,33 @@ void LLFloaterIMContainer::idleUpdate()
mGeneralTitleInUse = !needs_override;
setTitle(needs_override ? conversation_floaterp->getTitle() : mGeneralTitle);
}
+ const LLConversationItem* nearby_session = getSessionModel(LLUUID());
+ if (nearby_session)
+ {
+ LLSpeakerMgr* speaker_mgr = (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance());
+
+ LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = nearby_session->getChildrenBegin();
+ LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = nearby_session->getChildrenEnd();
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItemParticipant* participant_model =
+ dynamic_cast<LLConversationItemParticipant*>((*current_participant_model).get());
+ if (participant_model)
+ {
+ bool show_moderator_options = LLNearbyVoiceModeration::getInstance()->isNearbyChatModerator();
+ LLUUID participant_id = participant_model->getUUID();
+ if (participant_id != gAgentID)
+ {
+ // Don't show moderator options if participant is not connected to the same spatial channel
+ LLSpeaker* speakerp = speaker_mgr->findSpeaker(participant_id).get();
+ show_moderator_options &= speakerp && speakerp->isInVoiceChannel();
+ }
+ participant_model->setModeratorOptionsVisible(show_moderator_options);
+ }
+
+ current_participant_model++;
+ }
+ }
}
mParticipantRefreshTimer.setTimerExpirySec(1.0f);
@@ -1693,6 +1723,10 @@ bool LLFloaterIMContainer::visibleContextMenuItem(const LLSD& userdata)
{
return isMuted(conversation_item->getUUID());
}
+ else if ("can_allow_text_chat" == item)
+ {
+ return !isNearbyChatSpeakerSelected();
+ }
return true;
}
@@ -2022,9 +2056,27 @@ LLConversationViewParticipant* LLFloaterIMContainer::createConversationViewParti
bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata, bool is_self)
{
- // only group moderators can perform actions related to this "enable callback"
- if (!isGroupModerator())
+ if (LLNearbyVoiceModeration::getInstance()->isNearbyChatModerator() && isNearbyChatSpeakerSelected())
{
+ // Determine here which actions are allowed
+ if ("can_moderate_voice" == userdata)
+ {
+ return true;
+ }
+ else if (("can_mute" == userdata))
+ {
+ return !is_self;
+ }
+ else if ("can_unmute" == userdata)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ else if (!isGroupModerator())
+ {
+ // only group moderators can perform actions related to this "enable callback"
return false;
}
@@ -2157,7 +2209,35 @@ void LLFloaterIMContainer::banSelectedMember(const LLUUID& participant_uuid)
void LLFloaterIMContainer::moderateVoice(const std::string& command, const LLUUID& userID)
{
- if (!gAgent.getRegion()) return;
+ if (!gAgent.getRegion())
+ {
+ return;
+ }
+
+ if (isNearbyChatSpeakerSelected())
+ {
+ if ("selected" == command)
+ {
+ // Request a mute/unmute using a capability request via the simulator
+ LLNearbyVoiceModeration::getInstance()->requestMuteIndividual(userID, !isMuted(userID));
+ }
+ else
+ if ("mute_all" == command)
+ {
+ // Send the mute_all request to the server
+ const bool mute_state = true;
+ LLNearbyVoiceModeration::getInstance()->requestMuteAll(mute_state);
+ }
+ else
+ if ("unmute_all" == command)
+ {
+ // Send the unmute_all request to the server
+ const bool mute_state = false;
+ LLNearbyVoiceModeration::getInstance()->requestMuteAll(mute_state);
+ }
+
+ return;
+ }
if (command.compare("selected"))
{
@@ -2275,6 +2355,31 @@ LLSpeaker * LLFloaterIMContainer::getSpeakerOfSelectedParticipant(LLSpeakerMgr *
return speaker_managerp->findSpeaker(participant_itemp->getUUID());
}
+bool LLFloaterIMContainer::isNearbyChatSpeakerSelected()
+{
+ LLFolderViewItem *selectedItem = mConversationsRoot->getCurSelectedItem();
+ if (!selectedItem)
+ {
+ LL_WARNS() << "Current selected item is null" << LL_ENDL;
+ return NULL;
+ }
+
+ conversations_widgets_map::const_iterator iter = mConversationsWidgets.begin();
+ conversations_widgets_map::const_iterator end = mConversationsWidgets.end();
+ const LLUUID * conversation_uuidp = NULL;
+ while(iter != end)
+ {
+ if (iter->second == selectedItem || iter->second == selectedItem->getParentFolder())
+ {
+ conversation_uuidp = &iter->first;
+ break;
+ }
+ ++iter;
+ }
+ // Nearby chat ID is LLUUID::null
+ return conversation_uuidp->isNull();
+}
+
void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
{
LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 30eed8be36..9f1690a9b9 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -178,6 +178,7 @@ private:
void banSelectedMember(const LLUUID& participant_uuid);
void openNearbyChat();
bool isParticipantListExpanded();
+ bool isNearbyChatSpeakerSelected();
void idleUpdate(); // for convenience (self) from static idle
void idleProcessEvents();
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 84a9fad708..6d642638b3 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -142,7 +142,7 @@ void LLFloaterIMSession::onClickCloseBtn(bool app_qutting)
{
if (app_qutting)
{
- LLFloaterIMSessionTab::onClickCloseBtn();
+ LLFloaterIMSessionTab::onClickCloseBtn(app_qutting);
return;
}
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 48360f30d4..187dd3d8ff 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -48,6 +48,7 @@
#include "llfloaterimnearbychat.h"
#include "llgroupiconctrl.h"
#include "lllayoutstack.h"
+#include "llnotificationsutil.h"
#include "llpanelemojicomplete.h"
#include "lltoolbarview.h"
@@ -1419,3 +1420,20 @@ bool LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask )
}
return handled;
}
+
+void LLFloaterIMSessionTab::onClickCloseBtn(bool app_quitting)
+{
+ bool is_ad_hoc = (mSession ? mSession->isAdHocSessionType() : false);
+ if (is_ad_hoc && !app_quitting)
+ {
+ LLNotificationsUtil::add("ConfirmLeaveAdhoc", LLSD(), LLSD(), [this](const LLSD& notification, const LLSD& response)
+ {
+ if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+ closeFloater();
+ });
+ }
+ else
+ {
+ closeFloater();
+ }
+}
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 6d04d622e1..b27ac1b8f9 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -85,6 +85,8 @@ public:
void closeFloater(bool app_quitting = false) override;
void deleteAllChildren() override;
+ virtual void onClickCloseBtn(bool app_quitting = false) override;
+
// Handle the left hand participant list widgets
void addConversationViewParticipant(LLConversationItem* item, bool update_view = true);
void removeConversationViewParticipant(const LLUUID& participant_id);
diff --git a/indra/newview/llfloaterlinkreplace.cpp b/indra/newview/llfloaterlinkreplace.cpp
index c961070787..33e054aab9 100644
--- a/indra/newview/llfloaterlinkreplace.cpp
+++ b/indra/newview/llfloaterlinkreplace.cpp
@@ -225,6 +225,21 @@ void LLFloaterLinkReplace::linkCreatedCallback(LLHandle<LLFloaterLinkReplace> fl
<< " - description update = " << (needs_description_update ? "true" : "false") << LL_NEWLINE
<< " - outfit_folder_id = " << outfit_folder_id.asString() << LL_ENDL;
+ std::string old_description;
+ if (needs_wearable_ordering_update)
+ {
+ LLViewerInventoryItem* old_item = gInventory.getItem(old_item_id);
+ LLViewerInventoryItem* target_item = gInventory.getItem(target_item_id);
+ if (old_item && target_item &&
+ old_item->getType() == LLAssetType::AT_CLOTHING &&
+ target_item->getType() == LLAssetType::AT_CLOTHING &&
+ old_item->getWearableType() == target_item->getWearableType())
+ {
+ // Preserve the original description, which contains ordering info
+ old_description = old_item->getActualDescription();
+ }
+ }
+
// If we are replacing an object, bodypart or gesture link within an outfit folder,
// we need to change the actual description of the link itself. LLAppearanceMgr *should*
// have created COF links that will be used to save the outfit with an empty description.
@@ -246,7 +261,14 @@ void LLFloaterLinkReplace::linkCreatedCallback(LLHandle<LLFloaterLinkReplace> fl
{
LLPointer<LLViewerInventoryItem> item = *it;
- if ((item->getType() == LLAssetType::AT_BODYPART ||
+ if (item->getType() == LLAssetType::AT_CLOTHING && !old_description.empty())
+ {
+ // Use the old description to set ordering info
+ LLSD updates;
+ updates["desc"] = old_description;
+ update_inventory_item(item->getUUID(), updates, LLPointer<LLInventoryCallback>(NULL));
+ }
+ else if ((item->getType() == LLAssetType::AT_BODYPART ||
item->getType() == LLAssetType::AT_OBJECT ||
item->getType() == LLAssetType::AT_GESTURE)
&& !item->getActualDescription().empty())
@@ -347,12 +369,9 @@ void LLFloaterLinkReplace::processBatch(LLInventoryModel::item_array_t items)
bool is_outfit_folder = gInventory.isObjectDescendentOf(source_item->getParentUUID(), outfit_folder_id);
// If either the new or old item in the COF is a wearable, we need to update wearable ordering after the link has been replaced
bool needs_wearable_ordering_update = (is_outfit_folder && source_item->getType() == LLAssetType::AT_CLOTHING) || target_item->getType() == LLAssetType::AT_CLOTHING;
- // Other items in the COF need a description update (description of the actual link item must be empty)
- bool needs_description_update = is_outfit_folder && target_item->getType() != LLAssetType::AT_CLOTHING;
LL_DEBUGS() << "is_outfit_folder = " << (is_outfit_folder ? "true" : "false") << LL_NEWLINE
- << "needs_wearable_ordering_update = " << (needs_wearable_ordering_update ? "true" : "false") << LL_NEWLINE
- << "needs_description_update = " << (needs_description_update ? "true" : "false") << LL_ENDL;
+ << "needs_wearable_ordering_update = " << (needs_wearable_ordering_update ? "true" : "false") << LL_ENDL;
LLInventoryObject::const_object_list_t obj_array;
obj_array.push_back(LLConstPointer<LLInventoryObject>(target_item));
@@ -361,7 +380,7 @@ void LLFloaterLinkReplace::processBatch(LLInventoryModel::item_array_t items)
source_item->getUUID(),
target_item->getUUID(),
needs_wearable_ordering_update,
- needs_description_update,
+ is_outfit_folder,
(is_outfit_folder ? source_item->getParentUUID() : LLUUID::null) ));
link_inventory_array(source_item->getParentUUID(), obj_array, cb);
}
diff --git a/indra/newview/llfloatermarketplace.cpp b/indra/newview/llfloatermarketplace.cpp
index 7316d7617d..bb2378d864 100644
--- a/indra/newview/llfloatermarketplace.cpp
+++ b/indra/newview/llfloatermarketplace.cpp
@@ -39,6 +39,27 @@ LLFloaterMarketplace::~LLFloaterMarketplace()
{
}
+void LLFloaterMarketplace::onOpen(const LLSD& key)
+{
+ Params params(key);
+
+ if (!params.validateBlock())
+ {
+ closeFloater();
+ return;
+ }
+
+ if (params.url().empty())
+ {
+ openMarketplace();
+ }
+ else
+ {
+ openMarketplaceURL(params.url);
+ set_current_url(params.url); // Fix looping back to previous url when using the viewer navigation bar
+ }
+}
+
// just to override LLFloaterWebContent
void LLFloaterMarketplace::onClose(bool app_quitting)
{
@@ -68,3 +89,18 @@ void LLFloaterMarketplace::openMarketplace()
mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
}
}
+
+void LLFloaterMarketplace::openMarketplaceURL(const std::string& url)
+{
+ if (mCurrentURL != url)
+ {
+ mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+ }
+}
+
+// static
+bool LLFloaterMarketplace::isMarketplaceURL(const std::string& url)
+{
+ static LLCachedControl<std::string> marketplace_url(gSavedSettings, "MarketplaceURL", "https://marketplace.secondlife.com/");
+ return url.starts_with(marketplace_url());
+}
diff --git a/indra/newview/llfloatermarketplace.h b/indra/newview/llfloatermarketplace.h
index 9524c94eee..17979dae90 100644
--- a/indra/newview/llfloatermarketplace.h
+++ b/indra/newview/llfloatermarketplace.h
@@ -36,11 +36,14 @@ class LLFloaterMarketplace:
public:
void openMarketplace();
+ void openMarketplaceURL(const std::string& url);
+ bool static isMarketplaceURL(const std::string& url);
private:
LLFloaterMarketplace(const LLSD& key);
~LLFloaterMarketplace();
bool postBuild() override;
+ void onOpen(const LLSD& key) override;
void onClose(bool app_quitting) override;
};
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index f20fea01c5..dfd023e424 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -29,6 +29,7 @@
#include "llfloatermarketplacelistings.h"
+#include "llcallbacklist.h"
#include "llfloaterreg.h"
#include "llfiltereditor.h"
#include "llfolderview.h"
@@ -231,7 +232,7 @@ void LLPanelMarketplaceListings::onTabChange()
void LLPanelMarketplaceListings::onAddButtonClicked()
{
- LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ LLUUID marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
llassert(marketplacelistings_id.notNull());
LLFolderType::EType preferred_type = LLFolderType::lookup("category");
LLHandle<LLPanel> handle = getHandle();
@@ -351,7 +352,15 @@ public:
if (added_category_type == LLFolderType::FT_MARKETPLACE_LISTINGS)
{
- mMarketplaceListingsFloater->initializeMarketPlace();
+ LLHandle<LLFloater> handle = mMarketplaceListingsFloater->getHandle();
+ doOnIdleOneTime([handle]()
+ {
+ LLFloaterMarketplaceListings* floater = (LLFloaterMarketplaceListings*)handle.get();
+ if (floater)
+ {
+ floater->initializeMarketPlace();
+ }
+ });
}
}
}
@@ -415,7 +424,7 @@ bool LLFloaterMarketplaceListings::postBuild()
// Fetch aggressively so we can interact with listings as soon as possible
if (!fetchContents())
{
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
LLInventoryModelBackgroundFetch::instance().start(marketplacelistings_id, true);
}
@@ -513,8 +522,6 @@ void LLFloaterMarketplaceListings::setRootFolder()
return;
}
- mRootFolderCreating = false;
-
// No longer need to observe new category creation
if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
{
@@ -524,6 +531,8 @@ void LLFloaterMarketplaceListings::setRootFolder()
}
llassert(!mCategoryAddedObserver);
+ mRootFolderCreating = false;
+
if (marketplacelistings_id == mRootFolderId)
{
LL_WARNS("SLM") << "Inventory warning: Marketplace listings folder already set" << LL_ENDL;
@@ -566,7 +575,8 @@ void LLFloaterMarketplaceListings::setPanels()
void LLFloaterMarketplaceListings::initializeMarketPlace()
{
- LLMarketplaceData::instance().initializeSLM(boost::bind(&LLFloaterMarketplaceListings::updateView, this));
+ if (!mRootFolderCreating)
+ LLMarketplaceData::instance().initializeSLM(boost::bind(&LLFloaterMarketplaceListings::updateView, this));
}
S32 LLFloaterMarketplaceListings::getFolderCount()
@@ -909,7 +919,7 @@ void LLFloaterMarketplaceValidation::onOpen(const LLSD& key)
LLUUID cat_id(key.asUUID());
if (cat_id.isNull())
{
- cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ cat_id = gInventory.getMarketplaceListingsUUID();
}
// Validates the folder
diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp
index fa491a4b27..bd8530abd7 100644
--- a/indra/newview/llfloaterobjectweights.cpp
+++ b/indra/newview/llfloaterobjectweights.cpp
@@ -208,7 +208,7 @@ void LLFloaterObjectWeights::draw()
toggleRenderLoadingIndicators(false);
}
mTrianglesShown->setText(llformat("%d", total_tris));
- mPixelArea->setText(llformat("%d", pixel_area));
+ mPixelArea->setText(llformat("%ld", (S64)pixel_area)); // value capped at 10M
}
LLFloater::draw();
}
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index d5e45c09e3..e497fb0914 100644
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -502,7 +502,7 @@ void LLFloaterPay::onGive(give_money_ptr info)
amount = atoi(text_field->getValue().asString().c_str());
}
- if (amount > PAY_AMOUNT_NOTIFICATION && gStatusBar && gStatusBar->getBalance() > amount)
+ if (amount > PAY_AMOUNT_NOTIFICATION)
{
LLUUID payee_id = LLUUID::null;
bool is_group = false;
diff --git a/indra/newview/llfloaterpostprocess.cpp b/indra/newview/llfloaterpostprocess.cpp
deleted file mode 100644
index 616c13cdc7..0000000000
--- a/indra/newview/llfloaterpostprocess.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/**
- * @file llfloaterpostprocess.cpp
- * @brief LLFloaterPostProcess class definition
- *
- * $LicenseInfo:firstyear=2007&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 "llviewerprecompiledheaders.h"
-
-#include "llfloaterpostprocess.h"
-
-#include "llsliderctrl.h"
-#include "llcheckboxctrl.h"
-#include "llnotificationsutil.h"
-#include "lluictrlfactory.h"
-#include "llviewerdisplay.h"
-#include "llpostprocess.h"
-#include "llcombobox.h"
-#include "lllineeditor.h"
-#include "llviewerwindow.h"
-
-
-LLFloaterPostProcess::LLFloaterPostProcess(const LLSD& key)
- : LLFloater(key)
-{
-}
-
-LLFloaterPostProcess::~LLFloaterPostProcess()
-{
-
-
-}
-bool LLFloaterPostProcess::postBuild()
-{
- /// Color Filter Callbacks
- childSetCommitCallback("ColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter");
- //childSetCommitCallback("ColorFilterGamma", &LLFloaterPostProcess::onFloatControlMoved, &(gPostProcess->tweaks.gamma()));
- childSetCommitCallback("ColorFilterBrightness", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness");
- childSetCommitCallback("ColorFilterSaturation", &LLFloaterPostProcess::onFloatControlMoved, (char*)"saturation");
- childSetCommitCallback("ColorFilterContrast", &LLFloaterPostProcess::onFloatControlMoved, (char*)"contrast");
-
- childSetCommitCallback("ColorFilterBaseR", &LLFloaterPostProcess::onColorControlRMoved, (char*)"contrast_base");
- childSetCommitCallback("ColorFilterBaseG", &LLFloaterPostProcess::onColorControlGMoved, (char*)"contrast_base");
- childSetCommitCallback("ColorFilterBaseB", &LLFloaterPostProcess::onColorControlBMoved, (char*)"contrast_base");
- childSetCommitCallback("ColorFilterBaseI", &LLFloaterPostProcess::onColorControlIMoved, (char*)"contrast_base");
-
- /// Night Vision Callbacks
- childSetCommitCallback("NightVisionToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_night_vision");
- childSetCommitCallback("NightVisionBrightMult", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness_multiplier");
- childSetCommitCallback("NightVisionNoiseSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_size");
- childSetCommitCallback("NightVisionNoiseStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_strength");
-
- /// Bloom Callbacks
- childSetCommitCallback("BloomToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_bloom");
- childSetCommitCallback("BloomExtract", &LLFloaterPostProcess::onFloatControlMoved, (char*)"extract_low");
- childSetCommitCallback("BloomSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_width");
- childSetCommitCallback("BloomStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_strength");
-
- // Effect loading and saving.
- LLComboBox* comboBox = getChild<LLComboBox>("PPEffectsCombo");
- getChild<LLComboBox>("PPLoadEffect")->setCommitCallback(boost::bind(&LLFloaterPostProcess::onLoadEffect, this, comboBox));
- comboBox->setCommitCallback(boost::bind(&LLFloaterPostProcess::onChangeEffectName, this, _1));
-
- LLLineEditor* editBox = getChild<LLLineEditor>("PPEffectNameEditor");
- getChild<LLComboBox>("PPSaveEffect")->setCommitCallback(boost::bind(&LLFloaterPostProcess::onSaveEffect, this, editBox));
-
- syncMenu();
- return true;
-}
-
-// Bool Toggle
-void LLFloaterPostProcess::onBoolToggle(LLUICtrl* ctrl, void* userData)
-{
- char const * boolVariableName = (char const *)userData;
-
- // check the bool
- LLCheckBoxCtrl* cbCtrl = static_cast<LLCheckBoxCtrl*>(ctrl);
- gPostProcess->tweaks[boolVariableName] = cbCtrl->getValue();
-}
-
-// Float Moved
-void LLFloaterPostProcess::onFloatControlMoved(LLUICtrl* ctrl, void* userData)
-{
- char const * floatVariableName = (char const *)userData;
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- gPostProcess->tweaks[floatVariableName] = sldrCtrl->getValue();
-}
-
-// Color Moved
-void LLFloaterPostProcess::onColorControlRMoved(LLUICtrl* ctrl, void* userData)
-{
- char const * floatVariableName = (char const *)userData;
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- gPostProcess->tweaks[floatVariableName][0] = sldrCtrl->getValue();
-}
-
-// Color Moved
-void LLFloaterPostProcess::onColorControlGMoved(LLUICtrl* ctrl, void* userData)
-{
- char const * floatVariableName = (char const *)userData;
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- gPostProcess->tweaks[floatVariableName][1] = sldrCtrl->getValue();
-}
-
-// Color Moved
-void LLFloaterPostProcess::onColorControlBMoved(LLUICtrl* ctrl, void* userData)
-{
- char const * floatVariableName = (char const *)userData;
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- gPostProcess->tweaks[floatVariableName][2] = sldrCtrl->getValue();
-}
-
-// Color Moved
-void LLFloaterPostProcess::onColorControlIMoved(LLUICtrl* ctrl, void* userData)
-{
- char const * floatVariableName = (char const *)userData;
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- gPostProcess->tweaks[floatVariableName][3] = sldrCtrl->getValue();
-}
-
-void LLFloaterPostProcess::onLoadEffect(LLComboBox* comboBox)
-{
- LLSD::String effectName(comboBox->getSelectedValue().asString());
-
- gPostProcess->setSelectedEffect(effectName);
-
- syncMenu();
-}
-
-void LLFloaterPostProcess::onSaveEffect(LLLineEditor* editBox)
-{
- std::string effectName(editBox->getValue().asString());
-
- if (gPostProcess->mAllEffects.has(effectName))
- {
- LLSD payload;
- payload["effect_name"] = effectName;
- LLNotificationsUtil::add("PPSaveEffectAlert", LLSD(), payload, boost::bind(&LLFloaterPostProcess::saveAlertCallback, this, _1, _2));
- }
- else
- {
- gPostProcess->saveEffect(effectName);
- syncMenu();
- }
-}
-
-void LLFloaterPostProcess::onChangeEffectName(LLUICtrl* ctrl)
-{
- // get the combo box and name
- LLLineEditor* editBox = getChild<LLLineEditor>("PPEffectNameEditor");
-
- // set the parameter's new name
- editBox->setValue(ctrl->getValue());
-}
-
-bool LLFloaterPostProcess::saveAlertCallback(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- // if they choose save, do it. Otherwise, don't do anything
- if (option == 0)
- {
- gPostProcess->saveEffect(notification["payload"]["effect_name"].asString());
-
- syncMenu();
- }
- return false;
-}
-
-void LLFloaterPostProcess::syncMenu()
-{
- // add the combo boxe contents
- LLComboBox* comboBox = getChild<LLComboBox>("PPEffectsCombo");
-
- comboBox->removeall();
-
- LLSD::map_const_iterator currEffect;
- for(currEffect = gPostProcess->mAllEffects.beginMap();
- currEffect != gPostProcess->mAllEffects.endMap();
- ++currEffect)
- {
- comboBox->add(currEffect->first);
- }
-
- // set the current effect as selected.
- comboBox->selectByValue(gPostProcess->getSelectedEffect());
-
- /// Sync Color Filter Menu
- getChild<LLUICtrl>("ColorFilterToggle")->setValue(gPostProcess->tweaks.useColorFilter());
- //getChild<LLUICtrl>("ColorFilterGamma")->setValue(gPostProcess->tweaks.gamma());
- getChild<LLUICtrl>("ColorFilterBrightness")->setValue(gPostProcess->tweaks.brightness());
- getChild<LLUICtrl>("ColorFilterSaturation")->setValue(gPostProcess->tweaks.saturation());
- getChild<LLUICtrl>("ColorFilterContrast")->setValue(gPostProcess->tweaks.contrast());
- getChild<LLUICtrl>("ColorFilterBaseR")->setValue(gPostProcess->tweaks.contrastBaseR());
- getChild<LLUICtrl>("ColorFilterBaseG")->setValue(gPostProcess->tweaks.contrastBaseG());
- getChild<LLUICtrl>("ColorFilterBaseB")->setValue(gPostProcess->tweaks.contrastBaseB());
- getChild<LLUICtrl>("ColorFilterBaseI")->setValue(gPostProcess->tweaks.contrastBaseIntensity());
-
- /// Sync Night Vision Menu
- getChild<LLUICtrl>("NightVisionToggle")->setValue(gPostProcess->tweaks.useNightVisionShader());
- getChild<LLUICtrl>("NightVisionBrightMult")->setValue(gPostProcess->tweaks.brightMult());
- getChild<LLUICtrl>("NightVisionNoiseSize")->setValue(gPostProcess->tweaks.noiseSize());
- getChild<LLUICtrl>("NightVisionNoiseStrength")->setValue(gPostProcess->tweaks.noiseStrength());
-
- /// Sync Bloom Menu
- getChild<LLUICtrl>("BloomToggle")->setValue(LLSD(gPostProcess->tweaks.useBloomShader()));
- getChild<LLUICtrl>("BloomExtract")->setValue(gPostProcess->tweaks.extractLow());
- getChild<LLUICtrl>("BloomSize")->setValue(gPostProcess->tweaks.bloomWidth());
- getChild<LLUICtrl>("BloomStrength")->setValue(gPostProcess->tweaks.bloomStrength());
-}
diff --git a/indra/newview/llfloaterpostprocess.h b/indra/newview/llfloaterpostprocess.h
deleted file mode 100644
index 50b48d8410..0000000000
--- a/indra/newview/llfloaterpostprocess.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * @file llfloaterpostprocess.h
- * @brief LLFloaterPostProcess class definition
- *
- * $LicenseInfo:firstyear=2007&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_LLFLOATERPOSTPROCESS_H
-#define LL_LLFLOATERPOSTPROCESS_H
-
-#include "llfloater.h"
-
-class LLButton;
-class LLComboBox;
-class LLLineEditor;
-class LLSliderCtrl;
-class LLTabContainer;
-class LLPanelPermissions;
-class LLPanelObject;
-class LLPanelVolume;
-class LLPanelContents;
-class LLPanelFace;
-
-/**
- * Menu for adjusting the post process settings of the world
- */
-class LLFloaterPostProcess : public LLFloater
-{
-public:
-
- LLFloaterPostProcess(const LLSD& key);
- virtual ~LLFloaterPostProcess();
- bool postBuild();
-
- /// post process callbacks
- static void onBoolToggle(LLUICtrl* ctrl, void* userData);
- static void onFloatControlMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlRMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlGMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlBMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlIMoved(LLUICtrl* ctrl, void* userData);
- void onLoadEffect(LLComboBox* comboBox);
- void onSaveEffect(LLLineEditor* editBox);
- void onChangeEffectName(LLUICtrl* ctrl);
-
- /// prompts a user when overwriting an effect
- bool saveAlertCallback(const LLSD& notification, const LLSD& response);
-
- /// sync up sliders
- void syncMenu();
-};
-
-#endif
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index eb1b758332..d05eb975ae 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -474,7 +474,8 @@ bool LLFloaterPreference::postBuild()
getChild<LLUICtrl>("log_path_string")->setEnabled(false); // make it read-only but selectable
- getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
+ mLanguageCombobox = getChild<LLComboBox>("language_combobox");
+ mLanguageCombobox->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
mTimeFormatCombobox = getChild<LLComboBox>("time_format_combobox");
mTimeFormatCombobox->setCommitCallback(boost::bind(&LLFloaterPreference::onTimeFormatChange, this));
@@ -516,18 +517,18 @@ bool LLFloaterPreference::postBuild()
std::map<std::string, std::string>::iterator iter = labels.find(system_lang);
if (iter != labels.end())
{
- getChild<LLComboBox>("language_combobox")->add(iter->second, LLSD("default"), ADD_TOP, true);
+ mLanguageCombobox->add(iter->second, LLSD("default"), ADD_TOP, true);
}
else
{
LL_WARNS() << "Language \"" << system_lang << "\" is not in default_languages.xml" << LL_ENDL;
- getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
+ mLanguageCombobox->add("System default", LLSD("default"), ADD_TOP, true);
}
}
else
{
LL_WARNS() << "Failed to load labels from " << user_filename << ". Using default." << LL_ENDL;
- getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
+ mLanguageCombobox->add("System default", LLSD("default"), ADD_TOP, true);
}
#ifndef LL_DISCORD
@@ -619,8 +620,6 @@ void LLFloaterPreference::apply()
std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
setCacheLocation(cache_location);
- LLViewerMedia::getInstance()->setCookiesEnabled(getChild<LLUICtrl>("cookies_enabled")->getValue());
-
if (hasChild("web_proxy_enabled", true) &&hasChild("web_proxy_editor", true) && hasChild("web_proxy_port", true))
{
bool proxy_enable = getChild<LLUICtrl>("web_proxy_enabled")->getValue();
@@ -1340,6 +1339,12 @@ void LLFloaterPreference::refresh()
updateClickActionViews();
mTimeFormatCombobox->selectByValue(gSavedSettings.getBOOL("Use24HourClock") ? "1" : "0");
+
+ std::string current_language = gSavedSettings.getString("Language");
+ if (current_language != "default" && !current_language.empty())
+ {
+ mLanguageCombobox->selectByValue(LLSD(current_language));
+ }
}
void LLFloaterPreference::onCommitWindowedMode()
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 8d3f1ed6b0..33ba28d0dc 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -237,6 +237,7 @@ private:
LLButton* mEnablePopupBtn = nullptr;
LLButton* mDisablePopupBtn = nullptr;
LLComboBox* mTimeFormatCombobox = nullptr;
+ LLComboBox* mLanguageCombobox = nullptr;
std::unique_ptr< ll::prefs::SearchData > mSearchData;
bool mSearchDataDirty;
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 2be5953ecd..45f2abf011 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -538,6 +538,18 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
panel->getChildView("access_combo")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid));
panel->setCtrlsEnabled(allow_modify);
+ panel->getChild<LLLineEditor>("estate_id")->setValue((S32)region_info.mEstateID);
+
+ if (region)
+ {
+ panel->getChild<LLLineEditor>("grid_position_x")->setValue((S32)(region->getOriginGlobal()[VX] / 256));
+ panel->getChild<LLLineEditor>("grid_position_y")->setValue((S32)(region->getOriginGlobal()[VY] / 256));
+ }
+ else
+ {
+ panel->getChild<LLLineEditor>("grid_position_x")->setDefaultText();
+ panel->getChild<LLLineEditor>("grid_position_y")->setDefaultText();
+ }
// DEBUG PANEL
panel = tab->getChild<LLPanel>("Debug");
@@ -902,6 +914,9 @@ bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region)
getChildView("apply_btn")->setEnabled(false);
getChildView("access_text")->setEnabled(allow_modify);
// getChildView("access_combo")->setEnabled(allow_modify);
+ getChildView("estate_id")->setEnabled(false);
+ getChildView("grid_position_x")->setEnabled(false);
+ getChildView("grid_position_y")->setEnabled(false);
// now set in processRegionInfo for teen grid detection
getChildView("kick_btn")->setEnabled(allow_modify);
getChildView("kick_all_btn")->setEnabled(allow_modify);
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 9b7a4e5134..3c84f5b459 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -123,19 +123,32 @@ void LLFloaterSearch::initiateSearch(const LLSD& tokens)
subs["COLLECTION"] = "";
if (subs["TYPE"] == "standard")
{
+ std::string collection_args;
if (mCollectionType.find(collection) != mCollectionType.end())
{
- subs["COLLECTION"] = "&collection_chosen=" + std::string(collection);
+ collection_args = "&collection_chosen=" + std::string(collection);
}
- else
+ else if (tokens.has("collections") && tokens["collections"].isArray())
+ {
+ const LLSD &sd = tokens["collections"];
+ for (LLSD::array_const_iterator it = sd.beginArray();
+ it != sd.endArray();
+ ++it)
+ {
+ if (mCollectionType.find(it->asString()) != mCollectionType.end())
+ {
+ collection_args += "&collection_chosen=" + std::string(*it);
+ }
+ }
+ }
+ if (collection_args.empty())
{
- std::string collection_args("");
for (std::set<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it)
{
collection_args += "&collection_chosen=" + std::string(*it);
}
- subs["COLLECTION"] = collection_args;
}
+ subs["COLLECTION"] = collection_args;
}
// Default to PG
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index faf7ed0d8c..83d7a92846 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -1043,7 +1043,7 @@ bool LLFloaterSnapshot::postBuild()
getChild<LLComboBox>("profile_size_combo")->selectNthItem(0);
getChild<LLComboBox>("postcard_size_combo")->selectNthItem(0);
getChild<LLComboBox>("texture_size_combo")->selectNthItem(0);
- getChild<LLComboBox>("local_size_combo")->selectNthItem(8);
+ getChild<LLComboBox>("local_size_combo")->selectNthItem(0);
getChild<LLComboBox>("local_format_combo")->selectNthItem(0);
impl->mPreviewHandle = previewp->getHandle();
diff --git a/indra/newview/llfloatersounddevices.cpp b/indra/newview/llfloatersounddevices.cpp
deleted file mode 100644
index f11c5c0ad8..0000000000
--- a/indra/newview/llfloatersounddevices.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * @file llfloatersounddevices.cpp
- * @author Leyla Farazha
- * @brief Sound Preferences used for minimal skin
- *
-* $LicenseInfo:firstyear=2011&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 "llviewerprecompiledheaders.h"
-
-#include "llfloatersounddevices.h"
-
-#include "lldraghandle.h"
-
-#include "llpanelvoicedevicesettings.h"
-
-// Library includes
-#include "indra_constants.h"
-
-// protected
-LLFloaterSoundDevices::LLFloaterSoundDevices(const LLSD& key)
-: LLTransientDockableFloater(NULL, false, key)
-{
- LLTransientFloaterMgr::getInstance()->addControlView(this);
-
- // force docked state since this floater doesn't save it between recreations
- setDocked(true);
-}
-
-LLFloaterSoundDevices::~LLFloaterSoundDevices()
-{
- LLTransientFloaterMgr::getInstance()->removeControlView(this);
-}
-
-// virtual
-bool LLFloaterSoundDevices::postBuild()
-{
- LLTransientDockableFloater::postBuild();
-
- updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)
-
- LLPanelVoiceDeviceSettings* panel = findChild<LLPanelVoiceDeviceSettings>("device_settings_panel");
- if (panel)
- {
- panel->setUseTuningMode(false);
- getChild<LLUICtrl>("voice_input_device")->setCommitCallback(boost::bind(&LLPanelVoiceDeviceSettings::apply, panel));
- getChild<LLUICtrl>("voice_output_device")->setCommitCallback(boost::bind(&LLPanelVoiceDeviceSettings::apply, panel));
- getChild<LLUICtrl>("mic_volume_slider")->setCommitCallback(boost::bind(&LLPanelVoiceDeviceSettings::apply, panel));
- }
- return true;
-}
-
-//virtual
-void LLFloaterSoundDevices::setDocked(bool docked, bool pop_on_undock/* = true*/)
-{
- LLTransientDockableFloater::setDocked(docked, pop_on_undock);
-}
-
-// virtual
-void LLFloaterSoundDevices::setFocus(bool b)
-{
- LLTransientDockableFloater::setFocus(b);
-
- // Force using active floater transparency
- // We have to override setFocus() for because selecting an item of the
- // combobox causes the floater to lose focus and thus become transparent.
- updateTransparency(TT_ACTIVE);
-}
diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp
deleted file mode 100644
index 9f7c9aba87..0000000000
--- a/indra/newview/llfloatervoiceeffect.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/**
- * @file llfloatervoiceeffect.cpp
- * @author Aimee
- * @brief Selection and preview of voice effect.
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloatervoiceeffect.h"
-
-#include "llscrolllistctrl.h"
-#include "lltrans.h"
-#include "llweb.h"
-
-LLFloaterVoiceEffect::LLFloaterVoiceEffect(const LLSD& key)
- : LLFloater(key)
-{
- mCommitCallbackRegistrar.add("VoiceEffect.Record", boost::bind(&LLFloaterVoiceEffect::onClickRecord, this));
- mCommitCallbackRegistrar.add("VoiceEffect.Play", boost::bind(&LLFloaterVoiceEffect::onClickPlay, this));
- mCommitCallbackRegistrar.add("VoiceEffect.Stop", boost::bind(&LLFloaterVoiceEffect::onClickStop, this));
-// mCommitCallbackRegistrar.add("VoiceEffect.Activate", boost::bind(&LLFloaterVoiceEffect::onClickActivate, this));
-}
-
-// virtual
-LLFloaterVoiceEffect::~LLFloaterVoiceEffect()
-{
- if(LLVoiceClient::instanceExists())
- {
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (effect_interface)
- {
- effect_interface->removeObserver(this);
- }
- }
-}
-
-// virtual
-bool LLFloaterVoiceEffect::postBuild()
-{
- setDefaultBtn("record_btn");
- getChild<LLButton>("record_btn")->setFocus(true);
- getChild<LLUICtrl>("voice_morphing_link")->setTextArg("[URL]", LLTrans::getString("voice_morphing_url"));
-
- mVoiceEffectList = getChild<LLScrollListCtrl>("voice_effect_list");
- if (mVoiceEffectList)
- {
- mVoiceEffectList->setCommitCallback(boost::bind(&LLFloaterVoiceEffect::onClickPlay, this));
-// mVoiceEffectList->setDoubleClickCallback(boost::bind(&LLFloaterVoiceEffect::onClickActivate, this));
- }
-
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (effect_interface)
- {
- effect_interface->addObserver(this);
-
- // Disconnect from the current voice channel ready to record a voice sample for previewing
- effect_interface->enablePreviewBuffer(true);
- }
-
- refreshEffectList();
- updateControls();
-
- return true;
-}
-
-// virtual
-void LLFloaterVoiceEffect::onClose(bool app_quitting)
-{
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (effect_interface)
- {
- effect_interface->enablePreviewBuffer(false);
- }
-}
-
-void LLFloaterVoiceEffect::refreshEffectList()
-{
- if (!mVoiceEffectList)
- {
- return;
- }
-
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (!effect_interface)
- {
- mVoiceEffectList->setEnabled(false);
- return;
- }
-
- LL_DEBUGS("Voice")<< "Rebuilding Voice Morph list."<< LL_ENDL;
-
- // Preserve selected items and scroll position
- S32 scroll_pos = mVoiceEffectList->getScrollPos();
- uuid_vec_t selected_items;
- std::vector<LLScrollListItem*> items = mVoiceEffectList->getAllSelected();
- for(std::vector<LLScrollListItem*>::const_iterator it = items.begin(); it != items.end(); it++)
- {
- selected_items.push_back((*it)->getUUID());
- }
-
- mVoiceEffectList->deleteAllItems();
-
- {
- // Add the "No Voice Morph" entry
- LLSD element;
-
- element["id"] = LLUUID::null;
- element["columns"][NAME_COLUMN]["column"] = "name";
- element["columns"][NAME_COLUMN]["value"] = getString("no_voice_effect");
- element["columns"][NAME_COLUMN]["font"]["style"] = "BOLD";
-
- LLScrollListItem* sl_item = mVoiceEffectList->addElement(element, ADD_BOTTOM);
- // *HACK: Copied from llfloatergesture.cpp : ["font"]["style"] does not affect font style :(
- if(sl_item)
- {
- ((LLScrollListText*)sl_item->getColumn(0))->setFontStyle(LLFontGL::BOLD);
- }
- }
-
- // Add each Voice Morph template, if there are any (template list includes all usable effects)
- const voice_effect_list_t& template_list = effect_interface->getVoiceEffectTemplateList();
- if (!template_list.empty())
- {
- for (voice_effect_list_t::const_iterator it = template_list.begin(); it != template_list.end(); ++it)
- {
- const LLUUID& effect_id = it->second;
-
- std::string localized_effect = "effect_" + it->first;
- std::string effect_name = hasString(localized_effect) ? getString(localized_effect) : it->first; // XML contains localized effects names
-
- LLSD effect_properties = effect_interface->getVoiceEffectProperties(effect_id);
-
- // Tag the active effect.
- if (effect_id == LLVoiceClient::instance().getVoiceEffectDefault())
- {
- effect_name += " " + getString("active_voice_effect");
- }
-
- // Tag available effects that are new this session
- if (effect_properties["is_new"].asBoolean())
- {
- effect_name += " " + getString("new_voice_effect");
- }
-
- LLDate expiry_date = effect_properties["expiry_date"].asDate();
- bool is_template_only = effect_properties["template_only"].asBoolean();
-
- std::string font_style = "NORMAL";
- if (!is_template_only)
- {
- font_style = "BOLD";
- }
-
- LLSD element;
- element["id"] = effect_id;
-
- element["columns"][NAME_COLUMN]["column"] = "name";
- element["columns"][NAME_COLUMN]["value"] = effect_name;
- element["columns"][NAME_COLUMN]["font"]["style"] = font_style;
-
- element["columns"][1]["column"] = "expires";
- if (!is_template_only)
- {
- element["columns"][DATE_COLUMN]["value"] = expiry_date;
- element["columns"][DATE_COLUMN]["type"] = "date";
- }
- else {
- element["columns"][DATE_COLUMN]["value"] = getString("unsubscribed_voice_effect");
- }
-// element["columns"][DATE_COLUMN]["font"]["style"] = "NORMAL";
-
- LLScrollListItem* sl_item = mVoiceEffectList->addElement(element, ADD_BOTTOM);
- // *HACK: Copied from llfloatergesture.cpp : ["font"]["style"] does not affect font style :(
- if(sl_item)
- {
- LLFontGL::StyleFlags style = is_template_only ? LLFontGL::NORMAL : LLFontGL::BOLD;
- LLScrollListText* slt = dynamic_cast<LLScrollListText*>(sl_item->getColumn(0));
- llassert(slt);
- if (slt)
- {
- slt->setFontStyle(style);
- }
- }
- }
- }
-
- // Re-select items that were selected before, and restore the scroll position
- for(uuid_vec_t::iterator it = selected_items.begin(); it != selected_items.end(); it++)
- {
- mVoiceEffectList->selectByID(*it);
- }
- mVoiceEffectList->setScrollPos(scroll_pos);
- mVoiceEffectList->setEnabled(true);
-}
-
-void LLFloaterVoiceEffect::updateControls()
-{
- bool recording = false;
-
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (effect_interface)
- {
- recording = effect_interface->isPreviewRecording();
- }
-
- getChild<LLButton>("record_btn")->setVisible(!recording);
- getChild<LLButton>("record_stop_btn")->setVisible(recording);
-}
-
-// virtual
-void LLFloaterVoiceEffect::onVoiceEffectChanged(bool effect_list_updated)
-{
- if (effect_list_updated)
- {
- refreshEffectList();
- }
- updateControls();
-}
-
-void LLFloaterVoiceEffect::onClickRecord()
-{
- LL_DEBUGS("Voice") << "Record clicked" << LL_ENDL;
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (effect_interface)
- {
- effect_interface->recordPreviewBuffer();
- }
- updateControls();
-}
-
-void LLFloaterVoiceEffect::onClickPlay()
-{
- LL_DEBUGS("Voice") << "Play clicked" << LL_ENDL;
- if (!mVoiceEffectList)
- {
- return;
- }
-
- const LLUUID& effect_id = mVoiceEffectList->getCurrentID();
-
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (effect_interface)
- {
- effect_interface->playPreviewBuffer(effect_id);
- }
- updateControls();
-}
-
-void LLFloaterVoiceEffect::onClickStop()
-{
- LL_DEBUGS("Voice") << "Stop clicked" << LL_ENDL;
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (effect_interface)
- {
- effect_interface->stopPreviewBuffer();
- }
- updateControls();
-}
-
-//void LLFloaterVoiceEffect::onClickActivate()
-//{
-// LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
-// if (effect_interface && mVoiceEffectList)
-// {
-// effect_interface->setVoiceEffect(mVoiceEffectList->getCurrentID());
-// }
-//}
-
diff --git a/indra/newview/llfloatervoiceeffect.h b/indra/newview/llfloatervoiceeffect.h
deleted file mode 100644
index 323beb64ae..0000000000
--- a/indra/newview/llfloatervoiceeffect.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * @file llfloatervoiceeffect.h
- * @author Aimee
- * @brief Selection and preview of voice effects.
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLFLOATERVOICEEFFECT_H
-#define LL_LLFLOATERVOICEEFFECT_H
-
-#include "llfloater.h"
-#include "llvoiceclient.h"
-
-class LLButton;
-class LLScrollListCtrl;
-
-class LLFloaterVoiceEffect
- : public LLFloater
- , public LLVoiceEffectObserver
-{
-public:
- LOG_CLASS(LLFloaterVoiceEffect);
-
- LLFloaterVoiceEffect(const LLSD& key);
- virtual ~LLFloaterVoiceEffect();
-
- bool postBuild() override;
- void onClose(bool app_quitting) override;
-
-private:
- enum ColumnIndex
- {
- NAME_COLUMN = 0,
- DATE_COLUMN = 1,
- };
-
- void refreshEffectList();
- void updateControls();
-
- /// Called by voice effect provider when voice effect list is changed.
- virtual void onVoiceEffectChanged(bool effect_list_updated) override;
-
- void onClickRecord();
- void onClickPlay();
- void onClickStop();
-// void onClickActivate();
-
- LLUUID mSelectedID;
- LLScrollListCtrl* mVoiceEffectList;
-};
-
-#endif
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index ac8477a615..b784419780 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -170,7 +170,7 @@ namespace
void LLGLTFMaterialList::applyOverrideMessage(LLMessageSystem* msg, const std::string& data_in)
{
- std::istringstream str(data_in);
+ boost::iostreams::stream<boost::iostreams::array_source> str(data_in.data(), data_in.size());
LLSD data;
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 7659e5f082..074cda1683 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -317,7 +317,7 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
// virtual
bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
- // Why is "new group" sufficient?
+ // "new group" is sufficient because update_group_floaters always calls that on group changes
if (event->desc() == "new group")
{
setDirty();
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 11f049564a..4327d281e5 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -301,7 +301,7 @@ void LLHUDNameTag::renderText()
const S32 label_height = ll_round((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));
label_top_rect.mBottom = label_top_rect.mTop - label_height;
LLColor4 label_top_color = text_color;
- label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor;
+ label_top_color.mV[VALPHA] = bubble_opacity() * alpha_factor;
mRoundedRectTopImgp->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 7d9fad5a54..5d41cac5e1 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -336,7 +336,7 @@ bool LLInvFVBridge::cutToClipboard()
const LLInventoryObject* obj = gInventory.getObject(mUUID);
if (obj && isItemMovable() && isItemRemovable())
{
- const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
const bool cut_from_marketplacelistings = gInventory.isObjectDescendentOf(mUUID, marketplacelistings_id);
if (cut_from_marketplacelistings && (LLMarketplaceData::instance().isInActiveFolder(mUUID) ||
@@ -1378,7 +1378,7 @@ bool LLInvFVBridge::isInboxFolder() const
bool LLInvFVBridge::isMarketplaceListingsFolder() const
{
- const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID folder_id = gInventory.getMarketplaceListingsUUID();
if (folder_id.isNull())
{
@@ -1686,7 +1686,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
{
std::string error_msg;
LLInventoryModel* model = getInventoryModel();
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &marketplacelistings_id = model->getMarketplaceListingsUUID();
if (marketplacelistings_id.notNull())
{
LLViewerInventoryCategory * master_folder = model->getCategory(marketplacelistings_id);
@@ -1845,7 +1845,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
{
LLInventoryItem* itemp = model->getItem(mUUID);
if (!itemp) return;
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
// Note: For a single item, if it's not a copy, then it's a move
move_item_to_marketplacelistings(itemp, marketplacelistings_id, ("copy_to_marketplace_listings" == action));
}
@@ -2685,7 +2685,7 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
const LLUUID &cat_id = inv_cat->getUUID();
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
const LLUUID from_folder_uuid = inv_cat->getParentUUID();
const bool move_is_into_current_outfit = (mUUID == current_outfit_id);
@@ -3765,7 +3765,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
{
LLInventoryCategory * cat = gInventory.getCategory(mUUID);
if (!cat) return;
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
move_folder_to_marketplacelistings(cat, marketplacelistings_id, ("move_to_marketplace_listings" != action), (("copy_or_move_to_marketplace_listings" == action)));
}
else if ("copy_folder_uuid" == action)
@@ -4019,7 +4019,7 @@ void LLFolderBridge::pasteFromClipboard()
LLInventoryModel* model = getInventoryModel();
if (model && isClipboardPasteable())
{
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &marketplacelistings_id = model->getMarketplaceListingsUUID();
const bool paste_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
bool cut_from_marketplacelistings = false;
@@ -4081,7 +4081,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
if (model && isClipboardPasteable())
{
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
@@ -4378,7 +4378,7 @@ void LLFolderBridge::pasteLinkFromClipboard()
if(model)
{
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
const bool move_is_into_current_outfit = (mUUID == current_outfit_id);
@@ -4478,7 +4478,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
const LLUUID &favorites = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- const LLUUID &marketplace_listings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplace_listings_id = model->getMarketplaceListingsUUID();
const LLUUID &outfits_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
if (outfits_id == mUUID)
@@ -5717,7 +5717,7 @@ bool LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
const LLUUID from_folder_uuid = inv_item->getParentUUID();
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 3cc57e851f..7522ea4907 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -405,7 +405,7 @@ void update_all_marketplace_count(const LLUUID& cat_id)
void update_all_marketplace_count()
{
// Get the marketplace root and launch the recursive exploration
- const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplace_listings_uuid = gInventory.getMarketplaceListingsUUID();
if (!marketplace_listings_uuid.isNull())
{
update_all_marketplace_count(marketplace_listings_uuid);
@@ -1050,11 +1050,7 @@ void open_marketplace_listings()
S32 depth_nesting_in_marketplace(LLUUID cur_uuid)
{
- // Get the marketplace listings root, exit with -1 (i.e. not under the marketplace listings root) if none
- // Todo: findCategoryUUIDForType is somewhat expensive with large
- // flat root folders yet we use depth_nesting_in_marketplace at
- // every turn, find a way to correctly cache this id.
- const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplace_listings_uuid = gInventory.getMarketplaceListingsUUID();
if (marketplace_listings_uuid.isNull())
{
return -1;
@@ -2559,7 +2555,7 @@ bool get_is_favorite(const LLUUID& obj_id)
return obj && obj->getIsFavorite();
}
- return object->getIsFavorite();
+ return object && object->getIsFavorite();
}
void set_favorite(const LLUUID& obj_id, bool favorite)
@@ -3420,7 +3416,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
if ("delete" == action)
{
- const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
bool marketplacelistings_item = false;
bool has_worn = false;
bool needs_replacement = false;
@@ -3601,7 +3597,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
if (action == "wear" || action == "wear_add")
{
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID mp_id = gInventory.getMarketplaceListingsUUID();
std::copy_if(selected_uuid_set.begin(),
selected_uuid_set.end(),
std::back_inserter(ids),
@@ -4011,7 +4007,7 @@ void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root)
// target listing *and* the original listing. So we need to keep track of both.
// Note: do not however put the marketplace listings root itself in this list or the whole marketplace data will be rebuilt.
sMarketplaceFolders.clear();
- const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.isNull())
{
return;
diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index f77088e0b1..24b0866041 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -1726,7 +1726,7 @@ bool is_category_removable(const LLUUID& folder_id, bool check_worn)
}
}
- const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID mp_id = gInventory.getMarketplaceListingsUUID();
if (mp_id.notNull() && gInventory.isObjectDescendentOf(folder_id, mp_id))
{
return false;
@@ -1768,7 +1768,7 @@ void LLInventoryGallery::paste()
return;
}
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (mSelectedItemIDs.size() == 1 && gInventory.isObjectDescendentOf(*mSelectedItemIDs.begin(), marketplacelistings_id))
{
return;
@@ -2114,7 +2114,7 @@ void LLInventoryGallery::pasteAsLink()
}
const LLUUID& current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
const LLUUID& my_outifts_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
std::vector<LLUUID> objects;
@@ -3333,7 +3333,7 @@ bool dragItemIntoFolder(LLUUID folder_id, LLInventoryItem* inv_item, bool drop,
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
const bool move_is_into_current_outfit = (folder_id == current_outfit_id);
@@ -3727,7 +3727,7 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat,
const LLUUID &cat_id = inv_cat->getUUID();
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
//const LLUUID from_folder_uuid = inv_cat->getParentUUID();
const bool move_is_into_current_outfit = (dest_id == current_outfit_id);
const bool move_is_into_marketplacelistings = model->isObjectDescendentOf(dest_id, marketplacelistings_id);
diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp
index 22f6414960..ff7cab0ee3 100644
--- a/indra/newview/llinventorygallerymenu.cpp
+++ b/indra/newview/llinventorygallerymenu.cpp
@@ -409,7 +409,7 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata)
if (can_copy)
{
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (itemp)
{
move_item_to_marketplacelistings(itemp, marketplacelistings_id, copy_operation);
@@ -428,7 +428,7 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata)
// option == 0 Move no copy item(s)
// option == 1 Don't move no copy item(s) (leave them behind)
bool copy_and_move = option == 0;
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
// main inventory only allows one item?
LLViewerInventoryItem* itemp = gInventory.getItem(lamdba_list.front());
@@ -563,7 +563,7 @@ bool can_list_on_marketplace(const LLUUID &id)
if (can_list)
{
std::string error_msg;
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.notNull())
{
LLViewerInventoryCategory* master_folder = gInventory.getCategory(marketplacelistings_id);
@@ -1065,7 +1065,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
// Marketplace
bool can_list = false;
- const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.notNull() && !is_inbox && !obj->getIsLinkType())
{
if (is_folder)
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index a435a4f7c7..aa6ba6d023 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -41,7 +41,7 @@
#include "llinventorymodel.h"
#include "llviewerinventory.h"
-static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(&typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item");
constexpr S32 WIDGET_SPACING = 3;
constexpr S32 FAVORITE_IMAGE_SIZE = 14;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 3a7bc20c30..a8bc3b361e 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -975,6 +975,15 @@ const LLUUID LLInventoryModel::findLibraryCategoryUUIDForType(LLFolderType::ETyp
return findCategoryUUIDForTypeInRoot(preferred_type, gInventory.getLibraryRootFolderID());
}
+const LLUUID LLInventoryModel::getMarketplaceListingsUUID()
+{
+ if (mMarketplaceListingsUUID.isNull())
+ {
+ mMarketplaceListingsUUID = findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ }
+ return mMarketplaceListingsUUID;
+}
+
// Convenience function to create a new category. You could call
// updateCategory() with a newly generated UUID category, but this
// version will take care of details like what the name should be
@@ -1692,7 +1701,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32
mask |= LLInventoryObserver::LABEL;
}
// Under marketplace, category labels are quite complex and need extra upate
- const LLUUID marketplace_id = findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplace_id = getMarketplaceListingsUUID();
if (marketplace_id.notNull() && isObjectDescendentOf(cat->getUUID(), marketplace_id))
{
mask |= LLInventoryObserver::LABEL;
@@ -3416,6 +3425,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
LLSD inventory;
if (!is_cache_obsolete)
{
+ LL_PROFILE_ZONE_NAMED("inventory load from file - llsd parse");
LLPointer<LLSDParser> parser = new LLSDBinaryParser();
if (parser->parse(file, inventory, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
@@ -3427,56 +3437,61 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
if (!is_cache_obsolete)
{
- const LLSD& llsd_cats = inventory["categories"];
- if (llsd_cats.isArray())
{
- LLSD::array_const_iterator iter = llsd_cats.beginArray();
- LLSD::array_const_iterator end = llsd_cats.endArray();
- for (; iter != end; ++iter)
+ LL_PROFILE_ZONE_NAMED("inventory load from file - categories");
+ const LLSD& llsd_cats = inventory["categories"];
+ if (llsd_cats.isArray())
{
- LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null);
- if (inv_cat->importLLSDMap(*iter))
+ LLSD::array_const_iterator iter = llsd_cats.beginArray();
+ LLSD::array_const_iterator end = llsd_cats.endArray();
+ for (; iter != end; ++iter)
{
- categories.push_back(inv_cat);
+ LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null);
+ if (inv_cat->importLLSDMap(*iter))
+ {
+ categories.push_back(inv_cat);
+ }
}
}
}
- const LLSD& llsd_items = inventory["items"];
- if (llsd_items.isArray())
{
- LLSD::array_const_iterator iter = llsd_items.beginArray();
- LLSD::array_const_iterator end = llsd_items.endArray();
- for (; iter != end; ++iter)
+ LL_PROFILE_ZONE_NAMED("inventory load from file - items");
+ const LLSD& llsd_items = inventory["items"];
+ if (llsd_items.isArray())
{
- LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem;
- if (inv_item->fromLLSD(*iter))
+ LLSD::array_const_iterator iter = llsd_items.beginArray();
+ LLSD::array_const_iterator end = llsd_items.endArray();
+ for (; iter != end; ++iter)
{
- if (inv_item->getUUID().isNull())
- {
- LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: "
- << inv_item->getName() << LL_ENDL;
- }
- else
+ LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem;
+ if (inv_item->fromLLSD(*iter))
{
- if (inv_item->getType() == LLAssetType::AT_UNKNOWN)
+ if (inv_item->getUUID().isNull())
{
- cats_to_update.insert(inv_item->getParentUUID());
+ LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: " << inv_item->getName() << LL_ENDL;
}
else
{
- items.push_back(inv_item);
+ if (inv_item->getType() == LLAssetType::AT_UNKNOWN)
+ {
+ cats_to_update.insert(inv_item->getParentUUID());
+ }
+ else
+ {
+ items.push_back(inv_item);
+ }
}
}
- }
- // TODO(brad) - figure out how to reenable this without breaking everything else
- // static constexpr U64 BATCH_SIZE = 512U;
- // if ((++lines_count % BATCH_SIZE) == 0)
- // {
- // // SL-19968 - make sure message system code gets a chance to run every so often
- // pump_idle_startup_network();
- // }
+ // TODO(brad) - figure out how to reenable this without breaking everything else
+ // static constexpr U64 BATCH_SIZE = 512U;
+ // if ((++lines_count % BATCH_SIZE) == 0)
+ // {
+ // // SL-19968 - make sure message system code gets a chance to run every so often
+ // pump_idle_startup_network();
+ // }
+ }
}
}
}
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 2859923df9..05ada9121a 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -201,13 +201,13 @@ private:
// the inventory using several different identifiers.
// mInventory member data is the 'master' list of inventory, and
// mCategoryMap and mItemMap store uuid->object mappings.
- typedef std::map<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
- typedef std::map<LLUUID, LLPointer<LLViewerInventoryItem> > item_map_t;
+ typedef std::unordered_map<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
+ typedef std::unordered_map<LLUUID, LLPointer<LLViewerInventoryItem>> item_map_t;
cat_map_t mCategoryMap;
item_map_t mItemMap;
// This last set of indices is used to map parents to children.
- typedef std::map<LLUUID, cat_array_t*> parent_cat_map_t;
- typedef std::map<LLUUID, item_array_t*> parent_item_map_t;
+ typedef std::unordered_map<LLUUID, cat_array_t*> parent_cat_map_t;
+ typedef std::unordered_map<LLUUID, item_array_t*> parent_item_map_t;
parent_cat_map_t mParentChildCategoryTree;
parent_item_map_t mParentChildItemTree;
@@ -329,6 +329,8 @@ public:
// user specified one or it does not exist, creates default category if it is missing.
const LLUUID findUserDefinedCategoryUUIDForType(LLFolderType::EType preferred_type) const;
+ const LLUUID getMarketplaceListingsUUID();
+
// Get whatever special folder this object is a child of, if any.
const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const;
@@ -361,6 +363,8 @@ public:
private:
mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups
+ LLUUID mMarketplaceListingsUUID;
+
//--------------------------------------------------------------------
// Count
//--------------------------------------------------------------------
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 1e5f771ba7..82eefb50ac 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -828,7 +828,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis()
// Intent is for marketplace request to happen after
// main inventory is done, unless requested by floater
mRecursiveMarketplaceFetchStarted = true;
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.notNull())
{
mFetchFolderQueue.emplace_front(marketplacelistings_id, FT_FOLDER_AND_CONTENT);
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 9919dd5f8f..039567ea76 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1855,6 +1855,7 @@ void LLInventoryPanel::purgeSelectedItems()
{
if (!mFolderRoot.get()) return;
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
const std::set<LLFolderViewItem*> inventory_selected = mFolderRoot.get()->getSelectionList();
if (inventory_selected.empty()) return;
LLSD args;
@@ -1864,12 +1865,17 @@ void LLInventoryPanel::purgeSelectedItems()
it != end_it;
++it)
{
+ // Selection allows items outside trash folder, only count the ones inside.
LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- gInventory.collectDescendents(item_id, cats, items, LLInventoryModel::INCLUDE_TRASH);
- count += items.size() + cats.size();
- selected_items.push_back(item_id);
+ LLInventoryObject* obj = gInventory.getObject(item_id);
+ if (obj->getParentUUID() == trash_id)
+ {
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(item_id, cats, items, LLInventoryModel::INCLUDE_TRASH);
+ count += items.size() + cats.size();
+ selected_items.push_back(item_id);
+ }
}
args["COUNT"] = static_cast<S32>(count);
LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(callbackPurgeSelectedItems, _1, _2, selected_items));
@@ -2125,8 +2131,7 @@ LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id)
{
LL_PROFILE_ZONE_SCOPED;
- std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
- map_it = mItemMap.find(id);
+ auto map_it = mItemMap.find(id);
if (map_it != mItemMap.end())
{
return map_it->second;
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 644e0a1855..a17817c764 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -301,7 +301,7 @@ protected:
LLPointer<LLFolderViewGroupedItemBridge> mGroupedItemBridge;
Params mParams; // stored copy of parameter block
- std::map<LLUUID, LLFolderViewItem*> mItemMap;
+ std::unordered_map<LLUUID, LLFolderViewItem*> mItemMap;
/**
* Pointer to LLInventoryFolderViewModelBuilder.
*
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 6e56aac270..1329b1308d 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -596,7 +596,7 @@ void LLLocalBitmap::updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel)
if (object->isSculpted() && object->getVolume() &&
object->getVolume()->getParams().getSculptID() == old_id)
{
- LLSculptParams* old_params = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams* old_params = object->getSculptParams();
LLSculptParams new_params(*old_params);
new_params.setSculptTexture(new_id, (*old_params).getSculptType());
object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, new_params, true);
diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp
index 51c38aba3a..0a90cf0699 100644
--- a/indra/newview/llmachineid.cpp
+++ b/indra/newview/llmachineid.cpp
@@ -398,6 +398,8 @@ bool getSerialNumber(unsigned char *unique_id, size_t len)
S32 LLMachineID::init()
{
+ LL_PROFILE_ZONE_SCOPED;
+
size_t len = sizeof(static_unique_id);
memset(static_unique_id, 0, len);
S32 ret_code = 0;
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index ac2f52a262..30f634f6d4 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -850,7 +850,7 @@ void LLMarketplaceData::setDataFetchedSignal(const status_updated_signal_t::slot
// Get/Post/Put requests to the SLM Server using the SLM API
void LLMarketplaceData::getSLMListings()
{
- const LLUUID marketplaceFolderId = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplaceFolderId = gInventory.getMarketplaceListingsUUID();
setUpdating(marketplaceFolderId, true);
LLCoros::instance().launch("getSLMListings",
@@ -1757,7 +1757,7 @@ bool LLMarketplaceData::isUpdating(const LLUUID& folder_id, S32 depth)
}
else
{
- const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplace_listings_uuid = gInventory.getMarketplaceListingsUUID();
std::set<LLUUID>::iterator it = mPendingUpdateSet.find(marketplace_listings_uuid);
if (it != mPendingUpdateSet.end())
{
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index 1279b77ad4..c04f874923 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -33,9 +33,42 @@
#include "httprequest.h"
#include "httpheaders.h"
#include "httpoptions.h"
+#include <boost/container_hash/hash.hpp>
class LLViewerRegion;
+// struct for TE-specific material ID query
+class TEMaterialPair
+{
+public:
+ U32 te;
+ LLMaterialID materialID;
+
+ bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); }
+};
+
+inline bool operator<(const TEMaterialPair& lhs, const TEMaterialPair& rhs)
+{
+ return (lhs.te < rhs.te) ? true : (lhs.materialID < rhs.materialID);
+}
+
+// std::hash implementation for TEMaterialPair
+namespace std
+{
+ template<>
+ struct hash<TEMaterialPair>
+ {
+ inline size_t operator()(const TEMaterialPair& p) const noexcept
+ {
+ // Utilize boost::hash_combine to generate a good hash
+ size_t seed = 0;
+ boost::hash_combine(seed, p.te + 1);
+ boost::hash_combine(seed, p.materialID);
+ return seed;
+ }
+ };
+} // namespace std
+
class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
{
LLSINGLETON(LLMaterialMgr);
@@ -83,29 +116,6 @@ private:
void onRegionRemoved(LLViewerRegion* regionp);
private:
- // struct for TE-specific material ID query
- class TEMaterialPair
- {
- public:
-
- U32 te;
- LLMaterialID materialID;
-
- bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); }
- };
-
- // definitions follow class
- friend std::hash<TEMaterialPair>;
- friend size_t hash_value(const TEMaterialPair&) noexcept;
-
- friend inline bool operator<(
- const LLMaterialMgr::TEMaterialPair& lhs,
- const LLMaterialMgr::TEMaterialPair& rhs)
- {
- return (lhs.te < rhs.te) ? true :
- (lhs.materialID < rhs.materialID);
- }
-
typedef std::set<LLMaterialID> material_queue_t;
typedef std::map<LLUUID, material_queue_t> get_queue_t;
typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
@@ -113,7 +123,7 @@ private:
typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
- typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*> get_callback_te_map_t;
+ typedef std::unordered_map<TEMaterialPair, get_callback_te_t*> get_callback_te_map_t;
typedef std::set<LLUUID> getall_queue_t;
typedef std::map<LLUUID, F64> getall_pending_map_t;
typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t;
@@ -142,23 +152,5 @@ private:
U32 getMaxEntries(const LLViewerRegion* regionp);
};
-// std::hash implementation for TEMaterialPair
-namespace std
-{
- template<> struct hash<LLMaterialMgr::TEMaterialPair>
- {
- inline size_t operator()(const LLMaterialMgr::TEMaterialPair& p) const noexcept
- {
- return size_t((p.te + 1) * p.materialID.getDigest64());
- }
- };
-}
-
-// For use with boost containers.
-inline size_t hash_value(const LLMaterialMgr::TEMaterialPair& p) noexcept
-{
- return size_t((p.te + 1) * p.materialID.getDigest64());
-}
-
#endif // LL_LLMATERIALMGR_H
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index c0b1a5326a..20bda5039d 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -3331,6 +3331,8 @@ void LLMeshRepoThread::notifyLoadedMeshes()
loaded_queue.swap(mLoadedQ);
mLoadedMutex->unlock();
+ LL_PROFILE_ZONE_NAMED("notify loaded meshes");
+
update_metrics = true;
// Process the elements free of the lock
@@ -3362,6 +3364,8 @@ void LLMeshRepoThread::notifyLoadedMeshes()
unavil_queue.swap(mUnavailableQ);
mLoadedMutex->unlock();
+ LL_PROFILE_ZONE_NAMED("notify unavail meshes");
+
update_metrics = true;
// Process the elements free of the lock
@@ -3380,6 +3384,7 @@ void LLMeshRepoThread::notifyLoadedMeshes()
{
if (mLoadedMutex->trylock())
{
+ LL_PROFILE_ZONE_NAMED("notify misc meshes");
std::deque<LLPointer<LLMeshSkinInfo>> skin_info_q;
std::deque<UUIDBasedRequest> skin_info_unavail_q;
std::list<LLModel::Decomposition*> decomp_q;
@@ -4271,20 +4276,63 @@ S32 LLMeshRepository::update()
return static_cast<S32>(size);
}
-void LLMeshRepository::unregisterMesh(LLVOVolume* vobj)
+void LLMeshRepository::unregisterMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail)
{
- for (auto& lod : mLoadingMeshes)
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ llassert((mesh_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH);
+ llassert(mesh_params.getSculptID().notNull());
+ auto& lod = mLoadingMeshes[detail];
+ auto param_iter = lod.find(mesh_params.getSculptID());
+ if (param_iter != lod.end())
{
- for (auto& param : lod)
+ param_iter->second.mVolumes.erase(vobj);
+ llassert(!param_iter->second.mVolumes.contains(vobj));
+ if (param_iter->second.mVolumes.empty())
{
- vector_replace_with_last(param.second.mVolumes, vobj);
+ lod.erase(param_iter);
}
}
+}
- for (auto& skin_pair : mLoadingSkins)
+void LLMeshRepository::unregisterSkinInfo(const LLUUID& mesh_id, LLVOVolume* vobj)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ llassert(mesh_id.notNull());
+ auto skin_pair_iter = mLoadingSkins.find(mesh_id);
+ if (skin_pair_iter != mLoadingSkins.end())
+ {
+ skin_pair_iter->second.mVolumes.erase(vobj);
+ llassert(!skin_pair_iter->second.mVolumes.contains(vobj));
+ if (skin_pair_iter->second.mVolumes.empty())
+ {
+ mLoadingSkins.erase(skin_pair_iter);
+ }
+ }
+}
+
+// Lots of dead objects make expensive calls to
+// LLMeshRepository::unregisterMesh which may delay shutdown. Avoid this by
+// preemptively unregistering all meshes.
+// We can also do this safely if all objects are confirmed dead for some other
+// reason.
+void LLMeshRepository::unregisterAllMeshes()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ // The size of mLoadingMeshes and mLoadingSkins may be large and thus
+ // expensive to iterate over in LLVOVolume::~LLVOVolume.
+ // This is unnecessary during shutdown, so we ignore the referenced objects in the
+ // least expensive way which is still safe: by clearing these containers.
+ // Clear now and not in LLMeshRepository::shutdown because
+ // LLMeshRepository::notifyLoadedMeshes could (depending on invocation
+ // order) reference a pointer to an object after it has been deleted.
+ for (auto& lod : mLoadingMeshes)
{
- vector_replace_with_last(skin_pair.second.mVolumes, vobj);
+ lod.clear();
}
+ mLoadingSkins.clear();
}
S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 new_lod, S32 last_lod)
@@ -4306,7 +4354,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
mesh_load_map::iterator iter = mLoadingMeshes[new_lod].find(mesh_id);
if (iter != mLoadingMeshes[new_lod].end())
{ //request pending for this mesh, append volume id to list
- auto it = std::find(iter->second.mVolumes.begin(), iter->second.mVolumes.end(), vobj);
+ auto it = iter->second.mVolumes.find(vobj);
if (it == iter->second.mVolumes.end()) {
iter->second.addVolume(vobj);
}
@@ -4804,7 +4852,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOV
skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);
if (iter != mLoadingSkins.end())
{ //request pending for this mesh, append volume id to list
- auto it = std::find(iter->second.mVolumes.begin(), iter->second.mVolumes.end(), requesting_obj);
+ auto it = iter->second.mVolumes.find(requesting_obj);
if (it == iter->second.mVolumes.end()) {
iter->second.addVolume(requesting_obj);
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 01b51e753e..061b4b5428 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -290,7 +290,7 @@ private:
class MeshLoadData
{
public:
- MeshLoadData() {}
+ MeshLoadData() = default;
~MeshLoadData()
{
if (std::shared_ptr<PendingRequestBase> request = mRequest.lock())
@@ -300,19 +300,19 @@ public:
}
void initData(LLVOVolume* vol, std::shared_ptr<PendingRequestBase>& request)
{
- mVolumes.push_back(vol);
+ mVolumes.insert(vol);
request->trackData(this);
mRequest = request;
}
void addVolume(LLVOVolume* vol)
{
- mVolumes.push_back(vol);
+ mVolumes.insert(vol);
if (std::shared_ptr<PendingRequestBase> request = mRequest.lock())
{
request->setScoreDirty();
}
}
- std::vector<LLVOVolume*> mVolumes;
+ std::unordered_set<LLVOVolume*> mVolumes;
private:
std::weak_ptr<PendingRequestBase> mRequest;
};
@@ -442,7 +442,7 @@ public:
LLCondition* mSignal;
//map of known mesh headers
- typedef boost::unordered_map<LLUUID, LLMeshHeader> mesh_header_map; // pair is header_size and data
+ typedef std::unordered_map<LLUUID, LLMeshHeader> mesh_header_map; // pair is header_size and data
mesh_header_map mMeshHeader;
class HeaderRequest : public RequestStats
@@ -862,10 +862,12 @@ public:
LLMeshRepository();
void init();
+ void unregisterAllMeshes();
void shutdown();
S32 update();
- void unregisterMesh(LLVOVolume* volume);
+ void unregisterMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail);
+ void unregisterSkinInfo(const LLUUID& mesh_id, LLVOVolume* vobj);
//mesh management functions
S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 new_lod = 0, S32 last_lod = -1);
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 6a7c25ec0f..d3f28b3c18 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -3461,7 +3461,7 @@ bool LLModelPreview::render()
LLViewerCamera::getInstance()->setAspect(aspect);
- LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
+ LLViewerCamera::getInstance()->setViewNoBroadcast(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
LLVector3 offset = mCameraOffset;
LLVector3 target_pos = mPreviewTarget + offset;
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index f47a8cd241..b7bba02b9d 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -582,6 +582,8 @@ std::vector<LLMute> LLMuteList::getMutes() const
//-----------------------------------------------------------------------------
bool LLMuteList::loadFromFile(const std::string& filename)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if(!filename.size())
{
LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL;
@@ -966,6 +968,8 @@ bool LLRenderMuteList::saveToFile()
bool LLRenderMuteList::loadFromFile()
{
+ LL_PROFILE_ZONE_SCOPED;
+
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt");
LLFILE* fp = LLFile::fopen(filename, "rb");
if (!fp)
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index dfead5ee8a..9a0612e9f9 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -712,7 +712,14 @@ void LLNavigationBar::resizeLayoutPanel()
}
void LLNavigationBar::invokeSearch(std::string search_text)
{
- LLFloaterReg::showInstance("search", LLSD().with("category", "standard").with("query", LLSD(search_text)));
+ LLSD key;
+ key["category"] = "standard";
+ key["query"] = search_text;
+ LLSD collections = LLSD::emptyArray();
+ collections.append("destinations");
+ collections.append("places");
+ key["collections"] = collections;
+ LLFloaterReg::showInstance("search", key);
}
void LLNavigationBar::clearHistoryCache()
diff --git a/indra/newview/llnearbyvoicemoderation.cpp b/indra/newview/llnearbyvoicemoderation.cpp
new file mode 100644
index 0000000000..a5ee0e9423
--- /dev/null
+++ b/indra/newview/llnearbyvoicemoderation.cpp
@@ -0,0 +1,220 @@
+/**
+ * @file llnearbyvoicemoderation.cpp
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llnotificationsutil.h"
+#include "llviewerregion.h"
+#include "llvoavatar.h"
+#include "llvoicechannel.h"
+#include "llvoiceclient.h"
+#include "llviewerobjectlist.h"
+#include "llviewerparcelmgr.h"
+#include "roles_constants.h"
+
+#include "llnearbyvoicemoderation.h"
+
+LLNearbyVoiceModeration::LLNearbyVoiceModeration()
+{
+}
+
+LLNearbyVoiceModeration::~LLNearbyVoiceModeration()
+{
+}
+
+LLVOAvatar* LLNearbyVoiceModeration::getVOAvatarFromId(const LLUUID& agent_id)
+{
+ LLViewerObject *obj = gObjectList.findObject(agent_id);
+ while (obj && obj->isAttachment())
+ {
+ obj = (LLViewerObject*)obj->getParent();
+ }
+
+ if (obj && obj->isAvatar())
+ {
+ return (LLVOAvatar*)obj;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+const std::string LLNearbyVoiceModeration::getCapUrlFromRegion(LLViewerRegion* region)
+{
+ if (! region || ! region->capabilitiesReceived())
+ {
+ return std::string();
+ }
+
+ std::string url = region->getCapability("SpatialVoiceModerationRequest");
+ if (url.empty())
+ {
+ LL_INFOS() << "Capability URL for region " << region->getName() << " is empty" << LL_ENDL;
+ return std::string();
+ }
+ LL_INFOS() << "Capability URL for region " << region->getName() << " is " << url << LL_ENDL;
+
+ return url;
+}
+
+void LLNearbyVoiceModeration::requestMuteIndividual(const LLUUID& agent_id, bool mute)
+{
+ LLVOAvatar* avatar = getVOAvatarFromId(agent_id);
+ if (avatar)
+ {
+ const std::string cap_url = getCapUrlFromRegion(avatar->getRegion());
+ if (cap_url.length())
+ {
+ const std::string operand = mute ? "mute" : "unmute";
+
+ LLSD body;
+ body["operand"] = operand;
+ body["agent_id"] = agent_id;
+
+ const std::string agent_name = avatar->getFullname();
+ LL_INFOS() << "Resident " << agent_name
+ << " (" << agent_id << ")" << " applying " << operand << LL_ENDL;
+
+ std::string success_msg =
+ STRINGIZE("Resident " << agent_name
+ << " (" << agent_id << ")" << " nearby voice was set to " << operand);
+
+ std::string failure_msg =
+ STRINGIZE("Unable to change voice muting for resident "
+ << agent_name << " (" << agent_id << ")");
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(
+ cap_url,
+ body,
+ success_msg,
+ failure_msg);
+ }
+ }
+}
+
+void LLNearbyVoiceModeration::requestMuteAll(bool mute)
+{
+ // Use our own avatar to get the region name
+ LLViewerRegion* region = gAgent.getRegion();
+
+ const std::string cap_url = getCapUrlFromRegion(region);
+ if (cap_url.length())
+ {
+ const std::string operand = mute ? "mute_all" : "unmute_all";
+
+ LLSD body;
+ body["operand"] = operand;
+
+ LL_INFOS() << "For all residents in this region, applying: " << operand << LL_ENDL;
+
+ std::string success_msg =
+ STRINGIZE("Nearby voice for all residents was set to: " << operand);
+
+ std::string failure_msg =
+ STRINGIZE("Unable to set nearby voice for all residents to: " << operand);
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(
+ cap_url,
+ body,
+ success_msg,
+ failure_msg);
+ }
+}
+
+void LLNearbyVoiceModeration::setMutedInfo(const std::string& channelID, bool mute)
+{
+ auto it = mChannelMuteMap.find(channelID);
+ if (it == mChannelMuteMap.end())
+ {
+ if (mute)
+ {
+ // Channel is new and being muted
+ showMutedNotification(true);
+ }
+ mChannelMuteMap[channelID] = mute;
+ }
+ else
+ {
+ if (it->second != mute)
+ {
+ // Flag changed
+ showMutedNotification(mute);
+ it->second = mute;
+ }
+ }
+ if (mute && LLVoiceClient::getInstance()->getUserPTTState())
+ {
+ LLVoiceClient::getInstance()->setUserPTTState(false);
+ }
+}
+
+bool LLNearbyVoiceModeration::showNotificationIfNeeded()
+{
+ if (LLVoiceClient::getInstance()->inProximalChannel() &&
+ LLVoiceClient::getInstance()->getIsModeratorMuted(gAgentID))
+ {
+ return showMutedNotification(true);
+ }
+ return false;
+}
+
+bool LLNearbyVoiceModeration::showMutedNotification(bool is_muted)
+{
+ // Check if the current voice channel is nearby chat
+ if (LLVoiceClient::getInstance()->inProximalChannel())
+ {
+ LLNotificationsUtil::add(is_muted ? "NearbyVoiceMutedByModerator" : "NearbyVoiceUnmutedByModerator");
+ return true;
+ }
+ return false;
+}
+
+bool LLNearbyVoiceModeration::isNearbyChatModerator()
+{
+ // Region doesn't support WebRTC voice
+ if (!gAgent.getRegion() || !gAgent.getRegion()->isRegionWebRTCEnabled())
+ {
+ return false;
+ }
+
+ // Only show moderator options when connected to spatial voice chat
+ LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
+ if (!channel || channel->getSessionID().notNull() || !LLAgent::isActionAllowed("speak"))
+ {
+ return false;
+ }
+
+ if (LLViewerParcelMgr::getInstance()->isVoiceRestricted())
+ {
+ // Only the parcel owner should have access to moderate parcel voice space
+ return LLViewerParcelMgr::getInstance()->allowVoiceModeration();
+ }
+ else
+ {
+ return gAgent.canManageEstate();
+ }
+}
diff --git a/indra/newview/llnearbyvoicemoderation.h b/indra/newview/llnearbyvoicemoderation.h
new file mode 100644
index 0000000000..619f169883
--- /dev/null
+++ b/indra/newview/llnearbyvoicemoderation.h
@@ -0,0 +1,50 @@
+/**
+ * @file llnearbyvoicemoderation.h
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+class LLVOAvatar;
+
+class LLNearbyVoiceModeration : public LLSingleton <LLNearbyVoiceModeration> {
+ LLSINGLETON(LLNearbyVoiceModeration);
+ ~LLNearbyVoiceModeration();
+
+ public:
+ void requestMuteIndividual(const LLUUID& userID, bool mute);
+ void requestMuteAll(bool mute);
+
+ void setMutedInfo(const std::string& channelID, bool mute);
+ bool showMutedNotification(bool is_muted);
+ bool showNotificationIfNeeded();
+
+ bool isNearbyChatModerator();
+
+ private:
+ LLVOAvatar* getVOAvatarFromId(const LLUUID& id);
+ const std::string getCapUrlFromRegion(LLViewerRegion* region);
+
+ boost::signals2::connection mParcelCallbackConnection;
+ std::map<std::string, bool> mChannelMuteMap;
+};
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index af472c4259..63ec43458b 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -47,6 +47,7 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "llappviewer.h" // for gDisconnected
+#include "llavataractions.h"
#include "llcallingcard.h" // LLAvatarTracker
#include "llfloaterland.h"
#include "llfloaterworldmap.h"
@@ -397,20 +398,41 @@ void LLNetMap::draw()
LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgentCamera.getCameraPositionGlobal());
- // Draw avatars
+ std::vector<std::pair<U32, bool>> indexed_avatars;
+ indexed_avatars.reserve(avatar_ids.size());
for (U32 i = 0; i < avatar_ids.size(); i++)
{
- LLUUID uuid = avatar_ids[i];
+ indexed_avatars.emplace_back(i, LLAvatarActions::isFriend(avatar_ids[i]));
+ }
+
+ // Sort avatars so non-friends are drawn first and friend dots will appear on top
+ std::sort(indexed_avatars.begin(), indexed_avatars.end(),
+ [](const auto& a, const auto& b) { return a.second < b.second; });
+
+ uuid_vec_t sorted_avatar_ids;
+ std::vector<LLVector3d> sorted_positions;
+ sorted_avatar_ids.reserve(avatar_ids.size());
+ sorted_positions.reserve(positions.size());
+
+ // Reorder avatar_ids and positions based on sorted indices
+ for (const auto& indexed_avatar : indexed_avatars)
+ {
+ sorted_avatar_ids.push_back(avatar_ids[indexed_avatar.first]);
+ sorted_positions.push_back(positions[indexed_avatar.first]);
+ }
+
+ // Draw avatars
+ for (U32 i = 0; i < sorted_avatar_ids.size(); i++)
+ {
+ LLUUID uuid = sorted_avatar_ids[i];
// Skip self, we'll draw it later
if (uuid == gAgent.getID()) continue;
- pos_map = globalPosToView(positions[i]);
-
- bool show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL);
+ pos_map = globalPosToView(sorted_positions[i]);
- LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color;
+ LLColor4 color = LLAvatarActions::isFriend(uuid) ? map_avatar_friend_color : map_avatar_color;
- unknown_relative_z = positions[i].mdV[VZ] >= COARSEUPDATE_MAX_Z &&
+ unknown_relative_z = sorted_positions[i].mdV[VZ] >= COARSEUPDATE_MAX_Z &&
camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z;
LLWorldMapView::drawAvatar(
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 8589afae06..852f2dab21 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -850,7 +850,12 @@ void LLOutfitGallery::updateAddedCategory(LLUUID cat_id)
// Start observing changes in "My Outfits" category.
mCategoriesObserver->addCategory(cat_id,
- boost::bind(&LLOutfitGallery::refreshOutfit, this, cat_id), true);
+ [this, cat_id]()
+ {
+ mPendingOutfitRefreshes.insert(cat_id);
+ startIdleLoop(cat_id);
+ },
+ true);
outfit_category->fetch();
refreshOutfit(cat_id);
@@ -901,6 +906,18 @@ void LLOutfitGallery::updateChangedCategoryName(LLViewerInventoryCategory *cat,
}
}
+bool LLOutfitGallery::updateOneOutfit()
+{
+ if (mPendingOutfitRefreshes.empty())
+ return false;
+
+ auto it = mPendingOutfitRefreshes.begin();
+ LLUUID outfit_id = *it;
+ mPendingOutfitRefreshes.erase(it);
+ refreshOutfit(outfit_id);
+ return true;
+}
+
void LLOutfitGallery::onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
{
if (mOutfitMenu && cat_id.notNull())
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 5801a32a39..183b6ea9d5 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -98,6 +98,7 @@ public:
/*virtual*/ void updateAddedCategory(LLUUID cat_id);
/*virtual*/ void updateRemovedCategory(LLUUID cat_id);
/*virtual*/ void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name);
+ /*virtual*/ bool updateOneOutfit(); // bulk processing, scheduled by observer when updates are needed
/*virtual*/ bool hasItemSelected();
/*virtual*/ bool canWearSelected();
@@ -190,6 +191,7 @@ private:
typedef item_num_map_t::value_type item_numb_map_value_t;
item_num_map_t mItemIndexMap;
std::map<S32, LLOutfitGalleryItem*> mIndexToItemMap;
+ std::set<LLUUID> mPendingOutfitRefreshes;
LLInventoryCategoriesObserver* mOutfitsObserver;
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 32831fcd9b..7db79c7010 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -1055,6 +1055,15 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id)
}
}
+void LLOutfitListBase::startIdleLoop(const LLUUID cat_id)
+{
+ if (mRefreshListState.CategoryUUID.isNull())
+ {
+ mRefreshListState.CategoryUUID = cat_id;
+ gIdleCallbacks.addFunction(onIdle, this);
+ }
+}
+
// static
void LLOutfitListBase::onIdle(void* userdata)
{
@@ -1129,6 +1138,14 @@ void LLOutfitListBase::onIdleRefreshList()
return;
}
+ // Let derived classes process their own updates.
+ while (updateOneOutfit())
+ {
+ curent_time = LLTimer::getTotalSeconds();
+ if (curent_time >= end_time)
+ return;
+ }
+
sortOutfits();
highlightBaseOutfit();
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index bcf7e45696..408ff07116 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -95,6 +95,17 @@ public:
virtual void updateAddedCategory(LLUUID cat_id) = 0;
virtual void updateRemovedCategory(LLUUID cat_id) = 0;
virtual void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name) = 0;
+
+ /*
+ * Optional hook for derived classes to perform additional processing.
+ * This is called by the outfit list update logic after the core
+ * bookkeeping for an outfit has been handled.
+ *
+ * @return true if update processing should continue,
+ * false if no additional work is required.
+ * The base implementation returns false.
+ */
+ virtual bool updateOneOutfit() { return false; };
virtual void sortOutfits();
void removeSelected();
@@ -138,6 +149,7 @@ protected:
bool isOutfitFolder(LLViewerInventoryCategory* cat) const;
+ void startIdleLoop(const LLUUID cat_id);
static void onIdle(void* userdata);
void onIdleRefreshList();
@@ -150,6 +162,7 @@ protected:
uuid_vec_t::const_iterator RemovedIterator;
} mRefreshListState;
std::set<LLUUID> mChangedItems;
+ std::set<LLUUID> mPendingOutfitRefreshes;
bool mIsInitialized;
LLInventoryCategoriesObserver* mCategoriesObserver;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 6c0ff4a929..0801f2d9f7 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -852,6 +852,27 @@ struct LLPanelFaceSetAlignedTEFunctor : public LLSelectedTEFunctor
LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, uv_scale.mV[VX], te, object->getID());
LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, uv_scale.mV[VY], te, object->getID());
}
+
+ // Also align GLTF material if any
+ S32 gltf_info_index = 0; // base texture
+ LLVector2 gltf_offset, gltf_scale;
+ F32 gltf_rot;
+ if (facep->calcAlignedPlanarGLTF(mCenterFace, &gltf_offset, &gltf_scale, &gltf_rot, gltf_info_index))
+ {
+ LLGLTFMaterial new_override;
+ const LLTextureEntry* tep = object->getTE(te);
+ if (tep && tep->getGLTFMaterialOverride())
+ {
+ new_override = *tep->getGLTFMaterialOverride();
+ }
+
+ LLGLTFMaterial::TextureTransform& transform = new_override.mTextureTransform[gltf_info_index];
+ transform.mOffset.set(gltf_offset.mV[0], gltf_offset.mV[1]);
+ transform.mScale.set(gltf_scale.mV[0], gltf_scale.mV[1]);
+ transform.mRotation = gltf_rot;
+
+ LLGLTFMaterialList::queueModify(object, te, &new_override);
+ }
}
if (!set_aligned)
{
diff --git a/indra/newview/llpanelgenerictip.cpp b/indra/newview/llpanelgenerictip.cpp
index bc2b28269f..1b5228713e 100644
--- a/indra/newview/llpanelgenerictip.cpp
+++ b/indra/newview/llpanelgenerictip.cpp
@@ -43,5 +43,13 @@ LLPanelGenericTip::LLPanelGenericTip(
S32 max_line_count = gSavedSettings.getS32("TipToastMessageLineCount");
snapToMessageHeight(getChild<LLTextBox> ("message"), max_line_count);
+
+ // Check if notification should respond to mouse clicks
+ if (notification->getPayload().has("respond_on_mousedown")
+ && notification->getPayload()["respond_on_mousedown"])
+ {
+ setMouseDownCallback(boost::bind(&LLNotification::respond,
+ notification, notification->getResponseTemplate()));
+ }
}
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index ecb66f9cea..ad65293b98 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -191,6 +191,13 @@ bool LLPanelGroup::postBuild()
mButtonJoin->setCommitCallback(boost::bind(&LLPanelGroup::onBtnJoin,this));
mJoinText = panel_general->getChild<LLUICtrl>("join_cost_text");
+
+ mButtonActivate = panel_general->getChild<LLButton>("btn_activate");
+ mButtonActivate->setVisible(false);
+ mButtonActivate->setEnabled(gAgent.getGroupID() != mID);
+ mButtonActivate->setCommitCallback(boost::bind(&LLPanelGroup::onBtnActivate, this));
+
+ gAgent.addListener(this, "new group");
}
LLVoiceClient::addObserver(this);
@@ -267,6 +274,7 @@ void LLPanelGroup::onBtnJoin()
if (LLGroupActions::isInGroup(mID))
{
LLGroupActions::leave(mID);
+ mButtonActivate->setVisible(false);
}
else
{
@@ -275,6 +283,12 @@ void LLPanelGroup::onBtnJoin()
}
}
+void LLPanelGroup::onBtnActivate()
+{
+ LLGroupActions::activate(mID);
+ mButtonActivate->setEnabled(false);
+}
+
void LLPanelGroup::changed(LLGroupChange gc)
{
for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
@@ -312,6 +326,8 @@ void LLPanelGroup::update(LLGroupChange gc)
bool join_btn_visible = is_member || gdatap->mOpenEnrollment;
mButtonJoin->setVisible(join_btn_visible);
+ mButtonActivate->setEnabled(gAgent.getGroupID() != mID);
+ mButtonActivate->setVisible(is_member);
mJoinText->setVisible(join_btn_visible);
if (is_member)
@@ -384,6 +400,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
if(mButtonJoin)
mButtonJoin->setVisible(false);
+ if (mButtonActivate)
+ mButtonActivate->setVisible(false);
if(is_null_group_id)//creating new group
@@ -598,4 +616,20 @@ void LLPanelGroup::showNotice(const std::string& subject,
}
+bool LLPanelGroup::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ if (event->desc() == "new group")
+ {
+ mButtonActivate->setEnabled(gAgent.getGroupID() != mID);
+ return true;
+ }
+
+ if (event->desc() == "value_changed")
+ {
+ mButtonActivate->setEnabled(gAgent.getGroupID() != mID);
+ return true;
+ }
+
+ return false;
+}
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index b43a93bc40..d3550264a0 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -26,6 +26,7 @@
#ifndef LL_LLPANELGROUP_H
#define LL_LLPANELGROUP_H
+#include "llevent.h"
#include "llgroupmgr.h"
#include "llpanel.h"
#include "lltimer.h"
@@ -44,7 +45,8 @@ class LLAgent;
class LLPanelGroup : public LLPanel,
public LLGroupMgrObserver,
- public LLVoiceClientStatusObserver
+ public LLVoiceClientStatusObserver,
+ public LLOldEvents::LLSimpleListener
{
public:
LLPanelGroup();
@@ -94,6 +96,7 @@ protected:
void onBackBtnClick();
void onBtnJoin();
+ void onBtnActivate();
static void onBtnApply(void*);
static void onBtnRefresh(void*);
@@ -120,11 +123,15 @@ protected:
LLUICtrl* mGroupNameCtrl = nullptr;
LLButton* mButtonJoin = nullptr;
+ LLButton* mButtonActivate = nullptr;
LLButton* mButtonApply = nullptr;
LLButton* mButtonCall = nullptr;
LLButton* mButtonChat = nullptr;
LLButton* mButtonRefresh = nullptr;
LLUICtrl* mJoinText;
+
+private:
+ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // for agent group list changes
};
class LLPanelGroupTab : public LLPanel
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index fe9145bf71..868e02f28b 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -188,7 +188,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mUsernameLength(0),
mPasswordLength(0),
mLocationLength(0),
- mShowFavorites(false)
+ mShowFavorites(false),
+ mAlertNotif(false)
{
setBackgroundVisible(false);
setBackgroundOpaque(true);
@@ -219,6 +220,11 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
// STEAM-14: When user presses Enter with this field in focus, initiate login
password_edit->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, false));
+ childSetAction("connect_btn", onClickConnect, this);
+
+ mLoginBtn = getChild<LLButton>("connect_btn");
+ setDefaultBtn(mLoginBtn);
+
// change z sort of clickable text to be behind buttons
sendChildToBack(getChildView("forgot_password_text"));
sendChildToBack(getChildView("sign_up_text"));
@@ -295,11 +301,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
onUpdateStartSLURL(start_slurl); // updates grid if needed
}
- childSetAction("connect_btn", onClickConnect, this);
-
- LLButton* def_btn = getChild<LLButton>("connect_btn");
- setDefaultBtn(def_btn);
-
std::string channel = LLVersionInfo::instance().getChannel();
std::string version = stringize(LLVersionInfo::instance().getShortVersion(), " (",
LLVersionInfo::instance().getBuild(), ')');
@@ -327,6 +328,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this));
getChild<LLCheckBoxCtrl>("remember_password")->setCommitCallback(boost::bind(&LLPanelLogin::onRememberPasswordCheck, this));
+
+ mAlertListener = LLNotifications::instance().getChannel("Alerts")->connectChanged([this](const LLSD& notify){ return onUpdateNotification(notify); });
}
void LLPanelLogin::addFavoritesToStartLocation()
@@ -409,7 +412,7 @@ void LLPanelLogin::addFavoritesToStartLocation()
gSavedSettings.setBOOL("RememberPassword", save_password);
if (!save_password)
{
- getChild<LLButton>("connect_btn")->setEnabled(false);
+ mLoginBtn->setEnabled(false);
}
update_password_setting = false;
}
@@ -936,7 +939,7 @@ void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
// static
void LLPanelLogin::onClickConnect(bool commit_fields)
{
- if (sInstance && sInstance->mCallback)
+ if (sInstance && sInstance->mCallback && !sInstance->mAlertNotif)
{
if (commit_fields)
{
@@ -1193,9 +1196,7 @@ void LLPanelLogin::updateServer()
void LLPanelLogin::updateLoginButtons()
{
- LLButton* login_btn = getChild<LLButton>("connect_btn");
-
- login_btn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0);
+ mLoginBtn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0 && !mAlertNotif);
if (!mFirstLoginThisInstall)
{
@@ -1367,3 +1368,22 @@ std::string LLPanelLogin::getUserName(LLPointer<LLCredential> &cred)
return "unknown";
}
+bool LLPanelLogin::onUpdateNotification(const LLSD& notify)
+{
+ // disable Login button while alert notification is displayed
+ LLNotificationPtr notifyp = LLNotifications::instance().find(notify["id"].asUUID());
+ if (notifyp && notifyp->getName() == "PromptOptionalUpdate")
+ {
+ std::string sigtype = notify["sigtype"].asString();
+ if (sigtype == "add")
+ {
+ mAlertNotif = true;
+ }
+ else if (sigtype == "delete")
+ {
+ mAlertNotif = false;
+ }
+ updateLoginButtons();
+ }
+ return false;
+}
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index a1bf25fb05..f527aa53ac 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -105,8 +105,11 @@ private:
static void onRememberPasswordCheck(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
+ bool onUpdateNotification(const LLSD& notify);
+
private:
std::unique_ptr<LLPanelLoginListener> mListener;
+ LLTempBoundListener mAlertListener;
void updateLoginButtons();
void populateUserList(LLPointer<LLCredential> credential);
@@ -126,6 +129,9 @@ private:
unsigned int mUsernameLength;
unsigned int mPasswordLength;
unsigned int mLocationLength;
+
+ bool mAlertNotif;
+ LLButton* mLoginBtn;
};
#endif
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index ad7aa57842..04eebcefc1 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -216,14 +216,14 @@ bool LLPanelMainInventory::postBuild()
mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2));
}
- LLInventoryPanel* favorites_panel = getChild<LLInventoryPanel>(FAVORITES);
- if (favorites_panel)
+ mFavoritesPanel = getChild<LLInventoryPanel>(FAVORITES);
+ if (mFavoritesPanel)
{
- favorites_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER));
- LLInventoryFilter& favorites_filter = favorites_panel->getFilter();
+ mFavoritesPanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER));
+ LLInventoryFilter& favorites_filter = mFavoritesPanel->getFilter();
favorites_filter.setEmptyLookupMessage("InventoryNoMatchingFavorites");
favorites_filter.markDefault();
- favorites_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, favorites_panel, _1, _2));
+ mFavoritesPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mFavoritesPanel, _1, _2));
}
mSearchTypeCombo = getChild<LLComboBox>("search_type");
@@ -319,6 +319,10 @@ bool LLPanelMainInventory::postBuild()
menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);
}
+ mFilterTabs->setTabVisibility(mRecentPanel, gSavedSettings.getBOOL("InventoryShowRecentTab"));
+ mFilterTabs->setTabVisibility(mWornItemsPanel, gSavedSettings.getBOOL("InventoryShowWornTab"));
+ mFilterTabs->setTabVisibility(mFavoritesPanel, gSavedSettings.getBOOL("InventoryShowFavoritesTab"));
+
// Trigger callback for focus received so we can deselect items in inbox/outbox
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this));
@@ -1613,8 +1617,10 @@ void LLPanelMainInventory::initSingleFolderRoot(const LLUUID& start_folder_id)
void LLPanelMainInventory::initInventoryViews()
{
mAllItemsPanel->initializeViewBuilding();
- mRecentPanel->initializeViewBuilding();
- mWornItemsPanel->initializeViewBuilding();
+ if (gSavedSettings.getBOOL("InventoryShowRecentTab"))
+ mRecentPanel->initializeViewBuilding();
+ if (gSavedSettings.getBOOL("InventoryShowWornTab"))
+ mWornItemsPanel->initializeViewBuilding();
}
void LLPanelMainInventory::toggleViewMode()
@@ -2056,6 +2062,27 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
setViewMode(MODE_COMBINATION);
}
+
+ if (command_name == "toggle_recent_tab")
+ {
+ bool visibility = !gSavedSettings.getBOOL("InventoryShowRecentTab");
+ gSavedSettings.setBOOL("InventoryShowRecentTab", visibility);
+ mFilterTabs->setTabVisibility(mRecentPanel, visibility);
+ mRecentPanel->initializeViewBuilding();
+ }
+ if (command_name == "toggle_worn_tab")
+ {
+ bool visibility = !gSavedSettings.getBOOL("InventoryShowWornTab");
+ gSavedSettings.setBOOL("InventoryShowWornTab", visibility);
+ mFilterTabs->setTabVisibility(mWornItemsPanel, visibility);
+ mWornItemsPanel->initializeViewBuilding();
+ }
+ if (command_name == "toggle_favorites_tab")
+ {
+ bool visibility = !gSavedSettings.getBOOL("InventoryShowFavoritesTab");
+ gSavedSettings.setBOOL("InventoryShowFavoritesTab", visibility);
+ mFilterTabs->setTabVisibility(mFavoritesPanel, visibility);
+ }
}
void LLPanelMainInventory::onVisibilityChange( bool new_visibility )
@@ -2283,6 +2310,19 @@ bool LLPanelMainInventory::isActionChecked(const LLSD& userdata)
return isCombinationViewMode();
}
+ if (command_name == "recent_tab")
+ {
+ return mFilterTabs->getTabVisibility(mRecentPanel);
+ }
+ if (command_name == "worn_tab")
+ {
+ return mFilterTabs->getTabVisibility(mWornItemsPanel);
+ }
+ if (command_name == "favorites_tab")
+ {
+ return mFilterTabs->getTabVisibility(mFavoritesPanel);
+ }
+
return false;
}
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index a78c0c0fad..03650e7fc1 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -199,6 +199,7 @@ private:
LLInventoryPanel* mAllItemsPanel = nullptr;
LLInventoryPanel* mRecentPanel = nullptr;
LLInventoryPanel* mWornItemsPanel = nullptr;
+ LLInventoryPanel* mFavoritesPanel = nullptr;
bool mResortActivePanel;
LLSaveFolderState* mSavedFolderState;
std::string mFilterText;
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 23e6a9fbcf..69be65d9c9 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -625,7 +625,7 @@ void LLPanelObject::getState( )
}
- if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ if (objectp->getSculptParams())
{
selected_item = MI_SCULPT;
//LLFirstUse::useSculptedPrim();
@@ -1078,7 +1078,7 @@ void LLPanelObject::getState( )
LLUUID id;
- LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = objectp->getSculptParams();
if (sculpt_params) // if we have a legal sculpt param block for this object:
@@ -1246,13 +1246,13 @@ void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata )
if (selected_type == MI_SCULPT)
{
self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, true, true);
- LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = self->mObject->getSculptParams();
if (sculpt_params)
volume_params.setSculptID(sculpt_params->getSculptTexture(), sculpt_params->getSculptType());
}
else
{
- LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = self->mObject->getSculptParams();
if (sculpt_params)
self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, false, true);
}
@@ -2264,24 +2264,21 @@ void LLPanelObject::onCopyParams()
mClipboardParams["volume_params"] = params.asLLSD();
// Sculpted Prim
- if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ LLSculptParams *sculpt_params = objectp->getSculptParams();
+ if (sculpt_params)
{
- LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- if (sculpt_params)
+ LLUUID texture_id = sculpt_params->getSculptTexture();
+ if (get_can_copy_texture(texture_id))
{
- LLUUID texture_id = sculpt_params->getSculptTexture();
- if (get_can_copy_texture(texture_id))
- {
- LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL;
- mClipboardParams["sculpt"]["id"] = texture_id;
- }
- else
- {
- mClipboardParams["sculpt"]["id"] = SCULPT_DEFAULT_TEXTURE;
- }
-
- mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType();
+ LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL;
+ mClipboardParams["sculpt"]["id"] = texture_id;
}
+ else
+ {
+ mClipboardParams["sculpt"]["id"] = SCULPT_DEFAULT_TEXTURE;
+ }
+
+ mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType();
}
}
@@ -2304,7 +2301,7 @@ void LLPanelObject::onPasteParams()
}
else
{
- LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = objectp->getSculptParams();
if (sculpt_params)
{
objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, false, true);
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index a31a54bb67..d27ce81e4f 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1830,7 +1830,7 @@ void LLPanelObjectInventory::onFocusReceived()
LLFolderViewItem* LLPanelObjectInventory::getItemByID( const LLUUID& id )
{
- std::map<LLUUID, LLFolderViewItem*>::iterator map_it = mItemMap.find(id);
+ auto map_it = mItemMap.find(id);
if (map_it != mItemMap.end())
{
return map_it->second;
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index 154639e4bb..13e27b489c 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -109,7 +109,7 @@ protected:
bool isSelectionRemovable();
private:
- std::map<LLUUID, LLFolderViewItem*> mItemMap;
+ std::unordered_map<LLUUID, LLFolderViewItem*> mItemMap;
LLScrollContainer* mScroller;
LLFolderView* mFolders;
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index cbf5819fda..cff09b0778 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -786,7 +786,9 @@ void LLPanelPermissions::refresh()
getChildView("Edit Cost")->setEnabled(change_sale_allowed && !is_for_sale_mixed);
// Set the checkbox to tentative if the prices of each object selected
// are not the same.
- getChild<LLUICtrl>("checkbox for sale")->setTentative( is_for_sale_mixed);
+ // If object is marked for sale yet is not transferable, mark as tentative,
+ // as it is in a state where it can't be sold
+ getChild<LLUICtrl>("checkbox for sale")->setTentative((!can_transfer && num_for_sale) || is_for_sale_mixed);
getChildView("sale type")->setEnabled(num_for_sale && can_transfer && !is_sale_price_mixed);
getChildView("Next owner can:")->setEnabled(true);
diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp
deleted file mode 100644
index a0129b2cb1..0000000000
--- a/indra/newview/llpanelvoiceeffect.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * @file llpanelvoiceeffect.cpp
- * @author Aimee
- * @brief Panel to select Voice Morphs.
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelvoiceeffect.h"
-
-#include "llcombobox.h"
-#include "llfloaterreg.h"
-#include "llpanel.h"
-#include "lltrans.h"
-#include "lltransientfloatermgr.h"
-#include "llvoiceclient.h"
-#include "llweb.h"
-
-static LLPanelInjector<LLPanelVoiceEffect> t_panel_voice_effect("panel_voice_effect");
-
-LLPanelVoiceEffect::LLPanelVoiceEffect()
- : mVoiceEffectCombo(NULL)
-{
- mCommitCallbackRegistrar.add("Voice.CommitVoiceEffect", boost::bind(&LLPanelVoiceEffect::onCommitVoiceEffect, this));
-}
-
-LLPanelVoiceEffect::~LLPanelVoiceEffect()
-{
- LLView* combo_list_view = mVoiceEffectCombo->getChildView("ComboBox");
- LLTransientFloaterMgr::getInstance()->removeControlView(combo_list_view);
-
- if(LLVoiceClient::instanceExists())
- {
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (effect_interface)
- {
- effect_interface->removeObserver(this);
- }
- }
-}
-
-// virtual
-bool LLPanelVoiceEffect::postBuild()
-{
- mVoiceEffectCombo = getChild<LLComboBox>("voice_effect");
-
- // Need to tell LLTransientFloaterMgr about the combo list, otherwise it can't
- // be clicked while in a docked floater as it extends outside the floater area.
- LLView* combo_list_view = mVoiceEffectCombo->getChildView("ComboBox");
- LLTransientFloaterMgr::getInstance()->addControlView(combo_list_view);
-
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (effect_interface)
- {
- effect_interface->addObserver(this);
- }
-
- update(true);
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// PRIVATE SECTION
-//////////////////////////////////////////////////////////////////////////
-
-void LLPanelVoiceEffect::onCommitVoiceEffect()
-{
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (!effect_interface)
- {
- mVoiceEffectCombo->setEnabled(false);
- return;
- }
-
- LLSD value = mVoiceEffectCombo->getValue();
- if (value.asInteger() == PREVIEW_VOICE_EFFECTS)
- {
- // Open the Voice Morph preview floater
- LLFloaterReg::showInstance("voice_effect");
- }
- else if (value.asInteger() == GET_VOICE_EFFECTS)
- {
- // Open the voice morphing info web page
- LLWeb::loadURL(LLTrans::getString("voice_morphing_url"));
- }
- else
- {
- effect_interface->setVoiceEffect(value.asUUID());
- }
-
- mVoiceEffectCombo->setValue(effect_interface->getVoiceEffect());
-}
-
-// virtual
-void LLPanelVoiceEffect::onVoiceEffectChanged(bool effect_list_updated)
-{
- update(effect_list_updated);
-}
-
-void LLPanelVoiceEffect::update(bool list_updated)
-{
- if (mVoiceEffectCombo)
- {
- LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
- if (!effect_interface) return;
- if (list_updated)
- {
- // Add the default "No Voice Morph" entry.
- mVoiceEffectCombo->removeall();
- mVoiceEffectCombo->add(getString("no_voice_effect"), LLUUID::null);
- mVoiceEffectCombo->addSeparator();
-
- // Add entries for each Voice Morph.
- const voice_effect_list_t& effect_list = effect_interface->getVoiceEffectList();
- if (!effect_list.empty())
- {
- for (voice_effect_list_t::const_iterator it = effect_list.begin(); it != effect_list.end(); ++it)
- {
- mVoiceEffectCombo->add(it->first, it->second, ADD_BOTTOM);
- }
-
- mVoiceEffectCombo->addSeparator();
- }
-
- // Add the fixed entries to go to the preview floater or marketing page.
- mVoiceEffectCombo->add(getString("preview_voice_effects"), PREVIEW_VOICE_EFFECTS);
- mVoiceEffectCombo->add(getString("get_voice_effects"), GET_VOICE_EFFECTS);
- }
-
- if (effect_interface && LLVoiceClient::instance().isVoiceWorking())
- {
- // Select the current Voice Morph.
- mVoiceEffectCombo->setValue(effect_interface->getVoiceEffect());
- mVoiceEffectCombo->setEnabled(true);
- }
- else
- {
- // If voice isn't working or Voice Effects are not supported disable the control.
- mVoiceEffectCombo->setValue(LLUUID::null);
- mVoiceEffectCombo->setEnabled(false);
- }
- }
-}
diff --git a/indra/newview/llpanelvoiceeffect.h b/indra/newview/llpanelvoiceeffect.h
deleted file mode 100644
index f920e41081..0000000000
--- a/indra/newview/llpanelvoiceeffect.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file llpanelvoiceeffect.h
- * @author Aimee
- * @brief Panel to select Voice Effects.
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_PANELVOICEEFFECT_H
-#define LL_PANELVOICEEFFECT_H
-
-#include "llpanel.h"
-#include "llvoiceclient.h"
-
-class LLComboBox;
-
-class LLPanelVoiceEffect
- : public LLPanel
- , public LLVoiceEffectObserver
-{
-public:
- LOG_CLASS(LLPanelVoiceEffect);
-
- LLPanelVoiceEffect();
- virtual ~LLPanelVoiceEffect();
-
- bool postBuild() override;
-
-private:
- void onCommitVoiceEffect();
- void update(bool list_updated);
-
- /// Called by voice effect provider when voice effect list is changed.
- void onVoiceEffectChanged(bool effect_list_updated) override;
-
- // Fixed entries in the Voice Morph list
- typedef enum e_voice_effect_combo_items
- {
- NO_VOICE_EFFECT = 0,
- PREVIEW_VOICE_EFFECTS = 1,
- GET_VOICE_EFFECTS = 2
- } EVoiceEffectComboItems;
-
- LLComboBox* mVoiceEffectCombo;
-};
-
-
-#endif //LL_PANELVOICEEFFECT_H
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 5916163f60..94864797d5 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -532,7 +532,7 @@ void LLPanelVolume::getState( )
getChildView("FlexForceY")->setEnabled(true);
getChildView("FlexForceZ")->setEnabled(true);
- LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ LLFlexibleObjectData *attributes = objectp->getFlexibleObjectData();
getChild<LLUICtrl>("FlexNumSections")->setValue((F32)attributes->getSimulateLOD());
getChild<LLUICtrl>("FlexGravity")->setValue(attributes->getGravity());
@@ -643,7 +643,7 @@ void LLPanelVolume::getState( )
mComboPhysicsShapeType->add(getString("None"), LLSD(1));
bool isMesh = false;
- LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = objectp->getSculptParams();
if (sculpt_params)
{
U8 sculpt_type = sculpt_params->getSculptType();
@@ -1043,7 +1043,7 @@ void LLPanelVolume::onCopyFeatures()
// Flexi Prim
if (volobjp && volobjp->isFlexible())
{
- LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ LLFlexibleObjectData *attributes = objectp->getFlexibleObjectData();
if (attributes)
{
clipboard["flex"]["lod"] = attributes->getSimulateLOD();
@@ -1141,7 +1141,7 @@ void LLPanelVolume::onPasteFeatures()
objectp->setClickAction(CLICK_ACTION_NONE);
}
- LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ LLFlexibleObjectData *attributes = objectp->getFlexibleObjectData();
if (attributes)
{
LLFlexibleObjectData new_attributes;
@@ -1568,7 +1568,7 @@ void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
return;
}
- LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ LLFlexibleObjectData *attributes = objectp->getFlexibleObjectData();
if (attributes)
{
LLFlexibleObjectData new_attributes;
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index 1a2098ec7e..38deb87237 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -223,7 +223,7 @@ namespace LLPerfStats
static void updateMeanFrameTime(U64 tot_frame_time_raw);
// StatsArray is a uint64_t for each possible statistic type.
using StatsArray = std::array<uint64_t, static_cast<size_t>(LLPerfStats::StatType_t::STATS_COUNT)>;
- using StatsMap = std::unordered_map<LLUUID, StatsArray, boost::hash<LLUUID>>;
+ using StatsMap = std::unordered_map<LLUUID, StatsArray>;
using StatsTypeMatrix = std::array<StatsMap, static_cast<size_t>(LLPerfStats::ObjType_t::OT_COUNT)>;
using StatsSummaryArray = std::array<StatsArray, static_cast<size_t>(LLPerfStats::ObjType_t::OT_COUNT)>;
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 9a991727b2..eefd19e153 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -79,6 +79,7 @@ LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id,
LLPreviewNotecard::~LLPreviewNotecard()
{
delete mLiveFile;
+ mEditor = nullptr;
}
bool LLPreviewNotecard::postBuild()
@@ -166,7 +167,7 @@ bool LLPreviewNotecard::handleKeyHere(KEY key, MASK mask)
// virtual
bool LLPreviewNotecard::canClose()
{
- if(mForceClose || mEditor->isPristine())
+ if(mForceClose || !mEditor || mEditor->isPristine())
{
return true;
}
diff --git a/indra/newview/llscriptruntimeperms.h b/indra/newview/llscriptruntimeperms.h
index 300304c21b..6350b61d08 100644
--- a/indra/newview/llscriptruntimeperms.h
+++ b/indra/newview/llscriptruntimeperms.h
@@ -24,10 +24,7 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLSCRIPTRUNTIME_PERMS_H
-#define LL_LLSCRIPTRUNTIME_PERMS_H
-
-#include <boost/array.hpp>
+#pragma once
typedef struct _script_perm {
std::string question;
@@ -37,12 +34,12 @@ typedef struct _script_perm {
question(q), permbit(b), caution(c) {}
} script_perm_t;
-const U32 NUM_SCRIPT_PERMISSIONS = 18;
+const U32 NUM_SCRIPT_PERMISSIONS = 19;
const S32 SCRIPT_PERMISSION_DEBIT = 0;
const S32 SCRIPT_PERMISSION_TRIGGER_ANIMATION = 3;
const S32 SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS = 14;
-static const boost::array<script_perm_t, NUM_SCRIPT_PERMISSIONS> SCRIPT_PERMISSIONS = {{
+static const std::array<script_perm_t, NUM_SCRIPT_PERMISSIONS> SCRIPT_PERMISSIONS = {{
_script_perm("ScriptTakeMoney", (0x1 << 1), true),
_script_perm("ActOnControlInputs", (0x1 << 2), false),
_script_perm("RemapControlInputs", (0x1 << 3), false),
@@ -60,7 +57,7 @@ static const boost::array<script_perm_t, NUM_SCRIPT_PERMISSIONS> SCRIPT_PERMISSI
_script_perm("OverrideYourAnimations", (0x1 << 15), false),
_script_perm("ScriptReturnObjects", (0x1 << 16), false),
_script_perm("ForceSitAvatar", (0x1 << 17), false),
- _script_perm("ChangeEnvSettings", (0x1 << 18), false)
+ _script_perm("ChangeEnvSettings", (0x1 << 18), false),
+ _script_perm("PrivilegedLandAccess",(0x1 << 19), true)
} };
-#endif // LL_LLSCRIPTRUNTIME_PERMS_H
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 758e91f6c9..86c9818c4e 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6193,6 +6193,15 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use
node->mCategory = category;
node->mName.assign(name);
node->mDescription.assign(desc);
+
+ LLViewerObject* obj = node->getObject();
+ if (obj && LLViewerObject::isObjectInPendingUpdate(owner_id, obj))
+ {
+ // current response doesn't return modify permissions flags,
+ // so we should request it separately if needed
+ obj->requestObjectUpdate();
+ }
+
}
dialog_refresh_all();
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index a147cb4657..d2c7c5e5ce 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -135,9 +135,13 @@ void LLSpatialGroup::clearDrawMap()
mDrawMap.clear();
}
-bool LLSpatialGroup::isHUDGroup()
+bool LLSpatialGroup::isHUDGroup() const
{
- return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ;
+ if (hasState(DEAD))
+ return false;
+
+ LLSpatialPartition* part = (LLSpatialPartition*)mSpatialPartition;
+ return part && part->isHUDPartition();
}
void LLSpatialGroup::validate()
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index d8a94c8835..4b312b1597 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -264,7 +264,7 @@ public:
LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
- bool isHUDGroup() ;
+ bool isHUDGroup() const;
void clearDrawMap();
void validate();
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 1a7ce74ccc..8c8734b52f 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -875,7 +875,7 @@ std::string LLTextureCache::getTextureFileName(const LLUUID& id)
//debug
bool LLTextureCache::isInCache(const LLUUID& id)
{
- LLMutexLock lock(&mHeaderMutex);
+ LLMutexLock lock(&mHeaderIDMapMutex);
id_map_t::const_iterator iter = mHeaderIDMap.find(id);
return (iter != mHeaderIDMap.end()) ;
@@ -991,6 +991,8 @@ void LLTextureCache::setReadOnly(bool read_only)
// Returns the unused amount of max_size if any
S64 LLTextureCache::initCache(ELLPath location, S64 max_size, bool texture_cache_mismatch)
{
+ LL_PROFILE_ZONE_SCOPED;
+
llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
S64 entries_size = (max_size * 36) / 100; //0.36 * max_size
@@ -1115,10 +1117,13 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create
{
S32 idx = -1;
- id_map_t::iterator iter1 = mHeaderIDMap.find(id);
- if (iter1 != mHeaderIDMap.end())
{
- idx = iter1->second;
+ LLMutexLock lock(&mHeaderIDMapMutex);
+ id_map_t::iterator iter1 = mHeaderIDMap.find(id);
+ if (iter1 != mHeaderIDMap.end())
+ {
+ idx = iter1->second;
+ }
}
if (idx < 0)
@@ -1146,10 +1151,19 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create
// Erase entry from LRU regardless
mLRU.erase(curiter2);
// Look up entry and use it if it is valid
- id_map_t::iterator iter3 = mHeaderIDMap.find(oldid);
- if (iter3 != mHeaderIDMap.end() && iter3->second >= 0)
+
+ S32 found_idx = -1;
{
- idx = iter3->second;
+ LLMutexLock lock(&mHeaderIDMapMutex);
+ id_map_t::iterator iter3 = mHeaderIDMap.find(oldid);
+ if (iter3 != mHeaderIDMap.end() && iter3->second >= 0)
+ {
+ found_idx = iter3->second;
+ }
+ }
+ if (found_idx >= 0)
+ {
+ idx = found_idx;
removeCachedTexture(oldid) ;//remove the existing cached texture to release the entry index.
break;
}
@@ -1285,7 +1299,10 @@ bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32
bool update_header = false ;
if(entry.mImageSize < 0) //is a brand-new entry
{
- mHeaderIDMap[entry.mID] = idx;
+ {
+ LLMutexLock lock(&mHeaderIDMapMutex);
+ mHeaderIDMap[entry.mID] = idx;
+ }
mTexturesSizeMap[entry.mID] = new_body_size ;
mTexturesSizeTotal += new_body_size ;
@@ -1323,8 +1340,8 @@ bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32
U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries)
{
+ LLMutexLock lock(&mHeaderIDMapMutex);
U32 num_entries = mHeaderEntriesInfo.mEntries;
-
mHeaderIDMap.clear();
mTexturesSizeMap.clear();
mFreeList.clear();
@@ -1618,7 +1635,10 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
LLFile::rmdir(mTexturesDirName);
}
}
- mHeaderIDMap.clear();
+ {
+ LLMutexLock lock(&mHeaderIDMapMutex);
+ mHeaderIDMap.clear();
+ }
mTexturesSizeMap.clear();
mTexturesSizeTotal = 0;
mFreeList.clear();
@@ -1665,6 +1685,7 @@ void LLTextureCache::purgeTexturesLazy(F32 time_limit_sec)
{
if (iter1->second > 0)
{
+ LLMutexLock lock(&mHeaderIDMapMutex);
id_map_t::iterator iter2 = mHeaderIDMap.find(iter1->first);
if (iter2 != mHeaderIDMap.end())
{
@@ -1706,8 +1727,13 @@ void LLTextureCache::purgeTexturesLazy(F32 time_limit_sec)
Entry entry = mPurgeEntryList.back().second;
mPurgeEntryList.pop_back();
// make sure record is still valid
- id_map_t::iterator iter_header = mHeaderIDMap.find(entry.mID);
- if (iter_header != mHeaderIDMap.end() && iter_header->second == idx)
+ bool remove_entry = false;
+ {
+ LLMutexLock lock(&mHeaderIDMapMutex);
+ id_map_t::iterator iter_header = mHeaderIDMap.find(entry.mID);
+ remove_entry = (iter_header != mHeaderIDMap.end() && iter_header->second == idx);
+ }
+ if (remove_entry)
{
std::string tex_filename = getTextureFileName(entry.mID);
removeEntry(idx, entry, tex_filename);
@@ -1750,6 +1776,7 @@ void LLTextureCache::purgeTextures(bool validate)
{
if (iter1->second > 0)
{
+ LLMutexLock lock(&mHeaderIDMapMutex);
id_map_t::iterator iter2 = mHeaderIDMap.find(iter1->first);
if (iter2 != mHeaderIDMap.end())
{
@@ -2004,7 +2031,7 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
{
U32 offset;
{
- LLMutexLock lock(&mHeaderMutex);
+ LLMutexLock lock(&mHeaderIDMapMutex);
id_map_t::const_iterator iter = mHeaderIDMap.find(id);
if(iter == mHeaderIDMap.end())
{
@@ -2018,9 +2045,10 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
U8* data;
S32 head[4];
{
+ LL_PROFILE_ZONE_NAMED("Read fast cache");
LLMutexLock lock(&mFastCacheMutex);
- openFastCache();
+ openFastCache(); // only reopens if needed, lasts 10 seconds
mFastCachep->seek(APR_SET, offset);
@@ -2051,7 +2079,9 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
closeFastCache();
}
- LLPointer<LLImageRaw> raw = new LLImageRaw(data, head[0], head[1], head[2], true);
+
+ // directly construct image from new buffer.
+ LLPointer<LLImageRaw> raw = new LLImageRaw(data, head[0], head[1], head[2], true /*take ownership*/);
return raw;
}
@@ -2229,7 +2259,10 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)
mTexturesSizeTotal -= mTexturesSizeMap[id] ;
mTexturesSizeMap.erase(id);
}
- mHeaderIDMap.erase(id);
+ {
+ LLMutexLock lock(&mHeaderIDMapMutex);
+ mHeaderIDMap.erase(id);
+ }
// We are inside header's mutex so mHeaderAPRFilePoolp is safe to use,
// but getLocalAPRFilePool() is not safe, it might be in use by worker
LLAPRFile::remove(getTextureFileName(id), mHeaderAPRFilePoolp);
@@ -2260,7 +2293,10 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
entry.mImageSize = -1;
entry.mBodySize = 0;
- mHeaderIDMap.erase(entry.mID);
+ {
+ LLMutexLock lock(&mHeaderIDMapMutex);
+ mHeaderIDMap.erase(entry.mID);
+ }
mTexturesSizeMap.erase(entry.mID);
mFreeList.insert(idx);
}
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index faf722dc8f..a09bcc1572 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -148,7 +148,7 @@ public:
U32 getMaxEntries() { return sCacheMaxEntries; };
bool isInCache(const LLUUID& id) ;
bool isInLocal(const LLUUID& id) ; //not thread safe at the moment
-
+ LLMutex* getFastCacheMutex() { return &mFastCacheMutex; }
protected:
// Accessed by LLTextureCacheWorker
std::string getLocalFileName(const LLUUID& id);
@@ -194,6 +194,7 @@ private:
// Internal
LLMutex mWorkersMutex;
LLMutex mHeaderMutex;
+ LLMutex mHeaderIDMapMutex; // To avoid deadlocks, never lock mFastCacheMutex after mHeaderIDMapMutex.
LLMutex mListMutex;
LLMutex mFastCacheMutex;
LLAPRFile* mHeaderAPRFile;
diff --git a/indra/newview/lltoastscriptquestion.cpp b/indra/newview/lltoastscriptquestion.cpp
index 25dc0982b8..55e178e084 100644
--- a/indra/newview/lltoastscriptquestion.cpp
+++ b/indra/newview/lltoastscriptquestion.cpp
@@ -48,7 +48,12 @@ bool LLToastScriptQuestion::postBuild()
LLTextBox* mFooter = getChild<LLTextBox>("bottom_info_message");
mMessage->setValue(mNotification->getMessage());
- mFooter->setValue(mNotification->getFooter());
+ std::string footer = mNotification->getFooter();
+ mFooter->setValue(footer);
+ if (footer.empty())
+ {
+ mFooter->setVisible(false);
+ }
snapToMessageHeight();
@@ -78,21 +83,69 @@ void LLToastScriptQuestion::snapToMessageHeight()
if (mMessage->getVisible() && mFooter->getVisible())
{
- S32 heightDelta = 0;
- S32 maxTextHeight = (mMessage->getFont()->getLineHeight() * MAX_LINES_COUNT)
+ S32 height_delta = 0;
+ S32 max_text_height = (mMessage->getFont()->getLineHeight() * MAX_LINES_COUNT)
+ (mFooter->getFont()->getLineHeight() * MAX_LINES_COUNT);
- LLRect messageRect = mMessage->getRect();
- LLRect footerRect = mFooter->getRect();
+ LLRect message_rect = mMessage->getRect();
+
+ S32 old_message_height = message_rect.getHeight();
+ S32 new_message_height = mMessage->getTextBoundingRect().getHeight();
+ S32 new_footer_height = mFooter->getTextBoundingRect().getHeight();
+
+ constexpr S32 FOOTER_PADDING = 8; // new height should include padding for newly added footer
+ S32 required_text_height = new_message_height + new_footer_height + FOOTER_PADDING;
+ S32 new_text_height = llmin(required_text_height, max_text_height);
+
+ // Footer was invisible, so use old_message_height for old height
+ height_delta = new_text_height - old_message_height;
+
+ reshape( getRect().getWidth(), llmax(getRect().getHeight() + height_delta, MIN_PANEL_HEIGHT));
+
+ // Floater was resized, now resize and shift children
+ // Message follows top, so it's top is in a correct position, but needs to be resized down
+ S32 message_delta = new_message_height - old_message_height;
+ message_rect = mMessage->getRect(); // refresh since it might have changed after reshape
+ message_rect.mBottom = message_rect.mBottom - message_delta;
+ mMessage->setRect(message_rect);
+ mMessage->needsReflow();
+ // Button panel should stay the same size, just translate it
+ LLPanel* panel = getChild<LLPanel>("buttons_panel");
+ panel->translate(0, -message_delta);
+ // Footer should be both moved and resized
+ LLRect footer_rect = mFooter->getRect();
+ footer_rect.mTop = footer_rect.mTop - message_delta;
+ footer_rect.mBottom = footer_rect.mTop - new_footer_height;
+ mFooter->setRect(footer_rect);
+ mFooter->needsReflow();
+ }
+ else if (mMessage->getVisible())
+ {
+ S32 height_delta = 0;
+ S32 max_text_height = (mMessage->getFont()->getLineHeight() * MAX_LINES_COUNT);
+
+ LLRect message_rect = mMessage->getRect();
+
+ S32 old_message_height = message_rect.getHeight();
+ S32 new_message_height = mMessage->getTextBoundingRect().getHeight();
- S32 oldTextHeight = messageRect.getHeight() + footerRect.getHeight();
+ S32 new_text_height = llmin(new_message_height, max_text_height);
- S32 requiredTextHeight = mMessage->getTextBoundingRect().getHeight() + mFooter->getTextBoundingRect().getHeight();
- S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
+ // Footer was invisible, so use old_message_height for old height
+ height_delta = new_text_height - old_message_height;
- heightDelta = newTextHeight - oldTextHeight - heightDelta;
+ reshape(getRect().getWidth(), llmax(getRect().getHeight() + height_delta, MIN_PANEL_HEIGHT));
- reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT));
+ // Floater was resized, now resize and shift children
+ // Message follows top, so it's top is in a correct position, but needs to be resized down
+ S32 message_delta = new_message_height - old_message_height;
+ message_rect = mMessage->getRect(); // refresh since it might have changed after reshape
+ message_rect.mBottom = message_rect.mBottom - message_delta;
+ mMessage->setRect(message_rect);
+ mMessage->needsReflow();
+ // Button panel should stay the same size, just translate it
+ LLPanel* panel = getChild<LLPanel>("buttons_panel");
+ panel->translate(0, -message_delta);
}
}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index f78ff2226c..5e2d91d31e 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -775,7 +775,7 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, bool drop,
if (!handled)
{
// Disallow drag and drop to 3D from the marketplace
- const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.notNull())
{
for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++)
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index 5ccda7d4eb..3bd459f5b0 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -55,17 +55,17 @@ LLToolSelect::LLToolSelect( LLToolComposite* composite )
: LLTool( std::string("Select"), composite ),
mIgnoreGroup( false )
{
- }
+}
// True if you selected an object.
bool LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
{
// do immediate pick query
bool pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
- bool pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects");
- bool pick_reflection_probe = gSavedSettings.getBOOL("SelectReflectionProbes");
+ static LLCachedControl<bool> select_invisible_objects(gSavedSettings, "SelectInvisibleObjects");
+ static LLCachedControl<bool> select_reflection_probes(gSavedSettings, "SelectReflectionProbes");
- mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged, false, true, pick_reflection_probe);
+ mPick = gViewerWindow->pickImmediate(x, y, select_invisible_objects, pick_rigged, false, true, select_reflection_probes);
// Pass mousedown to agent
LLTool::handleMouseDown(x, y, mask);
@@ -73,7 +73,6 @@ bool LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
return mPick.getObject().notNull();
}
-
// static
LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick, bool ignore_group, bool temp_select, bool select_root)
{
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index aa0cbac91f..a7441febd9 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -398,18 +398,12 @@ void init_audio()
void audio_update_volume(bool force_update)
{
- F32 master_volume = gSavedSettings.getF32("AudioLevelMaster");
- bool mute_audio = gSavedSettings.getBOOL("MuteAudio");
-
- LLProgressView* progress = gViewerWindow->getProgressView();
- bool progress_view_visible = false;
-
- if (progress)
- {
- progress_view_visible = progress->getVisible();
- }
+ static LLCachedControl<F32> master_volume(gSavedSettings, "AudioLevelMaster");
+ static LLCachedControl<bool> mute_audio_setting(gSavedSettings, "MuteAudio");
+ static LLCachedControl<bool> mute_when_minimized(gSavedSettings, "MuteWhenMinimized");
+ bool mute_audio = mute_audio_setting();
- if (!gViewerWindow->getActive() && gSavedSettings.getBOOL("MuteWhenMinimized"))
+ if (!gViewerWindow->getActive() && mute_when_minimized())
{
mute_audio = true;
}
@@ -419,7 +413,7 @@ void audio_update_volume(bool force_update)
{
// Sound Effects
- gAudiop->setMasterGain ( master_volume );
+ gAudiop->setMasterGain (master_volume());
const F32 AUDIO_LEVEL_DOPPLER = 1.f;
gAudiop->setDopplerFactor(AUDIO_LEVEL_DOPPLER);
@@ -435,6 +429,7 @@ void audio_update_volume(bool force_update)
gAudiop->setRolloffFactor(AUDIO_LEVEL_UNDERWATER_ROLLOFF);
}
+ bool progress_view_visible = gViewerWindow->getShowProgress();
gAudiop->setMuted(mute_audio || progress_view_visible);
//Play any deferred sounds when unmuted
@@ -448,13 +443,21 @@ void audio_update_volume(bool force_update)
audio_update_wind(true);
}
+ static LLCachedControl<bool> mute_sounds(gSavedSettings, "MuteSounds");
+ static LLCachedControl<bool> mute_ui(gSavedSettings, "MuteUI");
+ static LLCachedControl<bool> mute_ambient(gSavedSettings, "MuteAmbient");
+ static LLCachedControl<bool> mute_music(gSavedSettings, "MuteMusic");
+ static LLCachedControl<F32> al_sfx(gSavedSettings, "AudioLevelSFX");
+ static LLCachedControl<F32> al_ui(gSavedSettings, "AudioLevelUI");
+ static LLCachedControl<F32> al_ambient(gSavedSettings, "AudioLevelAmbient");
+ static LLCachedControl<F32> al_music(gSavedSettings, "AudioLevelMusic");
// handle secondary gains
gAudiop->setSecondaryGain(LLAudioEngine::AUDIO_TYPE_SFX,
- gSavedSettings.getBOOL("MuteSounds") ? 0.f : gSavedSettings.getF32("AudioLevelSFX"));
+ mute_sounds() ? 0.f : al_sfx());
gAudiop->setSecondaryGain(LLAudioEngine::AUDIO_TYPE_UI,
- gSavedSettings.getBOOL("MuteUI") ? 0.f : gSavedSettings.getF32("AudioLevelUI"));
+ mute_ui() ? 0.f : al_ui());
gAudiop->setSecondaryGain(LLAudioEngine::AUDIO_TYPE_AMBIENT,
- gSavedSettings.getBOOL("MuteAmbient") ? 0.f : gSavedSettings.getF32("AudioLevelAmbient"));
+ mute_ambient() ? 0.f : al_ambient());
// Streaming Music
@@ -464,31 +467,29 @@ void audio_update_volume(bool force_update)
LLViewerAudio::getInstance()->setForcedTeleportFade(false);
}
- F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
- bool music_muted = gSavedSettings.getBOOL("MuteMusic");
F32 fade_volume = LLViewerAudio::getInstance()->getFadeVolume();
- music_volume = mute_volume * master_volume * music_volume * fade_volume;
- gAudiop->setInternetStreamGain (music_muted ? 0.f : music_volume);
+ F32 music_volume = mute_volume * master_volume * al_music() * fade_volume;
+ gAudiop->setInternetStreamGain (mute_music() ? 0.f : music_volume);
}
// Streaming Media
- F32 media_volume = gSavedSettings.getF32("AudioLevelMedia");
- bool media_muted = gSavedSettings.getBOOL("MuteMedia");
- media_volume = mute_volume * master_volume * media_volume;
- LLViewerMedia::getInstance()->setVolume( media_muted ? 0.0f : media_volume );
+ static LLCachedControl<bool> media_muted(gSavedSettings, "MuteMedia");
+ static LLCachedControl<F32> media_volume(gSavedSettings, "AudioLevelMedia");
+ LLViewerMedia::getInstance()->setVolume( media_muted() ? 0.0f : (mute_volume * master_volume() * media_volume()));
// Voice, this is parametric singleton, it gets initialized when ready
if (LLVoiceClient::instanceExists())
{
- F32 voice_volume = gSavedSettings.getF32("AudioLevelVoice");
- voice_volume = mute_volume * master_volume * voice_volume;
- bool voice_mute = gSavedSettings.getBOOL("MuteVoice");
+ static LLCachedControl<bool> voice_mute(gSavedSettings, "MuteVoice");
+ static LLCachedControl<F32> voice_volume_setting(gSavedSettings, "AudioLevelVoice");
+ static LLCachedControl<F32> voice_mic_setting(gSavedSettings, "AudioLevelMic");
+ F32 voice_volume = mute_volume * master_volume() * voice_volume_setting();
LLVoiceClient *voice_inst = LLVoiceClient::getInstance();
- voice_inst->setVoiceVolume(voice_mute ? 0.f : voice_volume);
- voice_inst->setMicGain(voice_mute ? 0.f : gSavedSettings.getF32("AudioLevelMic"));
+ voice_inst->setVoiceVolume(voice_mute() ? 0.f : voice_volume);
+ voice_inst->setMicGain(voice_mute() ? 0.f : voice_mic_setting());
- if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized")))
+ if (!gViewerWindow->getActive() && mute_when_minimized())
{
voice_inst->setMuteMic(true);
}
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 1c6a7a3e79..6d42cf2347 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -814,6 +814,7 @@ void setting_setup_signal_listener(LLControlGroup& group, const std::string& set
void settings_setup_listeners()
{
+ LL_PROFILE_ZONE_SCOPED;
setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTerrainScale", handleTerrainScaleChanged);
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 314e32bffd..41c048dc4d 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -576,9 +576,9 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot)
LLImageGL::updateStats(gFrameTimeSeconds);
static LLCachedControl<S32> avatar_name_tag_mode(gSavedSettings, "AvatarNameTagMode", 1);
- static LLCachedControl<bool> name_tag_show_group_titles(gSavedSettings, "NameTagShowGroupTitles", true);
+ static LLCachedControl<S32> name_tag_show_group_titles(gSavedSettings, "GroupTitlesTagMode", 2 /*all group tags*/);
LLVOAvatar::sRenderName = avatar_name_tag_mode;
- LLVOAvatar::sRenderGroupTitles = name_tag_show_group_titles && avatar_name_tag_mode > 0;
+ LLVOAvatar::sRenderGroupTitles = avatar_name_tag_mode > 0 ? name_tag_show_group_titles : 0;
gPipeline.mBackfaceCull = true;
gFrameCount++;
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index fca15d2e79..50cc2442cb 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -44,7 +44,6 @@
#include "llfloateravatarrendersettings.h"
#include "llfloateravatartextures.h"
#include "llfloaterbanduration.h"
-#include "llfloaterbigpreview.h"
#include "llfloaterbeacons.h"
#include "llfloaterbuildoptions.h"
#include "llfloaterbulkpermission.h"
@@ -121,7 +120,6 @@
#include "llfloaterpay.h"
#include "llfloaterperformance.h"
#include "llfloaterperms.h"
-#include "llfloaterpostprocess.h"
#include "llfloaterpreference.h"
#include "llfloaterpreferencesgraphicsadvanced.h"
#include "llfloaterpreferenceviewadvanced.h"
@@ -144,7 +142,6 @@
#include "llfloatersidepanelcontainer.h"
#include "llfloaterslapptest.h"
#include "llfloatersnapshot.h"
-#include "llfloatersounddevices.h"
#include "llfloaterspellchecksettings.h"
#include "llfloatertelehub.h"
#include "llfloatertestinspectors.h"
@@ -155,7 +152,6 @@
#include "llfloatertoybox.h"
#include "llfloatertranslationsettings.h"
#include "llfloateruipreview.h"
-#include "llfloatervoiceeffect.h"
#include "llfloaterwebcontent.h"
#include "llfloatervoicevolume.h"
#include "llfloaterwhitelistentry.h"
@@ -372,7 +368,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("emoji_picker", "floater_emoji_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEmojiPicker>);
LLFloaterReg::add("emoji_complete", "floater_emoji_complete.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEmojiComplete>);
- LLFloaterReg::add("env_post_process", "floater_post_process.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostProcess>);
LLFloaterReg::add("env_fixed_environmentent_water", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentWater>);
LLFloaterReg::add("env_fixed_environmentent_sky", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentSky>);
@@ -505,7 +500,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater);
LLFloaterReg::add("settings_color", "floater_settings_color.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsColor>);
LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>);
- LLFloaterReg::add("sound_devices", "floater_sound_devices.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundDevices>);
LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>);
LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>);
@@ -518,8 +512,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);
LLFloaterReg::add("slapp_test", "floater_test_slapp.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSLappTest>);
- LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
-
LLFloaterUIPreviewUtil::registerFloater();
LLFloaterReg::add("upload_anim_bvh", "floater_animation_bvh_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBvhPreview>, "upload");
LLFloaterReg::add("upload_anim_anim", "floater_animation_anim_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload");
@@ -528,8 +520,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("upload_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptPreview>, "upload");
LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
- LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>);
-
LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>);
LLFloaterReg::add("window_size", "floater_window_size.xml", &LLFloaterReg::build<LLFloaterWindowSize>);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 330aa7c368..6448dd6ba5 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -663,9 +663,10 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE);
llassert(!gCubeSnapshot);
+ static LLCachedControl<bool> use_read_thread(gSavedSettings, "PluginUseReadThread", true);
// Enable/disable the plugin read thread
- LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread"));
+ LLPluginProcessParent::setUseReadThread(use_read_thread());
// SL-16418 We can't call LLViewerMediaImpl->update() if we are in the state of shutting down.
if(LLApp::isExiting())
@@ -2206,16 +2207,19 @@ void LLViewerMediaImpl::updateVolume()
if (mProximityCamera > 0)
{
- if (mProximityCamera > gSavedSettings.getF32("MediaRollOffMax"))
+ static LLCachedControl<F32> media_rolloff_min(gSavedSettings, "MediaRollOffMin");
+ static LLCachedControl<F32> media_rolloff_max(gSavedSettings, "MediaRollOffMax");
+ static LLCachedControl<F32> media_rolloff_rate(gSavedSettings, "MediaRollOffRate");
+ if (mProximityCamera > media_rolloff_max())
{
volume = 0;
}
- else if (mProximityCamera > gSavedSettings.getF32("MediaRollOffMin"))
+ else if (mProximityCamera > media_rolloff_min())
{
// attenuated_volume = 1 / (roll_off_rate * (d - min))^2
// the +1 is there so that for distance 0 the volume stays the same
- F64 adjusted_distance = mProximityCamera - gSavedSettings.getF32("MediaRollOffMin");
- F64 attenuation = 1.0 + (gSavedSettings.getF32("MediaRollOffRate") * adjusted_distance);
+ F64 adjusted_distance = mProximityCamera - media_rolloff_min();
+ F64 attenuation = 1.0 + (media_rolloff_rate() * adjusted_distance);
attenuation = 1.0 / (attenuation * attenuation);
// the attenuation multiplier should never be more than one since that would increase volume
volume = volume * (F32)llmin(1.0, attenuation);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 5ea64a7824..55500eea9a 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -144,7 +144,7 @@
#include "llwindow.h"
#include "llpathfindingmanager.h"
#include "llstartup.h"
-#include "boost/unordered_map.hpp"
+#include <unordered_map>
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/json.hpp>
@@ -158,7 +158,7 @@ using namespace LLAvatarAppearanceDefines;
typedef LLPointer<LLViewerObject> LLViewerObjectPtr;
-static boost::unordered_map<std::string, LLStringExplicit> sDefaultItemLabels;
+static std::unordered_map<std::string, LLStringExplicit> sDefaultItemLabels;
LLVOAvatar* find_avatar_from_object(LLViewerObject* object);
LLVOAvatar* find_avatar_from_object(const LLUUID& object_id);
@@ -418,7 +418,23 @@ static LLSLMMenuUpdater* gSLMMenuUpdater = NULL;
LLSLMMenuUpdater::LLSLMMenuUpdater()
{
- mMarketplaceListingsItem = gMenuHolder->getChild<LLView>("MarketplaceListings")->getHandle();
+ LLView* me_menu = gMenuHolder->findChild<LLView>("Me");
+ if (!me_menu)
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Can't find 'Me' menu in 'menu_viewer'" << LL_ENDL;
+ return;
+ }
+
+ LLView* marketplace_listings = me_menu->findChild<LLView>("MarketplaceListings");
+ if (!marketplace_listings)
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Can't find 'MarketplaceListings' in 'Me' menu" << LL_ENDL;
+ return;
+ }
+
+ mMarketplaceListingsItem = marketplace_listings->getHandle();
}
void LLSLMMenuUpdater::setMerchantMenu()
{
@@ -430,7 +446,7 @@ void LLSLMMenuUpdater::setMerchantMenu()
LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
gToolBarView->enableCommand(command->id(), true);
- const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.isNull())
{
U32 mkt_status = LLMarketplaceData::instance().getSLMStatus();
@@ -478,6 +494,8 @@ void check_merchant_status(bool force)
void init_menus()
{
+ LL_PROFILE_ZONE_SCOPED;
+
// Initialize actions
initialize_menus();
@@ -554,7 +572,29 @@ void init_menus()
color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
}
- LLView* menu_bar_holder = gViewerWindow->getRootView()->getChildView("menu_bar_holder");
+ LLView* menu_stack = gViewerWindow->getMainView()->findChildView("menu_stack");
+ if (!menu_stack)
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Can't find menu_stack in main_view" << LL_ENDL;
+ return;
+ }
+
+ LLView* status_bar_container = menu_stack->findChildView("status_bar_container");
+ if (!status_bar_container)
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Can't find status_bar_container in main_view" << LL_ENDL;
+ return;
+ }
+
+ LLView* menu_bar_holder = status_bar_container->findChildView("menu_bar_holder");
+ if (!menu_bar_holder)
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Can't find status_bar_container in main_view" << LL_ENDL;
+ return;
+ }
gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
gMenuBarView->setRect(LLRect(0, menu_bar_holder->getRect().mTop, 0, menu_bar_holder->getRect().mTop - MENU_BAR_HEIGHT));
@@ -568,8 +608,33 @@ void init_menus()
// *TODO:Also fix cost in llfolderview.cpp for Inventory menus
const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
- gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", sound_upload_cost_str);
- gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", animation_upload_cost_str);
+
+ LLView* main_upload_menu = gMenuHolder->findChild<LLView>("Upload");
+ if (!main_upload_menu)
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Can't find 'Upload' menu in 'menu_viewer'" << LL_ENDL;
+ return;
+ }
+
+ LLView* upload_sound = main_upload_menu->findChild<LLView>("Upload Sound");
+ if (!upload_sound)
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Can't find 'Upload Sound' menu item in 'Upload' menu" << LL_ENDL;
+ return;
+ }
+ upload_sound->setLabelArg("[COST]", sound_upload_cost_str);
+
+ LLView* upload_anim = main_upload_menu->findChild<LLView>("Upload Animation");
+ if (!upload_anim)
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Can't find 'Upload Animation' menu item in 'Upload' menu" << LL_ENDL;
+ return;
+ }
+ upload_anim->setLabelArg("[COST]", animation_upload_cost_str);
+
gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", true);
gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", true);
@@ -577,13 +642,6 @@ void init_menus()
gDetachAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach", true);
gDetachHUDAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach HUD", true);
- // Don't display the Memory console menu if the feature is turned off
- LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild<LLMenuItemCheckGL>("Memory", true);
- if (memoryMenu)
- {
- memoryMenu->setVisible(false);
- }
-
gMenuBarView->createJumpKeys();
// Let land based option enable when parcel changes
@@ -2971,11 +3029,45 @@ void handle_object_show_original()
show_item_original(object->getAttachmentItemID());
}
+void handle_object_set_favorite(const LLSD& userdata)
+{
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object)
+ {
+ return;
+ }
+ LLViewerObject *parent = (LLViewerObject*)object->getParent();
+ while (parent)
+ {
+ if(parent->isAvatar())
+ {
+ break;
+ }
+ object = parent;
+ parent = (LLViewerObject*)parent->getParent();
+ }
+ if (!object || object->isAvatar())
+ {
+ return;
+ }
+
+ LLUUID item_id = gInventory.getLinkedItemID(object->getAttachmentItemID());
+
+ std::string action = userdata.asString();
+ if (action == "Add")
+ {
+ set_favorite(item_id, true);
+ }
+ if (action == "Remove")
+ {
+ set_favorite(item_id, false);
+ }
+}
static void init_default_item_label(LLUICtrl* ctrl)
{
const std::string& item_name = ctrl->getName();
- boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
+ std::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
if (it == sDefaultItemLabels.end())
{
// *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value
@@ -2991,7 +3083,7 @@ static void init_default_item_label(LLUICtrl* ctrl)
static LLStringExplicit get_default_item_label(const std::string& item_name)
{
LLStringExplicit res("");
- boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
+ std::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
if (it != sDefaultItemLabels.end())
{
res = it->second;
@@ -3027,6 +3119,41 @@ bool enable_object_touch(LLUICtrl* ctrl)
return new_value;
};
+bool enable_object_favorite(const LLSD& userdata)
+{
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object)
+ {
+ return false;
+ }
+ LLViewerObject* parent = (LLViewerObject*)object->getParent();
+ while (parent)
+ {
+ if (parent->isAvatar())
+ {
+ break;
+ }
+ object = parent;
+ parent = (LLViewerObject*)parent->getParent();
+ }
+ if (!object || object->isAvatar())
+ {
+ return false;
+ }
+
+ std::string action = userdata.asString();
+ LLUUID item_id = gInventory.getLinkedItemID(object->getAttachmentItemID());
+ if (action == "Add")
+ {
+ return !get_is_favorite(item_id);
+ }
+ if (action == "Remove")
+ {
+ return get_is_favorite(item_id);
+ }
+ return false;
+}
+
//void label_touch(std::string& label, void*)
//{
// LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
@@ -9616,17 +9743,6 @@ class LLWorldEnableEnvPreset : public view_listener_t
}
};
-
-/// Post-Process callbacks
-class LLWorldPostProcess : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloaterReg::showInstance("env_post_process");
- return true;
- }
-};
-
class LLWorldCheckBanLines : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -9809,6 +9925,8 @@ void initialize_spellcheck_menu()
void initialize_menus()
{
+ LL_PROFILE_ZONE_SCOPED;
+
// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
class LLZoomer : public view_listener_t
{
@@ -9918,7 +10036,6 @@ void initialize_menus()
view_listener_t::addMenu(new LLWorldEnableEnvSettings(), "World.EnableEnvSettings");
view_listener_t::addMenu(new LLWorldEnvPreset(), "World.EnvPreset");
view_listener_t::addMenu(new LLWorldEnableEnvPreset(), "World.EnableEnvPreset");
- view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess");
view_listener_t::addMenu(new LLWorldCheckBanLines() , "World.CheckBanLines");
view_listener_t::addMenu(new LLWorldShowBanLines() , "World.ShowBanLines");
@@ -10234,6 +10351,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
commit.add("Object.Touch", boost::bind(&handle_object_touch));
commit.add("Object.ShowOriginal", boost::bind(&handle_object_show_original));
+ commit.add("Object.SetFavorite", boost::bind(&handle_object_set_favorite, _2));
commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
commit.add("Object.Delete", boost::bind(&handle_object_delete));
view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
@@ -10262,6 +10380,7 @@ void initialize_menus()
enable.add("Object.EnableEditGLTFMaterial", boost::bind(&enable_object_edit_gltf_material));
enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
+ enable.add("Object.EnableFavorites", boost::bind(&enable_object_favorite, _2));
enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
enable.add("Object.EnableWear", boost::bind(&object_is_wearable));
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 494a11d94f..b8515fd92b 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -5771,28 +5771,40 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
args["NAME"] = clean_owner_name;
S32 known_questions = 0;
bool has_not_only_debit = questions ^ SCRIPT_PERMISSIONS[SCRIPT_PERMISSION_DEBIT].permbit;
+ bool caution_enabled = gSavedSettings.getBOOL("PermissionsCautionEnabled");
// check the received permission flags against each permission
+ std::string warning_msg;
for (const script_perm_t& script_perm : SCRIPT_PERMISSIONS)
{
if (questions & script_perm.permbit)
{
- count++;
known_questions |= script_perm.permbit;
// check whether permission question should cause special caution dialog
caution |= (script_perm.caution);
- if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit)
+ // Cautions go into top part of the dialog, questions go into the footer
+ if (caution_enabled && script_perm.caution)
+ {
+ warning_msg += "\n" + LLTrans::getString(script_perm.question + "Caution") + "\n";
continue;
+ }
if (LLTrans::getString(script_perm.question).empty())
{
continue;
}
- script_question += " " + LLTrans::getString(script_perm.question) + "\n";
+ count++;
+ script_question += "\n " + LLTrans::getString(script_perm.question);
}
}
+ if (!warning_msg.empty())
+ {
+ LLStringUtil::format(warning_msg, args);
+ args["WARNINGS"] = warning_msg;
+ }
+
args["QUESTIONS"] = script_question;
if (known_questions != questions)
@@ -5817,12 +5829,12 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
// check whether cautions are even enabled or not
const char* notification = "ScriptQuestion";
- if(caution && gSavedSettings.getBOOL("PermissionsCautionEnabled"))
+ if(caution && caution_enabled)
{
- args["FOOTERTEXT"] = (count > 1) ? LLTrans::getString("AdditionalPermissionsRequestHeader") + "\n\n" + script_question : "";
+ args["FOOTERTEXT"] = (count > 0) ? LLTrans::getString("AdditionalPermissionsRequestHeader") + "\n" + script_question : "";
notification = "ScriptQuestionCaution";
}
- else if(experienceid.notNull())
+ else if (experienceid.notNull())
{
payload["experience"]=experienceid;
LLExperienceCache::instance().get(experienceid, boost::bind(process_script_experience_details, _1, args, payload));
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index f7b1fb004f..607ffe32ee 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -130,6 +130,7 @@ F64Seconds LLViewerObject::sPhaseOutUpdateInterpolationTime(2.0); // For motio
F64Seconds LLViewerObject::sMaxRegionCrossingInterpolationTime(1.0);// For motion interpolation: don't interpolate over this time on region crossing
std::map<std::string, U32> LLViewerObject::sObjectDataMap;
+std::unordered_map<LLUUID, std::vector<LLViewerObject*>> LLViewerObject::sPendingUpdatesByOwner;
// The maximum size of an object extra parameters binary (packed) block
#define MAX_OBJECT_PARAMS_SIZE 1024
@@ -311,6 +312,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mLastUpdateType(OUT_UNKNOWN),
mLastUpdateCached(false),
mLocked(false),
+ mExtraParameterList(LLNetworkData::PARAMS_MAX >> 4),
mCachedMuteListUpdateTime(0),
mCachedOwnerInMuteList(false),
mRiggedAttachedWarned(false)
@@ -368,15 +370,6 @@ LLViewerObject::~LLViewerObject()
}
// Delete memory associated with extra parameters.
- std::unordered_map<U16, ExtraParameter*>::iterator iter;
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
- {
- if(iter->second != NULL)
- {
- delete iter->second->data;
- delete iter->second;
- }
- }
mExtraParameterList.clear();
for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
@@ -530,6 +523,8 @@ void LLViewerObject::markDead()
mReflectionProbe = nullptr;
}
+ removeObjectFromPendingUpdate(this);
+
sNumZombieObjects++;
}
}
@@ -1509,10 +1504,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
unpackParticleSource(block_num, owner_id);
// Mark all extra parameters not used
- std::unordered_map<U16, ExtraParameter*>::iterator iter;
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ for (auto& entry : mExtraParameterList)
{
- iter->second->in_use = false;
+ if (entry.in_use) *entry.in_use = false;
}
// Unpack extra parameters
@@ -1544,12 +1538,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
delete[] buffer;
}
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ for (size_t i = 0; i < mExtraParameterList.size(); ++i)
{
- if (!iter->second->in_use)
+ auto& entry = mExtraParameterList[i];
+ if (entry.in_use && !*entry.in_use)
{
// Send an update message in case it was formerly in use
- parameterChanged(iter->first, iter->second->data, false, false);
+ parameterChanged(((U16)i + 1) << 4, entry.data, false, false);
}
}
@@ -1851,10 +1846,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
// Mark all extra parameters not used
- std::unordered_map<U16, ExtraParameter*>::iterator iter;
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ for (auto& entry : mExtraParameterList)
{
- iter->second->in_use = false;
+ if (entry.in_use) *entry.in_use = false;
}
// Unpack extra params
@@ -1872,12 +1866,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
unpackParameterEntry(param_type, &dp2);
}
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ for (size_t i = 0; i < mExtraParameterList.size(); ++i)
{
- if (!iter->second->in_use)
+ auto& entry = mExtraParameterList[i];
+ if (entry.in_use && !*entry.in_use)
{
// Send an update message in case it was formerly in use
- parameterChanged(iter->first, iter->second->data, false, false);
+ parameterChanged(((U16)i + 1) << 4, entry.data, false, false);
}
}
@@ -4184,7 +4179,7 @@ void LLViewerObject::boostTexturePriority(bool boost_children /* = true */)
if (isSculpted() && !isMesh())
{
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = getSculptParams();
if (sculpt_params)
{
LLUUID sculpt_id = sculpt_params->getSculptTexture();
@@ -4656,9 +4651,10 @@ const LLQuaternion LLViewerObject::getRenderRotation() const
}
else
{
- if (!mDrawable->isRoot())
+ LLDrawable* parent = mDrawable->getParent();
+ if (!mDrawable->isRoot() && parent)
{
- ret = getRotation() * LLQuaternion(mDrawable->getParent()->getWorldMatrix());
+ ret = getRotation() * LLQuaternion(parent->getWorldMatrix());
}
else
{
@@ -6495,7 +6491,7 @@ bool LLViewerObject::unpackParameterEntry(U16 param_type, LLDataPacker *dp)
if (param)
{
param->data->unpack(*dp);
- param->in_use = true;
+ *param->in_use = true;
parameterChanged(param_type, param->data, true, false);
return true;
}
@@ -6507,108 +6503,79 @@ bool LLViewerObject::unpackParameterEntry(U16 param_type, LLDataPacker *dp)
LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 param_type)
{
- LLNetworkData* new_block = NULL;
+ LLNetworkData* new_block = nullptr;
+ bool* in_use = NULL;
switch (param_type)
{
case LLNetworkData::PARAMS_FLEXIBLE:
{
- new_block = new LLFlexibleObjectData();
+ mFlexibleObjectData = std::make_unique<LLFlexibleObjectData>();
+ new_block = mFlexibleObjectData.get();
+ in_use = &mFlexibleObjectDataInUse;
break;
}
case LLNetworkData::PARAMS_LIGHT:
{
- new_block = new LLLightParams();
+ mLightParams = std::make_unique<LLLightParams>();
+ new_block = mLightParams.get();
+ in_use = &mLightParamsInUse;
break;
}
case LLNetworkData::PARAMS_SCULPT:
{
- new_block = new LLSculptParams();
+ mSculptParams = std::make_unique<LLSculptParams>();
+ new_block = mSculptParams.get();
+ in_use = &mSculptParamsInUse;
break;
}
case LLNetworkData::PARAMS_LIGHT_IMAGE:
{
- new_block = new LLLightImageParams();
+ mLightImageParams = std::make_unique<LLLightImageParams>();
+ new_block = mLightImageParams.get();
+ in_use = &mLightImageParamsInUse;
break;
}
case LLNetworkData::PARAMS_EXTENDED_MESH:
{
- new_block = new LLExtendedMeshParams();
+ mExtendedMeshParams = std::make_unique<LLExtendedMeshParams>();
+ new_block = mExtendedMeshParams.get();
+ in_use = &mExtendedMeshParamsInUse;
break;
}
case LLNetworkData::PARAMS_RENDER_MATERIAL:
{
- new_block = new LLRenderMaterialParams();
+ mRenderMaterialParams = std::make_unique<LLRenderMaterialParams>();
+ new_block = mRenderMaterialParams.get();
+ in_use = &mRenderMaterialParamsInUse;
break;
}
case LLNetworkData::PARAMS_REFLECTION_PROBE:
{
- new_block = new LLReflectionProbeParams();
+ mReflectionProbeParams = std::make_unique<LLReflectionProbeParams>();
+ new_block = mReflectionProbeParams.get();
+ in_use = &mReflectionProbeParamsInUse;
break;
}
default:
{
- LL_INFOS_ONCE() << "Unknown param type: " << param_type << LL_ENDL;
+ LL_INFOS_ONCE() << "Unknown param type. (" << llformat("0x%2x", param_type) << ")" << LL_ENDL;
break;
}
};
+ ExtraParameter& entry = mExtraParameterList[U32(param_type >> 4) - 1];
if (new_block)
{
- ExtraParameter* new_entry = new ExtraParameter;
- new_entry->data = new_block;
- new_entry->in_use = false; // not in use yet
- llassert(mExtraParameterList[param_type] == nullptr); // leak -- redundantly allocated parameter entry
- mExtraParameterList[param_type] = new_entry;
- return new_entry;
- }
- return NULL;
-}
-
-LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER;
- std::unordered_map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
- if (itor != mExtraParameterList.end())
- {
- return itor->second;
- }
- return NULL;
-}
-
-LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntryCreate(U16 param_type)
-{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (!param)
- {
- param = createNewParameterEntry(param_type);
- }
- return param;
-}
-
-LLNetworkData* LLViewerObject::getParameterEntry(U16 param_type) const
-{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (param)
- {
- return param->data;
+ entry.in_use = in_use;
+ *entry.in_use = false; // not in use yet
+ entry.data = new_block;
+ return &entry;
}
else
{
- return NULL;
- }
-}
-
-bool LLViewerObject::getParameterEntryInUse(U16 param_type) const
-{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (param)
- {
- return param->in_use;
- }
- else
- {
- return false;
+ entry.is_invalid = true;
}
+ return nullptr;
}
bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin)
@@ -6616,11 +6583,11 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_
ExtraParameter* param = getExtraParameterEntryCreate(param_type);
if (param)
{
- if (param->in_use && new_value == *(param->data))
+ if (*(param->in_use) && new_value == *(param->data))
{
return false;
}
- param->in_use = true;
+ *param->in_use = true;
param->data->copy(new_value);
parameterChanged(param_type, param->data, true, local_origin);
return true;
@@ -6636,22 +6603,28 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_
// Should always return true.
bool LLViewerObject::setParameterEntryInUse(U16 param_type, bool in_use, bool local_origin)
{
- ExtraParameter* param = getExtraParameterEntryCreate(param_type);
- if (param && param->in_use != in_use)
+ if (param_type <= LLNetworkData::PARAMS_MAX)
{
- param->in_use = in_use;
- parameterChanged(param_type, param->data, in_use, local_origin);
- return true;
+ ExtraParameter* param = (in_use ? getExtraParameterEntryCreate(param_type) : &getExtraParameterEntry(param_type));
+ if (param && param->data && *param->in_use != in_use)
+ {
+ *param->in_use = in_use;
+ parameterChanged(param_type, param->data, in_use, local_origin);
+ return true;
+ }
}
return false;
}
void LLViewerObject::parameterChanged(U16 param_type, bool local_origin)
{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (param)
+ if (param_type <= LLNetworkData::PARAMS_MAX)
{
- parameterChanged(param_type, param->data, param->in_use, local_origin);
+ const ExtraParameter& param = getExtraParameterEntry(param_type);
+ if (param.data)
+ {
+ parameterChanged(param_type, param.data, *param.in_use, local_origin);
+ }
}
}
@@ -6699,7 +6672,7 @@ void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, bool
{
if (param_type == LLNetworkData::PARAMS_RENDER_MATERIAL)
{
- const LLRenderMaterialParams* params = in_use ? (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL) : nullptr;
+ const LLRenderMaterialParams* params = in_use ? getRenderMaterialParams() : nullptr;
setRenderMaterialIDs(params, local_origin);
}
}
@@ -7470,9 +7443,10 @@ const std::string& LLViewerObject::getAttachmentItemName() const
LLVOAvatar* LLViewerObject::getAvatar() const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- if (getControlAvatar())
+ LLControlAvatar* ca = getControlAvatar();
+ if (ca)
{
- return getControlAvatar();
+ return ca;
}
if (isAttachment())
{
@@ -7491,7 +7465,7 @@ LLVOAvatar* LLViewerObject::getAvatar() const
bool LLViewerObject::hasRenderMaterialParams() const
{
- return getParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ return mRenderMaterialParamsInUse;
}
void LLViewerObject::setHasRenderMaterialParams(bool has_materials)
@@ -7513,7 +7487,7 @@ void LLViewerObject::setHasRenderMaterialParams(bool has_materials)
const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const
{
- LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ const LLRenderMaterialParams* param_block = getRenderMaterialParams();
if (param_block)
{
return param_block->getMaterial(te);
@@ -7554,7 +7528,7 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
start_idx = llmax(start_idx, 0);
end_idx = llmin(end_idx, (S32) getNumTEs());
- LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ LLRenderMaterialParams* param_block = getRenderMaterialParams();
if (!param_block && id.notNull())
{ // block doesn't exist, but it will need to
param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data;
@@ -7782,6 +7756,61 @@ bool LLViewerObject::isReachable()
return false;
}
+void LLViewerObject::markObjectsForUpdate(const LLUUID& owner_id)
+{
+ sPendingUpdatesByOwner.erase(owner_id);
+ for (S32 i = 0; i < gObjectList.getNumObjects(); ++i)
+ {
+ LLViewerObject* obj = gObjectList.getObject(i);
+ if (!obj || obj->isDead() || obj->isAvatar() || obj->permYouOwner())
+ {
+ continue;
+ }
+ sPendingUpdatesByOwner[owner_id].push_back(obj);
+ }
+}
+
+void LLViewerObject::removeObjectFromPendingUpdate(LLViewerObject* obj)
+{
+ for (auto& [owner_id, objects] : sPendingUpdatesByOwner)
+ {
+ objects.erase(std::remove(objects.begin(), objects.end(), obj), objects.end());
+ }
+}
+
+bool LLViewerObject::isObjectInPendingUpdate(const LLUUID& owner_id, LLViewerObject* obj)
+{
+ if (!obj)
+ {
+ return false;
+ }
+ auto it = sPendingUpdatesByOwner.find(owner_id);
+ if (it != sPendingUpdatesByOwner.end())
+ {
+ const auto& objects = it->second;
+ return std::find(objects.begin(), objects.end(), obj) != objects.end();
+ }
+ return false;
+}
+
+void LLViewerObject::requestObjectUpdate()
+{
+ if (LLViewerRegion* regionp = getRegion())
+ {
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_RequestMultipleObjects);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_ObjectData);
+ msg->addU8Fast(_PREHASH_CacheMissType, 0);
+ msg->addU32Fast(_PREHASH_ID, getLocalID());
+ msg->sendReliable(regionp->getHost());
+
+ removeObjectFromPendingUpdate(this);
+ }
+}
+
class ObjectPhysicsProperties : public LLHTTPNode
{
public:
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 6e26da74e7..8f23563c28 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -126,13 +126,15 @@ class LLViewerObject
protected:
virtual ~LLViewerObject(); // use unref()
+private:
// TomY: Provide for a list of extra parameter structures, mapped by structure name
struct ExtraParameter
{
- bool in_use;
- LLNetworkData *data;
+ bool is_invalid = false;
+ bool* in_use = nullptr;
+ LLNetworkData* data = nullptr;
};
- std::unordered_map<U16, ExtraParameter*> mExtraParameterList;
+ std::vector<ExtraParameter> mExtraParameterList;
public:
typedef std::list<LLPointer<LLViewerObject> > child_list_t;
@@ -620,6 +622,11 @@ public:
void setPhysicsDensity(F32 density);
void setPhysicsRestitution(F32 restitution);
+ static void markObjectsForUpdate(const LLUUID& owner_id);
+ static void removeObjectFromPendingUpdate(LLViewerObject* obj);
+ static bool isObjectInPendingUpdate(const LLUUID& owner_id, LLViewerObject* obj);
+ void requestObjectUpdate();
+
virtual void dump() const;
static U32 getNumZombieObjects() { return sNumZombieObjects; }
@@ -630,10 +637,16 @@ public:
void dirtySpatialGroup() const;
virtual void dirtyMesh();
- virtual LLNetworkData* getParameterEntry(U16 param_type) const;
- virtual bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin);
- virtual bool getParameterEntryInUse(U16 param_type) const;
- virtual bool setParameterEntryInUse(U16 param_type, bool in_use, bool local_origin);
+ LLFlexibleObjectData* getFlexibleObjectData() const { return mFlexibleObjectDataInUse ? mFlexibleObjectData.get() : nullptr; }
+ LLLightParams* getLightParams() const { return mLightParamsInUse ? mLightParams.get() : nullptr; }
+ LLSculptParams* getSculptParams() const { return mSculptParamsInUse ? mSculptParams.get() : nullptr; }
+ LLLightImageParams* getLightImageParams() const { return mLightImageParamsInUse ? mLightImageParams.get() : nullptr; }
+ LLExtendedMeshParams* getExtendedMeshParams() const { return mExtendedMeshParamsInUse ? mExtendedMeshParams.get() : nullptr; }
+ LLRenderMaterialParams* getRenderMaterialParams() const { return mRenderMaterialParamsInUse ? mRenderMaterialParams.get() : nullptr; }
+ LLReflectionProbeParams* getReflectionProbeParams() const { return mReflectionProbeParamsInUse ? mReflectionProbeParams.get() : nullptr; }
+
+ bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin);
+ bool setParameterEntryInUse(U16 param_type, bool in_use, bool local_origin);
// Called when a parameter is changed
virtual void parameterChanged(U16 param_type, bool local_origin);
virtual void parameterChanged(U16 param_type, LLNetworkData* data, bool in_use, bool local_origin);
@@ -675,8 +688,31 @@ private:
bool isAssetInInventory(LLViewerInventoryItem* item, LLAssetType::EType type);
ExtraParameter* createNewParameterEntry(U16 param_type);
- ExtraParameter* getExtraParameterEntry(U16 param_type) const;
- ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
+ const ExtraParameter& getExtraParameterEntry(U16 param_type) const
+ {
+ return mExtraParameterList[U32(param_type >> 4) - 1];
+ }
+ ExtraParameter& getExtraParameterEntry(U16 param_type)
+ {
+ return mExtraParameterList[U32(param_type >> 4) - 1];
+ }
+ ExtraParameter* getExtraParameterEntryCreate(U16 param_type)
+ {
+ if (param_type <= LLNetworkData::PARAMS_MAX)
+ {
+ ExtraParameter& param = getExtraParameterEntry(param_type);
+ if (!param.is_invalid)
+ {
+ if (!param.data)
+ {
+ ExtraParameter* new_entry = createNewParameterEntry(param_type);
+ return new_entry;
+ }
+ return &param;
+ }
+ }
+ return nullptr;
+ }
bool unpackParameterEntry(U16 param_type, LLDataPacker *dp);
// This function checks to see if the given media URL has changed its version
@@ -749,7 +785,23 @@ private:
// Grabbed from UPDATE_FLAGS
U32 mFlags;
+ bool mFlexibleObjectDataInUse = false,
+ mLightParamsInUse = false,
+ mSculptParamsInUse = false,
+ mLightImageParamsInUse = false,
+ mExtendedMeshParamsInUse = false,
+ mRenderMaterialParamsInUse = false,
+ mReflectionProbeParamsInUse = false;
+ std::unique_ptr<LLFlexibleObjectData> mFlexibleObjectData;
+ std::unique_ptr<LLLightParams> mLightParams;
+ std::unique_ptr<LLSculptParams> mSculptParams;
+ std::unique_ptr<LLLightImageParams> mLightImageParams;
+ std::unique_ptr<LLExtendedMeshParams> mExtendedMeshParams;
+ std::unique_ptr<LLRenderMaterialParams> mRenderMaterialParams;
+ std::unique_ptr<LLReflectionProbeParams> mReflectionProbeParams;
+
static std::map<std::string, U32> sObjectDataMap;
+ static std::unordered_map<LLUUID, std::vector<LLViewerObject*>> sPendingUpdatesByOwner;
public:
// Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties
U8 mPhysicsShapeType;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index e41f5bc206..caabd66780 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -65,6 +65,7 @@
#include "lltoolmgr.h"
#include "lltoolpie.h"
#include "llkeyboard.h"
+#include "llmeshrepository.h"
#include "u64.h"
#include "llviewertexturelist.h"
#include "lldatapacker.h"
@@ -173,7 +174,7 @@ bool LLViewerObjectList::removeFromLocalIDTable(LLViewerObject* objectp)
U32 local_id = objectp->mLocalID;
U64 indexid = (((U64)objectp->mRegionIndex) << 32) | (U64)local_id;
- std::map<U64, LLUUID>::iterator iter = mIndexAndLocalIDToUUID.find(indexid);
+ auto iter = mIndexAndLocalIDToUUID.find(indexid);
if (iter == mIndexAndLocalIDToUUID.end())
{
return false;
@@ -1398,6 +1399,8 @@ void LLViewerObjectList::killAllObjects()
llassert((objectp == gAgentAvatarp) || objectp->isDead());
}
+ gMeshRepo.unregisterAllMeshes();
+
cleanDeadObjects(false);
if(!mObjects.empty())
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 547ef9fb2d..adc90a0483 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -204,7 +204,7 @@ protected:
uuid_set_t mDeadObjects;
- std::map<LLUUID, LLPointer<LLViewerObject> > mUUIDObjectMap;
+ std::unordered_map<LLUUID, LLPointer<LLViewerObject> > mUUIDObjectMap;
//set of objects that need to update their cost
uuid_set_t mStaleObjectCost;
@@ -221,7 +221,7 @@ protected:
static U32 sSimulatorMachineIndex;
std::map<U64, U32> mIPAndPortToIndex;
- std::map<U64, LLUUID> mIndexAndLocalIDToUUID;
+ std::unordered_map<U64, LLUUID> mIndexAndLocalIDToUUID;
friend class LLViewerObject;
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index 60e17a6f58..adfe709b04 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -316,7 +316,6 @@ public:
//virtual
bool isRecentlyVisible() const;
- LLViewerOctreePartition* getSpatialPartition()const {return mSpatialPartition;}
bool isAnyRecentlyVisible() const;
static U32 getNewOcclusionQueryObjectName();
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 432da2e990..b794047135 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -702,6 +702,16 @@ bool LLViewerParcelMgr::allowAgentVoice() const
return allowAgentVoice(gAgent.getRegion(), mAgentParcel);
}
+bool LLViewerParcelMgr::isVoiceRestricted() const
+{
+ return mAgentParcel && !mAgentParcel->getParcelFlagUseEstateVoiceChannel();
+}
+
+bool LLViewerParcelMgr::allowVoiceModeration() const
+{
+ return isVoiceRestricted() && isParcelOwnedByAgent(mAgentParcel, GP_SESSION_MODERATOR);
+}
+
bool LLViewerParcelMgr::allowAgentVoice(const LLViewerRegion* region, const LLParcel* parcel) const
{
return region && region->isVoiceEnabled()
@@ -881,7 +891,8 @@ LLParcel* LLViewerParcelMgr::getCollisionParcel() const
void LLViewerParcelMgr::render()
{
- if (mSelected && mRenderSelection && gSavedSettings.getBOOL("RenderParcelSelection") && !gDisconnected)
+ static LLCachedControl<bool> render_parcel_selection(gSavedSettings, "RenderParcelSelection");
+ if (mSelected && mRenderSelection && render_parcel_selection() && !gDisconnected)
{
// Rendering is done in agent-coordinates, so need to supply
// an appropriate offset to the render code.
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index 8439283eb0..0d79496ccc 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -174,6 +174,12 @@ public:
bool allowAgentVoice() const;
bool allowAgentVoice(const LLViewerRegion* region, const LLParcel* parcel) const;
+ // Returns true if this parcel is using private voice channel
+ bool isVoiceRestricted() const;
+
+ // Can this agent moderate Nearby voice chat on this parcel?
+ bool allowVoiceModeration() const;
+
// Can this agent start flying on this parcel?
// Used for parcel property icons in nav bar.
bool allowAgentFly(const LLViewerRegion* region, const LLParcel* parcel) const;
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 0bb03cdd60..02fdddd5d5 100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -63,9 +63,9 @@ LLUIColor LLViewerParcelOverlay::sForSaleColor;
LLUIColor LLViewerParcelOverlay::sAuctionColor;
LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters)
-: mRegion( region ),
- mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ),
- mDirty( false ),
+: mRegion(region),
+ mParcelGridsPerEdge(S32(region_width_meters / PARCEL_GRID_STEP_METERS)),
+ mDirty(false),
mTimeSinceLastUpdate(),
mOverlayTextureIdx(-1)
{
@@ -467,9 +467,9 @@ void LLViewerParcelOverlay::updatePropertyLines()
{
for (S32 col = 0; col < GRIDS_PER_EDGE; col++)
{
- U8 overlay = mOwnership[row*GRIDS_PER_EDGE+col];
+ U8 overlay = mOwnership[row * GRIDS_PER_EDGE + col];
S32 colorIndex = overlay & PARCEL_COLOR_MASK;
- switch(colorIndex)
+ switch (colorIndex)
{
case PARCEL_SELF:
case PARCEL_GROUP:
@@ -483,11 +483,11 @@ void LLViewerParcelOverlay::updatePropertyLines()
const LLColor4U& color = colors[colorIndex];
- F32 left = col*GRID_STEP;
- F32 right = left+GRID_STEP;
+ F32 left = col * GRID_STEP;
+ F32 right = left + GRID_STEP;
- F32 bottom = row*GRID_STEP;
- F32 top = bottom+GRID_STEP;
+ F32 bottom = row * GRID_STEP;
+ F32 top = bottom + GRID_STEP;
// West edge
if (overlay & PARCEL_WEST_LINE)
@@ -528,99 +528,121 @@ void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F3
Edge& edge = mEdges.back();
edge.color = color;
+ // Detailized rendering vertices:
+ // A B C D E F G
+ // *-*------*--------*--------*------*-* : 'outside' vertices are placed right on the border
+ // *------*--------*--------*------* : 'inside' vertices are shifted on LINE_WIDTH inside
+
+ // Simplified rendering vertices:
+ // A G
+ // *-----------------------------------*
+ // *-----------------------------------*
+
F32 outside_x = start_x;
F32 outside_y = start_y;
- F32 outside_z = 0.f;
- F32 inside_x = start_x + tick_dx;
- F32 inside_y = start_y + tick_dy;
- F32 inside_z = 0.f;
+ F32 outside_z = land.resolveHeightRegion(outside_x, outside_y);
+ F32 inside_x = start_x + tick_dx;
+ F32 inside_y = start_y + tick_dy;
+ F32 inside_z = land.resolveHeightRegion(inside_x, inside_y);
+
+ auto move = [&](F32 distance)
+ {
+ outside_x += dx * distance;
+ outside_y += dy * distance;
+ outside_z = land.resolveHeightRegion(outside_x, outside_y);
+ inside_x += dx * distance;
+ inside_y += dy * distance;
+ inside_z = land.resolveHeightRegion(inside_x, inside_y);
+ };
- auto split = [&](const LLVector3& start, F32 x, F32 y, F32 z, F32 part)
+ auto split = [&](U32 lod, const LLVector4a& start, F32 x, F32 y, F32 z, F32 part)
{
- F32 new_x = start.mV[VX] + (x - start.mV[VX]) * part;
- F32 new_y = start.mV[VY] + (y - start.mV[VY]) * part;
- F32 new_z = start.mV[VZ] + (z - start.mV[VZ]) * part;
- edge.vertices.emplace_back(new_x, new_y, new_z);
+ F32 new_x = start[VX] + (x - start[VX]) * part;
+ F32 new_y = start[VY] + (y - start[VY]) * part;
+ edge.pushVertex(lod, new_x, new_y, water_z, 0);
};
- auto checkForSplit = [&]()
+ auto checkForSplit = [&](U32 lod)
{
- const LLVector3& last_outside = edge.vertices.back();
- F32 z0 = last_outside.mV[VZ];
+ const std::vector<LLVector4a>& vertices = edge.verticesUnderWater[lod];
+ const LLVector4a& last_outside = vertices.back();
+ F32 z0 = last_outside[VZ];
F32 z1 = outside_z;
if ((z0 >= water_z && z1 >= water_z) || (z0 < water_z && z1 < water_z))
return;
F32 part = (water_z - z0) / (z1 - z0);
- const LLVector3& last_inside = edge.vertices[edge.vertices.size() - 2];
- split(last_inside, inside_x, inside_y, inside_z, part);
- split(last_outside, outside_x, outside_y, outside_z, part);
+ const LLVector4a& last_inside = vertices[vertices.size() - 2];
+ split(lod, last_inside, inside_x, inside_y, inside_z, part);
+ split(lod, last_outside, outside_x, outside_y, outside_z, part);
};
- // First part, only one vertex
- outside_z = land.resolveHeightRegion( outside_x, outside_y );
-
- edge.vertices.emplace_back(outside_x, outside_y, outside_z);
-
- inside_x += dx * LINE_WIDTH;
- inside_y += dy * LINE_WIDTH;
-
- outside_x += dx * LINE_WIDTH;
- outside_y += dy * LINE_WIDTH;
-
- // Then the "actual edge"
- inside_z = land.resolveHeightRegion( inside_x, inside_y );
- outside_z = land.resolveHeightRegion( outside_x, outside_y );
+ auto pushTwoVertices = [&](U32 lod)
+ {
+ LLVector3 out(outside_x, outside_y, outside_z);
+ LLVector3 in(inside_x, inside_y, inside_z);
+ if (fabs(inside_z - outside_z) < LINE_WIDTH / 5)
+ {
+ edge.pushVertex(lod, inside_x, inside_y, inside_z, water_z);
+ }
+ else
+ {
+ // Make the line thinner if heights differ too much
+ LLVector3 dist(in - out);
+ F32 coef = dist.length() / LINE_WIDTH;
+ LLVector3 new_in(out + dist / coef);
+ edge.pushVertex(lod, new_in[VX], new_in[VY], new_in[VZ], water_z);
+ }
+ edge.pushVertex(lod, outside_x, outside_y, outside_z, water_z);
+ };
- edge.vertices.emplace_back(inside_x, inside_y, inside_z);
- edge.vertices.emplace_back(outside_x, outside_y, outside_z);
+ // Point A simplified (first two vertices)
+ pushTwoVertices(1);
- inside_x += dx * (dx - LINE_WIDTH);
- inside_y += dy * (dy - LINE_WIDTH);
+ // Point A detailized (only one vertex)
+ edge.pushVertex(0, outside_x, outside_y, outside_z, water_z);
- outside_x += dx * (dx - LINE_WIDTH);
- outside_y += dy * (dy - LINE_WIDTH);
+ // Point B (two vertices)
+ move(LINE_WIDTH);
+ pushTwoVertices(0);
- // Middle part, full width
+ // Points C, D, E
+ F32 distance = 1.f - LINE_WIDTH;
constexpr S32 GRID_STEP = (S32)PARCEL_GRID_STEP_METERS;
- for (S32 i = 1; i < GRID_STEP; i++)
+ for (U32 i = 1; i < GRID_STEP; ++i)
{
- inside_z = land.resolveHeightRegion( inside_x, inside_y );
- outside_z = land.resolveHeightRegion( outside_x, outside_y );
-
- checkForSplit();
-
- edge.vertices.emplace_back(inside_x, inside_y, inside_z);
- edge.vertices.emplace_back(outside_x, outside_y, outside_z);
-
- inside_x += dx;
- inside_y += dy;
-
- outside_x += dx;
- outside_y += dy;
+ move(distance);
+ checkForSplit(0);
+ pushTwoVertices(0);
+ distance = 1.f;
}
- // Extra buffer for edge
- inside_x -= dx * LINE_WIDTH;
- inside_y -= dy * LINE_WIDTH;
-
- outside_x -= dx * LINE_WIDTH;
- outside_y -= dy * LINE_WIDTH;
-
- inside_z = land.resolveHeightRegion( inside_x, inside_y );
- outside_z = land.resolveHeightRegion( outside_x, outside_y );
-
- checkForSplit();
+ // Point F (two vertices)
+ move(1.f - LINE_WIDTH);
+ checkForSplit(0);
+ pushTwoVertices(0);
- edge.vertices.emplace_back(inside_x, inside_y, inside_z);
- edge.vertices.emplace_back(outside_x, outside_y, outside_z);
+ // Point G simplified (last two vertices)
+ move(LINE_WIDTH);
+ pushTwoVertices(1);
- outside_x += dx * LINE_WIDTH;
- outside_y += dy * LINE_WIDTH;
+ // Point G detailized (only one vertex)
+ edge.pushVertex(0, outside_x, outside_y, outside_z, water_z);
+}
- // Last edge is not drawn to the edge
- outside_z = land.resolveHeightRegion( outside_x, outside_y );
+void LLViewerParcelOverlay::Edge::pushVertex(U32 lod, F32 x, F32 y, F32 z, F32 water_z)
+{
+ verticesUnderWater[lod].emplace_back(x, y, z);
+ gGL.transform(verticesUnderWater[lod].back());
- edge.vertices.emplace_back(outside_x, outside_y, outside_z);
+ if (z >= water_z)
+ {
+ verticesAboveWater[lod].push_back(verticesUnderWater[lod].back());
+ }
+ else
+ {
+ verticesAboveWater[lod].emplace_back(x, y, water_z);
+ gGL.transform(verticesAboveWater[lod].back());
+ }
}
void LLViewerParcelOverlay::setDirty()
@@ -665,6 +687,9 @@ void LLViewerParcelOverlay::renderPropertyLines()
if (!show)
return;
+ LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_GPU_ZONE("Property Lines");
+
LLSurface& land = mRegion->getLand();
bool render_water = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER);
@@ -702,6 +727,8 @@ void LLViewerParcelOverlay::renderPropertyLines()
// Stomp the camera into two dimensions
LLVector3 camera_region = mRegion->getPosRegionFromGlobal( gAgentCamera.getCameraPositionGlobal() );
+ bool draw_underwater = camera_region.mV[VZ] < water_z ||
+ !gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER);
// Set up a cull plane 2 * PARCEL_GRID_STEP_METERS behind
// the camera. The cull plane normal is the camera's at axis.
@@ -709,15 +736,23 @@ void LLViewerParcelOverlay::renderPropertyLines()
cull_plane_point *= -2.f * PARCEL_GRID_STEP_METERS;
cull_plane_point += camera_region;
- bool render_hidden = LLSelectMgr::sRenderHiddenSelections && LLFloaterReg::instanceVisible("build");
+ bool render_hidden = !draw_underwater &&
+ LLSelectMgr::sRenderHiddenSelections &&
+ LLFloaterReg::instanceVisible("build");
constexpr F32 PROPERTY_LINE_CLIP_DIST_SQUARED = 256.f * 256.f;
+ const F32 PROPERTY_LINE_LOD0_DIST_SQUARED = PROPERTY_LINE_CLIP_DIST_SQUARED / 25;
for (const Edge& edge : mEdges)
{
- LLVector3 center = edge.vertices[edge.vertices.size() >> 1];
+ const std::vector<LLVector4a>& vertices0 = edge.verticesAboveWater[0];
+ const F32* first = vertices0.front().getF32ptr();
+ const F32* last = vertices0.back().getF32ptr();
+ LLVector3 center((first[VX] + last[VX]) / 2, (first[VY] + last[VY]) / 2, (first[VZ] + last[VZ]) / 2);
+ gGL.untransform(center);
- if (dist_vec_squared2D(center, camera_region) > PROPERTY_LINE_CLIP_DIST_SQUARED)
+ F32 dist_squared = dist_vec_squared(center, camera_region);
+ if (dist_squared > PROPERTY_LINE_CLIP_DIST_SQUARED)
{
continue;
}
@@ -731,43 +766,33 @@ void LLViewerParcelOverlay::renderPropertyLines()
continue;
}
+ U32 lod = dist_squared < PROPERTY_LINE_LOD0_DIST_SQUARED ? 0 : 1;
+
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.color4ubv(edge.color.mV);
- for (const LLVector3& vertex : edge.vertices)
+ if (draw_underwater)
{
- if (render_hidden || camera_z < water_z || vertex.mV[2] >= water_z)
- {
- gGL.vertex3fv(vertex.mV);
- }
- else
- {
- LLVector3 visible = vertex;
- visible.mV[VZ] = water_z;
- gGL.vertex3fv(visible.mV);
- }
+ gGL.vertexBatchPreTransformed(edge.verticesUnderWater[lod]);
}
-
- gGL.end();
-
- if (render_hidden)
+ else
{
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
+ gGL.vertexBatchPreTransformed(edge.verticesAboveWater[lod]);
- gGL.begin(LLRender::TRIANGLE_STRIP);
+ if (render_hidden)
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
- LLColor4U color = edge.color;
- color.mV[VALPHA] /= 4;
- gGL.color4ubv(color.mV);
+ LLColor4U color = edge.color;
+ color.mV[VALPHA] /= 4;
+ gGL.color4ubv(color.mV);
- for (const LLVector3& vertex : edge.vertices)
- {
- gGL.vertex3fv(vertex.mV);
+ gGL.vertexBatchPreTransformed(edge.verticesUnderWater[lod]);
}
-
- gGL.end();
}
+
+ gGL.end();
}
gGL.popMatrix();
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index 50bef02ddf..7271c85701 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -116,7 +116,10 @@ private:
struct Edge
{
- std::vector<LLVector3> vertices;
+ void pushVertex(U32 lod, F32 x, F32 y, F32 z, F32 water_z);
+ // LOD: 0 - detailized, 1 - simplified
+ std::vector<LLVector4a> verticesAboveWater[2];
+ std::vector<LLVector4a> verticesUnderWater[2];
LLColor4U color;
};
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index f6ee00cb25..d33d426769 100644
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -126,8 +126,6 @@
#include "llfloater.h"
#include <boost/signals2.hpp>
-#include <boost/unordered_set.hpp>
-#include <boost/unordered_map.hpp>
#include <boost/json.hpp>
#include "glm/glm.hpp"
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index cd70f8f9b9..f31befd1ab 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -104,7 +104,7 @@ S32 LLViewerRegion::sLastCameraUpdated = 0;
S32 LLViewerRegion::sNewObjectCreationThrottle = -1;
LLViewerRegion::vocache_entry_map_t LLViewerRegion::sRegionCacheCleanup;
-typedef std::map<std::string, std::string> CapabilityMap;
+typedef std::unordered_map<std::string, std::string, ll::string_hash, std::equal_to<>> CapabilityMap;
static void log_capabilities(const CapabilityMap &capmap);
@@ -3300,6 +3300,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("SetDisplayName");
capabilityNames.append("SimConsoleAsync");
capabilityNames.append("SimulatorFeatures");
+ capabilityNames.append("SpatialVoiceModerationRequest");
capabilityNames.append("StartGroupProposal");
capabilityNames.append("TerrainNavMeshProperties");
capabilityNames.append("TextureStats");
@@ -3437,7 +3438,7 @@ void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::stri
}
}
-std::string LLViewerRegion::getCapabilityDebug(const std::string& name) const
+std::string LLViewerRegion::getCapabilityDebug(std::string_view name) const
{
CapabilityMap::const_iterator iter = mImpl->mSecondCapabilitiesTracker.find(name);
if (iter == mImpl->mSecondCapabilitiesTracker.end())
@@ -3448,15 +3449,14 @@ std::string LLViewerRegion::getCapabilityDebug(const std::string& name) const
return iter->second;
}
-
-bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
+bool LLViewerRegion::isSpecialCapabilityName(std::string_view name)
{
return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
}
-std::string LLViewerRegion::getCapability(const std::string& name) const
+std::string LLViewerRegion::getCapability(std::string_view name) const
{
- if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia")))
+ if (!capabilitiesReceived() && (name != "Seed") && (name != "ObjectMedia"))
{
LL_WARNS() << "getCapability called before caps received for " << name << LL_ENDL;
}
@@ -3464,21 +3464,20 @@ std::string LLViewerRegion::getCapability(const std::string& name) const
CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
if(iter == mImpl->mCapabilities.end())
{
- return "";
+ return {};
}
return iter->second;
}
-bool LLViewerRegion::isCapabilityAvailable(const std::string& name) const
+bool LLViewerRegion::isCapabilityAvailable(std::string_view name) const
{
- if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia")))
+ if (!capabilitiesReceived() && (name != "Seed") && (name != "ObjectMedia"))
{
LL_WARNS() << "isCapabilityAvailable called before caps received for " << name << LL_ENDL;
}
- CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
- if(iter == mImpl->mCapabilities.end())
+ if (!mImpl->mCapabilities.contains(name))
{
return false;
}
@@ -3734,9 +3733,14 @@ bool LLViewerRegion::avatarHoverHeightEnabled() const
void log_capabilities(const CapabilityMap &capmap)
{
+ // Copy into sorted map for ordered output
+ using SortedCapabilityMap = std::map<std::string, std::string>;
+ SortedCapabilityMap sorted_capmap;
+ sorted_capmap.insert(capmap.begin(), capmap.end());
+
S32 count = 0;
- CapabilityMap::const_iterator iter;
- for (iter = capmap.begin(); iter != capmap.end(); ++iter, ++count)
+ SortedCapabilityMap::const_iterator iter;
+ for (iter = sorted_capmap.begin(); iter != sorted_capmap.end(); ++iter, ++count)
{
if (!iter->second.empty())
{
@@ -3797,6 +3801,16 @@ std::string LLViewerRegion::getSimHostName()
return std::string("...");
}
+
+bool LLViewerRegion::isRegionWebRTCEnabled()
+{
+ if (mSimulatorFeaturesReceived && mSimulatorFeatures.has("VoiceServerType"))
+ {
+ return mSimulatorFeatures["VoiceServerType"].asString() == "webrtc";
+ }
+ return false;
+}
+
void LLViewerRegion::applyCacheMiscExtras(LLViewerObject* obj)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 9c5a63e23a..a086d45ec1 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -275,10 +275,10 @@ public:
S32 getNumSeedCapRetries();
void setCapability(const std::string& name, const std::string& url);
void setCapabilityDebug(const std::string& name, const std::string& url);
- bool isCapabilityAvailable(const std::string& name) const;
+ bool isCapabilityAvailable(std::string_view name) const;
// implements LLCapabilityProvider
- virtual std::string getCapability(const std::string& name) const;
- std::string getCapabilityDebug(const std::string& name) const;
+ virtual std::string getCapability(std::string_view name) const;
+ std::string getCapabilityDebug(std::string_view name) const;
// has region received its final (not seed) capability list?
@@ -288,7 +288,7 @@ public:
void setCapabilitiesError();
boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb);
- static bool isSpecialCapabilityName(const std::string &name);
+ static bool isSpecialCapabilityName(std::string_view name);
void logActiveCapabilities() const;
// Utilities to post and get via
@@ -425,6 +425,8 @@ public:
std::string getSimHostName();
+ bool isRegionWebRTCEnabled();
+
static bool isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;}
// rebuild reflection probe list
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 59bb78f8f4..5e210312a9 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -263,6 +263,20 @@ LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > HUDS_FRAME_PCT("huds_
LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > UI_FRAME_PCT("ui_frame_pct");
LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > SWAP_FRAME_PCT("swap_frame_pct");
LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > IDLE_FRAME_PCT("idle_frame_pct");
+
+
+
+LLTrace::SampleStatHandle<U32> WEBRTC_PACKETS_IN_LOST("webrtc_packets_in_lost", "Lost incoming packets"),
+ WEBRTC_PACKETS_IN_RECEIVED("webrtc_packets_in_recv", "Incoming packets received"),
+ WEBRTC_PACKETS_OUT_SENT("webrtc_packets_out_sent", "Outgoing packets sent"),
+ WEBRTC_PACKETS_OUT_LOST("webrtc_packets_out_lost", "Lost outgoing packets");
+
+LLTrace::SampleStatHandle<F32> WEBRTC_JITTER_OUT("webrtc_jitter_out", "Timing variation of outgoing audio"),
+ WEBRTC_JITTER_IN("webrtc_jitter_in", "Timing variation of incoming audio"),
+ WEBRTC_LATENCY("webrtc_latency", "Round-trip audio delay"),
+ WEBRTC_UPLOAD_BANDWIDTH("webrtc_upload_bandwidth", "Estimated upload bandwidth"),
+ WEBRTC_JITTER_BUFFER("webrtc_jitter_buffer", "Average delay added to smooth incoming audio");
+
}
LLViewerStats::LLViewerStats()
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 1ac8b2f66b..8ec0dd0024 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -232,6 +232,9 @@ extern LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT
extern LLTrace::SampleStatHandle<F64> NOTRMALIZED_FRAMETIME_JITTER_SESSION;
extern LLTrace::SampleStatHandle<F64> NORMALIZED_FRAMTIME_JITTER_PERIOD;
+extern LLTrace::SampleStatHandle<U32> WEBRTC_PACKETS_IN_LOST, WEBRTC_PACKETS_IN_RECEIVED, WEBRTC_PACKETS_OUT_SENT, WEBRTC_PACKETS_OUT_LOST;
+extern LLTrace::SampleStatHandle<F32> WEBRTC_JITTER_OUT, WEBRTC_JITTER_IN, WEBRTC_LATENCY, WEBRTC_UPLOAD_BANDWIDTH, WEBRTC_JITTER_BUFFER;
+
}
class LLViewerStats : public LLSingleton<LLViewerStats>
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index c7513ded62..05b71b65b2 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1488,7 +1488,9 @@ bool LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/)
// from local images, but this might become unsafe in case of changes to fetcher
if (mBoostLevel == BOOST_PREVIEW)
{
- mRawImage->biasedScaleToPowerOfTwo(1024);
+ // A local file with a preview flag likely means mesh's texture upload
+ // which should follow normal upload scaling rules
+ mRawImage->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
}
else
{ // leave black border, do not scale image content
@@ -1896,12 +1898,10 @@ bool LLViewerFetchedTexture::processFetchResults(S32& desired_discard, S32 curre
mRawDiscardLevel = INVALID_DISCARD_LEVEL;
mIsFetching = false;
mLastPacketTimer.reset();
+ return false;
}
- else
- {
- mIsRawImageValid = true;
- addToCreateTexture();
- }
+
+ mIsRawImageValid = true;
if (mBoostLevel == LLGLTexture::BOOST_ICON)
{
@@ -1914,7 +1914,11 @@ bool LLViewerFetchedTexture::processFetchResults(S32& desired_discard, S32 curre
//
// BOOST_ICON gets scaling because profile icons can have a bunch of different formats, not just j2c
// Might need another pass to use discard for j2c and scaling for everything else.
- mRawImage = mRawImage->scaled(expected_width, expected_height);
+ LLPointer<LLImageRaw> scaled = mRawImage->scaled(expected_width, expected_height);
+ if (scaled.notNull())
+ {
+ mRawImage = scaled;
+ }
}
}
@@ -1929,10 +1933,16 @@ bool LLViewerFetchedTexture::processFetchResults(S32& desired_discard, S32 curre
//
// Todo: probably needs to be remade to use discard, all thumbnails are supposed to be j2c,
// so no need to scale, should be posible to use discard to scale image down.
- mRawImage = mRawImage->scaled(expected_width, expected_height);
+ LLPointer<LLImageRaw> scaled = mRawImage->scaled(expected_width, expected_height);
+ if (scaled.notNull())
+ {
+ mRawImage = scaled;
+ }
}
}
+ addToCreateTexture();
+
return true;
}
else
@@ -2574,14 +2584,31 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
S32 best_raw_discard = gl_discard; // Current GL quality level
S32 current_aux_discard = MAX_DISCARD_LEVEL + 1;
S32 best_aux_discard = MAX_DISCARD_LEVEL + 1;
+ LLImageRaw *current_raw_image = nullptr;
if (mIsRawImageValid)
{
- // If we have an existing raw image, we have a baseline for the raw and auxiliary quality levels.
+ // If we have an existing raw image, we have a baseline for the raw
+ // and auxiliary quality levels.
+ // Note: we call updateImagesCreateTextures before callbacks, which
+ // leads to destroyRawImage and deletes raw image. So this case
+ // might be rare or even never trigger as there is never a raw image,
+ // only a saved one.
current_raw_discard = mRawDiscardLevel;
best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel);
best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel); // We always decode the aux when we decode the base raw
current_aux_discard = llmin(current_aux_discard, best_aux_discard);
+ current_raw_image = mRawImage;
+ }
+ else if (mSavedRawImage.notNull())
+ {
+ // We have a saved raw image, we can use that as our baseline for
+ // raw and auxiliary quality levels.
+ current_raw_discard = mSavedRawDiscardLevel;
+ best_raw_discard = llmin(best_raw_discard, mSavedRawDiscardLevel);
+ best_aux_discard = llmin(best_aux_discard, mSavedRawDiscardLevel); // We always decode the aux when we decode the base raw
+ current_aux_discard = llmin(current_aux_discard, best_aux_discard);
+ current_raw_image = mSavedRawImage;
}
else
{
@@ -2646,12 +2673,17 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
if (need_readback)
{
readbackRawImage();
+ if (mIsRawImageValid)
+ {
+ current_raw_discard = mRawDiscardLevel;
+ current_raw_image = mRawImage;
+ }
}
//
// Run raw/auxiliary data callbacks
//
- if (run_raw_callbacks && mIsRawImageValid && (mRawDiscardLevel <= getMaxDiscardLevel()))
+ if (run_raw_callbacks && current_raw_image != nullptr && (current_raw_discard <= getMaxDiscardLevel()))
{
// Do callbacks which require raw image data.
//LL_INFOS() << "doLoadedCallbacks raw for " << getID() << LL_ENDL;
@@ -2662,7 +2694,7 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
{
callback_list_t::iterator curiter = iter++;
LLLoadedCallbackEntry *entryp = *curiter;
- if (entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > mRawDiscardLevel))
+ if (entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > current_raw_discard))
{
// If we've loaded all the data there is to load or we've loaded enough
// to satisfy the interested party, then this is the last time that
@@ -2673,11 +2705,11 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
{
LL_WARNS() << "Raw Image with no Aux Data for callback" << LL_ENDL;
}
- bool final = mRawDiscardLevel <= entryp->mDesiredDiscard;
+ bool final = current_raw_discard <= entryp->mDesiredDiscard;
//LL_INFOS() << "Running callback for " << getID() << LL_ENDL;
- //LL_INFOS() << mRawImage->getWidth() << "x" << mRawImage->getHeight() << LL_ENDL;
- entryp->mLastUsedDiscard = mRawDiscardLevel;
- entryp->mCallback(true, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData);
+ //LL_INFOS() << current_raw_image->getWidth() << "x" << current_raw_image->getHeight() << LL_ENDL;
+ entryp->mLastUsedDiscard = current_raw_discard;
+ entryp->mCallback(true, this, current_raw_image, mAuxRawImage, current_raw_discard, final, entryp->mUserData);
if (final)
{
iter = mLoadedCallbackList.erase(curiter);
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 6f62d13d51..d9516de89d 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1203,15 +1203,19 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
LLTimer timer;
image_list_t::iterator enditer = mFastCacheList.begin();
- for (image_list_t::iterator iter = mFastCacheList.begin();
- iter != mFastCacheList.end();)
{
- image_list_t::iterator curiter = iter++;
- enditer = iter;
- LLViewerFetchedTexture *imagep = *curiter;
- imagep->loadFromFastCache();
- if (timer.getElapsedTimeF32() > max_time)
- break;
+ // prelock fast cache mutex to avoid waiting multiple times.
+ LLMutexLock cache_lock(LLAppViewer::getTextureCache()->getFastCacheMutex());
+ for (image_list_t::iterator iter = mFastCacheList.begin();
+ iter != mFastCacheList.end();)
+ {
+ image_list_t::iterator curiter = iter++;
+ enditer = iter;
+ LLViewerFetchedTexture* imagep = *curiter;
+ imagep->loadFromFastCache();
+ if (timer.getElapsedTimeF32() > max_time)
+ break;
+ }
}
mFastCacheList.erase(mFastCacheList.begin(), enditer);
return timer.getElapsedTimeF32();
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
index 583fb25330..50af9756a3 100644
--- a/indra/newview/llviewerwearable.cpp
+++ b/indra/newview/llviewerwearable.cpp
@@ -96,6 +96,7 @@ LLViewerWearable::~LLViewerWearable()
// virtual
LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
// suppress texlayerset updates while wearables are being imported. Layersets will be updated
// when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.
LLOverrideBakedTextureUpdate stop_bakes(false);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 9788fc5f4d..f4227b1026 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -34,7 +34,6 @@
#include <fstream>
#include <algorithm>
#include <boost/filesystem.hpp>
-#include <boost/lambda/core.hpp>
#include <boost/regex.hpp>
#include "llagent.h"
@@ -1336,7 +1335,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
// Check the whitelist, if there's media (otherwise just show it)
if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url))
{
- if ( obj != mDragHoveredObject.get())
+ if (obj != mDragHoveredObject)
{
// Highlight the dragged object
LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
@@ -2078,10 +2077,6 @@ void LLViewerWindow::initGLDefaults()
gBox.prerender();
}
-struct MainPanel : public LLPanel
-{
-};
-
void LLViewerWindow::initBase()
{
S32 height = getWindowHeightScaled();
@@ -2120,6 +2115,8 @@ void LLViewerWindow::initBase()
main_view->setShape(full_window);
getRootView()->addChild(main_view);
+ mMainView = main_view;
+
// placeholder widget that controls where "world" is rendered
mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle();
mPopupView = main_view->getChild<LLPopupView>("popup_holder");
@@ -3332,7 +3329,7 @@ void LLViewerWindow::clearPopups()
void LLViewerWindow::moveCursorToCenter()
{
bool mouse_warp = false;
- LLCachedControl<S32> mouse_warp_mode(gSavedSettings, "MouseWarpMode", 1);
+ static LLCachedControl<S32> mouse_warp_mode(gSavedSettings, "MouseWarpMode", 1);
switch (mouse_warp_mode())
{
@@ -3405,13 +3402,11 @@ void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params)
}
}
-static LLTrace::BlockTimerStatHandle ftm("Update UI");
-
// Update UI based on stored mouse position from mouse-move
// event processing.
void LLViewerWindow::updateUI()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(ftm);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
static std::string last_handle_msg;
@@ -3429,12 +3424,15 @@ void LLViewerWindow::updateUI()
}
}
- LLConsole::updateClass();
+ {
+ LL_PROFILE_ZONE_NAMED("UI updateClass");
+ LLConsole::updateClass();
- // execute postponed arrange calls
- LLAccordionCtrl::updateClass();
- // animate layout stacks so we have up to date rect for world view
- LLLayoutStack::updateClass();
+ // execute postponed arrange calls
+ LLAccordionCtrl::updateClass();
+ // animate layout stacks so we have up to date rect for world view
+ LLLayoutStack::updateClass();
+ }
// use full window for world view when not rendering UI
bool world_view_uses_full_window = gAgentCamera.cameraMouselook() || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
@@ -3863,6 +3861,7 @@ void LLViewerWindow::updateUI()
void LLViewerWindow::updateLayout()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
if (gFloaterTools != NULL
&& tool != NULL
@@ -4342,15 +4341,15 @@ void LLViewerWindow::pickAsync( S32 x,
bool pick_unselectable,
bool pick_reflection_probes)
{
+ static LLCachedControl<bool> select_invisible_objects(gSavedSettings, "SelectInvisibleObjects");
// "Show Debug Alpha" means no object actually transparent
bool in_build_mode = LLFloaterReg::instanceVisible("build");
- if (LLDrawPoolAlpha::sShowDebugAlpha
- || (in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")))
+ if (LLDrawPoolAlpha::sShowDebugAlpha || (in_build_mode && select_invisible_objects))
{
pick_transparent = true;
}
- LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, false, pick_reflection_probes, pick_unselectable, true, callback);
+ LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, false, pick_reflection_probes, true, pick_unselectable, callback);
schedulePick(pick_info);
}
@@ -4374,7 +4373,6 @@ void LLViewerWindow::schedulePick(LLPickInfo& pick_info)
mWindow->delayInputProcessing();
}
-
void LLViewerWindow::performPick()
{
if (!mPicks.empty())
@@ -4408,8 +4406,9 @@ void LLViewerWindow::returnEmptyPicks()
// Performs the GL object/land pick.
LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, bool pick_transparent, bool pick_rigged, bool pick_particle, bool pick_unselectable, bool pick_reflection_probe)
{
+ static LLCachedControl<bool> select_invisible_objects(gSavedSettings, "SelectInvisibleObjects");
bool in_build_mode = LLFloaterReg::instanceVisible("build");
- if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha)
+ if ((in_build_mode && select_invisible_objects) || LLDrawPoolAlpha::sShowDebugAlpha)
{
// build mode allows interaction with all transparent objects
// "Show Debug Alpha" means no object actually transparent
@@ -4417,7 +4416,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, bool pick_transp
}
// shortcut queueing in mPicks and just update mLastPick in place
- MASK key_mask = gKeyboard->currentMask(true);
+ MASK key_mask = gKeyboard->currentMask(true);
mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, pick_reflection_probe, true, false, NULL);
mLastPick.fetchResults();
@@ -4929,6 +4928,19 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save
if (image->save(filepath))
{
playSnapshotAnimAndSound();
+
+ // Show clickable notification with filepath
+ LLSD args;
+ args["FILEPATH"] = filepath;
+
+ LLSD payload;
+ payload["filepath"] = filepath;
+
+ LLNotificationsUtil::add("SnapshotSavedToComputer",
+ args,
+ payload.with("respond_on_mousedown", true),
+ boost::bind(&LLViewerWindow::onSnapshotNotificationClick, _1, _2));
+
success_cb();
}
else
@@ -4943,6 +4955,16 @@ void LLViewerWindow::resetSnapshotLoc()
}
// static
+void LLViewerWindow::onSnapshotNotificationClick(const LLSD& notification, const LLSD& response)
+{
+ std::string filepath = notification["payload"]["filepath"].asString();
+ if (!filepath.empty())
+ {
+ gDirUtilp->openDir(filepath);
+ }
+}
+
+// static
void LLViewerWindow::movieSize(S32 new_width, S32 new_height)
{
LLCoordWindow size;
@@ -6164,14 +6186,14 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
bool pick_rigged,
bool pick_particle,
bool pick_reflection_probe,
- bool pick_uv_coords,
+ bool pick_surface_info,
bool pick_unselectable,
void (*pick_callback)(const LLPickInfo& pick_info))
: mMousePt(mouse_pos),
mKeyMask(keyboard_mask),
mPickCallback(pick_callback),
mPickType(PICK_INVALID),
- mWantSurfaceInfo(pick_uv_coords),
+ mWantSurfaceInfo(pick_surface_info),
mObjectFace(-1),
mUVCoords(-1.f, -1.f),
mSTCoords(-1.f, -1.f),
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index f3c7ef3289..ec28a3fc4a 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -144,6 +144,10 @@ private:
};
+struct MainPanel : public LLPanel
+{
+};
+
static const U32 MAX_SNAPSHOT_IMAGE_SIZE = 7680; // max snapshot image size 7680 * 7680 UHDTV2
class LLViewerWindow : public LLWindowCallbacks
@@ -248,6 +252,7 @@ public:
// ACCESSORS
//
LLRootView* getRootView() const;
+ MainPanel* getMainView() const { return mMainView; }
// 3D world area in scaled pixels (via UI scale), use for most UI computations
LLRect getWorldViewRectScaled() const;
@@ -405,6 +410,7 @@ public:
void resetSnapshotLoc();
void playSnapshotAnimAndSound();
+ static void onSnapshotNotificationClick(const LLSD& notification, const LLSD& response);
// draws selection boxes around selected objects, must call displayObjects first
void renderSelections( bool for_gl_pick, bool pick_parcel_walls, bool for_hud );
@@ -501,6 +507,7 @@ private:
LLRect mWorldViewRectRaw; // area of screen for 3D world
LLRect mWorldViewRectScaled; // area of screen for 3D world scaled by UI size
LLRootView* mRootView; // a view of size mWindowRectRaw, containing all child views
+ MainPanel* mMainView; // a view of size mWindowRectRaw, directly containing the base elements of the ui tree
LLView* mFloaterSnapRegion = nullptr;
LLView* mNavBarContainer = nullptr;
LLPanel* mStatusBarContainer = nullptr;
diff --git a/indra/newview/llvlmanager.cpp b/indra/newview/llvlmanager.cpp
index c2bcd32921..f4c2c27cee 100644
--- a/indra/newview/llvlmanager.cpp
+++ b/indra/newview/llvlmanager.cpp
@@ -68,7 +68,11 @@ void LLVLManager::addLayerData(LLVLData *vl_datap, const S32Bytes mesg_size)
}
else
{
- LL_ERRS() << "Unknown layer type!" << (S32)vl_datap->mType << LL_ENDL;
+ // Corrupted message? New feature?
+ LL_WARNS() << "Unknown layer type!" << (S32)vl_datap->mType
+ << " for region " << vl_datap->mRegionp->getName() << LL_ENDL;
+ delete vl_datap; // addLayerData took ownership
+ return;
}
mPacketData.push_back(vl_datap);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index e2cafffb51..384b45ca4c 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -218,6 +218,13 @@ enum ERenderName
RENDER_NAME_FADE
};
+enum ERenderGroupTitle
+{
+ RENDER_GROUP_TITLE_NEVER,
+ RENDER_GROUP_TITLE_SELF,
+ RENDER_GROUP_TITLE_ALWAYS
+};
+
#define JELLYDOLLS_SHOULD_IMPOSTOR
//-----------------------------------------------------------------------------
@@ -608,7 +615,7 @@ const LLUUID LLVOAvatar::sStepSounds[LL_MCODE_END] =
};
S32 LLVOAvatar::sRenderName = RENDER_NAME_ALWAYS;
-bool LLVOAvatar::sRenderGroupTitles = true;
+S32 LLVOAvatar::sRenderGroupTitles = RENDER_GROUP_TITLE_ALWAYS;
S32 LLVOAvatar::sNumVisibleChatBubbles = 0;
bool LLVOAvatar::sDebugInvisible = false;
bool LLVOAvatar::sShowAttachmentPoints = false;
@@ -3584,9 +3591,10 @@ void LLVOAvatar::idleUpdateNameTagText(bool new_name)
addNameTagLine(line, name_tag_color, LLFontGL::NORMAL,
LLFontGL::getFontSansSerifSmall());
}
+ bool render_title = (sRenderGroupTitles == RENDER_GROUP_TITLE_ALWAYS) ||
+ (isSelf() && (sRenderGroupTitles == RENDER_GROUP_TITLE_SELF));
- if (sRenderGroupTitles
- && title && title->getString() && title->getString()[0] != '\0')
+ if (render_title && title && title->getString() && title->getString()[0] != '\0')
{
std::string title_str = title->getString();
LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
@@ -11451,12 +11459,17 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
LLPerfStats::tunables.userFPSTuningStrategy != LLPerfStats::TUNE_SCENE_ONLY &&
!isVisuallyMuted())
{
- LLUUID id = getID(); // <== use id to make sure this avatar didn't get deleted between frames
- LL::WorkQueue::getInstance("mainloop")->post([this, id]()
+ const LLUUID id = getID(); // <== use id to make sure this avatar didn't get deleted between frames
+ LL::WorkQueue::getInstance("mainloop")->post([id]()
{
- if (gObjectList.findObject(id) != nullptr)
+ LLViewerObject* obj = gObjectList.findObject(id);
+ if (obj
+ && !obj->isDead()
+ && obj->isAvatar()
+ && obj->mDrawable)
{
- gPipeline.profileAvatar(this);
+ LLVOAvatar* avatar = (LLVOAvatar*)obj;
+ gPipeline.profileAvatar(avatar);
}
});
}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 1e563c4869..fc3a97a25d 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -354,7 +354,7 @@ public:
//--------------------------------------------------------------------
public:
static S32 sRenderName;
- static bool sRenderGroupTitles;
+ static S32 sRenderGroupTitles;
static const U32 NON_IMPOSTORS_MAX_SLIDER; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors
* slider in panel_preferences_graphics1.xml */
static U32 sMaxNonImpostors; // affected by control "RenderAvatarMaxNonImpostors"
@@ -1120,7 +1120,7 @@ private:
bool mNameFriend;
bool mNameCloud;
F32 mNameAlpha;
- bool mRenderGroupTitles;
+ S32 mRenderGroupTitles;
//--------------------------------------------------------------------
// Display the name (then optionally fade it out)
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 59e8db7752..91d5451bff 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -41,6 +41,7 @@
#include "llagent.h"
#include "lltrans.h"
#include "lluiusage.h"
+#include "llnearbyvoicemoderation.h"
const F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f;
@@ -792,6 +793,13 @@ bool LLVoiceClient::getPTTIsToggle()
void LLVoiceClient::inputUserControlState(bool down)
{
+ if (down && !getUserPTTState())
+ {
+ // Nearby chat is muted by moderator, don't toggle PTT
+ if (LLNearbyVoiceModeration::getInstance()->showNotificationIfNeeded())
+ return;
+ }
+
if(mPTTIsToggle)
{
if(down) // toggle open-mic state on 'down'
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index e08bc2dfc4..f32bdfb75c 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -1116,7 +1116,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
while (!sPump && !sShuttingDown)
{ // Can't use the pump until we have it available.
- llcoro::suspend();
+ llcoro::suspendUntilNextFrame();
}
if (sShuttingDown)
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 06ccd23670..7caac0a267 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -61,10 +61,12 @@
#include "llrand.h"
#include "llviewerwindow.h"
#include "llviewercamera.h"
+#include "llviewerstats.h"
#include "llversioninfo.h"
#include "llviewernetwork.h"
#include "llnotificationsutil.h"
+#include "llnearbyvoicemoderation.h"
#include "llcorehttputil.h"
#include "lleventfilter.h"
@@ -80,6 +82,8 @@
const std::string WEBRTC_VOICE_SERVER_TYPE = "webrtc";
+const F32 STATS_TIMER_DELAY = 2.0;
+
namespace {
const F32 MAX_AUDIO_DIST = 50.0f;
@@ -2496,17 +2500,18 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection)
// callback from llwebrtc
void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)
{
+ connectionPtr_t connection = shared_from_this();
LL::WorkQueue::postMaybe(mMainQueue,
- [=, this] {
- if (mShutDown)
+ [=] {
+ if (connection->mShutDown)
{
return;
}
LL_DEBUGS("Voice") << "On Offer Available." << LL_ENDL;
- mChannelSDP = sdp;
- if (mVoiceConnectionState == VOICE_STATE_WAIT_FOR_SESSION_START)
+ connection->mChannelSDP = sdp;
+ if (connection->mVoiceConnectionState == VOICE_STATE_WAIT_FOR_SESSION_START)
{
- mVoiceConnectionState = VOICE_STATE_REQUEST_CONNECTION;
+ connection->mVoiceConnectionState = VOICE_STATE_REQUEST_CONNECTION;
}
});
}
@@ -2523,16 +2528,17 @@ void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)
// callback from llwebrtc
void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface* audio_interface)
{
+ connectionPtr_t connection = shared_from_this();
LL::WorkQueue::postMaybe(mMainQueue,
- [=, this] {
- if (mShutDown)
+ [=] {
+ if (connection->mShutDown)
{
return;
}
LL_DEBUGS("Voice") << "On AudioEstablished." << LL_ENDL;
- mWebRTCAudioInterface = audio_interface;
- mWebRTCAudioInterface->setMute(true); // mute will be set appropriately later when we finish setting up.
- setVoiceConnectionState(VOICE_STATE_SESSION_ESTABLISHED);
+ connection->mWebRTCAudioInterface = audio_interface;
+ connection->mWebRTCAudioInterface->setMute(true); // mute will be set appropriately later when we finish setting up.
+ connection->setVoiceConnectionState(VOICE_STATE_SESSION_ESTABLISHED);
});
}
@@ -2902,6 +2908,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
}
mWebRTCAudioInterface->setReceiveVolume(mSpeakerVolume);
LLWebRTCVoiceClient::getInstance()->OnConnectionEstablished(mChannelID, mRegionID);
+ resetConnectionStats();
setVoiceConnectionState(VOICE_STATE_WAIT_FOR_DATA_CHANNEL);
break;
}
@@ -2955,6 +2962,13 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
sendJoin();
}
}
+
+ static LLTimer stats_timer;
+ if (stats_timer.getElapsedTimeF32() > STATS_TIMER_DELAY)
+ {
+ mWebRTCPeerConnectionInterface->gatherConnectionStats();
+ stats_timer.reset();
+ }
}
break;
}
@@ -3171,12 +3185,54 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
if (participant_obj.contains("m") && participant_obj["m"].is_bool())
{
- participant->mIsModeratorMuted = participant_obj["m"].as_bool();
+ bool is_moderator_muted = participant_obj["m"].as_bool();
+ if (isSpatial())
+ {
+ // ignore muted flags from non-primary server
+ if (mPrimary || primary)
+ {
+ participant->mIsModeratorMuted = is_moderator_muted;
+ if (gAgentID == agent_id)
+ {
+ LLNearbyVoiceModeration::getInstance()->setMutedInfo(mChannelID, is_moderator_muted);
+ }
+ }
+ }
+ else
+ {
+ participant->mIsModeratorMuted = is_moderator_muted;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (isSpatial() && (mPrimary || primary))
+ {
+ // mute info message can be received before join message, so try to mute again later
+ if (participant_obj.contains("m") && participant_obj["m"].is_bool())
+ {
+ bool is_moderator_muted = participant_obj["m"].as_bool();
+ std::string channel_id = mChannelID;
+ F32 delay { 1.5f };
+ doAfterInterval(
+ [channel_id, agent_id, is_moderator_muted]()
+ {
+ LLWebRTCVoiceClient::participantStatePtr_t participant =
+ LLWebRTCVoiceClient::getInstance()->findParticipantByID(channel_id, agent_id);
+ if (participant)
+ {
+ participant->mIsModeratorMuted = is_moderator_muted;
+ if (gAgentID == agent_id)
+ {
+ LLNearbyVoiceModeration::getInstance()->setMutedInfo(channel_id, is_moderator_muted);
+ }
+ }
+ }, delay);
}
}
}
}
-
// tell the simulator to set the mute and volume data for this
// participant, if there are any updates.
boost::json::object root;
@@ -3207,17 +3263,18 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
// llwebrtc callback
void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface)
{
+ connectionPtr_t connection = shared_from_this();
LL::WorkQueue::postMaybe(mMainQueue,
- [=, this] {
- if (mShutDown)
+ [=] {
+ if (connection->mShutDown)
{
return;
}
if (data_interface)
{
- mWebRTCDataInterface = data_interface;
- mWebRTCDataInterface->setDataObserver(this);
+ connection->mWebRTCDataInterface = data_interface;
+ connection->mWebRTCDataInterface->setDataObserver(connection.get());
}
});
}
@@ -3247,6 +3304,112 @@ void LLVoiceWebRTCConnection::sendJoin()
mWebRTCDataInterface->sendData(json_data, false);
}
+void LLVoiceWebRTCConnection::OnStatsDelivered(const llwebrtc::LLWebRTCStatsMap& stats_data)
+{
+ LL::WorkQueue::postMaybe(mMainQueue, [=, this]
+ {
+ if (mShutDown)
+ {
+ return;
+ }
+ for (const auto& [stats_id, attributes] : stats_data)
+ {
+ if (attributes.contains("currentRoundTripTime"))
+ {
+ F32 rtt_seconds = 0.0f;
+ LLStringUtil::convertToF32(attributes.at("currentRoundTripTime"), rtt_seconds);
+ sample(LLStatViewer::WEBRTC_LATENCY, rtt_seconds * 1000.0f);
+ }
+ if (attributes.contains("availableOutgoingBitrate"))
+ {
+ F32 bitrate_bps = 0.0f;
+ LLStringUtil::convertToF32(attributes.at("availableOutgoingBitrate"), bitrate_bps);
+ sample(LLStatViewer::WEBRTC_UPLOAD_BANDWIDTH, bitrate_bps / 1000.0f);
+ }
+
+ // Stat type detection below is heuristic-based.
+ // It's relied on specific fields to distinguish outbound-rtp, remote-inbound-rtp, and inbound-rtp.
+ // This approach works with current WebRTC stats but may need updating later.
+
+ // Outbound RTP
+ if (attributes.contains("mediaSourceId"))
+ {
+ U32 out_packets_sent = 0;
+ LLStringUtil::convertToU32(attributes.at("packetsSent"), out_packets_sent);
+ sample(LLStatViewer::WEBRTC_PACKETS_OUT_SENT, out_packets_sent);
+ }
+ // Remote-Inbound RTP
+ else if (attributes.contains("localId"))
+ {
+ if (attributes.contains("packetsLost"))
+ {
+ U32 out_packets_lost = 0;
+ LLStringUtil::convertToU32(attributes.at("packetsLost"), out_packets_lost);
+ sample(LLStatViewer::WEBRTC_PACKETS_OUT_LOST, out_packets_lost);
+ }
+ if (attributes.contains("jitter"))
+ {
+ F32 jitter_seconds = 0.0f;
+ LLStringUtil::convertToF32(attributes.at("jitter"), jitter_seconds);
+ sample(LLStatViewer::WEBRTC_JITTER_OUT, jitter_seconds * 1000.0f);
+ }
+ }
+ // Inbound RTP
+ else if (attributes.contains("jitterBufferDelay"))
+ {
+ if (attributes.contains("packetsLost"))
+ {
+ U32 in_packets_lost = 0;
+ LLStringUtil::convertToU32(attributes.at("packetsLost"), in_packets_lost);
+ sample(LLStatViewer::WEBRTC_PACKETS_IN_LOST, in_packets_lost);
+ }
+ if (attributes.contains("packetsReceived"))
+ {
+ U32 in_packets_recv = 0;
+ LLStringUtil::convertToU32(attributes.at("packetsReceived"), in_packets_recv);
+ sample(LLStatViewer::WEBRTC_PACKETS_IN_RECEIVED, in_packets_recv);
+ }
+ if (attributes.contains("jitter"))
+ {
+ F32 jitter_seconds = 0.0f;
+ LLStringUtil::convertToF32(attributes.at("jitter"), jitter_seconds);
+ sample(LLStatViewer::WEBRTC_JITTER_IN, jitter_seconds * 1000.0f);
+ }
+ if (attributes.contains("jitterBufferDelay") && attributes.contains("jitterBufferEmittedCount"))
+ {
+ F32 total_delay_seconds = 0.0f;
+ F32 emitted_count_f = 0.0f;
+
+ // total delay in seconds
+ LLStringUtil::convertToF32(attributes.at("jitterBufferDelay"), total_delay_seconds);
+
+ // number of packets played out
+ LLStringUtil::convertToF32(attributes.at("jitterBufferEmittedCount"), emitted_count_f);
+ if (emitted_count_f > 0.0f)
+ {
+ F32 avg_delay_seconds = total_delay_seconds / emitted_count_f;
+ F32 avg_delay_ms = avg_delay_seconds * 1000.0f;
+ sample(LLStatViewer::WEBRTC_JITTER_BUFFER, avg_delay_seconds * 1000.0f);
+ }
+ }
+ }
+ }
+ });
+}
+
+void LLVoiceWebRTCConnection::resetConnectionStats()
+{
+ sample(LLStatViewer::WEBRTC_JITTER_BUFFER, 0);
+ sample(LLStatViewer::WEBRTC_JITTER_IN, 0);
+ sample(LLStatViewer::WEBRTC_JITTER_OUT, 0);
+ sample(LLStatViewer::WEBRTC_LATENCY, 0);
+ sample(LLStatViewer::WEBRTC_PACKETS_IN_LOST, 0);
+ sample(LLStatViewer::WEBRTC_PACKETS_IN_RECEIVED, 0);
+ sample(LLStatViewer::WEBRTC_PACKETS_OUT_SENT, 0);
+ sample(LLStatViewer::WEBRTC_PACKETS_OUT_LOST, 0);
+ sample(LLStatViewer::WEBRTC_UPLOAD_BANDWIDTH, 0);
+}
+
/////////////////////////////
// WebRTC Spatial Connection
diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h
index 0c658803db..033990f789 100644
--- a/indra/newview/llvoicewebrtc.h
+++ b/indra/newview/llvoicewebrtc.h
@@ -540,6 +540,8 @@ private:
static bool sShuttingDown;
LLEventMailDrop mWebRTCPump;
+
+ LLSD mLastWebRTCStats;
};
@@ -603,6 +605,8 @@ class LLVoiceWebRTCConnection :
//@{
void OnDataReceived(const std::string &data, bool binary) override;
void OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface) override;
+
+ void OnStatsDelivered(const llwebrtc::LLWebRTCStatsMap& stats_data) override;
//@}
void OnDataReceivedImpl(const std::string &data, bool binary);
@@ -638,6 +642,8 @@ class LLVoiceWebRTCConnection :
void OnVoiceConnectionRequestSuccess(const LLSD &body);
+ void resetConnectionStats();
+
protected:
typedef enum e_voice_connection_state
{
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 4c316fce07..d1feb7e875 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -250,10 +250,12 @@ LLVOVolume::~LLVOVolume()
delete mVolumeImpl;
mVolumeImpl = NULL;
- gMeshRepo.unregisterMesh(this);
+ unregisterOldMeshAndSkin();
if(!mMediaImplList.empty())
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("delete volume media list");
+
for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
{
if(mMediaImplList[i].notNull())
@@ -351,7 +353,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
U8 sculpt_type = 0;
if (isSculpted())
{
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = getSculptParams();
if (sculpt_params)
{
sculpt_id = sculpt_params->getSculptTexture();
@@ -924,7 +926,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
if (getLightTextureID().notNull())
{
- LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ LLLightImageParams* params = getLightImageParams();
LLUUID id = params->getLightTexture();
mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE);
if (mLightTexture.notNull())
@@ -1048,6 +1050,28 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
+// Inverse of gMeshRepo.loadMesh and gMeshRepo.getSkinInfo, combined into one function
+// Assume a Collada mesh never changes after being set.
+void LLVOVolume::unregisterOldMeshAndSkin()
+{
+ if (mVolumep)
+ {
+ const LLVolumeParams& params = mVolumep->getParams();
+ if ((params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ {
+ // object is being deleted, so it will no longer need to request
+ // meshes.
+ for (S32 lod = 0; lod != LLVolumeLODGroup::NUM_LODS; ++lod)
+ {
+ gMeshRepo.unregisterMesh(this, params, lod);
+ }
+ // This volume may or may not have a skin
+ gMeshRepo.unregisterSkinInfo(params.getSculptID(), this);
+ }
+ }
+}
+
+
bool LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bool unique_volume)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
@@ -1082,7 +1106,7 @@ bool LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, true, false);
if (!mVolumeImpl)
{
- LLFlexibleObjectData* data = (LLFlexibleObjectData*)getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ LLFlexibleObjectData* data = getFlexibleObjectData();
mVolumeImpl = new LLVolumeImplFlexible(this, data);
}
}
@@ -1193,7 +1217,7 @@ void LLVOVolume::updateSculptTexture()
if (isSculpted() && !isMesh())
{
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = getSculptParams();
if (sculpt_params)
{
LLUUID id = sculpt_params->getSculptTexture();
@@ -3053,7 +3077,7 @@ void LLVOVolume::setLightTextureID(LLUUID id)
{
old_texturep->removeVolume(LLRender::LIGHT_TEX, this);
}
- LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ LLLightImageParams* param_block = getLightImageParams();
if (param_block && param_block->getLightTexture() != id)
{
param_block->setLightTexture(id);
@@ -3083,7 +3107,7 @@ void LLVOVolume::setLightTextureID(LLUUID id)
void LLVOVolume::setSpotLightParams(LLVector3 params)
{
- LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ LLLightImageParams* param_block = getLightImageParams();
if (param_block && param_block->getParams() != params)
{
param_block->setParams(params);
@@ -3125,7 +3149,7 @@ void LLVOVolume::setLightSRGBColor(const LLColor3& color)
void LLVOVolume::setLightLinearColor(const LLColor3& color)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ LLLightParams *param_block = getLightParams();
if (param_block)
{
if (param_block->getLinearColor() != color)
@@ -3140,7 +3164,7 @@ void LLVOVolume::setLightLinearColor(const LLColor3& color)
void LLVOVolume::setLightIntensity(F32 intensity)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ LLLightParams *param_block = getLightParams();
if (param_block)
{
if (param_block->getLinearColor().mV[3] != intensity)
@@ -3153,7 +3177,7 @@ void LLVOVolume::setLightIntensity(F32 intensity)
void LLVOVolume::setLightRadius(F32 radius)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ LLLightParams *param_block = getLightParams();
if (param_block)
{
if (param_block->getRadius() != radius)
@@ -3166,7 +3190,7 @@ void LLVOVolume::setLightRadius(F32 radius)
void LLVOVolume::setLightFalloff(F32 falloff)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ LLLightParams *param_block = getLightParams();
if (param_block)
{
if (param_block->getFalloff() != falloff)
@@ -3179,7 +3203,7 @@ void LLVOVolume::setLightFalloff(F32 falloff)
void LLVOVolume::setLightCutoff(F32 cutoff)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ LLLightParams *param_block = getLightParams();
if (param_block)
{
if (param_block->getCutoff() != cutoff)
@@ -3194,7 +3218,7 @@ void LLVOVolume::setLightCutoff(F32 cutoff)
bool LLVOVolume::getIsLight() const
{
- mIsLight = getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT);
+ mIsLight = getLightParams() != nullptr;
return mIsLight;
}
@@ -3210,7 +3234,7 @@ LLColor3 LLVOVolume::getLightSRGBBaseColor() const
LLColor3 LLVOVolume::getLightLinearBaseColor() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return LLColor3(param_block->getLinearColor());
@@ -3223,7 +3247,7 @@ LLColor3 LLVOVolume::getLightLinearBaseColor() const
LLColor3 LLVOVolume::getLightLinearColor() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return LLColor3(param_block->getLinearColor()) * param_block->getLinearColor().mV[3];
@@ -3241,33 +3265,27 @@ LLColor3 LLVOVolume::getLightSRGBColor() const
return ret;
}
-LLUUID LLVOVolume::getLightTextureID() const
+const LLUUID& LLVOVolume::getLightTextureID() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ const LLLightImageParams *param_block = getLightImageParams();
+ if (param_block)
{
- const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (param_block)
- {
- return param_block->getLightTexture();
- }
+ return param_block->getLightTexture();
}
return LLUUID::null;
}
-LLVector3 LLVOVolume::getSpotLightParams() const
+const LLVector3& LLVOVolume::getSpotLightParams() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ const LLLightImageParams *param_block = getLightImageParams();
+ if (param_block)
{
- const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (param_block)
- {
- return param_block->getParams();
- }
+ return param_block->getParams();
}
- return LLVector3();
+ return LLVector3::zero;
}
F32 LLVOVolume::getSpotLightPriority() const
@@ -3304,8 +3322,8 @@ void LLVOVolume::updateSpotLightPriority()
bool LLVOVolume::isLightSpotlight() const
{
- LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ const LLLightImageParams* params = getLightImageParams();
+ if (params)
{
return params->isLightSpotlight();
}
@@ -3315,7 +3333,7 @@ bool LLVOVolume::isLightSpotlight() const
LLViewerTexture* LLVOVolume::getLightTexture()
{
- LLUUID id = getLightTextureID();
+ const LLUUID& id = getLightTextureID();
if (id.notNull())
{
@@ -3326,7 +3344,7 @@ LLViewerTexture* LLVOVolume::getLightTexture()
}
else
{
- mLightTexture = NULL;
+ mLightTexture = nullptr;
}
return mLightTexture;
@@ -3334,7 +3352,7 @@ LLViewerTexture* LLVOVolume::getLightTexture()
F32 LLVOVolume::getLightIntensity() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return param_block->getLinearColor().mV[3];
@@ -3347,7 +3365,7 @@ F32 LLVOVolume::getLightIntensity() const
F32 LLVOVolume::getLightRadius() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return param_block->getRadius();
@@ -3360,7 +3378,7 @@ F32 LLVOVolume::getLightRadius() const
F32 LLVOVolume::getLightFalloff(const F32 fudge_factor) const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return param_block->getFalloff() * fudge_factor;
@@ -3373,7 +3391,7 @@ F32 LLVOVolume::getLightFalloff(const F32 fudge_factor) const
F32 LLVOVolume::getLightCutoff() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return param_block->getCutoff();
@@ -3386,7 +3404,7 @@ F32 LLVOVolume::getLightCutoff() const
bool LLVOVolume::isReflectionProbe() const
{
- return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ return getReflectionProbeParams() != nullptr;
}
bool LLVOVolume::setIsReflectionProbe(bool is_probe)
@@ -3411,7 +3429,7 @@ bool LLVOVolume::setIsReflectionProbe(bool is_probe)
bool LLVOVolume::setReflectionProbeAmbiance(F32 ambiance)
{
- LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
if (param_block->getAmbiance() != ambiance)
@@ -3427,7 +3445,7 @@ bool LLVOVolume::setReflectionProbeAmbiance(F32 ambiance)
bool LLVOVolume::setReflectionProbeNearClip(F32 near_clip)
{
- LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
if (param_block->getClipDistance() != near_clip)
@@ -3443,7 +3461,7 @@ bool LLVOVolume::setReflectionProbeNearClip(F32 near_clip)
bool LLVOVolume::setReflectionProbeIsBox(bool is_box)
{
- LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
if (param_block->getIsBox() != is_box)
@@ -3459,7 +3477,7 @@ bool LLVOVolume::setReflectionProbeIsBox(bool is_box)
bool LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
{
- LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
if (param_block->getIsDynamic() != is_dynamic)
@@ -3475,7 +3493,7 @@ bool LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror)
{
- LLReflectionProbeParams *param_block = (LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
if (param_block->getIsMirror() != is_mirror)
@@ -3498,7 +3516,7 @@ bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror)
F32 LLVOVolume::getReflectionProbeAmbiance() const
{
- const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ const LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
return param_block->getAmbiance();
@@ -3511,7 +3529,7 @@ F32 LLVOVolume::getReflectionProbeAmbiance() const
F32 LLVOVolume::getReflectionProbeNearClip() const
{
- const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ const LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
return param_block->getClipDistance();
@@ -3524,7 +3542,7 @@ F32 LLVOVolume::getReflectionProbeNearClip() const
bool LLVOVolume::getReflectionProbeIsBox() const
{
- const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ const LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
return param_block->getIsBox();
@@ -3535,7 +3553,7 @@ bool LLVOVolume::getReflectionProbeIsBox() const
bool LLVOVolume::getReflectionProbeIsDynamic() const
{
- const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ const LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
return param_block->getIsDynamic();
@@ -3546,8 +3564,7 @@ bool LLVOVolume::getReflectionProbeIsDynamic() const
bool LLVOVolume::getReflectionProbeIsMirror() const
{
- const LLReflectionProbeParams *param_block =
- (const LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ const LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
return param_block->getIsMirror();
@@ -3568,7 +3585,7 @@ U32 LLVOVolume::getVolumeInterfaceID() const
bool LLVOVolume::isFlexible() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE))
+ if (getFlexibleObjectData())
{
LLVolume* volume = getVolume();
if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE)
@@ -3587,7 +3604,7 @@ bool LLVOVolume::isFlexible() const
bool LLVOVolume::isSculpted() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ if (getSculptParams())
{
return true;
}
@@ -3599,7 +3616,7 @@ bool LLVOVolume::isMesh() const
{
if (isSculpted())
{
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ const LLSculptParams *sculpt_params = getSculptParams();
if (sculpt_params)
{
U8 sculpt_type = sculpt_params->getSculptType();
@@ -3617,7 +3634,7 @@ bool LLVOVolume::isMesh() const
bool LLVOVolume::hasLightTexture() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ if (getLightImageParams())
{
return true;
}
@@ -3737,8 +3754,7 @@ bool LLVOVolume::isRiggedMesh() const
//----------------------------------------------------------------------------
U32 LLVOVolume::getExtendedMeshFlags() const
{
- const LLExtendedMeshParams *param_block =
- (const LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH);
+ const LLExtendedMeshParams *param_block = getExtendedMeshParams();
if (param_block)
{
return param_block->getFlags();
@@ -3783,8 +3799,7 @@ void LLVOVolume::setExtendedMeshFlags(U32 flags)
{
bool in_use = true;
setParameterEntryInUse(LLNetworkData::PARAMS_EXTENDED_MESH, in_use, true);
- LLExtendedMeshParams *param_block =
- (LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH);
+ LLExtendedMeshParams *param_block = (LLExtendedMeshParams *)getExtendedMeshParams();
if (param_block)
{
param_block->setFlags(flags);
@@ -3842,11 +3857,12 @@ void LLVOVolume::onReparent(LLViewerObject *old_parent, LLViewerObject *new_pare
}
if (old_volp && old_volp->isAnimatedObject())
{
- if (old_volp->getControlAvatar())
+ LLControlAvatar* cav = old_volp->getControlAvatar();
+ if (cav)
{
// We have been removed from an animated object, need to do cleanup.
- old_volp->getControlAvatar()->updateAttachmentOverrides();
- old_volp->getControlAvatar()->updateAnimations();
+ cav->updateAttachmentOverrides();
+ cav->updateAnimations();
}
}
}
@@ -5131,7 +5147,7 @@ U32 LLVOVolume::getPartitionType() const
{
return LLViewerRegion::PARTITION_HUD;
}
- if (isAnimatedObject() && getControlAvatar())
+ if (isAnimatedObjectFast() && getControlAvatar())
{
return LLViewerRegion::PARTITION_CONTROL_AV;
}
@@ -5757,11 +5773,18 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
// Standard rigged mesh attachments:
- bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();
+ bool is_animated = vobj->isAnimatedObject();
+ bool rigged = !is_animated && skinInfo && vobj->isAttachment();
// Animated objects. Have to check for isRiggedMesh() to
// exclude static objects in animated object linksets.
- rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() &&
- vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying);
+ if (!rigged && is_animated && vobj->isRiggedMesh())
+ {
+ LLControlAvatar* cav = vobj->getControlAvatar();
+ if (cav)
+ {
+ rigged = cav->mPlaying;
+ }
+ }
bool any_rigged_face = false;
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 97a5131260..b6044bc319 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -227,6 +227,7 @@ public:
void setTexture(const S32 face);
S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];}
+ void unregisterOldMeshAndSkin();
/*virtual*/ bool setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override;
void updateSculptTexture();
void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;}
@@ -283,9 +284,9 @@ public:
// Get the light color in sRGB color space scaled by intensity.
LLColor3 getLightSRGBColor() const;
- LLUUID getLightTextureID() const;
+ const LLUUID& getLightTextureID() const;
bool isLightSpotlight() const;
- LLVector3 getSpotLightParams() const;
+ const LLVector3& getSpotLightParams() const;
void updateSpotLightPriority();
F32 getSpotLightPriority() const;
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index cc593fe7b4..f639024228 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -82,7 +82,7 @@ LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item, co
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelWearableOutfitItem(&typeid(LLPanelWearableOutfitItem::Params), "wearable_outfit_list_item");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelWearableOutfitItem(typeid(LLPanelWearableOutfitItem::Params), "wearable_outfit_list_item");
LLPanelWearableOutfitItem::Params::Params()
: add_btn("add_btn"),
@@ -222,7 +222,7 @@ void LLPanelWearableOutfitItem::updateItem(const std::string& name,
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelClothingListItem(&typeid(LLPanelClothingListItem::Params), "clothing_list_item");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelClothingListItem(typeid(LLPanelClothingListItem::Params), "clothing_list_item");
LLPanelClothingListItem::Params::Params()
@@ -309,7 +309,7 @@ bool LLPanelClothingListItem::postBuild()
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelBodyPartsListItem(&typeid(LLPanelBodyPartsListItem::Params), "bodyparts_list_item");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelBodyPartsListItem(typeid(LLPanelBodyPartsListItem::Params), "bodyparts_list_item");
LLPanelBodyPartsListItem::Params::Params()
@@ -380,7 +380,7 @@ bool LLPanelBodyPartsListItem::postBuild()
return true;
}
-static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDeletableWearableListItem(&typeid(LLPanelDeletableWearableListItem::Params), "deletable_wearable_list_item");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDeletableWearableListItem(typeid(LLPanelDeletableWearableListItem::Params), "deletable_wearable_list_item");
LLPanelDeletableWearableListItem::Params::Params()
: delete_btn("delete_btn")
@@ -467,7 +467,7 @@ void LLPanelAttachmentListItem::updateItem(const std::string& name,
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDummyClothingListItem(&typeid(LLPanelDummyClothingListItem::Params), "dummy_clothing_list_item");
+static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDummyClothingListItem(typeid(LLPanelDummyClothingListItem::Params), "dummy_clothing_list_item");
LLPanelDummyClothingListItem::Params::Params()
: add_panel("add_panel"),
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index a319aa00bc..f603274335 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -34,6 +34,7 @@
#include "llagent.h"
#include "llappviewer.h"
+#include "llfloatermarketplace.h"
#include "llfloaterwebcontent.h"
#include "llfloaterreg.h"
#include "lllogininstance.h"
@@ -74,12 +75,20 @@ void LLWeb::loadURL(const std::string& url, const std::string& target, const std
}
// static
-// Explicitly open a Web URL using the Web content floater
+// Explicitly open a Web URL using the Web content floater or Marketplace floater
void LLWeb::loadURLInternal(const std::string &url, const std::string& target, const std::string& uuid, bool dev_mode)
{
LLFloaterWebContent::Params p;
p.url(url).target(target).id(uuid).dev_mode(dev_mode);
- LLFloaterReg::showInstance("web_content", p);
+
+ if (LLFloaterMarketplace::isMarketplaceURL(url))
+ {
+ LLFloaterReg::showInstance("marketplace", p);
+ }
+ else
+ {
+ LLFloaterReg::showInstance("web_content", p);
+ }
}
// static
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 153bee3aef..1db36649fa 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -118,6 +118,7 @@ LLVector3d LLSimInfo::getGlobalOrigin() const
{
return from_region_handle(mHandle);
}
+
LLVector3 LLSimInfo::getLocalPos(LLVector3d global_pos) const
{
LLVector3d sim_origin = from_region_handle(mHandle);
diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h
index 68e7f3ee29..91bc699708 100644
--- a/indra/newview/llworldmap.h
+++ b/indra/newview/llworldmap.h
@@ -37,18 +37,6 @@
#include "llviewertexture.h"
#include "llgltexture.h"
-// map item types
-const U32 MAP_ITEM_TELEHUB = 0x01;
-const U32 MAP_ITEM_PG_EVENT = 0x02;
-const U32 MAP_ITEM_MATURE_EVENT = 0x03;
-//const U32 MAP_ITEM_POPULAR = 0x04; // No longer supported, 2009-03-02 KLW
-//const U32 MAP_ITEM_AGENT_COUNT = 0x05;
-const U32 MAP_ITEM_AGENT_LOCATIONS = 0x06;
-const U32 MAP_ITEM_LAND_FOR_SALE = 0x07;
-const U32 MAP_ITEM_CLASSIFIED = 0x08;
-const U32 MAP_ITEM_ADULT_EVENT = 0x09;
-const U32 MAP_ITEM_LAND_FOR_SALE_ADULT = 0x0a;
-
// Description of objects like hubs, events, land for sale, people and more (TBD).
// Note: we don't store a "type" in there so we need to store instances of this class in
// well known objects (i.e. list of objects which type is "well known").
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 6b2bd3e6fb..1be6a6cfff 100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -517,26 +517,38 @@ void LLWorldMapView::draw()
// Draw the region name in the lower left corner
if (mMapScale >= DRAW_TEXT_THRESHOLD)
{
- std::string mesg;
+ static LLCachedControl<bool> print_coords(gSavedSettings, "MapShowGridCoords");
+ static LLFontGL* font = LLFontGL::getFontSansSerifSmallBold();
+
+ auto print = [&](std::string text, F32 x, F32 y, bool use_ellipses)
+ {
+ font->renderUTF8(text, 0,
+ (F32)llfloor(left + x), (F32)llfloor(bottom + y),
+ LLColor4::white,
+ LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
+ S32_MAX, //max_chars
+ (S32)mMapScale, //max_pixels
+ NULL,
+ use_ellipses);
+ };
+
+ std::string grid_name = info->getName();
if (info->isDown())
{
- mesg = llformat( "%s (%s)", info->getName().c_str(), sStringsMap["offline"].c_str());
+ grid_name += " (" + sStringsMap["offline"] + ")";
}
- else
+
+ if (print_coords)
{
- mesg = info->getName();
+ print(grid_name, 3, 14, true);
+ // Obtain and print the grid map coordinates
+ LLVector3d region_pos = info->getGlobalOrigin();
+ std::string grid_coords = llformat("[%.0f, %.0f]", region_pos[VX] / 256, region_pos[VY] / 256);
+ print(grid_coords, 3, 2, false);
}
- if (!mesg.empty())
+ else
{
- LLFontGL::getFontSansSerifSmallBold()->renderUTF8(
- mesg, 0,
- (F32)llfloor(left + 3), (F32)llfloor(bottom + 2),
- LLColor4::white,
- LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
- S32_MAX, //max_chars
- (S32)mMapScale, //max_pixels
- NULL,
- /*use_ellipses*/true);
+ print(grid_name, 3, 2, true);
}
}
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index a844e29cbb..86f7a08233 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2811,6 +2811,10 @@ void LLPipeline::clearRebuildGroups()
{
LLSpatialGroup* group = *iter;
+ if (!group || group->isDead())
+ {
+ continue;
+ }
// If the group contains HUD objects, save the group
if (group->isHUDGroup())
{
@@ -5693,7 +5697,7 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_
if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE))
{
// moving lights get a little higher priority (too much causes artifacts)
- dist = llmax(dist - light->getLightRadius()*0.25f, 0.f);
+ dist = llmax(dist - radius * 0.25f, 0.f);
}
return dist;
}
diff --git a/indra/newview/skins/default/xui/da/floater_sound_devices.xml b/indra/newview/skins/default/xui/da/floater_sound_devices.xml
deleted file mode 100644
index cb4cbba570..0000000000
--- a/indra/newview/skins/default/xui/da/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_sound_devices" title="Lyd enheder">
- <text name="voice_label">
- Stemme chat
- </text>
- <check_box label="Aktiveret" name="enable_voice"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/da/floater_voice_effect.xml b/indra/newview/skins/default/xui/da/floater_voice_effect.xml
deleted file mode 100644
index 86ad251103..0000000000
--- a/indra/newview/skins/default/xui/da/floater_voice_effect.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Steder" name="voice_effects" title="STEMME MORPH">
- <string name="no_voice_effect">
- (Ingen stemme &quot;morph&quot;)
- </string>
- <string name="active_voice_effect">
- (Aktiv)
- </string>
- <string name="unsubscribed_voice_effect">
- (Ikke aktiveret)
- </string>
- <string name="new_voice_effect">
- (Ny!)
- </string>
- <text name="preview_text">
- For at se
- </text>
- <text name="status_text">
- Optag en prøve, klik derefter på en stemme for at høre hvordan det vil lyde.
- </text>
- <button label="Optag" name="record_btn" tool_tip="Optag en stemmeprøve."/>
- <button label="Stop" name="record_stop_btn"/>
- <text name="voice_morphing_link">
- [[URL] Abonnér nu]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="Optag en prøve med din stemme og klik på en effekt for at teste.">
- <scroll_list.columns label="Stemme navn" name="name"/>
- <scroll_list.columns label="Udløber" name="expires"/>
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/da/panel_voice_effect.xml b/indra/newview/skins/default/xui/da/panel_voice_effect.xml
deleted file mode 100644
index 50f561ec7f..0000000000
--- a/indra/newview/skins/default/xui/da/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- Voice Morphing Off
- </string>
- <string name="preview_voice_effects">
- Se stemme &quot;morph&quot; ▶
- </string>
- <string name="get_voice_effects">
- Hente stemme &quot;morph&quot; ▶
- </string>
- <combo_box name="voice_effect" tool_tip="Vælg en stemme &quot;morph&quot; for at ændre din stemme">
- <combo_box.item label="Stemme morph slukket" name="no_voice_effect"/>
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/de/floater_big_preview.xml b/indra/newview/skins/default/xui/de/floater_big_preview.xml
deleted file mode 100644
index c5ce56d1d9..0000000000
--- a/indra/newview/skins/default/xui/de/floater_big_preview.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_big_preview" title="VORSCHAU"/>
diff --git a/indra/newview/skins/default/xui/de/floater_post_process.xml b/indra/newview/skins/default/xui/de/floater_post_process.xml
deleted file mode 100644
index a6ed8cc3df..0000000000
--- a/indra/newview/skins/default/xui/de/floater_post_process.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater name="Post-Process Floater" title="POST-PROCESSING-EINSTELLUNGEN">
- <tab_container name="Post-Process Tabs">
- <panel label="Farbfilter" name="wmiColorFilterPanel">
- <check_box label="Ein" name="wmiColorFilterToggle" />
- <text name="wmiColorFilterBrightnessText">
- Helligkeit
- </text>
- <text name="wmiColorFilterSaturationText">
- Sättigung
- </text>
- <text name="wmiColorFilterContrastText">
- Kontrast
- </text>
- <text name="wmiColorFilterBaseText">
- Kontrast-Grundfarbe
- </text>
- <slider label="R" name="wmiColorFilterBaseR" />
- <slider label="G" name="wmiColorFilterBaseG" />
- <slider label="B" name="wmiColorFilterBaseB" />
- <slider label="I" name="wmiColorFilterBaseI" />
- </panel>
- <panel label="Nachtsicht" name="wmiNightVisionPanel">
- <check_box label="Ein" name="wmiNightVisionToggle" />
- <text name="wmiNightVisionBrightMultText">
- Lichtverstärkungsmultiplikator
- </text>
- <text name="wmiNightVisionNoiseSizeText">
- Rauschen-Größe
- </text>
- <text name="wmiNightVisionNoiseStrengthText">
- Rauschen-Stärke
- </text>
- </panel>
- <panel label="Bloom" name="wmiBloomPanel">
- <check_box label="Ein" name="wmiBloomToggle" />
- <text name="wmiBloomExtractText">
- Luminanz-Extraktion
- </text>
- <text name="wmiBloomSizeText">
- Bloom-Größe
- </text>
- <text name="wmiBloomStrengthText">
- Bloom-Stärke
- </text>
- </panel>
- <panel label="Extras" name="Extras">
- <button label="Effekt laden" label_selected="Effekt laden" name="PPLoadEffect" />
- <button label="Effekt speichern" label_selected="Effekt speichern" name="PPSaveEffect" />
- <line_editor label="Effektname" name="PPEffectNameEditor" />
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_sound_devices.xml b/indra/newview/skins/default/xui/de/floater_sound_devices.xml
deleted file mode 100644
index 22ccb2c1a2..0000000000
--- a/indra/newview/skins/default/xui/de/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_sound_devices" title="SOUNDGERÄTE">
- <text name="voice_label">
- Voice-Chat
- </text>
- <check_box label="Aktiviert" name="enable_voice"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_voice_effect.xml b/indra/newview/skins/default/xui/de/floater_voice_effect.xml
deleted file mode 100644
index 8d37950480..0000000000
--- a/indra/newview/skins/default/xui/de/floater_voice_effect.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Orte" name="voice_effects" title="VOICE-MORPHING-VORSCHAU">
- <string name="no_voice_effect">
- (Kein Voice-Morphing)
- </string>
- <string name="active_voice_effect">
- (Aktiv)
- </string>
- <string name="unsubscribed_voice_effect">
- (nicht abonniert)
- </string>
- <string name="new_voice_effect">
- (Neu!)
- </string>
- <string name="effect_Arena">
- Arena
- </string>
- <string name="effect_Beast">
- Bestie
- </string>
- <string name="effect_Buff">
- Muskulös
- </string>
- <string name="effect_Buzz">
- Buzz
- </string>
- <string name="effect_Camille">
- Camille
- </string>
- <string name="effect_Creepy">
- Unheimlich
- </string>
- <string name="effect_CreepyBot">
- UnheimlicherBot
- </string>
- <string name="effect_Cyber">
- Cyber
- </string>
- <string name="effect_DeepBot">
- TieferBot
- </string>
- <string name="effect_Demon">
- Dämon
- </string>
- <string name="effect_Female Elf">
- Weibliche Elfe
- </string>
- <string name="effect_Flirty">
- Kokett
- </string>
- <string name="effect_Foxy">
- Attraktiv
- </string>
- <string name="effect_Halloween 2010 Bonus">
- Bonus_Halloween_2010
- </string>
- <string name="effect_Helium">
- Helium
- </string>
- <string name="effect_Husky">
- Rauchig
- </string>
- <string name="effect_Husky Whisper">
- Rauchiges Flüstern
- </string>
- <string name="effect_Intercom">
- Intercom
- </string>
- <string name="effect_Julia">
- Julia
- </string>
- <string name="effect_Lo Lilt">
- Leises Trällern
- </string>
- <string name="effect_Macho">
- Macho
- </string>
- <string name="effect_Micro">
- Micro
- </string>
- <string name="effect_Mini">
- Mini
- </string>
- <string name="effect_Model">
- Modell
- </string>
- <string name="effect_Nano">
- Nano
- </string>
- <string name="effect_Nightmare">
- Alptraum
- </string>
- <string name="effect_PopBot">
- PopBot
- </string>
- <string name="effect_Rachel">
- Rachel
- </string>
- <string name="effect_Radio">
- Radio
- </string>
- <string name="effect_Robot">
- Roboter
- </string>
- <string name="effect_Roxanne">
- Roxanne
- </string>
- <string name="effect_Rumble">
- Rumpeln
- </string>
- <string name="effect_Sabrina">
- Sabrina
- </string>
- <string name="effect_Samantha">
- Samantha
- </string>
- <string name="effect_Sexy">
- Sexy
- </string>
- <string name="effect_Shorty">
- Shorty
- </string>
- <string name="effect_Smaller">
- Kleiner
- </string>
- <string name="effect_Sneaky">
- Hinterhältig
- </string>
- <string name="effect_Stallion">
- Hengst
- </string>
- <string name="effect_Sultry">
- Feurig
- </string>
- <string name="effect_Thunder">
- Donner
- </string>
- <string name="effect_Vixen">
- Erotisch
- </string>
- <string name="effect_WhinyBot">
- JammernderBot
- </string>
- <text name="preview_text">
- Zur Vorschau
- </text>
- <text name="status_text">
- Stimme aufnehmen und auf einen Effekt klicken, um diesen auf Ihre Stimme anzuwenden.
- </text>
- <button label="Aufnehmen" name="record_btn" tool_tip="Nehmen Sie Ihre Stimme auf."/>
- <button label="Stopp" name="record_stop_btn"/>
- <text name="voice_morphing_link">
- [[URL] Jetzt abonnieren]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="Nehmen Sie Ihre Stimme auf und klicken Sie dann auf einen Effekt, um diesen auszuprobieren.">
- <scroll_list.columns label="Bezeichnung" name="name"/>
- <scroll_list.columns label="Gültig bis" name="expires"/>
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/panel_voice_effect.xml b/indra/newview/skins/default/xui/de/panel_voice_effect.xml
deleted file mode 100644
index 533deb8597..0000000000
--- a/indra/newview/skins/default/xui/de/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- Voice-Morphing Aus
- </string>
- <string name="preview_voice_effects">
- Voice-Morphing ausprobieren ▶
- </string>
- <string name="get_voice_effects">
- Voice-Morphing abonnieren ▶
- </string>
- <combo_box name="voice_effect" tool_tip="Wählen Sie einen Voice-Morph-Effekt aus, um Ihre Stimme zu verändern.">
- <combo_box.item label="Voice-Morphing Aus" name="no_voice_effect"/>
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/floater_big_preview.xml b/indra/newview/skins/default/xui/en/floater_big_preview.xml
deleted file mode 100644
index 362853d06f..0000000000
--- a/indra/newview/skins/default/xui/en/floater_big_preview.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater
- positioning="cascading"
- can_close="true"
- can_resize="true"
- can_minimize="false"
- help_topic="floater_big_preview"
- layout="topleft"
- name="floater_big_preview"
- save_rect="true"
- single_instance="true"
- reuse_instance="true"
- title="PREVIEW"
- height="465"
- width="770">
- <panel
- height="450"
- width="750"
- visible="true"
- name="big_preview_placeholder"
- top="5"
- follows="all"
- left="10">
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_post_process.xml b/indra/newview/skins/default/xui/en/floater_post_process.xml
deleted file mode 100644
index 37339f79c8..0000000000
--- a/indra/newview/skins/default/xui/en/floater_post_process.xml
+++ /dev/null
@@ -1,426 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater
- legacy_header_height="18"
- height="400"
- layout="topleft"
- name="Post-Process Floater"
- help_topic="post_process_floater"
- title="POST-PROCESS SETTINGS"
- width="400">
- <tab_container
- follows="left|top"
- height="400"
- layout="topleft"
- left="0"
- name="Post-Process Tabs"
- tab_position="top"
- top="0"
- width="400">
- <panel
- border="true"
- follows="left|top|right|bottom"
- height="400"
- label="Color Filter"
- layout="topleft"
- left="1"
- mouse_opaque="false"
- help_topic="post_process_color_filter_tab"
- name="wmiColorFilterPanel"
- top="0"
- width="398">
- <check_box
- control_name="wmiColorFilterToggle"
- height="16"
- label="Enable"
- layout="topleft"
- left="14"
- name="wmiColorFilterToggle"
- top="4"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-4"
- name="wmiColorFilterBrightnessText"
- top_pad="4"
- width="355">
- Brightness
- </text>
- <slider
- control_name="wmiColorFilterBrightness"
- decimal_digits="2"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="1.0"
- layout="topleft"
- left_delta="4"
- max_val="4"
- name="wmiColorFilterBrightness"
- top_pad="20"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-4"
- name="wmiColorFilterSaturationText"
- top_pad="4"
- width="355">
- Saturation
- </text>
- <slider
- control_name="wmiColorFilterSaturation"
- decimal_digits="2"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="1.0"
- layout="topleft"
- left_delta="4"
- max_val="2"
- min_val="-1"
- name="wmiColorFilterSaturation"
- top_pad="20"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-4"
- name="wmiColorFilterContrastText"
- top_pad="4"
- width="355">
- Contrast
- </text>
- <slider
- control_name="wmiColorFilterContrast"
- decimal_digits="2"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="1.0"
- layout="topleft"
- left_delta="4"
- max_val="4"
- name="wmiColorFilterContrast"
- top_pad="20"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-4"
- name="wmiColorFilterBaseText"
- top_pad="4"
- width="355">
- Contrast Base Color
- </text>
- <slider
- control_name="wmiColorFilterBaseR"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="1.0"
- label="R"
- layout="topleft"
- left_delta="4"
- name="wmiColorFilterBaseR"
- top_pad="20"
- width="200" />
- <slider
- control_name="wmiColorFilterBaseG"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="1.0"
- label="G"
- layout="topleft"
- left_delta="0"
- name="wmiColorFilterBaseG"
- top_pad="10"
- width="200" />
- <slider
- control_name="wmiColorFilterBaseB"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="1.0"
- label="B"
- layout="topleft"
- left_delta="0"
- name="wmiColorFilterBaseB"
- top_pad="10"
- width="200" />
- <slider
- control_name="wmiColorFilterBaseI"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="0.5"
- label="I"
- layout="topleft"
- left_delta="0"
- name="wmiColorFilterBaseI"
- top_pad="10"
- width="200" />
- </panel>
- <panel
- border="true"
- follows="left|top|right|bottom"
- height="400"
- label="Night Vision"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
- help_topic="post_process_night_vision_tab"
- name="wmiNightVisionPanel"
- top_delta="-236"
- width="398">
- <check_box
- control_name="wmiNightVisionToggle"
- height="16"
- label="Enable"
- layout="topleft"
- left="14"
- name="wmiNightVisionToggle"
- top="4"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-4"
- name="wmiNightVisionBrightMultText"
- top_pad="5"
- width="355">
- Light Amplification Multiple
- </text>
- <slider
- control_name="wmiNightVisionBrightMult"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="3.0"
- layout="topleft"
- left_delta="4"
- max_val="10"
- min_val="1"
- name="wmiNightVisionBrightMult"
- top_pad="20"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-4"
- name="wmiNightVisionNoiseSizeText"
- top_pad="4"
- width="355">
- Noise Size
- </text>
- <slider
- control_name="wmiNightVisionNoiseSize"
- follows="left"
- height="10"
- initial_value="1"
- layout="topleft"
- left_delta="4"
- max_val="100"
- min_val="1"
- name="wmiNightVisionNoiseSize"
- top_pad="20"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-4"
- name="wmiNightVisionNoiseStrengthText"
- top_pad="4"
- width="355">
- Noise Strength
- </text>
- <slider
- control_name="wmiNightVisionNoiseStrength"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="0.3"
- layout="topleft"
- left_delta="4"
- name="wmiNightVisionNoiseStrength"
- top_pad="20"
- width="200" />
- </panel>
- <panel
- border="true"
- follows="left|top|right|bottom"
- height="400"
- label="Bloom"
- layout="topleft"
- left_delta="0"
- help_topic="post_process_bloom_tab"
- name="wmiBloomPanel"
- top_delta="-236"
- width="398">
- <check_box
- control_name="wmiBloomToggle"
- height="16"
- label="Enable"
- layout="topleft"
- left="14"
- name="wmiBloomToggle"
- top="4"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-4"
- name="wmiBloomExtractText"
- top_pad="5"
- width="355">
- Luminosity Extraction
- </text>
- <slider
- control_name="wmiBloomExtract"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="0.9"
- layout="topleft"
- left_delta="4"
- name="wmiBloomExtract"
- top_pad="20"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-4"
- name="wmiBloomSizeText"
- top_pad="4"
- width="355">
- Bloom Size
- </text>
- <slider
- control_name="wmiBloomSize"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="3.0"
- layout="topleft"
- left_delta="4"
- max_val="20"
- name="wmiBloomSize"
- top_pad="20"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-4"
- name="wmiBloomStrengthText"
- top_pad="4"
- width="355">
- Bloom Strength
- </text>
- <slider
- control_name="wmiBloomStrength"
- follows="left"
- height="10"
- increment="0.01"
- initial_value="1.2"
- layout="topleft"
- left_delta="4"
- max_val="10"
- name="wmiBloomStrength"
- top_pad="20"
- width="200" />
- </panel>
- <panel
- border="true"
- follows="left|top|right|bottom"
- height="400"
- label="Extras"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
- help_topic="post_process_extras_tab"
- name="Extras"
- top_delta="-236"
- width="398">
- <button
- height="20"
- label="LoadEffect"
- label_selected="LoadEffect"
- layout="topleft"
- left="15"
- name="PPLoadEffect"
- top="13"
- width="100" />
- <button
- height="20"
- label="SaveEffect"
- label_selected="SaveEffect"
- layout="topleft"
- left_delta="0"
- name="PPSaveEffect"
- top_pad="7"
- width="100" />
- <combo_box
- height="18"
- layout="topleft"
- left_delta="120"
- name="PPEffectsCombo"
- top="15"
- width="150" />
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|right|bottom"
- font="SansSerif"
- height="20"
- label="Effect Name"
- layout="topleft"
- left_delta="0"
- max_length_bytes="40"
- name="PPEffectNameEditor"
- tab_group="1"
- top_pad="22"
- width="150" />
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_sound_devices.xml b/indra/newview/skins/default/xui/en/floater_sound_devices.xml
deleted file mode 100644
index dec0e9b6c6..0000000000
--- a/indra/newview/skins/default/xui/en/floater_sound_devices.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater
- border_visible="false"
- border="false"
- legacy_header_height="18"
- can_minimize="true"
- can_resize="false"
- can_close="false"
- chrome="true"
- save_dock_state="true"
- save_visibility="true"
- save_rect="true"
- single_instance="true"
- bevel_style="in"
- height="164"
- layout="topleft"
- name="floater_sound_devices"
- title="SOUND DEVICES"
- width="490">
- <panel
- layout="topleft"
- follows="all"
- filename="panel_sound_devices.xml"
- name="device_settings_panel"
- width="400"
- left="10"
- top="26"
- class="panel_voice_device_settings"/>
- <text
- name="voice_label"
- top="136"
- left="12"
- height="14"
- width="80"
- layout="topleft"
- >Voice Chat</text>
- <check_box
- layout="topleft"
- control_name="EnableVoiceChat"
- follows="bottom|left"
- top="138"
- left="80"
- name="enable_voice"
- width="100"
- height="14"
- label="Enabled"
- />
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml
index 1600c422c3..191db4f854 100644
--- a/indra/newview/skins/default/xui/en/floater_stats.xml
+++ b/indra/newview/skins/default/xui/en/floater_stats.xml
@@ -418,6 +418,64 @@
</stat_view>
</stat_view>
</stat_view>
+ <stat_view name="voice"
+ label="Voice"
+ setting="OpenDebugStatVoice">
+ <stat_bar
+ name="webrtc_latency"
+ label="Latency"
+ stat="webrtc_latency"
+ unit_label="ms"
+ decimal_digits="1"/>
+ <stat_bar
+ name="webrtc_upload_bandwidth"
+ label="Upload bandwidth"
+ stat="webrtc_upload_bandwidth"
+ unit_label="kbps"
+ decimal_digits="0"/>
+ <stat_view name="incoming_audio"
+ label="Incoming audio"
+ setting="OpenDebugStatVoiceIncoming">
+ <stat_bar
+ name="incoming_packet_recv"
+ label="Packets received"
+ stat="webrtc_packets_in_recv"/>
+ <stat_bar
+ name="packets_in_lost"
+ label="Packets lost"
+ stat="webrtc_packets_in_lost"/>
+ <stat_bar
+ name="jitter_in"
+ label="Jitter"
+ stat="webrtc_jitter_in"
+ unit_label="ms"
+ decimal_digits="1"/>
+ <stat_bar
+ name="jitter_buffer"
+ label="Jitter buffer"
+ stat="webrtc_jitter_buffer"
+ unit_label="ms"
+ decimal_digits="1"/>
+ </stat_view>
+ <stat_view name="outgoing_audio"
+ label="Outgoing audio"
+ setting="OpenDebugStatVoiceOutgoing">
+ <stat_bar
+ name="packets_out_sent"
+ label="Packets sent"
+ stat="webrtc_packets_out_sent"/>
+ <stat_bar
+ name="packets_out_lost"
+ label="Packets lost"
+ stat="webrtc_packets_out_lost"/>
+ <stat_bar
+ name="jitter_out"
+ label="Jitter"
+ stat="webrtc_jitter_out"
+ unit_label="ms"
+ decimal_digits="1"/>
+ </stat_view>
+ </stat_view>
</container_view>
</scroll_container>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_combobox.xml b/indra/newview/skins/default/xui/en/floater_test_combobox.xml
index 4211d624ac..0d75685223 100644
--- a/indra/newview/skins/default/xui/en/floater_test_combobox.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_combobox.xml
@@ -155,4 +155,36 @@
name="item3"
value="tx" />
</combo_box>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ top_pad="24"
+ width="200">
+ Multiple columns:
+ </text>
+ <combo_box
+ name="multi_column_combo"
+ layout="topleft"
+ height="20"
+ width="150"
+ left_delta="0"
+ top_pad="4">
+ <combo_item name="combo_item1" value="0">
+ <column width="40" name="label" label="|Abc|" />
+ <column name="longtext" label="Match full text" />
+ </combo_item>
+
+ <combo_item name="combo_item2" value="1">
+ <column name="label" label="*Abc*" />
+ <column name="longtext" label="Match substring" />
+ </combo_item>
+
+ <combo_item name="combo_item3" value="2">
+ <column name="label" label="/ *. /" />
+ <column name="longtext" label="Match regular expression" />
+ </combo_item>
+ </combo_box>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_voice_effect.xml b/indra/newview/skins/default/xui/en/floater_voice_effect.xml
deleted file mode 100644
index d037bdb813..0000000000
--- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater
- legacy_header_height="27"
- can_resize="true"
- height="500"
- name="voice_effects"
- help_topic="voice_effects"
- title="VOICE MORPHING PREVIEW"
- background_visible="true"
- label="Places"
- layout="topleft"
- min_height="360"
- min_width="200"
- save_rect="true"
- width="300">
- <string name="no_voice_effect">
- (No Voice Morph)
- </string>
- <string name="active_voice_effect">
- (Active)
- </string>
- <string name="unsubscribed_voice_effect">
- (Unsubscribed)
- </string>
- <string name="new_voice_effect">
- (New!)
- </string>
-
- <!-- effect names begin -->
- <string name="effect_Arena">Arena</string>
- <string name="effect_Beast">Beast</string>
- <string name="effect_Buff">Buff</string>
- <string name="effect_Buzz">Buzz</string>
- <string name="effect_Camille">Camille</string>
- <string name="effect_Creepy">Creepy</string>
- <string name="effect_CreepyBot">CreepyBot</string>
- <string name="effect_Cyber">Cyber</string>
- <string name="effect_DeepBot">DeepBot</string>
- <string name="effect_Demon">Demon</string>
- <string name="effect_Female Elf">Female Elf</string>
- <string name="effect_Flirty">Flirty</string>
- <string name="effect_Foxy">Foxy</string>
- <string name="effect_Halloween 2010 Bonus">Halloween_2010_Bonus</string>
- <string name="effect_Helium">Helium</string>
- <string name="effect_Husky">Husky</string>
- <string name="effect_Husky Whisper">Husky Whisper</string>
- <string name="effect_Intercom">Intercom</string>
- <string name="effect_Julia">Julia</string>
- <string name="effect_Lo Lilt">Lo Lilt</string>
- <string name="effect_Macho">Macho</string>
- <string name="effect_Micro">Micro</string>
- <string name="effect_Mini">Mini</string>
- <string name="effect_Model">Model</string>
- <string name="effect_Nano">Nano</string>
- <string name="effect_Nightmare">Nightmare</string>
- <string name="effect_PopBot">PopBot</string>
- <string name="effect_Rachel">Rachel</string>
- <string name="effect_Radio">Radio</string>
- <string name="effect_Robot">Robot</string>
- <string name="effect_Roxanne">Roxanne</string>
- <string name="effect_Rumble">Rumble</string>
- <string name="effect_Sabrina">Sabrina</string>
- <string name="effect_Samantha">Samantha</string>
- <string name="effect_Sexy">Sexy</string>
- <string name="effect_Shorty">Shorty</string>
- <string name="effect_Smaller">Smaller</string>
- <string name="effect_Sneaky">Sneaky</string>
- <string name="effect_Stallion">Stallion</string>
- <string name="effect_Sultry">Sultry</string>
- <string name="effect_Thunder">Thunder</string>
- <string name="effect_Vixen">Vixen</string>
- <string name="effect_WhinyBot">WhinyBot</string>
- <!-- effect names end -->
-
- <text
- height="16"
- word_wrap="true"
- use_ellipses="true"
- type="string"
- follows="left|top|right"
- layout="topleft"
- font="SansSerifBold"
- color="White"
- left="10"
- name="preview_text"
- right="-10"
- top="27">To Preview
- </text>
- <text
- height="23"
- word_wrap="true"
- use_ellipses="true"
- type="string"
- follows="left|top|right"
- layout="topleft"
- left="10"
- name="status_text"
- right="-5"
- top_pad="0">
-Record a sample, then click on a voice to hear how it will sound.
- </text>
- <button
- follows="left|top"
- height="23"
- label="Record"
- layout="topleft"
- left="10"
- name="record_btn"
- tool_tip="Record a sample of your voice."
- top_pad="5"
- width="100">
- <button.commit_callback
- function="VoiceEffect.Record" />
- </button>
- <button
- follows="left|top"
- height="23"
- label="Stop"
- layout="topleft"
- left_delta="0"
- name="record_stop_btn"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="VoiceEffect.Stop" />
- </button>
- <text
- height="23"
- halign="right"
- use_ellipses="true"
- type="string"
- follows="left|top|right"
- layout="topleft"
- left_pad="10"
- top_delta="10"
- name="voice_morphing_link"
- right="-10">
- [[URL] Subscribe Now]
- </text>
- <scroll_list
- bottom="-10"
- draw_heading="true"
- follows="all"
- layout="topleft"
- left="10"
- multi_select="false"
- name="voice_effect_list"
- right="-10"
- tool_tip="Record a sample of your voice, then click an effect to preview."
- top="95">
- <scroll_list.columns
- label="Voice Name"
- name="name"
- relative_width="0.60" />
- <scroll_list.columns
- dynamic_width="true"
- label="Expires"
- name="expires"
- relative_width="0.30" />
- </scroll_list>
-
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index fb93d32ee4..9c4ccc0e8d 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -109,7 +109,7 @@
</panel>
<panel
follows="right|top"
- height="126"
+ height="150"
top_pad="4"
width="238"
left="1"
@@ -285,6 +285,30 @@
by owner
</text>
+ <check_box
+ name="grid_coords_chk"
+ control_name="MapShowGridCoords"
+ layout="topleft"
+ follows="top|right"
+ top_pad="2"
+ left="3"
+ height="16"
+ width="22"
+ />
+ <text
+ name="grid_coords_label"
+ type="string"
+ layout="topleft"
+ follows="top|right"
+ top_delta="2"
+ left_pad="3"
+ height="16"
+ width="220"
+ halign="left"
+ length="1" >
+ Show grid map coordinates
+ </text>
+
<button
follows="top|right"
height="22"
@@ -455,7 +479,7 @@
<panel
follows="right|top|bottom"
- height="235"
+ height="220"
top_pad="0"
width="238"
name="layout_panel_4">
@@ -573,7 +597,7 @@
draw_stripes="false"
bg_writeable_color="0.75 0.75 0.75 0.15"
follows="all"
- height="145"
+ height="130"
layout="topleft"
left="28"
name="search_results"
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index d978619355..c9adf46ad7 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -48,6 +48,28 @@
<menu_item_call.on_click
function="Object.ShowOriginal" />
</menu_item_call>
+ <menu_item_call
+ label="Add to favorites"
+ layout="topleft"
+ name="Add to favorites">
+ <menu_item_call.on_click
+ function="Object.SetFavorite"
+ parameter="Add" />
+ <menu_item_call.on_visible
+ function="Object.EnableFavorites"
+ parameter="Add"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Remove from favorites"
+ layout="topleft"
+ name="Remove from favorites">
+ <menu_item_call.on_click
+ function="Object.SetFavorite"
+ parameter="Remove" />
+ <menu_item_call.on_visible
+ function="Object.EnableFavorites"
+ parameter="Remove" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index 62cdaa5886..5a28f0dde5 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -176,57 +176,60 @@
<on_click function="Group.DoToSelected" parameter="leave_group"/>
<on_enable function="Avatar.EnableItem" parameter="can_leave_group" />
</menu_item_call>
- <menu_item_separator layout="topleft" name="Moderator Options Separator"/>
- <context_menu
- label="Moderator Options"
- layout="topleft"
- name="Moderator Options">
- <menu_item_check
- label="Allow text chat"
- layout="topleft"
- name="AllowTextChat">
- <on_check function="Avatar.CheckItem" parameter="is_allowed_text_chat" />
- <on_click function="Avatar.DoToSelected" parameter="toggle_allow_text_chat" />
- <on_enable function="Avatar.EnableItem" parameter="can_allow_text_chat" />
- </menu_item_check>
- <menu_item_separator layout="topleft" name="moderate_voice_separator" />
- <menu_item_call
- label="Mute this participant"
- layout="topleft"
- name="ModerateVoiceMuteSelected">
- <on_click function="Avatar.DoToSelected" parameter="selected" />
- <on_enable function="Avatar.EnableItem" parameter="can_mute" />
- <on_visible function="Avatar.VisibleItem" parameter="show_mute" />
- </menu_item_call>
+ <menu_item_separator layout="topleft" name="Moderator Options Separator"/>
+ <context_menu
+ label="Moderator Options"
+ layout="topleft"
+ name="Moderator Options">
+ <menu_item_check
+ label="Allow text chat"
+ layout="topleft"
+ name="AllowTextChat">
+ <on_check function="Avatar.CheckItem" parameter="is_allowed_text_chat" />
+ <on_click function="Avatar.DoToSelected" parameter="toggle_allow_text_chat" />
+ <on_enable function="Avatar.EnableItem" parameter="can_allow_text_chat" />
+ <on_visible function="Avatar.VisibleItem" parameter="can_allow_text_chat" />
+ </menu_item_check>
+ <menu_item_separator layout="topleft" name="moderate_voice_separator">
+ <on_visible function="Avatar.VisibleItem" parameter="can_allow_text_chat" />
+ </menu_item_separator>
+ <menu_item_call
+ label="Mute this participant"
+ layout="topleft"
+ name="ModerateVoiceMuteSelected">
+ <on_click function="Avatar.DoToSelected" parameter="selected" />
+ <on_enable function="Avatar.EnableItem" parameter="can_mute" />
+ <on_visible function="Avatar.VisibleItem" parameter="show_mute" />
+ </menu_item_call>
+ <menu_item_call
+ label="Unmute this participant"
+ layout="topleft"
+ name="ModerateVoiceUnMuteSelected">
+ <on_click function="Avatar.DoToSelected" parameter="selected" />
+ <on_enable function="Avatar.EnableItem" parameter="can_unmute" />
+ <on_visible function="Avatar.VisibleItem" parameter="show_unmute" />
+ </menu_item_call>
+ <menu_item_call
+ label="Mute everyone"
+ layout="topleft"
+ name="ModerateVoiceMute">
+ <on_click function="Avatar.DoToSelected" parameter="mute_all" />
+ <on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
+ </menu_item_call>
+ <menu_item_call
+ label="Unmute everyone"
+ layout="topleft"
+ name="ModerateVoiceUnmute">
+ <on_click function="Avatar.DoToSelected" parameter="unmute_all" />
+ <on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
+ </menu_item_call>
+ </context_menu>
+ <menu_item_separator layout="topleft" name="Group Ban Separator"/>
<menu_item_call
- label="Unmute this participant"
- layout="topleft"
- name="ModerateVoiceUnMuteSelected">
- <on_click function="Avatar.DoToSelected" parameter="selected" />
- <on_enable function="Avatar.EnableItem" parameter="can_unmute" />
- <on_visible function="Avatar.VisibleItem" parameter="show_unmute" />
- </menu_item_call>
- <menu_item_call
- label="Mute everyone"
- layout="topleft"
- name="ModerateVoiceMute">
- <on_click function="Avatar.DoToSelected" parameter="mute_all" />
- <on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
- </menu_item_call>
- <menu_item_call
- label="Unmute everyone"
- layout="topleft"
- name="ModerateVoiceUnmute">
- <on_click function="Avatar.DoToSelected" parameter="unmute_all" />
- <on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
- </menu_item_call>
- </context_menu>
- <menu_item_separator layout="topleft" name="Group Ban Separator"/>
- <menu_item_call
- label="Ban member"
- layout="topleft"
- name="BanMember">
- <on_click function="Avatar.DoToSelected" parameter="ban_member" />
- <on_enable function="Avatar.EnableItem" parameter="can_ban_member" />
- </menu_item_call>
+ label="Ban member"
+ layout="topleft"
+ name="BanMember">
+ <on_click function="Avatar.DoToSelected" parameter="ban_member" />
+ <on_enable function="Avatar.EnableItem" parameter="can_ban_member" />
+ </menu_item_call>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml
index 97f53d3a17..f85f897700 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml
@@ -53,11 +53,7 @@
function="Inventory.GearDefault.Visible"
parameter="multi_folder_view" />
</menu_item_check>
- <menu_item_separator>
- <menu_item_separator.on_visible
- function="Inventory.GearDefault.Visible"
- parameter="single_folder_view" />
- </menu_item_separator>
+ <menu_item_separator/>
<menu_item_check
label="List view"
layout="topleft"
@@ -100,4 +96,46 @@
function="Inventory.GearDefault.Visible"
parameter="single_folder_view" />
</menu_item_check>
+ <menu_item_check
+ label="Recent tab"
+ layout="topleft"
+ name="recent_tab">
+ <on_click
+ function="Inventory.GearDefault.Custom.Action"
+ parameter="toggle_recent_tab" />
+ <on_check
+ function="Inventory.GearDefault.Check"
+ parameter="recent_tab" />
+ <on_visible
+ function="Inventory.GearDefault.Visible"
+ parameter="multi_folder_view" />
+ </menu_item_check>
+ <menu_item_check
+ label="Worn tab"
+ layout="topleft"
+ name="worn_tab">
+ <on_click
+ function="Inventory.GearDefault.Custom.Action"
+ parameter="toggle_worn_tab" />
+ <on_check
+ function="Inventory.GearDefault.Check"
+ parameter="worn_tab" />
+ <on_visible
+ function="Inventory.GearDefault.Visible"
+ parameter="multi_folder_view" />
+ </menu_item_check>
+ <menu_item_check
+ label="Favorites tab"
+ layout="topleft"
+ name="favorites_tab">
+ <on_click
+ function="Inventory.GearDefault.Custom.Action"
+ parameter="toggle_favorites_tab" />
+ <on_check
+ function="Inventory.GearDefault.Check"
+ parameter="favorites_tab" />
+ <on_visible
+ function="Inventory.GearDefault.Visible"
+ parameter="multi_folder_view" />
+ </menu_item_check>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index f444275878..5335e0f8bd 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -982,7 +982,8 @@
</menu_item_check>
<menu_item_check
label="Midday (Legacy)"
- name="legacy noon">
+ name="legacy noon"
+ shortcut="control|shift|T">
<menu_item_check.on_click
function="World.EnvSettings"
parameter="legacy noon" />
@@ -1014,8 +1015,8 @@
</menu_item_check>
<menu_item_check
label="Use Shared Environment"
- shortcut="control|shift|X"
- name="Use Shared Environment">
+ name="Use Shared Environment"
+ shortcut="control|shift|X">
<menu_item_check.on_click
function="World.EnvSettings"
parameter="region" />
@@ -2695,18 +2696,6 @@ function="World.EnvPreset"
parameter="fast timers" />
</menu_item_check>
<menu_item_check
- label="Memory"
- name="Memory"
- shortcut="control|shift|0"
- use_mac_ctrl="true">
- <menu_item_check.on_check
- function="Advanced.CheckConsole"
- parameter="memory view" />
- <menu_item_check.on_click
- function="Advanced.ToggleConsole"
- parameter="memory view" />
- </menu_item_check>
- <menu_item_check
label="Scene Statistics"
name="Scene Statistics">
<menu_item_check.on_check
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index fe2f1ec1e3..505d00398b 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4436,9 +4436,9 @@ Click OK to install.
</notification>
<notification
- icon="alertmodal.tga"
+ icon="alert.tga"
name="PromptOptionalUpdate"
- type="alertmodal">
+ type="alert">
Version [VERSION] has been downloaded and is ready to install.
Release notes: [URL]
@@ -8596,10 +8596,10 @@ Scripts associated with this experience will be able to do the following on regi
priority="critical"
persist="true"
type="notify">
-Warning: The object &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; wants total access to your Linden Dollars account. If you allow access, it can remove funds from your account at any time, or empty your account completely, on an ongoing basis with no additional warnings.
-
-Do not allow access if you do not fully understand why it wants access to your account.
+Warning:
+[WARNINGS]
+Do not allow access if you do not fully understand why it wants access to your account.
<tag>confirm</tag>
<form name="form">
<button
@@ -8612,9 +8612,7 @@ Do not allow access if you do not fully understand why it wants access to your a
name="Deny"
text="Deny"/>
</form>
- <footer>
-[FOOTERTEXT]
- </footer>
+ <footer>[FOOTERTEXT]</footer>
</notification>
<notification
@@ -9129,6 +9127,14 @@ Failed to save snapshot to [PATH]: Disk is full. [NEED_MEMORY]KB is required but
Failed to save snapshot to [PATH]: Directory does not exist.
</notification>
+ <notification icon="notifytip.tga"
+ name="SnapshotSavedToComputer" type="notifytip">
+Screenshot saved to:
+ [FILEPATH]
+
+Click to open folder.
+ </notification>
+
<notification
icon="notifytip.tga"
name="PresetNotSaved"
@@ -9204,6 +9210,23 @@ Your voice has been muted by moderator.
</notification>
<notification
+ icon="notifytip.tga"
+ name="NearbyVoiceMutedByModerator"
+ type="notifytip">
+ The moderator has muted your voice chat.
+People in this location will not hear you if you speak.
+ <tag>voice</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="NearbyVoiceUnmutedByModerator"
+ type="notifytip">
+ Your voice chat can now be heard by people in this location.
+ <tag>voice</tag>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="FailedToGetBenefits"
type="alertmodal">
@@ -9688,6 +9711,22 @@ Are you sure you want to leave this call?
<notification
icon="alertmodal.tga"
+ name="ConfirmLeaveAdhoc"
+ type="alertmodal">
+Are you sure you want to leave this conference chat?
+ <tag>confirm</tag>
+ <tag>voice</tag>
+ <usetemplate
+ ignoretext="Confirm before I leave conference chat"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes">
+ <unique/>
+ </usetemplate>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ConfirmMuteAll"
type="alert">
You have selected to mute all participants in a group call.
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index aac4037bb3..3428991460 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -86,6 +86,15 @@ Hover your mouse over the options for more help.
name="btn_join"
visible="true"
width="120" />
+ <button
+ follows="left|top"
+ left_pad="6"
+ top_delta="0"
+ height="23"
+ label="Activate"
+ name="btn_activate"
+ visible="true"
+ width="120" />
</panel>
<text_editor
type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml
index bfe738f472..eaf638d35f 100644
--- a/indra/newview/skins/default/xui/en/panel_notification.xml
+++ b/indra/newview/skins/default/xui/en/panel_notification.xml
@@ -49,7 +49,7 @@
embedded_items="false"
enabled="false"
follows="left|right|top|bottom"
- height="85"
+ height="85"
layout="topleft"
left="10"
mouse_opaque="false"
@@ -67,16 +67,16 @@
<panel
background_visible="false"
follows="left|right|bottom"
- height="30"
+ height="30"
width="290"
label="control_panel"
layout="topleft"
left="10"
name="control_panel"
top_pad="5">
- <!--
+ <!--
Notes:
- This panel holds buttons of notification. Change of its size can affect the layout of buttons.
+ This panel holds buttons of notification. Change of its size can affect the layout of buttons.
-->
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index ddddb4855f..08b3ef69b6 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -113,7 +113,7 @@
width="70">
<combo_box.item
enabled="true"
- label="1:00 AM"
+ label="1:00 PM"
name="12H"
value="0" />
<combo_box.item
@@ -295,16 +295,16 @@
tool_tip="Show username, like bobsmith123"
top_delta="0" />
<check_box
- control_name="NameTagShowGroupTitles"
- enabled_control="AvatarNameTagMode"
+ control_name="UseDisplayNames"
+ follows="top|left"
height="16"
- label="Group titles"
+ label="Display names"
layout="topleft"
left="35"
- width="100"
- name="show_all_title_checkbox1"
- tool_tip="Show group titles, like Officer or Member"
- top_pad="3" />
+ name="display_names_check"
+ width="100"
+ tool_tip="Check to use display names in chat, IM, name tags, etc."
+ top_pad="3"/>
<check_box
control_name="NameTagShowFriends"
enabled_control="AvatarNameTagMode"
@@ -313,19 +313,29 @@
layout="topleft"
left_pad="50"
name="show_friends"
- tool_tip="Highlight the name tags of your friends"/>
- <check_box
- control_name="UseDisplayNames"
- follows="top|left"
- height="16"
- label="View Display Names"
- layout="topleft"
- left="35"
- name="display_names_check"
- width="237"
- tool_tip="Check to use display names in chat, IM, name tags, etc."
- top_pad="3"/>
-
+ tool_tip="Highlight the name tags of your friends"/>
+ <combo_box
+ height="23"
+ layout="topleft"
+ control_name="GroupTitlesTagMode"
+ enabled_control="AvatarNameTagMode"
+ left="39"
+ top_pad="3"
+ name="group_title"
+ width="130">
+ <combo_box.item
+ label="No group tags"
+ name="no_tags"
+ value="0" />
+ <combo_box.item
+ label="Only my group tag"
+ name="my_tag"
+ value="1" />
+ <combo_box.item
+ label="All group tags"
+ name="all_tags"
+ value="2" />
+ </combo_box>
<text
type="string"
length="1"
@@ -334,7 +344,7 @@
layout="topleft"
left="30"
name="inworld_typing_rg_label"
- top_pad="1"
+ top_pad="4"
width="400">
Pressing letter keys:
</text>
diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml
index 6ef1b6e44a..47e1e669d1 100644
--- a/indra/newview/skins/default/xui/en/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_general.xml
@@ -33,6 +33,28 @@
unknown
</text>
<text
+ follows="right|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ top_delta="0"
+ right="-100"
+ name="estate_id_lbl"
+ width="80">
+ Estate ID:
+ </text>
+ <line_editor
+ follows="right|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ top_delta="0"
+ name="estate_id"
+ enabled="false"
+ right="-10"
+ initial_value="unknown"
+ width="85" />
+ <text
follows="left|top"
font="SansSerif"
height="20"
@@ -55,6 +77,39 @@
unknown
</text>
<text
+ follows="right|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ top_delta="0"
+ right="-100"
+ name="grid_position_lbl"
+ width="80">
+ Grid Position:
+ </text>
+ <line_editor
+ follows="right|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ right="-55"
+ name="grid_position_x"
+ enabled="false"
+ top_delta="0"
+ default_text="n/a"
+ width="40" />
+ <line_editor
+ follows="right|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ right="-10"
+ name="grid_position_y"
+ enabled="false"
+ top_delta="0"
+ default_text="n/a"
+ width="40" />
+ <text
follows="left|top"
font="SansSerif"
height="20"
diff --git a/indra/newview/skins/default/xui/en/panel_script_question_toast.xml b/indra/newview/skins/default/xui/en/panel_script_question_toast.xml
index 1b1e31165a..9045e6a8ae 100644
--- a/indra/newview/skins/default/xui/en/panel_script_question_toast.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_question_toast.xml
@@ -6,7 +6,7 @@
bg_alpha_color="PanelNotificationBackground"
bg_opaque_color="PanelNotificationBackground"
chrome="true"
- height="270"
+ height="220"
label="script_question_panel"
layout="topleft"
left="0"
@@ -39,9 +39,9 @@
width="285">
</panel>
<text
- follows="all"
+ follows="left|right|top"
font="SansSerifBold"
- height="55"
+ height="15"
layout="topleft"
mouse_opaque="false"
name="bottom_info_message"
diff --git a/indra/newview/skins/default/xui/en/panel_voice_effect.xml b/indra/newview/skins/default/xui/en/panel_voice_effect.xml
deleted file mode 100644
index 42cd510efd..0000000000
--- a/indra/newview/skins/default/xui/en/panel_voice_effect.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel
- follows="all"
- height="26"
- layout="topleft"
- name="panel_voice_effect"
- width="200">
- <string name="no_voice_effect">
- Voice Morphing Off
- </string>
- <string name="preview_voice_effects">
- Preview Voice Morphing ▶
- </string>
- <string name="get_voice_effects">
- Get Voice Morphing ▶
- </string>
- <combo_box
- enabled="false"
- follows="left|top|right"
- height="23"
- name="voice_effect"
- tool_tip="Select a Voice Morph to change your voice"
- top_pad="0"
- width="200">
- <combo_box.item
- label="Voice Morphing Off"
- name="no_voice_effect"
- top_pad="0"
- value="0" />
- <combo_box.commit_callback
- function="Voice.CommitVoiceEffect" />
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index b4b4ac4a86..82dcbf2d30 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -519,6 +519,8 @@ http://secondlife.com/support for help fixing this problem.
<string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string>
<string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS].</string>
<string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS].</string>
+ <string name="ScriptTakeMoneyCaution">The object &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; wants total access to your Linden Dollars account. If you allow access, it can remove funds from your account at any time, or empty your account completely, on an ongoing basis with no additional warnings.</string>
+ <string name="PrivilegedLandAccessCaution">The object &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; wants privileged access to your land. If you allow access it may sell your land with no additional warnings.</string>
<string name="AdditionalPermissionsRequestHeader">If you allow access to your account, you will also be allowing the object to:</string>
<string name="ScriptTakeMoney">Take Linden dollars (L$) from you</string>
<string name="ActOnControlInputs">Act on your control inputs</string>
@@ -536,6 +538,7 @@ http://secondlife.com/support for help fixing this problem.
<string name="ChangeYourDefaultAnimations">Change your default animations</string>
<string name="ForceSitAvatar">Force your avatar to sit</string>
<string name="ChangeEnvSettings">Change your environment settings</string>
+ <string name="PrivilegedLandAccess">Sell land on your behalf.</string>
<string name="NotConnected">Not Connected</string>
<string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name -->
diff --git a/indra/newview/skins/default/xui/es/floater_big_preview.xml b/indra/newview/skins/default/xui/es/floater_big_preview.xml
deleted file mode 100644
index b112243d7a..0000000000
--- a/indra/newview/skins/default/xui/es/floater_big_preview.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_big_preview" title="VISTA PREVIA"/>
diff --git a/indra/newview/skins/default/xui/es/floater_post_process.xml b/indra/newview/skins/default/xui/es/floater_post_process.xml
deleted file mode 100644
index 5c62ccde36..0000000000
--- a/indra/newview/skins/default/xui/es/floater_post_process.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Post-Process Floater" title="CONFIGURACIÓN DEL PROCESAMIENTO">
- <tab_container name="Post-Process Tabs">
- <panel label="Color del filtro" name="wmiColorFilterPanel">
- <check_box label="Activar" name="wmiColorFilterToggle"/>
- <text name="wmiColorFilterBrightnessText">
- Brillo
- </text>
- <text name="wmiColorFilterSaturationText">
- Saturación
- </text>
- <text name="wmiColorFilterContrastText">
- Contraste
- </text>
- <text name="wmiColorFilterBaseText">
- Color base del contraste
- </text>
- <slider label="R" name="wmiColorFilterBaseR"/>
- <slider label="V" name="wmiColorFilterBaseG"/>
- <slider label="A" name="wmiColorFilterBaseB"/>
- <slider label="I" name="wmiColorFilterBaseI"/>
- </panel>
- <panel label="Visión nocturna" name="wmiNightVisionPanel">
- <check_box label="Activar" name="wmiNightVisionToggle"/>
- <text name="wmiNightVisionBrightMultText">
- Amplificación de luz
- </text>
- <text name="wmiNightVisionNoiseSizeText">
- Cantidad de ruido
- </text>
- <text name="wmiNightVisionNoiseStrengthText">
- Intensidad del ruido
- </text>
- </panel>
- <panel label="Bloom" name="wmiBloomPanel">
- <check_box label="Activar" name="wmiBloomToggle"/>
- <text name="wmiBloomExtractText">
- Extracción de la luminosidad
- </text>
- <text name="wmiBloomSizeText">
- Bloom: cantidad
- </text>
- <text name="wmiBloomStrengthText">
- Bloom: intensidad
- </text>
- </panel>
- <panel label="Extras" name="Extras">
- <button label="Cargar efecto" label_selected="Cargar efecto" name="PPLoadEffect"/>
- <button label="Guardar efecto" label_selected="Guardar efecto" name="PPSaveEffect"/>
- <line_editor label="Nombre del efecto" name="PPEffectNameEditor"/>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_sound_devices.xml b/indra/newview/skins/default/xui/es/floater_sound_devices.xml
deleted file mode 100644
index 0291f9e796..0000000000
--- a/indra/newview/skins/default/xui/es/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_sound_devices" title="DISPOSITIVOS DE SONIDO">
- <text name="voice_label">
- Chat de voz
- </text>
- <check_box label="Activados" name="enable_voice"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_voice_effect.xml b/indra/newview/skins/default/xui/es/floater_voice_effect.xml
deleted file mode 100644
index 02ebe80ff7..0000000000
--- a/indra/newview/skins/default/xui/es/floater_voice_effect.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Lugares" name="voice_effects" title="PROBAR TRANSFORMACIÓN DE VOZ">
- <string name="no_voice_effect">
- (Sin transformación de voz)
- </string>
- <string name="active_voice_effect">
- (Activo)
- </string>
- <string name="unsubscribed_voice_effect">
- (Suscripción cancelada)
- </string>
- <string name="new_voice_effect">
- (¡Nuevo!)
- </string>
- <string name="effect_Arena">
- Campo
- </string>
- <string name="effect_Beast">
- Bestia
- </string>
- <string name="effect_Buff">
- Musculoso
- </string>
- <string name="effect_Buzz">
- Murmullo
- </string>
- <string name="effect_Camille">
- Camila
- </string>
- <string name="effect_Creepy">
- Aterrador
- </string>
- <string name="effect_CreepyBot">
- Robot aterrador
- </string>
- <string name="effect_Cyber">
- Cyber
- </string>
- <string name="effect_DeepBot">
- Robot profundo
- </string>
- <string name="effect_Demon">
- Diablo
- </string>
- <string name="effect_Flirty">
- Coqueta
- </string>
- <string name="effect_Foxy">
- Astuto
- </string>
- <string name="effect_Halloween_2010_Bonus">
- Halloween_2010_Bonus
- </string>
- <string name="effect_Helium">
- Helio
- </string>
- <string name="effect_Husky">
- Corpulento
- </string>
- <string name="effect_Intercom">
- Intercom
- </string>
- <string name="effect_Macho">
- Macho
- </string>
- <string name="effect_Micro">
- Micro
- </string>
- <string name="effect_Mini">
- Mini
- </string>
- <string name="effect_Nano">
- Nano
- </string>
- <string name="effect_Nightmare">
- Pesadilla
- </string>
- <string name="effect_PopBot">
- Robot pop
- </string>
- <string name="effect_Rachel">
- Raquel
- </string>
- <string name="effect_Radio">
- Radio
- </string>
- <string name="effect_Robot">
- Robot
- </string>
- <string name="effect_Roxanne">
- Roxana
- </string>
- <string name="effect_Sabrina">
- Sabrina
- </string>
- <string name="effect_Samantha">
- Samanta
- </string>
- <string name="effect_Sexy">
- Sexy
- </string>
- <string name="effect_Shorty">
- Bajito
- </string>
- <string name="effect_Sneaky">
- Furtivo
- </string>
- <string name="effect_Stallion">
- Mujeriego
- </string>
- <string name="effect_Sultry">
- Sensual
- </string>
- <string name="effect_Thunder">
- Trueno
- </string>
- <string name="effect_Vixen">
- Tigresa
- </string>
- <string name="effect_WhinyBot">
- Robot llorica
- </string>
- <text name="preview_text">
- Para probarla
- </text>
- <text name="status_text">
- Graba una muestra y pulsa en una voz para escuchar cómo suena.
- </text>
- <button label="Grabar" name="record_btn" tool_tip="Graba una muestra de tu voz."/>
- <button label="Parar" name="record_stop_btn"/>
- <text name="voice_morphing_link">
- [[URL] Suscríbete ahora]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="Graba una muestra de tu voz y pulsa en un efecto para ver cómo suena.">
- <scroll_list.columns label="Nombre de la voz" name="name"/>
- <scroll_list.columns label="Caduca" name="expires"/>
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/panel_voice_effect.xml b/indra/newview/skins/default/xui/es/panel_voice_effect.xml
deleted file mode 100644
index 94a0428941..0000000000
--- a/indra/newview/skins/default/xui/es/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- Transformación de voz desactivada
- </string>
- <string name="preview_voice_effects">
- Probar transformación de voz ▶
- </string>
- <string name="get_voice_effects">
- Obtener transformación de voz ▶
- </string>
- <combo_box name="voice_effect" tool_tip="Selecciona una transformación de voz para cambiar tu voz">
- <combo_box.item label="Transformación de voz desactivada" name="no_voice_effect"/>
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/fr/floater_big_preview.xml b/indra/newview/skins/default/xui/fr/floater_big_preview.xml
deleted file mode 100644
index 0c09a4c188..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_big_preview.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_big_preview" title="APERÇU"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_post_process.xml b/indra/newview/skins/default/xui/fr/floater_post_process.xml
deleted file mode 100644
index a22c7512e5..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_post_process.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater name="Post-Process Floater" title="PARAMÈTRES POST-TRAITEMENT">
- <tab_container name="Post-Process Tabs">
- <panel label="Filtre couleur" name="wmiColorFilterPanel">
- <check_box label="Activer" name="wmiColorFilterToggle" />
- <text name="wmiColorFilterBrightnessText">
- Luminosité
- </text>
- <text name="wmiColorFilterSaturationText">
- Saturation
- </text>
- <text name="wmiColorFilterContrastText">
- Contraste
- </text>
- <text name="wmiColorFilterBaseText">
- Couleur de base du contraste
- </text>
- <slider label="R" name="wmiColorFilterBaseR" />
- <slider label="V" name="wmiColorFilterBaseG" />
- <slider label="B" name="wmiColorFilterBaseB" />
- <slider label="I" name="wmiColorFilterBaseI" />
- </panel>
- <panel label="Vision de nuit" name="wmiNightVisionPanel">
- <check_box label="Activer" name="wmiNightVisionToggle" />
- <text name="wmiNightVisionBrightMultText">
- Multiple d&apos;amplificateur de lumière
- </text>
- <text name="wmiNightVisionNoiseSizeText">
- Taille du bruit
- </text>
- <text name="wmiNightVisionNoiseStrengthText">
- Force du bruit
- </text>
- </panel>
- <panel label="Éclat" name="wmiBloomPanel">
- <check_box label="Activer" name="wmiBloomToggle" />
- <text name="wmiBloomExtractText">
- Extraction de la luminosité
- </text>
- <text name="wmiBloomSizeText">
- Taille de l&apos;éclat
- </text>
- <text name="wmiBloomStrengthText">
- Force de l&apos;éclat
- </text>
- </panel>
- <panel label="Extras" name="Extras">
- <button label="Charger effet" label_selected="Charger effet" name="PPLoadEffect" />
- <button label="Enregistrer effet" label_selected="Enregistrer effet"
- name="PPSaveEffect" />
- <line_editor label="Nom de l&apos;effet" name="PPEffectNameEditor" />
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_sound_devices.xml b/indra/newview/skins/default/xui/fr/floater_sound_devices.xml
deleted file mode 100644
index 080ade9dd4..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_sound_devices" title="PERIPHERIQUES AUDIO">
- <text name="voice_label">
- Chat vocal
- </text>
- <check_box label="Activé" name="enable_voice"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_voice_effect.xml b/indra/newview/skins/default/xui/fr/floater_voice_effect.xml
deleted file mode 100644
index f9a76d127e..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_voice_effect.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Endroits" name="voice_effects" title="APERÇU DES EFFETS DE VOIX">
- <string name="no_voice_effect">
- (Aucun effet de voix)
- </string>
- <string name="active_voice_effect">
- (Actif)
- </string>
- <string name="unsubscribed_voice_effect">
- (Pas d&apos;abonnement)
- </string>
- <string name="new_voice_effect">
- (Nouveau !)
- </string>
- <string name="effect_Arena">
- Stade
- </string>
- <string name="effect_Beast">
- Brute
- </string>
- <string name="effect_Buff">
- Nasal
- </string>
- <string name="effect_Buzz">
- Friture
- </string>
- <string name="effect_Camille">
- Camille
- </string>
- <string name="effect_Creepy">
- Effrayant
- </string>
- <string name="effect_CreepyBot">
- BotEffrayant
- </string>
- <string name="effect_Cyber">
- Cyber
- </string>
- <string name="effect_DeepBot">
- BotGrave
- </string>
- <string name="effect_Demon">
- Démon
- </string>
- <string name="effect_Female Elf">
- Femme elfe
- </string>
- <string name="effect_Flirty">
- Flirt
- </string>
- <string name="effect_Foxy">
- Séduction
- </string>
- <string name="effect_Halloween 2010 Bonus">
- Halloween_2010_Bonus
- </string>
- <string name="effect_Helium">
- Hélium
- </string>
- <string name="effect_Husky">
- Rauque
- </string>
- <string name="effect_Husky Whisper">
- Murmure rauque
- </string>
- <string name="effect_Intercom">
- Interphone
- </string>
- <string name="effect_Julia">
- Julia
- </string>
- <string name="effect_Lo Lilt">
- Mélodieux
- </string>
- <string name="effect_Macho">
- Macho
- </string>
- <string name="effect_Micro">
- Micro
- </string>
- <string name="effect_Mini">
- Mini
- </string>
- <string name="effect_Model">
- Modèle
- </string>
- <string name="effect_Nano">
- Nano
- </string>
- <string name="effect_Nightmare">
- Cauchemar
- </string>
- <string name="effect_PopBot">
- BotPop
- </string>
- <string name="effect_Rachel">
- Rachel
- </string>
- <string name="effect_Radio">
- Radio
- </string>
- <string name="effect_Robot">
- Robot
- </string>
- <string name="effect_Roxanne">
- Roxanne
- </string>
- <string name="effect_Rumble">
- Grondement
- </string>
- <string name="effect_Sabrina">
- Sabrina
- </string>
- <string name="effect_Samantha">
- Samantha
- </string>
- <string name="effect_Sexy">
- Sexy
- </string>
- <string name="effect_Shorty">
- Petite voix
- </string>
- <string name="effect_Smaller">
- Plus faible
- </string>
- <string name="effect_Sneaky">
- Sournois
- </string>
- <string name="effect_Stallion">
- Étalon
- </string>
- <string name="effect_Sultry">
- Sensuel
- </string>
- <string name="effect_Thunder">
- Tonnerre
- </string>
- <string name="effect_Vixen">
- Mégère
- </string>
- <string name="effect_WhinyBot">
- BotPleurnichard
- </string>
- <text name="preview_text">
- Aperçu
- </text>
- <text name="status_text">
- Enregistrez un extrait et cliquez sur un effet pour obtenir un aperçu.
- </text>
- <button label="Enregistrer" name="record_btn" tool_tip="Enregistrez un extrait de votre voix."/>
- <button label="Arrêter" name="record_stop_btn"/>
- <text name="voice_morphing_link">
- [[URL] S&apos;abonner]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="Enregistrez un extrait de votre voix, puis cliquez sur un effet pour obtenir un aperçu.">
- <scroll_list.columns label="Nom de l&apos;effet" name="name"/>
- <scroll_list.columns label="Date d&apos;expiration" name="expires"/>
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/panel_voice_effect.xml b/indra/newview/skins/default/xui/fr/panel_voice_effect.xml
deleted file mode 100644
index a134854706..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- Effet de voix désactivé
- </string>
- <string name="preview_voice_effects">
- Aperçu des effets de voix ▶
- </string>
- <string name="get_voice_effects">
- Obtenir un effet de voix ▶
- </string>
- <combo_box name="voice_effect" tool_tip="Sélectionner un effet pour modifier le son de votre voix">
- <combo_box.item label="Effet de voix désactivé" name="no_voice_effect"/>
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/it/floater_big_preview.xml b/indra/newview/skins/default/xui/it/floater_big_preview.xml
deleted file mode 100644
index 7bc50a6d39..0000000000
--- a/indra/newview/skins/default/xui/it/floater_big_preview.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_big_preview" title="ANTEPRIMA"/>
diff --git a/indra/newview/skins/default/xui/it/floater_post_process.xml b/indra/newview/skins/default/xui/it/floater_post_process.xml
deleted file mode 100644
index 3aa8b29101..0000000000
--- a/indra/newview/skins/default/xui/it/floater_post_process.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Post-Process Floater" title="IMPOSTAZIONI DI POST-PRODUZIONE">
- <tab_container name="Post-Process Tabs">
- <panel label="Filtro Colore" name="wmiColorFilterPanel">
- <check_box label="Abilita" name="wmiColorFilterToggle"/>
- <text name="wmiColorFilterBrightnessText">
- Luminosità
- </text>
- <text name="wmiColorFilterSaturationText">
- Saturazione
- </text>
- <text name="wmiColorFilterContrastText">
- Contrasto
- </text>
- <text name="wmiColorFilterBaseText">
- Colore Base Contrasto
- </text>
- <slider label="R" name="wmiColorFilterBaseR"/>
- <slider label="G" name="wmiColorFilterBaseG"/>
- <slider label="B" name="wmiColorFilterBaseB"/>
- <slider label="I" name="wmiColorFilterBaseI"/>
- </panel>
- <panel label="Visione Notturna" name="wmiNightVisionPanel">
- <check_box label="Abilita" name="wmiNightVisionToggle"/>
- <text name="wmiNightVisionBrightMultText">
- Amplificazione Multipla Luce
- </text>
- <text name="wmiNightVisionNoiseSizeText">
- Ampiezza disturbo
- </text>
- <text name="wmiNightVisionNoiseStrengthText">
- Forza disturbo
- </text>
- </panel>
- <panel label="Raggiatura" name="wmiBloomPanel">
- <check_box label="Abilita" name="wmiBloomToggle"/>
- <text name="wmiBloomExtractText">
- Estrazione luminosità
- </text>
- <text name="wmiBloomSizeText">
- Dimensione raggiatura
- </text>
- <text name="wmiBloomStrengthText">
- Forza raggiatura
- </text>
- </panel>
- <panel label="Extra" name="Extras">
- <button label="Carica effetto" label_selected="Carica effetto" name="PPLoadEffect"/>
- <button label="Salva effetto" label_selected="Salva effetto" name="PPSaveEffect"/>
- <line_editor label="Nome Effetto" name="PPEffectNameEditor"/>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_sound_devices.xml b/indra/newview/skins/default/xui/it/floater_sound_devices.xml
deleted file mode 100644
index 9799b48d89..0000000000
--- a/indra/newview/skins/default/xui/it/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_sound_devices" title="DISPOSITIVI AUDIO">
- <text name="voice_label">
- Chat vocale
- </text>
- <check_box label="Abilitato" name="enable_voice"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_voice_effect.xml b/indra/newview/skins/default/xui/it/floater_voice_effect.xml
deleted file mode 100644
index f102622f5d..0000000000
--- a/indra/newview/skins/default/xui/it/floater_voice_effect.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Luoghi" name="voice_effects" title="ANTEPRIMA MANIPOLAZIONE VOCE">
- <string name="no_voice_effect">
- (Nessuna manipolazione voce)
- </string>
- <string name="active_voice_effect">
- (Attivato)
- </string>
- <string name="unsubscribed_voice_effect">
- (Iscrizione annullata)
- </string>
- <string name="new_voice_effect">
- (Nuovo!)
- </string>
- <string name="effect_Arena">
- Arena
- </string>
- <string name="effect_Beast">
- Bestia
- </string>
- <string name="effect_Buff">
- Appassionato
- </string>
- <string name="effect_Buzz">
- Euforia
- </string>
- <string name="effect_Camille">
- Camilla
- </string>
- <string name="effect_Creepy">
- Terrificante
- </string>
- <string name="effect_CreepyBot">
- TerrificanteBot
- </string>
- <string name="effect_Cyber">
- Cyber
- </string>
- <string name="effect_DeepBot">
- ProfondoBot
- </string>
- <string name="effect_Demon">
- Demonio
- </string>
- <string name="effect_Female Elf">
- Elfo donna
- </string>
- <string name="effect_Flirty">
- Civettuolo
- </string>
- <string name="effect_Foxy">
- Scaltro
- </string>
- <string name="effect_Halloween 2010 Bonus">
- Halloween_2010_Bonus
- </string>
- <string name="effect_Helium">
- Elio
- </string>
- <string name="effect_Husky">
- Fusto
- </string>
- <string name="effect_Husky Whisper">
- Sospiro rauco
- </string>
- <string name="effect_Intercom">
- Interfono
- </string>
- <string name="effect_Julia">
- Julia
- </string>
- <string name="effect_Lo Lilt">
- Inflessione bassa
- </string>
- <string name="effect_Macho">
- Macho
- </string>
- <string name="effect_Micro">
- Micro
- </string>
- <string name="effect_Mini">
- Mini
- </string>
- <string name="effect_Model">
- Modella
- </string>
- <string name="effect_Nano">
- Nano
- </string>
- <string name="effect_Nightmare">
- Incubo
- </string>
- <string name="effect_PopBot">
- PopBot
- </string>
- <string name="effect_Rachel">
- Rachele
- </string>
- <string name="effect_Radio">
- Radio
- </string>
- <string name="effect_Robot">
- Robot
- </string>
- <string name="effect_Roxanne">
- Rosanna
- </string>
- <string name="effect_Rumble">
- Rombo
- </string>
- <string name="effect_Sabrina">
- Sabrina
- </string>
- <string name="effect_Samantha">
- Samanta
- </string>
- <string name="effect_Sexy">
- Sexy
- </string>
- <string name="effect_Shorty">
- Bassotto
- </string>
- <string name="effect_Smaller">
- Più piccolo
- </string>
- <string name="effect_Sneaky">
- Vile
- </string>
- <string name="effect_Stallion">
- Stallone
- </string>
- <string name="effect_Sultry">
- Focoso
- </string>
- <string name="effect_Thunder">
- Tuono
- </string>
- <string name="effect_Vixen">
- Maliziosa
- </string>
- <string name="effect_WhinyBot">
- PiangiBot
- </string>
- <text name="preview_text">
- Per l&apos;anteprima
- </text>
- <text name="status_text">
- Registra un campione di voce, quindi fai clic su un effetto per ascoltare il risultato.
- </text>
- <button label="Registra" name="record_btn" tool_tip="Registra un campione della tua voce."/>
- <button label="Ferma" name="record_stop_btn"/>
- <text name="voice_morphing_link">
- [[URL] Subscribe Now]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="Registra un campione della tua voce, quindi fai clic su uno degli effetti per un&apos;anteprima del risultato.">
- <scroll_list.columns label="Nome effetto" name="name"/>
- <scroll_list.columns label="Scade il" name="expires"/>
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/panel_voice_effect.xml b/indra/newview/skins/default/xui/it/panel_voice_effect.xml
deleted file mode 100644
index b43f766e5e..0000000000
--- a/indra/newview/skins/default/xui/it/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- Disattiva manipolazione voce
- </string>
- <string name="preview_voice_effects">
- Anteprima manipolazione voce ▶
- </string>
- <string name="get_voice_effects">
- Ottieni manipolazione voce ▶
- </string>
- <combo_box name="voice_effect" tool_tip="Scegli un effetto di manipolazione per modificare il suono della tua voce">
- <combo_box.item label="Disattiva manipolazione voce" name="no_voice_effect"/>
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/ja/floater_big_preview.xml b/indra/newview/skins/default/xui/ja/floater_big_preview.xml
deleted file mode 100644
index e88d6fc488..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_big_preview.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_big_preview" title="プレビュー"/> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/ja/floater_post_process.xml b/indra/newview/skins/default/xui/ja/floater_post_process.xml
deleted file mode 100644
index 91ecbb73a2..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_post_process.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Post-Process Floater" title="ポストプロセス設定">
- <tab_container name="Post-Process Tabs">
- <panel label="カラー・フィルタ" name="wmiColorFilterPanel">
- <check_box label="有効" name="wmiColorFilterToggle"/>
- <text name="wmiColorFilterBrightnessText">
- 明度
- </text>
- <text name="wmiColorFilterSaturationText">
- 彩度
- </text>
- <text name="wmiColorFilterContrastText">
- 輝度
- </text>
- <text name="wmiColorFilterBaseText">
- 輝度の基準色
- </text>
- <slider label="赤" name="wmiColorFilterBaseR"/>
- <slider label="緑" name="wmiColorFilterBaseG"/>
- <slider label="青" name="wmiColorFilterBaseB"/>
- <slider label="I" name="wmiColorFilterBaseI"/>
- </panel>
- <panel label="暗視" name="wmiNightVisionPanel">
- <check_box label="有効" name="wmiNightVisionToggle"/>
- <text name="wmiNightVisionBrightMultText">
- 光の増幅(マルチ)
- </text>
- <text name="wmiNightVisionNoiseSizeText">
- ノイズ・サイズ
- </text>
- <text name="wmiNightVisionNoiseStrengthText">
- ノイズ強度
- </text>
- </panel>
- <panel label="ブルーム" name="wmiBloomPanel">
- <check_box label="有効" name="wmiBloomToggle"/>
- <text name="wmiBloomExtractText">
- 明度の抽出
- </text>
- <text name="wmiBloomSizeText">
- ブルーム・サイズ
- </text>
- <text name="wmiBloomStrengthText">
- ブルーム強度
- </text>
- </panel>
- <panel label="その他" name="Extras">
- <button label="効果読み込み" label_selected="効果読み込み" name="PPLoadEffect"/>
- <button label="効果保存" label_selected="効果保存" name="PPSaveEffect"/>
- <line_editor label="効果名" name="PPEffectNameEditor"/>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_sound_devices.xml b/indra/newview/skins/default/xui/ja/floater_sound_devices.xml
deleted file mode 100644
index 28d2388bed..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_sound_devices" title="サウンドデバイス">
- <text name="voice_label">
- ボイスチャット
- </text>
- <check_box label="有効" name="enable_voice"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_voice_effect.xml b/indra/newview/skins/default/xui/ja/floater_voice_effect.xml
deleted file mode 100644
index b38ea9331a..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_voice_effect.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="場所" name="voice_effects" title="ボイスモーフィングのプレビュー">
- <string name="no_voice_effect">
- (ボイスモーフィングなし)
- </string>
- <string name="active_voice_effect">
- (アクティブ)
- </string>
- <string name="unsubscribed_voice_effect">
- (取消し済み)
- </string>
- <string name="new_voice_effect">
- (新登場!)
- </string>
- <string name="effect_Arena">
- アリーナ
- </string>
- <string name="effect_Beast">
- 野獣
- </string>
- <string name="effect_Buff">
- がっしり
- </string>
- <string name="effect_Buzz">
- ブザー
- </string>
- <string name="effect_Camille">
- カミール
- </string>
- <string name="effect_Creepy">
- 気味の悪い
- </string>
- <string name="effect_CreepyBot">
- 気味わるボット
- </string>
- <string name="effect_Cyber">
- サイバー
- </string>
- <string name="effect_DeepBot">
- ディープボット
- </string>
- <string name="effect_Demon">
- デーモン
- </string>
- <string name="effect_Female Elf">
- 女性のエルフ
- </string>
- <string name="effect_Flirty">
- 気のありそうな
- </string>
- <string name="effect_Foxy">
- 魅惑的
- </string>
- <string name="effect_Halloween 2010 Bonus">
- ハロウィン_2010_ボーナス
- </string>
- <string name="effect_Helium">
- ヘリウム
- </string>
- <string name="effect_Husky">
- ハスキー
- </string>
- <string name="effect_Husky Whisper">
- スモーキーウィスパー
- </string>
- <string name="effect_Intercom">
- インターホン
- </string>
- <string name="effect_Julia">
- ジュリア
- </string>
- <string name="effect_Lo Lilt">
- 軽快
- </string>
- <string name="effect_Macho">
- マッチョ
- </string>
- <string name="effect_Micro">
- ミクロ
- </string>
- <string name="effect_Mini">
- ミニ
- </string>
- <string name="effect_Model">
- モデル
- </string>
- <string name="effect_Nano">
- ナノ
- </string>
- <string name="effect_Nightmare">
- 悪夢
- </string>
- <string name="effect_PopBot">
- ポップボット
- </string>
- <string name="effect_Rachel">
- レイチェル
- </string>
- <string name="effect_Radio">
- ラジオ
- </string>
- <string name="effect_Robot">
- ロボット
- </string>
- <string name="effect_Roxanne">
- ロクサン
- </string>
- <string name="effect_Rumble">
- ランブル
- </string>
- <string name="effect_Sabrina">
- サブリナ
- </string>
- <string name="effect_Samantha">
- サマンサ
- </string>
- <string name="effect_Sexy">
- セクシー
- </string>
- <string name="effect_Shorty">
- チビ
- </string>
- <string name="effect_Smaller">
- 小さめ
- </string>
- <string name="effect_Sneaky">
- コソコソ
- </string>
- <string name="effect_Stallion">
- 雄馬
- </string>
- <string name="effect_Sultry">
- 艶かしい
- </string>
- <string name="effect_Thunder">
- サンダー
- </string>
- <string name="effect_Vixen">
- 性悪な
- </string>
- <string name="effect_WhinyBot">
- 不機嫌ボット
- </string>
- <text name="preview_text">
- プレビュー
- </text>
- <text name="status_text">
- 声をテスト録音してからボイスエフェクトを1つクリックして聞いてみます。
- </text>
- <button label="録音" name="record_btn" tool_tip="あなたの声を録音します。"/>
- <button label="停止" name="record_stop_btn"/>
- <text name="voice_morphing_link">
- [[URL] 今すぐ申し込む]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="声を録音してボイスモーフィングを1つクリックすると、そのエフェクトをプレビューできます。">
- <scroll_list.columns label="ボイス名" name="name"/>
- <scroll_list.columns label="有効期限" name="expires"/>
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/panel_voice_effect.xml b/indra/newview/skins/default/xui/ja/panel_voice_effect.xml
deleted file mode 100644
index 57a1bb7838..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- ボイスモーフィングなし
- </string>
- <string name="preview_voice_effects">
- ボイスモーフィングをプレビュー
- </string>
- <string name="get_voice_effects">
- ボイスモーフィングを取得
- </string>
- <combo_box name="voice_effect" tool_tip="ボイスモーフィングを選択してボイスを変更">
- <combo_box.item label="ボイスモーフィングなし" name="no_voice_effect"/>
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/pl/floater_big_preview.xml b/indra/newview/skins/default/xui/pl/floater_big_preview.xml
deleted file mode 100644
index e730cff618..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_big_preview.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<floater name="floater_big_preview" title="PODGLĄD" />
diff --git a/indra/newview/skins/default/xui/pl/floater_post_process.xml b/indra/newview/skins/default/xui/pl/floater_post_process.xml
deleted file mode 100644
index 47c40d2315..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_post_process.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater name="Post-Process Floater" title="USTAWIENIA PRZETWARZANIA KOŃCOWEGO">
- <tab_container name="Post-Process Tabs">
- <panel label="Filtr koloru" name="wmiColorFilterPanel">
- <check_box label="Włącz" name="wmiColorFilterToggle" />
- <text name="wmiColorFilterBrightnessText">
- Jasność
- </text>
- <text name="wmiColorFilterSaturationText">
- Nasycenie
- </text>
- <text name="wmiColorFilterContrastText">
- Kontrast
- </text>
- <text name="wmiColorFilterBaseText">
- Kontrast koloru podstawowego
- </text>
- </panel>
- <panel label="Noktowizja" name="wmiNightVisionPanel">
- <check_box label="Włącz" name="wmiNightVisionToggle" />
- <text name="wmiNightVisionBrightMultText">
- Wielokrotne wzmocnienie światła
- </text>
- <text name="wmiNightVisionNoiseSizeText">
- Rozmiar szumu
- </text>
- <text name="wmiNightVisionNoiseStrengthText">
- Moc szumu
- </text>
- </panel>
- <panel label="Poświata" name="wmiBloomPanel">
- <check_box label="Włącz" name="wmiBloomToggle" />
- <text name="wmiBloomExtractText">
- Ekstracja luminacji
- </text>
- <text name="wmiBloomSizeText">
- Rozmiar poświaty
- </text>
- <text name="wmiBloomStrengthText">
- Moc poświaty
- </text>
- </panel>
- <panel label="Dodatki" name="Extras">
- <button label="Wczytaj efekt" label_selected="Wczytaj efekt" name="PPLoadEffect" />
- <button label="Zapisz efekt" label_selected="Zapisz efekt" name="PPSaveEffect" />
- <line_editor label="Nazwa efektu" name="PPEffectNameEditor" />
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/pl/floater_sound_devices.xml b/indra/newview/skins/default/xui/pl/floater_sound_devices.xml
deleted file mode 100644
index 93a27f68a7..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater name="floater_sound_devices" title="URZĄDZENIA DŹWIĘKOWE">
- <text name="voice_label">
- Czat głos.
- </text>
- <check_box name="enable_voice" label="Włączone" />
-</floater>
diff --git a/indra/newview/skins/default/xui/pl/floater_voice_effect.xml b/indra/newview/skins/default/xui/pl/floater_voice_effect.xml
deleted file mode 100644
index b02266caa9..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_voice_effect.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater name="voice_effects" title="PODGLĄD PRZEKSZTAŁCANIA GŁOSU" label="Miejsca">
- <string name="no_voice_effect">
- (Bez Przekształcania)
- </string>
- <string name="active_voice_effect">
- (Aktywny)
- </string>
- <string name="unsubscribed_voice_effect">
- (Bez subskrybcji)
- </string>
- <string name="new_voice_effect">
- (Nowy!)
- </string>
- <string name="effect_Beast">
- Bestia
- </string>
- <string name="effect_Buzz">
- Brzęczenie
- </string>
- <string name="effect_Creepy">
- Przerażający
- </string>
- <string name="effect_Cyber">
- Cybernetyczny
- </string>
- <string name="effect_Female Elf">
- Kobiecy Elf
- </string>
- <string name="effect_Flirty">
- Flirt
- </string>
- <string name="effect_Foxy">
- Ponętny
- </string>
- <string name="effect_Helium">
- Hel
- </string>
- <string name="effect_Husky Whisper">
- Szept Husky
- </string>
- <string name="effect_Macho">
- Maczo
- </string>
- <string name="effect_Micro">
- Mikrus
- </string>
- <string name="effect_Mini">
- Miniaturowy
- </string>
- <string name="effect_Nano">
- Malutki
- </string>
- <string name="effect_Nightmare">
- Koszmar
- </string>
- <string name="effect_Rumble">
- Burczenie
- </string>
- <string name="effect_Sexy">
- Seksowny
- </string>
- <string name="effect_Shorty">
- Krótki
- </string>
- <string name="effect_Smaller">
- Mniejszy
- </string>
- <string name="effect_Sneaky">
- Podstępny
- </string>
- <string name="effect_Stallion">
- Ogier
- </string>
- <string name="effect_Sultry">
- Gorąco
- </string>
- <string name="effect_Thunder">
- Grzmot
- </string>
- <string name="effect_Vixen">
- Lisica
- </string>
- <text name="preview_text">
- Podgląd
- </text>
- <text name="status_text">
- Nagraj próbkę, a następnie kliknij na głos aby usłyszeć jego brzmienie.
- </text>
- <button label="Nagraj" name="record_btn" tool_tip="Nagraj próbkę swojego głosu." />
- <text name="voice_morphing_link">
- [[URL] Subskrybuj teraz]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="Nagraj próbkę swojego głosu, a następnie kliknij na efekt aby odsłuchać podgląd.">
- <scroll_list.columns label="Nazwa głosu" name="name" />
- <scroll_list.columns label="Wygasa" name="expires" />
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/pl/panel_voice_effect.xml b/indra/newview/skins/default/xui/pl/panel_voice_effect.xml
deleted file mode 100644
index 94878943a1..0000000000
--- a/indra/newview/skins/default/xui/pl/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- Wyłącz Przekształcanie
- </string>
- <string name="preview_voice_effects">
- Przeglądaj Przekształcania ▶
- </string>
- <string name="get_voice_effects">
- Uzyskaj Przekształcanie ▶
- </string>
- <combo_box name="voice_effect" tool_tip="Wybierz odpowienie Przekształcanie Głosu, aby zmienić brzmienie swojego głosu">
- <combo_box.item label="Wyłącz Przekształcanie" name="no_voice_effect" />
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/pt/floater_big_preview.xml b/indra/newview/skins/default/xui/pt/floater_big_preview.xml
deleted file mode 100644
index 76ca176689..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_big_preview.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_big_preview" title="VISUALIZAR"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_post_process.xml b/indra/newview/skins/default/xui/pt/floater_post_process.xml
deleted file mode 100644
index d4f2e96539..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_post_process.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Post-Process Floater" title="AJUSTES DE PÓS-PROCESSAMENTO">
- <tab_container name="Post-Process Tabs">
- <panel label="Filtro de Cor" name="wmiColorFilterPanel">
- <check_box label="Habilitar" name="wmiColorFilterToggle"/>
- <text name="wmiColorFilterBrightnessText">
- Brilho
- </text>
- <text name="wmiColorFilterSaturationText">
- Saturação
- </text>
- <text name="wmiColorFilterContrastText">
- Contraste
- </text>
- <text name="wmiColorFilterBaseText">
- Cor Base do Contraste
- </text>
- <slider label="R" name="wmiColorFilterBaseR"/>
- <slider label="G" name="wmiColorFilterBaseG"/>
- <slider label="B" name="wmiColorFilterBaseB"/>
- <slider label="I" name="wmiColorFilterBaseI"/>
- </panel>
- <panel label="visão Noturna" name="wmiNightVisionPanel">
- <check_box label="Habilitar" name="wmiNightVisionToggle"/>
- <text name="wmiNightVisionBrightMultText">
- Múltiplo de Amplificação de Luz
- </text>
- <text name="wmiNightVisionNoiseSizeText">
- Tamanho de Ruído
- </text>
- <text name="wmiNightVisionNoiseStrengthText">
- Intensidade de Ruído
- </text>
- </panel>
- <panel label="Florescência" name="wmiBloomPanel">
- <check_box label="Habilitar" name="wmiBloomToggle"/>
- <text name="wmiBloomExtractText">
- Extração de Luminosidade
- </text>
- <text name="wmiBloomSizeText">
- Tamanho da florescência
- </text>
- <text name="wmiBloomStrengthText">
- Inensidade da florescência
- </text>
- </panel>
- <panel label="Extras" name="Extras">
- <button label="CarregaEfeito" label_selected="CarregaEfeito" name="PPLoadEffect"/>
- <button label="SalvaEfeito" label_selected="SalvaEfeito" name="PPSaveEffect"/>
- <line_editor label="Nome do Efeito" name="PPEffectNameEditor"/>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_sound_devices.xml b/indra/newview/skins/default/xui/pt/floater_sound_devices.xml
deleted file mode 100644
index 948d727540..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_sound_devices" title="DISPOSITIVOS DE SOM">
- <text name="voice_label">
- Bate-papo de voz
- </text>
- <check_box label="Ativado" name="enable_voice"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_voice_effect.xml b/indra/newview/skins/default/xui/pt/floater_voice_effect.xml
deleted file mode 100644
index 71d3c33ae5..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_voice_effect.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Lugares" name="voice_effects" title="AMOSTRA DE DISTORÇÃO DE VOZ">
- <string name="no_voice_effect">
- (Não distorcer voz)
- </string>
- <string name="active_voice_effect">
- (Ativo)
- </string>
- <string name="unsubscribed_voice_effect">
- (Cancelou)
- </string>
- <string name="new_voice_effect">
- (Novo!)
- </string>
- <string name="effect_Arena">
- Arena
- </string>
- <string name="effect_Beast">
- Fera
- </string>
- <string name="effect_Buff">
- Entusiasmado
- </string>
- <string name="effect_Buzz">
- Zumbido
- </string>
- <string name="effect_Camille">
- Camille
- </string>
- <string name="effect_Creepy">
- Assustador
- </string>
- <string name="effect_CreepyBot">
- RobôAssustador
- </string>
- <string name="effect_Cyber">
- Cyber
- </string>
- <string name="effect_DeepBot">
- RobôVozGrossa
- </string>
- <string name="effect_Demon">
- Demônio
- </string>
- <string name="effect_Female Elf">
- Elfa
- </string>
- <string name="effect_Flirty">
- Paquerador
- </string>
- <string name="effect_Foxy">
- Sensual
- </string>
- <string name="effect_Halloween 2010 Bonus">
- Bônus_Halloween_2010
- </string>
- <string name="effect_Helium">
- Hélio
- </string>
- <string name="effect_Husky">
- Rouco
- </string>
- <string name="effect_Husky Whisper">
- Sussurro rouco
- </string>
- <string name="effect_Intercom">
- Interfone
- </string>
- <string name="effect_Julia">
- Julia
- </string>
- <string name="effect_Lo Lilt">
- Cantarolado baixo
- </string>
- <string name="effect_Macho">
- Macho
- </string>
- <string name="effect_Micro">
- Micro
- </string>
- <string name="effect_Mini">
- Mini
- </string>
- <string name="effect_Model">
- Modelo
- </string>
- <string name="effect_Nano">
- Nano
- </string>
- <string name="effect_Nightmare">
- Pesadelo
- </string>
- <string name="effect_PopBot">
- RobôPop
- </string>
- <string name="effect_Rachel">
- Rachel
- </string>
- <string name="effect_Radio">
- Rádio
- </string>
- <string name="effect_Robot">
- Robô
- </string>
- <string name="effect_Roxanne">
- Roxanne
- </string>
- <string name="effect_Rumble">
- Ronco
- </string>
- <string name="effect_Sabrina">
- Sabrina
- </string>
- <string name="effect_Samantha">
- Samantha
- </string>
- <string name="effect_Sexy">
- Sexy
- </string>
- <string name="effect_Shorty">
- Baixinho
- </string>
- <string name="effect_Smaller">
- Menor
- </string>
- <string name="effect_Sneaky">
- Sorrateiro
- </string>
- <string name="effect_Stallion">
- Garanhão
- </string>
- <string name="effect_Sultry">
- Ardente
- </string>
- <string name="effect_Thunder">
- Trovão
- </string>
- <string name="effect_Vixen">
- Maliciosa
- </string>
- <string name="effect_WhinyBot">
- RobôReclamão
- </string>
- <text name="preview_text">
- Visualizar
- </text>
- <text name="status_text">
- Grave uma amostra da sua voz, depois clique em um efeito para ouvir o resultado.
- </text>
- <button label="Gravar" name="record_btn" tool_tip="Grave uma amostra da sua voz."/>
- <button label="Parar" name="record_stop_btn"/>
- <text name="voice_morphing_link">
- [[URL] Assine agora]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="Grave sua voz por alguns instantes, depois clique num efeito para ouvir a distorção.">
- <scroll_list.columns label="Nome da voz" name="name"/>
- <scroll_list.columns label="Vence em" name="expires"/>
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/panel_voice_effect.xml b/indra/newview/skins/default/xui/pt/panel_voice_effect.xml
deleted file mode 100644
index 1d7878408a..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- Distorção de voz desligada
- </string>
- <string name="preview_voice_effects">
- Checar distorção de voz ▶
- </string>
- <string name="get_voice_effects">
- Distorcer voz ▶
- </string>
- <combo_box name="voice_effect" tool_tip="Selecione um efeito de distorção para mudar sua voz.">
- <combo_box.item label="Distorção de voz desligada" name="no_voice_effect"/>
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/ru/floater_big_preview.xml b/indra/newview/skins/default/xui/ru/floater_big_preview.xml
deleted file mode 100644
index cdacebadef..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_big_preview.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_big_preview" title="ПРОСМОТР"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_post_process.xml b/indra/newview/skins/default/xui/ru/floater_post_process.xml
deleted file mode 100644
index ae97670548..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_post_process.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Post-Process Floater" title="НАСТРОЙКИ ПОСЛЕДУЮЩЕЙ ОБРАБОТКИ">
- <tab_container name="Post-Process Tabs">
- <panel label="Цветовой фильтр" name="wmiColorFilterPanel">
- <check_box label="Вкл." name="wmiColorFilterToggle"/>
- <text name="wmiColorFilterBrightnessText">
- Яркость
- </text>
- <text name="wmiColorFilterSaturationText">
- Насыщенность
- </text>
- <text name="wmiColorFilterContrastText">
- Контрастность
- </text>
- <text name="wmiColorFilterBaseText">
- Основной цвет контрастности
- </text>
- <slider label="К" name="wmiColorFilterBaseR"/>
- <slider label="З" name="wmiColorFilterBaseG"/>
- <slider label="С" name="wmiColorFilterBaseB"/>
- <slider label="И" name="wmiColorFilterBaseI"/>
- </panel>
- <panel label="Ночное видение" name="wmiNightVisionPanel">
- <check_box label="Вкл." name="wmiNightVisionToggle"/>
- <text name="wmiNightVisionBrightMultText">
- Коэффициент усиления света
- </text>
- <text name="wmiNightVisionNoiseSizeText">
- Размер искажений
- </text>
- <text name="wmiNightVisionNoiseStrengthText">
- Мощность искажений
- </text>
- </panel>
- <panel label="Ореол" name="wmiBloomPanel">
- <check_box label="Вкл." name="wmiBloomToggle"/>
- <text name="wmiBloomExtractText">
- Яркость света
- </text>
- <text name="wmiBloomSizeText">
- Размер ореола
- </text>
- <text name="wmiBloomStrengthText">
- Мощность ореола
- </text>
- </panel>
- <panel label="Дополнительно" name="Extras">
- <button label="Загрузить эффект" label_selected="Загрузить эффект" name="PPLoadEffect"/>
- <button label="Сохранить эффект" label_selected="Сохранить эффект" name="PPSaveEffect"/>
- <line_editor label="Название эффекта" name="PPEffectNameEditor"/>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_sound_devices.xml b/indra/newview/skins/default/xui/ru/floater_sound_devices.xml
deleted file mode 100644
index fc8de858cd..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_sound_devices" title="ЗВУКОВЫЕ УСТРОЙСТВА">
- <text name="voice_label">
- Голосовой чат
- </text>
- <check_box label="Включен" name="enable_voice"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_voice_effect.xml b/indra/newview/skins/default/xui/ru/floater_voice_effect.xml
deleted file mode 100644
index d3cef042a3..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_voice_effect.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Места" name="voice_effects" title="ПРОСМОТР ИЗМЕНЕНИЯ ГОЛОСА">
- <string name="no_voice_effect">
- (Нет изменения голоса)
- </string>
- <string name="active_voice_effect">
- (Активно)
- </string>
- <string name="unsubscribed_voice_effect">
- (Нет подписки)
- </string>
- <string name="new_voice_effect">
- (Новый!)
- </string>
- <string name="effect_Arena">
- Arena
- </string>
- <string name="effect_Beast">
- Beast
- </string>
- <string name="effect_Buff">
- Buff
- </string>
- <string name="effect_Buzz">
- Buzz
- </string>
- <string name="effect_Camille">
- Camille
- </string>
- <string name="effect_Creepy">
- Creepy
- </string>
- <string name="effect_CreepyBot">
- CreepyBot
- </string>
- <string name="effect_Cyber">
- Cyber
- </string>
- <string name="effect_DeepBot">
- DeepBot
- </string>
- <string name="effect_Demon">
- Demon
- </string>
- <string name="effect_Female Elf">
- Фея
- </string>
- <string name="effect_Flirty">
- Flirty
- </string>
- <string name="effect_Foxy">
- Foxy
- </string>
- <string name="effect_Halloween 2010 Bonus">
- Бонус_за_Хэллоуин_2010
- </string>
- <string name="effect_Helium">
- Helium
- </string>
- <string name="effect_Husky">
- Husky
- </string>
- <string name="effect_Husky Whisper">
- Хриплый шепот
- </string>
- <string name="effect_Intercom">
- Внутренняя связь
- </string>
- <string name="effect_Julia">
- Julia
- </string>
- <string name="effect_Lo Lilt">
- Напев
- </string>
- <string name="effect_Macho">
- Macho
- </string>
- <string name="effect_Micro">
- Micro
- </string>
- <string name="effect_Mini">
- Mini
- </string>
- <string name="effect_Model">
- Модель
- </string>
- <string name="effect_Nano">
- Nano
- </string>
- <string name="effect_Nightmare">
- Nightmare
- </string>
- <string name="effect_PopBot">
- PopBot
- </string>
- <string name="effect_Rachel">
- Rachel
- </string>
- <string name="effect_Radio">
- Radio
- </string>
- <string name="effect_Robot">
- Robot
- </string>
- <string name="effect_Roxanne">
- Roxanne
- </string>
- <string name="effect_Rumble">
- Урчание
- </string>
- <string name="effect_Sabrina">
- Sabrina
- </string>
- <string name="effect_Samantha">
- Samantha
- </string>
- <string name="effect_Sexy">
- Sexy
- </string>
- <string name="effect_Shorty">
- Shorty
- </string>
- <string name="effect_Smaller">
- Меньше
- </string>
- <string name="effect_Sneaky">
- Sneaky
- </string>
- <string name="effect_Stallion">
- Stallion
- </string>
- <string name="effect_Sultry">
- Sultry
- </string>
- <string name="effect_Thunder">
- Thunder
- </string>
- <string name="effect_Vixen">
- Vixen
- </string>
- <string name="effect_WhinyBot">
- WhinyBot
- </string>
- <text name="preview_text">
- Прослушивание
- </text>
- <text name="status_text">
- Запишите образец, затем щелкните, чтобы услышать, как будет звучать голос.
- </text>
- <button label="Запись" name="record_btn" tool_tip="Записать образец вашего голоса."/>
- <button label="Стоп" name="record_stop_btn"/>
- <text name="voice_morphing_link">
- [[URL] Подписаться]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="Запишите образец вашего голоса, затем щелкните, чтобы прослушать эффект.">
- <scroll_list.columns label="Название голоса" name="name"/>
- <scroll_list.columns label="Истекает" name="expires"/>
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/panel_voice_effect.xml b/indra/newview/skins/default/xui/ru/panel_voice_effect.xml
deleted file mode 100644
index de0b38198f..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- Изменение голоса отключено
- </string>
- <string name="preview_voice_effects">
- Прослушать изменение голоса ▶
- </string>
- <string name="get_voice_effects">
- Приобрести изменение голоса ▶
- </string>
- <combo_box name="voice_effect" tool_tip="Выбор типа изменения для своего голоса">
- <combo_box.item label="Изменение голоса отключено" name="no_voice_effect"/>
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/tr/floater_big_preview.xml b/indra/newview/skins/default/xui/tr/floater_big_preview.xml
deleted file mode 100644
index c99a71d3c2..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_big_preview.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_big_preview" title="ÖNİZLEME"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_post_process.xml b/indra/newview/skins/default/xui/tr/floater_post_process.xml
deleted file mode 100644
index 5e419f8ffa..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_post_process.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Post-Process Floater" title="İŞLEM SONRASI AYARLARI">
- <tab_container name="Post-Process Tabs">
- <panel label="Renk Filtresi" name="wmiColorFilterPanel">
- <check_box label="Etkinleştir" name="wmiColorFilterToggle"/>
- <text name="wmiColorFilterBrightnessText">
- Parlaklık
- </text>
- <text name="wmiColorFilterSaturationText">
- Doygunluk
- </text>
- <text name="wmiColorFilterContrastText">
- Kontrast
- </text>
- <text name="wmiColorFilterBaseText">
- Kontrast Baz Rengi
- </text>
- <slider label="R" name="wmiColorFilterBaseR"/>
- <slider label="G" name="wmiColorFilterBaseG"/>
- <slider label="B" name="wmiColorFilterBaseB"/>
- <slider label="I" name="wmiColorFilterBaseI"/>
- </panel>
- <panel label="Gece Görüşü" name="wmiNightVisionPanel">
- <check_box label="Etkinleştir" name="wmiNightVisionToggle"/>
- <text name="wmiNightVisionBrightMultText">
- Işık Yükseltme Çarpanı
- </text>
- <text name="wmiNightVisionNoiseSizeText">
- Gürültü Büyüklüğü
- </text>
- <text name="wmiNightVisionNoiseStrengthText">
- Gürültü Gücü
- </text>
- </panel>
- <panel label="Işıma" name="wmiBloomPanel">
- <check_box label="Etkinleştir" name="wmiBloomToggle"/>
- <text name="wmiBloomExtractText">
- Parlaklık Çıkarma
- </text>
- <text name="wmiBloomSizeText">
- Işıma Büyüklüğü
- </text>
- <text name="wmiBloomStrengthText">
- Işıma Gücü
- </text>
- </panel>
- <panel label="Ekstralar" name="Extras">
- <button label="EfektYükle" label_selected="EfektYükle" name="PPLoadEffect"/>
- <button label="EfektKaydet" label_selected="EfektKaydet" name="PPSaveEffect"/>
- <line_editor label="Efekt Adı" name="PPEffectNameEditor"/>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_sound_devices.xml b/indra/newview/skins/default/xui/tr/floater_sound_devices.xml
deleted file mode 100644
index 470a222d7e..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_sound_devices" title="SES CİHAZLARI">
- <text name="voice_label">
- Sesli Sohbet
- </text>
- <check_box label="Etkin" name="enable_voice"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_voice_effect.xml b/indra/newview/skins/default/xui/tr/floater_voice_effect.xml
deleted file mode 100644
index 7a157244cd..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_voice_effect.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Yerler" name="voice_effects" title="SES ŞEKİLLENDİRME ÖNİZLEMESİ">
- <string name="no_voice_effect">
- (Ses Şekillendirme Yok)
- </string>
- <string name="active_voice_effect">
- (Etkin)
- </string>
- <string name="unsubscribed_voice_effect">
- (Abonelik İptal)
- </string>
- <string name="new_voice_effect">
- (Yeni!)
- </string>
- <string name="effect_Arena">
- Arena
- </string>
- <string name="effect_Beast">
- Yaratık
- </string>
- <string name="effect_Buff">
- Yapılı
- </string>
- <string name="effect_Buzz">
- Vızıltı
- </string>
- <string name="effect_Camille">
- Camille
- </string>
- <string name="effect_Creepy">
- Korkutucu
- </string>
- <string name="effect_CreepyBot">
- KorkutucuBot
- </string>
- <string name="effect_Cyber">
- Siber
- </string>
- <string name="effect_DeepBot">
- DerinBot
- </string>
- <string name="effect_Demon">
- İblis
- </string>
- <string name="effect_Female Elf">
- Dişi Cin
- </string>
- <string name="effect_Flirty">
- Cilveli
- </string>
- <string name="effect_Foxy">
- Alımlı
- </string>
- <string name="effect_Halloween 2010 Bonus">
- Halloween_2010_Bonus
- </string>
- <string name="effect_Helium">
- Helyum
- </string>
- <string name="effect_Husky">
- Güçlü
- </string>
- <string name="effect_Husky Whisper">
- Boğuk Fısıltı
- </string>
- <string name="effect_Intercom">
- İnterkom
- </string>
- <string name="effect_Julia">
- Julia
- </string>
- <string name="effect_Lo Lilt">
- Yavaş Mırıltı
- </string>
- <string name="effect_Macho">
- Maço
- </string>
- <string name="effect_Micro">
- Mikro
- </string>
- <string name="effect_Mini">
- Mini
- </string>
- <string name="effect_Model">
- Model
- </string>
- <string name="effect_Nano">
- Nano
- </string>
- <string name="effect_Nightmare">
- Kabus
- </string>
- <string name="effect_PopBot">
- PopBot
- </string>
- <string name="effect_Rachel">
- Rachel
- </string>
- <string name="effect_Radio">
- Radyo
- </string>
- <string name="effect_Robot">
- Robot
- </string>
- <string name="effect_Roxanne">
- Roxanne
- </string>
- <string name="effect_Rumble">
- Gurultu
- </string>
- <string name="effect_Sabrina">
- Sabrina
- </string>
- <string name="effect_Samantha">
- Samantha
- </string>
- <string name="effect_Sexy">
- Seksi
- </string>
- <string name="effect_Shorty">
- Bücür
- </string>
- <string name="effect_Smaller">
- Daha Küçük
- </string>
- <string name="effect_Sneaky">
- Sinsi
- </string>
- <string name="effect_Stallion">
- Maskülen
- </string>
- <string name="effect_Sultry">
- İhtiraslı
- </string>
- <string name="effect_Thunder">
- Gök gürültüsü
- </string>
- <string name="effect_Vixen">
- Çekici
- </string>
- <string name="effect_WhinyBot">
- AğlakBot
- </string>
- <text name="preview_text">
- Önizleme için
- </text>
- <text name="status_text">
- Bir örnek kaydettikten sonra sese tıklayarak nasıl olduğunu duyun.
- </text>
- <button label="Kaydet" name="record_btn" tool_tip="Sesinizin örneğini kaydedin."/>
- <button label="Durdur" name="record_stop_btn"/>
- <text name="voice_morphing_link">
- [[URL] Hemen Abone Ol]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="Sesinizin örneğini kaydettikten sonra önizleme için bir efekte tıklayın.">
- <scroll_list.columns label="Ses Adı" name="name"/>
- <scroll_list.columns label="Bitiş Tarihi" name="expires"/>
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/panel_voice_effect.xml b/indra/newview/skins/default/xui/tr/panel_voice_effect.xml
deleted file mode 100644
index b46833d7e6..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- Ses Şekillendirme Kapalı
- </string>
- <string name="preview_voice_effects">
- Ses Şekillendirme Önizleme ▶
- </string>
- <string name="get_voice_effects">
- Ses Şekillendirmeyi Etkinleştir ▶
- </string>
- <combo_box name="voice_effect" tool_tip="Sesinizi değiştirmek için bir Ses Şekli seçin">
- <combo_box.item label="Ses Şekillendirme Kapalı" name="no_voice_effect"/>
- </combo_box>
-</panel>
diff --git a/indra/newview/skins/default/xui/zh/floater_big_preview.xml b/indra/newview/skins/default/xui/zh/floater_big_preview.xml
deleted file mode 100644
index ae68cd7ddf..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_big_preview.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_big_preview" title="預覽"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_post_process.xml b/indra/newview/skins/default/xui/zh/floater_post_process.xml
deleted file mode 100644
index 2908f7c1d0..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_post_process.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Post-Process Floater" title="後處理設定:">
- <tab_container name="Post-Process Tabs">
- <panel label="顏色過濾" name="wmiColorFilterPanel">
- <check_box label="啟用" name="wmiColorFilterToggle"/>
- <text name="wmiColorFilterBrightnessText">
- 亮度
- </text>
- <text name="wmiColorFilterSaturationText">
- 飽和度
- </text>
- <text name="wmiColorFilterContrastText">
- 對比
- </text>
- <text name="wmiColorFilterBaseText">
- 對比基本色
- </text>
- <slider label="R" name="wmiColorFilterBaseR"/>
- <slider label="G" name="wmiColorFilterBaseG"/>
- <slider label="B" name="wmiColorFilterBaseB"/>
- <slider label="I" name="wmiColorFilterBaseI"/>
- </panel>
- <panel label="夜視" name="wmiNightVisionPanel">
- <check_box label="啟用" name="wmiNightVisionToggle"/>
- <text name="wmiNightVisionBrightMultText">
- 光放大倍數
- </text>
- <text name="wmiNightVisionNoiseSizeText">
- 噪音規模
- </text>
- <text name="wmiNightVisionNoiseStrengthText">
- 噪音強度
- </text>
- </panel>
- <panel label="開花" name="wmiBloomPanel">
- <check_box label="啟用" name="wmiBloomToggle"/>
- <text name="wmiBloomExtractText">
- 光度萃取
- </text>
- <text name="wmiBloomSizeText">
- 開花大小
- </text>
- <text name="wmiBloomStrengthText">
- 開花強度
- </text>
- </panel>
- <panel label="其他" name="Extras">
- <button label="LoadEffect" label_selected="LoadEffect" name="PPLoadEffect"/>
- <button label="SaveEffect" label_selected="SaveEffect" name="PPSaveEffect"/>
- <line_editor label="效果名稱" name="PPEffectNameEditor"/>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_sound_devices.xml b/indra/newview/skins/default/xui/zh/floater_sound_devices.xml
deleted file mode 100644
index 0374c74f8f..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_sound_devices.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_sound_devices" title="聲音裝置">
- <text name="voice_label">
- 語音聊天
- </text>
- <check_box label="已啟用" name="enable_voice"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_voice_effect.xml b/indra/newview/skins/default/xui/zh/floater_voice_effect.xml
deleted file mode 100644
index aab5fa6028..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_voice_effect.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="地點" name="voice_effects" title="語音變聲試聽">
- <string name="no_voice_effect">
- (無變聲效果)
- </string>
- <string name="active_voice_effect">
- (使用中)
- </string>
- <string name="unsubscribed_voice_effect">
- (已停止訂用)
- </string>
- <string name="new_voice_effect">
- (新的!)
- </string>
- <string name="effect_Arena">
- 競技場
- </string>
- <string name="effect_Beast">
- 野獸
- </string>
- <string name="effect_Buff">
- Buff
- </string>
- <string name="effect_Buzz">
- Buzz
- </string>
- <string name="effect_Camille">
- 卡蜜兒
- </string>
- <string name="effect_Creepy">
- 怪異
- </string>
- <string name="effect_CreepyBot">
- 怪異機器人
- </string>
- <string name="effect_Cyber">
- 科幻
- </string>
- <string name="effect_DeepBot">
- 深沉機器人
- </string>
- <string name="effect_Demon">
- 魔鬼
- </string>
- <string name="effect_Female Elf">
- 女性 - 小精靈
- </string>
- <string name="effect_Flirty">
- 調情
- </string>
- <string name="effect_Foxy">
- 香豔
- </string>
- <string name="effect_Halloween 2010 Bonus">
- 2010萬聖節加贈
- </string>
- <string name="effect_Helium">
- 氦氣
- </string>
- <string name="effect_Husky">
- 沙啞
- </string>
- <string name="effect_Husky Whisper">
- 沙啞耳語
- </string>
- <string name="effect_Intercom">
- 對講機
- </string>
- <string name="effect_Julia">
- 茱莉亞
- </string>
- <string name="effect_Lo Lilt">
- 輕微抑揚頓挫
- </string>
- <string name="effect_Macho">
- 陽剛
- </string>
- <string name="effect_Micro">
- Micro
- </string>
- <string name="effect_Mini">
- 迷你
- </string>
- <string name="effect_Model">
- 模型
- </string>
- <string name="effect_Nano">
- Nano
- </string>
- <string name="effect_Nightmare">
- 惡夢
- </string>
- <string name="effect_PopBot">
- PopBot
- </string>
- <string name="effect_Rachel">
- 瑞秋
- </string>
- <string name="effect_Radio">
- 收音機
- </string>
- <string name="effect_Robot">
- 機器人
- </string>
- <string name="effect_Roxanne">
- 蘿姍
- </string>
- <string name="effect_Rumble">
- 低沉隆隆聲
- </string>
- <string name="effect_Sabrina">
- 薩賓娜
- </string>
- <string name="effect_Samantha">
- 姍曼莎
- </string>
- <string name="effect_Sexy">
- 性感
- </string>
- <string name="effect_Shorty">
- 矮個兒
- </string>
- <string name="effect_Smaller">
- 較小
- </string>
- <string name="effect_Sneaky">
- 鬼祟
- </string>
- <string name="effect_Stallion">
- 種馬
- </string>
- <string name="effect_Sultry">
- 勾魂
- </string>
- <string name="effect_Thunder">
- 雷聲
- </string>
- <string name="effect_Vixen">
- 潑婦
- </string>
- <string name="effect_WhinyBot">
- 哭鬧機器人
- </string>
- <text name="preview_text">
- 預覽
- </text>
- <text name="status_text">
- 錄下一段樣本,再點按聲音檢查結果。
- </text>
- <button label="錄音" name="record_btn" tool_tip="錄下一段你的聲音。"/>
- <button label="停止" name="record_stop_btn"/>
- <text name="voice_morphing_link">
- [[URL] 現在訂用]
- </text>
- <scroll_list name="voice_effect_list" tool_tip="錄下一段你的聲音,再點選一個效果試聽。">
- <scroll_list.columns label="語音名稱" name="name"/>
- <scroll_list.columns label="過期" name="expires"/>
- </scroll_list>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/panel_voice_effect.xml b/indra/newview/skins/default/xui/zh/panel_voice_effect.xml
deleted file mode 100644
index 6c8a452014..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_voice_effect.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_voice_effect">
- <string name="no_voice_effect">
- 關閉變聲效果
- </string>
- <string name="preview_voice_effects">
- 預覽變聲效果 ▶
- </string>
- <string name="get_voice_effects">
- 取得變聲效果 ▶
- </string>
- <combo_box name="voice_effect" tool_tip="選取一個變聲效果來改變你的聲音">
- <combo_box.item label="關閉變聲效果" name="no_voice_effect"/>
- </combo_box>
-</panel>
diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp
index acbf019034..3e2e5e70a2 100644
--- a/indra/newview/tests/lldateutil_test.cpp
+++ b/indra/newview/tests/lldateutil_test.cpp
@@ -34,16 +34,16 @@
#include "lltrans.h"
#include "llui.h"
-#include <map>
+#include <unordered_map>
// Baked-in return values for getString()
-std::map< std::string, std::string, std::less<>> gString;
+std::unordered_map< std::string, std::string, ll::string_hash, std::equal_to<>> gString;
// Baked-in return values for getCountString()
// map of pairs of input xml_desc and integer count
typedef std::pair< std::string, int > count_string_t;
-std::map< count_string_t, std::string > gCountString;
+std::map<count_string_t, std::string> gCountString;
std::string LLTrans::getString(const std::string_view xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
{