summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2025-11-19 21:05:46 +0200
committerAndrey Lihatskiy <alihatskiy@productengine.com>2025-11-19 21:05:46 +0200
commit093d969eb97ca03dbf4ae5cd3a3c784f58613a32 (patch)
tree916a65d49f2bfe6c12effba979bfa39417d6304a
parent7e09943d57ecf2d9b15249cbc19b4e2ec16f7bf3 (diff)
parentae659adab6f8d1adf0224d12fb3b379251eaa501 (diff)
Merge branch 'develop-linux' into marchcat/slua-linux
# Conflicts: # indra/newview/llfeaturemanager.cpp # indra/newview/llstartup.cpp
-rw-r--r--.gitattributes4
-rw-r--r--.github/workflows/build.yaml52
-rwxr-xr-x.gitignore4
-rw-r--r--autobuild.xml567
-rwxr-xr-xbuild.sh31
-rw-r--r--doc/BUILD.LINUX.md79
-rw-r--r--indra/CMakeLists.txt45
-rw-r--r--indra/cmake/00-COMPILE-LINK-RUN.txt4
-rw-r--r--indra/cmake/00-Common.cmake89
-rw-r--r--indra/cmake/APR.cmake5
-rw-r--r--indra/cmake/Boost.cmake151
-rw-r--r--indra/cmake/BuildVersion.cmake9
-rw-r--r--indra/cmake/CEFPlugin.cmake11
-rw-r--r--indra/cmake/CMakeLists.txt10
-rw-r--r--indra/cmake/ConfigurePkgConfig.cmake74
-rw-r--r--indra/cmake/Copy3rdPartyLibs.cmake19
-rw-r--r--indra/cmake/DBusGlib.cmake14
-rw-r--r--indra/cmake/Discord.cmake23
-rw-r--r--indra/cmake/FindPipeWire.cmake100
-rw-r--r--indra/cmake/FreeType.cmake4
-rw-r--r--indra/cmake/GLEXT.cmake3
-rw-r--r--indra/cmake/GLH.cmake7
-rw-r--r--indra/cmake/GLIB.cmake22
-rw-r--r--indra/cmake/GStreamer010Plugin.cmake12
-rw-r--r--indra/cmake/GStreamer10Plugin.cmake27
-rw-r--r--indra/cmake/Havok.cmake37
-rw-r--r--indra/cmake/JPEG.cmake3
-rw-r--r--indra/cmake/LLAddBuildTest.cmake55
-rw-r--r--indra/cmake/LLAppearanceUtility.cmake12
-rw-r--r--indra/cmake/LLKDU.cmake18
-rw-r--r--indra/cmake/LLWindow.cmake21
-rw-r--r--indra/cmake/LibVLCPlugin.cmake35
-rw-r--r--indra/cmake/NDOF.cmake7
-rw-r--r--indra/cmake/OPENAL.cmake2
-rw-r--r--indra/cmake/OpenXR.cmake27
-rw-r--r--indra/cmake/PNG.cmake4
-rw-r--r--indra/cmake/Prebuilt.cmake5
-rw-r--r--indra/cmake/Python.cmake2
-rw-r--r--indra/cmake/SDL3.cmake26
-rw-r--r--indra/cmake/UI.cmake45
-rw-r--r--indra/cmake/Variables.cmake69
-rw-r--r--indra/cmake/ViewerMiscLibs.cmake7
-rw-r--r--indra/cmake/ZLIBNG.cmake1
-rw-r--r--indra/cmake/bugsplat.cmake14
-rwxr-xr-xindra/cmake/run_build_test.py2
-rw-r--r--indra/integration_tests/llimage_libtest/CMakeLists.txt13
-rw-r--r--indra/integration_tests/llimage_libtest/llimage_libtest.cpp7
-rw-r--r--indra/integration_tests/llui_libtest/CMakeLists.txt14
-rw-r--r--indra/linux_crash_logger/CMakeLists.txt72
-rw-r--r--indra/linux_crash_logger/README.txt3
-rw-r--r--indra/linux_crash_logger/linux_crash_logger.cpp58
-rw-r--r--indra/linux_crash_logger/llcrashloggerlinux.cpp146
-rw-r--r--indra/llappearance/CMakeLists.txt11
-rw-r--r--indra/llappearance/llavatarappearancedefines.cpp4
-rw-r--r--indra/llappearance/llavatarappearancedefines.h4
-rw-r--r--indra/llappearance/llavatarjoint.h6
-rw-r--r--indra/llappearance/llavatarjointmesh.h3
-rw-r--r--indra/llappearance/lldriverparam.h2
-rw-r--r--indra/llappearance/llpolymorph.h2
-rw-r--r--indra/llappearance/llpolyskeletaldistortion.h4
-rw-r--r--indra/llappearance/lltexlayer.cpp25
-rw-r--r--indra/llappearance/lltexlayer.h2
-rw-r--r--indra/llappearance/lltexlayerparams.h6
-rw-r--r--indra/llappearance/llviewervisualparam.h5
-rw-r--r--indra/llappearanceutility/CMakeLists.txt86
-rw-r--r--indra/llappearanceutility/README.md33
-rw-r--r--indra/llappearanceutility/appearance_utility.cpp71
-rw-r--r--indra/llappearanceutility/llappappearanceutility.cpp681
-rw-r--r--indra/llappearanceutility/llappappearanceutility.h108
-rw-r--r--indra/llappearanceutility/llbakingavatar.cpp177
-rw-r--r--indra/llappearanceutility/llbakingavatar.h131
-rw-r--r--indra/llappearanceutility/llbakingjoint.cpp (renamed from indra/linux_crash_logger/llcrashloggerlinux.h)45
-rw-r--r--indra/llappearanceutility/llbakingjoint.h45
-rw-r--r--indra/llappearanceutility/llbakingjointmesh.cpp43
-rw-r--r--indra/llappearanceutility/llbakingjointmesh.h46
-rw-r--r--indra/llappearanceutility/llbakingprocess.cpp47
-rw-r--r--indra/llappearanceutility/llbakingprocess.h60
-rw-r--r--indra/llappearanceutility/llbakingshadermgr.cpp250
-rw-r--r--indra/llappearanceutility/llbakingshadermgr.h137
-rw-r--r--indra/llappearanceutility/llbakingtexlayer.cpp373
-rw-r--r--indra/llappearanceutility/llbakingtexlayer.h77
-rw-r--r--indra/llappearanceutility/llbakingtexture.cpp81
-rw-r--r--indra/llappearanceutility/llbakingtexture.h69
-rw-r--r--indra/llappearanceutility/llbakingwearable.cpp77
-rw-r--r--indra/llappearanceutility/llbakingwearable.h48
-rw-r--r--indra/llappearanceutility/llbakingwearablesdata.cpp131
-rw-r--r--indra/llappearanceutility/llbakingwearablesdata.h55
-rw-r--r--indra/llappearanceutility/llbakingwindow.cpp94
-rw-r--r--indra/llappearanceutility/llbakingwindow.h45
-rwxr-xr-xindra/llappearanceutility/llprocessparams.cpp281
-rw-r--r--indra/llappearanceutility/llprocessparams.h49
-rw-r--r--indra/llappearanceutility/llprocessskin.cpp118
-rw-r--r--indra/llappearanceutility/llprocessskin.h43
-rw-r--r--indra/llappearanceutility/llprocesstexture.cpp284
-rw-r--r--indra/llappearanceutility/llprocesstexture.h63
-rw-r--r--indra/llappearanceutility/tests/joint-offsets.xml1
-rw-r--r--indra/llappearanceutility/tests/joint-offsets.xml.output1
-rw-r--r--indra/llappearanceutility/tests/params.xml1140
-rw-r--r--indra/llappearanceutility/tests/params.xml.output1
-rw-r--r--indra/llappearanceutility/tests/texture.llsd.binarybin0 -> 170423 bytes
-rw-r--r--indra/llappearanceutility/tests/texture.llsd.outputbin0 -> 112866 bytes
-rw-r--r--indra/llaudio/CMakeLists.txt4
-rw-r--r--indra/llcharacter/CMakeLists.txt4
-rw-r--r--indra/llcharacter/lleditingmotion.h15
-rw-r--r--indra/llcharacter/lljoint.h7
-rw-r--r--indra/llcharacter/llkeyframestandmotion.h5
-rw-r--r--indra/llcharacter/llpose.h7
-rw-r--r--indra/llcharacter/llvisualparam.h5
-rw-r--r--indra/llcommon/CMakeLists.txt28
-rw-r--r--indra/llcommon/StackWalker.cpp2
-rw-r--r--indra/llcommon/classic_callback.h4
-rw-r--r--indra/llcommon/llapp.cpp51
-rw-r--r--indra/llcommon/llapr.cpp4
-rw-r--r--indra/llcommon/llatomic.cpp2
-rw-r--r--indra/llcommon/llcallbacklist.cpp2
-rw-r--r--indra/llcommon/llcommon.cpp54
-rw-r--r--indra/llcommon/lldate.cpp4
-rw-r--r--indra/llcommon/lldeadmantimer.cpp1
-rw-r--r--indra/llcommon/lldefs.h55
-rw-r--r--indra/llcommon/llerror.cpp51
-rw-r--r--indra/llcommon/llerror.h7
-rw-r--r--indra/llcommon/llfasttimer.cpp11
-rw-r--r--indra/llcommon/llfindlocale.cpp4
-rw-r--r--indra/llcommon/llinstancetracker.h4
-rw-r--r--indra/llcommon/llkeybind.cpp9
-rw-r--r--indra/llcommon/llkeybind.h1
-rw-r--r--indra/llcommon/llmd5.cpp6
-rw-r--r--indra/llcommon/llmemory.cpp3
-rw-r--r--indra/llcommon/llmemory.h46
-rw-r--r--indra/llcommon/llpreprocessor.h50
-rw-r--r--indra/llcommon/llprocess.cpp12
-rw-r--r--indra/llcommon/llprocessor.cpp67
-rw-r--r--indra/llcommon/llprocinfo.cpp1
-rw-r--r--indra/llcommon/llprofiler.cpp2
-rw-r--r--indra/llcommon/llprofiler.h9
-rw-r--r--indra/llcommon/llrand.cpp25
-rw-r--r--indra/llcommon/llsd.cpp5
-rw-r--r--indra/llcommon/llsdjson.cpp1
-rw-r--r--indra/llcommon/llsdserialize.cpp5
-rw-r--r--indra/llcommon/llsdutil.cpp4
-rw-r--r--indra/llcommon/llstl.h10
-rw-r--r--indra/llcommon/llsys.cpp132
-rw-r--r--indra/llcommon/llthread.cpp46
-rw-r--r--indra/llcommon/llthread.h8
-rw-r--r--indra/llcommon/lltracerecording.cpp9
-rw-r--r--indra/llcommon/stdtypes.h24
-rw-r--r--indra/llcommon/tests/commonmisc_test.cpp4
-rw-r--r--indra/llcommon/tests/lldependencies_test.cpp12
-rw-r--r--indra/llcommon/tests/llerror_test.cpp4
-rw-r--r--indra/llcommon/tests/llprocess_test.cpp12
-rw-r--r--indra/llcommon/tests/llsdserialize_test.cpp2
-rw-r--r--indra/llcommon/tests/llstring_test.cpp4
-rw-r--r--indra/llcommon/threadpool.cpp1
-rw-r--r--indra/llcorehttp/CMakeLists.txt13
-rw-r--r--indra/llcorehttp/_httpservice.cpp3
-rwxr-xr-xindra/llcorehttp/llhttpconstants.h2
-rw-r--r--indra/llcrashlogger/CMakeLists.txt23
-rw-r--r--indra/llcrashlogger/README.txt3
-rw-r--r--indra/llcrashlogger/llcrashlock.cpp212
-rw-r--r--indra/llcrashlogger/llcrashlock.h73
-rw-r--r--indra/llcrashlogger/llcrashlogger.cpp682
-rw-r--r--indra/llcrashlogger/llcrashlogger.h97
-rw-r--r--indra/llfilesystem/CMakeLists.txt11
-rw-r--r--indra/llfilesystem/lldir_win32.cpp4
-rw-r--r--indra/llfilesystem/lldiriterator.cpp2
-rw-r--r--indra/llfilesystem/lldiskcache.cpp12
-rw-r--r--indra/llfilesystem/tests/lldir_test.cpp31
-rw-r--r--indra/llimage/CMakeLists.txt4
-rw-r--r--indra/llimagej2coj/CMakeLists.txt3
-rw-r--r--indra/llinventory/CMakeLists.txt4
-rw-r--r--indra/llinventory/llsettingsbase.cpp4
-rw-r--r--indra/llinventory/llsettingsdaycycle.cpp2
-rw-r--r--indra/llinventory/llsettingssky.cpp2
-rw-r--r--indra/llinventory/llsettingswater.cpp1
-rw-r--r--indra/llkdu/include_kdu_xxxx.h2
-rw-r--r--indra/llkdu/tests/llimagej2ckdu_test.cpp2
-rw-r--r--indra/llmath/CMakeLists.txt8
-rw-r--r--indra/llmath/llcalc.cpp11
-rw-r--r--indra/llmath/llcalc.h7
-rw-r--r--indra/llmath/llcalcparser.h18
-rw-r--r--indra/llmath/llcamera.h12
-rw-r--r--indra/llmath/llmatrix3a.cpp2
-rw-r--r--indra/llmath/llmatrix3a.h5
-rw-r--r--indra/llmath/llmatrix4a.h5
-rw-r--r--indra/llmath/llplane.h7
-rw-r--r--indra/llmath/llquantize.h8
-rw-r--r--indra/llmath/llquaternion2.h3
-rw-r--r--indra/llmath/llquaternion2.inl2
-rw-r--r--indra/llmath/llsimdtypes.inl4
-rw-r--r--indra/llmath/llvector4a.cpp4
-rw-r--r--indra/llmath/llvector4a.inl10
-rw-r--r--indra/llmath/llvector4logical.h4
-rw-r--r--indra/llmath/llvolume.cpp2
-rw-r--r--indra/llmath/llvolumeoctree.h6
-rw-r--r--indra/llmath/tests/alignment_test.cpp5
-rw-r--r--indra/llmeshoptimizer/CMakeLists.txt4
-rw-r--r--indra/llmessage/CMakeLists.txt4
-rw-r--r--indra/llmessage/llavatarname.h2
-rw-r--r--indra/llmessage/llbufferstream.cpp11
-rw-r--r--indra/llmessage/llbufferstream.h9
-rw-r--r--indra/llmessage/llcachename.cpp1
-rw-r--r--indra/llmessage/llexperiencecache.cpp2
-rw-r--r--indra/llmessage/llpartdata.cpp8
-rw-r--r--indra/llmessage/llstoredmessage.cpp2
-rw-r--r--indra/llmessage/lltemplatemessagedispatcher.cpp1
-rw-r--r--indra/llmessage/lltemplatemessagereader.cpp3
-rw-r--r--indra/llphysicsextensionsos/CMakeLists.txt4
-rw-r--r--indra/llplugin/CMakeLists.txt5
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp13
-rw-r--r--indra/llplugin/llpluginclassmedia.h4
-rw-r--r--indra/llplugin/slplugin/CMakeLists.txt10
-rw-r--r--indra/llprecompiled/CMakeLists.txt53
-rw-r--r--indra/llprecompiled/cmake_dummy.cpp (renamed from indra/newview/llappviewerlinux_api_dbus.h)22
-rw-r--r--indra/llprimitive/CMakeLists.txt4
-rw-r--r--indra/llprimitive/lldaeloader.cpp2
-rw-r--r--indra/llprimitive/llmaterialid.cpp21
-rw-r--r--indra/llprimitive/llmaterialid.h5
-rw-r--r--indra/llprimitive/llmodel.h12
-rw-r--r--indra/llprimitive/llmodelloader.cpp2
-rw-r--r--indra/llprimitive/llprimtexturelist.cpp2
-rw-r--r--indra/llprimitive/tests/llprimitive_test.cpp4
-rw-r--r--indra/llrender/CMakeLists.txt27
-rw-r--r--indra/llrender/llgl.cpp1997
-rw-r--r--indra/llrender/llgl.h95
-rw-r--r--indra/llrender/llglcommonfunc.cpp2
-rw-r--r--indra/llrender/llglheaders.h581
-rw-r--r--indra/llrender/llglstates.h27
-rw-r--r--indra/llrender/llimagegl.cpp22
-rw-r--r--indra/llrender/llimagegl.h1
-rw-r--r--indra/llrender/llpostprocess.cpp454
-rw-r--r--indra/llrender/llpostprocess.h267
-rw-r--r--indra/llrender/llrender.cpp139
-rw-r--r--indra/llrender/llrender.h19
-rw-r--r--indra/llrender/llrender2dutils.cpp15
-rw-r--r--indra/llrender/llshadermgr.cpp1
-rw-r--r--indra/llrender/lltexturemanagerbridge.cpp2
-rw-r--r--indra/llui/CMakeLists.txt4
-rw-r--r--indra/llui/llcheckboxctrl.h5
-rw-r--r--indra/llui/llemojihelper.h2
-rw-r--r--indra/llui/llfloater.cpp2
-rw-r--r--indra/llui/llscrolllistcell.cpp32
-rw-r--r--indra/llui/llscrolllistcell.h2
-rw-r--r--indra/llui/llviewereventrecorder.h2
-rw-r--r--indra/llwindow/CMakeLists.txt112
-rw-r--r--indra/llwindow/llkeyboard.cpp18
-rw-r--r--indra/llwindow/llkeyboard.h26
-rw-r--r--indra/llwindow/llkeyboardheadless.cpp21
-rw-r--r--indra/llwindow/llkeyboardheadless.h16
-rw-r--r--indra/llwindow/llkeyboardmacosx.cpp13
-rw-r--r--indra/llwindow/llkeyboardmacosx.h16
-rw-r--r--indra/llwindow/llkeyboardsdl.cpp446
-rw-r--r--indra/llwindow/llkeyboardsdl.h27
-rw-r--r--indra/llwindow/llkeyboardwin32.cpp4
-rw-r--r--indra/llwindow/llkeyboardwin32.h17
-rw-r--r--indra/llwindow/llmousehandler.cpp2
-rw-r--r--indra/llwindow/llsdl.cpp149
-rw-r--r--indra/llwindow/llsdl.h (renamed from indra/media_plugins/gstreamer010/llmediaimplgstreamer.h)33
-rw-r--r--indra/llwindow/llwindow.cpp52
-rw-r--r--indra/llwindow/llwindow.h5
-rw-r--r--indra/llwindow/llwindowheadless.h2
-rw-r--r--indra/llwindow/llwindowmesaheadless.h121
-rw-r--r--indra/llwindow/llwindowsdl.cpp2636
-rw-r--r--indra/llwindow/llwindowsdl.h313
-rw-r--r--indra/llwindow/llwindowwin32.cpp17
-rw-r--r--indra/llwindow/llwindowwin32.h3
-rw-r--r--indra/llxml/CMakeLists.txt3
-rw-r--r--indra/media_plugins/CMakeLists.txt18
-rw-r--r--indra/media_plugins/base/media_plugin_base.cpp96
-rw-r--r--indra/media_plugins/base/media_plugin_base.h39
-rw-r--r--indra/media_plugins/cef/CMakeLists.txt63
-rw-r--r--indra/media_plugins/cef/linux/volume_catcher_linux.cpp78
-rw-r--r--indra/media_plugins/cef/linux/volume_catcher_linux.h149
-rwxr-xr-xindra/media_plugins/cef/linux/volume_catcher_pipewire.cpp333
-rw-r--r--indra/media_plugins/cef/linux/volume_catcher_pipewire_syms.inc26
-rwxr-xr-xindra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp322
-rwxr-xr-xindra/media_plugins/cef/linux/volume_catcher_pulseaudio_glib_syms.inc10
-rwxr-xr-xindra/media_plugins/cef/linux/volume_catcher_pulseaudio_syms.inc29
-rw-r--r--indra/media_plugins/cef/media_plugin_cef.cpp41
-rw-r--r--indra/media_plugins/cef/volume_catcher.h10
-rw-r--r--indra/media_plugins/cef/volume_catcher_null.cpp (renamed from indra/media_plugins/cef/mac_volume_catcher_null.cpp)50
-rw-r--r--indra/media_plugins/cef/windows_volume_catcher.cpp1
-rw-r--r--indra/media_plugins/gstreamer010/CMakeLists.txt46
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp167
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h74
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc51
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc5
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h55
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp526
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h105
-rw-r--r--indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp1266
-rw-r--r--indra/media_plugins/gstreamer10/CMakeLists.txt40
-rw-r--r--indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms_raw.inc71
-rw-r--r--indra/media_plugins/gstreamer10/media_plugin_gstreamer10.cpp958
-rw-r--r--indra/media_plugins/libvlc/media_plugin_libvlc.cpp2
-rw-r--r--indra/newview/CMakeLists.txt109
-rw-r--r--indra/newview/app_settings/settings.xml124
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl20
-rw-r--r--indra/newview/featuretable.txt30
-rw-r--r--indra/newview/featuretable_linux.txt658
-rw-r--r--indra/newview/featuretable_mac.txt29
-rw-r--r--indra/newview/gltf/accessor.cpp2
-rw-r--r--indra/newview/gltf/asset.cpp4
-rw-r--r--indra/newview/gltf/llgltfloader.cpp4
-rw-r--r--indra/newview/linux_tools/client-readme-joystick.txt78
-rw-r--r--indra/newview/linux_tools/client-readme-voice.txt81
-rw-r--r--indra/newview/linux_tools/client-readme.txt244
-rwxr-xr-xindra/newview/linux_tools/launch_url.sh86
-rwxr-xr-xindra/newview/linux_tools/refresh_desktop_app_entry.sh15
-rwxr-xr-xindra/newview/linux_tools/register_secondlifeprotocol.sh75
-rwxr-xr-xindra/newview/linux_tools/wrapper.sh108
-rw-r--r--indra/newview/llappdelegate-objc.mm2
-rw-r--r--indra/newview/llappviewer.cpp39
-rw-r--r--indra/newview/llappviewerlinux.cpp486
-rw-r--r--indra/newview/llappviewerlinux.h51
-rw-r--r--indra/newview/llappviewerlinux_api.h143
-rw-r--r--indra/newview/llappviewerlinux_api.xml14
-rw-r--r--indra/newview/llappviewerlinux_api_dbus.cpp126
-rw-r--r--indra/newview/llappviewerlinux_api_dbus_syms_raw.inc9
-rw-r--r--indra/newview/llappviewerwin32.cpp2
-rw-r--r--indra/newview/lldirpicker.cpp176
-rw-r--r--indra/newview/lldirpicker.h8
-rw-r--r--indra/newview/lldrawable.h5
-rw-r--r--indra/newview/lldrawpool.cpp2
-rw-r--r--indra/newview/lldrawpoolterrain.cpp373
-rw-r--r--indra/newview/lldrawpoolterrain.h3
-rw-r--r--indra/newview/lldynamictexture.h4
-rw-r--r--indra/newview/lleventnotifier.cpp71
-rw-r--r--indra/newview/lleventnotifier.h25
-rw-r--r--indra/newview/llface.cpp8
-rw-r--r--indra/newview/llfasttimerview.cpp6
-rw-r--r--indra/newview/llfeaturemanager.cpp14
-rw-r--r--indra/newview/llfilepicker.cpp939
-rw-r--r--indra/newview/llfilepicker.h34
-rw-r--r--indra/newview/llflexibleobject.cpp2
-rw-r--r--indra/newview/llfloateravatarpicker.cpp150
-rw-r--r--indra/newview/llfloateravatarpicker.h3
-rw-r--r--indra/newview/llfloaterdirectory.cpp100
-rw-r--r--indra/newview/llfloaterdirectory.h81
-rw-r--r--indra/newview/llfloatergesture.cpp82
-rw-r--r--indra/newview/llfloaterland.cpp23
-rw-r--r--indra/newview/llfloaternotificationstabbed.cpp4
-rw-r--r--indra/newview/llfloaternotificationstabbed.h2
-rw-r--r--indra/newview/llfloaterpostprocess.cpp229
-rw-r--r--indra/newview/llfloaterpostprocess.h72
-rw-r--r--indra/newview/llfloaterpreference.cpp2
-rw-r--r--indra/newview/llfloaterpreferencesgraphicsadvanced.cpp22
-rw-r--r--indra/newview/llfloaterregioninfo.h4
-rw-r--r--indra/newview/llglsandbox.cpp12
-rw-r--r--indra/newview/llgltfmaterialpreviewmgr.cpp4
-rw-r--r--indra/newview/llinventorygallerymenu.cpp4
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.cpp71
-rw-r--r--indra/newview/lllocationinputctrl.h4
-rw-r--r--indra/newview/llmaniprotate.cpp1
-rw-r--r--indra/newview/llmarketplacefunctions.cpp23
-rw-r--r--indra/newview/llmarketplacefunctions.h10
-rw-r--r--indra/newview/llmaterialmgr.cpp22
-rw-r--r--indra/newview/llmaterialmgr.h6
-rw-r--r--indra/newview/llmediactrl.cpp4
-rw-r--r--indra/newview/llmediactrl.h1
-rw-r--r--indra/newview/llmeshrepository.cpp2
-rw-r--r--indra/newview/llmodelpreview.cpp20
-rw-r--r--indra/newview/lloutfitgallery.cpp2
-rw-r--r--indra/newview/lloutfitobserver.h2
-rw-r--r--indra/newview/llpanelclassified.cpp4
-rw-r--r--indra/newview/llpaneldirbrowser.cpp1169
-rw-r--r--indra/newview/llpaneldirbrowser.h167
-rw-r--r--indra/newview/llpaneldirclassified.cpp109
-rw-r--r--indra/newview/llpaneldirclassified.h55
-rw-r--r--indra/newview/llpaneldirevents.cpp248
-rw-r--r--indra/newview/llpaneldirevents.h61
-rw-r--r--indra/newview/llpaneldirgroups.cpp90
-rw-r--r--indra/newview/llpaneldirgroups.h45
-rw-r--r--indra/newview/llpaneldirland.cpp247
-rw-r--r--indra/newview/llpaneldirland.h53
-rw-r--r--indra/newview/llpaneldirpeople.cpp105
-rw-r--r--indra/newview/llpaneldirpeople.h48
-rw-r--r--indra/newview/llpaneldirplaces.cpp185
-rw-r--r--indra/newview/llpaneldirplaces.h51
-rw-r--r--indra/newview/llpaneldirweb.cpp148
-rw-r--r--indra/newview/llpaneldirweb.h63
-rw-r--r--indra/newview/llpaneleventinfo.cpp195
-rw-r--r--indra/newview/llpaneleventinfo.h76
-rw-r--r--indra/newview/llpanelgroup.cpp6
-rw-r--r--indra/newview/llpanelgroup.h1
-rw-r--r--indra/newview/llpaneloutfitedit.cpp2
-rw-r--r--indra/newview/llpanelplaces.cpp9
-rw-r--r--indra/newview/llpanelplaces.h2
-rw-r--r--indra/newview/llpanelprofile.cpp14
-rw-r--r--indra/newview/llpanelprofile.h3
-rw-r--r--indra/newview/llselectmgr.cpp2
-rw-r--r--indra/newview/llsettingsvo.cpp4
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp4
-rw-r--r--indra/newview/llspatialpartition.cpp34
-rw-r--r--indra/newview/llspatialpartition.h13
-rw-r--r--indra/newview/llstartup.cpp13
-rw-r--r--indra/newview/llterrainpaintmap.cpp2
-rw-r--r--indra/newview/lltexturecache.cpp55
-rw-r--r--indra/newview/llversioninfo.cpp2
-rw-r--r--indra/newview/llversioninfovars.h.in31
-rw-r--r--indra/newview/llviewercontrol.cpp18
-rw-r--r--indra/newview/llviewerdisplay.cpp3
-rw-r--r--indra/newview/llviewerfloaterreg.cpp10
-rw-r--r--indra/newview/llviewerjoint.h3
-rw-r--r--indra/newview/llviewerjointattachment.h3
-rw-r--r--indra/newview/llviewerjointmesh.cpp8
-rw-r--r--indra/newview/llviewerjointmesh.h3
-rw-r--r--indra/newview/llviewermedia.cpp16
-rw-r--r--indra/newview/llviewermenufile.cpp6
-rw-r--r--indra/newview/llviewermessage.cpp4
-rw-r--r--indra/newview/llvieweroctree.h26
-rwxr-xr-xindra/newview/llviewerparceloverlay.cpp2
-rw-r--r--indra/newview/llviewershadermgr.cpp30
-rw-r--r--indra/newview/llviewerwindow.cpp24
-rw-r--r--indra/newview/llviewerwindow.h1
-rw-r--r--indra/newview/llvoavatar.cpp8
-rw-r--r--indra/newview/llvoavatar.h8
-rw-r--r--indra/newview/llvoiceclient.cpp121
-rw-r--r--indra/newview/llvoicewebrtc.cpp11
-rw-r--r--indra/newview/llxmlrpctransaction.cpp2
-rw-r--r--indra/newview/pipeline.cpp46
-rw-r--r--indra/newview/skins/default/textures/icon_auction.tgabin0 -> 1068 bytes
-rw-r--r--indra/newview/skins/default/textures/icon_event.tgabin0 -> 1068 bytes
-rw-r--r--indra/newview/skins/default/textures/icon_event_adult.tgabin0 -> 648 bytes
-rw-r--r--indra/newview/skins/default/textures/icon_event_mature.tgabin0 -> 1068 bytes
-rw-r--r--indra/newview/skins/default/textures/icon_place.tgabin0 -> 1068 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_directory.xml150
-rw-r--r--indra/newview/skins/default/xui/en/floater_gesture.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_post_process.xml426
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml54
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml8
-rw-r--r--indra/newview/skins/default/xui/en/mime_types_linux.xml70
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified_info.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_dir_classified.xml215
-rw-r--r--indra/newview/skins/default/xui/en/panel_dir_events.xml300
-rw-r--r--indra/newview/skins/default/xui/en/panel_dir_groups.xml129
-rw-r--r--indra/newview/skins/default/xui/en/panel_dir_land.xml268
-rw-r--r--indra/newview/skins/default/xui/en/panel_dir_people.xml120
-rw-r--r--indra/newview/skins/default/xui/en/panel_dir_places.xml215
-rw-r--r--indra/newview/skins/default/xui/en/panel_dir_web.xml76
-rw-r--r--indra/newview/skins/default/xui/en/panel_event_info.xml212
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml4
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml1
-rw-r--r--indra/newview/tests/llsechandler_basic_test.cpp4
-rw-r--r--indra/newview/tests/llversioninfo_test.cpp2
-rwxr-xr-xindra/newview/viewer_manifest.py169
-rw-r--r--indra/test/CMakeLists.txt75
-rw-r--r--indra/test/lltut.h4
-rw-r--r--indra/test/test.cpp7
456 files changed, 19711 insertions, 13569 deletions
diff --git a/.gitattributes b/.gitattributes
index 5c7f5b73b0..e7c2f83897 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -24,6 +24,10 @@
*.dll binary
*.exe binary
+# Test Resources
+*.binary binary
+*.output binary
+
# Files with Windows line endings
VivoxAUP.txt text eol=crlf
FILES_ARE_UNICODE_UTF-16LE.txt text eol=crlf
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 4c948e5586..2fe666680f 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -43,7 +43,7 @@ jobs:
needs: setup
strategy:
matrix:
- runner: ${{ fromJson((github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/Second_Life')) && '["windows-large","macos-15-xlarge"]' || '["windows-2022","macos-15-xlarge"]') }}
+ runner: ${{ fromJson((github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/Second_Life')) && '["windows-large","macos-15-xlarge","linux-large"]' || '["windows-2022","macos-15-xlarge","ubuntu-22.04"]') }}
configuration: ${{ fromJson(needs.setup.outputs.configurations) }}
runs-on: ${{ matrix.runner }}
outputs:
@@ -90,6 +90,20 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
+ - name: Linux Disk Cleanup
+ if: runner.os == 'Linux'
+ run: |
+ # Prune various unused files from linux builder to fix free runner disk space exhaustion
+ df -h
+ sudo docker container prune -f
+ sudo docker image prune -a -f
+ sudo rm -rf /usr/local/share/boost
+ sudo rm -rf /usr/share/dotnet
+ sudo rm -rf /usr/local/lib/android
+ sudo rm -rf /opt/ghc
+ sudo rm -rf /usr/local/.ghcup
+ df -h
+
- name: Setup python
uses: actions/setup-python@v5
with:
@@ -120,6 +134,21 @@ jobs:
${{ runner.os }}-64-${{ matrix.configuration }}-
${{ runner.os }}-64-
+ - name: Install Linux dependencies
+ if: runner.os == 'Linux'
+ run: |
+ sudo apt update
+ sudo apt install -y \
+ libpulse-dev libunwind-dev \
+ libgl1-mesa-dev libglu1-mesa-dev libxinerama-dev \
+ libxcursor-dev libxfixes-dev libgstreamer1.0-dev \
+ libgstreamer-plugins-base1.0-dev ninja-build libxft-dev \
+ libpipewire-0.3-dev libdbus-1-dev libvlc-dev \
+ libosmesa6-dev
+ sudo locale-gen en_US.UTF-8
+ sudo locale-gen en_GB.UTF-8
+ sudo locale-gen fr_FR.UTF-8
+
- name: Determine source branch
id: which-branch
uses: secondlife/viewer-build-util/which-branch@v2
@@ -298,6 +327,16 @@ jobs:
path: |
${{ steps.build.outputs.physicstpv }}
+ - name: Upload appearance utility package
+ uses: actions/upload-artifact@v4
+ if: steps.build.outputs.appearanceutility
+ with:
+ name: "${{ steps.build.outputs.artifact }}-appearanceutility"
+ # emitted by build.sh, zero or one lines
+ path: |
+ ${{ steps.build.outputs.appearanceutility }}
+
+
sign-and-package-windows:
env:
AZURE_KEY_VAULT_URI: ${{ secrets.AZURE_KEY_VAULT_URI }}
@@ -425,20 +464,26 @@ jobs:
runs-on: ubuntu-latest
if: needs.setup.outputs.release_run
steps:
- - uses: actions/download-artifact@v4
+ - uses: actions/download-artifact@v5
with:
pattern: "*-installer"
- - uses: actions/download-artifact@v4
+ - uses: actions/download-artifact@v5
with:
pattern: "*-metadata"
+ - uses: actions/download-artifact@v5
+ with:
+ name: "Linux-app"
+
- name: Rename metadata
run: |
cp Windows-metadata/autobuild-package.xml Windows-autobuild-package.xml
cp Windows-metadata/newview/viewer_version.txt Windows-viewer_version.txt
cp macOS-metadata/autobuild-package.xml macOS-autobuild-package.xml
cp macOS-metadata/newview/viewer_version.txt macOS-viewer_version.txt
+ cp Linux-metadata/autobuild-package.xml Linux-autobuild-package.xml
+ cp Linux-metadata/newview/viewer_version.txt Linux-viewer_version.txt
# forked from softprops/action-gh-release
- name: Create GitHub release
@@ -462,6 +507,7 @@ jobs:
files: |
macOS-installer/*.dmg
Windows-installer/*.exe
+ *.tar.xz
*-autobuild-package.xml
*-viewer_version.txt
diff --git a/.gitignore b/.gitignore
index c4accf37b5..a784d6e7d4 100755
--- a/.gitignore
+++ b/.gitignore
@@ -17,11 +17,11 @@
*~
# Specific paths and/or names
+.venv
CMakeCache.txt
cmake_install.cmake
LICENSES
-build-darwin-*
-build-linux-*
+build-*
debian/files
debian/secondlife-appearance-utility*
debian/secondlife-viewer*
diff --git a/autobuild.xml b/autobuild.xml
index 51288ed7e3..64c0a2262e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -7,33 +7,65 @@
<string>autobuild</string>
<key>installables</key>
<map>
- <key>SDL</key>
+ <key>SDL3</key>
<map>
<key>platforms</key>
<map>
+ <key>windows64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>121b209bbf8ffb2f7f668a74de0e654f4be7339f</string>
+ <key>hash_algorithm</key>
+ <string>sha1</string>
+ <key>url</key>
+ <string>https://github.com/secondlife/3p-sdl3/releases/download/v3.2.24-r1/SDL3-3.2.24-r1-windows64-18539840462.tar.zst</string>
+ </map>
+ <key>name</key>
+ <string>windows64</string>
+ </map>
<key>linux64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>7ea2df03bfc35c06acf23dd9e734adac</string>
+ <string>06226c54c57afd601707c0f5f7a2e0736ab1f326</string>
+ <key>hash_algorithm</key>
+ <string>sha1</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1103/2554/SDL-1.2.15-linux64-501092.tar.bz2</string>
+ <string>https://github.com/secondlife/3p-sdl3/releases/download/v3.2.24-r1/SDL3-3.2.24-r1-linux64-18539840462.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
</map>
+ <key>darwin64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>aff68fb5655629c698e198af1581835267588f77</string>
+ <key>hash_algorithm</key>
+ <string>sha1</string>
+ <key>url</key>
+ <string>https://github.com/secondlife/3p-sdl3/releases/download/v3.2.24-r1/SDL3-3.2.24-r1-darwin64-18539840462.tar.zst</string>
+ </map>
+ <key>name</key>
+ <string>darwin64</string>
+ </map>
</map>
<key>license</key>
<string>lgpl</string>
<key>license_file</key>
- <string>LICENSES/SDL.txt</string>
+ <string>LICENSES/SDL3.txt</string>
<key>copyright</key>
- <string>Copyright (C) 1997-2012 Sam Lantinga</string>
+ <string>Copyright (C) 1997-2022 Sam Lantinga (slouken@libsdl.org)</string>
<key>version</key>
- <string>1.2.15</string>
+ <string>3.2.24-r1</string>
+ <key>use_scm_version</key>
+ <boolean>true</boolean>
<key>name</key>
- <string>SDL</string>
+ <string>SDL3</string>
<key>description</key>
<string>Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer.</string>
</map>
@@ -46,11 +78,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>a21487f4e3a68721fd97edef117795a1b7212a77</string>
+ <string>3f8e58fe74e144b771858e89a5514bf354964c76</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.5-r1/apr_suite-1.7.5-12259255574-darwin64-12259255574.tar.zst</string>
+ <string>https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.5-r2/apr_suite-1.7.5-18696779749-darwin64-18696779749.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -60,11 +92,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>45baf82d3366734e542a2a3749f495b64f5513b4</string>
+ <string>df36114eb8fb66fdcbb190011222a7d336791d98</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.5-r1/apr_suite-1.7.5-12259255574-linux64-12259255574.tar.zst</string>
+ <string>https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.5-r2/apr_suite-1.7.5-18696779749-linux64-18696779749.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -74,11 +106,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>bdd35d3b9580d3cdcb98afae639936aaa40e24c4</string>
+ <string>164705831819d247753c9fd608c2c1ac8dca1883</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.5-r1/apr_suite-1.7.5-12259255574-windows64-12259255574.tar.zst</string>
+ <string>https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.5-r2/apr_suite-1.7.5-18696779749-windows64-18696779749.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -91,7 +123,7 @@
<key>copyright</key>
<string>Copyright © 2012 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.</string>
<key>version</key>
- <string>1.7.5-12259255574</string>
+ <string>1.7.5-18696779749</string>
<key>name</key>
<string>apr_suite</string>
<key>description</key>
@@ -270,11 +302,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>d5fb3832a338bbe4891b823c64fdb4806706568e</string>
+ <string>e21e7755fe740d5ed30bd29441170449a57caa8b</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-darwin64-d7afe27.tar.zst</string>
+ <string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-cb8785a/cubemaptoequirectangular-1.1.0-darwin64-cb8785a.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -284,11 +316,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>77c53daf558f51aec6e9f4bd9e930a103630ee7d</string>
+ <string>aea0bed0f953a9371b9091f09230b41597f891f7</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-linux64-d7afe27.tar.zst</string>
+ <string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-cb8785a/cubemaptoequirectangular-1.1.0-linux64-cb8785a.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -298,11 +330,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>6c51855bcf3a8628289881fdaea08c25cf7b1b90</string>
+ <string>eabc3b0c9d9084f49b8a4dc5d3834d77f668c27a</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-windows64-d7afe27.tar.zst</string>
+ <string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-cb8785a/cubemaptoequirectangular-1.1.0-windows64-cb8785a.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -379,36 +411,6 @@
<key>description</key>
<string>Library for transferring data specified with URL syntax</string>
</map>
- <key>dbus_glib</key>
- <map>
- <key>platforms</key>
- <map>
- <key>linux64</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>7ee7b9aed3c0c8c09e7bf26bba7af8e1</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-dbus-glib/rev/314266/arch/Linux/installer/dbus_glib-0.76-linux64-314266.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux64</string>
- </map>
- </map>
- <key>license</key>
- <string>Academic Free License v. 2.1</string>
- <key>license_file</key>
- <string>LICENSES/dbus-glib.txt</string>
- <key>copyright</key>
- <string>Copyright (C) Red Hat Inc.</string>
- <key>version</key>
- <string>0.76</string>
- <key>name</key>
- <string>dbus_glib</string>
- <key>description</key>
- <string>D-Bus bindings for glib</string>
- </map>
<key>dictionaries</key>
<map>
<key>platforms</key>
@@ -450,11 +452,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>126e0fa4c16dfd433c9fb7d1d242da98f213d933</string>
+ <string>2c81fa7aa03b427088ab54ce3b71088a0003126b</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/dullahan/releases/download/v1.24.0-CEF_139.0.40/dullahan-1.24.0.202510081737_139.0.40_g465474a_chromium-139.0.7258.139-darwin64-18353103947.tar.zst</string>
+ <string>https://github.com/secondlife/dullahan/releases/download/v1.26.0-CEF_139.0.40/dullahan-1.26.0.202510161627_139.0.40_g465474a_chromium-139.0.7258.139-darwin64-18568015445.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -464,11 +466,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>209d031ae67bc66d8e8f8509c71d259014c65ceb</string>
+ <string>8e06d060729250c5bfcb993c8f818f36ea17de16</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/dullahan/releases/download/v1.14.0-r3/dullahan-1.14.0.202408091637_118.4.1_g3dd6078_chromium-118.0.5993.54-linux64-10322607516.tar.zst</string>
+ <string>https://github.com/secondlife/dullahan/releases/download/v1.26.0-CEF_139.0.40/dullahan-1.26.0.202510161627_139.0.40_g465474a_chromium-139.0.7258.139-linux64-18568015445.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -478,11 +480,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>20de62c9e57d9e6539c1e2437ec4b46c3ca237bc</string>
+ <string>7ca6db37f019b47e230c0861607c546d45535367</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/dullahan/releases/download/v1.24.0-CEF_139.0.40/dullahan-1.24.0.202510081738_139.0.40_g465474a_chromium-139.0.7258.139-windows64-18353103947.tar.zst</string>
+ <string>https://github.com/secondlife/dullahan/releases/download/v1.26.0-CEF_139.0.40/dullahan-1.26.0.202510161628_139.0.40_g465474a_chromium-139.0.7258.139-windows64-18568015445.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -495,7 +497,7 @@
<key>copyright</key>
<string>Copyright (c) 2017, Linden Research, Inc.</string>
<key>version</key>
- <string>1.24.0.202510081737_139.0.40_g465474a_chromium-139.0.7258.139</string>
+ <string>1.26.0.202510161627_139.0.40_g465474a_chromium-139.0.7258.139</string>
<key>name</key>
<string>dullahan</string>
<key>description</key>
@@ -595,36 +597,6 @@
<key>description</key>
<string>Expat is an XML parser library written in C</string>
</map>
- <key>fontconfig</key>
- <map>
- <key>platforms</key>
- <map>
- <key>linux64</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>e2419d56960c160670051fbb055fb729</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-fontconfig/rev/314281/arch/Linux/installer/fontconfig-2.11.0-linux64-314281.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux64</string>
- </map>
- </map>
- <key>license</key>
- <string>bsd</string>
- <key>license_file</key>
- <string>LICENSES/fontconfig.txt</string>
- <key>copyright</key>
- <string>Copyright (C) 2000,2001,2002,2003,2004,2006,2007 Keith Packard, 2005 Patrick Lam, 2009 Roozbeh Pournader, 2008,2009 Red Hat, Inc., 2008 Danilo Å egan, 2012 Google, Inc.</string>
- <key>version</key>
- <string>2.11.0</string>
- <key>name</key>
- <string>fontconfig</string>
- <key>description</key>
- <string>Fontconfig is a library for configuring and customizing font access.</string>
- </map>
<key>freetype</key>
<map>
<key>platforms</key>
@@ -694,11 +666,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>7cc58b3acb230a7e65ea5f0ff800be393eb4aa1b</string>
+ <string>90eade4785ee8acf18837125208b717f7e857d06</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-glext/releases/download/v69/glext-68-common-685b36e.tar.zst</string>
+ <string>https://github.com/secondlife/3p-glext/releases/download/v2025.10.27-r1/glext-2025.10.27-common-18888617188.tar.zst</string>
</map>
<key>name</key>
<string>common</string>
@@ -711,44 +683,12 @@
<key>copyright</key>
<string>Copyright (c) 2007-2010 The Khronos Group Inc.</string>
<key>version</key>
- <string>68</string>
+ <string>2025.10.27</string>
<key>name</key>
<string>glext</string>
<key>description</key>
<string>glext headers define function prototypes and constants for OpenGL extensions</string>
</map>
- <key>glh_linear</key>
- <map>
- <key>platforms</key>
- <map>
- <key>common</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>066625e7aa7f697a4b6cd461aad960c57181011f</string>
- <key>hash_algorithm</key>
- <string>sha1</string>
- <key>url</key>
- <string>https://github.com/secondlife/3p-glh_linear/releases/download/v1.0.1-dev4-984c397/glh_linear-1.0.1-dev4-common-984c397.tar.zst</string>
- </map>
- <key>name</key>
- <string>common</string>
- </map>
- </map>
- <key>license</key>
- <string>BSD</string>
- <key>license_file</key>
- <string>LICENSES/glh-linear.txt</string>
- <key>copyright</key>
- <string>Copyright (c) 2000 Cass Everitt</string>
- <key>version</key>
- <string>1.0.1-dev4</string>
- <key>name</key>
- <string>glh_linear</string>
- <key>description</key>
- <string>glh - is a platform-indepenedent C++ OpenGL helper library</string>
- </map>
<key>glm</key>
<map>
<key>platforms</key>
@@ -791,62 +731,6 @@
<key>source_type</key>
<string>git</string>
</map>
- <key>gstreamer</key>
- <map>
- <key>platforms</key>
- <map>
- <key>linux64</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>7c9d7cc88add7831a6afeedc20cad2fe</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gstreamer/rev/314267/arch/Linux/installer/gstreamer-0.10.6.314267-linux64-314267.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux64</string>
- </map>
- </map>
- <key>license</key>
- <string>LGPL</string>
- <key>license_file</key>
- <string>LICENSES/gstreamer.txt</string>
- <key>copyright</key>
- <string>Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</string>
- <key>version</key>
- <string>0.10.6.314267</string>
- <key>name</key>
- <string>gstreamer</string>
- </map>
- <key>gtk-atk-pango-glib</key>
- <map>
- <key>platforms</key>
- <map>
- <key>linux64</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>de7bba8fd2275a11b077b124413065d0</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gtk-atk-pango-glib/rev/314220/arch/Linux/installer/gtk_atk_pango_glib-0.1-linux64-314220.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux64</string>
- </map>
- </map>
- <key>license</key>
- <string>lgpl</string>
- <key>license_file</key>
- <string>LICENSES/gtk-atk-pango-glib.txt</string>
- <key>copyright</key>
- <string>Copyright (various, see sources)</string>
- <key>version</key>
- <string>0.1</string>
- <key>name</key>
- <string>gtk-atk-pango-glib</string>
- </map>
<key>havok-source</key>
<map>
<key>platforms</key>
@@ -858,11 +742,11 @@
<key>creds</key>
<string>github</string>
<key>hash</key>
- <string>ae2c2a215b1bc2e3f37a67e301926dc405902d1a</string>
+ <string>1648aeb68395cba38f9326c671609d6730cbcc28</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/136778143</string>
+ <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/196725921</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -871,10 +755,14 @@
<map>
<key>archive</key>
<map>
+ <key>creds</key>
+ <string>github</string>
<key>hash</key>
- <string>00d0333936a67059a43a6ec8ac38d564</string>
+ <string>702ad28b6dbace2a68260d69f6d1768d163b5a6f</string>
+ <key>hash_algorithm</key>
+ <string>sha1</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/748/1563/havok_source-2012.1-2-linux64-500739.tar.bz2</string>
+ <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/196725902</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -886,11 +774,11 @@
<key>creds</key>
<string>github</string>
<key>hash</key>
- <string>0393dd75c58f7046bed47e62a8884a78cb02a5c3</string>
+ <string>ea980f372981fe7685f91a111da2785825d473ed</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/136778145</string>
+ <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/196725911</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -1081,22 +969,6 @@
<key>name</key>
<string>windows64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>creds</key>
- <string>github</string>
- <key>hash</key>
- <string>85e294becce8b2ac5d2e5e052b0e21ff865d1108</string>
- <key>hash_algorithm</key>
- <string>sha1</string>
- <key>url</key>
- <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/208381806</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
</map>
<key>license</key>
<string>Kakadu</string>
@@ -1277,36 +1149,6 @@
<key>description</key>
<string>PNG Reference library</string>
</map>
- <key>libuuid</key>
- <map>
- <key>platforms</key>
- <map>
- <key>linux64</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>fb89f1281dd54d8b99b339fc5b712b27</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libuuid/rev/314269/arch/Linux/installer/libuuid-1.6.2-linux64-314269.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux64</string>
- </map>
- </map>
- <key>license</key>
- <string>UUID</string>
- <key>license_file</key>
- <string>LICENSES/uuid.txt</string>
- <key>copyright</key>
- <string>Copyright (c) 2004-2008 The OSSP Project &lt;http://www.ossp.org/&gt;</string>
- <key>version</key>
- <string>1.6.2</string>
- <key>name</key>
- <string>libuuid</string>
- <key>description</key>
- <string>OSSP uuid is a ISO-C:1999 application programming interface (API) and corresponding command line interface (CLI) for the generation of DCE 1.1, ISO/IEC 11578:1996 and RFC 4122 compliant Universally Unique Identifier (UUID). </string>
- </map>
<key>libxml2</key>
<map>
<key>platforms</key>
@@ -1367,36 +1209,6 @@
<key>description</key>
<string>Libxml2 is the XML C parser and toolkit developed for the Gnome project.</string>
</map>
- <key>llappearance_utility</key>
- <map>
- <key>platforms</key>
- <map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>fddd634dec5ec03924d62cc774f7f8ea</string>
- <key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/p64_viewer-llappearance-utility/rev/317266/arch/Linux/installer/llappearance_utility-0.0.1-linux-317266.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
- </map>
- <key>license</key>
- <string>Proprietary</string>
- <key>license_file</key>
- <string>LICENSES/llappearanceutility.txt</string>
- <key>copyright</key>
- <string>Copyright (c) 2000-2012, Linden Research, Inc.</string>
- <key>version</key>
- <string>0.0.1</string>
- <key>name</key>
- <string>llappearance_utility</string>
- <key>description</key>
- <string>Linden Lab appearance utility for server-side avatar baking services.</string>
- </map>
<key>llca</key>
<map>
<key>platforms</key>
@@ -1512,32 +1324,6 @@
<key>name</key>
<string>llphysicsextensions_tpv</string>
</map>
- <key>mesa</key>
- <map>
- <key>platforms</key>
- <map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>22c50a5d362cad311b4f413cfcffbba2</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/mesa_3p-update-mesa/rev/297294/arch/Linux/installer/mesa-7.11.1.297294-linux-297294.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
- </map>
- <key>license</key>
- <string>mesa</string>
- <key>license_file</key>
- <string>LICENSES/mesa.txt</string>
- <key>version</key>
- <string>7.11.1.297294</string>
- <key>name</key>
- <string>mesa</string>
- </map>
<key>meshoptimizer</key>
<map>
<key>platforms</key>
@@ -1937,6 +1723,23 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
</map>
<key>open-libndofdev</key>
<map>
+ <key>platforms</key>
+ <map>
+ <key>linux64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>612bfcb7cf0e6afaf7ce7f1db6feccd81137eb99</string>
+ <key>hash_algorithm</key>
+ <string>sha1</string>
+ <key>url</key>
+ <string>https://github.com/secondlife/3p-open-libndofdev/releases/download/v1.14-r7/open_libndofdev-0.14.19022717849-linux64-19022717849.tar.zst</string>
+ </map>
+ <key>name</key>
+ <string>linux64</string>
+ </map>
+ </map>
<key>license</key>
<string>BSD</string>
<key>license_file</key>
@@ -1944,7 +1747,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>copyright</key>
<string>Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com)</string>
<key>version</key>
- <string>0.14.11968684513</string>
+ <string>0.14.19022717849</string>
<key>name</key>
<string>open-libndofdev</string>
<key>description</key>
@@ -2019,11 +1822,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>94a72c6ddbfb23796ce913c55bc47c128542a582</string>
+ <string>8dc190451c5b7af0d72e7ab54f8fbde6dccf79c6</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.3-r1/openjpeg-2.5.3.15590356935-darwin64-15590356935.tar.zst</string>
+ <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.4-r1/openjpeg-2.5.4.18754730947-darwin64-18754730947.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -2033,11 +1836,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>751172af405f4a47a3aebb37729d62229cab6c07</string>
+ <string>9c89879f81ee0434e1f59c47d74a25958ae08e9e</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.3-r1/openjpeg-2.5.3.15590356935-linux64-15590356935.tar.zst</string>
+ <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.4-r1/openjpeg-2.5.4.18754730947-linux64-18754730947.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -2047,11 +1850,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>8aab9cf250dfee252386e1c79b5205e6d3b3e19e</string>
+ <string>b78887212f18ae59dc7961e0e1af781e568bd92c</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.3-r1/openjpeg-2.5.3.15590356935-windows64-15590356935.tar.zst</string>
+ <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.4-r1/openjpeg-2.5.4.18754730947-windows64-18754730947.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -2064,7 +1867,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>copyright</key>
<string>Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium; Copyright (c) 2002-2007, Professor Benoit Macq; Copyright (c) 2001-2003, David Janssens; Copyright (c) 2002-2003, Yannick Verschueren; Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe; Copyright (c) 2005, Herve Drolon, FreeImage Team; Copyright (c) 2006-2007, Parvatha Elangovan; Copyright (c) 2008, Jerome Fimes, Communications &amp; Systemes &lt;jerome.fimes@c-s.fr&gt;; Copyright (c) 2010-2011, Kaori Hagihara; Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France; Copyright (c) 2012, CS Systemes d'Information, France;</string>
<key>version</key>
- <string>2.5.3.15590356935</string>
+ <string>2.5.4.18754730947</string>
<key>name</key>
<string>openjpeg</string>
<key>description</key>
@@ -2542,7 +2345,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>description</key>
<string>Linden Lab Viewer Management Process suite.</string>
<key>source</key>
- <string>https://bitbucket.org/lindenlab/vmp-standalone</string>
+ <string>https://github.com/secondlife/viewer-manager</string>
<key>source_type</key>
<string>hg</string>
</map>
@@ -2633,11 +2436,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>43c5f93517794aeade550e4266b959d1f0cfcb7f</string>
+ <string>a5e72a9d13b6c4646d1e02b5820f16560d204de7</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-darwin64-17630578914.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.21/webrtc-m137.7151.04.21.18609120431-darwin64-18609120431.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -2647,11 +2450,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>efc5b176d878cfc16b8f82445d82ddb96815b6ab</string>
+ <string>1030e5086f401d738463223da3ed99c225340f39</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-linux64-17630578914.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.21/webrtc-m137.7151.04.21.18609120431-linux64-18609120431.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -2661,11 +2464,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>1e36f100de32c7c71325497a672fb1659b3f206d</string>
+ <string>d1cae9bc8866ca01aa9f5e72b36d12ef608b1998</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-windows64-17630578914.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.21/webrtc-m137.7151.04.21.18609120431-windows64-18609120431.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -2678,7 +2481,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>copyright</key>
<string>Copyright (c) 2011, The WebRTC project authors. All rights reserved.</string>
<key>version</key>
- <string>m137.7151.04.20-universal.17630578914</string>
+ <string>m137.7151.04.21.18609120431</string>
<key>name</key>
<string>webrtc</string>
<key>vcs_branch</key>
@@ -2891,11 +2694,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>140d8fc952a10edb5f2d72ab405336019ef32cadfa64f0cfce76c9de4bc6268cbc87cc8cd89d3417fb78b531d441701afc8d016bafe4bd275df2707f7daf1387</string>
+ <string>49046b0b41310d2fb0d72853730b2faad35d3e36</string>
<key>hash_algorithm</key>
- <string>blake2b</string>
+ <string>sha1</string>
<key>url</key>
- <string>https://github.com/AlchemyViewer/3p-vhacd/releases/download/v4.1.0-r2/vhacd-4.1.0-r2-common-18166921729.tar.zst</string>
+ <string>https://github.com/secondlife/3p-vhacd/releases/download/v4.1.0-r1/vhacd-4.1.0-r1-common-18475951995.tar.zst</string>
</map>
<key>name</key>
<string>common</string>
@@ -2908,7 +2711,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>copyright</key>
<string>Copyright (c) 2011, Khaled Mamou</string>
<key>version</key>
- <string>4.1.0-r2</string>
+ <string>4.1.0-r1</string>
<key>name</key>
<string>vhacd</string>
<key>description</key>
@@ -3183,15 +2986,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<map>
<key>configurations</key>
<map>
- <key>Release</key>
+ <key>RelWithDebInfo</key>
<map>
<key>configure</key>
<map>
<key>options</key>
<array>
<string>-G</string>
- <string>Ninja</string>
- <string>-DLL_TESTS=Off</string>
+ <string>Unix Makefiles</string>
</array>
<key>arguments</key>
<array>
@@ -3201,14 +3003,23 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>build</key>
<map>
<key>command</key>
- <string>ninja</string>
+ <string>cmake</string>
+ <key>options</key>
+ <array>
+ <string>--build</string>
+ <string>.</string>
+ <string>--config</string>
+ <string>Release</string>
+ <string>--parallel</string>
+ <string>$AUTOBUILD_CPU_COUNT</string>
+ </array>
</map>
<key>default</key>
<string>True</string>
<key>name</key>
- <string>Release</string>
+ <string>RelWithDebInfo</string>
</map>
- <key>ReleaseOS</key>
+ <key>RelWithDebInfoOS</key>
<map>
<key>configure</key>
<map>
@@ -3216,24 +3027,82 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<array>
<string>-G</string>
<string>Ninja</string>
- <string>-DLL_TESTS=Off</string>
</array>
</map>
<key>build</key>
<map>
<key>command</key>
- <string>ninja</string>
+ <string>cmake</string>
+ <key>options</key>
+ <array>
+ <string>--build</string>
+ <string>.</string>
+ <string>--config</string>
+ <string>Release</string>
+ <string>--parallel</string>
+ <string>$AUTOBUILD_CPU_COUNT</string>
+ </array>
</map>
<key>name</key>
- <string>ReleaseOS</string>
+ <string>RelWithDebInfoOS</string>
+ </map>
+ <key>Release</key>
+ <map>
+ <key>configure</key>
+ <map>
+ <key>options</key>
+ <array>
+ <string>-G</string>
+ <string>Unix Makefiles</string>
+ </array>
+ <key>arguments</key>
+ <array>
+ <string>../indra</string>
+ </array>
+ </map>
+ <key>build</key>
+ <map>
+ <key>command</key>
+ <string>cmake</string>
+ <key>options</key>
+ <array>
+ <string>--build</string>
+ <string>.</string>
+ <string>--config</string>
+ <string>Release</string>
+ <string>--parallel</string>
+ <string>$AUTOBUILD_CPU_COUNT</string>
+ </array>
+ </map>
+ <key>name</key>
+ <string>Release</string>
</map>
- <key>default</key>
+ <key>ReleaseOS</key>
<map>
+ <key>configure</key>
+ <map>
+ <key>options</key>
+ <array>
+ <string>-G</string>
+ <string>Ninja</string>
+ </array>
+ </map>
<key>build</key>
<map>
+ <key>command</key>
+ <string>cmake</string>
+ <key>options</key>
+ <array>
+ <string>--build</string>
+ <string>.</string>
+ <string>--config</string>
+ <string>Release</string>
+ <string>--parallel</string>
+ <string>$AUTOBUILD_CPU_COUNT</string>
+ </array>
</map>
<key>name</key>
- <string>default</string>
+ <string>ReleaseOS</string>
</map>
</map>
<key>build_directory</key>
@@ -3264,15 +3133,15 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>build</key>
<map>
<key>command</key>
- <string>devenv</string>
+ <string>cmake</string>
<key>options</key>
<array>
- <string>/build</string>
- <string>RelWithDebInfo|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
- </array>
- <key>arguments</key>
- <array>
- <string>SecondLife.sln</string>
+ <string>--build</string>
+ <string>.</string>
+ <string>--config</string>
+ <string>RelWithDebInfo</string>
+ <string>--parallel</string>
+ <string>$AUTOBUILD_CPU_COUNT</string>
</array>
</map>
<key>default</key>
@@ -3302,19 +3171,15 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>build</key>
<map>
<key>command</key>
- <string>msbuild.exe</string>
+ <string>cmake</string>
<key>options</key>
<array>
- <string>/p:Configuration=RelWithDebInfo</string>
- <string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
- <string>/t:Build</string>
- <string>/p:useenv=true</string>
- <string>/verbosity:minimal</string>
- <string>/p:VCBuildAdditionalOptions= /incremental</string>
- </array>
- <key>arguments</key>
- <array>
- <string>SecondLife.sln</string>
+ <string>--build</string>
+ <string>.</string>
+ <string>--config</string>
+ <string>RelWithDebInfo</string>
+ <string>--parallel</string>
+ <string>$AUTOBUILD_CPU_COUNT</string>
</array>
</map>
<key>name</key>
@@ -3339,15 +3204,15 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>build</key>
<map>
<key>command</key>
- <string>devenv</string>
+ <string>cmake</string>
<key>options</key>
<array>
- <string>/build</string>
- <string>Release|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
- </array>
- <key>arguments</key>
- <array>
- <string>SecondLife.sln</string>
+ <string>--build</string>
+ <string>.</string>
+ <string>--config</string>
+ <string>Release</string>
+ <string>--parallel</string>
+ <string>$AUTOBUILD_CPU_COUNT</string>
</array>
</map>
<key>name</key>
@@ -3376,19 +3241,15 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>build</key>
<map>
<key>command</key>
- <string>msbuild.exe</string>
+ <string>cmake</string>
<key>options</key>
<array>
- <string>/p:Configuration=Release</string>
- <string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
- <string>/t:Build</string>
- <string>/p:useenv=true</string>
- <string>/verbosity:minimal</string>
- <string>/p:VCBuildAdditionalOptions= /incremental</string>
- </array>
- <key>arguments</key>
- <array>
- <string>SecondLife.sln</string>
+ <string>--build</string>
+ <string>.</string>
+ <string>--config</string>
+ <string>Release</string>
+ <string>--parallel</string>
+ <string>$AUTOBUILD_CPU_COUNT</string>
</array>
</map>
<key>name</key>
diff --git a/build.sh b/build.sh
index ba90065827..31604663f1 100755
--- a/build.sh
+++ b/build.sh
@@ -45,7 +45,7 @@ build_dir_Darwin()
build_dir_Linux()
{
- echo build-linux-i686
+ echo build-linux-x86_64
}
build_dir_CYGWIN()
@@ -119,11 +119,13 @@ EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
metadata=()
symbolfile=()
physicstpv=()
+appearanceutility=()
# and dump them to GITHUB_OUTPUT when done
cleanup="$cleanup ; \
arrayoutput metadata ; \
arrayoutput symbolfile ; \
-arrayoutput physicstpv"
+arrayoutput physicstpv ; \
+arrayoutput appearanceutility"
trap "$cleanup" EXIT
arrayoutput()
@@ -163,6 +165,12 @@ pre_build()
fi
fi
+ if [[ "$arch" == "Linux" ]]
+ then
+ # RELEASE_CRASH_REPORTING is tuned on unconditionaly, this is fine but not for Linux as of now (due to missing breakpad/crashpad support)
+ RELEASE_CRASH_REPORTING=OFF
+ fi
+
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
then
case "$arch" in
@@ -246,6 +254,10 @@ build()
"$autobuild" build --no-configure -c $variant \
$eval_autobuild_build_parameters \
|| fatal "failed building $variant"
+
+ ctest -C Release --test-dir "${build_dir}" --output-on-failure -j $(nproc --all) \
+ || fatal "failed testing $variant"
+
echo true >"$build_dir"/build_ok
end_section "autobuild $variant"
@@ -394,12 +406,7 @@ do
python_cmd "$helpers/codeticket.py" addoutput "Autobuild Metadata" "$build_dir/autobuild-package.xml" --mimetype text/xml \
|| fatal "Upload of autobuild metadata failed"
metadata+=("$build_dir/autobuild-package.xml")
- if [ "$arch" != "Linux" ]
- then
- record_dependencies_graph "$build_dir/autobuild-package.xml" # defined in buildscripts/hg/bin/build.sh
- else
- record_event "TBD - no dependency graph for linux (probable python version dependency)"
- fi
+ record_dependencies_graph "$build_dir/autobuild-package.xml" # defined in buildscripts/hg/bin/build.sh
end_section "Autobuild metadata"
else
record_event "no autobuild metadata at '$build_dir/autobuild-package.xml'"
@@ -537,6 +544,14 @@ then
symbolfile+=("$symbol_file")
fi
+ # Upload our apperance utility packages for linux
+ if [ "$arch" == "Linux" ]
+ then
+ appearance_utility_dir="${build_dir}/llappearanceutility"
+ appearanceutility+=("${appearance_utility_dir}/appearance-utility-bin")
+ appearanceutility+=("${appearance_utility_dir}/appearance-utility-headless-bin")
+ fi
+
# Upload the llphysicsextensions_tpv package, if one was produced
# Only upload this package when building the private repo so the
# artifact is private.
diff --git a/doc/BUILD.LINUX.md b/doc/BUILD.LINUX.md
new file mode 100644
index 0000000000..28c0689cd5
--- /dev/null
+++ b/doc/BUILD.LINUX.md
@@ -0,0 +1,79 @@
+# Building on Linux
+
+## Install Dependencies
+
+### AlmaLinux 10
+```
+sudo dnf group install "Development Tools"
+sudo dnf install cmake fontconfig-devel git glib2-devel gstreamer1-devel gstreamer1-plugins-base-devel libX11-devel mesa-libOSMesa-devel libglvnd-devel ninja-build python3 vlc-devel wayland-devel
+```
+> [!NOTE]
+> You may need to enable the EPEL repository for some packages `sudo dnf install epel-release`
+
+### Arch
+```
+sudo pacman -Syu base-devel cmake fontconfig git glib2-devel gstreamer gst-plugins-base-libs ninja libglvnd libvlc libx11 python wayland
+```
+
+### Debian - Ubuntu 22.04 - Ubuntu 24.04
+```
+sudo apt install build-essential cmake git libfontconfig-dev libglib2.0-dev libglvnd-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libosmesa6-dev libvlc-dev libwayland-dev libx11-dev ninja-build python3 python3-venv
+```
+
+### Fedora
+```
+sudo dnf install @development-tools @c-development cmake fontconfig-devel git glib-devel gstreamer1-devel gstreamer1-plugins-base-devel libX11-devel mesa-compat-libOSMesa-devel libglvnd-devel ninja-build python3 vlc-devel wayland-devel
+```
+
+### OpenSUSE Tumbleweed
+```
+sudo zypper in -t pattern devel_basis devel_C_C++
+sudo zypper install cmake fontconfig-devel git glib2-devel gstreamer-devel gstreamer-plugins-base-devel libglvnd-devel libX11-devel ninja Mesa-libGL-devel python3 vlc-devel wayland-devel
+```
+
+## Create development folders
+```
+mkdir -p ~/code/secondlife
+cd ~/code/secondlife
+```
+
+## Setup Virtual Environment and install Autobuild
+```
+python3 -m venv .venv
+source .venv/bin/activate
+pip install autobuild llsd
+```
+> [!NOTE]
+> If the above was successful you should receive output similar to `autobuild 3.10.2` when running `autobuild --version`
+
+## Setup Build Variables
+```
+git clone https://github.com/secondlife/build-variables.git
+export AUTOBUILD_VARIABLES_FILE=~/code/secondlife/build-variables/variables
+```
+
+## Clone Viewer
+```
+git clone https://github.com/secondlife/viewer.git
+cd ~/code/secondlife/viewer
+```
+
+## Configure Viewer
+
+### GCC
+```
+autobuild configure -c ReleaseOS -A64
+```
+
+### Clang
+```
+autobuild configure -c ReleaseOS -- -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_LINKER_TYPE=LLD
+```
+
+## Build Viewer
+```
+autobuild build -c ReleaseOS --no-configure
+```
+
+> [!NOTE]
+> If the above was successful you should find the viewer package in `viewer/build-linux-x86_64/newview`
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 8fde58fa43..61a2916bdb 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -56,8 +56,37 @@ if (NOT CMAKE_BUILD_TYPE)
"Build type. One of: Debug Release RelWithDebInfo" FORCE)
endif (NOT CMAKE_BUILD_TYPE)
+if (LL_TESTS)
+ set(CMAKE_SKIP_TEST_ALL_DEPENDENCY FALSE)
+ include(ProcessorCount)
+ ProcessorCount(NUM_CORES)
+
+ # Set parallel level to decrease test runtime
+ set(CMAKE_CTEST_ARGUMENTS -j${NUM_CORES} --output-on-failure)
+
+ # Set up our test targets
+ set(CTEST_TEST_TARGET_ALIAS BUILD_AND_RUN_TESTS)
+ include(CTest)
+
+ set_target_properties(BUILD_AND_RUN_TESTS
+ PROPERTIES
+ FOLDER "CMakePredefinedTargets"
+ )
+
+ add_custom_target(BUILD_TESTS)
+ add_dependencies(BUILD_AND_RUN_TESTS BUILD_TESTS)
+
+ set_target_properties(BUILD_TESTS
+ PROPERTIES
+ FOLDER "CMakePredefinedTargets"
+ )
+endif ()
+
add_subdirectory(cmake)
+if (USE_PRECOMPILED_HEADERS)
+ add_subdirectory(${LIBS_OPEN_PREFIX}llprecompiled)
+endif ()
add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
add_subdirectory(${LIBS_OPEN_PREFIX}llappearance)
add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
@@ -84,10 +113,6 @@ endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
add_custom_target(viewer)
-if (NOT USE_BUGSPLAT)
-add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
-endif (NOT USE_BUGSPLAT)
-
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
@@ -103,16 +128,8 @@ add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
endif (ENABLE_MEDIA_PLUGINS)
if (LINUX)
- if (INSTALL_PROPRIETARY)
- include(LLAppearanceUtility)
- add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
- endif (INSTALL_PROPRIETARY)
-elseif (WINDOWS)
- # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
- if (EXISTS ${VIEWER_DIR}win_setup)
- add_subdirectory(${VIEWER_DIR}win_setup)
- endif (EXISTS ${VIEWER_DIR}win_setup)
-endif (LINUX)
+ add_subdirectory(llappearanceutility)
+endif()
if (WINDOWS)
# cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
diff --git a/indra/cmake/00-COMPILE-LINK-RUN.txt b/indra/cmake/00-COMPILE-LINK-RUN.txt
index 1933072a6d..7b91b5a0d4 100644
--- a/indra/cmake/00-COMPILE-LINK-RUN.txt
+++ b/indra/cmake/00-COMPILE-LINK-RUN.txt
@@ -117,7 +117,7 @@ Compilation
currently being generated with a link path of
'@executable_path/../Resources/<library>'. If we were to follow
the recommendations in dyld's man page, we’d instead reference
- '@loader_path/<library>', use -rpath on the executable link
+ '@loader_path/<library>', use -rpath on the executable link
(pointing to the 'Resources' subdir of the main executable), and
be able to avoid some symlinking in the .app tree.
@@ -162,7 +162,7 @@ Linking
* Update the autobuild.xml of ALL consumers of the library. In
the case of zlib, that meant updating freetype, libpng, openssl,
- libxml2, fontconfig, curl, Boost, SDL, llqtwebkit, google-mock and
+ libxml2, fontconfig, curl, Boost, SDL3, llqtwebkit, google-mock and
colladadom.
* Confirm by test and observation that the consumers actually use
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 99ea22ab4b..1ab94e13df 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -11,13 +11,20 @@
#
# Also realize that CMAKE_CXX_FLAGS may already be partially populated on
# entry to this file.
+#
+# Additionally CMAKE_C_FLAGS is prepended to CMAKE_CXX_FLAGS_RELEASE and
+# CMAKE_CXX_FLAGS_RELWITHDEBINFO which risks having flags overriden by cmake
+# inserting additional options that are part of the build config type.
#*****************************************************************************
include_guard()
include(Variables)
+include(Linking)
# We go to some trouble to set LL_BUILD to the set of relevant compiler flags.
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}")
+set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} $ENV{LL_BUILD_RELEASE}")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} $ENV{LL_BUILD_RELWITHDEBINFO}")
+
# Given that, all the flags you see added below are flags NOT present in
# https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables.
# Before adding new ones here, it's important to ask: can this flag really be
@@ -25,7 +32,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}")
# as well?
# Portable compilation flags.
-add_compile_definitions( ADDRESS_SIZE=${ADDRESS_SIZE})
+add_compile_definitions(ADDRESS_SIZE=${ADDRESS_SIZE})
# Because older versions of Boost.Bind dumped placeholders _1, _2 et al. into
# the global namespace, Boost now requires either BOOST_BIND_NO_PLACEHOLDERS
# to avoid that or BOOST_BIND_GLOBAL_PLACEHOLDERS to state that we require it
@@ -111,7 +118,7 @@ if (WINDOWS)
#ND: When using something like buildcache (https://github.com/mbitsnbites/buildcache)
# to make those wrappers work /Zi must be changed to /Z7, as /Zi due to it's nature is not compatible with caching
- if(${CMAKE_CXX_COMPILER_LAUNCHER} MATCHES ".*cache.*")
+ if (${CMAKE_CXX_COMPILER_LAUNCHER} MATCHES ".*cache.*")
add_compile_options( /Z7 )
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
@@ -125,9 +132,6 @@ endif (WINDOWS)
if (LINUX)
set(CMAKE_SKIP_RPATH TRUE)
- # EXTERNAL_TOS
- # force this platform to accept TOS via external browser
-
# LL_IGNORE_SIGCHLD
# don't catch SIGCHLD in our base application class for the viewer - some of
# our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The
@@ -135,42 +139,70 @@ if (LINUX)
add_compile_definitions(
_REENTRANT
- _FORTIFY_SOURCE=2
- EXTERNAL_TOS
APPID=secondlife
LL_IGNORE_SIGCHLD
)
+
+ option(ENABLE_ASAN "Enable Address Sanitizer" OFF)
+ option(ENABLE_UBSAN "Enable Undefined Behavior Sanitizer" OFF)
+ option(ENABLE_THREADSAN "Enable Thread Sanitizer" OFF)
+ if(ENABLE_ASAN OR ENABLE_UBSAN OR ENABLE_THREADSAN)
+ set(GCC_DISABLE_FATAL_WARNINGS ON) # Disable warnings as errors during sanitizer builds due to false positives
+
+ add_compile_options(
+ -U_FORTIFY_SOURCE
+ -fno-omit-frame-pointer
+ -fno-common
+ -fsanitize-recover=all
+ )
+
+ # libwebrtc is incompatible with sanitizers
+ set(DISABLE_WEBRTC ON)
+ add_compile_definitions(DISABLE_WEBRTC=1)
+
+ if(ENABLE_ASAN)
+ add_compile_options(-fsanitize=address)
+ add_link_options(-fsanitize=address)
+ endif()
+
+ if(ENABLE_UBSAN)
+ add_compile_options(-fsanitize=undefined)
+ add_link_options(-fsanitize=undefined)
+ endif()
+
+ if(ENABLE_THREADSAN)
+ add_compile_options(-fsanitize=thread)
+ add_link_options(-fsanitize=thread)
+ endif()
+ else()
+ add_compile_definitions($<$<CONFIG:Release>:_FORTIFY_SOURCE=2>)
+ endif()
+
add_compile_options(
+ $<$<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>>:-fstack-protector>
-fexceptions
-fno-math-errno
-fno-strict-aliasing
-fsigned-char
+ -g
-msse2
- -mfpmath=sse
-pthread
- -Wno-parentheses
- -Wno-deprecated
-fvisibility=hidden
)
- if (ADDRESS_SIZE EQUAL 32)
- add_compile_options(-march=pentium4)
- endif (ADDRESS_SIZE EQUAL 32)
-
- # this stops us requiring a really recent glibc at runtime
- add_compile_options(-fno-stack-protector)
- # linking can be very memory-hungry, especially the final viewer link
- set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
-
- set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
+ add_link_options(
+ "LINKER:-z,relro"
+ "LINKER:-z,now"
+ "LINKER:--build-id"
+ "LINKER:--as-needed"
+ "LINKER:--no-undefined"
+ )
endif (LINUX)
if (DARWIN)
# Use rpath loading on macos
set(CMAKE_MACOSX_RPATH TRUE)
- # Warnings should be fatal -- thanks, Nicky Perian, for spotting reversed default
- set(CLANG_DISABLE_FATAL_WARNINGS OFF)
set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
@@ -184,21 +216,22 @@ endif(DARWIN)
if (LINUX OR DARWIN)
add_compile_options(-Wall -Wno-sign-compare -Wno-trigraphs -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable)
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ add_compile_options(-Wno-unused-private-field)
+ endif()
+
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
- # libstdc++ headers contain deprecated declarations that fail on clang
- # macOS currently has many deprecated calls
add_compile_options(-Wno-unused-local-typedef)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- add_compile_options(-Wno-stringop-truncation -Wno-parentheses -Wno-maybe-uninitialized)
- endif()
+ add_compile_options(-Wno-stringop-truncation -Wno-stringop-overflow -Wno-parentheses -Wno-maybe-uninitialized -Wno-unused-local-typedefs)
+ endif ()
if (NOT GCC_DISABLE_FATAL_WARNINGS AND NOT CLANG_DISABLE_FATAL_WARNINGS)
add_compile_options(-Werror)
endif ()
- add_compile_options(${GCC_WARNINGS})
add_compile_options(-m${ADDRESS_SIZE})
endif (LINUX OR DARWIN)
diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake
index 310659686d..e0807a7d19 100644
--- a/indra/cmake/APR.cmake
+++ b/indra/cmake/APR.cmake
@@ -31,8 +31,3 @@ if(DARWIN)
endif()
target_include_directories(ll::apr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/apr-1)
-
-# Fix erroneous check for __attribute__ definition introduced with APR 1.7.5, causing lots of "this declaration may not have extern 'C' linkage" errors in VS
-file(READ ${LIBS_PREBUILT_DIR}/include/apr-1/apr.h APR_HEADER_CONTENTS)
-string(REPLACE "#if !(defined(__attribute__) || defined(__has_attribute))" "#if !defined(__attribute__)" APR_HEADER_CONTENTS "${APR_HEADER_CONTENTS}")
-file(WRITE ${LIBS_PREBUILT_DIR}/include/apr-1/apr.h "${APR_HEADER_CONTENTS}")
diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake
index b57c33c3e0..610a4f6232 100644
--- a/indra/cmake/Boost.cmake
+++ b/indra/cmake/Boost.cmake
@@ -1,5 +1,6 @@
# -*- cmake -*-
include(Prebuilt)
+include(Linking)
include_guard()
@@ -16,107 +17,69 @@ use_prebuilt_binary(boost)
# with the address size.
set(addrsfx "-x${ADDRESS_SIZE}")
-if (WINDOWS)
+find_library(BOOST_CONTEXT_LIBRARY
+ NAMES
+ libboost_context-mt
+ libboost_context-mt${addrsfx}
+ boost_context-mt
+ boost_context-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- find_library(BOOST_CONTEXT_LIBRARY
- NAMES
- libboost_context-mt
- libboost_context-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+find_library(BOOST_FIBER_LIBRARY
+ NAMES
+ libboost_fiber-mt
+ libboost_fiber-mt${addrsfx}
+ boost_fiber-mt
+ boost_fiber-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- find_library(BOOST_FIBER_LIBRARY
- NAMES
- libboost_fiber-mt
- libboost_fiber-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+find_library(BOOST_FILESYSTEM_LIBRARY
+ NAMES
+ libboost_filesystem-mt
+ libboost_filesystem-mt${addrsfx}
+ boost_filesystem-mt
+ boost_filesystem-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- find_library(BOOST_FILESYSTEM_LIBRARY
- NAMES
- 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-mt
+ libboost_program_options-mt${addrsfx}
+ boost_program_options-mt
+ boost_program_options-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- find_library(BOOST_PROGRAMOPTIONS_LIBRARY
- NAMES
- 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}
+ boost_regex-mt
+ boost_regex-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}
+ boost_system-mt
+ boost_system-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-mt
+ libboost_thread-mt${addrsfx}
+ boost_thread-mt
+ boost_thread-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- find_library(BOOST_THREAD_LIBRARY
- NAMES
- libboost_thread-mt
- libboost_thread-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_URL_LIBRARY
- NAMES
- libboost_url-mt
- libboost_url-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
-else (WINDOWS)
-
- find_library(BOOST_CONTEXT_LIBRARY
- NAMES
- boost_context-mt
- boost_context-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_FIBER_LIBRARY
- NAMES
- boost_fiber-mt
- boost_fiber-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_FILESYSTEM_LIBRARY
- NAMES
- 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-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-mt
- boost_thread-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_URL_LIBRARY
- NAMES
- boost_url-mt
- boost_url-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
-endif (WINDOWS)
+find_library(BOOST_URL_LIBRARY
+ NAMES
+ libboost_url-mt
+ libboost_url-mt${addrsfx}
+ boost_url-mt
+ boost_url-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
target_link_libraries(ll::boost INTERFACE
${BOOST_FIBER_LIBRARY}
diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake
index aa151bafc8..6939f9a4da 100644
--- a/indra/cmake/BuildVersion.cmake
+++ b/indra/cmake/BuildVersion.cmake
@@ -46,13 +46,4 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
message(STATUS "Ultimate fallback, revision was blank or not set: will use 0")
set(VIEWER_VERSION_REVISION 0)
endif ("${VIEWER_VERSION_REVISION}" STREQUAL "")
-
- set(VIEWER_CHANNEL_VERSION_DEFINES
- "LL_VIEWER_CHANNEL=${VIEWER_CHANNEL}"
- "LL_VIEWER_VERSION_MAJOR=${VIEWER_VERSION_MAJOR}"
- "LL_VIEWER_VERSION_MINOR=${VIEWER_VERSION_MINOR}"
- "LL_VIEWER_VERSION_PATCH=${VIEWER_VERSION_PATCH}"
- "LL_VIEWER_VERSION_BUILD=${VIEWER_VERSION_REVISION}"
- "LLBUILD_CONFIG=\"${CMAKE_BUILD_TYPE}\""
- )
endif (NOT DEFINED VIEWER_SHORT_VERSION)
diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake
index e27929fa08..5f5c55f0e9 100644
--- a/indra/cmake/CEFPlugin.cmake
+++ b/indra/cmake/CEFPlugin.cmake
@@ -10,9 +10,9 @@ target_include_directories( ll::cef SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/inclu
if (WINDOWS)
target_link_libraries( ll::cef INTERFACE
- libcef.lib
- libcef_dll_wrapper.lib
- dullahan.lib
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libcef.lib
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.lib
+ ${ARCH_PREBUILT_DIRS_RELEASE}/dullahan.lib
)
elseif (DARWIN)
FIND_LIBRARY(APPKIT_LIBRARY AppKit)
@@ -32,4 +32,9 @@ elseif (DARWIN)
)
elseif (LINUX)
+ target_link_libraries( ll::cef INTERFACE
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libdullahan.a
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libcef.so
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
+ )
endif (WINDOWS)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 270a5c8664..6bbc61feaa 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -11,23 +11,24 @@ set(cmake_SOURCE_FILES
Audio.cmake
Boost.cmake
bugsplat.cmake
+ BuildPackagesInfo.cmake
BuildVersion.cmake
CEFPlugin.cmake
CEFPlugin.cmake
CMakeCopyIfDifferent.cmake
- ConfigurePkgConfig.cmake
- CURL.cmake
Copy3rdPartyLibs.cmake
- DBusGlib.cmake
+ CURL.cmake
DeploySharedLibs.cmake
Discord.cmake
DragDrop.cmake
EXPAT.cmake
FindAutobuild.cmake
+ FindPipeWire.cmake
FreeType.cmake
GLEXT.cmake
- GLH.cmake
+ GLIB.cmake
GLM.cmake
+ GStreamer10Plugin.cmake
Havok.cmake
Hunspell.cmake
LLAddBuildTest.cmake
@@ -53,6 +54,7 @@ set(cmake_SOURCE_FILES
Prebuilt.cmake
PulseAudio.cmake
Python.cmake
+ SDL3.cmake
SSE2NEON.cmake
TemplateCheck.cmake
TinyEXR.cmake
diff --git a/indra/cmake/ConfigurePkgConfig.cmake b/indra/cmake/ConfigurePkgConfig.cmake
deleted file mode 100644
index 9e798d663b..0000000000
--- a/indra/cmake/ConfigurePkgConfig.cmake
+++ /dev/null
@@ -1,74 +0,0 @@
-# -*- cmake -*-
-
-SET(DEBUG_PKG_CONFIG "YES")
-
-# Don't change this if manually set by user.
-IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
-
- # Guess at architecture-specific system library paths.
- if (ADDRESS_SIZE EQUAL 32)
- SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib)
- SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib)
- SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu)
- SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu)
- else (ADDRESS_SIZE EQUAL 32)
- SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib)
- SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib)
- SET(PKG_CONFIG_MULTI_GUESS /usr/local/lib/x86_64-linux-gnu)
- SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu)
- endif (ADDRESS_SIZE EQUAL 32)
-
- # Use DPKG architecture, if available.
- IF (${DPKG_ARCH})
- SET(PKG_CONFIG_MULTI_GUESS /usr/lib/${DPKG_ARCH})
- SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usrlocal/lib/${DPKG_ARCH})
- ENDIF (${DPKG_ARCH})
-
- # Explicitly include anything listed in PKG_CONFIG_PATH
- string(REPLACE ":" ";" PKG_CONFIG_PATH_LIST "$ENV{PKG_CONFIG_PATH}")
- FOREACH(PKG_CONFIG_DIR ${PKG_CONFIG_PATH_LIST})
- SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_DIR}/pkgconfig")
- ENDFOREACH(PKG_CONFIG_DIR)
-
- # Look for valid pkgconfig directories.
- FIND_PATH(PKG_CONFIG_ENV pkgconfig ENV LD_LIBRARY_PATH)
- FIND_PATH(PKG_CONFIG_MULTI pkgconfig HINT ${PKG_CONFIG_MULTI_GUESS})
- FIND_PATH(PKG_CONFIG_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_MULTI_LOCAL_GUESS})
- FIND_PATH(PKG_CONFIG_NO_MULTI pkgconfig HINT ${PKG_CONFIG_NO_MULTI_GUESS})
- FIND_PATH(PKG_CONFIG_NO_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_NO_MULTI_LOCAL_GUESS})
-
- # Add anything we found to our list.
- IF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND)
- SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_ENV}/pkgconfig")
- ENDIF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND)
-
- IF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND)
- SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI}/pkgconfig")
- ENDIF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND)
-
- IF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND)
- SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI_LOCAL}/pkgconfig")
- ENDIF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND)
-
- IF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND)
- SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI}/pkgconfig")
- ENDIF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND)
-
- IF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND)
- SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI_LOCAL}/pkgconfig")
- ENDIF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND)
-
- # Also add some non-architecture specific package locations.
- SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:/usr/share/pkgconfig:/usr/local/share/pkgconfig")
-
- # Remove first unwanted ':'
- string(SUBSTRING ${VALID_PKG_LIBDIRS} 1 -1 VALID_PKG_LIBDIRS)
-
- # Set PKG_CONFIG_LIBDIR environment.
- SET(ENV{PKG_CONFIG_LIBDIR} ${VALID_PKG_LIBDIRS})
-ENDIF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
-
-IF(DEBUG_PKG_CONFIG)
- MESSAGE(STATUS "Using PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}")
-ENDIF(DEBUG_PKG_CONFIG)
-
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 680f2f3ac2..9925be5fec 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -98,6 +98,9 @@ if(WINDOWS)
elseif (MSVC_VERSION GREATER_EQUAL 1930 AND MSVC_VERSION LESS 1950) # Visual Studio 2022
set(MSVC_VER 140)
set(MSVC_TOOLSET_VER 143)
+ elseif (MSVC_VERSION GREATER_EQUAL 1950 AND MSVC_VERSION LESS 1970) # Visual Studio 2026
+ set(MSVC_VER 140)
+ set(MSVC_TOOLSET_VER 145)
else (MSVC80)
MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake")
endif (MSVC80)
@@ -135,6 +138,7 @@ if(WINDOWS)
msvcp${MSVC_VER}_atomic_wait.dll
msvcp${MSVC_VER}_codecvt_ids.dll
msvcr${MSVC_VER}.dll
+ vccorlib${MSVC_VER}.dll
vcruntime${MSVC_VER}.dll
vcruntime${MSVC_VER}_1.dll
vcruntime${MSVC_VER}_threads.dll
@@ -211,17 +215,10 @@ elseif(LINUX)
if( USE_AUTOBUILD_3P )
list( APPEND release_files
- libatk-1.0.so
- libfreetype.so.6.6.2
- libfreetype.so.6
- libopenjp2.so
- libuuid.so.16
- libuuid.so.16.0.22
- libfontconfig.so.1.8.0
- libfontconfig.so.1
- libgmodule-2.0.so
- libgobject-2.0.so
- )
+ libSDL3.so
+ libSDL3.so.0
+ libSDL3.so.0.2.24
+ )
endif()
else(WINDOWS)
diff --git a/indra/cmake/DBusGlib.cmake b/indra/cmake/DBusGlib.cmake
deleted file mode 100644
index c9b727ca9d..0000000000
--- a/indra/cmake/DBusGlib.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- cmake -*-
-include(Prebuilt)
-
-add_library( ll::dbus INTERFACE IMPORTED)
-
-if( LINUX )
- # Only define this when not using the prebuild 3ps, lls prebuild is broken
- if( NOT USE_AUTOBUILD_3P )
- target_compile_definitions( ll::dbus INTERFACE LL_DBUS_ENABLED )
- endif()
- use_system_binary(dbus)
-
- use_prebuilt_binary(dbus_glib)
-endif()
diff --git a/indra/cmake/Discord.cmake b/indra/cmake/Discord.cmake
index 95cfaacf5b..0e63d05350 100644
--- a/indra/cmake/Discord.cmake
+++ b/indra/cmake/Discord.cmake
@@ -2,10 +2,23 @@ include(Prebuilt)
include_guard()
-add_library(ll::discord_sdk INTERFACE IMPORTED)
-target_compile_definitions(ll::discord_sdk INTERFACE LL_DISCORD=1)
+option(USE_DISCORD "Enable Discord SDK" OFF)
-use_prebuilt_binary(discord_sdk)
+if(USE_DISCORD)
+ add_library(ll::discord_sdk INTERFACE IMPORTED)
-target_include_directories(ll::discord_sdk SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/discord_sdk)
-target_link_libraries(ll::discord_sdk INTERFACE discord_partner_sdk)
+ target_compile_definitions(ll::discord_sdk INTERFACE LL_DISCORD=1)
+
+ use_prebuilt_binary(discord_sdk)
+
+ find_library(DISCORD_SDK_LIBRARY
+ NAMES
+ discord_partner_sdk
+ discord_partner_sdk.lib
+ libdiscord_partner_sdk.so
+ libdiscord_partner_sdk.dylib
+ PATHS "${ARCH_PREBUILT_DIRS_ARCH_RELEASE}" "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+
+ target_include_directories(ll::discord_sdk SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/discord_sdk)
+ target_link_libraries(ll::discord_sdk INTERFACE ${DISCORD_SDK_LIBRARY})
+endif()
diff --git a/indra/cmake/FindPipeWire.cmake b/indra/cmake/FindPipeWire.cmake
new file mode 100644
index 0000000000..868acf5ec1
--- /dev/null
+++ b/indra/cmake/FindPipeWire.cmake
@@ -0,0 +1,100 @@
+# cmake-format: off
+# .rst: FindPipeWire
+# -------
+#
+# Try to find PipeWire on a Unix system.
+#
+# This will define the following variables:
+#
+# ``PIPEWIRE_FOUND`` True if (the requested version of) PipeWire is available
+# ``PIPEWIRE_VERSION`` The version of PipeWire ``PIPEWIRE_LIBRARIES`` This can
+# be passed to target_link_libraries() instead of the ``PipeWire::PipeWire``
+# target ``PIPEWIRE_INCLUDE_DIRS`` This should be passed to
+# target_include_directories() if the target is not used for linking
+# ``PIPEWIRE_COMPILE_FLAGS`` This should be passed to target_compile_options()
+# if the target is not used for linking
+#
+# If ``PIPEWIRE_FOUND`` is TRUE, it will also define the following imported
+# target:
+#
+# ``PipeWire::PipeWire`` The PipeWire library
+#
+# In general we recommend using the imported target, as it is easier to use.
+# Bear in mind, however, that if the target is in the link interface of an
+# exported library, it must be made available by the package config file.
+
+# =============================================================================
+# Copyright 2014 Alex Merry <alex.merry@kde.org> Copyright 2014 Martin Gräßlin
+# <mgraesslin@kde.org> Copyright 2018-2020 Jan Grulich <jgrulich@redhat.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the copyright notice, this list
+# of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the copyright notice, this
+# list of conditions and the following disclaimer in the documentation and/or
+# other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# =============================================================================
+# cmake-format: on
+
+# Use pkg-config to get the directories and then use these values in the FIND_PATH() and FIND_LIBRARY() calls
+find_package(PkgConfig QUIET)
+
+pkg_search_module(PKG_PIPEWIRE QUIET libpipewire-0.3)
+pkg_search_module(PKG_SPA QUIET libspa-0.2)
+
+set(PIPEWIRE_COMPILE_FLAGS "${PKG_PIPEWIRE_CFLAGS}" "${PKG_SPA_CFLAGS}")
+set(PIPEWIRE_VERSION "${PKG_PIPEWIRE_VERSION}")
+
+find_path(
+ PIPEWIRE_INCLUDE_DIRS
+ NAMES pipewire/pipewire.h
+ HINTS ${PKG_PIPEWIRE_INCLUDE_DIRS} ${PKG_PIPEWIRE_INCLUDE_DIRS}/pipewire-0.3)
+
+find_path(
+ SPA_INCLUDE_DIRS
+ NAMES spa/param/props.h
+ HINTS ${PKG_SPA_INCLUDE_DIRS} ${PKG_SPA_INCLUDE_DIRS}/spa-0.2)
+
+find_library(
+ PIPEWIRE_LIBRARIES
+ NAMES pipewire-0.3
+ HINTS ${PKG_PIPEWIRE_LIBRARY_DIRS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ PipeWire
+ FOUND_VAR PIPEWIRE_FOUND
+ REQUIRED_VARS PIPEWIRE_LIBRARIES PIPEWIRE_INCLUDE_DIRS SPA_INCLUDE_DIRS
+ VERSION_VAR PIPEWIRE_VERSION)
+
+if(PIPEWIRE_FOUND AND NOT TARGET PipeWire::PipeWire)
+ add_library(PipeWire::PipeWire UNKNOWN IMPORTED)
+ set_target_properties(
+ PipeWire::PipeWire
+ PROPERTIES IMPORTED_LOCATION "${PIPEWIRE_LIBRARIES}"
+ INTERFACE_COMPILE_OPTIONS "${PIPEWIRE_COMPILE_FLAGS}"
+ INTERFACE_INCLUDE_DIRECTORIES "${PIPEWIRE_INCLUDE_DIRS};${SPA_INCLUDE_DIRS}")
+endif()
+
+mark_as_advanced(PIPEWIRE_LIBRARIES PIPEWIRE_INCLUDE_DIRS)
+
+include(FeatureSummary)
+set_package_properties(
+ PipeWire PROPERTIES
+ URL "https://www.pipewire.org"
+ DESCRIPTION "PipeWire - multimedia processing")
diff --git a/indra/cmake/FreeType.cmake b/indra/cmake/FreeType.cmake
index 3c635e851b..eb018c09e9 100644
--- a/indra/cmake/FreeType.cmake
+++ b/indra/cmake/FreeType.cmake
@@ -1,6 +1,8 @@
# -*- cmake -*-
include(Prebuilt)
include(Linking)
+include(PNG)
+include(ZLIBNG)
include_guard()
add_library( ll::freetype INTERFACE IMPORTED )
@@ -15,4 +17,4 @@ find_library(FREETYPE_LIBRARY
libfreetype.a
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-target_link_libraries(ll::freetype INTERFACE ${FREETYPE_LIBRARY})
+target_link_libraries(ll::freetype INTERFACE ${FREETYPE_LIBRARY} ll::libpng ll::zlib-ng)
diff --git a/indra/cmake/GLEXT.cmake b/indra/cmake/GLEXT.cmake
index a780966f0c..2124cc2fc8 100644
--- a/indra/cmake/GLEXT.cmake
+++ b/indra/cmake/GLEXT.cmake
@@ -1,8 +1,7 @@
# -*- cmake -*-
include(Prebuilt)
-include(GLH)
-add_library( ll::glext INTERFACE IMPORTED )
+add_library(ll::glext INTERFACE IMPORTED)
use_system_binary(glext)
use_prebuilt_binary(glext)
diff --git a/indra/cmake/GLH.cmake b/indra/cmake/GLH.cmake
deleted file mode 100644
index 0cefc3543a..0000000000
--- a/indra/cmake/GLH.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-include(Prebuilt)
-
-add_library( ll::glh_linear INTERFACE IMPORTED )
-
-use_system_binary( glh_linear )
-use_prebuilt_binary(glh_linear)
diff --git a/indra/cmake/GLIB.cmake b/indra/cmake/GLIB.cmake
new file mode 100644
index 0000000000..f52cbb7f87
--- /dev/null
+++ b/indra/cmake/GLIB.cmake
@@ -0,0 +1,22 @@
+include_guard()
+
+include(Prebuilt)
+
+add_library( ll::glib INTERFACE IMPORTED )
+add_library( ll::glib_headers INTERFACE IMPORTED )
+add_library( ll::gio INTERFACE IMPORTED )
+
+if( LINUX )
+ find_package(PkgConfig REQUIRED)
+ pkg_search_module(GLIB REQUIRED glib-2.0)
+ pkg_search_module(GIO REQUIRED gio-2.0)
+
+ target_include_directories( ll::glib SYSTEM INTERFACE ${GLIB_INCLUDE_DIRS} )
+ target_link_libraries( ll::glib INTERFACE ${GLIB_LDFLAGS} )
+ target_compile_definitions( ll::glib INTERFACE -DLL_GLIB=1)
+
+ target_include_directories( ll::glib_headers SYSTEM INTERFACE ${GLIB_INCLUDE_DIRS} )
+ target_compile_definitions( ll::glib_headers INTERFACE -DLL_GLIB=1)
+
+ target_link_libraries( ll::gio INTERFACE ${GIO_LDFLAGS} )
+endif()
diff --git a/indra/cmake/GStreamer010Plugin.cmake b/indra/cmake/GStreamer010Plugin.cmake
deleted file mode 100644
index 61f6f74033..0000000000
--- a/indra/cmake/GStreamer010Plugin.cmake
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- cmake -*-
-include(Prebuilt)
-if (NOT LINUX)
- return()
-endif()
-
-add_library( ll::gstreamer INTERFACE IMPORTED )
-target_compile_definitions( ll::gstreamer INTERFACE LL_GSTREAMER010_ENABLED=1)
-use_system_binary(gstreamer)
-
-use_prebuilt_binary(gstreamer)
-
diff --git a/indra/cmake/GStreamer10Plugin.cmake b/indra/cmake/GStreamer10Plugin.cmake
new file mode 100644
index 0000000000..01522db3a3
--- /dev/null
+++ b/indra/cmake/GStreamer10Plugin.cmake
@@ -0,0 +1,27 @@
+# -*- cmake -*-
+
+include_guard()
+
+include(Prebuilt)
+include(GLIB)
+
+add_library( ll::gstreamer10 INTERFACE IMPORTED )
+
+if (LINUX)
+ find_package(PkgConfig REQUIRED)
+
+ pkg_check_modules(GSTREAMER10 REQUIRED gstreamer-1.0)
+ pkg_check_modules(GSTREAMER10_PLUGINS_BASE REQUIRED gstreamer-plugins-base-1.0)
+
+ target_include_directories( ll::gstreamer10 SYSTEM INTERFACE ${GSTREAMER10_INCLUDE_DIRS})
+ target_link_libraries( ll::gstreamer10 INTERFACE ll::glib_headers)
+
+endif ()
+
+if (GSTREAMER10_FOUND AND GSTREAMER10_PLUGINS_BASE_FOUND)
+ set(GSTREAMER10 ON CACHE BOOL "Build with GStreamer-1.0 streaming media support.")
+endif (GSTREAMER10_FOUND AND GSTREAMER10_PLUGINS_BASE_FOUND)
+
+if (GSTREAMER10)
+ add_definitions(-DLL_GSTREAMER10_ENABLED=1)
+endif (GSTREAMER10)
diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake
index c544440adc..64e33f6c83 100644
--- a/indra/cmake/Havok.cmake
+++ b/indra/cmake/Havok.cmake
@@ -27,26 +27,26 @@ else (LL_DEBUG_HAVOK)
endif (LL_DEBUG_HAVOK)
set(HAVOK_LIBS
- hkBase
- hkCompat
+ hkgpConvexDecomposition
hkGeometryUtilities
- hkInternal
hkSerialize
hkSceneData
hkpCollide
hkpUtilities
hkpConstraintSolver
hkpDynamics
- hkpInternal
- hkaiInternal
hkaiPathfinding
hkaiAiPhysicsBridge
- hkcdInternal
hkcdCollide
hkpVehicle
hkVisualize
hkaiVisualize
- hkgpConvexDecomposition
+ hkaiInternal
+ hkcdInternal
+ hkpInternal
+ hkInternal
+ hkCompat
+ hkBase
)
unset(HK_DEBUG_LIBRARIES)
@@ -60,16 +60,22 @@ if (DEBUG_PREBUILT)
# but making it pretty is a lot more work
message(STATUS "${ARGN}")
endfunction(DEBUG_MESSAGE)
+ function(DEBUG_EXEC_FUNC)
+ execute_process(COMMAND ${ARGN})
+ endfunction(DEBUG_EXEC_FUNC)
else (DEBUG_PREBUILT)
# without DEBUG_PREBUILT, DEBUG_MESSAGE() is a no-op
function(DEBUG_MESSAGE)
endfunction(DEBUG_MESSAGE)
+ function(DEBUG_EXEC_FUNC)
+ execute_process(COMMAND ${ARGN} OUTPUT_QUIET)
+ endfunction(DEBUG_EXEC_FUNC)
endif (DEBUG_PREBUILT)
# DEBUG_EXEC() reports each execute_process() before invoking
function(DEBUG_EXEC)
DEBUG_MESSAGE(${ARGN})
- execute_process(COMMAND ${ARGN})
+ DEBUG_EXEC_FUNC(${ARGN})
endfunction(DEBUG_EXEC)
# *TODO: Figure out why we need to extract like this...
@@ -79,9 +85,7 @@ foreach(HAVOK_LIB ${HAVOK_LIBS})
find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
if(LINUX)
- set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
- set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
# Try to avoid extracting havok library each time we run cmake.
if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted")
@@ -92,8 +96,8 @@ foreach(HAVOK_LIB ${HAVOK_LIBS})
if(${PREBUILD_TRACKING_DIR}/havok_source_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
DEBUG_MESSAGE("Extracting ${HAVOK_LIB}...")
- foreach(lib ${debug_dir} ${release_dir} ${relwithdebinfo_dir})
- DEBUG_EXEC("mkdir" ${lib})
+ foreach(lib ${release_dir})
+ DEBUG_EXEC("mkdir" "-p" ${lib})
DEBUG_EXEC("ar" "-xv" "../lib${HAVOK_LIB}.a"
WORKING_DIRECTORY ${lib})
endforeach(lib)
@@ -104,17 +108,12 @@ foreach(HAVOK_LIB ${HAVOK_LIBS})
endif()
- file(GLOB extracted_debug "${debug_dir}/*.o")
file(GLOB extracted_release "${release_dir}/*.o")
- file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
-
- DEBUG_MESSAGE("extracted_debug ${debug_dir}/*.o")
DEBUG_MESSAGE("extracted_release ${release_dir}/*.o")
- DEBUG_MESSAGE("extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")
- list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
+ list(APPEND HK_DEBUG_LIBRARIES ${extracted_release})
list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
- list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
+ list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_release})
else(LINUX)
# Win32
list(APPEND HK_DEBUG_LIBRARIES ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
diff --git a/indra/cmake/JPEG.cmake b/indra/cmake/JPEG.cmake
index f864ca7f8d..49880e7f72 100644
--- a/indra/cmake/JPEG.cmake
+++ b/indra/cmake/JPEG.cmake
@@ -11,6 +11,9 @@ use_prebuilt_binary(libjpeg-turbo)
find_library(JPEG_LIBRARY
NAMES
+ jpeg
+ jpeg-static
+ jpeg-static.lib
jpeg.lib
libjpeg.a
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 83725ffd1b..bd2f894c97 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -1,4 +1,11 @@
# -*- cmake -*-
+
+include_guard()
+
+if( NOT LL_TESTS )
+ return()
+endif()
+
include(00-Common)
include(LLTestCommand)
include(bugsplat)
@@ -26,8 +33,6 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
#project(UNITTEST_PROJECT_${project})
# Setup includes, paths, etc
set(alltest_SOURCE_FILES
- ${CMAKE_SOURCE_DIR}/test/test.cpp
- ${CMAKE_SOURCE_DIR}/test/lltut.cpp
)
set(alltest_DEP_TARGETS
# needed by the test harness itself
@@ -35,6 +40,7 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
)
set(alltest_LIBRARIES
+ lltut_runner_lib
llcommon
)
if(NOT "${project}" STREQUAL "llmath")
@@ -100,6 +106,10 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
)
endif(DARWIN)
+ if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(PROJECT_${project}_TEST_${name} REUSE_FROM llprecompiled)
+ endif ()
+
#
# Per-codefile additional / external project dep and lib dep property extraction
#
@@ -122,7 +132,9 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
set_target_properties(PROJECT_${project}_TEST_${name}
PROPERTIES
COMPILE_FLAGS "${${name}_test_additional_CFLAGS}"
- COMPILE_DEFINITIONS "LL_TEST=${name};LL_TEST_${name}")
+ COMPILE_DEFINITIONS "LL_TEST=${name};LL_TEST_${name}"
+ FOLDER "Tests"
+ )
if(LL_TEST_VERBOSE)
message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
endif()
@@ -131,6 +143,7 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
# test binaries always need to be signed for local development
set_target_properties(PROJECT_${project}_TEST_${name}
PROPERTIES
+ OSX_ARCHITECTURES ${LL_MACOS_TEST_ARCHITECTURE}
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-")
endif ()
@@ -153,24 +166,15 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
endif()
# Add test
- add_custom_command(
- OUTPUT ${TEST_OUTPUT}
+ add_test(
+ NAME PROJECT_${project}_TEST_${name}
COMMAND ${TEST_SCRIPT_CMD}
- DEPENDS PROJECT_${project}_TEST_${name}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
- # Why not add custom target and add POST_BUILD command?
- # Slightly less uncertain behavior
- # (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19
- # > I did not use a post build step as I could not make it notify of a
- # > failure after the first time you build and fail a test. - daveh 2009-04-20
+
+ add_dependencies(BUILD_TESTS PROJECT_${project}_TEST_${name})
list(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT})
endforeach (source)
-
- # Add the test runner target per-project
- # (replaces old _test_ok targets all over the place)
- add_custom_target(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
- add_dependencies(${project} ${project}_tests)
ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
#*****************************************************************************
@@ -198,12 +202,11 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
set(source_files
tests/${testname}_test.cpp
- ${CMAKE_SOURCE_DIR}/test/test.cpp
- ${CMAKE_SOURCE_DIR}/test/lltut.cpp
${additional_source_files}
)
set(libraries
+ lltut_runner_lib
${library_dependencies}
)
@@ -217,6 +220,7 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
COMPILE_DEFINITIONS "LL_TEST=${testname};LL_TEST_${testname}"
+ FOLDER "Tests"
)
# The following was copied to llcorehttp/CMakeLists.txt's texture_load target.
@@ -232,6 +236,7 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
# test binaries always need to be signed for local development
set_target_properties(INTEGRATION_TEST_${testname}
PROPERTIES
+ OSX_ARCHITECTURES ${LL_MACOS_TEST_ARCHITECTURE}
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-"
BUILD_WITH_INSTALL_RPATH 1
INSTALL_RPATH "@executable_path/Resources"
@@ -246,6 +251,11 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
target_link_libraries(INTEGRATION_TEST_${testname} ${libraries})
target_include_directories (INTEGRATION_TEST_${testname} PRIVATE ${LIBS_OPEN_DIR}/test )
+ if (USE_PRECOMPILED_HEADERS)
+ target_include_directories (INTEGRATION_TEST_${testname} PRIVATE ${LIBS_OPEN_DIR}/llmath )
+ target_precompile_headers(INTEGRATION_TEST_${testname} REUSE_FROM llprecompiled)
+ endif ()
+
# Create the test running command
set(test_command ${ARGN})
set(TEST_EXE $<TARGET_FILE:INTEGRATION_TEST_${testname}>)
@@ -274,14 +284,9 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}")
endif()
- add_custom_command(
- TARGET INTEGRATION_TEST_${testname}
- POST_BUILD
- COMMAND ${TEST_SCRIPT_CMD}
- )
+ add_test(NAME INTEGRATION_TEST_RUNNER_${testname} COMMAND ${TEST_SCRIPT_CMD})
- # Use CTEST? Not sure how to yet...
- # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD})
+ add_dependencies(BUILD_TESTS INTEGRATION_TEST_${testname})
ENDFUNCTION(LL_ADD_INTEGRATION_TEST)
diff --git a/indra/cmake/LLAppearanceUtility.cmake b/indra/cmake/LLAppearanceUtility.cmake
deleted file mode 100644
index 0eb3c723d5..0000000000
--- a/indra/cmake/LLAppearanceUtility.cmake
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- cmake -*-
-include(Prebuilt)
-include(Boost)
-
-# Linux proprietary build only
-if (INSTALL_PROPRIETARY)
- if(LINUX)
- use_prebuilt_binary(llappearance_utility)
- set(LLAPPEARANCEUTILITY_SRC_DIR ${LIBS_PREBUILT_DIR}/llappearanceutility/src)
- set(LLAPPEARANCEUTILITY_BIN_DIR ${CMAKE_BINARY_DIR}/llappearanceutility)
- endif (LINUX)
-endif (INSTALL_PROPRIETARY)
diff --git a/indra/cmake/LLKDU.cmake b/indra/cmake/LLKDU.cmake
index 7680ab7b54..3009b4b9cc 100644
--- a/indra/cmake/LLKDU.cmake
+++ b/indra/cmake/LLKDU.cmake
@@ -14,19 +14,11 @@ if (USE_KDU)
include(Prebuilt)
use_prebuilt_binary(kdu)
- if (WINDOWS)
- find_library(KDU_LIBRARY
- NAMES
- kdu
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- else (WINDOWS)
- find_library(KDU_LIBRARY
- NAMES
- libkdu.a
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- endif (WINDOWS)
+ find_library(KDU_LIBRARY
+ NAMES
+ kdu
+ libkdu.a
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
target_link_libraries(ll::kdu INTERFACE ${KDU_LIBRARY})
diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake
index 2e1b601b79..1f12dec1f6 100644
--- a/indra/cmake/LLWindow.cmake
+++ b/indra/cmake/LLWindow.cmake
@@ -1,22 +1,7 @@
# -*- cmake -*-
+include_guard()
include(Variables)
-include(GLEXT)
include(Prebuilt)
-
-include_guard()
-add_library( ll::SDL INTERFACE IMPORTED )
-
-
-if (LINUX)
- #Must come first as use_system_binary can exit this file early
- target_compile_definitions( ll::SDL INTERFACE LL_SDL=1)
-
- use_system_binary(SDL)
- use_prebuilt_binary(SDL)
-
- target_include_directories( ll::SDL SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
- target_link_libraries( ll::SDL INTERFACE SDL directfb fusion direct X11)
-endif (LINUX)
-
-
+include(GLEXT)
+include(SDL3)
diff --git a/indra/cmake/LibVLCPlugin.cmake b/indra/cmake/LibVLCPlugin.cmake
index 6361028c0c..a38c660a33 100644
--- a/indra/cmake/LibVLCPlugin.cmake
+++ b/indra/cmake/LibVLCPlugin.cmake
@@ -5,20 +5,31 @@ include(Prebuilt)
include_guard()
add_library( ll::libvlc INTERFACE IMPORTED )
-use_prebuilt_binary(vlc-bin)
set(LIBVLCPLUGIN ON CACHE BOOL
"LIBVLCPLUGIN support for the llplugin/llmedia test apps.")
-find_library(VLC_LIBRARY
- NAMES
- libvlc.lib
- libvlc.dylib
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+if (LIBVLCPLUGIN)
+ if(LINUX)
+ find_package(PkgConfig REQUIRED)
-find_library(VLCCORE_LIBRARY
- NAMES
- libvlccore.lib
- libvlccore.dylib
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+ pkg_check_modules(libvlc REQUIRED IMPORTED_TARGET libvlc)
+ target_link_libraries( ll::libvlc INTERFACE PkgConfig::libvlc)
+ return()
+ endif()
-target_link_libraries(ll::libvlc INTERFACE ${VLC_LIBRARY} ${VLCCORE_LIBRARY})
+ use_prebuilt_binary(vlc-bin)
+
+ find_library(VLC_LIBRARY
+ NAMES
+ libvlc.lib
+ libvlc.dylib
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+
+ find_library(VLCCORE_LIBRARY
+ NAMES
+ libvlccore.lib
+ libvlccore.dylib
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+
+ target_link_libraries(ll::libvlc INTERFACE ${VLC_LIBRARY} ${VLCCORE_LIBRARY})
+endif()
diff --git a/indra/cmake/NDOF.cmake b/indra/cmake/NDOF.cmake
index a8f63f945b..60b29a57fe 100644
--- a/indra/cmake/NDOF.cmake
+++ b/indra/cmake/NDOF.cmake
@@ -19,7 +19,12 @@ if (NDOF)
ndofdev
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- target_link_libraries(ll::ndof INTERFACE ${NDOF_LIBRARY})
+ if (LINUX)
+ include(SDL3)
+ target_link_libraries(ll::ndof INTERFACE ${NDOF_LIBRARY} ll::SDL3)
+ else()
+ target_link_libraries(ll::ndof INTERFACE ${NDOF_LIBRARY})
+ endif()
target_compile_definitions(ll::ndof INTERFACE LIB_NDOF=1)
endif (NDOF)
diff --git a/indra/cmake/OPENAL.cmake b/indra/cmake/OPENAL.cmake
index ab1604aa22..523a2d16f6 100644
--- a/indra/cmake/OPENAL.cmake
+++ b/indra/cmake/OPENAL.cmake
@@ -26,6 +26,7 @@ if (USE_OPENAL)
NAMES
OpenAL32
openal
+ OpenAL32.lib
libopenal.dylib
libopenal.so
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
@@ -33,6 +34,7 @@ if (USE_OPENAL)
find_library(ALUT_LIBRARY
NAMES
alut
+ alut.lib
libalut.dylib
libalut.so
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
diff --git a/indra/cmake/OpenXR.cmake b/indra/cmake/OpenXR.cmake
index 2cc862b927..7cc1be634b 100644
--- a/indra/cmake/OpenXR.cmake
+++ b/indra/cmake/OpenXR.cmake
@@ -5,18 +5,21 @@ include(Prebuilt)
include_guard()
add_library( ll::openxr INTERFACE IMPORTED )
-if(USE_CONAN )
- target_link_libraries( ll::openxr INTERFACE CONAN_PKG::openxr )
- return()
-endif()
+option(USE_OPENXR "Enable building with OpenXR support" OFF)
+if(USE_OPENXR)
+ if(USE_CONAN )
+ target_link_libraries( ll::openxr INTERFACE CONAN_PKG::openxr )
+ return()
+ endif()
-use_prebuilt_binary(openxr)
-if (WINDOWS)
- target_link_libraries( ll::openxr INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/openxr_loader.lib )
-else()
- target_link_libraries( ll::openxr INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libopenxr_loader.a )
-endif (WINDOWS)
+ use_prebuilt_binary(openxr)
+ if (WINDOWS)
+ target_link_libraries( ll::openxr INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/openxr_loader.lib )
+ else()
+ target_link_libraries( ll::openxr INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libopenxr_loader.a )
+ endif (WINDOWS)
-if( NOT LINUX )
- target_include_directories( ll::openxr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
+ if( NOT LINUX )
+ target_include_directories( ll::openxr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
+ endif()
endif()
diff --git a/indra/cmake/PNG.cmake b/indra/cmake/PNG.cmake
index 0c01e5ee78..6a66f40385 100644
--- a/indra/cmake/PNG.cmake
+++ b/indra/cmake/PNG.cmake
@@ -1,5 +1,7 @@
# -*- cmake -*-
include(Prebuilt)
+include(Linking)
+include(ZLIBNG)
include_guard()
add_library( ll::libpng INTERFACE IMPORTED )
@@ -13,5 +15,5 @@ find_library(LIBPNG_LIBRARY
libpng16.a
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-target_link_libraries(ll::libpng INTERFACE ${LIBPNG_LIBRARY})
+target_link_libraries(ll::libpng INTERFACE ${LIBPNG_LIBRARY} ll::zlib-ng)
target_include_directories(ll::libpng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/libpng16)
diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake
index 634cc15c21..d0ab341d94 100644
--- a/indra/cmake/Prebuilt.cmake
+++ b/indra/cmake/Prebuilt.cmake
@@ -2,9 +2,6 @@
include_guard()
include(FindAutobuild)
-if(INSTALL_PROPRIETARY)
- include(FindSCP)
-endif(INSTALL_PROPRIETARY)
set(PREBUILD_TRACKING_DIR ${AUTOBUILD_INSTALL_DIR}/cmake_tracking)
# For the library installation process;
@@ -40,8 +37,10 @@ macro (use_prebuilt_binary _binary)
--install-dir=${AUTOBUILD_INSTALL_DIR}
${_binary} ")
endif(DEBUG_PREBUILT)
+ message(STATUS "Installing ${_binary}...")
execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}"
install
+ --skip-source-environment
--install-dir=${AUTOBUILD_INSTALL_DIR}
${_binary}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake
index 7cce190f6a..39fd21c33f 100644
--- a/indra/cmake/Python.cmake
+++ b/indra/cmake/Python.cmake
@@ -13,7 +13,7 @@ elseif (WINDOWS)
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)
+ foreach(pyver 3.14 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()
diff --git a/indra/cmake/SDL3.cmake b/indra/cmake/SDL3.cmake
new file mode 100644
index 0000000000..fe9012de17
--- /dev/null
+++ b/indra/cmake/SDL3.cmake
@@ -0,0 +1,26 @@
+# -*- cmake -*-
+include_guard()
+include(Linking)
+include(Prebuilt)
+
+add_library(ll::SDL3 INTERFACE IMPORTED)
+
+if (LINUX)
+ set(USE_SDL_WINDOW ON CACHE BOOL "Build with SDL window backend")
+else()
+ set(USE_SDL_WINDOW OFF CACHE BOOL "Build with SDL window backend")
+endif (LINUX)
+
+if(USE_SDL_WINDOW)
+ use_system_binary(SDL3)
+ use_prebuilt_binary(SDL3)
+
+ find_library( SDL3_LIBRARY
+ NAMES SDL3 SDL3.lib libSDL3.so libSDL3.dylib
+ PATHS "${LIBS_PREBUILT_DIR}/lib/release" REQUIRED)
+
+ target_link_libraries(ll::SDL3 INTERFACE ${SDL3_LIBRARY})
+ target_include_directories(ll::SDL3 SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include/")
+
+endif(USE_SDL_WINDOW)
+
diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake
index 8f135676d6..f2776b21e1 100644
--- a/indra/cmake/UI.cmake
+++ b/indra/cmake/UI.cmake
@@ -1,35 +1,42 @@
# -*- cmake -*-
include(Prebuilt)
include(FreeType)
+include(GLIB)
+include_guard()
add_library( ll::uilibraries INTERFACE IMPORTED )
if (LINUX)
- target_compile_definitions(ll::uilibraries INTERFACE LL_GTK=1 LL_X11=1 )
-
if( USE_CONAN )
- target_link_libraries( ll::uilibraries INTERFACE CONAN_PKG::gtk )
return()
endif()
- use_prebuilt_binary(gtk-atk-pango-glib)
+
+ find_package(PkgConfig REQUIRED)
+ pkg_check_modules(WAYLAND_CLIENT wayland-client)
+
+ if(WAYLAND_CLIENT_FOUND)
+ target_include_directories(ll::uilibraries INTERFACE ${WAYLAND_CLIENT_INCLUDE_DIRS})
+ target_compile_definitions(ll::uilibraries INTERFACE LL_WAYLAND=1)
+ else()
+ message("pkgconfig could not find wayland client, compiling without full wayland support")
+ endif()
+
+ find_package(X11)
+ if(X11_FOUND)
+ target_compile_definitions(ll::uilibraries INTERFACE LL_X11=1)
+ else()
+ message("Could not find X11, compiling without full X11 support")
+ endif()
+
target_link_libraries( ll::uilibraries INTERFACE
- atk-1.0
- gdk-x11-2.0
- gdk_pixbuf-2.0
- Xinerama
- glib-2.0
- gmodule-2.0
- gobject-2.0
- gthread-2.0
- gtk-x11-2.0
- pango-1.0
- pangoft2-1.0
- pangox-1.0
- pangoxft-1.0
- Xinerama
+ ll::fontconfig
ll::freetype
- )
+ ll::SDL3
+ ll::glib
+ ll::gio
+ )
+
endif (LINUX)
if( WINDOWS )
target_link_libraries( ll::uilibraries INTERFACE
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 22c2156bb8..81a8f87cd3 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -9,21 +9,51 @@
# LINUX - Linux
# WINDOWS - Windows
+include_guard()
+
# Switches set here and in 00-Common.cmake must agree with
# https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables
# Reading $LL_BUILD is an attempt to directly use those switches.
-if ("$ENV{LL_BUILD}" STREQUAL "" AND "${LL_BUILD_ENV}" STREQUAL "" )
- message(FATAL_ERROR "Environment variable LL_BUILD must be set")
-elseif("$ENV{LL_BUILD}" STREQUAL "")
- set( ENV{LL_BUILD} "${LL_BUILD_ENV}" )
- message( "Setting ENV{LL_BUILD} to cached variable ${LL_BUILD_ENV}" )
+if ("$ENV{AUTOBUILD_ADDRSIZE}" STREQUAL "" AND "${AUTOBUILD_ADDRSIZE_ENV}" STREQUAL "" )
+ message(FATAL_ERROR "Environment variable AUTOBUILD_ADDRSIZE must be set")
+elseif("$ENV{AUTOBUILD_ADDRSIZE}" STREQUAL "")
+ set( ENV{AUTOBUILD_ADDRSIZE} "${AUTOBUILD_ADDRSIZE_ENV}" )
+ message( "Setting ENV{AUTOBUILD_ADDRSIZE} to cached variable ${AUTOBUILD_ADDRSIZE_ENV}" )
else()
- set( LL_BUILD_ENV "$ENV{LL_BUILD}" CACHE STRING "Save environment" FORCE )
+ set( AUTOBUILD_ADDRSIZE_ENV "$ENV{AUTOBUILD_ADDRSIZE}" CACHE STRING "Save environment AUTOBUILD_ADDRSIZE" FORCE )
endif ()
-include_guard()
-# Relative and absolute paths to subtrees.
+if ("$ENV{AUTOBUILD_PLATFORM}" STREQUAL "" AND "${AUTOBUILD_PLATFORM_ENV}" STREQUAL "" )
+ message(FATAL_ERROR "Environment variable AUTOBUILD_PLATFORM must be set")
+elseif("$ENV{AUTOBUILD_PLATFORM}" STREQUAL "")
+ set( ENV{AUTOBUILD_PLATFORM} "${AUTOBUILD_PLATFORM_ENV}" )
+ message( "Setting ENV{AUTOBUILD_PLATFORM} to cached variable ${AUTOBUILD_PLATFORM_ENV}" )
+else()
+ set( AUTOBUILD_PLATFORM_ENV "$ENV{AUTOBUILD_PLATFORM}" CACHE STRING "Save environment AUTOBUILD_PLATFORM" FORCE )
+endif ()
+# Switches set here and in 00-Common.cmake must agree with
+# https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables
+# Reading $LL_BUILD is an attempt to directly use those switches.
+if ("$ENV{LL_BUILD_RELEASE}" STREQUAL "" AND "${LL_BUILD_RELEASE_ENV}" STREQUAL "" )
+ message(FATAL_ERROR "Environment variable LL_BUILD_RELEASE must be set")
+elseif("$ENV{LL_BUILD_RELEASE}" STREQUAL "")
+ set( ENV{LL_BUILD_RELEASE} "${LL_BUILD_RELEASE_ENV}" )
+ message( "Setting ENV{LL_BUILD_RELEASE} to cached variable ${LL_BUILD_RELEASE_ENV}" )
+else()
+ set( LL_BUILD_RELEASE_ENV "$ENV{LL_BUILD_RELEASE}" CACHE STRING "Save environment RELEASE" FORCE )
+endif ()
+
+if ("$ENV{LL_BUILD_RELWITHDEBINFO}" STREQUAL "" AND "${LL_BUILD_RELWITHDEBINFO_ENV}" STREQUAL "" )
+ message(FATAL_ERROR "Environment variable LL_BUILD_RELWITHDEBINFO must be set")
+elseif("$ENV{LL_BUILD_RELWITHDEBINFO}" STREQUAL "")
+ set( ENV{LL_BUILD_RELWITHDEBINFO} "${LL_BUILD_RELWITHDEBINFO_ENV}" )
+ message( "Setting ENV{LL_BUILD_RELWITHDEBINFO} to cached variable ${LL_BUILD_RELWITHDEBINFO_ENV}" )
+else()
+ set( LL_BUILD_RELWITHDEBINFO_ENV "$ENV{LL_BUILD_RELWITHDEBINFO}" CACHE STRING "Save environment RELWITHDEBINFO" FORCE )
+endif ()
+
+# Relative and absolute paths to subtrees.
if(NOT DEFINED COMMON_CMAKE_DIR)
set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake")
endif(NOT DEFINED COMMON_CMAKE_DIR)
@@ -67,7 +97,7 @@ set(TEMPLATE_VERIFIER_MASTER_URL "https://github.com/secondlife/master-message-t
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
- "Build type. One of: Debug Release RelWithDebInfo" FORCE)
+ "Build type. One of: Release RelWithDebInfo" FORCE)
endif (NOT CMAKE_BUILD_TYPE)
# If someone has specified an address size, use that to determine the
@@ -127,16 +157,12 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib/${DPKG_ARCH} /usr/local/lib/${DPKG_ARCH} ${CMAKE_SYSTEM_LIBRARY_PATH})
endif (DPKG_RESULT EQUAL 0)
- include(ConfigurePkgConfig)
-
- if (INSTALL_PROPRIETARY)
- # Only turn on headless if we can find osmesa libraries.
- include(FindPkgConfig)
- #pkg_check_modules(OSMESA osmesa)
- #if (OSMESA_FOUND)
- # set(BUILD_HEADLESS ON CACHE BOOL "Build headless libraries.")
- #endif (OSMESA_FOUND)
- endif (INSTALL_PROPRIETARY)
+ # Only turn on headless if we can find osmesa libraries.
+ find_package(PkgConfig)
+ pkg_check_modules(OSMESA IMPORTED_TARGET GLOBAL osmesa)
+ if (OSMESA_FOUND)
+ set(BUILD_HEADLESS ON CACHE BOOL "Build headless libraries.")
+ endif (OSMESA_FOUND)
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@@ -172,6 +198,11 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(CMAKE_XCODE_ATTRIBUTE_DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING YES)
set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION NO)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "macOS Build Arch" FORCE)
+ if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
+ set(LL_MACOS_TEST_ARCHITECTURE "arm64")
+ else()
+ set(LL_MACOS_TEST_ARCHITECTURE "x86_64")
+ endif()
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Default deploy grid
diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake
index cae68fbc11..23fd477ba8 100644
--- a/indra/cmake/ViewerMiscLibs.cmake
+++ b/indra/cmake/ViewerMiscLibs.cmake
@@ -5,11 +5,8 @@ if (LINUX)
#use_prebuilt_binary(libuuid)
add_library( ll::fontconfig INTERFACE IMPORTED )
- if( NOT USE_CONAN )
- use_prebuilt_binary(fontconfig)
- else()
- target_link_libraries( ll::fontconfig INTERFACE CONAN_PKG::fontconfig )
- endif()
+ find_package(Fontconfig REQUIRED)
+ target_link_libraries( ll::fontconfig INTERFACE Fontconfig::Fontconfig )
endif (LINUX)
if( NOT USE_CONAN )
diff --git a/indra/cmake/ZLIBNG.cmake b/indra/cmake/ZLIBNG.cmake
index a6d67489e7..9f8f12d973 100644
--- a/indra/cmake/ZLIBNG.cmake
+++ b/indra/cmake/ZLIBNG.cmake
@@ -1,6 +1,7 @@
# -*- cmake -*-
include(Prebuilt)
+include(Linking)
include_guard()
add_library( ll::zlib-ng INTERFACE IMPORTED )
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
index 509981d72c..8916cb282c 100644
--- a/indra/cmake/bugsplat.cmake
+++ b/indra/cmake/bugsplat.cmake
@@ -1,18 +1,19 @@
-if (INSTALL_PROPRIETARY)
+if (INSTALL_PROPRIETARY AND NOT LINUX)
# Note that viewer_manifest.py makes decision based on BUGSPLAT_DB and not USE_BUGSPLAT
if (BUGSPLAT_DB)
set(USE_BUGSPLAT ON CACHE BOOL "Use the BugSplat crash reporting system")
else (BUGSPLAT_DB)
set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system")
endif (BUGSPLAT_DB)
-else (INSTALL_PROPRIETARY)
+else ()
set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system")
-endif (INSTALL_PROPRIETARY)
+ set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name")
+endif ()
include_guard()
add_library( ll::bugsplat INTERFACE IMPORTED )
-if (USE_BUGSPLAT)
+if (USE_BUGSPLAT AND NOT LINUX)
include(Prebuilt)
use_prebuilt_binary(bugsplat)
if (WINDOWS)
@@ -36,6 +37,7 @@ if (USE_BUGSPLAT)
set_property( TARGET ll::bugsplat APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS LL_BUGSPLAT)
else()
- set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name")
-endif (USE_BUGSPLAT)
+ set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system" FORCE)
+ set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name" FORCE)
+endif ()
diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py
index 940a130a50..85689b361a 100755
--- a/indra/cmake/run_build_test.py
+++ b/indra/cmake/run_build_test.py
@@ -133,7 +133,7 @@ def main(command, arguments=[], libpath=[], vars={}):
raise
# In practice, the pathnames into CMake's build tree are so long as to
# obscure the name of the test program. Just log its basename.
- log.warn("No such program %s; check for preceding build errors" % \
+ log.warning("No such program %s; check for preceding build errors" % \
os.path.basename(command[0]))
# What rc should we simulate for missing executable? Windows produces
# 9009.
diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt
index e6ff142626..40837c8abb 100644
--- a/indra/integration_tests/llimage_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt
@@ -9,7 +9,6 @@ include(00-Common)
include(LLCommon)
include(LLImage)
include(LLMath)
-include(LLKDU)
set(llimage_libtest_SOURCE_FILES
llimage_libtest.cpp
@@ -26,6 +25,18 @@ add_executable(llimage_libtest
${llimage_libtest_SOURCE_FILES}
)
+set_target_properties(llimage_libtest
+ PROPERTIES
+ FOLDER "Tests"
+ )
+
+if(DARWIN)
+ set_target_properties(llimage_libtest
+ PROPERTIES
+ OSX_ARCHITECTURES ${LL_MACOS_TEST_ARCHITECTURE}
+ )
+endif()
+
# Libraries on which this application depends on
# Sort by high-level to low-level
target_link_libraries(llimage_libtest
diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
index c45bd6fd01..b82ced2f8d 100644
--- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
+++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
@@ -329,7 +329,7 @@ public:
void run()
{
- std::ofstream os(mFile.c_str());
+ llofstream os(mFile.c_str());
while (!sAllDone)
{
@@ -345,6 +345,11 @@ public:
int main(int argc, char** argv)
{
+ // Call Tracy first thing to have it allocate memory
+ // https://github.com/wolfpld/tracy/issues/196
+ LL_PROFILER_FRAME_END;
+ LL_PROFILER_SET_THREAD_NAME("App");
+
// List of input and output files
std::list<std::string> input_filenames;
std::list<std::string> output_filenames;
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index a6ce657f4f..19ae1ae215 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -49,9 +49,14 @@ target_link_libraries(llui_libtest
llimagej2coj
)
+set_target_properties(llui_libtest
+ PROPERTIES
+ FOLDER "Tests"
+ )
+
if (WINDOWS)
set_target_properties(llui_libtest
- PROPERTIES
+ PROPERTIES
LINK_FLAGS "/NODEFAULTLIB:LIBCMT"
)
@@ -66,6 +71,13 @@ if (WINDOWS)
)
endif (WINDOWS)
+if(DARWIN)
+ set_target_properties(llui_libtest
+ PROPERTIES
+ OSX_ARCHITECTURES ${LL_MACOS_TEST_ARCHITECTURE}
+ )
+endif()
+
# Ensure people working on the viewer don't break this library
# *NOTE: This could be removed, or only built by Parabuild, if the build
# and link times become too long. JC
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
deleted file mode 100644
index 1793aa82b9..0000000000
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-# -*- cmake -*-
-
-project(linux_crash_logger)
-
-include(00-Common)
-include(GLH)
-include(LLCoreHttp)
-include(LLCommon)
-include(LLCrashLogger)
-include(LLMath)
-include(LLMessage)
-include(LLFileSystem)
-include(LLXML)
-include(Linking)
-include(UI)
-include(FreeType)
-include(Boost)
-
-include_directories(
- ${LLCOREHTTP_INCLUDE_DIRS}
- ${LLCOMMON_INCLUDE_DIRS}
- ${LLCRASHLOGGER_INCLUDE_DIRS}
- ${LLMATH_INCLUDE_DIRS}
- ${LLFILESYSTEM_INCLUDE_DIRS}
- ${LLXML_INCLUDE_DIRS}
- ${FREETYPE_INCLUDE_DIRS}
- )
-include_directories(SYSTEM
- ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
- ${LLXML_SYSTEM_INCLUDE_DIRS}
- )
-include_directories(SYSTEM
- ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
- ${LLXML_SYSTEM_INCLUDE_DIRS}
- )
-
-set(linux_crash_logger_SOURCE_FILES
- linux_crash_logger.cpp
- llcrashloggerlinux.cpp
- )
-
-set(linux_crash_logger_HEADER_FILES
- CMakeLists.txt
-
- llcrashloggerlinux.h
- )
-
-list(APPEND linux_crash_logger_SOURCE_FILES
- ${linux_crash_logger_HEADER_FILES}
- )
-
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
-
-add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES})
-
-# llcommon uses `clock_gettime' which is provided by librt on linux.
-set(LIBRT_LIBRARY rt)
-
-
-target_link_libraries(linux-crash-logger
- llcrashlogger
- llfilesystem
- llxml
- llmessage
- llmath
- llcorehttp
- llcommon
- ll::uilibraries
- )
-
-add_custom_target(linux-crash-logger-target ALL
- DEPENDS linux-crash-logger)
diff --git a/indra/linux_crash_logger/README.txt b/indra/linux_crash_logger/README.txt
deleted file mode 100644
index 6932a8d9c3..0000000000
--- a/indra/linux_crash_logger/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-This component is no longer used in Linden Lab builds.
-Change requests to support continued use by open source
-builds are welcome.
diff --git a/indra/linux_crash_logger/linux_crash_logger.cpp b/indra/linux_crash_logger/linux_crash_logger.cpp
deleted file mode 100644
index b36312c607..0000000000
--- a/indra/linux_crash_logger/linux_crash_logger.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file linux_crash_logger.cpp
- * @brief Linux crash logger implementation
- *
- * $LicenseInfo:firstyear=2003&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 "llcrashloggerlinux.h"
-#include "llsdutil.h"
-
-int main(int argc, char **argv)
-{
- LL_INFOS() << "Starting crash reporter." << LL_ENDL;
-
- LLCrashLoggerLinux app;
- app.parseCommandOptions(argc, argv);
-
- LLSD options = LLApp::instance()->getOptionData(
- LLApp::PRIORITY_COMMAND_LINE);
- //LLApp::PRIORITY_RUNTIME_OVERRIDE);
-
-
- if (!(options.has("pid") && options.has("dumpdir")))
- {
- LL_WARNS() << "Insufficient parameters to crash report." << LL_ENDL;
- }
-
- if (! app.init())
- {
- LL_WARNS() << "Unable to initialize application." << LL_ENDL;
- return 1;
- }
-
- app.frame();
- app.cleanup();
- LL_INFOS() << "Crash reporter finished normally." << LL_ENDL;
- return 0;
-}
diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp
deleted file mode 100644
index 9b40de741e..0000000000
--- a/indra/linux_crash_logger/llcrashloggerlinux.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/**
- * @file llcrashloggerlinux.cpp
- * @brief Linux crash logger implementation
- *
- * $LicenseInfo:firstyear=2003&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 "llcrashloggerlinux.h"
-
-#include <iostream>
-
-#include "linden_common.h"
-
-#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
-#include "llerror.h"
-#include "llfile.h"
-#include "lltimer.h"
-#include "llstring.h"
-#include "lldir.h"
-#include "llsdserialize.h"
-
-#if LL_GTK
-# include "gtk/gtk.h"
-#endif // LL_GTK
-
-#define MAX_LOADSTRING 100
-
-// These need to be localized.
-static const char dialog_text[] =
-"Second Life appears to have crashed or frozen last time it ran.\n"
-"This crash reporter collects information about your computer's hardware, operating system, and some Second Life logs, all of which are used for debugging purposes only.\n"
-"\n"
-"Send crash report?";
-
-static const char dialog_title[] =
-"Second Life Crash Logger";
-
-#if LL_GTK
-static void response_callback (GtkDialog *dialog,
- gint arg1,
- gpointer user_data)
-{
- gint *response = (gint*)user_data;
- *response = arg1;
- gtk_widget_destroy(GTK_WIDGET(dialog));
- gtk_main_quit();
-}
-#endif // LL_GTK
-
-static BOOL do_ask_dialog(void)
-{
-#if LL_GTK
- gtk_disable_setlocale();
- if (!gtk_init_check(NULL, NULL)) {
- LL_INFOS() << "Could not initialize GTK for 'ask to send crash report' dialog; not sending report." << LL_ENDL;
- return FALSE;
- }
-
- GtkWidget *win = NULL;
- GtkDialogFlags flags = GTK_DIALOG_MODAL;
- GtkMessageType messagetype = GTK_MESSAGE_QUESTION;
- GtkButtonsType buttons = GTK_BUTTONS_YES_NO;
- gint response = GTK_RESPONSE_NONE;
-
- win = gtk_message_dialog_new(NULL,
- flags, messagetype, buttons,
- "%s", dialog_text);
- gtk_window_set_type_hint(GTK_WINDOW(win),
- GDK_WINDOW_TYPE_HINT_DIALOG);
- gtk_window_set_title(GTK_WINDOW(win), dialog_title);
- g_signal_connect (win,
- "response",
- G_CALLBACK (response_callback),
- &response);
- gtk_widget_show_all (win);
- gtk_main();
-
- return (GTK_RESPONSE_OK == response ||
- GTK_RESPONSE_YES == response ||
- GTK_RESPONSE_APPLY == response);
-#else
- return FALSE;
-#endif // LL_GTK
-}
-
-LLCrashLoggerLinux::LLCrashLoggerLinux(void)
-{
-}
-
-LLCrashLoggerLinux::~LLCrashLoggerLinux(void)
-{
-}
-
-void LLCrashLoggerLinux::gatherPlatformSpecificFiles()
-{
-}
-
-bool LLCrashLoggerLinux::frame()
-{
- bool send_logs = true;
- if(CRASH_BEHAVIOR_ASK == getCrashBehavior())
- {
- send_logs = do_ask_dialog();
- }
- else if(CRASH_BEHAVIOR_NEVER_SEND == getCrashBehavior())
- {
- send_logs = false;
- }
-
- if(send_logs)
- {
- sendCrashLogs();
- }
- return true;
-}
-
-bool LLCrashLoggerLinux::cleanup()
-{
- commonCleanup();
- mKeyMaster.releaseMaster();
- return true;
-}
-
-void LLCrashLoggerLinux::updateApplication(const std::string& message)
-{
- LLCrashLogger::updateApplication(message);
-}
diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt
index 6744c8d8a4..5b6d68fa37 100644
--- a/indra/llappearance/CMakeLists.txt
+++ b/indra/llappearance/CMakeLists.txt
@@ -28,7 +28,7 @@ set(llappearance_SOURCE_FILES
llviewervisualparam.cpp
llavatarappearancedefines.cpp
)
-
+
set(llappearance_HEADER_FILES
CMakeLists.txt
@@ -69,6 +69,10 @@ target_link_libraries(llappearance
)
target_include_directories( llappearance INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llappearance REUSE_FROM llprecompiled)
+endif ()
+
if (BUILD_HEADLESS)
add_library (llappearanceheadless ${llappearance_SOURCE_FILES})
target_include_directories( llappearanceheadless INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
@@ -77,6 +81,7 @@ if (BUILD_HEADLESS)
llcharacter
llinventory
llimage
+ llrenderheadless
llfilesystem
llmath
llxml
@@ -84,4 +89,8 @@ if (BUILD_HEADLESS)
llcorehttp
llcommon
)
+
+ if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llappearanceheadless REUSE_FROM llprecompiled)
+ endif ()
endif (BUILD_HEADLESS)
diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp
index 47798844bc..f26795123f 100644
--- a/indra/llappearance/llavatarappearancedefines.cpp
+++ b/indra/llappearance/llavatarappearancedefines.cpp
@@ -260,7 +260,7 @@ ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextu
return getBakedTexture(index)->mTextureIndex;
}
-EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::string name)
+EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(const std::string& name) const
{
U8 index = 0;
while (index < BAKED_NUM_INDICES)
@@ -277,7 +277,7 @@ EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::stri
return BAKED_NUM_INDICES;
}
-EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::string name)
+EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(const std::string& name) const
{
U8 index = 0;
while (index < BAKED_NUM_INDICES)
diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h
index 50a72a45a5..0f9edc1ca0 100644
--- a/indra/llappearance/llavatarappearancedefines.h
+++ b/indra/llappearance/llavatarappearancedefines.h
@@ -238,8 +238,8 @@ public:
ETextureIndex bakedToLocalTextureIndex(EBakedTextureIndex t) const;
// find a baked texture index based on its name
- EBakedTextureIndex findBakedByRegionName(std::string name);
- EBakedTextureIndex findBakedByImageName(std::string name);
+ EBakedTextureIndex findBakedByRegionName(const std::string& name) const;
+ EBakedTextureIndex findBakedByImageName(const std::string& name) const;
// Given a texture entry, determine which wearable type owns it.
LLWearableType::EType getTEWearableType(ETextureIndex index) const;
diff --git a/indra/llappearance/llavatarjoint.h b/indra/llappearance/llavatarjoint.h
index 13f025fd5f..71fe4b61b6 100644
--- a/indra/llappearance/llavatarjoint.h
+++ b/indra/llappearance/llavatarjoint.h
@@ -41,9 +41,10 @@ extern const F32 DEFAULT_AVATAR_JOINT_LOD;
//-----------------------------------------------------------------------------
// class LLViewerJoint
//-----------------------------------------------------------------------------
-class LLAvatarJoint :
+class alignas(16) LLAvatarJoint :
public LLJoint
{
+ LL_ALIGN_NEW
public:
LLAvatarJoint();
LLAvatarJoint(S32 joint_num);
@@ -121,8 +122,9 @@ protected:
S32 mMeshID;
};
-class LLAvatarJointCollisionVolume : public LLAvatarJoint
+class alignas(16) LLAvatarJointCollisionVolume : public LLAvatarJoint
{
+ LL_ALIGN_NEW
public:
LLAvatarJointCollisionVolume();
virtual ~LLAvatarJointCollisionVolume() {};
diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h
index 33f50fce00..153a2b88fe 100644
--- a/indra/llappearance/llavatarjointmesh.h
+++ b/indra/llappearance/llavatarjointmesh.h
@@ -59,8 +59,9 @@ public:
//-----------------------------------------------------------------------------
// class LLViewerJointMesh
//-----------------------------------------------------------------------------
-class LLAvatarJointMesh : public virtual LLAvatarJoint
+class alignas(16) LLAvatarJointMesh : public virtual LLAvatarJoint
{
+ LL_ALIGN_NEW
protected:
LLColor4 mColor; // color value
// LLColor4 mSpecular; // specular color (always white for now)
diff --git a/indra/llappearance/lldriverparam.h b/indra/llappearance/lldriverparam.h
index 59092988dd..df8733dde7 100644
--- a/indra/llappearance/lldriverparam.h
+++ b/indra/llappearance/lldriverparam.h
@@ -128,7 +128,7 @@ protected:
void setDrivenWeight(LLDrivenEntry* driven, F32 driven_weight);
- LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder
+ LLVector4a mDefaultVec; // temp holder
entry_list_t mDriven;
LLViewerVisualParam* mCurrentDistortionParam{ nullptr };
// Backlink only; don't make this an LLPointer.
diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h
index 8c76689f2c..64434bd5d9 100644
--- a/indra/llappearance/llpolymorph.h
+++ b/indra/llappearance/llpolymorph.h
@@ -71,7 +71,7 @@ public:
private:
void freeData();
-} LL_ALIGN_POSTFIX(16);
+};
//-----------------------------------------------------------------------------
diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h
index 9ba4cf66e9..37f35d50ba 100644
--- a/indra/llappearance/llpolyskeletaldistortion.h
+++ b/indra/llappearance/llpolyskeletaldistortion.h
@@ -111,13 +111,13 @@ public:
protected:
LLPolySkeletalDistortion(const LLPolySkeletalDistortion& pOther);
- LL_ALIGN_16(LLVector4a mDefaultVec);
+ LLVector4a mDefaultVec;
typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
joint_vec_map_t mJointScales;
joint_vec_map_t mJointOffsets;
// Backlink only; don't make this an LLPointer.
LLAvatarAppearance *mAvatar;
-} LL_ALIGN_POSTFIX(16);
+};
#endif // LL_LLPOLYSKELETALDISTORTION_H
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index 7f7eaf1855..1bdaa814b7 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -435,6 +435,31 @@ const std::string LLTexLayerSet::getBodyRegionName() const
return mInfo->mBodyRegion;
}
+// virtual
+void LLTexLayerSet::asLLSD(LLSD& sd) const
+{
+ sd["visible"] = LLSD::Boolean(isVisible());
+ LLSD layer_list_sd;
+ layer_list_t::const_iterator layer_iter = mLayerList.begin();
+ layer_list_t::const_iterator layer_end = mLayerList.end();
+ for(; layer_iter != layer_end; ++layer_iter)
+ {
+ LLSD layer_sd;
+ LLTexLayerInterface* layer = (*layer_iter);
+ if (layer)
+ {
+ layer->asLLSD(layer_sd);
+ }
+ layer_list_sd.append(layer_sd);
+ }
+ LLSD mask_list_sd;
+ LLSD info_sd;
+ sd["layers"] = layer_list_sd;
+ sd["masks"] = mask_list_sd;
+ sd["info"] = info_sd;
+}
+
+
void LLTexLayerSet::destroyComposite()
{
if( mComposite )
diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h
index 876ea6f600..6b501474d6 100644
--- a/indra/llappearance/lltexlayer.h
+++ b/indra/llappearance/lltexlayer.h
@@ -220,6 +220,8 @@ public:
static bool sHasCaches;
+ virtual void asLLSD(LLSD& sd) const;
+
protected:
typedef std::vector<LLTexLayerInterface *> layer_list_t;
layer_list_t mLayerList;
diff --git a/indra/llappearance/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h
index 5e785e4f3e..2c243d0e9b 100644
--- a/indra/llappearance/lltexlayerparams.h
+++ b/indra/llappearance/lltexlayerparams.h
@@ -30,6 +30,7 @@
#include "llpointer.h"
#include "v4color.h"
#include "llviewervisualparam.h"
+#include <atomic>
class LLAvatarAppearance;
class LLImageRaw;
@@ -62,7 +63,6 @@ protected:
// LLTexLayerParamAlpha
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LL_ALIGN_PREFIX(16)
class alignas(16) LLTexLayerParamAlpha : public LLTexLayerParam
{
LL_ALIGN_NEW
@@ -102,7 +102,7 @@ private:
LLPointer<LLImageRaw> mStaticImageRaw;
std::atomic<bool> mNeedsCreateTexture;
bool mStaticImageInvalid;
- LL_ALIGN_16(LLVector4a mAvgDistortionVec);
+ LLVector4a mAvgDistortionVec;
F32 mCachedEffectiveWeight;
public:
@@ -112,7 +112,7 @@ public:
typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t;
static param_alpha_ptr_list_t sInstances;
-} LL_ALIGN_POSTFIX(16);
+};
class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
{
friend class LLTexLayerParamAlpha;
diff --git a/indra/llappearance/llviewervisualparam.h b/indra/llappearance/llviewervisualparam.h
index b79983df8e..37771cc8d3 100644
--- a/indra/llappearance/llviewervisualparam.h
+++ b/indra/llappearance/llviewervisualparam.h
@@ -65,8 +65,7 @@ protected:
// VIRTUAL CLASS
// a viewer side interface class for a generalized parametric modification of the avatar mesh
//-----------------------------------------------------------------------------
-LL_ALIGN_PREFIX(16)
-class LLViewerVisualParam : public LLVisualParam
+class alignas(16) LLViewerVisualParam : public LLVisualParam
{
public:
LLViewerVisualParam();
@@ -107,6 +106,6 @@ public:
protected:
LLViewerVisualParam(const LLViewerVisualParam& pOther);
-} LL_ALIGN_POSTFIX(16);
+};
#endif // LL_LLViewerVisualParam_H
diff --git a/indra/llappearanceutility/CMakeLists.txt b/indra/llappearanceutility/CMakeLists.txt
new file mode 100644
index 0000000000..53b5ce1cbe
--- /dev/null
+++ b/indra/llappearanceutility/CMakeLists.txt
@@ -0,0 +1,86 @@
+# -*- cmake -*-
+
+project(appearance_utility)
+
+include(00-Common)
+include(Boost)
+include(LLAppearance)
+include(LLCommon)
+include(LLImage)
+include(LLMath)
+include(LLWindow)
+include(Linking)
+
+set(appearance_utility_SOURCE_FILES
+ appearance_utility.cpp
+ llappappearanceutility.cpp
+ llbakingavatar.cpp
+ llbakingjoint.cpp
+ llbakingjointmesh.cpp
+ llbakingprocess.cpp
+ llbakingshadermgr.cpp
+ llbakingtexlayer.cpp
+ llbakingtexture.cpp
+ llbakingwearable.cpp
+ llbakingwearablesdata.cpp
+ llbakingwindow.cpp
+ llprocessparams.cpp
+ llprocessskin.cpp
+ llprocesstexture.cpp
+ )
+
+set(appearance_utility_HEADER_FILES
+ CMakeLists.txt
+ llappappearanceutility.h
+ llbakingavatar.h
+ llbakingjoint.h
+ llbakingjointmesh.h
+ llbakingprocess.h
+ llbakingshadermgr.h
+ llbakingtexlayer.h
+ llbakingtexture.h
+ llbakingwearable.h
+ llbakingwearablesdata.h
+ llbakingwindow.h
+ llprocessparams.h
+ llprocessskin.h
+ llprocesstexture.h
+ )
+
+set_source_files_properties(${appearance_utility_HEADER_FILES}
+ PROPERTIES HEADER_FILES_ONLY TRUE)
+
+list(APPEND appearance_utility_SOURCE_FILES ${appearance_utility_HEADER_FILES})
+
+add_executable(appearance-utility-bin ${appearance_utility_SOURCE_FILES})
+
+target_link_libraries(appearance-utility-bin
+ llcharacter
+ llinventory
+ llappearance
+ llwindow
+ llrender
+ llxml
+ )
+
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(appearance-utility-bin REUSE_FROM llprecompiled)
+endif ()
+
+if (BUILD_HEADLESS)
+ add_executable(appearance-utility-headless-bin ${appearance_utility_SOURCE_FILES})
+
+ target_link_libraries(appearance-utility-headless-bin
+ llcharacter
+ llinventory
+ llappearanceheadless
+ llwindowheadless
+ llrenderheadless
+ llxml
+ )
+
+ if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(appearance-utility-headless-bin REUSE_FROM llprecompiled)
+ endif ()
+endif (BUILD_HEADLESS)
+
diff --git a/indra/llappearanceutility/README.md b/indra/llappearanceutility/README.md
new file mode 100644
index 0000000000..21019ffd27
--- /dev/null
+++ b/indra/llappearanceutility/README.md
@@ -0,0 +1,33 @@
+# llappearanceutility
+
+This directory contains the appearance utility employed by the bake service to process avatar textures and handle various other appearance-related functions. Please note that this utility is currently configured to build only on Linux systems.
+
+## Prerequisites
+
+Ensure the following prerequisites are met before building and testing the utility:
+
+- **X11 Display**: Ensure an X11 display is available, either virtual or physical, with the `DISPLAY` environment variable set appropriately (e.g., `DISPLAY=:1`).
+- **Linux Build Environment**: Confirm that the Second Life Viewer can be built on your Linux system.
+
+## Testing
+
+Given the constraints with GitHub runners, we instead utilize Behavior-Driven Development (BDD) tests to evaluate the `llappearanceutility` through the bake service. For local development, test inputs and their expected outputs are provided below.
+
+### Test Commands
+
+1. **Baking Textures**:
+ ```sh
+ appearance-utility-bin --agent-id de494a4f-f01a-47a4-98cf-c94ef9ecca38 --texture /viewer/indra/llappearanceutility/tests/texture.llsd.binary > /viewer/indra/llappearanceutility/tests/texture.llsd.output
+ ```
+
+2. **Generating Bake Parameters**:
+ ```sh
+ appearance-utility-bin --agent-id de494a4f-f01a-47a4-98cf-c94ef9ecca38 --params /viewer/indra/llappearanceutility/tests/params.xml > /viewer/indra/llappearanceutility/tests/params.xml.output
+ ```
+
+3. **Calculating Joint Offsets**:
+ ```sh
+ appearance-utility-bin --agent-id de494a4f-f01a-47a4-98cf-c94ef9ecca38 --joint-offsets /viewer/indra/llappearanceutility/tests/joint-offsets.xml > /viewer/indra/llappearanceutility/tests/joint-offsets.xml.output
+ ```
+
+These commands will execute the utility with specific test inputs and direct the output to corresponding files for validation. \ No newline at end of file
diff --git a/indra/llappearanceutility/appearance_utility.cpp b/indra/llappearanceutility/appearance_utility.cpp
new file mode 100644
index 0000000000..a9a310eb89
--- /dev/null
+++ b/indra/llappearanceutility/appearance_utility.cpp
@@ -0,0 +1,71 @@
+/**
+ * @file appearance_utility.cpp
+ * @author Don Kjer <don@lindenlab.com>, Nyx Linden
+ * @brief Utility for processing avatar appearance without a full viewer implementation.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+// linden includes
+#include "linden_common.h"
+#include "llapr.h"
+
+// project includes
+#include "llappappearanceutility.h"
+
+int main(int argc, char** argv)
+{
+ // Call Tracy first thing to have it allocate memory
+ // https://github.com/wolfpld/tracy/issues/196
+ LL_PROFILER_FRAME_END;
+ LL_PROFILER_SET_THREAD_NAME("App");
+
+ // Create an application instance.
+ ll_init_apr();
+ LLAppAppearanceUtility* app = new LLAppAppearanceUtility(argc, argv);
+
+ // Assume success, unless exception is thrown.
+ EResult rv = RV_SUCCESS;
+ try
+ {
+ // Process command line and initialize system.
+ if (app->init())
+ {
+ // Run process.
+ app->frame();
+ }
+ }
+ catch (LLAppException& e)
+ {
+ // Deal with errors.
+ rv = e.getStatusCode();
+ }
+
+ // Clean up application instance.
+ app->cleanup();
+ delete app;
+ ll_cleanup_apr();
+
+ return (int) rv;
+}
+
+
diff --git a/indra/llappearanceutility/llappappearanceutility.cpp b/indra/llappearanceutility/llappappearanceutility.cpp
new file mode 100644
index 0000000000..d223c859ab
--- /dev/null
+++ b/indra/llappearanceutility/llappappearanceutility.cpp
@@ -0,0 +1,681 @@
+/**
+ * @file llappappearanceutility.cpp
+ * @brief Implementation of LLAppAppearanceUtility class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 <iostream>
+#include <sstream>
+#include <string>
+#include "boost/bind.hpp"
+
+// linden includes
+#include "linden_common.h"
+
+#include "llapr.h"
+#include "llerrorcontrol.h"
+#include "llfasttimer.h"
+#include "llgl.h"
+#include "llmd5.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "llsdutil.h"
+#include "llquantize.h"
+#include "lltreeiterators.h"
+#include "v3color.h"
+#include "llwindow.h"
+#include "lltrace.h"
+
+// appearance includes
+#include "llavatarappearance.h"
+#include "llwearabletype.h"
+
+// project includes
+#include "llappappearanceutility.h"
+#include "llbakingprocess.h"
+#include "llprocessparams.h"
+#include "llprocesstexture.h"
+#include "llprocessskin.h"
+
+const std::string NOTHING_EXTRA("");
+
+////////////////////////////////////////////
+// LLAppException
+////////////////////////////////////////////
+
+static const std::string MESSAGE_RV_UNKNOWN("Unknown error.");
+static const std::string MESSAGE_RV_ARGUMENTS
+("Invalid arguments: ");
+static const std::string MESSAGE_RV_UNABLE_OPEN("Unable to open file: ");
+static const std::string MESSAGE_RV_UNABLE_TO_PARSE("Unable to parse input LLSD.");
+static const std::string MESSAGE_RV_UNABLE_TO_DECODE("Unable to decode input J2C.");
+static const std::string MESSAGE_RV_UNABLE_TO_ENCODE("Unable to encode output J2C.");
+static const std::string MESSAGE_RV_UNABLE_TO_INIT_GL("Unable to initialize GL.");
+static const std::string MESSAGE_RV_UNABLE_TO_BAKE("Unable to bake texture.");
+static const std::string MESSAGE_RV_INVALID_SKIN_BLOCK("Invalid skin block.");
+static const std::string MESSAGE_DUPLICATE_MODES = "Cannot specify more than one process mode.";
+
+
+LLAppException::LLAppException(EResult status_code, const std::string& extra) :
+ mStatusCode(status_code)
+{
+ switch(status_code)
+ {
+ case RV_UNKNOWN_ERROR:
+ printErrorLLSD("unknown", MESSAGE_RV_UNKNOWN);
+ case RV_BAD_ARGUMENTS:
+ printErrorLLSD("arguments", MESSAGE_RV_ARGUMENTS + extra);
+ break;
+ case RV_UNABLE_OPEN:
+ printErrorLLSD("file", MESSAGE_RV_UNABLE_OPEN + extra);
+ break;
+ case RV_UNABLE_TO_PARSE:
+ printErrorLLSD("input", MESSAGE_RV_UNABLE_TO_PARSE + extra);
+ break;
+ case RV_UNABLE_TO_DECODE:
+ printErrorLLSD("input", MESSAGE_RV_UNABLE_TO_DECODE + extra);
+ break;
+ case RV_UNABLE_TO_ENCODE:
+ printErrorLLSD("input", MESSAGE_RV_UNABLE_TO_ENCODE + extra);
+ break;
+ case RV_UNABLE_TO_INIT_GL:
+ printErrorLLSD("input", MESSAGE_RV_UNABLE_TO_INIT_GL + extra);
+ break;
+ case RV_UNABLE_TO_BAKE:
+ printErrorLLSD("input", MESSAGE_RV_UNABLE_TO_BAKE + extra);
+ break;
+ case RV_INVALID_SKIN_BLOCK:
+ printErrorLLSD("input", MESSAGE_RV_INVALID_SKIN_BLOCK + extra);
+ break;
+ default:
+ printErrorLLSD("arguments", "Unknown exception.");
+ break;
+ }
+}
+
+void LLAppException::printErrorLLSD(const std::string& key, const std::string& message)
+{
+ LLSD error_llsd;
+ error_llsd["success"] = false;
+ error_llsd["error"]["key"] = key;
+ error_llsd["error"]["message"] = message;
+
+ std::cerr << LLSDOStreamer<LLSDXMLFormatter>(error_llsd);
+}
+
+
+
+////////////////////////////////////////////
+// LLAppAppearanceUtility
+////////////////////////////////////////////
+
+///////// Option Parsing /////////
+
+// Simple usage command.
+class LLProcessUsage : public LLBakingProcess
+{
+public:
+ LLProcessUsage(LLAppAppearanceUtility* app) :
+ LLBakingProcess(app) {}
+ void process(std::ostream& output) override
+ {
+ mApp->usage(output);
+ }
+};
+
+
+static const apr_getopt_option_t APPEARANCE_UTILITY_OPTIONS[] =
+{
+ {"params", 'p', 0, "Generate appearance parameters for an agent."},
+ {"texture", 't', 0, "Generate baked texture for a slot."},
+ {"output", 'o', 1, "The output file to write to. Default is stdout"},
+ {"agent-id", 'a', 1, "The agent-id of the user."},
+ {"bake-size", 'b', 1, "The bake texture size. eg use 512 for 512*512 textures, 1024 for 1024*1024 textures" },
+ //{"grid", 'g', 1, "The grid."},
+ {"debug", 'd', 0, "Enable debug spam. Default is warn/info spam only."},
+ {"treemap", 'm', 1, "Output LLFrameTimer to specified file in graphviz treemap/pachwork format."},
+ {"threshold", 's', 1, "Percent threshold of max LLFrameTimer time in order to appear on treemap. Default is 1%."},
+ {"joint-offsets",'j',0,"Extract joint positions from skin."},
+ {"help", 'h', 0, "Print the help message."},
+ {0, 0, 0, 0}
+};
+
+void LLAppAppearanceUtility::usage(std::ostream& ostr)
+{
+ ostr << "Utilities for processing agent appearance data."
+ << std::endl << std::endl
+ << "Usage:" << std::endl
+ << "\t" << mAppName << " [options] filename" << std::endl << std::endl
+ << "Will read from stdin if filename is set to '-'." << std::endl << std::endl
+ << "Options:" << std::endl;
+ const apr_getopt_option_t* option = &APPEARANCE_UTILITY_OPTIONS[0];
+ while(option->name)
+ {
+ ostr << "\t--" << option->name << "\t\t"
+ << option->description << std::endl;
+ ++option;
+ }
+ ostr << std::endl << "Return Values:" << std::endl
+ << "\t0\t\tSuccess." << std::endl
+ << "\t1\t\tUnknown error." << std::endl
+ << "\t2\t\tBad arguments." << std::endl
+ << "\t3\t\tUnable to open file. Possibly wrong filename"
+ << " or bad permissions." << std::endl
+ << "\t4\t\tUnable to parse input LLSD." << std::endl
+ << std::endl
+ << "Output:" << std::endl
+ << "If a non-zero status code is returned, additional error information"
+ << " will be returned on stderr." << std::endl
+ << "* This will be in the form of an LLSD document." << std::endl
+ << "* Check ['error']['message'] to get a human readable message." << std::endl
+ << "If a zero status code is returned, processed output will be written"
+ << " to the file specified by --out (or stdout, if not specified)." << std::endl
+ << std::endl
+ << std::endl;
+}
+
+
+/////// LLApp Interface ////////
+
+LLAppAppearanceUtility::LLAppAppearanceUtility(int argc, char** argv) :
+ LLApp(),
+ mArgc(argc),
+ mArgv(argv),
+ mProcess(nullptr),
+ mInput(nullptr),
+ mOutput(nullptr),
+ mAppName(argv[0]),
+ mDebugMode(false),
+ mTreeMapThreshold(1),
+ mBakeTextureSize(512)
+{
+}
+
+// virtual
+LLAppAppearanceUtility::~LLAppAppearanceUtility()
+{
+}
+
+void LLAppAppearanceUtility::verifyNoProcess()
+{
+ if (mProcess)
+ {
+ std::cerr << "Invalid arguments. " << MESSAGE_DUPLICATE_MODES << std::endl;
+ usage(std::cerr);
+ throw LLAppException(RV_BAD_ARGUMENTS, MESSAGE_DUPLICATE_MODES);
+ }
+}
+
+void LLAppAppearanceUtility::parseArguments()
+{
+ ////// BEGIN OPTION PARSING //////
+ // Check for '-' as last option, since apr doesn't seem to like that.
+ if (std::string(mArgv[mArgc-1]) == "-")
+ {
+ mInputFilename.assign("-");
+ mArgc--;
+ }
+
+ apr_status_t apr_err;
+ const char* opt_arg = nullptr;
+ int opt_id = 0;
+ apr_getopt_t* os = nullptr;
+ if(APR_SUCCESS != apr_getopt_init(&os, gAPRPoolp, mArgc, mArgv))
+ {
+ std::cerr << "Unable to initialize apr" << std::endl;
+ throw LLAppException(RV_UNKNOWN_ERROR);
+ }
+
+ //std::string grid;
+ while(true)
+ {
+ apr_err = apr_getopt_long(os, APPEARANCE_UTILITY_OPTIONS, &opt_id, &opt_arg);
+ if(APR_STATUS_IS_EOF(apr_err)) break;
+ if(apr_err)
+ {
+ char buf[MAX_STRING]; /* Flawfinder: ignore */
+ std::cerr << "Error parsing options: "
+ << apr_strerror(apr_err, buf, MAX_STRING) << std::endl;
+ usage(std::cerr);
+ throw LLAppException(RV_BAD_ARGUMENTS, buf);
+ }
+ switch (opt_id)
+ {
+ case 'h':
+ verifyNoProcess();
+ mProcess = new LLProcessUsage(this);
+ break;
+ case 'p':
+ verifyNoProcess();
+ mProcess = new LLProcessParams(this);
+ break;
+ case 't':
+ verifyNoProcess();
+ mProcess = new LLProcessTexture(this);
+ break;
+ case 'j':
+ verifyNoProcess();
+ mProcess = new LLProcessSkin( this );
+ break;
+ case 'o':
+ mOutputFilename.assign(opt_arg);
+ break;
+ case 'a':
+ mAgentID.set(opt_arg);
+ if (mAgentID.isNull())
+ {
+ const char* INVALID_AGENT_ID="agent-id must be a valid uuid.";
+ std::cerr << "Invalid arguments. " << INVALID_AGENT_ID << std::endl;
+ usage(std::cerr);
+ throw LLAppException(RV_BAD_ARGUMENTS, INVALID_AGENT_ID);
+ }
+ break;
+ case 'b':
+ mBakeTextureSize = atoi(opt_arg);
+ break;
+ //case 'g':
+ // grid = opt_arg;
+ // break;
+ case 'd':
+ mDebugMode = true;
+ break;
+ case 'm':
+ mTreeMapFilename.assign(opt_arg);
+ break;
+ case 's':
+ mTreeMapThreshold = atoi(opt_arg);
+ break;
+ default:
+ usage(std::cerr);
+ throw LLAppException(RV_BAD_ARGUMENTS, "Unknown option.");
+ }
+ }
+
+ if ("-" != mInputFilename)
+ {
+ bool valid_input_filename = false;
+ // Try to grab the input filename.
+ if (os->argv && os->argv[os->ind])
+ {
+ mInputFilename.assign(os->argv[os->ind]);
+ if (! mInputFilename.empty() )
+ {
+ valid_input_filename = true;
+ }
+ }
+ if (!valid_input_filename)
+ {
+ const char* INVALID_FILENAME="Must specify input file.";
+ std::cerr << "Invalid arguments. " << INVALID_FILENAME << std::endl;
+ usage(std::cerr);
+ throw LLAppException(RV_BAD_ARGUMENTS, INVALID_FILENAME);
+ }
+ }
+
+ ////// END OPTION PARSING //////
+}
+
+void LLAppAppearanceUtility::validateArguments()
+{
+ ///// BEGIN ARGUMENT VALIDATION /////
+
+ // Make sure we have a command specified.
+ if (!mProcess)
+ {
+ const char* INVALID_MODE="No process mode specified.";
+ std::cerr << "Invalid arguments. " << INVALID_MODE
+ << std::endl;
+ usage(std::cerr);
+ throw LLAppException(RV_BAD_ARGUMENTS, INVALID_MODE);
+ }
+
+ ///// END ARGUMENT VALIDATION /////
+}
+
+void LLAppAppearanceUtility::initializeIO()
+{
+ ///// BEGIN OPEN INPUT FILE ////
+
+ if ( "-" == mInputFilename )
+ {
+ // Read unformated data from stdin in to memory.
+ std::stringstream* data = new std::stringstream();
+ const S32 BUFFER_SIZE = BUFSIZ;
+ char buffer[BUFFER_SIZE];
+ while (true)
+ {
+ std::cin.read(buffer, BUFFER_SIZE);
+ // Check if anything out of the ordinary happened.
+ if (!std::cin)
+ {
+ // See if something 'really bad' happened, or if we just
+ // used up all of our buffer.
+ if (std::cin.bad())
+ {
+ std::cerr << "Problem reading standard input." << std::endl;
+ delete data;
+ throw (RV_UNKNOWN_ERROR);
+ }
+ else
+ {
+ // Output normally.
+ data->write(buffer, std::cin.gcount());
+ if (std::cin.eof()) break;
+
+ // Clear this problem. We have handled it.
+ std::cin.clear();
+ }
+ }
+ else
+ {
+ data->write(buffer, std::cin.gcount());
+ if (std::cin.eof()) break;
+ }
+ }
+ mInput = data;
+ }
+ else
+ {
+ // Make sure we can open the input file.
+ std::ifstream* input_file = new std::ifstream();
+ input_file->open( mInputFilename.c_str(), std::fstream::in | std::fstream::binary );
+ if ( input_file->fail())
+ {
+ std::cerr << "Couldn't open input file '" << mInputFilename << "'." << std::endl;
+ delete input_file;
+ throw LLAppException(RV_UNABLE_OPEN, mInputFilename);
+ }
+ mInput = input_file;
+ }
+ ///// END OPEN INPUT FILE ////
+
+ ///// BEGIN OPEN OUTPUT FILE ////
+
+ if ("" == mOutputFilename)
+ {
+ mOutput = &std::cout;
+ }
+ else
+ {
+ // Make sure we can open the output file.
+ std::fstream* output_file = new std::fstream();
+ output_file->open( mOutputFilename.c_str(), std::fstream::out );
+ if ( output_file->fail() )
+ {
+ std::cerr << "Couldn't open output file '" << mOutputFilename << "'." << std::endl;
+ delete output_file;
+ throw LLAppException(RV_UNABLE_OPEN, mOutputFilename);
+ }
+ mOutput = output_file;
+ }
+ ///// END OPEN OUTPUT FILE ////
+
+ ///// BEGIN INPUT PARSING ////
+ if (mProcess)
+ {
+ mProcess->parseInput( *mInput );
+ }
+ ///// END INPUT PARSING ////
+}
+
+class LLPassthroughTranslationBridge : public LLTranslationBridge
+{
+public:
+ virtual std::string getString(const std::string &xml_desc)
+ {
+ // Just pass back the input string.
+ return xml_desc;
+ }
+};
+
+
+bool LLAppAppearanceUtility::init()
+{
+ parseArguments();
+
+ bool log_to_stderr = true;
+ LLError::initForApplication(".", ".", true);
+ if (mDebugMode)
+ {
+ mRecording.start();
+ LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
+ }
+ else
+ {
+ LLError::setDefaultLevel(LLError::LEVEL_WARN);
+ }
+
+ validateArguments();
+
+ LL_DEBUGS() << "BakeSize: " << mBakeTextureSize << LL_ENDL;
+
+ // Initialize classes.
+ // Values taken from settings.xml.
+ const bool USE_TEXTURE_NEW_BYTE_RANGE=true;
+ const S32 TEXTURE_REVERSE_BYTE_RANGE=50;
+ LLImage::initClass(USE_TEXTURE_NEW_BYTE_RANGE, TEXTURE_REVERSE_BYTE_RANGE);
+ const bool SKIP_ANALYZE_ALPHA=true;
+
+ LLTranslationBridge::ptr_t trans = std::make_shared<LLPassthroughTranslationBridge>();
+ LLWearableType::initParamSingleton(trans);
+
+ // *TODO: Create a texture bridge?
+ LLAvatarAppearance::initClass();
+
+ initializeIO();
+ if (mProcess)
+ {
+ mProcess->init();
+ }
+ return true;
+}
+
+
+void add_cluster(LLTrace::Recording& recording, std::ostream& tree, LLTrace::BlockTimerStatHandle& node, std::vector < S32 > & clusters, F64Milliseconds threshold)
+{
+ LLMD5 hash;
+ hash.update((const unsigned char*)node.getName().c_str(), node.getName().size());
+ hash.finalize();
+ char buf[33];
+ hash.hex_digest(buf);
+ buf[6] = 0;
+ LLColor3 color(buf);
+ if (color.brightness() < 0.25f)
+ {
+ color.normalize();
+ }
+ std::ostringstream color_str;
+ color_str << "#" << std::hex << std::setfill('0') << std::setw(2)
+ << (S32) F32_to_U8(color.mV[0], 0.0f, 1.0f)
+ << (S32) F32_to_U8(color.mV[1], 0.0f, 1.0f)
+ << (S32) F32_to_U8(color.mV[2], 0.0f, 1.0f);
+
+ std::vector<S32>::iterator iter = clusters.begin();
+ std::vector<S32>::iterator end = clusters.end();
+ std::ostringstream padding;
+ for(; iter != end; ++iter)
+ {
+ padding << " ";
+ }
+
+ std::ostringstream node_id;
+ bool first = true;
+ iter = clusters.begin();
+ for(; iter != end; ++iter)
+ {
+ if (!first)
+ {
+ node_id << "_";
+ }
+ first = false;
+ node_id << (*iter);
+ }
+
+ if (node.getChildren().size() == 0)
+ {
+ F64Milliseconds leaf_time_ms(recording.getSum(node));
+ if (leaf_time_ms > threshold)
+ {
+ tree << padding.str() << "n" << node_id.str() << " ["
+ << "label=\"" << node.getName() << " (" << leaf_time_ms.value() << ")\" "
+ << "fillcolor=\"" << color_str.str() << "\" "
+ << "area=" << leaf_time_ms.value() / 10 << "]" << std::endl;
+ }
+ }
+ else
+ {
+ if (clusters.size())
+ {
+ tree << padding.str() << "subgraph cluster" << node_id.str();
+ tree << " {" << std::endl;
+ }
+
+ S32Milliseconds node_area(recording.getSum(node));
+ std::vector<LLTrace::BlockTimerStatHandle*>::iterator child_iter = node.getChildren().begin();
+ for (S32 num=0; child_iter != node.getChildren().end(); ++child_iter, ++num)
+ {
+ clusters.push_back(num);
+ add_cluster(recording, tree, *(*child_iter), clusters, threshold);
+ clusters.pop_back();
+ node_area -= recording.getSum(*(*child_iter));
+ }
+
+ S32Milliseconds node_time_ms(node_area);
+ if (node_time_ms > threshold)
+ {
+ tree << padding.str() << "n" << node_id.str() << " ["
+ << "label=\"" << node.getName() << " (" << node_time_ms.value() << ")\" "
+ << "fillcolor=\"" << color_str.str() << "\" "
+ << "area=" << node_time_ms.value() / 10 << "]" << std::endl;
+ }
+ if (clusters.size())
+ {
+ tree << padding.str() << "}" << std::endl;;
+ }
+ }
+}
+
+bool LLAppAppearanceUtility::cleanup()
+{
+ if (mProcess)
+ {
+ mProcess->cleanup();
+ }
+
+ // Spam fast timer information in debug mode.
+ if (mDebugMode)
+ {
+ mRecording.stop();
+ LLTrace::BlockTimer::processTimes();
+
+ S32Milliseconds max_time_ms(0);
+ for (LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(LLTrace::BlockTimer::getRootTimeBlock());
+ it != LLTrace::end_block_timer_tree_df();
+ ++it)
+ {
+ LLTrace::BlockTimerStatHandle* idp = (*it);
+ // Skip near-zero time leafs.
+ S32Milliseconds leaf_time_ms(mRecording.getSum(*idp));
+ if (leaf_time_ms > max_time_ms) max_time_ms = leaf_time_ms;
+ if ((S32Milliseconds)0 == leaf_time_ms) continue;
+
+ std::vector< LLTrace::BlockTimerStatHandle* > parents;
+ LLTrace::BlockTimerStatHandle* parentp = idp->getParent();
+ while (parentp)
+ {
+ parents.push_back(parentp);
+ if (parentp->getParent() == parentp) break;
+ parentp = parentp->getParent();
+ }
+
+ std::ostringstream fullname;
+ bool is_first = true;
+ for ( std::vector< LLTrace::BlockTimerStatHandle* >::reverse_iterator iter = parents.rbegin();
+ iter != parents.rend(); ++iter)
+ {
+ // Skip root
+ if (is_first)
+ {
+ is_first = false;
+ continue;
+ }
+ LLTrace::BlockTimerStatHandle* parent_idp = (*iter);
+ U32Milliseconds time_ms(mRecording.getSum(parent_idp->selfTime()));
+ fullname << parent_idp->getName() << " ";
+ fullname << "(";
+ if (time_ms > (U32Milliseconds)0)
+ {
+ fullname << time_ms.value() << " ms, ";
+ }
+ fullname << mRecording.getSum(parent_idp->callCount()) << " call)-> ";
+ }
+ LL_DEBUGS() << fullname.str() << LL_ENDL;
+ }
+ if (!mTreeMapFilename.empty())
+ {
+ std::ofstream tree(mTreeMapFilename.c_str());
+ tree << "graph G {" << std::endl;
+ tree << " node[style=filled]" << std::endl;
+
+ LLTrace::BlockTimerStatHandle& root = LLTrace::BlockTimer::getRootTimeBlock();
+ std::vector<S32> clusters;
+ add_cluster(mRecording, tree, root, clusters, (((F32) mTreeMapThreshold / 100.f) * max_time_ms) );
+
+ tree << "}" << std::endl;
+
+ LL_DEBUGS() << "To generate a treemap of LLFrameTimer results, run:" << LL_ENDL;
+ LL_DEBUGS() << "patchwork " << mTreeMapFilename << " -Tpng > rendered.png" << LL_ENDL;
+ }
+ }
+
+ LLAvatarAppearance::cleanupClass();
+ LLImageGL::cleanupClass();
+ LLImage::cleanupClass();
+
+ if (mProcess)
+ {
+ delete mProcess;
+ mProcess = nullptr;
+ }
+ if ("-" != mInputFilename && mInput)
+ {
+ static_cast<std::ifstream*>(mInput)->close();
+ }
+ if ("" != mOutputFilename && mOutput)
+ {
+ static_cast<std::ofstream*>(mOutput)->close();
+ delete mOutput;
+ mOutput = nullptr;
+ }
+ delete mInput;
+ mInput = nullptr;
+ return true;
+}
+
+bool LLAppAppearanceUtility::frame()
+{
+ // This isn't really a loop, for this application. We just execute the requested command.
+ mProcess->process(*mOutput);
+ return true;
+}
+
diff --git a/indra/llappearanceutility/llappappearanceutility.h b/indra/llappearanceutility/llappappearanceutility.h
new file mode 100644
index 0000000000..80d1e8b1bf
--- /dev/null
+++ b/indra/llappearanceutility/llappappearanceutility.h
@@ -0,0 +1,108 @@
+/**
+ * @file llappappearanceutility.h
+ * @brief Declaration of LLAppAppearanceUtility class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLAPPAPPEARANCEUTILITY_H
+#define LL_LLAPPAPPEARANCEUTILITY_H
+
+#include <exception>
+
+#include "llapp.h"
+#include "lltracerecording.h"
+
+enum EResult
+{
+ RV_SUCCESS = 0,
+ RV_UNKNOWN_ERROR,
+ RV_BAD_ARGUMENTS,
+ RV_UNABLE_OPEN,
+ RV_UNABLE_TO_PARSE,
+ RV_UNABLE_TO_DECODE,
+ RV_UNABLE_TO_ENCODE,
+ RV_UNABLE_TO_INIT_GL,
+ RV_UNABLE_TO_BAKE,
+ RV_INVALID_SKIN_BLOCK,
+};
+
+extern const std::string NOTHING_EXTRA;
+
+class LLAppAppearanceUtility;
+class LLBakingProcess;
+
+// Translate error status into error messages.
+class LLAppException : public std::exception
+{
+public:
+ LLAppException(EResult status_code, const std::string& extra = NOTHING_EXTRA);
+ EResult getStatusCode() { return mStatusCode; }
+
+private:
+ void printErrorLLSD(const std::string& key, const std::string& message);
+ EResult mStatusCode;
+};
+
+
+class LLAppAppearanceUtility : public LLApp
+{
+public:
+ LLAppAppearanceUtility(int argc, char** argv);
+ virtual ~LLAppAppearanceUtility();
+
+ // LLApp interface.
+ bool init() override;
+ bool cleanup() override;
+ bool frame() override;
+
+private:
+ // Option parsing.
+ void verifyNoProcess();
+ void parseArguments();
+ void validateArguments();
+ void initializeIO();
+public:
+ void usage(std::ostream& ostr);
+ bool isDebugMode() const { return mDebugMode; }
+ S32 bakeTextureSize() const { return mBakeTextureSize; }
+
+private:
+ int mArgc;
+ char** mArgv;
+ LLBakingProcess* mProcess;
+ std::istream* mInput;
+ std::ostream* mOutput;
+ std::string mAppName;
+ std::string mInputFilename;
+ std::string mOutputFilename;
+ LLUUID mAgentID;
+ S32 mBakeTextureSize;
+ bool mDebugMode;
+ LLTrace::Recording mRecording;
+ S32 mTreeMapThreshold;
+ std::string mTreeMapFilename;
+};
+
+
+#endif /* LL_LLAPPAPPEARANCEUTILITY_H */
+
diff --git a/indra/llappearanceutility/llbakingavatar.cpp b/indra/llappearanceutility/llbakingavatar.cpp
new file mode 100644
index 0000000000..426fa705e9
--- /dev/null
+++ b/indra/llappearanceutility/llbakingavatar.cpp
@@ -0,0 +1,177 @@
+/**
+ * @File llbakingavatar.cpp
+ * @brief Implementation of LLBakingAvatar class which is a derivation of LLAvatarAppearance
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+// linden includes
+#include "linden_common.h"
+#include "v3dmath.h"
+
+// appearance includes
+#include "llavatarappearancedefines.h"
+
+// project includes
+#include "llbakingavatar.h"
+#include "llbakingjoint.h"
+#include "llbakingjointmesh.h"
+#include "llbakingtexlayer.h"
+
+using namespace LLAvatarAppearanceDefines;
+
+LLBakingAvatar::LLBakingAvatar(LLWearableData* wearable_data,S32 bakeTextureSize) :
+ LLAvatarAppearance(wearable_data),
+ mBakeTextureSize(bakeTextureSize)
+{
+}
+
+// virtual
+LLBakingAvatar::~LLBakingAvatar()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Implemented methods
+//-----------------------------------------------------------------------------
+
+LLAvatarJoint* LLBakingAvatar::createAvatarJoint()
+{
+ return new LLBakingJoint();
+}
+
+LLAvatarJoint* LLBakingAvatar::createAvatarJoint(S32 joint_num)
+{
+ return new LLBakingJoint(joint_num);
+}
+
+LLAvatarJointMesh* LLBakingAvatar::createAvatarJointMesh()
+{
+ return new LLBakingJointMesh();
+}
+
+LLTexLayerSet* LLBakingAvatar::createTexLayerSet()
+{
+ return new LLBakingTexLayerSet(this);
+}
+
+void LLBakingAvatar::bakedTextureDatasAsLLSD(LLSD& sd) const
+{
+ bakedtexturedata_vec_t::const_iterator baked_iter = mBakedTextureDatas.begin();
+ bakedtexturedata_vec_t::const_iterator baked_end = mBakedTextureDatas.end();
+ for (; baked_iter != baked_end; ++baked_iter)
+ {
+ LLBakingTexLayerSet* layer_set = dynamic_cast<LLBakingTexLayerSet*>(baked_iter->mTexLayerSet);
+ LLSD layer_sd;
+ layer_set->asLLSD(layer_sd);
+ sd[LLAvatarAppearance::getDictionary()->getTexture(baked_iter->mTextureIndex)->mName] = layer_sd;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// (Ignored) Non-implemented methods.
+//-----------------------------------------------------------------------------
+
+void LLBakingAvatar::applyMorphMask(const U8* tex_data, S32 width, S32 height, S32 num_components,
+ LLAvatarAppearanceDefines::EBakedTextureIndex index) {}
+void LLBakingAvatar::invalidateComposite(LLTexLayerSet* layerset) {}
+void LLBakingAvatar::updateMeshTextures() {}
+void LLBakingAvatar::dirtyMesh() {}
+void LLBakingAvatar::dirtyMesh(S32 priority) {}
+void LLBakingAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color) {}
+
+bool LLBakingAvatar::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
+{
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// (LLERR) Non-implemented methods.
+//-----------------------------------------------------------------------------
+
+LLVector3 LLBakingAvatar::getCharacterPosition()
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+ return LLVector3::zero;
+}
+
+LLQuaternion LLBakingAvatar::getCharacterRotation()
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+ return LLQuaternion::DEFAULT;
+}
+
+LLVector3 LLBakingAvatar::getCharacterVelocity()
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+ return LLVector3::zero;
+}
+
+LLVector3 LLBakingAvatar::getCharacterAngularVelocity()
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+ return LLVector3::zero;
+}
+
+const LLUUID& LLBakingAvatar::getID() const
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+ return LLUUID::null;
+}
+
+void LLBakingAvatar::addDebugText(const std::string& text)
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+}
+
+F32 LLBakingAvatar::getTimeDilation()
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+ return 0.0f;
+}
+
+void LLBakingAvatar::getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm)
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+}
+
+F32 LLBakingAvatar::getPixelArea() const
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+ return 0.0f;
+}
+
+LLVector3d LLBakingAvatar::getPosGlobalFromAgent(const LLVector3 &position)
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+ return LLVector3d::zero;
+}
+
+LLVector3 LLBakingAvatar::getPosAgentFromGlobal(const LLVector3d &position)
+{
+ LL_ERRS("AppearanceUtility") << "Not implemented." << LL_ENDL;
+ return LLVector3::zero;
+}
+
+
+
diff --git a/indra/llappearanceutility/llbakingavatar.h b/indra/llappearanceutility/llbakingavatar.h
new file mode 100644
index 0000000000..b4cf99cbfb
--- /dev/null
+++ b/indra/llappearanceutility/llbakingavatar.h
@@ -0,0 +1,131 @@
+/**
+ * @file llbakingavatar.h
+ * @brief Declaration of LLBakingAvatar class which is a derivation of LLAvatarAppearance
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLBAKINGAVATAR_H
+#define LL_LLBAKINGAVATAR_H
+
+#include "llavatarappearance.h"
+
+class LLBakingAvatar : public LLAvatarAppearance
+{
+ LOG_CLASS(LLBakingAvatar);
+
+/********************************************************************************
+ ** **
+ ** INITIALIZATION
+ **/
+public:
+ LL_ALIGN_NEW
+
+ LLBakingAvatar(LLWearableData* wearable_data, S32 bakeTextureSize = 512);
+ virtual ~LLBakingAvatar();
+
+ static void initClass(); // initializes static members
+
+/** Initialization
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** INHERITED
+ **/
+
+ //--------------------------------------------------------------------
+ // LLCharacter interface
+ //--------------------------------------------------------------------
+public:
+ LLVector3 getCharacterPosition() override;
+ LLQuaternion getCharacterRotation() override;
+ LLVector3 getCharacterVelocity() override;
+ LLVector3 getCharacterAngularVelocity() override;
+
+ const LLUUID& getID() const override;
+ void addDebugText(const std::string& text) override;
+ F32 getTimeDilation() override;
+ void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm) override;
+ F32 getPixelArea() const override;
+ LLVector3d getPosGlobalFromAgent(const LLVector3 &position) override;
+ LLVector3 getPosAgentFromGlobal(const LLVector3d &position) override;
+
+ //--------------------------------------------------------------------
+ // LLAvatarAppearance interface
+ //--------------------------------------------------------------------
+public:
+ void applyMorphMask(const U8* tex_data, S32 width, S32 height, S32 num_components,
+ LLAvatarAppearanceDefines::EBakedTextureIndex index) override;
+ void invalidateComposite(LLTexLayerSet* layerset) override;
+ void updateMeshTextures() override;
+ void dirtyMesh() override; // Dirty the avatar mesh
+ void onGlobalColorChanged(const LLTexGlobalColor* global_color) override;
+ bool isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const override;
+ bool isUsingLocalAppearance() const override { return false; }
+ bool isEditingAppearance() const override { return false; }
+private:
+ void dirtyMesh(S32 priority) override; // Dirty the avatar mesh, with priority
+
+ // LLAvatarAppearance instance factories:
+protected:
+ LLAvatarJoint* createAvatarJoint() override;
+ LLAvatarJoint* createAvatarJoint(S32 joint_num) override;
+ LLAvatarJointMesh* createAvatarJointMesh() override;
+ LLTexLayerSet* createTexLayerSet() override;
+
+
+/** Inherited
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** STATE
+ **/
+public:
+ bool isSelf() const override { return true; }
+ bool isValid() const override { return true; }
+
+/** State
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** BAKING
+ **/
+public:
+ void bakedTextureDatasAsLLSD(LLSD& sd) const;
+ S32 bakeTextureSize() const { return mBakeTextureSize; }
+
+/** Baking
+ ** **
+ *******************************************************************************/
+
+private:
+ S32 mBakeTextureSize;
+};
+
+#endif /* LL_LLBAKINGAVATAR_H */
+
diff --git a/indra/linux_crash_logger/llcrashloggerlinux.h b/indra/llappearanceutility/llbakingjoint.cpp
index dcecbe746d..25edaa645f 100644
--- a/indra/linux_crash_logger/llcrashloggerlinux.h
+++ b/indra/llappearanceutility/llbakingjoint.cpp
@@ -1,10 +1,10 @@
/**
- * @file llcrashloggerlinux.h
- * @brief Linux crash logger definition
+ * @file llbakingjoint.cpp
+ * @brief Implementation of LLBakingJoint class
*
- * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2012, 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
@@ -24,22 +24,31 @@
* $/LicenseInfo$
*/
-#ifndef LLCRASHLOGGERLINUX_H
-#define LLCRASHLOGGERLINUX_H
#include "linden_common.h"
-#include "llcrashlogger.h"
-#include "llstring.h"
-class LLCrashLoggerLinux : public LLCrashLogger
+#include "llbakingjoint.h"
+
+
+LLBakingJoint::LLBakingJoint() :
+ LLAvatarJoint()
+{
+}
+
+LLBakingJoint::LLBakingJoint(S32 joint_num) :
+ LLAvatarJoint(joint_num)
+{
+}
+
+// virtual
+LLBakingJoint::~LLBakingJoint()
+{
+}
+
+// virtual
+U32 LLBakingJoint::render( F32 pixelArea, bool first_pass, bool is_dummy)
{
-public:
- LLCrashLoggerLinux(void);
- ~LLCrashLoggerLinux(void);
- virtual bool frame();
- virtual void updateApplication(const std::string& = LLStringUtil::null);
- virtual void gatherPlatformSpecificFiles();
- virtual bool cleanup();
-};
+ LL_ERRS() << "LLBakingJoint::render() should never be called!" << LL_ENDL;
+ return 0;
+}
-#endif
diff --git a/indra/llappearanceutility/llbakingjoint.h b/indra/llappearanceutility/llbakingjoint.h
new file mode 100644
index 0000000000..10201cc7b8
--- /dev/null
+++ b/indra/llappearanceutility/llbakingjoint.h
@@ -0,0 +1,45 @@
+/**
+ * @file llbakingjoint.h
+ * @brief Declaration of LLBakingJoint class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLBAKINGJOINT_H
+#define LL_LLBAKINGJOINT_H
+
+#include "llavatarjoint.h"
+
+class alignas(16) LLBakingJoint : public virtual LLAvatarJoint
+{
+ LL_ALIGN_NEW
+public:
+ LLBakingJoint();
+ LLBakingJoint(S32 joint_num);
+ virtual ~LLBakingJoint();
+
+ // LLViewerJoint interface
+ U32 render( F32 pixelArea, bool first_pass = true, bool is_dummy = false ) override;
+};
+
+#endif /* LL_LLBAKINGJOINT_H */
+
diff --git a/indra/llappearanceutility/llbakingjointmesh.cpp b/indra/llappearanceutility/llbakingjointmesh.cpp
new file mode 100644
index 0000000000..b8e3283df2
--- /dev/null
+++ b/indra/llappearanceutility/llbakingjointmesh.cpp
@@ -0,0 +1,43 @@
+/**
+ * @file llbakingjointmesh.cpp
+ * @brief Implementation of LLBakingJointMesh class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llbakingjointmesh.h"
+
+
+LLBakingJointMesh::LLBakingJointMesh() :
+ LLAvatarJointMesh()
+{
+}
+
+// virtual
+LLBakingJointMesh::~LLBakingJointMesh()
+{
+}
+
+
diff --git a/indra/llappearanceutility/llbakingjointmesh.h b/indra/llappearanceutility/llbakingjointmesh.h
new file mode 100644
index 0000000000..9c7b276bd8
--- /dev/null
+++ b/indra/llappearanceutility/llbakingjointmesh.h
@@ -0,0 +1,46 @@
+/**
+ * @file llbakingjoint.h
+ * @brief Implementation of LLBakingJointMesh class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLBAKINGJOINTMESH_H
+#define LL_LLBAKINGJOINTMESH_H
+
+#include "llavatarjointmesh.h"
+#include "llbakingjoint.h"
+
+class alignas(16) LLBakingJointMesh : public LLAvatarJointMesh, public LLBakingJoint
+{
+ LL_ALIGN_NEW
+public:
+ LLBakingJointMesh();
+ LLBakingJointMesh(S32 joint_num);
+ virtual ~LLBakingJointMesh();
+
+ U32 render( F32 pixelArea, bool first_pass = true, bool is_dummy = false )
+ { return LLBakingJoint::render(pixelArea,first_pass,is_dummy); }
+};
+
+#endif /* LL_LLBAKINGJOINTMESH_H */
+
diff --git a/indra/llappearanceutility/llbakingprocess.cpp b/indra/llappearanceutility/llbakingprocess.cpp
new file mode 100644
index 0000000000..85553b0fdb
--- /dev/null
+++ b/indra/llappearanceutility/llbakingprocess.cpp
@@ -0,0 +1,47 @@
+/**
+ * @file llbakingprocess.cpp
+ * @brief Implementation of LLBakingProcess class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+// linden includes
+#include "linden_common.h"
+
+#include "llsd.h"
+#include "llsdserialize.h"
+
+// project includes
+#include "llappappearanceutility.h"
+#include "llbakingprocess.h"
+
+// virtual
+void LLBakingProcess::parseInput(std::istream& input)
+{
+ LLSDSerialize::fromXML( mInputData, input );
+ if (mInputData.isUndefined())
+ {
+ throw LLAppException(RV_UNABLE_TO_PARSE);
+ }
+}
+
+
diff --git a/indra/llappearanceutility/llbakingprocess.h b/indra/llappearanceutility/llbakingprocess.h
new file mode 100644
index 0000000000..de38b7a36b
--- /dev/null
+++ b/indra/llappearanceutility/llbakingprocess.h
@@ -0,0 +1,60 @@
+/**
+ * @file llbakingprocess.h
+ * @brief Declaration of LLBakingProcess interface.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLBAKINGPROCESS_H
+#define LL_LLBAKINGPROCESS_H
+
+#include <ostream>
+
+class LLAppAppearanceUtility;
+class LLSD;
+
+// Simple wrapper for various process modes.
+class LLBakingProcess
+{
+private:
+ // Hide default constructor.
+ LLBakingProcess() {}
+public:
+ LLBakingProcess(LLAppAppearanceUtility* app) :
+ mApp(app) {}
+ virtual ~LLBakingProcess() {}
+
+ virtual void parseInput(std::istream& input);
+ //virtual std::string getProcessName() const = 0;
+ virtual void process(std::ostream& output) = 0;
+
+ virtual void init() {}
+ virtual void cleanup() {}
+
+protected:
+ LLAppAppearanceUtility* mApp;
+ LLSD mInputData;
+};
+
+
+#endif /* LL_LLBAKINGPROCESS_H */
+
diff --git a/indra/llappearanceutility/llbakingshadermgr.cpp b/indra/llappearanceutility/llbakingshadermgr.cpp
new file mode 100644
index 0000000000..5246f96ae4
--- /dev/null
+++ b/indra/llappearanceutility/llbakingshadermgr.cpp
@@ -0,0 +1,250 @@
+
+/**
+ * @file LLBakingShaderMgr.cpp
+ * @brief Viewer shader manager implementation.
+ *
+ * $LicenseInfo:firstyear=2005&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 "llbakingshadermgr.h"
+
+#include "lldir.h"
+#include "llfile.h"
+#include "llrender.h"
+#include "llvertexbuffer.h"
+
+#if LL_DARWIN
+#include "OpenGL/OpenGL.h"
+#endif
+
+#ifdef LL_RELEASE_FOR_DOWNLOAD
+#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
+#else
+#define UNIFORM_ERRS LL_ERRS("Shader")
+#endif
+
+// Lots of STL stuff in here, using namespace std to keep things more readable
+using std::vector;
+using std::pair;
+using std::make_pair;
+using std::string;
+
+bool LLBakingShaderMgr::sInitialized = false;
+bool LLBakingShaderMgr::sSkipReload = false;
+
+//utility shaders
+LLGLSLShader gAlphaMaskProgram;
+
+
+LLBakingShaderMgr::LLBakingShaderMgr() :
+ mVertexShaderLevel(SHADER_COUNT, 0),
+ mMaxAvatarShaderLevel(0)
+{
+}
+
+LLBakingShaderMgr::~LLBakingShaderMgr()
+{
+ mVertexShaderLevel.clear();
+ mShaderList.clear();
+}
+
+// static
+LLBakingShaderMgr * LLBakingShaderMgr::instance()
+{
+ if(nullptr == sInstance)
+ {
+ sInstance = new LLBakingShaderMgr();
+ }
+
+ return static_cast<LLBakingShaderMgr*>(sInstance);
+}
+
+void LLBakingShaderMgr::initAttribsAndUniforms(void)
+{
+ if (mReservedAttribs.empty())
+ {
+ LLShaderMgr::initAttribsAndUniforms();
+ }
+}
+
+
+//============================================================================
+// Set Levels
+
+S32 LLBakingShaderMgr::getVertexShaderLevel(S32 type)
+{
+ return mVertexShaderLevel[type];
+}
+
+//============================================================================
+// Shader Management
+
+void LLBakingShaderMgr::setShaders()
+{
+ //setShaders might be called redundantly by gSavedSettings, so return on reentrance
+ static bool reentrance = false;
+
+ if (!sInitialized || reentrance || sSkipReload)
+ {
+ return;
+ }
+
+ LLGLSLShader::sIndexedTextureChannels = llmax(gGLManager.mNumTextureImageUnits, 1);
+
+ //NEVER use more than 16 texture channels (work around for prevalent driver bug)
+ LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16);
+
+ if (gGLManager.mGLSLVersionMajor < 1 ||
+ (gGLManager.mGLSLVersionMajor == 1 && gGLManager.mGLSLVersionMinor <= 20))
+ { //NEVER use indexed texture rendering when GLSL version is 1.20 or earlier
+ LLGLSLShader::sIndexedTextureChannels = 1;
+ }
+
+ reentrance = true;
+
+ initAttribsAndUniforms();
+
+ // Shaders
+ LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL;
+ LL_INFOS("ShaderLoading") << llformat("Using GLSL %d.%d", gGLManager.mGLSLVersionMajor, gGLManager.mGLSLVersionMinor) << LL_ENDL;
+
+ for (S32 i = 0; i < SHADER_COUNT; i++)
+ {
+ mVertexShaderLevel[i] = 0;
+ }
+ mMaxAvatarShaderLevel = 0;
+
+ LLVertexBuffer::unbind();
+ bool loaded = false;
+ if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10)
+ {
+ S32 light_class = 2;
+ mVertexShaderLevel[SHADER_INTERFACE] = light_class;
+
+ // loadBasicShaders
+ vector< pair<string, S32> > shaders;
+ if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)
+ {
+ shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
+ }
+ shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
+ shaders.push_back( make_pair( "deferred/textureUtilV.glsl", 1 ) );
+ loaded = true;
+ for (U32 i = 0; i < shaders.size(); i++)
+ {
+ // Note usage of GL_VERTEX_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER) == 0)
+ {
+ LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
+ loaded = false;
+ break;
+ }
+ }
+
+ shaders.clear();
+
+ // fragment shaders
+ shaders.push_back( make_pair( "deferred/globalF.glsl", 1 ) );
+
+ for (U32 i = 0; i < shaders.size(); i++)
+ {
+ // Note usage of GL_FRAGMENT_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER) == 0)
+ {
+ LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
+ loaded = false;
+ break;
+ }
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersInterface();
+ }
+ }
+
+ if (!loaded)
+ {
+ //gPipeline.mVertexShadersEnabled = false;
+ //gPipeline.mVertexShadersLoaded = 0;
+ mVertexShaderLevel[SHADER_LIGHTING] = 0;
+ mVertexShaderLevel[SHADER_INTERFACE] = 0;
+ mVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
+ mVertexShaderLevel[SHADER_WATER] = 0;
+ mVertexShaderLevel[SHADER_OBJECT] = 0;
+ mVertexShaderLevel[SHADER_EFFECT] = 0;
+ mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
+ mVertexShaderLevel[SHADER_AVATAR] = 0;
+ }
+
+ //gPipeline.createGLBuffers();
+
+ reentrance = false;
+}
+
+void LLBakingShaderMgr::unloadShaders()
+{
+ gAlphaMaskProgram.unload();
+
+ mVertexShaderLevel[SHADER_INTERFACE] = 0;
+
+ //gPipeline.mVertexShadersLoaded = 0;
+}
+
+bool LLBakingShaderMgr::loadShadersInterface()
+{
+ gAlphaMaskProgram.mName = "Alpha Mask Shader";
+ gAlphaMaskProgram.mShaderFiles.clear();
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER));
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER));
+ gAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+
+ if( !gAlphaMaskProgram.createShader() )
+ {
+ mVertexShaderLevel[SHADER_INTERFACE] = 0;
+ return false;
+ }
+
+ return true;
+}
+
+std::string LLBakingShaderMgr::getShaderDirPrefix(void)
+{
+ return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
+}
+
+void LLBakingShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
+{
+}
+
+LLBakingShaderMgr::shader_iter LLBakingShaderMgr::beginShaders() const
+{
+ return mShaderList.begin();
+}
+
+LLBakingShaderMgr::shader_iter LLBakingShaderMgr::endShaders() const
+{
+ return mShaderList.end();
+}
diff --git a/indra/llappearanceutility/llbakingshadermgr.h b/indra/llappearanceutility/llbakingshadermgr.h
new file mode 100644
index 0000000000..60ab3f94e8
--- /dev/null
+++ b/indra/llappearanceutility/llbakingshadermgr.h
@@ -0,0 +1,137 @@
+/**
+ * @file llbakingshadermgr.h
+ * @brief Texture Baking Shader Manager
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_BAKING_SHADER_MGR_H
+#define LL_BAKING_SHADER_MGR_H
+
+#include "llshadermgr.h"
+
+class LLBakingShaderMgr: public LLShaderMgr
+{
+public:
+ static bool sInitialized;
+ static bool sSkipReload;
+
+ LLBakingShaderMgr();
+ ~LLBakingShaderMgr();
+
+ // singleton pattern implementation
+ static LLBakingShaderMgr * instance();
+
+ void initAttribsAndUniforms(void) override;
+ void setShaders();
+ void unloadShaders();
+ S32 getVertexShaderLevel(S32 type);
+ bool loadShadersInterface();
+
+ std::vector<S32> mVertexShaderLevel;
+ S32 mMaxAvatarShaderLevel;
+
+ enum EShaderClass
+ {
+ SHADER_LIGHTING,
+ SHADER_OBJECT,
+ SHADER_AVATAR,
+ SHADER_ENVIRONMENT,
+ SHADER_INTERFACE,
+ SHADER_EFFECT,
+ SHADER_WINDLIGHT,
+ SHADER_WATER,
+ SHADER_DEFERRED,
+ SHADER_TRANSFORM,
+ SHADER_COUNT
+ };
+
+ // simple model of forward iterator
+ // http://www.sgi.com/tech/stl/ForwardIterator.html
+ class shader_iter
+ {
+ private:
+ friend bool operator == (shader_iter const & a, shader_iter const & b);
+ friend bool operator != (shader_iter const & a, shader_iter const & b);
+
+ typedef std::vector<LLGLSLShader *>::const_iterator base_iter_t;
+ public:
+ shader_iter()
+ {
+ }
+
+ shader_iter(base_iter_t iter) : mIter(iter)
+ {
+ }
+
+ LLGLSLShader & operator * () const
+ {
+ return **mIter;
+ }
+
+ LLGLSLShader * operator -> () const
+ {
+ return *mIter;
+ }
+
+ shader_iter & operator++ ()
+ {
+ ++mIter;
+ return *this;
+ }
+
+ shader_iter operator++ (int)
+ {
+ return mIter++;
+ }
+
+ private:
+ base_iter_t mIter;
+ };
+
+ shader_iter beginShaders() const;
+ shader_iter endShaders() const;
+
+ std::string getShaderDirPrefix(void) override;
+
+ void updateShaderUniforms(LLGLSLShader * shader) override;
+
+private:
+
+ // the list of shaders we need to propagate parameters to.
+ std::vector<LLGLSLShader *> mShaderList;
+
+}; //LLBakingShaderMgr
+
+inline bool operator == (LLBakingShaderMgr::shader_iter const & a, LLBakingShaderMgr::shader_iter const & b)
+{
+ return a.mIter == b.mIter;
+}
+
+inline bool operator != (LLBakingShaderMgr::shader_iter const & a, LLBakingShaderMgr::shader_iter const & b)
+{
+ return a.mIter != b.mIter;
+}
+
+extern LLVector4 gShinyOrigin;
+
+#endif // LL_BAKING_SHADER_MGR_H
diff --git a/indra/llappearanceutility/llbakingtexlayer.cpp b/indra/llappearanceutility/llbakingtexlayer.cpp
new file mode 100644
index 0000000000..3427331a96
--- /dev/null
+++ b/indra/llappearanceutility/llbakingtexlayer.cpp
@@ -0,0 +1,373 @@
+/**
+ * @file llbakingtexlayer.cpp
+ * @brief Implementation of LLBakingTexLayer class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "indra_constants.h"
+#include "llappappearanceutility.h"
+#include "llavatarappearance.h"
+#include "llbakingtexlayer.h"
+#include "llbakingwearable.h"
+#include "llfasttimer.h"
+#include "lllocaltextureobject.h"
+#include "llimagej2c.h"
+#include "llwearabledata.h"
+#include "llmd5.h"
+#include "llbakingavatar.h"
+
+//#define DEBUG_TEXTURE_IDS 1
+
+static const char* BAKE_HASH_VERSION = "3";
+
+using namespace LLAvatarAppearanceDefines;
+
+LLBakingTexLayerSetBuffer::LLBakingTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height)
+ : LLTexLayerSetBuffer(owner),
+ LLBakingTexture( width, height, 4 )
+{}
+
+// virtual
+LLBakingTexLayerSetBuffer::~LLBakingTexLayerSetBuffer()
+{
+ destroyGLTexture();
+}
+
+bool LLBakingTexLayerSetBuffer::render()
+{
+ bool result = false;
+
+ preRenderTexLayerSet();
+ result = renderTexLayerSet(nullptr);
+ postRenderTexLayerSet(result);
+
+ return result;
+}
+
+static LLFastTimer::DeclareTimer FTM_MID_RENDER("midRenderTexLayerSet");
+static LLFastTimer::DeclareTimer FTM_CREATE_J2C("Encode J2C image.");
+void LLBakingTexLayerSetBuffer::midRenderTexLayerSet(bool success)
+{
+ LL_RECORD_BLOCK_TIME(FTM_MID_RENDER);
+ if (!mTexLayerSet->isVisible())
+ {
+ // Should have used IMG_INVISIBLE during hash id generation?
+ LL_ERRS() << "Rendered texture for non-visible tex layer set!" << LL_ENDL;
+ }
+
+ if (!success)
+ {
+ throw LLAppException(RV_UNABLE_TO_BAKE, " Rendering process failed.");
+ }
+
+ // Get the COLOR information from our texture
+ LL_DEBUGS() << "glReadPixels..." << LL_ENDL;
+ LL_DEBUGS() << "getCompositeWidth()" << getCompositeWidth() << "getCompositeHeight()" << getCompositeHeight() << LL_ENDL;
+
+ U8* baked_color_data = new U8[ getCompositeWidth() * getCompositeHeight() * 4 ];
+ glReadPixels(getCompositeOriginX(), getCompositeOriginY(),
+ getCompositeWidth(), getCompositeHeight(),
+ GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
+ stop_glerror();
+
+ // Get the MASK information from our texture
+ LLGLSUIDefault gls_ui;
+ LL_DEBUGS() << "Creating baked mask image raw.." << LL_ENDL;
+ LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(getCompositeWidth(), getCompositeHeight(), 1 );
+ U8* baked_mask_data = baked_mask_image->getData();
+
+ LL_DEBUGS() << "Gathering Morph Mask Alpha..." << LL_ENDL;
+ mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data,
+ getCompositeOriginX(), getCompositeOriginY(),
+ getCompositeWidth(), getCompositeHeight(), nullptr);
+
+ // Create the baked image from our color and mask information
+ const S32 baked_image_components = 5; // red green blue [bump] clothing
+ LL_DEBUGS() << "Creating baked image raw.." << LL_ENDL;
+ LLPointer<LLImageRaw> baked_image = new LLImageRaw( getCompositeWidth(), getCompositeHeight(), baked_image_components );
+ U8* baked_image_data = baked_image->getData();
+ S32 i = 0;
+ LL_DEBUGS() << "Running ugly loop..." << LL_ENDL;
+ for (S32 u=0; u < getCompositeWidth(); u++)
+ {
+ for (S32 v=0; v < getCompositeHeight(); v++)
+ {
+ baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
+ baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
+ baked_image_data[5*i + 2] = baked_color_data[4*i + 2];
+ baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes.
+ baked_image_data[5*i + 4] = baked_mask_data[i];
+ i++;
+ }
+ }
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_CREATE_J2C);
+ LL_DEBUGS() << "Creating J2C..." << LL_ENDL;
+ mCompressedImage = new LLImageJ2C;
+ const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
+ if (!mCompressedImage->encode(baked_image, comment_text))
+ {
+ throw LLAppException(RV_UNABLE_TO_ENCODE);
+ }
+ }
+
+ delete [] baked_color_data;
+}
+
+LLBakingTexLayerSet::LLBakingTexLayerSet(LLAvatarAppearance* const appearance) :
+ LLTexLayerSet(appearance)
+{
+}
+
+// virtual
+LLBakingTexLayerSet::~LLBakingTexLayerSet()
+{
+}
+
+// Ignored.
+void LLBakingTexLayerSet::requestUpdate()
+{
+}
+
+void LLBakingTexLayerSet::createComposite()
+{
+ if(!mComposite)
+ {
+ const LLBakingAvatar* avatar = dynamic_cast<const LLBakingAvatar*> (mAvatarAppearance);
+ S32 width = avatar->bakeTextureSize();
+ S32 height = avatar->bakeTextureSize();
+
+ LL_DEBUGS() << "Creating composite with width and height " << width << " " << height << LL_ENDL;
+
+ mComposite = new LLBakingTexLayerSetBuffer(this, width, height);
+ }
+}
+
+LLSD LLBakingTexLayerSet::computeTextureIDs() const
+{
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict =
+ LLAvatarAppearance::getDictionary()->getBakedTexture(getBakedTexIndex());
+#ifdef DEBUG_TEXTURE_IDS
+ const std::string& slot_name = LLAvatarAppearance::getDictionary()->getTexture(
+ LLAvatarAppearance::getDictionary()->bakedToLocalTextureIndex(getBakedTexIndex()) )->mDefaultImageName;
+ const LLAvatarAppearanceDictionary::TextureEntry* entry = LLAvatarAppearance::getDictionary()->getTexture(baked_dict->mTextureIndex);
+ LL_DEBUGS() << "-----------------------------------------------------------------" << LL_ENDL;
+ LL_DEBUGS() << "BakedTexIndex = " << (S32) getBakedTexIndex() << " (" << slot_name << ") "
+ << "BakedEntry::mTextureIndex = " << (S32) baked_dict->mTextureIndex
+ << " (" << entry->mDefaultImageName
+ << ")" << LL_ENDL;
+ //LL_DEBUGS() << "LLAvatarAppearanceDictionary::getTEWearableType(" << baked_dict->mTextureIndex << ") = " << (S32) LLAvatarAppearanceDictionary::getTEWearableType(baked_dict->mTextureIndex) << LL_ENDL;
+
+ texture_vec_t::const_iterator idx_iter = baked_dict->mLocalTextures.begin();
+ texture_vec_t::const_iterator idx_end = baked_dict->mLocalTextures.end();
+ std::ostringstream idx_str;
+ for (; idx_iter != idx_end; ++idx_iter)
+ {
+ entry = LLAvatarAppearance::getDictionary()->getTexture((*idx_iter));
+ idx_str << (*idx_iter) << " (" << entry->mDefaultImageName
+ << ";" << LLWearableType::getInstance()->getTypeName( entry->mWearableType )
+ << "), ";
+ }
+ LL_DEBUGS() << "BakedEntry::mLocalTextures: " << idx_str.str() << LL_ENDL;
+ wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
+ wearables_vec_t::const_iterator type_end = baked_dict->mWearables.end();
+ std::ostringstream type_str;
+ for (; type_iter != type_end; ++type_iter)
+ {
+ type_str << (S32) (*type_iter) << " ("
+ << LLWearableType::getInstance()->getTypeName( (*type_iter) )
+ << "), ";
+ }
+ LL_DEBUGS() << "BakedEntry::mWearables: " << type_str.str() << LL_ENDL;
+ //LL_DEBUGS() << "BakedEntry::mWearablesHashID: " << baked_dict->mWearablesHashID << LL_ENDL;
+#endif
+
+ LLMD5 hash;
+ std::set<LLUUID> texture_ids;
+
+ bool is_visible = true;
+ bool hash_computed = computeLayerListTextureIDs(hash, texture_ids, mLayerList, is_visible);
+ if (is_visible)
+ {
+ hash_computed |= computeLayerListTextureIDs(hash, texture_ids, mMaskLayerList, is_visible);
+ }
+
+ LLUUID hash_id;
+ if (!is_visible)
+ {
+ hash_id = IMG_INVISIBLE;
+ texture_ids.clear();
+ }
+ else if (hash_computed)
+ {
+ if ((getBakedTexIndex() == EBakedTextureIndex::BAKED_LEFT_ARM) ||
+ (getBakedTexIndex() == EBakedTextureIndex::BAKED_LEFT_LEG) ||
+ (getBakedTexIndex() == EBakedTextureIndex::BAKED_AUX1) ||
+ (getBakedTexIndex() == EBakedTextureIndex::BAKED_AUX2) ||
+ (getBakedTexIndex() == EBakedTextureIndex::BAKED_AUX3))
+ {
+ hash.update(BAKE_HASH_VERSION);
+ }
+
+ hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
+ hash.finalize();
+ hash.raw_digest(hash_id.mData);
+ }
+
+ if (hash_id.isNull())
+ {
+ hash_id = IMG_DEFAULT_AVATAR;
+ }
+
+ if (getBakedTexIndex() == EBakedTextureIndex::BAKED_SKIRT)
+ {
+ if (getAvatarAppearance()->getWearableData()->getWearableCount(LLWearableType::WT_SKIRT) == 0)
+ {
+ hash_id = IMG_DEFAULT_AVATAR;
+ texture_ids.clear();
+ }
+ }
+ LLSD sd;
+ sd["hash_id"] = hash_id;
+ sd["texture_ids"] = LLSD::emptyArray();
+ std::set<LLUUID>::iterator id_iter = texture_ids.begin();
+ std::set<LLUUID>::iterator id_end = texture_ids.end();
+ for (; id_iter != id_end; ++id_iter)
+ {
+ sd["texture_ids"].append( *id_iter );
+ }
+ return sd;
+}
+
+bool LLBakingTexLayerSet::computeLayerListTextureIDs(LLMD5& hash,
+ std::set<LLUUID>& texture_ids,
+ const layer_list_t& layer_list,
+ bool& is_visible) const
+{
+ is_visible = true;
+ bool hash_computed = false;
+ layer_list_t::const_iterator iter = layer_list.begin();
+ layer_list_t::const_iterator end = layer_list.end();
+ for (; iter != end; ++iter)
+ {
+ const LLTexLayerInterface* layer_template = *iter;
+ LLWearableType::EType wearable_type = layer_template->getWearableType();
+ ETextureIndex te = layer_template->getLocalTextureIndex();
+ U32 num_wearables = getAvatarAppearance()->getWearableData()->getWearableCount(wearable_type);
+#ifdef DEBUG_TEXTURE_IDS
+ const LLAvatarAppearanceDictionary::TextureEntry* entry = LLAvatarAppearance::getDictionary()->getTexture(te);
+ if (entry)
+ {
+ LL_DEBUGS() << "LLTexLayerInterface(" << layer_template->getName() << ") type = "
+ << (S32) wearable_type << " ("
+ << LLWearableType::getInstance()->getTypeName( wearable_type ) << ") te = "
+ << (S32) te << " ("<< entry->mDefaultImageName
+ << ";" << LLWearableType::getInstance()->getTypeName( entry->mWearableType )
+ << ") wearable_count = " << num_wearables << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS() << "LLTexLayerInterface(" << layer_template->getName() << ") type = "
+ << (S32) wearable_type << " ("
+ << LLWearableType::getInstance()->getTypeName( wearable_type )
+ << ") wearable_count = " << num_wearables << LL_ENDL;
+ }
+#endif
+ if (LLWearableType::WT_INVALID == wearable_type)
+ {
+ //LL_DEBUGS() << "Skipping invalid wearable type" << LL_ENDL;
+ continue;
+ }
+
+ for (U32 i = 0; i < num_wearables; i++)
+ {
+ LLBakingWearable* wearable = dynamic_cast<LLBakingWearable*> (
+ getAvatarAppearance()->getWearableData()->getWearable(wearable_type, i));
+ if (!wearable)
+ {
+ //LL_DEBUGS() << "Skipping wearable" << LL_ENDL;
+ continue;
+ }
+#ifdef DEBUG_TEXTURE_IDS
+ S32 num_ltos = wearable->getLocalTextureListSeq().size();
+ LL_DEBUGS() << "LLWearable (" << wearable->getName() << ") type = "
+ << (S32) wearable->getAssetType() << " ("
+ << LLAssetType::lookup(wearable->getAssetType())
+ << ") num_ltos = " << num_ltos << LL_ENDL;
+#endif
+ LLLocalTextureObject *lto = wearable->getLocalTextureObject(te);
+ if (lto)
+ {
+#ifdef DEBUG_TEXTURE_IDS
+ LL_DEBUGS() << "LocalTextureObject id = " << lto->getID() << " num texlayers = " << lto->getNumTexLayers() << LL_ENDL;
+#endif
+ // Hash texture id
+ LLUUID texture_id = lto->getID();
+ if (IMG_INVISIBLE == texture_id)
+ {
+ is_visible = false;
+ }
+ hash.update((const unsigned char*)texture_id.mData, UUID_BYTES);
+ hash_computed = true;
+ // Add texture to list.
+ texture_ids.insert(texture_id);
+ }
+#ifdef DEBUG_TEXTURE_IDS
+ else
+ {
+ LL_DEBUGS() << "LLWearable -- no LocalTextureObject for te " << (S32) te << LL_ENDL;
+ }
+
+
+ for(S32 i = 0; i < (S32)TEX_NUM_INDICES; i++)
+ {
+ lto = wearable->getLocalTextureObject(i);
+ if (lto)
+ {
+ LL_DEBUGS() << "LTO (" << i << ") id = " << lto->getID() << " num texlayers = " << lto->getNumTexLayers() << LL_ENDL;
+ }
+ }
+#endif
+
+ for( LLVisualParam* param = getAvatarAppearance()->getFirstVisualParam();
+ param; param = getAvatarAppearance()->getNextVisualParam() )
+ {
+ // cross-wearable parameters are not authoritative, as they are driven by a different wearable.
+ if( (((LLViewerVisualParam*)param)->getWearableType() == wearable_type) &&
+ (!((LLViewerVisualParam*)param)->getCrossWearable()) )
+ {
+ std::ostringstream ostr;
+ F32 weight = wearable->getVisualParamWeight(param->getID());
+ ostr << param->getID() << " " << weight;
+ hash.update(ostr.str());
+ hash_computed = true;
+ }
+ }
+ }
+ }
+ return hash_computed;
+}
+
diff --git a/indra/llappearanceutility/llbakingtexlayer.h b/indra/llappearanceutility/llbakingtexlayer.h
new file mode 100644
index 0000000000..dc82b27ce2
--- /dev/null
+++ b/indra/llappearanceutility/llbakingtexlayer.h
@@ -0,0 +1,77 @@
+/**
+ * @file llbakingtexlayer.h
+ * @brief Declaration of LLBakingTexLayerSet.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLBAKINGTEXLAYER_H
+#define LL_LLBAKINGTEXLAYER_H
+
+#include "llbakingtexture.h"
+#include "llimagej2c.h"
+#include "llpointer.h"
+#include "lltexlayer.h"
+
+class LLMD5;
+
+class LLBakingTexLayerSetBuffer : public LLTexLayerSetBuffer, public LLBakingTexture
+{
+ LOG_CLASS(LLBakingTexLayerSetBuffer);
+public:
+ LLBakingTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
+ virtual ~LLBakingTexLayerSetBuffer();
+
+ LLImageJ2C* getCompressedImage() { return mCompressedImage; }
+
+ bool render();
+ bool bindDebugImage(const S32 stage = 0) override { return false; }
+ bool isActiveFetching() override { return false; };
+
+private:
+ S32 getCompositeOriginX() const override { return 0; }
+ S32 getCompositeOriginY() const override { return 0; }
+ S32 getCompositeWidth() const override { return getFullWidth(); }
+ S32 getCompositeHeight() const override { return getFullHeight(); }
+ void midRenderTexLayerSet(bool success) override;
+
+ LLPointer<LLImageJ2C> mCompressedImage;
+};
+
+class LLBakingTexLayerSet : public LLTexLayerSet
+{
+public:
+ LLBakingTexLayerSet(LLAvatarAppearance* const appearance);
+ virtual ~LLBakingTexLayerSet();
+
+ LLSD computeTextureIDs() const;
+ bool computeLayerListTextureIDs(LLMD5& hash,
+ std::set<LLUUID>& texture_ids,
+ const layer_list_t& layer_list,
+ bool& is_visible) const;
+
+ void requestUpdate() override;
+ void createComposite() override;
+};
+
+#endif /* LL_LLBAKINGTEXLAYER_H */
+
diff --git a/indra/llappearanceutility/llbakingtexture.cpp b/indra/llappearanceutility/llbakingtexture.cpp
new file mode 100644
index 0000000000..ae83081aef
--- /dev/null
+++ b/indra/llappearanceutility/llbakingtexture.cpp
@@ -0,0 +1,81 @@
+/**
+ * @file llbakingtexture.cpp
+ * @brief Implementation of LLBakingTexture class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+// linden includes
+#include "linden_common.h"
+
+// project includes
+#include "llbakingtexture.h"
+#include "llgltexture.h"
+#include "llimage.h"
+
+static const bool USE_MIP_MAPS = true;
+
+LLBakingTexture::LLBakingTexture(const LLUUID& id, const LLImageRaw* raw)
+ : LLGLTexture(raw, USE_MIP_MAPS),
+ mID(id)
+{
+}
+
+LLBakingTexture::LLBakingTexture(bool usemipmaps)
+ : LLGLTexture(usemipmaps),
+ mID(LLUUID::null)
+{
+}
+
+LLBakingTexture::LLBakingTexture(const U32 width, const U32 height, const U8 components, bool usemipmaps)
+ : LLGLTexture(width, height, components, USE_MIP_MAPS),
+ mID(LLUUID::null)
+{
+}
+
+// virtual
+LLBakingTexture::~LLBakingTexture()
+{
+}
+
+void LLBakingTexture::setKnownDrawSize(S32 width, S32 height)
+{
+ //nothing here.
+ LL_ERRS() << "Not implemented." << LL_ENDL;
+}
+
+bool LLBakingTexture::bindDefaultImage(S32 stage)
+{
+ LL_ERRS() << "Not implemented." << LL_ENDL;
+ return false;
+}
+
+void LLBakingTexture::forceImmediateUpdate()
+{
+ LL_ERRS() << "Not implemented." << LL_ENDL;
+}
+
+void LLBakingTexture::updateBindStatsForTester()
+{
+ LL_ERRS() << "Not implemented." << LL_ENDL;
+}
+
diff --git a/indra/llappearanceutility/llbakingtexture.h b/indra/llappearanceutility/llbakingtexture.h
new file mode 100644
index 0000000000..50b4193b2e
--- /dev/null
+++ b/indra/llappearanceutility/llbakingtexture.h
@@ -0,0 +1,69 @@
+/**
+ * @file llbakingtexture.h
+ * @brief Declaration of LLBakingTexture class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLBAKINGTEXTURE_H
+#define LL_LLBAKINGTEXTURE_H
+
+#include "llgltexture.h"
+#include "lluuid.h"
+
+class LLImageRaw;
+
+class LLBakingTexture : public LLGLTexture
+{
+public:
+ enum
+ {
+ LOCAL_TEXTURE,
+ BAKING_TEXTURE,
+ INVALID_TEXTURE_TYPE
+ };
+ LLBakingTexture(const LLUUID& id, const LLImageRaw* raw);
+ LLBakingTexture(bool usemipmaps);
+ LLBakingTexture(const U32 width, const U32 height, const U8 components, bool usemipmaps = true);
+ const LLUUID& getID() const override { return mID; }
+ S8 getType() const override { return BAKING_TEXTURE; }
+
+ // Not implemented.
+ void setKnownDrawSize(S32 width, S32 height) override;
+ bool bindDefaultImage(const S32 stage = 0) override ;
+ void forceImmediateUpdate() override;
+ void updateBindStatsForTester() override ;
+ bool bindDebugImage(const S32 stage = 0) override { return false; }
+ bool isActiveFetching() override { return false; }
+
+protected:
+ virtual ~LLBakingTexture();
+ LOG_CLASS(LLBakingTexture);
+private:
+ // Hide default constructor.
+ LLBakingTexture() {}
+
+ LLUUID mID;
+};
+
+#endif /* LL_LLBAKINGTEXTURE_H */
+
diff --git a/indra/llappearanceutility/llbakingwearable.cpp b/indra/llappearanceutility/llbakingwearable.cpp
new file mode 100644
index 0000000000..0e5251aba1
--- /dev/null
+++ b/indra/llappearanceutility/llbakingwearable.cpp
@@ -0,0 +1,77 @@
+/**
+ * @file llbakingwearable.cpp
+ * @brief Implementation of LLBakingWearable class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llavatarappearance.h"
+#include "llavatarappearancedefines.h"
+#include "llbakingwearable.h"
+#include "llmd5.h"
+#include "indra_constants.h"
+
+using namespace LLAvatarAppearanceDefines;
+
+LLBakingWearable::LLBakingWearable()
+{
+}
+
+// virtual
+LLBakingWearable::~LLBakingWearable()
+{
+}
+
+// virtual
+void LLBakingWearable::setUpdated() const
+{
+}
+
+// virtual
+void LLBakingWearable::addToBakedTextureHash(LLMD5& hash) const
+{
+}
+
+// virtual
+LLUUID LLBakingWearable::getDefaultTextureImageID(ETextureIndex index) const
+{
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture(index);
+ const std::string &default_image_name = texture_dict->mDefaultImageName;
+ if (default_image_name == "")
+ {
+ return IMG_DEFAULT_AVATAR;
+ }
+ else
+ {
+ //return LLUUID(gSavedSettings.getString(default_image_name));
+ // *TODO: Fix this.
+ return LLUUID::null;
+ }
+}
+
+void LLBakingWearable::asLLSD(LLSD& sd) const
+{
+ // stub implementation. TODO: fill in.
+}
diff --git a/indra/llappearanceutility/llbakingwearable.h b/indra/llappearanceutility/llbakingwearable.h
new file mode 100644
index 0000000000..bb96dc3709
--- /dev/null
+++ b/indra/llappearanceutility/llbakingwearable.h
@@ -0,0 +1,48 @@
+/**
+ * @file llbakingwearable.h
+ * @brief Declaration of LLBakingWearable class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLBAKINGWEARABLE_H
+#define LL_LLBAKINGWEARABLE_H
+
+#include "llwearable.h"
+#include "llmd5.h"
+
+class LLBakingWearable : public LLWearable
+{
+public:
+ LLBakingWearable();
+ virtual ~LLBakingWearable();
+
+ virtual void setUpdated() const;
+ virtual void addToBakedTextureHash(LLMD5& hash) const;
+ virtual LLUUID getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const;
+
+ void asLLSD(LLSD& sd) const;
+
+};
+
+#endif /* LL_LLBAKINGWEARABLE_H */
+
diff --git a/indra/llappearanceutility/llbakingwearablesdata.cpp b/indra/llappearanceutility/llbakingwearablesdata.cpp
new file mode 100644
index 0000000000..18edb86348
--- /dev/null
+++ b/indra/llappearanceutility/llbakingwearablesdata.cpp
@@ -0,0 +1,131 @@
+/**
+ * @file llbakingwearablesdata.cpp
+ * @brief Implementation of LLBakingWearablesData class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llbakingwearablesdata.h"
+#include "llbakingwearable.h"
+
+using namespace LLAvatarAppearanceDefines;
+
+LLBakingWearablesData::LLBakingWearablesData()
+{
+}
+
+// virtual
+LLBakingWearablesData::~LLBakingWearablesData()
+{
+ std::for_each(mWearables.begin(), mWearables.end(), DeletePointer());
+ mWearables.clear();
+}
+
+void LLBakingWearablesData::setWearableOutfit(LLSD& sd)
+{
+ LLSD::array_const_iterator type_iter = sd.beginArray();
+ LLSD::array_const_iterator type_end = sd.endArray();
+ S32 wearable_index = 0;
+ for (; type_iter != type_end && wearable_index < (S32) LLWearableType::WT_COUNT; ++type_iter, ++wearable_index)
+ {
+ LLSD::array_const_iterator wearable_iter = type_iter->beginArray();
+ LLSD::array_const_iterator wearable_end = type_iter->endArray();
+ for (; wearable_iter != wearable_end; ++wearable_iter)
+ {
+ if ( wearable_iter->isDefined() )
+ {
+ LLBakingWearable* wearable = new LLBakingWearable();
+ std::istringstream istr( (*wearable_iter)["contents"].asString() );
+ wearable->importStream(istr, mAvatarAppearance);
+
+ // Sanity check the wearable type.
+ if (wearable->getType() != wearable_index)
+ {
+ LL_WARNS() << "Unexpected wearable type! Expected " << wearable_index
+ << ", processed " << (S32) wearable->getType() << LL_ENDL;
+ // *TODO: Throw exception?
+ delete wearable;
+ continue;
+ }
+ mWearables.push_back(wearable);
+
+ const LLWearableType::EType type = wearable->getType();
+ if (wearable->getAssetType() == LLAssetType::AT_BODYPART)
+ {
+ // exactly one wearable per body part
+ setWearable(type,0,wearable);
+ }
+ else
+ {
+ pushWearable(type,wearable);
+ }
+ }
+ }
+ }
+
+ wearable_list_t::const_iterator wearable_iter = mWearables.begin();
+ wearable_list_t::const_iterator wearable_end = mWearables.end();
+ for (; wearable_iter != wearable_end; ++wearable_iter)
+ {
+ LLBakingWearable* wearable = (*wearable_iter);
+ const bool removed = false;
+ wearableUpdated(wearable, removed);
+ }
+
+ for(wearable_index = 0; wearable_index < (S32) LLWearableType::WT_COUNT; wearable_index++)
+ {
+ LLWearable* top_wearable = getTopWearable((LLWearableType::EType)wearable_index);
+ if (top_wearable)
+ {
+ top_wearable->writeToAvatar(mAvatarAppearance);
+ }
+ }
+}
+
+
+void LLBakingWearablesData::asLLSD(LLSD& sd) const
+{
+ sd = LLSD::emptyMap();
+ wearableentry_map_t::const_iterator type_iter = mWearableDatas.begin();
+ wearableentry_map_t::const_iterator type_end = mWearableDatas.end();
+ for (; type_iter != type_end; ++type_iter)
+ {
+ LLSD wearable_type_sd = LLSD::emptyArray();
+ LLWearableType::EType wearable_type = type_iter->first;
+ wearableentry_vec_t::const_iterator wearable_iter = type_iter->second.begin();
+ wearableentry_vec_t::const_iterator wearable_end = type_iter->second.end();
+ for (; wearable_iter != wearable_end; ++wearable_iter)
+ {
+ const LLBakingWearable* wearable = dynamic_cast<LLBakingWearable*>(*wearable_iter);
+ LLSD wearable_sd;
+ wearable->asLLSD(wearable_sd);
+ wearable_type_sd.append(wearable_sd);
+ }
+ sd[LLWearableType::getInstance()->getTypeName(wearable_type)] = wearable_type_sd;
+ }
+}
+
+
+
diff --git a/indra/llappearanceutility/llbakingwearablesdata.h b/indra/llappearanceutility/llbakingwearablesdata.h
new file mode 100644
index 0000000000..1db2ca4bc1
--- /dev/null
+++ b/indra/llappearanceutility/llbakingwearablesdata.h
@@ -0,0 +1,55 @@
+/**
+ * @file llbakingwearablesdata.h
+ * @brief Declaration of LLBakingWearablesData class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLBAKINGWEARABLESDATA_H
+#define LL_LLBAKINGWEARABLESDATA_H
+
+#include "llwearabledata.h"
+
+class LLBakingWearable;
+
+class LLBakingWearablesData : public LLWearableData
+{
+public:
+ LLBakingWearablesData();
+ virtual ~LLBakingWearablesData();
+
+ void setWearableOutfit(LLSD& sd);
+
+ //--------------------------------------------------------------------
+ // I/O methods
+ //--------------------------------------------------------------------
+public:
+ void asLLSD(LLSD& sd) const;
+
+private:
+ typedef std::vector<LLBakingWearable*> wearable_list_t;
+ wearable_list_t mWearables;
+
+};
+
+#endif /* LL_LLBAKINGWEARABLESDATA_H */
+
diff --git a/indra/llappearanceutility/llbakingwindow.cpp b/indra/llappearanceutility/llbakingwindow.cpp
new file mode 100644
index 0000000000..8799105932
--- /dev/null
+++ b/indra/llappearanceutility/llbakingwindow.cpp
@@ -0,0 +1,94 @@
+/**
+ * @file llbakingwindow.cpp
+ * @brief Implementation of LLBakingWindow class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+// linden includes
+#include "linden_common.h"
+
+// project includes
+#include "llappappearanceutility.h"
+#include "llbakingshadermgr.h"
+#include "llbakingwindow.h"
+#include "llgl.h"
+#include "llgltexture.h"
+#include "llvertexbuffer.h"
+
+LLBakingWindow::LLBakingWindow(S32 width, S32 height)
+{
+ const S32 WINDOW_ORIGIN_X = 0;
+ const S32 WINDOW_ORIGIN_Y = 0;
+ const U32 FLAGS = 32; // *TODO: Why did mapserver use this? mFlags looks unused.
+ const bool NO_FULLSCREEN = false;
+ const bool NO_CLEAR_BG = false;
+ const bool NO_DISABLE_VSYNC = false;
+ const bool NO_IGNORE_PIXEL_DEPTH = false;
+ const bool USE_GL = true;
+ mWindow = LLWindowManager::createWindow(this,
+ "appearanceutility", "Appearance Utility",
+ WINDOW_ORIGIN_X, WINDOW_ORIGIN_Y,
+ width, height,
+ FLAGS,
+ NO_FULLSCREEN,
+ NO_CLEAR_BG,
+ NO_DISABLE_VSYNC, //gSavedSettings.getBOOL("DisableVerticalSync"),
+ USE_GL, // not headless
+ NO_IGNORE_PIXEL_DEPTH); //gIgnorePixelDepth = false
+
+ if (nullptr == mWindow)
+ {
+ throw LLAppException(RV_UNABLE_TO_INIT_GL);
+ }
+
+ LLVertexBuffer::initClass(mWindow);
+
+ gGL.init(true);
+
+ if (!LLBakingShaderMgr::sInitialized)
+ { //immediately initialize shaders
+ LLBakingShaderMgr::sInitialized = true;
+ LLBakingShaderMgr::instance()->setShaders();
+ }
+
+ LLImageGL::initClass(mWindow, LLGLTexture::MAX_GL_IMAGE_CATEGORY, true, false);
+
+ // mWindow->show();
+ // mWindow->bringToFront();
+ // mWindow->focusClient();
+ // mWindow->gatherInput();
+}
+
+LLBakingWindow::~LLBakingWindow()
+{
+ if (mWindow)
+ {
+ LLWindowManager::destroyWindow(mWindow);
+ }
+ mWindow = nullptr;
+}
+
+void LLBakingWindow::swapBuffers()
+{
+ mWindow->swapBuffers();
+}
diff --git a/indra/llappearanceutility/llbakingwindow.h b/indra/llappearanceutility/llbakingwindow.h
new file mode 100644
index 0000000000..a6bf1d8714
--- /dev/null
+++ b/indra/llappearanceutility/llbakingwindow.h
@@ -0,0 +1,45 @@
+/**
+ * @file llbakingwindow.h
+ * @brief Declaration of LLBakingWindow class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLBAKINGWINDOW_H
+#define LL_LLBAKINGWINDOW_H
+
+#include "llwindow.h"
+#include "llwindowcallbacks.h"
+
+class LLBakingWindow : public LLWindowCallbacks
+{
+public:
+ LLBakingWindow(S32 width, S32 height);
+ ~LLBakingWindow();
+
+ void swapBuffers();
+private:
+ LLWindow* mWindow;
+};
+
+#endif /* LL_LLBAKINGWINDOW_H */
+
diff --git a/indra/llappearanceutility/llprocessparams.cpp b/indra/llappearanceutility/llprocessparams.cpp
new file mode 100755
index 0000000000..ad1b44e794
--- /dev/null
+++ b/indra/llappearanceutility/llprocessparams.cpp
@@ -0,0 +1,281 @@
+/**
+ * @file llprocessparams.cpp
+ * @brief Implementation of LLProcessParams class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+// linden includes
+#include "linden_common.h"
+
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "llsdutil.h"
+#include "llsdutil_math.h"
+#include "llstl.h"
+#include "llmath.h"
+#include "llquantize.h"
+
+// appearance includes
+#include "lltexturemanagerbridge.h"
+#include "llwearabletype.h"
+#include "llavatarappearancedefines.h"
+
+// project includes
+#include "llappappearanceutility.h"
+#include "llbakingavatar.h"
+#include "llbakingtexlayer.h"
+#include "llbakingwearable.h"
+#include "llbakingwearablesdata.h"
+#include "llprocessparams.h"
+
+#define APPEARANCE_PARAM_VERSION 11000
+
+const U32 FULL_RIG_JOINT_COUNT = 20;
+
+using namespace LLAvatarAppearanceDefines;
+
+// Create a bridge to the viewer texture manager.
+class LLNullTextureManagerBridge : public LLTextureManagerBridge
+{
+public:
+ LLPointer<LLGLTexture> getLocalTexture(bool usemipmaps = true, bool generate_gl_tex = true) override
+ {
+ return nullptr;
+ }
+
+ LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, bool usemipmaps, bool generate_gl_tex = true) override
+ {
+ return nullptr;
+ }
+
+ LLGLTexture* getFetchedTexture(const LLUUID &image_id) override
+ {
+ return nullptr;
+ }
+};
+
+LLSD dump_joint_offsets_for_avatar(LLBakingAvatar& avatar)
+{
+ LLSD joints = LLSD::emptyArray();
+
+ for (U32 joint_index = 0;; joint_index++)
+ {
+ LLJoint* pJoint = avatar.getCharacterJoint(joint_index);
+ if (!pJoint)
+ {
+ break;
+ }
+ LLVector3 pos;
+ LLUUID mesh_id;
+ if (pJoint->hasAttachmentPosOverride(pos, mesh_id))
+ {
+ LLSD info;
+ info["name"] = pJoint->getName();
+ info["pos"] = ll_sd_from_vector3(pos);
+ info["mesh_id"] = mesh_id;
+ joints.append(info);
+ }
+ }
+
+ return joints;
+}
+
+void LLProcessParams::process(std::ostream& output)
+{
+ if (!mInputData.has("wearables")) throw LLAppException(RV_UNABLE_TO_PARSE, " Missing wearables");
+
+ // Create a null-texture manager bridge.
+ gTextureManagerBridgep = new LLNullTextureManagerBridge();
+
+ // Construct the avatar.
+ LLBakingWearablesData wearable_data;
+ LLBakingAvatar avatar(&wearable_data, mApp->bakeTextureSize());
+ avatar.initInstance();
+ wearable_data.setAvatarAppearance(&avatar);
+
+ //Process the params data for joint information
+ //bool bodySizeSet = processInputDataForJointInfo( avatar );
+
+ // Extract and parse wearables.
+ wearable_data.setWearableOutfit(mInputData["wearables"]);
+
+ // Set appearance parameter to flag server-side baking.
+ avatar.setVisualParamWeight(APPEARANCE_PARAM_VERSION, 1.0f);
+
+ avatar.setSex( (avatar.getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE );
+
+ avatar.updateVisualParams();
+
+ // Extract texture ids, texture hashes, and avatar scale.
+ LLSD texture_ids = LLSD::emptyMap();
+
+ //Process the params data for joint information
+ bool bodySizeSet = processInputDataForJointInfo( avatar );
+
+ //if we didn't compute a body size from a mesh attachment that included
+ //joint offsets we need to do it now
+ if (!bodySizeSet )
+ {
+ avatar.computeBodySize();
+ }
+
+ for (U32 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
+ {
+ EBakedTextureIndex bake_type = (EBakedTextureIndex) baked_index;
+ LLBakingTexLayerSet* layer_set = dynamic_cast<LLBakingTexLayerSet*>(avatar.getAvatarLayerSet(bake_type));
+ const std::string& slot_name = LLAvatarAppearance::getDictionary()->getTexture(
+ LLAvatarAppearance::getDictionary()->bakedToLocalTextureIndex(bake_type) )->mDefaultImageName;
+ texture_ids[slot_name] = layer_set->computeTextureIDs();
+ }
+
+ // Extract visual params
+ U32 count = 0;
+ LLSD params = LLSD::emptyMap();
+ LLSD debug_params = LLSD::emptyMap();
+ for (LLViewerVisualParam* param = (LLViewerVisualParam*)avatar.getFirstVisualParam();
+ param;
+ param = (LLViewerVisualParam*)avatar.getNextVisualParam())
+ {
+ if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ||
+ param->getGroup() == VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE) // do not transmit params of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
+ {
+ const F32 param_value = param->getWeight();
+ const U8 new_weight = F32_to_U8(param_value, param->getMinWeight(), param->getMaxWeight());
+ LLSD body;
+ body["name"] = param->getName();
+ body["value"] = param_value;
+ body["weight"] = new_weight;
+ debug_params[LLSD(param->getID()).asString()] = body;
+ params.append(new_weight);
+ count++;
+ }
+ }
+
+ // Output
+ LLSD result;
+ result["success"] = true;
+ result["params"] = params;
+ result["debug_params"] = debug_params;
+ result["slot_textures"] = texture_ids;
+ result["avatar_scale"] = ll_sd_from_vector3(avatar.mBodySize + avatar.mAvatarOffset);
+ result["dump_joint_offsets"] = dump_joint_offsets_for_avatar(avatar);
+ output << LLSDOStreamer<LLSDXMLFormatter>(result);
+}
+
+bool LLProcessParams::processInputDataForJointInfo( LLBakingAvatar& avatar )
+{
+ bool returnResult = false;
+
+ if ( !mInputData.has("skindata") || mInputData["skindata"].isUndefined() )
+ {
+ LL_DEBUGS() << "Skipping missing skindata" << LL_ENDL;
+ return returnResult;
+ }
+
+ const LLSD& skindata = mInputData["skindata"];
+
+ //float pelvisOffset = 0.0f;
+ std::vector<std::string> jointNames;
+ std::vector<LLVector3> jointOffsets;
+
+ LLSD::map_const_iterator skinIter = skindata.beginMap();
+ LLSD::map_const_iterator skinIterEnd = skindata.endMap();
+
+ for ( ; skinIter!=skinIterEnd; ++skinIter )
+ {
+ const LLSD& skin = skinIter->second;
+ const char *uuid_str = skinIter->first.c_str();
+ const LLUUID mesh_id(uuid_str);
+
+ if ( !skin.has("joint_names") || !skin.has("joint_offset") )
+ {
+ throw LLAppException(RV_INVALID_SKIN_BLOCK);
+ }
+
+ // Build list of joints
+ {
+ LLSD::array_const_iterator iter(skin["joint_names"].beginArray());
+ LLSD::array_const_iterator iter_end(skin["joint_names"].endArray());
+ for ( ; iter != iter_end; ++iter )
+ {
+ jointNames.push_back( iter->asString() );
+ }
+ }
+ // Extract joint offsets
+ {
+ LLSD::array_const_iterator iter(skin["joint_offset"].beginArray());
+ LLSD::array_const_iterator iter_end(skin["joint_offset"].endArray());
+ for ( ; iter != iter_end; ++iter )
+ {
+ jointOffsets.push_back( ll_vector3_from_sd(*iter) );
+ }
+ }
+
+ // get at the *optional* pelvis offset
+ //if ( skin.has("pelvis_offset") )
+ //{
+ // pelvisOffset = skin["pelvis_offset"].asReal();
+ //}
+ // Now apply the extracted joint data to the avatar
+ U32 jointCount = narrow(jointNames.size());
+
+ if ( jointOffsets.size() < jointCount )
+ {
+ throw LLAppException(RV_INVALID_SKIN_BLOCK);
+ }
+
+ bool fullRig = ( jointCount>= FULL_RIG_JOINT_COUNT ) ? true : false;
+ //bool pelvisGotSet = false;
+
+ returnResult = fullRig;
+
+ if ( fullRig )
+ {
+ for ( U32 i=0; i<jointCount; ++i )
+ {
+ LLJoint* pJoint = avatar.getJoint( jointNames[i] );
+ if ( pJoint )
+ {
+ LL_DEBUGS() << "Apply joint : " << jointNames[i] << " "
+ << jointOffsets[i][0] << " "
+ << jointOffsets[i][1] << " "
+ << jointOffsets[i][2] << LL_ENDL;
+ // FIXME replace with new attachment override code.
+ //pJoint->storeCurrentXform( jointOffsets[i] );
+
+ bool active_override_changed = false;
+ pJoint->addAttachmentPosOverride(jointOffsets[i], mesh_id, "", active_override_changed);
+ }
+ }
+
+ avatar.computeBodySize();
+ avatar.mRoot->touch();
+ avatar.mRoot->updateWorldMatrixChildren();
+
+ }
+
+ jointNames.clear();
+ jointOffsets.clear();
+ }
+ return returnResult;
+}
diff --git a/indra/llappearanceutility/llprocessparams.h b/indra/llappearanceutility/llprocessparams.h
new file mode 100644
index 0000000000..6df893fe21
--- /dev/null
+++ b/indra/llappearanceutility/llprocessparams.h
@@ -0,0 +1,49 @@
+/**
+ * @file llprocessparams.h
+ * @brief Declaration of LLProcessParams class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLPROCESSPARAMS_H
+#define LL_LLPROCESSPARAMS_H
+
+#include "llbakingprocess.h"
+
+class LLBakingAvatar;
+class LLProcessParams : public LLBakingProcess
+{
+public:
+ LLProcessParams(LLAppAppearanceUtility* app) :
+ LLBakingProcess(app) {}
+
+ void process(std::ostream& output) override;
+private:
+
+ bool processInputDataForJointInfo( LLBakingAvatar& avatar );
+};
+
+
+
+
+#endif /* LL_LLPROCESSPARAMS_H */
+
diff --git a/indra/llappearanceutility/llprocessskin.cpp b/indra/llappearanceutility/llprocessskin.cpp
new file mode 100644
index 0000000000..a3d4d3c6f3
--- /dev/null
+++ b/indra/llappearanceutility/llprocessskin.cpp
@@ -0,0 +1,118 @@
+/**
+ * @file llprocessskin.cpp
+ * @brief Implementation of LLProcesSkin class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+// linden includes
+#include "linden_common.h"
+
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "llsdutil.h"
+#include "llsdutil_math.h"
+#include "llstl.h"
+#include "llmath.h"
+#include "m4math.h"
+#include "v4math.h"
+
+// project includes
+#include "llappappearanceutility.h"
+#include "llprocessskin.h"
+
+void LLProcessSkin::process(std::ostream& output)
+{
+ const LLSD& dataBlock = mInputData;
+ LLSD skinData = LLSD::emptyMap();
+
+ LLSD::map_const_iterator skinIter = dataBlock.beginMap();
+ LLSD::map_const_iterator skinIterEnd = dataBlock.endMap();
+
+ for ( ; skinIter!=skinIterEnd; ++skinIter )
+ {
+ const LLSD& skin = skinIter->second;
+ if ( !skin.has("joint_names") || !skin.has("alt_inverse_bind_matrix") )
+ {
+ throw LLAppException(RV_INVALID_SKIN_BLOCK);
+ }
+
+ LLSD entry = LLSD::emptyMap();
+
+ //get all joint names from the skin
+ {
+ entry["joint_names"] = LLSD::emptyArray();
+ LLSD& joint_names = entry["joint_names"];
+ LLSD::array_const_iterator iter(skin["joint_names"].beginArray());
+ LLSD::array_const_iterator iter_end(skin["joint_names"].endArray());
+ for ( ; iter != iter_end; ++iter )
+ {
+ LL_DEBUGS() << "joint: " << iter->asString() << LL_ENDL;
+ joint_names.append(*iter);
+ }
+ }
+ //get at the translational component for the joint offsets
+ {
+ entry["joint_offset"] = LLSD::emptyArray();
+ LLSD& joint_offsets = entry["joint_offset"];
+ LLSD::array_const_iterator iter(skin["alt_inverse_bind_matrix"].beginArray());
+ LLSD::array_const_iterator iter_end(skin["alt_inverse_bind_matrix"].endArray());
+ //just get at the translational component
+ for ( ; iter != iter_end; ++iter )
+ {
+ LLMatrix4 mat;
+ for (U32 j = 0; j < 4; j++)
+ {
+ for (U32 k = 0; k < 4; k++)
+ {
+ mat.mMatrix[j][k] = static_cast<F32>((*iter)[j*4+k].asReal());
+ }
+ }
+ joint_offsets.append( ll_sd_from_vector3( mat.getTranslation() ));
+ LL_DEBUGS() << "offset: [" << mat.getTranslation()[0] << " "
+ << mat.getTranslation()[1] << " "
+ << mat.getTranslation()[2] << " ]" << LL_ENDL;
+ }
+ }
+
+ //get at the *optional* pelvis offset
+ if (skin.has("pelvis_offset"))
+ {
+ entry["pelvis_offset"] = skin["pelvis_offset"];
+ }
+ else
+ {
+ entry["pelvis_offset"] = LLSD::Real(0.f);
+ }
+
+ //add block to outgoing result llsd
+ skinData[skinIter->first] = entry;
+ }
+
+ //dump the result llsd into the outgoing output
+ LLSD result;
+ result["success"] = true;
+ result["skindata"] = skinData;
+ LL_DEBUGS() << "---------------------------\n" << result << LL_ENDL;
+ output << LLSDOStreamer<LLSDXMLFormatter>(result);
+}
+
diff --git a/indra/llappearanceutility/llprocessskin.h b/indra/llappearanceutility/llprocessskin.h
new file mode 100644
index 0000000000..a3cc8c7087
--- /dev/null
+++ b/indra/llappearanceutility/llprocessskin.h
@@ -0,0 +1,43 @@
+/**
+ * @file llprocessskin.h
+ * @brief Declaration of LLProcessSkin class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLPROCESSSKIN_H
+#define LL_LLPROCESSSKIN_H
+
+#include "llbakingprocess.h"
+class LLProcessSkin : public LLBakingProcess
+{
+public:
+ LLProcessSkin(LLAppAppearanceUtility* app) :
+ LLBakingProcess(app) {}
+ void process(std::ostream& output) override;
+
+private:
+
+};
+
+#endif /* LL_LLPROCESSSKIN_H */
+
diff --git a/indra/llappearanceutility/llprocesstexture.cpp b/indra/llappearanceutility/llprocesstexture.cpp
new file mode 100644
index 0000000000..527a6822f2
--- /dev/null
+++ b/indra/llappearanceutility/llprocesstexture.cpp
@@ -0,0 +1,284 @@
+/**
+ * @file llprocesstexture.cpp
+ * @brief Implementation of LLProcessTexture class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+// linden includes
+#include "linden_common.h"
+
+#include "llfasttimer.h"
+#include "llgl.h"
+#include "llimagej2c.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "llsdutil.h"
+
+// appearance includes
+#include "llwearabletype.h"
+#include "llavatarappearancedefines.h"
+
+// project includes
+#include "llappappearanceutility.h"
+#include "llbakingavatar.h"
+#include "llbakingtexlayer.h"
+#include "llbakingtexture.h"
+#include "llbakingwearable.h"
+#include "llbakingwearablesdata.h"
+#include "llbakingwindow.h"
+#include "llprocesstexture.h"
+
+static const S32 MAX_SIZE_LLSD_HEADER = 1024 * 1024;
+static const bool USE_MIP_MAPS = true;
+
+static const S32 EYES_SLOT_DIMENSIONS=512;
+
+using namespace LLAvatarAppearanceDefines;
+
+LLProcessTexture::LLProcessTexture(LLAppAppearanceUtility* app)
+ : LLBakingProcess(app),
+ mWindow(nullptr),
+ mInputRaw(nullptr),
+ mBakeSize(512)
+{
+}
+
+void LLProcessTexture::cleanup()
+{
+ delete mWindow;
+}
+
+static LLFastTimer::DeclareTimer FTM_CREATE_TEXTURE_FROM_STREAM("Create texture from stream.");
+static LLPointer<LLImageRaw> create_texture_from_stream(std::istream& input,
+ S32 texture_size,
+ const LLUUID& id)
+{
+ LL_RECORD_BLOCK_TIME(FTM_CREATE_TEXTURE_FROM_STREAM);
+ // Read compressed j2c texture data from the input stream.
+ U8* buffer = (U8*) ll_aligned_malloc_16(texture_size);
+ input.read((char*) buffer, texture_size);
+
+ if (input.gcount() < texture_size)
+ {
+ ll_aligned_free_16(buffer);
+ throw LLAppException(RV_UNABLE_TO_DECODE, " Early EOF in input stream.");
+ }
+ if (input.gcount() > texture_size)
+ {
+ ll_aligned_free_16(buffer);
+ throw LLAppException(RV_UNABLE_TO_DECODE, " Read too much data from input stream: Programming Error.");
+ }
+
+ const S32 DISCARD_FULL_TEXTURE_RESOLUTION = 0;
+ LLPointer<LLImageJ2C> j2c = new LLImageJ2C();
+ j2c->setDiscardLevel(DISCARD_FULL_TEXTURE_RESOLUTION);
+ // Transfer the j2c buffer to an LLImageJ2C object.
+ // This gives memory ownership of buffer to LLImageJ2C
+ if (!j2c->validate(buffer, texture_size))
+ {
+ throw LLAppException(RV_UNABLE_TO_DECODE, " Unable to validate J2C: " + LLImage::getLastThreadError());
+ }
+ if (!(j2c->getWidth() * j2c->getHeight() * j2c->getComponents() > 0))
+ {
+ throw LLAppException(RV_UNABLE_TO_DECODE, " Invalid dimensions.");
+ }
+
+ // Decompress the J2C image into a raw image.
+ LLPointer<LLImageRaw> image_raw = new LLImageRaw(j2c->getWidth(),
+ j2c->getHeight(),
+ j2c->getComponents());
+ const F32 MAX_DECODE_TIME = 60.f;
+ j2c->setDiscardLevel(0);
+ if (!j2c->decode(image_raw, MAX_DECODE_TIME))
+ {
+ throw LLAppException(RV_UNABLE_TO_DECODE, " Decoding timeout.");
+ }
+ // *TODO: Check for decode failure?
+ LL_DEBUGS() << "ID: " << id << ", Raw Width: " << image_raw->getWidth() << ", Raw Height: " << image_raw->getHeight()
+ << ", Raw Components: " << (S32) image_raw->getComponents()
+ << ", J2C Width: " << j2c->getWidth() << ", J2C Height: " << j2c->getHeight()
+ << ", J2C Components: " << (S32) j2c->getComponents() << LL_ENDL;
+
+ return image_raw;
+}
+
+void LLProcessTexture::parseInput(std::istream& input)
+{
+ mInputRaw = &input;
+ LL_DEBUGS() << "Reading..." << LL_ENDL;
+ // Parse LLSD header.
+ mInputData = LLSDSerialize::fromBinary( *mInputRaw, MAX_SIZE_LLSD_HEADER );
+ if (mInputData.isUndefined()) throw LLAppException(RV_UNABLE_TO_PARSE);
+ if (!mInputData.has("slot_id")) throw LLAppException(RV_UNABLE_TO_PARSE, " Missing slot id");
+ if (!mInputData.has("textures")) throw LLAppException(RV_UNABLE_TO_PARSE, " Missing texture header");
+ if (!mInputData.has("wearables")) throw LLAppException(RV_UNABLE_TO_PARSE, " Missing wearables");
+
+ // Verify the slot_id is valid.
+ if (BAKED_NUM_INDICES == LLAvatarAppearance::getDictionary()->findBakedByImageName(mInputData["slot_id"].asString()))
+ {
+ throw LLAppException(RV_UNABLE_TO_PARSE, " Invalid slot id");
+ }
+}
+
+void LLProcessTexture::init()
+{
+ if (mApp->isDebugMode()) gDebugGL = true;
+
+ S32 maxTextureDecodedWidth = 0;
+ S32 maxTextureDecodedHeight = 0;
+
+ // Extract texture data.
+ LLSD::array_const_iterator iter = mInputData["textures"].beginArray();
+ LLSD::array_const_iterator end = mInputData["textures"].endArray();
+ std::map< LLUUID, LLPointer<LLImageRaw> > imageRawMap;
+
+ for (; iter != end; ++iter)
+ {
+ LLUUID texture_id = (*iter)[0].asUUID();
+ S32 texture_size = (*iter)[1];
+ imageRawMap[texture_id] = create_texture_from_stream(*mInputRaw, texture_size, texture_id);
+ maxTextureDecodedWidth = imageRawMap[texture_id]->getWidth() > maxTextureDecodedWidth ? imageRawMap[texture_id]->getWidth() : maxTextureDecodedWidth;
+ maxTextureDecodedHeight = imageRawMap[texture_id]->getHeight() > maxTextureDecodedHeight ? imageRawMap[texture_id]->getHeight() : maxTextureDecodedHeight;
+ }
+
+ if ("eyes" == mInputData["slot_id"].asString())
+ {
+ mBakeSize = 512;
+ }
+ else
+ {
+ // optimization: maybe we could use maxTextureDecodedWidth and
+ // maxTextureDecodedHeight for new LLBakingWindow below?
+ if ((maxTextureDecodedWidth > 1024) || (maxTextureDecodedHeight > 1024))
+ {
+ mBakeSize = 2048;
+ }
+ else if ((maxTextureDecodedWidth > 512) || (maxTextureDecodedHeight > 512))
+ {
+ mBakeSize = 1024;
+ }
+ else
+ {
+ mBakeSize = 512;
+ }
+ }
+
+ mWindow = new LLBakingWindow(mBakeSize, mBakeSize);
+
+ for (iter = mInputData["textures"].beginArray(); iter != mInputData["textures"].endArray(); ++iter)
+ {
+ LLUUID texture_id = (*iter)[0].asUUID();
+
+ LLPointer<LLBakingTexture> texture = new LLBakingTexture(texture_id, imageRawMap[texture_id]);
+ texture->forceActive();
+ texture->setGLTextureCreated(true);
+
+ mTextureData[texture_id] = texture;
+ }
+
+}
+
+LLPointer<LLGLTexture> LLProcessTexture::getLocalTexture(bool usemipmaps, bool generate_gl_tex)
+{
+ LLPointer<LLBakingTexture> tex = new LLBakingTexture(usemipmaps);
+ if(generate_gl_tex)
+ {
+ tex->generateGLTexture() ;
+ tex->setCategory(LLGLTexture::LOCAL) ;
+ }
+ return tex ;
+}
+
+LLPointer<LLGLTexture> LLProcessTexture::getLocalTexture(const U32 width, const U32 height, const U8 components, bool usemipmaps, bool generate_gl_tex)
+{
+ LLPointer<LLBakingTexture> tex = new LLBakingTexture(width, height, components, usemipmaps) ;
+ if(generate_gl_tex)
+ {
+ tex->generateGLTexture() ;
+ tex->setCategory(LLGLTexture::LOCAL) ;
+ }
+ return tex ;
+}
+
+LLGLTexture* LLProcessTexture::getFetchedTexture(const LLUUID &image_id)
+{
+ texture_map_t::iterator texture_iter = mTextureData.find(image_id);
+ if (mTextureData.end() == texture_iter)
+ {
+ LL_DEBUGS() << "Ignoring unused texture id: " << image_id << LL_ENDL;
+ return nullptr;
+ }
+
+ return texture_iter->second;
+}
+
+void LLProcessTexture::process(std::ostream& output)
+{
+ LL_DEBUGS() << "Building avatar..." << LL_ENDL;
+ // Set ourself as the texture bridge.
+ gTextureManagerBridgep = this;
+
+ // Construct the avatar.
+ LLBakingWearablesData wearable_data;
+ LLBakingAvatar avatar(&wearable_data, mBakeSize);
+ avatar.initInstance();
+ wearable_data.setAvatarAppearance(&avatar);
+
+ // Extract and parse wearables.
+ wearable_data.setWearableOutfit(mInputData["wearables"]);
+
+ avatar.setSex( (avatar.getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE );
+
+ avatar.updateVisualParams();
+
+ // Prepare gl for avatar baking
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ EBakedTextureIndex bake_type = LLAvatarAppearance::getDictionary()->findBakedByImageName(mInputData["slot_id"].asString());
+ LLTexLayerSet* layer_set = avatar.getAvatarLayerSet(bake_type);
+ LLBakingTexLayerSetBuffer* composite = dynamic_cast<LLBakingTexLayerSetBuffer*> (layer_set->getComposite());
+ if (!composite)
+ {
+ throw LLAppException(RV_UNABLE_TO_BAKE, " Could not build composite.");
+ }
+
+ LL_DEBUGS() << "Rendering..." << LL_ENDL;
+ if (!composite->render())
+ {
+ throw LLAppException(RV_UNABLE_TO_BAKE, " Failed to render composite.");
+ }
+
+ mWindow->swapBuffers();
+
+ LL_DEBUGS() << "Compressing..." << LL_ENDL;
+ LLImageJ2C* j2c = composite->getCompressedImage();
+ if (!j2c)
+ {
+ throw LLAppException(RV_UNABLE_TO_BAKE, " Could not build image.");
+ }
+
+ LL_DEBUGS() << "Writing..." << LL_ENDL;
+ output.write((char*)j2c->getData(), j2c->getDataSize());
+ LL_DEBUGS() << "Done." << LL_ENDL;
+}
diff --git a/indra/llappearanceutility/llprocesstexture.h b/indra/llappearanceutility/llprocesstexture.h
new file mode 100644
index 0000000000..8bf2c7396f
--- /dev/null
+++ b/indra/llappearanceutility/llprocesstexture.h
@@ -0,0 +1,63 @@
+/**
+ * @file llprocesstexture.h
+ * @brief Declaration of LLProcessTexture class.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLPROCESSTEXTURE_H
+#define LL_LLPROCESSTEXTURE_H
+
+#include "llbakingprocess.h"
+#include "llbakingtexture.h"
+#include "llpointer.h"
+#include "lltexturemanagerbridge.h"
+#include "llbakingwindow.h"
+
+class LLBakingWindow;
+
+class LLProcessTexture : public LLBakingProcess, public LLTextureManagerBridge
+{
+public:
+ LLProcessTexture(LLAppAppearanceUtility* app);
+
+ /////// LLBakingProcess interface. /////////
+ void parseInput(std::istream& input) override;
+ void process(std::ostream& output) override;
+ void init() override;
+ void cleanup() override;
+
+ /////// LLTextureManagerBridge interface. ////////
+ LLPointer<LLGLTexture> getLocalTexture(bool usemipmaps = true, bool generate_gl_tex = true) override;
+ LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, bool usemipmaps, bool generate_gl_tex = true) override;
+ LLGLTexture* getFetchedTexture(const LLUUID &image_id) override;
+
+private:
+ typedef std::map< LLUUID, LLPointer<LLBakingTexture> > texture_map_t;
+ texture_map_t mTextureData;
+ LLBakingWindow* mWindow;
+ std::istream* mInputRaw;
+ S32 mBakeSize;
+};
+
+#endif /* LL_LLPROCESSTEXTURE_H */
+
diff --git a/indra/llappearanceutility/tests/joint-offsets.xml b/indra/llappearanceutility/tests/joint-offsets.xml
new file mode 100644
index 0000000000..4dca3c3429
--- /dev/null
+++ b/indra/llappearanceutility/tests/joint-offsets.xml
@@ -0,0 +1 @@
+<?xml version="1.0" ?><llsd><map><key>92a7dd5c-bc30-9952-3b3b-e6cc10336cbe</key><map><key>bind_shape_matrix</key><array><real>0.04880329594016075</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.048803336918354034</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.04902994632720947</real><real>0.0</real><real>0.05886554718017578</real><real>-0.0343865305185318</real><real>1.7572450637817383</real><real>1.0</real></array><key>joint_names</key><array><string>mEyeLeft</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mEyeRight</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.09042750298976898</real><real>0.03717460110783577</real><real>0.08056280016899109</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.09042750298976898</real><real>-0.03717460110783577</real><real>0.08056280016899109</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.06363839656114578</real><real>-0.03717460110783577</real><real>-1.8997000455856323</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.06363839656114578</real><real>0.03717460110783577</real><real>-1.8997000455856323</real><real>1.0</real></array></array></map><key>971cf873-afce-8b69-44d6-3f5879cb94c2</key><map><key>bind_shape_matrix</key><array><real>0.02992800809442997</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.04658059775829315</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.009469985961914062</real><real>0.0</real><real>0.13773700594902039</real><real>5.450006574392319e-05</real><real>1.6883649826049805</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025394700467586517</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10700099915266037</real><real>0.0</real><real>-0.02607489936053753</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>-0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.02026969939470291</real><real>0.0</real><real>0.005331280175596476</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08300650119781494</real><real>0.0</real><real>-0.020363999530673027</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08378739655017853</real><real>0.0</real><real>-0.026688499376177788</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>-0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>-0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>-0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.07319430261850357</real><real>0.0</real><real>0.08750399947166443</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10439900308847427</real><real>0.0</real><real>0.017178799957036972</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.15049900114536285</real><real>0.0</real><real>0.003853919915854931</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>-0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>0.016701199114322662</real><real>0.0</real><real>0.009711739607155323</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10521099716424942</real><real>0.0</real><real>-1.8401600122451782</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>-0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.09693530201911926</real><real>0.0</real><real>-1.8257900476455688</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11720500141382217</real><real>0.0</real><real>-1.8204599618911743</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11798600107431412</real><real>0.0</real><real>-1.8141299486160278</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>-0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>-0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>-0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.07140520215034485</real><real>0.0</real><real>-1.951159954071045</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10260900110006332</real><real>0.0</real><real>-1.8824299573898315</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.1487099975347519</real><real>0.0</real><real>-1.8694000244140625</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>-0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>-0.12191300094127655</real><real>0.0</real><real>-1.7818800210952759</real><real>1.0</real></array></array></map><key>7e7a6834-8b41-4029-8f87-ce57b7d05bee</key><map><key>bind_shape_matrix</key><array><real>0.2741509974002838</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.15283240377902985</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.2336200475692749</real><real>0.0</real><real>0.03308449685573578</real><real>0.0</real><real>1.7400600910186768</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025394700467586517</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10700099915266037</real><real>0.0</real><real>-0.02607489936053753</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>-0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.02026969939470291</real><real>0.0</real><real>0.005331280175596476</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08300650119781494</real><real>0.0</real><real>-0.020363999530673027</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08378739655017853</real><real>0.0</real><real>-0.026688499376177788</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>-0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>-0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>-0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.07319430261850357</real><real>0.0</real><real>0.08750399947166443</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10439900308847427</real><real>0.0</real><real>0.017178799957036972</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.15049900114536285</real><real>0.0</real><real>0.003853919915854931</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>-0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>0.016701199114322662</real><real>0.0</real><real>0.009711739607155323</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10521099716424942</real><real>0.0</real><real>-1.8401600122451782</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>-0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.09693530201911926</real><real>0.0</real><real>-1.8257900476455688</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11720500141382217</real><real>0.0</real><real>-1.8204599618911743</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11798600107431412</real><real>0.0</real><real>-1.8141299486160278</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>-0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>-0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>-0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.07140520215034485</real><real>0.0</real><real>-1.951159954071045</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10260900110006332</real><real>0.0</real><real>-1.8824299573898315</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.1487099975347519</real><real>0.0</real><real>-1.8694000244140625</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>-0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>-0.12191300094127655</real><real>0.0</real><real>-1.7818800210952759</real><real>1.0</real></array></array></map><key>547d8392-9f19-35fb-3508-121eea388f0a</key><map><key>bind_shape_matrix</key><array><real>0.1242017075419426</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.04083459824323654</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.014499902725219727</real><real>0.0</real><real>0.07738315314054489</real><real>0.0</real><real>1.6899499893188477</real><real>1.0</real></array><key>joint_names</key><array><string>mFaceJaw</string><string>mFaceRoot</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceTongueBase</string><string>mFaceTeethLower</string><string>mFaceTongueTip</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025394700467586517</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.029850399121642113</real><real>0.0</real><real>0.007831689901649952</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08300650119781494</real><real>0.0</real><real>-0.020363999530673027</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.038916200399398804</real><real>0.0</real><real>-0.002775429980829358</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.08735450357198715</real><real>0.0</real><real>-1.8282899856567383</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11720500141382217</real><real>0.0</real><real>-1.8204599618911743</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.12627099454402924</real><real>0.0</real><real>-1.825510025024414</real><real>1.0</real></array></array></map><key>ed796a27-cff0-454a-ecec-fd10794ca2c9</key><map><key>bind_shape_matrix</key><array><real>0.007152989972382784</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.019312690943479538</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.023620009422302246</real><real>0.0</real><real>0.16310149431228638</real><real>0.0002091950736939907</real><real>1.7110600471496582</real><real>1.0</real></array><key>joint_names</key><array><string>mFaceNoseBase</string><string>mFaceRoot</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceLipUpperCenter</string><string>mFaceTeethUpper</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.15049900114536285</real><real>0.0</real><real>0.003853919915854931</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>0.016701199114322662</real><real>0.0</real><real>0.009711739607155323</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10700099915266037</real><real>0.0</real><real>-0.02607489936053753</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.1487099975347519</real><real>0.0</real><real>-1.8694000244140625</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>-0.12191300094127655</real><real>0.0</real><real>-1.7818800210952759</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10521099716424942</real><real>0.0</real><real>-1.8401600122451782</real><real>1.0</real></array></array></map><key>fa0aabfe-4b1c-fa9b-4942-74e7e7f50fe2</key><map><key>bind_shape_matrix</key><array><real>0.02271599881350994</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.02271599881350994</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.022709965705871582</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0670149326324463</real><real>1.0</real></array><key>joint_names</key><array><string>mPelvis</string><string>mHandMiddle1Left</string><string>mHandMiddle2Left</string><string>mHandMiddle3Left</string><string>mHandIndex1Left</string><string>mHandIndex2Left</string><string>mHandIndex3Left</string><string>mHandRing1Left</string><string>mHandRing2Left</string><string>mHandRing3Left</string><string>mHandPinky1Left</string><string>mHandPinky2Left</string><string>mHandPinky3Left</string><string>mHandThumb1Left</string><string>mHandThumb2Left</string><string>mHandThumb3Left</string><string>mHandMiddle1Right</string><string>mHandMiddle2Right</string><string>mHandMiddle3Right</string><string>mHandIndex1Right</string><string>mHandIndex2Right</string><string>mHandIndex3Right</string><string>mHandRing1Right</string><string>mHandRing2Right</string><string>mHandRing3Right</string><string>mHandPinky1Right</string><string>mHandPinky2Right</string><string>mHandPinky3Right</string><string>mHandThumb1Right</string><string>mHandThumb2Right</string><string>mHandThumb3Right</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>0.9987319707870483</real><real>0.04983130097389221</real><real>-0.007089749909937382</real><real>0.0</real><real>-0.030134299769997597</real><real>0.704800009727478</real><real>0.708765983581543</real><real>0.0</real><real>0.040315598249435425</real><real>-0.7076539993286133</real><real>0.705407977104187</real><real>0.0</real><real>0.015188699588179588</real><real>0.09894219785928726</real><real>0.010429499670863152</real><real>1.0</real></array><array><real>0.9989460110664368</real><real>0.045610301196575165</real><real>-0.00513580022379756</real><real>0.0</real><real>-0.028957000002264977</real><real>0.7130839824676514</real><real>0.7004799842834473</real><real>0.0</real><real>0.03561139851808548</real><real>-0.6995930075645447</real><real>0.7136539816856384</real><real>0.0</real><real>-0.0010505600366741419</real><real>0.04202070087194443</real><real>-0.006302990019321442</real><real>1.0</real></array><array><real>0.9963470101356506</real><real>0.08039940148591995</real><real>-0.02878049947321415</real><real>0.0</real><real>-0.038300998508930206</real><real>0.7219560146331787</real><real>0.6908779740333557</real><real>0.0</real><real>0.07632440328598022</real><real>-0.6872519850730896</real><real>0.7223989963531494</real><real>0.0</real><real>-0.0005042509874328971</real><real>0.024710899218916893</real><real>-0.004034650046378374</real><real>1.0</real></array><array><real>0.9319689869880676</real><real>-0.24829800426959991</real><real>0.26416099071502686</real><real>0.0</real><real>0.02338249981403351</real><real>0.768297016620636</real><real>0.6396660208702087</real><real>0.0</real><real>-0.3617820143699646</real><real>-0.589972972869873</real><real>0.7218350172042847</real><real>0.0</real><real>0.0342739000916481</real><real>0.09468069672584534</real><real>0.009629939682781696</real><real>1.0</real></array><array><real>0.9427329897880554</real><real>-0.22354599833488464</real><real>0.2475530058145523</real><real>0.0</real><real>0.01767759956419468</real><real>0.774619996547699</real><real>0.6321790218353271</real><real>0.0</real><real>-0.333079993724823</real><real>-0.5916000008583069</real><real>0.7342119812965393</real><real>0.0</real><real>0.017191000282764435</real><real>0.03640490025281906</real><real>-0.006067920010536909</real><real>1.0</real></array><array><real>0.9429500102996826</real><real>-0.2165369987487793</real><real>0.2528969943523407</real><real>0.0</real><real>0.00269406009465456</real><real>0.7645390033721924</real><real>0.6445720195770264</real><real>0.0</real><real>-0.3329229950904846</real><real>-0.6071180105209351</real><real>0.7215059995651245</real><real>0.0</real><real>0.010213700123131275</real><real>0.023345300927758217</real><real>-0.004377489909529686</real><real>1.0</real></array><array><real>0.965412974357605</real><real>0.157709002494812</real><real>-0.20761699974536896</real><real>0.0</real><real>0.015564500354230404</real><real>0.7600290179252625</real><real>0.6497020125389099</real><real>0.0</real><real>0.2602590024471283</real><real>-0.6304630041122437</real><real>0.7312880158424377</real><real>0.0</real><real>-0.0036476401146501303</real><real>0.09658080339431763</real><real>0.004405209794640541</real><real>1.0</real></array><array><real>0.9724739789962769</real><real>0.11432900279760361</real><real>-0.20303800702095032</real><real>0.0</real><real>0.04479910060763359</real><real>0.7633640170097351</real><real>0.6444140076637268</real><real>0.0</real><real>0.2286670058965683</real><real>-0.6357709765434265</real><real>0.7372289896011353</real><real>0.0</real><real>-0.012315300293266773</real><real>0.035998500883579254</real><real>-0.007578520104289055</real><real>1.0</real></array><array><real>0.9637609720230103</real><real>0.15707699954509735</real><real>-0.2156199961900711</real><real>0.0</real><real>0.018911100924015045</real><real>0.7660049796104431</real><real>0.6425570249557495</real><real>0.0</real><real>0.2660970091819763</real><real>-0.6233490109443665</real><real>0.7352749705314636</real><real>0.0</real><real>-0.006562709808349609</real><real>0.02019299939274788</real><real>-0.004543889779597521</real><real>1.0</real></array><array><real>0.8221949934959412</real><real>0.3776470124721527</real><real>-0.4258840084075928</real><real>0.0</real><real>-0.11812599748373032</real><real>0.8451250195503235</real><real>0.521353006362915</real><real>0.0</real><real>0.5568130016326904</real><real>-0.3783459961414337</real><real>0.739467978477478</real><real>0.0</real><real>-0.023213399574160576</real><real>0.08812329918146133</real><real>-0.004173850174993277</real><real>1.0</real></array><array><real>0.8617600202560425</real><real>0.33954399824142456</real><real>-0.3769359886646271</real><real>0.0</real><real>-0.10624899715185165</real><real>0.8473150134086609</real><real>0.5203530192375183</real><real>0.0</real><real>0.49606600403785706</real><real>-0.4083710014820099</real><real>0.7662580013275146</real><real>0.0</real><real>-0.022267799824476242</real><real>0.02319590002298355</real><real>-0.005566920153796673</real><real>1.0</real></array><array><real>0.8747770190238953</real><real>0.3211840093135834</real><real>-0.3627749979496002</real><real>0.0</real><real>-0.10898099839687347</real><real>0.8599650263786316</real><real>0.4985809922218323</real><real>0.0</real><real>0.47211000323295593</real><real>-0.3966119885444641</real><real>0.7872809767723083</real><real>0.0</real><real>-0.01243670005351305</real><real>0.014924099668860435</real><real>-0.003316479967907071</real><real>1.0</real></array><array><real>0.9163669943809509</real><real>-0.07201720029115677</real><real>0.3938089907169342</real><real>0.0</real><real>-0.1188109964132309</real><real>0.8904470205307007</real><real>0.439303994178772</real><real>0.0</real><real>-0.38230299949645996</real><real>-0.4493519961833954</real><real>0.807420015335083</real><real>0.0</real><real>0.03221559897065163</real><real>0.02088090032339096</real><real>-0.00855305977165699</real><real>1.0</real></array><array><real>0.9283679723739624</real><real>-0.020162200555205345</real><real>0.3711149990558624</real><real>0.0</real><real>-0.16619600355625153</real><real>0.8706110119819641</real><real>0.4630500078201294</real><real>0.0</real><real>-0.33243298530578613</real><real>-0.4915589988231659</real><real>0.8048970103263855</real><real>0.0</real><real>0.029450999572873116</real><real>0.03365840017795563</real><real>-0.0010520200012251735</real><real>1.0</real></array><array><real>0.928991973400116</real><real>0.07955490052700043</real><real>0.3614490032196045</real><real>0.0</real><real>-0.2616580128669739</real><real>0.8318700194358826</real><real>0.4894149899482727</real><real>0.0</real><real>-0.2617430090904236</real><real>-0.5492380261421204</real><real>0.7936170101165771</real><real>0.0</real><real>0.020924899727106094</real><real>0.028203699737787247</real><real>-0.000909622001927346</real><real>1.0</real></array><array><real>0.9987319707870483</real><real>-0.04983120039105415</real><real>-0.007089769933372736</real><real>0.0</real><real>0.030134299769997597</real><real>0.704800009727478</real><real>-0.708765983581543</real><real>0.0</real><real>0.040315501391887665</real><real>0.7076539993286133</real><real>0.705407977104187</real><real>0.0</real><real>0.015188699588179588</real><real>-0.09894219785928726</real><real>0.010429499670863152</real><real>1.0</real></array><array><real>0.9989460110664368</real><real>-0.045610301196575165</real><real>-0.00513580022379756</real><real>0.0</real><real>0.028957000002264977</real><real>0.7130839824676514</real><real>-0.7004799842834473</real><real>0.0</real><real>0.03561139851808548</real><real>0.6995930075645447</real><real>0.7136539816856384</real><real>0.0</real><real>-0.0010505500249564648</real><real>-0.042020801454782486</real><real>-0.006302880123257637</real><real>1.0</real></array><array><real>0.9963470101356506</real><real>-0.08039940148591995</real><real>-0.02878049947321415</real><real>0.0</real><real>0.038300998508930206</real><real>0.7219560146331787</real><real>-0.6908779740333557</real><real>0.0</real><real>0.07632440328598022</real><real>0.6872519850730896</real><real>0.7223989963531494</real><real>0.0</real><real>-0.0005042660050094128</real><real>-0.024710899218916893</real><real>-0.0040346598252654076</real><real>1.0</real></array><array><real>0.9319689869880676</real><real>0.24829800426959991</real><real>0.26416099071502686</real><real>0.0</real><real>-0.023382600396871567</real><real>0.768297016620636</real><real>-0.6396669745445251</real><real>0.0</real><real>-0.3617820143699646</real><real>0.589972972869873</real><real>0.7218350172042847</real><real>0.0</real><real>0.0342739000916481</real><real>-0.09468069672584534</real><real>0.009629939682781696</real><real>1.0</real></array><array><real>0.9427329897880554</real><real>0.22354599833488464</real><real>0.2475530058145523</real><real>0.0</real><real>-0.017677700147032738</real><real>0.774619996547699</real><real>-0.6321790218353271</real><real>0.0</real><real>-0.333079993724823</real><real>0.5916000008583069</real><real>0.7342119812965393</real><real>0.0</real><real>0.017191000282764435</real><real>-0.03640500083565712</real><real>-0.006067819893360138</real><real>1.0</real></array><array><real>0.9429500102996826</real><real>0.2165369987487793</real><real>0.2528969943523407</real><real>0.0</real><real>-0.002694070106372237</real><real>0.7645390033721924</real><real>-0.6445720195770264</real><real>0.0</real><real>-0.3329229950904846</real><real>0.6071180105209351</real><real>0.7215059995651245</real><real>0.0</real><real>0.010213700123131275</real><real>-0.023345300927758217</real><real>-0.004377489909529686</real><real>1.0</real></array><array><real>0.965412974357605</real><real>-0.157709002494812</real><real>-0.20761699974536896</real><real>0.0</real><real>-0.015564500354230404</real><real>0.7600290179252625</real><real>-0.6497020125389099</real><real>0.0</real><real>0.2602590024471283</real><real>0.6304630041122437</real><real>0.7312880158424377</real><real>0.0</real><real>-0.0036476401146501303</real><real>-0.09658080339431763</real><real>0.004405209794640541</real><real>1.0</real></array><array><real>0.9724739789962769</real><real>-0.11432900279760361</real><real>-0.20303800702095032</real><real>0.0</real><real>-0.04479910060763359</real><real>0.7633640170097351</real><real>-0.6444140076637268</real><real>0.0</real><real>0.2286670058965683</real><real>0.6357709765434265</real><real>0.7372289896011353</real><real>0.0</real><real>-0.012315300293266773</real><real>-0.035998400300741196</real><real>-0.007578390184789896</real><real>1.0</real></array><array><real>0.9637609720230103</real><real>-0.15707699954509735</real><real>-0.2156199961900711</real><real>0.0</real><real>-0.018911100924015045</real><real>0.7660049796104431</real><real>-0.6425570249557495</real><real>0.0</real><real>0.2660970091819763</real><real>0.6233490109443665</real><real>0.7352749705314636</real><real>0.0</real><real>-0.006562769878655672</real><real>-0.02019290067255497</real><real>-0.004543649964034557</real><real>1.0</real></array><array><real>0.8221949934959412</real><real>-0.3776470124721527</real><real>-0.4258840084075928</real><real>0.0</real><real>0.11812599748373032</real><real>0.8451250195503235</real><real>-0.521353006362915</real><real>0.0</real><real>0.5568130016326904</real><real>0.3783459961414337</real><real>0.739467978477478</real><real>0.0</real><real>-0.023213399574160576</real><real>-0.08812329918146133</real><real>-0.004173850174993277</real><real>1.0</real></array><array><real>0.8617600202560425</real><real>-0.33954399824142456</real><real>-0.3769359886646271</real><real>0.0</real><real>0.10624899715185165</real><real>0.8473150134086609</real><real>-0.5203530192375183</real><real>0.0</real><real>0.49606600403785706</real><real>0.4083710014820099</real><real>0.7662580013275146</real><real>0.0</real><real>-0.022267799824476242</real><real>-0.023195700719952583</real><real>-0.005566900130361319</real><real>1.0</real></array><array><real>0.8747770190238953</real><real>-0.3211840093135834</real><real>-0.3627749979496002</real><real>0.0</real><real>0.10898099839687347</real><real>0.8599650263786316</real><real>-0.4985809922218323</real><real>0.0</real><real>0.47211000323295593</real><real>0.3966119885444641</real><real>0.7872809767723083</real><real>0.0</real><real>-0.012436600401997566</real><real>-0.014924000017344952</real><real>-0.0033167300280183554</real><real>1.0</real></array><array><real>0.9163669943809509</real><real>0.07201740145683289</real><real>0.3938089907169342</real><real>0.0</real><real>0.1188109964132309</real><real>0.8904470205307007</real><real>-0.439303994178772</real><real>0.0</real><real>-0.38230299949645996</real><real>0.4493519961833954</real><real>0.807420015335083</real><real>0.0</real><real>0.03221559897065163</real><real>-0.02088090032339096</real><real>-0.00855305977165699</real><real>1.0</real></array><array><real>0.9283679723739624</real><real>0.020162200555205345</real><real>0.3711149990558624</real><real>0.0</real><real>0.16619600355625153</real><real>0.8706110119819641</real><real>-0.4630500078201294</real><real>0.0</real><real>-0.33243298530578613</real><real>0.4915589988231659</real><real>0.8048970103263855</real><real>0.0</real><real>0.029450900852680206</real><real>-0.03365840017795563</real><real>-0.0010520999785512686</real><real>1.0</real></array><array><real>0.928991973400116</real><real>-0.07955490052700043</real><real>0.3614490032196045</real><real>0.0</real><real>0.2616580128669739</real><real>0.8318700194358826</real><real>-0.4894149899482727</real><real>0.0</real><real>-0.2617430090904236</real><real>0.5492380261421204</real><real>0.7936170101165771</real><real>0.0</real><real>0.020925000309944153</real><real>-0.028203800320625305</real><real>-0.0009097899892367423</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.067020058631897</real><real>1.0</real></array><array><real>0.9987319707870483</real><real>0.04983130097389221</real><real>-0.007089749909937382</real><real>0.0</real><real>-0.030134299769997597</real><real>0.704800009727478</real><real>0.708765983581543</real><real>0.0</real><real>0.040315598249435425</real><real>-0.7076539993286133</real><real>0.705407977104187</real><real>0.0</real><real>-0.008488760329782963</real><real>0.41053301095962524</real><real>-1.2015999555587769</real><real>1.0</real></array><array><real>0.9989460110664368</real><real>0.045610301196575165</real><real>-0.00513580022379756</real><real>0.0</real><real>-0.028957000002264977</real><real>0.7130839824676514</real><real>0.7004799842834473</real><real>0.0</real><real>0.03561139851808548</real><real>-0.6995930075645447</real><real>0.7136539816856384</real><real>0.0</real><real>-0.0029308199882507324</real><real>0.35466399788856506</real><real>-1.1994999647140503</real><real>1.0</real></array><array><real>0.9963470101356506</real><real>0.08039940148591995</real><real>-0.02878049947321415</real><real>0.0</real><real>-0.038300998508930206</real><real>0.7219560146331787</real><real>0.6908779740333557</real><real>0.0</real><real>0.07632440328598022</real><real>-0.6872519850730896</real><real>0.7223989963531494</real><real>0.0</real><real>-0.04098540171980858</real><real>0.3118860125541687</real><real>-1.1996099948883057</real><real>1.0</real></array><array><real>0.9319689869880676</real><real>-0.24829800426959991</real><real>0.26416099071502686</real><real>0.0</real><real>0.02338249981403351</real><real>0.768297016620636</real><real>0.6396660208702087</real><real>0.0</real><real>-0.3617820143699646</real><real>-0.589972972869873</real><real>0.7218350172042847</real><real>0.0</real><real>0.40104299783706665</real><real>0.2437240034341812</real><real>-1.1804200410842896</real><real>1.0</real></array><array><real>0.9427329897880554</real><real>-0.22354599833488464</real><real>0.2475530058145523</real><real>0.0</real><real>0.01767759956419468</real><real>0.774619996547699</real><real>0.6321790218353271</real><real>0.0</real><real>-0.333079993724823</real><real>-0.5916000008583069</real><real>0.7342119812965393</real><real>0.0</real><real>0.35530799627304077</real><real>0.2053389996290207</real><real>-1.183650016784668</real><real>1.0</real></array><array><real>0.9429500102996826</real><real>-0.2165369987487793</real><real>0.2528969943523407</real><real>0.0</real><real>0.00269406009465456</real><real>0.7645390033721924</real><real>0.6445720195770264</real><real>0.0</real><real>-0.3329229950904846</real><real>-0.6071180105209351</real><real>0.7215059995651245</real><real>0.0</real><real>0.35388800501823425</real><real>0.2048649936914444</real><real>-1.1728999614715576</real><real>1.0</real></array><array><real>0.965412974357605</real><real>0.157709002494812</real><real>-0.20761699974536896</real><real>0.0</real><real>0.015564500354230404</real><real>0.7600290179252625</real><real>0.6497020125389099</real><real>0.0</real><real>0.2602590024471283</real><real>-0.6304630041122437</real><real>0.7312880158424377</real><real>0.0</real><real>-0.2662949860095978</real><real>0.2996309995651245</real><real>-1.2001399993896484</real><real>1.0</real></array><array><real>0.9724739789962769</real><real>0.11432900279760361</real><real>-0.20303800702095032</real><real>0.0</real><real>0.04479910060763359</real><real>0.7633640170097351</real><real>0.6444140076637268</real><real>0.0</real><real>0.2286670058965683</real><real>-0.6357709765434265</real><real>0.7372289896011353</real><real>0.0</real><real>-0.2356870025396347</real><real>0.26565900444984436</real><real>-1.1958600282669067</real><real>1.0</real></array><array><real>0.9637609720230103</real><real>0.15707699954509735</real><real>-0.2156199961900711</real><real>0.0</real><real>0.018911100924015045</real><real>0.7660049796104431</real><real>0.6425570249557495</real><real>0.0</real><real>0.2660970091819763</real><real>-0.6233490109443665</real><real>0.7352749705314636</real><real>0.0</real><real>-0.2549220025539398</real><real>0.23242099583148956</real><real>-1.188689947128296</real><real>1.0</real></array><array><real>0.8221949934959412</real><real>0.3776470124721527</real><real>-0.4258840084075928</real><real>0.0</real><real>-0.11812599748373032</real><real>0.8451250195503235</real><real>0.521353006362915</real><real>0.0</real><real>0.5568130016326904</real><real>-0.3783459961414337</real><real>0.739467978477478</real><real>0.0</real><real>-0.5196760296821594</real><real>-0.007902019657194614</real><real>-1.1486300230026245</real><real>1.0</real></array><array><real>0.8617600202560425</real><real>0.33954399824142456</real><real>-0.3769359886646271</real><real>0.0</real><real>-0.10624899715185165</real><real>0.8473150134086609</real><real>0.5203530192375183</real><real>0.0</real><real>0.49606600403785706</real><real>-0.4083710014820099</real><real>0.7662580013275146</real><real>0.0</real><real>-0.4340290129184723</real><real>-0.0015098199946805835</real><real>-1.169010043144226</real><real>1.0</real></array><array><real>0.8747770190238953</real><real>0.3211840093135834</real><real>-0.3627749979496002</real><real>0.0</real><real>-0.10898099839687347</real><real>0.8599650263786316</real><real>0.4985809922218323</real><real>0.0</real><real>0.47211000323295593</real><real>-0.3966119885444641</real><real>0.7872809767723083</real><real>0.0</real><real>-0.3928540050983429</real><real>-0.03789449855685234</real><real>-1.1751899719238281</real><real>1.0</real></array><array><real>0.9163669943809509</real><real>-0.07201720029115677</real><real>0.3938089907169342</real><real>0.0</real><real>-0.1188109964132309</real><real>0.8904470205307007</real><real>0.439303994178772</real><real>0.0</real><real>-0.38230299949645996</real><real>-0.4493519961833954</real><real>0.807420015335083</real><real>0.0</real><real>0.51316899061203</real><real>0.09074380248785019</real><real>-1.1683000326156616</real><real>1.0</real></array><array><real>0.9283679723739624</real><real>-0.020162200555205345</real><real>0.3711149990558624</real><real>0.0</real><real>-0.16619600355625153</real><real>0.8706110119819641</real><real>0.4630500078201294</real><real>0.0</real><real>-0.33243298530578613</real><real>-0.4915589988231659</real><real>0.8048970103263855</real><real>0.0</real><real>0.45058199763298035</real><real>0.11499100178480148</real><real>-1.1762100458145142</real><real>1.0</real></array><array><real>0.928991973400116</real><real>0.07955490052700043</real><real>0.3614490032196045</real><real>0.0</real><real>-0.2616580128669739</real><real>0.8318700194358826</real><real>0.4894149899482727</real><real>0.0</real><real>-0.2617430090904236</real><real>-0.5492380261421204</real><real>0.7936170101165771</real><real>0.0</real><real>0.401203989982605</real><real>0.1690800040960312</real><real>-1.1763999462127686</real><real>1.0</real></array><array><real>0.9987319707870483</real><real>-0.04983120039105415</real><real>-0.007089769933372736</real><real>0.0</real><real>0.030134299769997597</real><real>0.704800009727478</real><real>-0.708765983581543</real><real>0.0</real><real>0.040315501391887665</real><real>0.7076539993286133</real><real>0.705407977104187</real><real>0.0</real><real>-0.008488760329782963</real><real>-0.41053301095962524</real><real>-1.2015999555587769</real><real>1.0</real></array><array><real>0.9989460110664368</real><real>-0.045610301196575165</real><real>-0.00513580022379756</real><real>0.0</real><real>0.028957000002264977</real><real>0.7130839824676514</real><real>-0.7004799842834473</real><real>0.0</real><real>0.03561139851808548</real><real>0.6995930075645447</real><real>0.7136539816856384</real><real>0.0</real><real>-0.0029308199882507324</real><real>-0.35466399788856506</real><real>-1.1994999647140503</real><real>1.0</real></array><array><real>0.9963470101356506</real><real>-0.08039940148591995</real><real>-0.02878049947321415</real><real>0.0</real><real>0.038300998508930206</real><real>0.7219560146331787</real><real>-0.6908779740333557</real><real>0.0</real><real>0.07632440328598022</real><real>0.6872519850730896</real><real>0.7223989963531494</real><real>0.0</real><real>-0.04098540171980858</real><real>-0.3118860125541687</real><real>-1.1996099948883057</real><real>1.0</real></array><array><real>0.9319689869880676</real><real>0.24829800426959991</real><real>0.26416099071502686</real><real>0.0</real><real>-0.023382600396871567</real><real>0.768297016620636</real><real>-0.6396669745445251</real><real>0.0</real><real>-0.3617820143699646</real><real>0.589972972869873</real><real>0.7218350172042847</real><real>0.0</real><real>0.40104299783706665</real><real>-0.2437240034341812</real><real>-1.1804200410842896</real><real>1.0</real></array><array><real>0.9427329897880554</real><real>0.22354599833488464</real><real>0.2475530058145523</real><real>0.0</real><real>-0.017677700147032738</real><real>0.774619996547699</real><real>-0.6321790218353271</real><real>0.0</real><real>-0.333079993724823</real><real>0.5916000008583069</real><real>0.7342119812965393</real><real>0.0</real><real>0.35530799627304077</real><real>-0.2053389996290207</real><real>-1.183650016784668</real><real>1.0</real></array><array><real>0.9429500102996826</real><real>0.2165369987487793</real><real>0.2528969943523407</real><real>0.0</real><real>-0.002694070106372237</real><real>0.7645390033721924</real><real>-0.6445720195770264</real><real>0.0</real><real>-0.3329229950904846</real><real>0.6071180105209351</real><real>0.7215059995651245</real><real>0.0</real><real>0.35388800501823425</real><real>-0.2048649936914444</real><real>-1.1728999614715576</real><real>1.0</real></array><array><real>0.965412974357605</real><real>-0.157709002494812</real><real>-0.20761699974536896</real><real>0.0</real><real>-0.015564500354230404</real><real>0.7600290179252625</real><real>-0.6497020125389099</real><real>0.0</real><real>0.2602590024471283</real><real>0.6304630041122437</real><real>0.7312880158424377</real><real>0.0</real><real>-0.2662949860095978</real><real>-0.2996309995651245</real><real>-1.2001399993896484</real><real>1.0</real></array><array><real>0.9724739789962769</real><real>-0.11432900279760361</real><real>-0.20303800702095032</real><real>0.0</real><real>-0.04479910060763359</real><real>0.7633640170097351</real><real>-0.6444140076637268</real><real>0.0</real><real>0.2286670058965683</real><real>0.6357709765434265</real><real>0.7372289896011353</real><real>0.0</real><real>-0.2356870025396347</real><real>-0.26565900444984436</real><real>-1.1958600282669067</real><real>1.0</real></array><array><real>0.9637609720230103</real><real>-0.15707699954509735</real><real>-0.2156199961900711</real><real>0.0</real><real>-0.018911100924015045</real><real>0.7660049796104431</real><real>-0.6425570249557495</real><real>0.0</real><real>0.2660970091819763</real><real>0.6233490109443665</real><real>0.7352749705314636</real><real>0.0</real><real>-0.2549220025539398</real><real>-0.23242099583148956</real><real>-1.188689947128296</real><real>1.0</real></array><array><real>0.8221949934959412</real><real>-0.3776470124721527</real><real>-0.4258840084075928</real><real>0.0</real><real>0.11812599748373032</real><real>0.8451250195503235</real><real>-0.521353006362915</real><real>0.0</real><real>0.5568130016326904</real><real>0.3783459961414337</real><real>0.739467978477478</real><real>0.0</real><real>-0.5196760296821594</real><real>0.007902019657194614</real><real>-1.1486300230026245</real><real>1.0</real></array><array><real>0.8617600202560425</real><real>-0.33954399824142456</real><real>-0.3769359886646271</real><real>0.0</real><real>0.10624899715185165</real><real>0.8473150134086609</real><real>-0.5203530192375183</real><real>0.0</real><real>0.49606600403785706</real><real>0.4083710014820099</real><real>0.7662580013275146</real><real>0.0</real><real>-0.4340290129184723</real><real>0.0015098199946805835</real><real>-1.169010043144226</real><real>1.0</real></array><array><real>0.8747770190238953</real><real>-0.3211840093135834</real><real>-0.3627749979496002</real><real>0.0</real><real>0.10898099839687347</real><real>0.8599650263786316</real><real>-0.4985809922218323</real><real>0.0</real><real>0.47211000323295593</real><real>0.3966119885444641</real><real>0.7872809767723083</real><real>0.0</real><real>-0.3928540050983429</real><real>0.03789449855685234</real><real>-1.1751899719238281</real><real>1.0</real></array><array><real>0.9163669943809509</real><real>0.07201740145683289</real><real>0.3938089907169342</real><real>0.0</real><real>0.1188109964132309</real><real>0.8904470205307007</real><real>-0.439303994178772</real><real>0.0</real><real>-0.38230299949645996</real><real>0.4493519961833954</real><real>0.807420015335083</real><real>0.0</real><real>0.51316899061203</real><real>-0.0907440036535263</real><real>-1.1683000326156616</real><real>1.0</real></array><array><real>0.9283679723739624</real><real>0.020162200555205345</real><real>0.3711149990558624</real><real>0.0</real><real>0.16619600355625153</real><real>0.8706110119819641</real><real>-0.4630500078201294</real><real>0.0</real><real>-0.33243298530578613</real><real>0.4915589988231659</real><real>0.8048970103263855</real><real>0.0</real><real>0.45058199763298035</real><real>-0.11499100178480148</real><real>-1.1762100458145142</real><real>1.0</real></array><array><real>0.928991973400116</real><real>-0.07955490052700043</real><real>0.3614490032196045</real><real>0.0</real><real>0.2616580128669739</real><real>0.8318700194358826</real><real>-0.4894149899482727</real><real>0.0</real><real>-0.2617430090904236</real><real>0.5492380261421204</real><real>0.7936170101165771</real><real>0.0</real><real>0.401203989982605</real><real>-0.1690800040960312</real><real>-1.1763999462127686</real><real>1.0</real></array></array></map><key>15659a9a-f1c1-3e38-8343-2e23e9f65d20</key><map><key>bind_shape_matrix</key><array><real>0.12950499355793</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.09769980609416962</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.13808000087738037</real><real>0.0</real><real>0.021911798045039177</real><real>-0.057047098875045776</real><real>1.8354499340057373</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceEar2Right</string><string>mFaceEar1Right</string><string>mFaceRoot</string><string>mFaceEar1Left</string><string>mFaceEar2Left</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0142705999314785</real><real>-0.017557399347424507</real><real>0.05648919939994812</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0041375597938895226</real><real>-0.04739430174231529</real><real>0.08954329788684845</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0041375597938895226</real><real>0.04739430174231529</real><real>0.08954329788684845</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0142705999314785</real><real>0.017557399347424507</real><real>0.05648919939994812</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.016442900523543358</real><real>0.062392398715019226</real><real>-1.8631500005722046</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.0021723099052906036</real><real>0.04483500123023987</real><real>-1.8066600561141968</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.0021723099052906036</real><real>-0.04483500123023987</real><real>-1.8066600561141968</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.016442900523543358</real><real>-0.062392398715019226</real><real>-1.8631500005722046</real><real>1.0</real></array></array></map><key>1d5936bc-0501-7376-f70c-06dcfac920ed</key><map><key>bind_shape_matrix</key><array><real>0.04880329594016075</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.048803336918354034</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.04902994632720947</real><real>0.0</real><real>0.05886554718017578</real><real>0.0343865305185318</real><real>1.7572450637817383</real><real>1.0</real></array><key>joint_names</key><array><string>mEyeLeft</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mEyeRight</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.09042750298976898</real><real>0.03717460110783577</real><real>0.08056280016899109</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.09042750298976898</real><real>-0.03717460110783577</real><real>0.08056280016899109</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.06363839656114578</real><real>-0.03717460110783577</real><real>-1.8997000455856323</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.06363839656114578</real><real>0.03717460110783577</real><real>-1.8997000455856323</real><real>1.0</real></array></array></map><key>9174c7f1-bd5f-68d2-2f4f-cc9b36312067</key><map><key>bind_shape_matrix</key><array><real>0.08326390385627747</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.12516659498214722</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.10517990589141846</real><real>0.0</real><real>0.11359705030918121</real><real>0.0</real><real>1.7399399280548096</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025396499782800674</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10700099915266037</real><real>0.0</real><real>-0.026076599955558777</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>-0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.02026969939470291</real><real>0.0</real><real>0.005331280175596476</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08300650119781494</real><real>0.0</real><real>-0.020363999530673027</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08378739655017853</real><real>0.0</real><real>-0.026688499376177788</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>-0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.03835279867053032</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.03835279867053032</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>0.016734100878238678</real><real>0.05700350180268288</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>-0.016734100878238678</real><real>0.05700350180268288</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>0.03760350123047829</real><real>0.05627429857850075</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>-0.03760350123047829</real><real>0.05627429857850075</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.07319430261850357</real><real>0.0</real><real>0.08750239759683609</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10439900308847427</real><real>0.0</real><real>0.017177099362015724</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.15049900114536285</real><real>0.0</real><real>0.0038522500544786453</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.03835279867053032</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.03835279867053032</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>0.05687420070171356</real><real>-0.004532460123300552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>-0.05687420070171356</real><real>-0.004532460123300552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>0.016701199114322662</real><real>0.0</real><real>0.009711739607155323</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10521099716424942</real><real>0.0</real><real>-1.840149998664856</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>-0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.09693530201911926</real><real>0.0</real><real>-1.8257900476455688</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11720500141382217</real><real>0.0</real><real>-1.820449948310852</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11798600107431412</real><real>0.0</real><real>-1.8141299486160278</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>-0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>-0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>-0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.07140520215034485</real><real>0.0</real><real>-1.9511499404907227</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10260900110006332</real><real>0.0</real><real>-1.8824299573898315</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.1487099975347519</real><real>0.0</real><real>-1.8694000244140625</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>-0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>-0.12191300094127655</real><real>0.0</real><real>-1.7818800210952759</real><real>1.0</real></array></array></map><key>d73dea3b-b8cb-59ff-c76b-cfdcc8119bb5</key><map><key>bind_shape_matrix</key><array><real>0.08899261057376862</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.06393220275640488</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.020760059356689453</real><real>0.0</real><real>0.10354769974946976</real><real>0.0</real><real>1.693750023841858</real><real>1.0</real></array><key>joint_names</key><array><string>mFaceJaw</string><string>mFaceRoot</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025394700467586517</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array></array></map><key>d0328b82-d9ca-6071-b248-17edfc7612cb</key><map><key>bind_shape_matrix</key><array><real>0.13549870252609253</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.1464741975069046</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.12077999114990234</real><real>0.0</real><real>0.10338164865970612</real><real>0.0</real><real>1.7488499879837036</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025394700467586517</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10700099915266037</real><real>0.0</real><real>-0.02607489936053753</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>-0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.02026969939470291</real><real>0.0</real><real>0.005331280175596476</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08300650119781494</real><real>0.0</real><real>-0.020363999530673027</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08378739655017853</real><real>0.0</real><real>-0.026688499376177788</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>-0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>-0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>-0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.07319430261850357</real><real>0.0</real><real>0.08750399947166443</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10439900308847427</real><real>0.0</real><real>0.017178799957036972</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.15049900114536285</real><real>0.0</real><real>0.003853919915854931</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>-0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>0.016701199114322662</real><real>0.0</real><real>0.009711739607155323</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10521099716424942</real><real>0.0</real><real>-1.8401600122451782</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>-0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.09693530201911926</real><real>0.0</real><real>-1.8257900476455688</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11720500141382217</real><real>0.0</real><real>-1.8204599618911743</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11798600107431412</real><real>0.0</real><real>-1.8141299486160278</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>-0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>-0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>-0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.07140520215034485</real><real>0.0</real><real>-1.951159954071045</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10260900110006332</real><real>0.0</real><real>-1.8824299573898315</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.1487099975347519</real><real>0.0</real><real>-1.8694000244140625</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>-0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>-0.12191300094127655</real><real>0.0</real><real>-1.7818800210952759</real><real>1.0</real></array></array></map><key>05bf604d-d1c0-352b-cb2f-c37caca6f542</key><map><key>bind_shape_matrix</key><array><real>0.014549999497830868</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.035996198654174805</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.019659996032714844</real><real>0.0</real><real>0.1341239959001541</real><real>0.0</real><real>1.6930099725723267</real><real>1.0</real></array><key>joint_names</key><array><string>mFaceJaw</string><string>mFaceRoot</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025394700467586517</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array></array></map><key>46ee8fb2-15f0-fa2e-d260-e7e6e8295445</key><map><key>bind_shape_matrix</key><array><real>0.14447110891342163</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07934600114822388</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0342099666595459</real><real>0.0</real><real>0.07812044024467468</real><real>0.0</real><real>1.69725501537323</real><real>1.0</real></array><key>joint_names</key><array><string>mFaceJaw</string><string>mFaceRoot</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025394700467586517</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array></array></map><key>d2205615-2ce0-4ff1-2bfd-bdc77a3825cc</key><map><key>bind_shape_matrix</key><array><real>0.06583520025014877</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.1928279995918274</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.10592997074127197</real><real>0.0</real><real>0.02077449858188629</real><real>0.0</real><real>1.7146050930023193</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025394700467586517</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10700099915266037</real><real>0.0</real><real>-0.02607489936053753</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>-0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.02026969939470291</real><real>0.0</real><real>0.005331280175596476</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08300650119781494</real><real>0.0</real><real>-0.020363999530673027</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08378739655017853</real><real>0.0</real><real>-0.026688499376177788</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>-0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>-0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>-0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.07319430261850357</real><real>0.0</real><real>0.08750399947166443</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10439900308847427</real><real>0.0</real><real>0.017178799957036972</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.15049900114536285</real><real>0.0</real><real>0.003853919915854931</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>-0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>0.016701199114322662</real><real>0.0</real><real>0.009711739607155323</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10521099716424942</real><real>0.0</real><real>-1.8401600122451782</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>-0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.09693530201911926</real><real>0.0</real><real>-1.8257900476455688</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11720500141382217</real><real>0.0</real><real>-1.8204599618911743</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11798600107431412</real><real>0.0</real><real>-1.8141299486160278</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>-0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>-0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>-0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.07140520215034485</real><real>0.0</real><real>-1.951159954071045</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10260900110006332</real><real>0.0</real><real>-1.8824299573898315</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.1487099975347519</real><real>0.0</real><real>-1.8694000244140625</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>-0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>-0.12191300094127655</real><real>0.0</real><real>-1.7818800210952759</real><real>1.0</real></array></array></map><key>8665c374-cb61-d418-d412-7f4ea828e119</key><map><key>bind_shape_matrix</key><array><real>0.6689305901527405</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.17128899693489075</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.1917099952697754</real><real>0.0</real><real>-0.40683069825172424</real><real>0.0</real><real>1.1260449886322021</real><real>1.0</real></array><key>joint_names</key><array><string>mTail1</string><string>mPelvis</string><string>mTail2</string><string>mTail3</string><string>mTail4</string><string>mTail6</string><string>mTail5</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.16599999368190765</real><real>0.0</real><real>0.06700000166893005</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.14775000512599945</real><real>0.0</real><real>0.0</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.12600000202655792</real><real>0.0</real><real>0.0</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.10649999976158142</real><real>0.0</real><real>0.0</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.07050000131130219</real><real>0.0</real><real>0.0</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.08399999886751175</real><real>0.0</real><real>0.0</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.16599999368190765</real><real>0.0</real><real>-1.1340199708938599</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.067020058631897</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.3137499988079071</real><real>0.0</real><real>-1.1340199708938599</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.43974998593330383</real><real>0.0</real><real>-1.1340199708938599</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.5462499856948853</real><real>0.0</real><real>-1.1340199708938599</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.7007499933242798</real><real>0.0</real><real>-1.1340199708938599</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.6302499771118164</real><real>0.0</real><real>-1.1340199708938599</real><real>1.0</real></array></array></map><key>e678576a-dc9f-5187-6ed5-5b4aafb65d7b</key><map><key>bind_shape_matrix</key><array><real>0.010342992842197418</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.06067759916186333</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.012930035591125488</real><real>0.0</real><real>0.11175650358200073</real><real>0.0</real><real>1.6866850852966309</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025394700467586517</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10700099915266037</real><real>0.0</real><real>-0.02607489936053753</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>-0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.02026969939470291</real><real>0.0</real><real>0.005331280175596476</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08300650119781494</real><real>0.0</real><real>-0.020363999530673027</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08378739655017853</real><real>0.0</real><real>-0.026688499376177788</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>-0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>-0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>-0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.07319430261850357</real><real>0.0</real><real>0.08750399947166443</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10439900308847427</real><real>0.0</real><real>0.017178799957036972</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.15049900114536285</real><real>0.0</real><real>0.003853919915854931</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>-0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>0.016701199114322662</real><real>0.0</real><real>0.009711739607155323</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10521099716424942</real><real>0.0</real><real>-1.8401600122451782</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>-0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.09693530201911926</real><real>0.0</real><real>-1.8257900476455688</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11720500141382217</real><real>0.0</real><real>-1.8204599618911743</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11798600107431412</real><real>0.0</real><real>-1.8141299486160278</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>-0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>-0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>-0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.07140520215034485</real><real>0.0</real><real>-1.951159954071045</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10260900110006332</real><real>0.0</real><real>-1.8824299573898315</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.1487099975347519</real><real>0.0</real><real>-1.8694000244140625</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>-0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>-0.12191300094127655</real><real>0.0</real><real>-1.7818800210952759</real><real>1.0</real></array></array></map><key>8d23b8c8-fadf-c1b3-0b04-a3ecea292576</key><map><key>bind_shape_matrix</key><array><real>0.12950499355793</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.09769980609416962</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.13808000087738037</real><real>0.0</real><real>0.021911798045039177</real><real>0.057047098875045776</real><real>1.8354499340057373</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceEar2Right</string><string>mFaceEar1Right</string><string>mFaceRoot</string><string>mFaceEar1Left</string><string>mFaceEar2Left</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0142705999314785</real><real>-0.017557399347424507</real><real>0.05648919939994812</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0041375597938895226</real><real>-0.04739430174231529</real><real>0.08954329788684845</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0041375597938895226</real><real>0.04739430174231529</real><real>0.08954329788684845</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0142705999314785</real><real>0.017557399347424507</real><real>0.05648919939994812</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.016442900523543358</real><real>0.062392398715019226</real><real>-1.8631500005722046</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.0021723099052906036</real><real>0.04483500123023987</real><real>-1.8066600561141968</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.0021723099052906036</real><real>-0.04483500123023987</real><real>-1.8066600561141968</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.016442900523543358</real><real>-0.062392398715019226</real><real>-1.8631500005722046</real><real>1.0</real></array></array></map><key>2a30e7ec-9840-f495-daa1-2b8d0d025a78</key><map><key>bind_shape_matrix</key><array><real>0.06447789818048477</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.06988950073719025</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.10517000406980515</real><real>0.0</real><real>0.006453849375247955</real><real>0.07881925255060196</real><real>1.8452450037002563</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceEar2Right</string><string>mFaceEar1Right</string><string>mFaceRoot</string><string>mFaceEar1Left</string><string>mFaceEar2Left</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0142705999314785</real><real>-0.017557399347424507</real><real>0.05648919939994812</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0041375597938895226</real><real>-0.04739430174231529</real><real>0.08954329788684845</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0041375597938895226</real><real>0.04739430174231529</real><real>0.08954329788684845</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0142705999314785</real><real>0.017557399347424507</real><real>0.05648919939994812</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.016442900523543358</real><real>0.062392398715019226</real><real>-1.8631500005722046</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.0021723099052906036</real><real>0.04483500123023987</real><real>-1.8066600561141968</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.0021723099052906036</real><real>-0.04483500123023987</real><real>-1.8066600561141968</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.016442900523543358</real><real>-0.062392398715019226</real><real>-1.8631500005722046</real><real>1.0</real></array></array></map><key>3bd8d73d-be6f-8de2-39ae-1f680189bc27</key><map><key>bind_shape_matrix</key><array><real>0.06447789818048477</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.06988950073719025</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.10517000406980515</real><real>0.0</real><real>0.006453849375247955</real><real>-0.07881925255060196</real><real>1.8452450037002563</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceEar2Right</string><string>mFaceEar1Right</string><string>mFaceRoot</string><string>mFaceEar1Left</string><string>mFaceEar2Left</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0142705999314785</real><real>-0.017557399347424507</real><real>0.05648919939994812</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0041375597938895226</real><real>-0.04739430174231529</real><real>0.08954329788684845</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0041375597938895226</real><real>0.04739430174231529</real><real>0.08954329788684845</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0142705999314785</real><real>0.017557399347424507</real><real>0.05648919939994812</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.016442900523543358</real><real>0.062392398715019226</real><real>-1.8631500005722046</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.0021723099052906036</real><real>0.04483500123023987</real><real>-1.8066600561141968</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.0021723099052906036</real><real>-0.04483500123023987</real><real>-1.8066600561141968</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.016442900523543358</real><real>-0.062392398715019226</real><real>-1.8631500005722046</real><real>1.0</real></array></array></map><key>34db2e33-e79f-ea57-14af-c1ce9cbc63ff</key><map><key>bind_shape_matrix</key><array><real>0.03714209794998169</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.14610280096530914</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.03297996520996094</real><real>0.0</real><real>0.07929874956607819</real><real>0.0</real><real>1.7578400373458862</real><real>1.0</real></array><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>alt_inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.07562989741563797</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.00950700044631958</real><real>0.0</real><real>0.25110799074172974</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>-0.01536799967288971</real><real>0.0</real><real>0.20487700402736664</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.08407290279865265</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.067020058631897</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.035987500101327896</real><real>0.0</real><real>-0.025394700467586517</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.02500000037252903</real><real>0.0</real><real>0.04500000178813934</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10700099915266037</real><real>0.0</real><real>-0.02607489936053753</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.059168100357055664</real><real>0.0</real><real>0.004850860219448805</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>-0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03629549965262413</real><real>0.01899999938905239</real><real>-0.013485999777913094</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.02026969939470291</real><real>0.0</real><real>0.005331280175596476</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08300650119781494</real><real>0.0</real><real>-0.020363999530673027</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.08378739655017853</real><real>0.0</real><real>-0.026688499376177788</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>-0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.03427229821681976</real><real>0.01206200011074543</real><real>0.0005108119803480804</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.018112899735569954</real><real>-0.016734100878238678</real><real>0.057005301117897034</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.008231439627707005</real><real>-0.03760350123047829</real><real>0.056276001036167145</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.07319430261850357</real><real>0.0</real><real>0.08750399947166443</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.10439900308847427</real><real>0.0</real><real>0.017178799957036972</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.15049900114536285</real><real>0.0</real><real>0.003853919915854931</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.04490169882774353</real><real>-0.036976300179958344</real><real>0.038354501128196716</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.029158199205994606</real><real>-0.05687420070171356</real><real>-0.0045307897962629795</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>0.016701199114322662</real><real>0.0</real><real>0.009711739607155323</real><real>1.0</real></array></array><key>pelvis_offset</key><real>0.0</real><key>inverse_bind_matrix</key><array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.026789100840687752</real><real>0.0</real><real>-1.8191399574279785</real><real>1.0</real></array><array><real>1.1834299564361572</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.19760000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.029325399547815323</real><real>0.0</real><real>-1.607069969177246</real><real>1.0</real></array><array><real>1.01010000705719</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0416699647903442</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.015523199923336506</real><real>0.0</real><real>-1.3559600114822388</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.1510900259017944</real><real>1.0</real></array><array><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>-1.0670100450515747</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.034198399633169174</real><real>0.0</real><real>-1.8408199548721313</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0570800304412842</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.1061899662017822</real><real>0.0</real><real>0.0017891100142151117</real><real>0.0</real><real>-1.9089800119400024</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10521099716424942</real><real>0.0</real><real>-1.8401600122451782</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.220829963684082</real><real>0.0</real><real>-0.04604329913854599</real><real>0.0</real><real>-2.0834999084472656</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.14150699973106384</real><real>-0.01899999938905239</real><real>-1.8266700506210327</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.09693530201911926</real><real>0.0</real><real>-1.8257900476455688</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11720500141382217</real><real>0.0</real><real>-1.8204599618911743</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.11798600107431412</real><real>0.0</real><real>-1.8141299486160278</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.15147699415683746</real><real>-0.01206200011074543</real><real>-1.820970058441162</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>-0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>-0.016323799267411232</real><real>0.017114000394940376</real><real>-1.5125499963760376</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>-0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.8510640263557434</real><real>0.0</real><real>0.010020599700510502</real><real>0.038457199931144714</real><real>-1.511989951133728</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.07140520215034485</real><real>0.0</real><real>-1.951159954071045</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.10260900110006332</real><real>0.0</real><real>-1.8824299573898315</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.1487099975347519</real><real>0.0</real><real>-1.8694000244140625</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>-0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.04311259835958481</real><real>0.037815701216459274</real><real>-1.9031200408935547</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>-0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>-0.027369100600481033</real><real>0.058165401220321655</real><real>-1.8612099885940552</real><real>1.0</real></array><array><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.0810799598693848</real><real>0.0</real><real>0.0</real><real>0.0</real><real>0.0</real><real>1.04135000705719</real><real>0.0</real><real>-0.12191300094127655</real><real>0.0</real><real>-1.7818800210952759</real><real>1.0</real></array></array></map></map></llsd> \ No newline at end of file
diff --git a/indra/llappearanceutility/tests/joint-offsets.xml.output b/indra/llappearanceutility/tests/joint-offsets.xml.output
new file mode 100644
index 0000000000..d0f94b8f11
--- /dev/null
+++ b/indra/llappearanceutility/tests/joint-offsets.xml.output
@@ -0,0 +1 @@
+<llsd><map><key>skindata</key><map><key>05bf604d-d1c0-352b-cb2f-c37caca6f542</key><map><key>joint_names</key><array><string>mFaceJaw</string><string>mFaceRoot</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string></array><key>joint_offset</key><array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539470046758651733398438</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array></array><key>pelvis_offset</key><real>0</real></map><key>15659a9a-f1c1-3e38-8343-2e23e9f65d20</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceEar2Right</string><string>mFaceEar1Right</string><string>mFaceRoot</string><string>mFaceEar1Left</string><string>mFaceEar2Left</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.01427059993147850036621094</real><real>-0.01755739934742450714111328</real><real>0.0564891993999481201171875</real></array><array><real>0.004137559793889522552490234</real><real>-0.04739430174231529235839844</real><real>0.08954329788684844970703125</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>0.004137559793889522552490234</real><real>0.04739430174231529235839844</real><real>0.08954329788684844970703125</real></array><array><real>0.01427059993147850036621094</real><real>0.01755739934742450714111328</real><real>0.0564891993999481201171875</real></array></array><key>pelvis_offset</key><real>0</real></map><key>1d5936bc-0501-7376-f70c-06dcfac920ed</key><map><key>joint_names</key><array><string>mEyeLeft</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mEyeRight</string></array><key>joint_offset</key><array><array><real>0.09042750298976898193359375</real><real>0.03717460110783576965332031</real><real>0.0805628001689910888671875</real></array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.09042750298976898193359375</real><real>-0.03717460110783576965332031</real><real>0.0805628001689910888671875</real></array></array><key>pelvis_offset</key><real>0</real></map><key>2a30e7ec-9840-f495-daa1-2b8d0d025a78</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceEar2Right</string><string>mFaceEar1Right</string><string>mFaceRoot</string><string>mFaceEar1Left</string><string>mFaceEar2Left</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.01427059993147850036621094</real><real>-0.01755739934742450714111328</real><real>0.0564891993999481201171875</real></array><array><real>0.004137559793889522552490234</real><real>-0.04739430174231529235839844</real><real>0.08954329788684844970703125</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>0.004137559793889522552490234</real><real>0.04739430174231529235839844</real><real>0.08954329788684844970703125</real></array><array><real>0.01427059993147850036621094</real><real>0.01755739934742450714111328</real><real>0.0564891993999481201171875</real></array></array><key>pelvis_offset</key><real>0</real></map><key>34db2e33-e79f-ea57-14af-c1ce9cbc63ff</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539470046758651733398438</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.1070009991526603698730469</real><real>0</real><real>-0.02607489936053752899169922</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.03629549965262413024902344</real><real>-0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>0.03629549965262413024902344</real><real>0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>-0.02026969939470291137695312</real><real>0</real><real>0.005331280175596475601196289</real></array><array><real>0.08300650119781494140625</real><real>0</real><real>-0.02036399953067302703857422</real></array><array><real>0.08378739655017852783203125</real><real>0</real><real>-0.02668849937617778778076172</real></array><array><real>0.03427229821681976318359375</real><real>-0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.03427229821681976318359375</real><real>0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.01811289973556995391845703</real><real>0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>0.01811289973556995391845703</real><real>-0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>-0.008231439627707004547119141</real><real>0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>-0.008231439627707004547119141</real><real>-0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>0.07319430261850357055664062</real><real>0</real><real>0.0875039994716644287109375</real></array><array><real>0.1043990030884742736816406</real><real>0</real><real>0.01717879995703697204589844</real></array><array><real>0.1504990011453628540039062</real><real>0</real><real>0.003853919915854930877685547</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.02915819920599460601806641</real><real>0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.02915819920599460601806641</real><real>-0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.01670119911432266235351562</real><real>0</real><real>0.009711739607155323028564453</real></array></array><key>pelvis_offset</key><real>0</real></map><key>3bd8d73d-be6f-8de2-39ae-1f680189bc27</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceEar2Right</string><string>mFaceEar1Right</string><string>mFaceRoot</string><string>mFaceEar1Left</string><string>mFaceEar2Left</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.01427059993147850036621094</real><real>-0.01755739934742450714111328</real><real>0.0564891993999481201171875</real></array><array><real>0.004137559793889522552490234</real><real>-0.04739430174231529235839844</real><real>0.08954329788684844970703125</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>0.004137559793889522552490234</real><real>0.04739430174231529235839844</real><real>0.08954329788684844970703125</real></array><array><real>0.01427059993147850036621094</real><real>0.01755739934742450714111328</real><real>0.0564891993999481201171875</real></array></array><key>pelvis_offset</key><real>0</real></map><key>46ee8fb2-15f0-fa2e-d260-e7e6e8295445</key><map><key>joint_names</key><array><string>mFaceJaw</string><string>mFaceRoot</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string></array><key>joint_offset</key><array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539470046758651733398438</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array></array><key>pelvis_offset</key><real>0</real></map><key>547d8392-9f19-35fb-3508-121eea388f0a</key><map><key>joint_names</key><array><string>mFaceJaw</string><string>mFaceRoot</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceTongueBase</string><string>mFaceTeethLower</string><string>mFaceTongueTip</string></array><key>joint_offset</key><array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539470046758651733398438</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>-0.02985039912164211273193359</real><real>0</real><real>0.007831689901649951934814453</real></array><array><real>0.08300650119781494140625</real><real>0</real><real>-0.02036399953067302703857422</real></array><array><real>0.0389162003993988037109375</real><real>0</real><real>-0.002775429980829358100891113</real></array></array><key>pelvis_offset</key><real>0</real></map><key>7e7a6834-8b41-4029-8f87-ce57b7d05bee</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539470046758651733398438</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.1070009991526603698730469</real><real>0</real><real>-0.02607489936053752899169922</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.03629549965262413024902344</real><real>-0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>0.03629549965262413024902344</real><real>0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>-0.02026969939470291137695312</real><real>0</real><real>0.005331280175596475601196289</real></array><array><real>0.08300650119781494140625</real><real>0</real><real>-0.02036399953067302703857422</real></array><array><real>0.08378739655017852783203125</real><real>0</real><real>-0.02668849937617778778076172</real></array><array><real>0.03427229821681976318359375</real><real>-0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.03427229821681976318359375</real><real>0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.01811289973556995391845703</real><real>0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>0.01811289973556995391845703</real><real>-0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>-0.008231439627707004547119141</real><real>0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>-0.008231439627707004547119141</real><real>-0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>0.07319430261850357055664062</real><real>0</real><real>0.0875039994716644287109375</real></array><array><real>0.1043990030884742736816406</real><real>0</real><real>0.01717879995703697204589844</real></array><array><real>0.1504990011453628540039062</real><real>0</real><real>0.003853919915854930877685547</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.02915819920599460601806641</real><real>0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.02915819920599460601806641</real><real>-0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.01670119911432266235351562</real><real>0</real><real>0.009711739607155323028564453</real></array></array><key>pelvis_offset</key><real>0</real></map><key>8665c374-cb61-d418-d412-7f4ea828e119</key><map><key>joint_names</key><array><string>mTail1</string><string>mPelvis</string><string>mTail2</string><string>mTail3</string><string>mTail4</string><string>mTail6</string><string>mTail5</string></array><key>joint_offset</key><array><array><real>-0.1659999936819076538085938</real><real>0</real><real>0.0670000016689300537109375</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>-0.1477500051259994506835938</real><real>0</real><real>0</real></array><array><real>-0.1260000020265579223632812</real><real>0</real><real>0</real></array><array><real>-0.1064999997615814208984375</real><real>0</real><real>0</real></array><array><real>-0.07050000131130218505859375</real><real>0</real><real>0</real></array><array><real>-0.08399999886751174926757812</real><real>0</real><real>0</real></array></array><key>pelvis_offset</key><real>0</real></map><key>8d23b8c8-fadf-c1b3-0b04-a3ecea292576</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceEar2Right</string><string>mFaceEar1Right</string><string>mFaceRoot</string><string>mFaceEar1Left</string><string>mFaceEar2Left</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.01427059993147850036621094</real><real>-0.01755739934742450714111328</real><real>0.0564891993999481201171875</real></array><array><real>0.004137559793889522552490234</real><real>-0.04739430174231529235839844</real><real>0.08954329788684844970703125</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>0.004137559793889522552490234</real><real>0.04739430174231529235839844</real><real>0.08954329788684844970703125</real></array><array><real>0.01427059993147850036621094</real><real>0.01755739934742450714111328</real><real>0.0564891993999481201171875</real></array></array><key>pelvis_offset</key><real>0</real></map><key>9174c7f1-bd5f-68d2-2f4f-cc9b36312067</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539649978280067443847656</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.1070009991526603698730469</real><real>0</real><real>-0.02607659995555877685546875</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.03629549965262413024902344</real><real>-0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>0.03629549965262413024902344</real><real>0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>-0.02026969939470291137695312</real><real>0</real><real>0.005331280175596475601196289</real></array><array><real>0.08300650119781494140625</real><real>0</real><real>-0.02036399953067302703857422</real></array><array><real>0.08378739655017852783203125</real><real>0</real><real>-0.02668849937617778778076172</real></array><array><real>0.03427229821681976318359375</real><real>-0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.03427229821681976318359375</real><real>0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835279867053031921386719</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835279867053031921386719</real></array><array><real>0.01811289973556995391845703</real><real>0.01673410087823867797851562</real><real>0.05700350180268287658691406</real></array><array><real>0.01811289973556995391845703</real><real>-0.01673410087823867797851562</real><real>0.05700350180268287658691406</real></array><array><real>-0.008231439627707004547119141</real><real>0.03760350123047828674316406</real><real>0.05627429857850074768066406</real></array><array><real>-0.008231439627707004547119141</real><real>-0.03760350123047828674316406</real><real>0.05627429857850074768066406</real></array><array><real>0.07319430261850357055664062</real><real>0</real><real>0.08750239759683609008789062</real></array><array><real>0.1043990030884742736816406</real><real>0</real><real>0.01717709936201572418212891</real></array><array><real>0.1504990011453628540039062</real><real>0</real><real>0.003852250054478645324707031</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835279867053031921386719</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835279867053031921386719</real></array><array><real>0.02915819920599460601806641</real><real>0.05687420070171356201171875</real><real>-0.004532460123300552368164062</real></array><array><real>0.02915819920599460601806641</real><real>-0.05687420070171356201171875</real><real>-0.004532460123300552368164062</real></array><array><real>0.01670119911432266235351562</real><real>0</real><real>0.009711739607155323028564453</real></array></array><key>pelvis_offset</key><real>0</real></map><key>92a7dd5c-bc30-9952-3b3b-e6cc10336cbe</key><map><key>joint_names</key><array><string>mEyeLeft</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mEyeRight</string></array><key>joint_offset</key><array><array><real>0.09042750298976898193359375</real><real>0.03717460110783576965332031</real><real>0.0805628001689910888671875</real></array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.09042750298976898193359375</real><real>-0.03717460110783576965332031</real><real>0.0805628001689910888671875</real></array></array><key>pelvis_offset</key><real>0</real></map><key>971cf873-afce-8b69-44d6-3f5879cb94c2</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539470046758651733398438</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.1070009991526603698730469</real><real>0</real><real>-0.02607489936053752899169922</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.03629549965262413024902344</real><real>-0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>0.03629549965262413024902344</real><real>0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>-0.02026969939470291137695312</real><real>0</real><real>0.005331280175596475601196289</real></array><array><real>0.08300650119781494140625</real><real>0</real><real>-0.02036399953067302703857422</real></array><array><real>0.08378739655017852783203125</real><real>0</real><real>-0.02668849937617778778076172</real></array><array><real>0.03427229821681976318359375</real><real>-0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.03427229821681976318359375</real><real>0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.01811289973556995391845703</real><real>0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>0.01811289973556995391845703</real><real>-0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>-0.008231439627707004547119141</real><real>0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>-0.008231439627707004547119141</real><real>-0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>0.07319430261850357055664062</real><real>0</real><real>0.0875039994716644287109375</real></array><array><real>0.1043990030884742736816406</real><real>0</real><real>0.01717879995703697204589844</real></array><array><real>0.1504990011453628540039062</real><real>0</real><real>0.003853919915854930877685547</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.02915819920599460601806641</real><real>0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.02915819920599460601806641</real><real>-0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.01670119911432266235351562</real><real>0</real><real>0.009711739607155323028564453</real></array></array><key>pelvis_offset</key><real>0</real></map><key>d0328b82-d9ca-6071-b248-17edfc7612cb</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539470046758651733398438</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.1070009991526603698730469</real><real>0</real><real>-0.02607489936053752899169922</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.03629549965262413024902344</real><real>-0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>0.03629549965262413024902344</real><real>0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>-0.02026969939470291137695312</real><real>0</real><real>0.005331280175596475601196289</real></array><array><real>0.08300650119781494140625</real><real>0</real><real>-0.02036399953067302703857422</real></array><array><real>0.08378739655017852783203125</real><real>0</real><real>-0.02668849937617778778076172</real></array><array><real>0.03427229821681976318359375</real><real>-0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.03427229821681976318359375</real><real>0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.01811289973556995391845703</real><real>0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>0.01811289973556995391845703</real><real>-0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>-0.008231439627707004547119141</real><real>0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>-0.008231439627707004547119141</real><real>-0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>0.07319430261850357055664062</real><real>0</real><real>0.0875039994716644287109375</real></array><array><real>0.1043990030884742736816406</real><real>0</real><real>0.01717879995703697204589844</real></array><array><real>0.1504990011453628540039062</real><real>0</real><real>0.003853919915854930877685547</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.02915819920599460601806641</real><real>0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.02915819920599460601806641</real><real>-0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.01670119911432266235351562</real><real>0</real><real>0.009711739607155323028564453</real></array></array><key>pelvis_offset</key><real>0</real></map><key>d2205615-2ce0-4ff1-2bfd-bdc77a3825cc</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539470046758651733398438</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.1070009991526603698730469</real><real>0</real><real>-0.02607489936053752899169922</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.03629549965262413024902344</real><real>-0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>0.03629549965262413024902344</real><real>0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>-0.02026969939470291137695312</real><real>0</real><real>0.005331280175596475601196289</real></array><array><real>0.08300650119781494140625</real><real>0</real><real>-0.02036399953067302703857422</real></array><array><real>0.08378739655017852783203125</real><real>0</real><real>-0.02668849937617778778076172</real></array><array><real>0.03427229821681976318359375</real><real>-0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.03427229821681976318359375</real><real>0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.01811289973556995391845703</real><real>0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>0.01811289973556995391845703</real><real>-0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>-0.008231439627707004547119141</real><real>0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>-0.008231439627707004547119141</real><real>-0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>0.07319430261850357055664062</real><real>0</real><real>0.0875039994716644287109375</real></array><array><real>0.1043990030884742736816406</real><real>0</real><real>0.01717879995703697204589844</real></array><array><real>0.1504990011453628540039062</real><real>0</real><real>0.003853919915854930877685547</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.02915819920599460601806641</real><real>0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.02915819920599460601806641</real><real>-0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.01670119911432266235351562</real><real>0</real><real>0.009711739607155323028564453</real></array></array><key>pelvis_offset</key><real>0</real></map><key>d73dea3b-b8cb-59ff-c76b-cfdcc8119bb5</key><map><key>joint_names</key><array><string>mFaceJaw</string><string>mFaceRoot</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string></array><key>joint_offset</key><array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539470046758651733398438</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array></array><key>pelvis_offset</key><real>0</real></map><key>e678576a-dc9f-5187-6ed5-5b4aafb65d7b</key><map><key>joint_names</key><array><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceJaw</string><string>mFaceRoot</string><string>mFaceLipUpperLeft</string><string>mFaceTeethUpper</string><string>mFaceLipUpperRight</string><string>mFaceLipCornerLeft</string><string>mFaceLipCornerRight</string><string>mFaceLipLowerCenter</string><string>mFaceTeethLower</string><string>mFaceChin</string><string>mFaceLipLowerLeft</string><string>mFaceLipLowerRight</string><string>mFaceEyeLidUpperLeft</string><string>mFaceEyeLidUpperRight</string><string>mFaceEyebrowInnerLeft</string><string>mFaceEyebrowInnerRight</string><string>mFaceEyebrowCenterLeft</string><string>mFaceEyebrowCenterRight</string><string>mFaceForeheadCenter</string><string>mFaceNoseBridge</string><string>mFaceNoseBase</string><string>mFaceEyeLidLowerLeft</string><string>mFaceEyeLidLowerRight</string><string>mFaceCheekUpperLeft</string><string>mFaceCheekUpperRight</string><string>mFaceLipUpperCenter</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.03598750010132789611816406</real><real>0</real><real>-0.02539470046758651733398438</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.1070009991526603698730469</real><real>0</real><real>-0.02607489936053752899169922</real></array><array><real>-0.0591681003570556640625</real><real>0</real><real>0.00485086021944880485534668</real></array><array><real>0.03629549965262413024902344</real><real>-0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>0.03629549965262413024902344</real><real>0.01899999938905239105224609</real><real>-0.01348599977791309356689453</real></array><array><real>-0.02026969939470291137695312</real><real>0</real><real>0.005331280175596475601196289</real></array><array><real>0.08300650119781494140625</real><real>0</real><real>-0.02036399953067302703857422</real></array><array><real>0.08378739655017852783203125</real><real>0</real><real>-0.02668849937617778778076172</real></array><array><real>0.03427229821681976318359375</real><real>-0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.03427229821681976318359375</real><real>0.01206200011074542999267578</real><real>0.0005108119803480803966522217</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.01811289973556995391845703</real><real>0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>0.01811289973556995391845703</real><real>-0.01673410087823867797851562</real><real>0.05700530111789703369140625</real></array><array><real>-0.008231439627707004547119141</real><real>0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>-0.008231439627707004547119141</real><real>-0.03760350123047828674316406</real><real>0.05627600103616714477539062</real></array><array><real>0.07319430261850357055664062</real><real>0</real><real>0.0875039994716644287109375</real></array><array><real>0.1043990030884742736816406</real><real>0</real><real>0.01717879995703697204589844</real></array><array><real>0.1504990011453628540039062</real><real>0</real><real>0.003853919915854930877685547</real></array><array><real>0.0449016988277435302734375</real><real>0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.0449016988277435302734375</real><real>-0.03697630017995834350585938</real><real>0.03835450112819671630859375</real></array><array><real>0.02915819920599460601806641</real><real>0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.02915819920599460601806641</real><real>-0.05687420070171356201171875</real><real>-0.004530789796262979507446289</real></array><array><real>0.01670119911432266235351562</real><real>0</real><real>0.009711739607155323028564453</real></array></array><key>pelvis_offset</key><real>0</real></map><key>ed796a27-cff0-454a-ecec-fd10794ca2c9</key><map><key>joint_names</key><array><string>mFaceNoseBase</string><string>mFaceRoot</string><string>mHead</string><string>mNeck</string><string>mChest</string><string>mTorso</string><string>mPelvis</string><string>mFaceLipUpperCenter</string><string>mFaceTeethUpper</string></array><key>joint_offset</key><array><array><real>0.1504990011453628540039062</real><real>0</real><real>0.003853919915854930877685547</real></array><array><real>0.02500000037252902984619141</real><real>0</real><real>0.04500000178813934326171875</real></array><array><real>0</real><real>0</real><real>0.07562989741563796997070312</real></array><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array><array><real>0</real><real>0</real><real>0.08407290279865264892578125</real></array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.01670119911432266235351562</real><real>0</real><real>0.009711739607155323028564453</real></array><array><real>0.1070009991526603698730469</real><real>0</real><real>-0.02607489936053752899169922</real></array></array><key>pelvis_offset</key><real>0</real></map><key>fa0aabfe-4b1c-fa9b-4942-74e7e7f50fe2</key><map><key>joint_names</key><array><string>mPelvis</string><string>mHandMiddle1Left</string><string>mHandMiddle2Left</string><string>mHandMiddle3Left</string><string>mHandIndex1Left</string><string>mHandIndex2Left</string><string>mHandIndex3Left</string><string>mHandRing1Left</string><string>mHandRing2Left</string><string>mHandRing3Left</string><string>mHandPinky1Left</string><string>mHandPinky2Left</string><string>mHandPinky3Left</string><string>mHandThumb1Left</string><string>mHandThumb2Left</string><string>mHandThumb3Left</string><string>mHandMiddle1Right</string><string>mHandMiddle2Right</string><string>mHandMiddle3Right</string><string>mHandIndex1Right</string><string>mHandIndex2Right</string><string>mHandIndex3Right</string><string>mHandRing1Right</string><string>mHandRing2Right</string><string>mHandRing3Right</string><string>mHandPinky1Right</string><string>mHandPinky2Right</string><string>mHandPinky3Right</string><string>mHandThumb1Right</string><string>mHandThumb2Right</string><string>mHandThumb3Right</string></array><key>joint_offset</key><array><array><real>0</real><real>0</real><real>1.06702005863189697265625</real></array><array><real>0.01518869958817958831787109</real><real>0.09894219785928726196289062</real><real>0.01042949967086315155029297</real></array><array><real>-0.001050560036674141883850098</real><real>0.04202070087194442749023438</real><real>-0.006302990019321441650390625</real></array><array><real>-0.0005042509874328970909118652</real><real>0.02471089921891689300537109</real><real>-0.004034650046378374099731445</real></array><array><real>0.03427390009164810180664062</real><real>0.0946806967258453369140625</real><real>0.009629939682781696319580078</real></array><array><real>0.01719100028276443481445312</real><real>0.03640490025281906127929688</real><real>-0.006067920010536909103393555</real></array><array><real>0.01021370012313127517700195</real><real>0.02334530092775821685791016</real><real>-0.004377489909529685974121094</real></array><array><real>-0.003647640114650130271911621</real><real>0.096580803394317626953125</real><real>0.004405209794640541076660156</real></array><array><real>-0.01231530029326677322387695</real><real>0.03599850088357925415039062</real><real>-0.007578520104289054870605469</real></array><array><real>-0.006562709808349609375</real><real>0.02019299939274787902832031</real><real>-0.00454388977959752082824707</real></array><array><real>-0.02321339957416057586669922</real><real>0.08812329918146133422851562</real><real>-0.004173850174993276596069336</real></array><array><real>-0.02226779982447624206542969</real><real>0.02319590002298355102539062</real><real>-0.005566920153796672821044922</real></array><array><real>-0.0124367000535130500793457</real><real>0.01492409966886043548583984</real><real>-0.003316479967907071113586426</real></array><array><real>0.03221559897065162658691406</real><real>0.02088090032339096069335938</real><real>-0.008553059771656990051269531</real></array><array><real>0.02945099957287311553955078</real><real>0.03365840017795562744140625</real><real>-0.001052020001225173473358154</real></array><array><real>0.02092489972710609436035156</real><real>0.02820369973778724670410156</real><real>-0.0009096220019273459911346436</real></array><array><real>0.01518869958817958831787109</real><real>-0.09894219785928726196289062</real><real>0.01042949967086315155029297</real></array><array><real>-0.001050550024956464767456055</real><real>-0.04202080145478248596191406</real><real>-0.006302880123257637023925781</real></array><array><real>-0.0005042660050094127655029297</real><real>-0.02471089921891689300537109</real><real>-0.004034659825265407562255859</real></array><array><real>0.03427390009164810180664062</real><real>-0.0946806967258453369140625</real><real>0.009629939682781696319580078</real></array><array><real>0.01719100028276443481445312</real><real>-0.03640500083565711975097656</real><real>-0.006067819893360137939453125</real></array><array><real>0.01021370012313127517700195</real><real>-0.02334530092775821685791016</real><real>-0.004377489909529685974121094</real></array><array><real>-0.003647640114650130271911621</real><real>-0.096580803394317626953125</real><real>0.004405209794640541076660156</real></array><array><real>-0.01231530029326677322387695</real><real>-0.03599840030074119567871094</real><real>-0.007578390184789896011352539</real></array><array><real>-0.006562769878655672073364258</real><real>-0.02019290067255496978759766</real><real>-0.004543649964034557342529297</real></array><array><real>-0.02321339957416057586669922</real><real>-0.08812329918146133422851562</real><real>-0.004173850174993276596069336</real></array><array><real>-0.02226779982447624206542969</real><real>-0.02319570071995258331298828</real><real>-0.005566900130361318588256836</real></array><array><real>-0.01243660040199756622314453</real><real>-0.01492400001734495162963867</real><real>-0.003316730028018355369567871</real></array><array><real>0.03221559897065162658691406</real><real>-0.02088090032339096069335938</real><real>-0.008553059771656990051269531</real></array><array><real>0.02945090085268020629882812</real><real>-0.03365840017795562744140625</real><real>-0.001052099978551268577575684</real></array><array><real>0.02092500030994415283203125</real><real>-0.02820380032062530517578125</real><real>-0.0009097899892367422580718994</real></array></array><key>pelvis_offset</key><real>0</real></map></map><key>success</key><boolean>1</boolean></map></llsd>
diff --git a/indra/llappearanceutility/tests/params.xml b/indra/llappearanceutility/tests/params.xml
new file mode 100644
index 0000000000..7d7ff646b7
--- /dev/null
+++ b/indra/llappearanceutility/tests/params.xml
@@ -0,0 +1,1140 @@
+<?xml version="1.0" ?>
+<llsd>
+<map>
+ <key>skindata</key>
+ <map>
+ <key>270bb701-8643-c4b3-6a93-7a2b6503b30a</key>
+ <map>
+ <key>joint_names</key>
+ <array>
+ <string>mTail1</string>
+ <string>mPelvis</string>
+ <string>mTail2</string>
+ <string>mTorso</string>
+ <string>mSpine2</string>
+ <string>mSpine1</string>
+ <string>mHipLeft</string>
+ <string>mKneeLeft</string>
+ <string>mHipRight</string>
+ <string>mKneeRight</string>
+ <string>mChest</string>
+ <string>mSpine4</string>
+ <string>mSpine3</string>
+ <string>mShoulderRight</string>
+ <string>mCollarRight</string>
+ <string>mShoulderLeft</string>
+ <string>mCollarLeft</string>
+ <string>mElbowRight</string>
+ <string>mElbowLeft</string>
+ <string>mNeck</string>
+ <string>mAnkleRight</string>
+ <string>mAnkleLeft</string>
+ </array>
+ <key>joint_offset</key>
+ <array>
+ <array>
+ <real>-0.12795400619506836</real>
+ <real>0.0</real>
+ <real>0.001858999952673912</real>
+ </array>
+ <array>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>1.081987977027893</real>
+ </array>
+ <array>
+ <real>-0.018850000575184822</real>
+ <real>0.0</real>
+ <real>-0.09493499994277954</real>
+ </array>
+ <array>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>0.08407299965620041</real>
+ </array>
+ <array>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>-0.08407299965620041</real>
+ </array>
+ <array>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>0.08407299965620041</real>
+ </array>
+ <array>
+ <real>0.03375700116157532</real>
+ <real>0.12676499783992767</real>
+ <real>-0.04099800065159798</real>
+ </array>
+ <array>
+ <real>-0.0008870000019669533</real>
+ <real>-0.04556800052523613</real>
+ <real>-0.4910529851913452</real>
+ </array>
+ <array>
+ <real>0.03361999988555908</real>
+ <real>-0.1288059949874878</real>
+ <real>-0.041085999459028244</real>
+ </array>
+ <array>
+ <real>-0.0007800000021234155</real>
+ <real>0.04863499850034714</real>
+ <real>-0.4909220039844513</real>
+ </array>
+ <array>
+ <real>-0.01536799967288971</real>
+ <real>0.0</real>
+ <real>0.20487700402736664</real>
+ </array>
+ <array>
+ <real>0.01536799967288971</real>
+ <real>0.0</real>
+ <real>-0.20487700402736664</real>
+ </array>
+ <array>
+ <real>-0.01536799967288971</real>
+ <real>0.0</real>
+ <real>0.20487700402736664</real>
+ </array>
+ <array>
+ <real>0.0</real>
+ <real>-0.07941800355911255</real>
+ <real>0.0</real>
+ </array>
+ <array>
+ <real>-0.020927000790834427</real>
+ <real>-0.08500000089406967</real>
+ <real>0.16539600491523743</real>
+ </array>
+ <array>
+ <real>0.0</real>
+ <real>0.07900000363588333</real>
+ <real>0.0</real>
+ </array>
+ <array>
+ <real>-0.020927000790834427</real>
+ <real>0.08466500043869019</real>
+ <real>0.16539600491523743</real>
+ </array>
+ <array>
+ <real>0.0</real>
+ <real>-0.24799999594688416</real>
+ <real>0.0</real>
+ </array>
+ <array>
+ <real>0.0</real>
+ <real>0.24799999594688416</real>
+ <real>0.0</real>
+ </array>
+ <array>
+ <real>-0.00950700044631958</real>
+ <real>0.0</real>
+ <real>0.25110799074172974</real>
+ </array>
+ <array>
+ <real>-0.02886899933218956</real>
+ <real>0.0</real>
+ <real>-0.4684939980506897</real>
+ </array>
+ <array>
+ <real>-0.028886999934911728</real>
+ <real>0.0013780000153928995</real>
+ <real>-0.4684489965438843</real>
+ </array>
+ </array>
+ <key>pelvis_offset</key>
+ <real>0.0</real>
+ </map>
+ </map>
+ <key>wearables</key>
+ <array>
+ <array>
+ <map>
+ <key>agent_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>asset_id</key>
+ <string>7e3e76fc-7fa4-ec8f-a785-8956dbce6e72</string>
+ <key>contents</key>
+ <string>LLWearable version 22
+Fashionista Male - Shape (new)
+
+ permissions 0
+ {
+ base_mask 7fffffff
+ owner_mask 7fffffff
+ group_mask 00000000
+ everyone_mask 00000000
+ next_owner_mask 00082000
+ creator_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ owner_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ last_owner_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ group_id 00000000-0000-0000-0000-000000000000
+ }
+ sale_info 0
+ {
+ sale_type not
+ sale_price 10
+ }
+type 0
+parameters 142
+1 0
+2 .16
+4 -.23
+5 -.1
+6 -.3
+7 0
+8 0
+10 0
+11 .04
+12 0
+13 0
+14 0
+15 0
+17 0
+18 0
+19 -.1
+20 .56
+21 .07
+22 0
+23 .42
+24 -.66
+25 .51
+26 0
+27 .02
+28 .6
+29 0
+30 0
+32 1
+33 -.41
+34 .4
+35 0
+36 -.49
+37 0
+38 .42
+40 1
+80 1
+100 1
+104 0
+105 .5
+106 0
+107 0
+151 .16
+152 0
+153 1
+155 -.13
+156 0
+157 0
+185 -.44
+186 0
+187 0
+188 0
+189 0
+193 .5
+194 -.12
+195 -.06
+196 -.59
+505 .65
+506 -.04
+507 0
+515 -.2
+517 .12
+518 -.3
+626 0
+627 0
+629 .5
+630 0
+631 0
+633 .01
+634 .01
+635 .01
+637 .01
+646 0
+647 0
+648 0
+649 .5
+650 -.67
+651 .03
+652 .49
+653 .26
+655 -.08
+656 0
+657 .03
+658 0
+659 .51
+660 0
+661 0
+662 .5
+663 -.2
+664 .13
+665 .04
+675 .03
+676 -.43
+677 .34
+678 .37
+679 -.08
+680 -.08
+681 -.08
+682 .5
+683 -.14
+684 0
+685 .14
+686 -.68
+687 -.09
+688 -.09
+689 -.34
+690 .33
+691 -.09
+692 .24
+693 .1
+694 -.08
+695 -.09
+753 .06
+756 -.08
+758 -1.05
+759 .67
+760 0
+764 -.5
+765 1.02
+767 .08
+768 .08
+769 .52
+770 0
+772 0
+773 .5
+794 0
+795 .41
+796 0
+797 .15
+798 0
+799 .45
+841 0
+842 -.8
+843 0
+853 0
+854 .06
+855 -.43
+879 -.1
+880 -.82
+1103 0
+1104 0
+1105 0
+11001 0
+textures 0
+</string>
+ <key>created_at</key>
+ <integer>1724256027</integer>
+ <key>desc</key>
+ <string />
+ <key>flags</key>
+ <integer>256</integer>
+ <key>inv_type</key>
+ <integer>18</integer>
+ <key>item_id</key>
+ <string>8bbf11b0-b86b-3b4c-8c5c-c84902425f42</string>
+ <key>metadata</key>
+ <map>
+ </map>
+ <key>name</key>
+ <string>Leonard - Shape</string>
+ <key>parent_id</key>
+ <string>056f26cf-a9d9-39b9-a90c-f7b0fcd92347</string>
+ <key>permissions</key>
+ <map>
+ <key>base_mask</key>
+ <integer>573440</integer>
+ <key>creator_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>everyone_mask</key>
+ <integer>524288</integer>
+ <key>group_id</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ <key>group_mask</key>
+ <integer>540672</integer>
+ <key>last_owner_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>next_owner_mask</key>
+ <integer>573440</integer>
+ <key>owner_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>owner_mask</key>
+ <integer>573440</integer>
+ </map>
+ <key>sale_info</key>
+ <map>
+ <key>sale_price</key>
+ <integer>10</integer>
+ <key>sale_type</key>
+ <integer>0</integer>
+ </map>
+ <key>type</key>
+ <integer>13</integer>
+ <key>wearable_type</key>
+ <integer>0</integer>
+ </map>
+ </array>
+ <array>
+ <map>
+ <key>agent_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>asset_id</key>
+ <string>9e675544-77c0-0db6-3694-462be7460b76</string>
+ <key>contents</key>
+ <string>LLWearable version 22
+Formal Male - Skin (less old)
+
+ permissions 0
+ {
+ base_mask 7fffffff
+ owner_mask 7fffffff
+ group_mask 00000000
+ everyone_mask 00000000
+ next_owner_mask 00082000
+ creator_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ owner_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ last_owner_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ group_id 00000000-0000-0000-0000-000000000000
+ }
+ sale_info 0
+ {
+ sale_type not
+ sale_price 10
+ }
+type 1
+parameters 37
+108 0
+110 0
+111 0
+116 0
+117 0
+118 0
+125 0
+126 0
+150 0
+158 0
+159 0
+161 0
+162 0
+163 0
+165 0
+700 .25
+701 0
+702 0
+703 0
+704 0
+705 .5
+706 .6
+707 0
+708 0
+709 0
+710 0
+711 .5
+712 0
+713 .7
+714 0
+715 0
+775 0
+776 0
+777 0
+873 0
+874 0
+878 0
+textures 3
+0 a21d4081-601e-f9f0-0acc-9192c72863dc
+5 a85bf749-952d-3835-d9ac-a307c780930c
+6 ab169525-d46c-918b-3195-7f2b92fd76c5
+</string>
+ <key>created_at</key>
+ <integer>1724256027</integer>
+ <key>desc</key>
+ <string />
+ <key>flags</key>
+ <integer>257</integer>
+ <key>inv_type</key>
+ <integer>18</integer>
+ <key>item_id</key>
+ <string>9e6c5696-cae0-337e-a5c6-aa6fede08ec6</string>
+ <key>metadata</key>
+ <map>
+ </map>
+ <key>name</key>
+ <string>Leonard - Skin</string>
+ <key>parent_id</key>
+ <string>056f26cf-a9d9-39b9-a90c-f7b0fcd92347</string>
+ <key>permissions</key>
+ <map>
+ <key>base_mask</key>
+ <integer>557056</integer>
+ <key>creator_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>everyone_mask</key>
+ <integer>524288</integer>
+ <key>group_id</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ <key>group_mask</key>
+ <integer>524288</integer>
+ <key>last_owner_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>next_owner_mask</key>
+ <integer>557056</integer>
+ <key>owner_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>owner_mask</key>
+ <integer>557056</integer>
+ </map>
+ <key>sale_info</key>
+ <map>
+ <key>sale_price</key>
+ <integer>10</integer>
+ <key>sale_type</key>
+ <integer>0</integer>
+ </map>
+ <key>type</key>
+ <integer>13</integer>
+ <key>wearable_type</key>
+ <integer>1</integer>
+ </map>
+ </array>
+ <array>
+ <map>
+ <key>agent_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>asset_id</key>
+ <string>0b935621-92da-099e-a248-cfbfa3624c68</string>
+ <key>contents</key>
+ <string>LLWearable version 22
+Fashionista Male - Brows (new)
+
+ permissions 0
+ {
+ base_mask 00082000
+ owner_mask 00082000
+ group_mask 00000000
+ everyone_mask 00000000
+ next_owner_mask 00082000
+ creator_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ owner_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ last_owner_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ group_id 00000000-0000-0000-0000-000000000000
+ }
+ sale_info 0
+ {
+ sale_type not
+ sale_price 10
+ }
+type 2
+parameters 90
+16 .41
+31 1.04
+112 0
+113 0
+114 0
+115 0
+119 .5
+130 0
+131 0
+132 0
+133 0
+134 0
+135 0
+136 0
+137 .5
+140 0
+141 0
+142 0
+143 -4
+144 1
+145 0
+146 1
+147 0
+148 1
+149 0
+166 0
+167 0
+168 0
+169 0
+171 0
+172 1
+173 0
+174 1
+175 0
+176 1
+177 0
+178 0
+179 1
+180 0
+181 -1
+182 -1
+183 -1
+184 0
+190 0
+191 0
+192 0
+400 .75
+640 -.01
+641 .2
+642 0
+643 0
+644 .24
+645 0
+674 -.3
+750 .65
+751 0
+752 .5
+754 0
+755 .05
+757 -1.6
+761 1.3
+762 0
+763 0
+771 -.08
+774 0
+782 0
+783 0
+784 0
+785 0
+786 0
+787 0
+788 0
+789 0
+790 0
+870 -.11
+871 -.4
+872 .52
+1000 .5
+1001 .5
+1002 .65
+1003 .65
+1004 0
+1005 0
+1006 0
+1007 0
+1008 0
+1009 0
+1010 0
+1011 0
+1012 .25
+textures 1
+4 3cc3add8-6ff0-0640-79ba-b15137f64008
+</string>
+ <key>created_at</key>
+ <integer>1724256027</integer>
+ <key>desc</key>
+ <string />
+ <key>flags</key>
+ <integer>258</integer>
+ <key>inv_type</key>
+ <integer>18</integer>
+ <key>item_id</key>
+ <string>3ddd2d41-fbe4-3076-9732-c5f3b12973b1</string>
+ <key>metadata</key>
+ <map>
+ </map>
+ <key>name</key>
+ <string>Leonard - Brows</string>
+ <key>parent_id</key>
+ <string>056f26cf-a9d9-39b9-a90c-f7b0fcd92347</string>
+ <key>permissions</key>
+ <map>
+ <key>base_mask</key>
+ <integer>557056</integer>
+ <key>creator_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>everyone_mask</key>
+ <integer>524288</integer>
+ <key>group_id</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ <key>group_mask</key>
+ <integer>524288</integer>
+ <key>last_owner_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>next_owner_mask</key>
+ <integer>557056</integer>
+ <key>owner_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>owner_mask</key>
+ <integer>557056</integer>
+ </map>
+ <key>sale_info</key>
+ <map>
+ <key>sale_price</key>
+ <integer>10</integer>
+ <key>sale_type</key>
+ <integer>0</integer>
+ </map>
+ <key>type</key>
+ <integer>13</integer>
+ <key>wearable_type</key>
+ <integer>2</integer>
+ </map>
+ </array>
+ <array>
+ <map>
+ <key>agent_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>asset_id</key>
+ <string>052ca46d-9612-7a43-25a9-d7c8a5387cf6</string>
+ <key>contents</key>
+ <string>LLWearable version 22
+Fashionista Male - Eyes
+
+ permissions 0
+ {
+ base_mask 7fffffff
+ owner_mask 7fffffff
+ group_mask 00000000
+ everyone_mask 00000000
+ next_owner_mask 00082000
+ creator_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ owner_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ last_owner_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ group_id 00000000-0000-0000-0000-000000000000
+ }
+ sale_info 0
+ {
+ sale_type not
+ sale_price 10
+ }
+type 3
+parameters 2
+98 1
+99 0
+textures 1
+3 579e320c-0f16-2a1d-2018-2a00cc657068
+</string>
+ <key>created_at</key>
+ <integer>1724256027</integer>
+ <key>desc</key>
+ <string />
+ <key>flags</key>
+ <integer>259</integer>
+ <key>inv_type</key>
+ <integer>18</integer>
+ <key>item_id</key>
+ <string>9d4e7072-0e92-39a1-95a4-b5330450b1ee</string>
+ <key>metadata</key>
+ <map>
+ </map>
+ <key>name</key>
+ <string>Leonard - Eyes</string>
+ <key>parent_id</key>
+ <string>056f26cf-a9d9-39b9-a90c-f7b0fcd92347</string>
+ <key>permissions</key>
+ <map>
+ <key>base_mask</key>
+ <integer>557056</integer>
+ <key>creator_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>everyone_mask</key>
+ <integer>524288</integer>
+ <key>group_id</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ <key>group_mask</key>
+ <integer>524288</integer>
+ <key>last_owner_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>next_owner_mask</key>
+ <integer>557056</integer>
+ <key>owner_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>owner_mask</key>
+ <integer>557056</integer>
+ </map>
+ <key>sale_info</key>
+ <map>
+ <key>sale_price</key>
+ <integer>10</integer>
+ <key>sale_type</key>
+ <integer>0</integer>
+ </map>
+ <key>type</key>
+ <integer>13</integer>
+ <key>wearable_type</key>
+ <integer>3</integer>
+ </map>
+ </array>
+ <array>
+ </array>
+ <array>
+ </array>
+ <array>
+ <map>
+ <key>agent_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>asset_id</key>
+ <string>5f049939-bb34-ad27-66cb-38c9151a105d</string>
+ <key>contents</key>
+ <string>LLWearable version 22
+Fashionista Male - Shoe Base
+
+ permissions 0
+ {
+ base_mask 7fffffff
+ owner_mask 7fffffff
+ group_mask 00000000
+ everyone_mask 00000000
+ next_owner_mask 00082000
+ creator_id 73ecef5a-3110-4e95-92bc-da0ae7598652
+ owner_id 73ecef5a-3110-4e95-92bc-da0ae7598652
+ last_owner_id 73ecef5a-3110-4e95-92bc-da0ae7598652
+ group_id 00000000-0000-0000-0000-000000000000
+ }
+ sale_info 0
+ {
+ sale_type not
+ sale_price 10
+ }
+type 6
+parameters 20
+197 0
+198 0
+500 0
+501 .1
+502 .1
+503 .1
+508 -.52
+509 1
+510 0
+511 .82
+512 0
+513 0
+514 .09
+616 .3
+654 .06
+812 1
+813 1
+817 1
+1052 .3
+1053 .3
+textures 1
+7 8dcd4a48-2d37-4909-9f78-f7a9eb4ef903
+</string>
+ <key>created_at</key>
+ <integer>1724256027</integer>
+ <key>desc</key>
+ <string>@600</string>
+ <key>flags</key>
+ <integer>262</integer>
+ <key>inv_type</key>
+ <integer>18</integer>
+ <key>item_id</key>
+ <string>dc5e279a-4a34-36ee-9075-028df446392c</string>
+ <key>metadata</key>
+ <map>
+ </map>
+ <key>name</key>
+ <string>Leonard - Shoes BASE</string>
+ <key>parent_id</key>
+ <string>056f26cf-a9d9-39b9-a90c-f7b0fcd92347</string>
+ <key>permissions</key>
+ <map>
+ <key>base_mask</key>
+ <integer>557056</integer>
+ <key>creator_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>everyone_mask</key>
+ <integer>524288</integer>
+ <key>group_id</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ <key>group_mask</key>
+ <integer>524288</integer>
+ <key>last_owner_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>next_owner_mask</key>
+ <integer>557056</integer>
+ <key>owner_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>owner_mask</key>
+ <integer>557056</integer>
+ </map>
+ <key>sale_info</key>
+ <map>
+ <key>sale_price</key>
+ <integer>10</integer>
+ <key>sale_type</key>
+ <integer>0</integer>
+ </map>
+ <key>type</key>
+ <integer>5</integer>
+ <key>wearable_type</key>
+ <integer>6</integer>
+ </map>
+ </array>
+ <array>
+ </array>
+ <array>
+ </array>
+ <array>
+ </array>
+ <array>
+ </array>
+ <array>
+ </array>
+ <array>
+ </array>
+ <array>
+ <map>
+ <key>agent_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>asset_id</key>
+ <string>ab0bd2c6-3776-7ea6-264f-102842c6328b</string>
+ <key>contents</key>
+ <string>LLWearable version 22
+Fashionista Female - Heels Alpha
+
+ permissions 0
+ {
+ base_mask 7fffffff
+ owner_mask 7fffffff
+ group_mask 00000000
+ everyone_mask 00000000
+ next_owner_mask 00082000
+ creator_id 73ecef5a-3110-4e95-92bc-da0ae7598652
+ owner_id 73ecef5a-3110-4e95-92bc-da0ae7598652
+ last_owner_id 73ecef5a-3110-4e95-92bc-da0ae7598652
+ group_id 00000000-0000-0000-0000-000000000000
+ }
+ sale_info 0
+ {
+ sale_type not
+ sale_price 10
+ }
+type 13
+parameters 0
+textures 5
+21 b5b09502-8305-af43-cc4e-7238cb715b11
+22 5748decc-f629-461c-9a36-a35a221fe21f
+23 5748decc-f629-461c-9a36-a35a221fe21f
+24 5748decc-f629-461c-9a36-a35a221fe21f
+25 5748decc-f629-461c-9a36-a35a221fe21f
+</string>
+ <key>created_at</key>
+ <integer>1724256027</integer>
+ <key>desc</key>
+ <string>@1300</string>
+ <key>flags</key>
+ <integer>269</integer>
+ <key>inv_type</key>
+ <integer>18</integer>
+ <key>item_id</key>
+ <string>b76dde5f-0da2-3e21-b505-d587b16ddb3c</string>
+ <key>metadata</key>
+ <map>
+ </map>
+ <key>name</key>
+ <string>Leonard - Shoes ALPHA</string>
+ <key>parent_id</key>
+ <string>056f26cf-a9d9-39b9-a90c-f7b0fcd92347</string>
+ <key>permissions</key>
+ <map>
+ <key>base_mask</key>
+ <integer>557056</integer>
+ <key>creator_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>everyone_mask</key>
+ <integer>524288</integer>
+ <key>group_id</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ <key>group_mask</key>
+ <integer>524288</integer>
+ <key>last_owner_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>next_owner_mask</key>
+ <integer>557056</integer>
+ <key>owner_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>owner_mask</key>
+ <integer>557056</integer>
+ </map>
+ <key>sale_info</key>
+ <map>
+ <key>sale_price</key>
+ <integer>10</integer>
+ <key>sale_type</key>
+ <integer>0</integer>
+ </map>
+ <key>type</key>
+ <integer>5</integer>
+ <key>wearable_type</key>
+ <integer>13</integer>
+ </map>
+ <map>
+ <key>agent_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>asset_id</key>
+ <string>cb80f44f-8265-f56b-c812-ddf729cee73b</string>
+ <key>contents</key>
+ <string>LLWearable version 22
+New Alpha
+
+ permissions 0
+ {
+ base_mask 7fffffff
+ owner_mask 7fffffff
+ group_mask 00000000
+ everyone_mask 00000000
+ next_owner_mask 00082000
+ creator_id 8b1453d6-ec45-4434-bee3-1c4d6fe1bc55
+ owner_id 8b1453d6-ec45-4434-bee3-1c4d6fe1bc55
+ last_owner_id 8b1453d6-ec45-4434-bee3-1c4d6fe1bc55
+ group_id 00000000-0000-0000-0000-000000000000
+ }
+ sale_info 0
+ {
+ sale_type not
+ sale_price 10
+ }
+type 13
+parameters 0
+textures 5
+21 d9413239-769d-abc9-e929-4fa98f52c07b
+22 b5d465f9-ca8e-8ba4-efd8-ee8929c592b8
+23 5748decc-f629-461c-9a36-a35a221fe21f
+24 5748decc-f629-461c-9a36-a35a221fe21f
+25 5748decc-f629-461c-9a36-a35a221fe21f
+</string>
+ <key>created_at</key>
+ <integer>1724256027</integer>
+ <key>desc</key>
+ <string>@1301</string>
+ <key>flags</key>
+ <integer>269</integer>
+ <key>inv_type</key>
+ <integer>18</integer>
+ <key>item_id</key>
+ <string>efc7da55-02ba-3286-8458-780aede51b49</string>
+ <key>metadata</key>
+ <map>
+ </map>
+ <key>name</key>
+ <string>Leonard - Suit Alpha</string>
+ <key>parent_id</key>
+ <string>056f26cf-a9d9-39b9-a90c-f7b0fcd92347</string>
+ <key>permissions</key>
+ <map>
+ <key>base_mask</key>
+ <integer>557056</integer>
+ <key>creator_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>everyone_mask</key>
+ <integer>524288</integer>
+ <key>group_id</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ <key>group_mask</key>
+ <integer>524288</integer>
+ <key>last_owner_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>next_owner_mask</key>
+ <integer>557056</integer>
+ <key>owner_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>owner_mask</key>
+ <integer>557056</integer>
+ </map>
+ <key>sale_info</key>
+ <map>
+ <key>sale_price</key>
+ <integer>10</integer>
+ <key>sale_type</key>
+ <integer>0</integer>
+ </map>
+ <key>type</key>
+ <integer>5</integer>
+ <key>wearable_type</key>
+ <integer>13</integer>
+ </map>
+ <map>
+ <key>agent_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>asset_id</key>
+ <string>f235a6a9-062a-bb40-46c2-c8a7bec95fbf</string>
+ <key>contents</key>
+ <string>LLWearable version 22
+System Eyelash Remover
+
+ permissions 0
+ {
+ base_mask 7fffffff
+ owner_mask 7fffffff
+ group_mask 00000000
+ everyone_mask 00000000
+ next_owner_mask 00082000
+ creator_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ owner_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ last_owner_id 1f8f7642-ce98-4d1b-9314-e2bc98b6538d
+ group_id 00000000-0000-0000-0000-000000000000
+ }
+ sale_info 0
+ {
+ sale_type not
+ sale_price 10
+ }
+type 13
+parameters 0
+textures 5
+21 5748decc-f629-461c-9a36-a35a221fe21f
+22 5748decc-f629-461c-9a36-a35a221fe21f
+23 9e460914-daed-b03f-0f2a-afbe67833b11
+24 5748decc-f629-461c-9a36-a35a221fe21f
+25 5748decc-f629-461c-9a36-a35a221fe21f
+</string>
+ <key>created_at</key>
+ <integer>1724256027</integer>
+ <key>desc</key>
+ <string>@1302</string>
+ <key>flags</key>
+ <integer>269</integer>
+ <key>inv_type</key>
+ <integer>18</integer>
+ <key>item_id</key>
+ <string>624f9c12-72e8-3409-a3f3-b3fe8f496b13</string>
+ <key>metadata</key>
+ <map>
+ </map>
+ <key>name</key>
+ <string>System Eyelash Remover</string>
+ <key>parent_id</key>
+ <string>056f26cf-a9d9-39b9-a90c-f7b0fcd92347</string>
+ <key>permissions</key>
+ <map>
+ <key>base_mask</key>
+ <integer>557056</integer>
+ <key>creator_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>everyone_mask</key>
+ <integer>524288</integer>
+ <key>group_id</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ <key>group_mask</key>
+ <integer>524288</integer>
+ <key>last_owner_id</key>
+ <string>ba2a564a-f0f1-4b82-9c61-b7520bfcd09f</string>
+ <key>next_owner_mask</key>
+ <integer>557056</integer>
+ <key>owner_id</key>
+ <string>de494a4f-f01a-47a4-98cf-c94ef9ecca38</string>
+ <key>owner_mask</key>
+ <integer>557056</integer>
+ </map>
+ <key>sale_info</key>
+ <map>
+ <key>sale_price</key>
+ <integer>10</integer>
+ <key>sale_type</key>
+ <integer>0</integer>
+ </map>
+ <key>type</key>
+ <integer>5</integer>
+ <key>wearable_type</key>
+ <integer>13</integer>
+ </map>
+ </array>
+ <array>
+ </array>
+ <array>
+ </array>
+ <array>
+ </array>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/llappearanceutility/tests/params.xml.output b/indra/llappearanceutility/tests/params.xml.output
new file mode 100644
index 0000000000..58449dd37a
--- /dev/null
+++ b/indra/llappearanceutility/tests/params.xml.output
@@ -0,0 +1 @@
+<llsd><map><key>avatar_scale</key><array><real>0.449999988079071044921875</real><real>0.60000002384185791015625</real><real>1.76146829128265380859375</real></array><key>debug_params</key><map><key>1</key><map><key>name</key><string>big_brow</string><key>value</key><real>0</real><key>weight</key><integer>33</integer></map><key>10</key><map><key>name</key><string>sunken_cheeks</string><key>value</key><real>0</real><key>weight</key><integer>85</integer></map><key>10000</key><map><key>name</key><string>breast_physics_mass</string><key>value</key><real>0.1000000014901161193847656</real><key>weight</key><integer>0</integer></map><key>10001</key><map><key>name</key><string>breast_physics_gravity</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>10002</key><map><key>name</key><string>breast_physics_drag</string><key>value</key><real>1</real><key>weight</key><integer>25</integer></map><key>10003</key><map><key>name</key><string>breast_physics_updown_max_effect</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>10004</key><map><key>name</key><string>breast_physics_updown_spring</string><key>value</key><real>10</real><key>weight</key><integer>25</integer></map><key>10005</key><map><key>name</key><string>breast_physics_updown_gain</string><key>value</key><real>10</real><key>weight</key><integer>23</integer></map><key>10006</key><map><key>name</key><string>breast_physics_updown_damping</string><key>value</key><real>0.2000000029802322387695312</real><key>weight</key><integer>51</integer></map><key>10007</key><map><key>name</key><string>breast_physics_inout_max_effect</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>10008</key><map><key>name</key><string>breast_physics_inout_spring</string><key>value</key><real>10</real><key>weight</key><integer>25</integer></map><key>10009</key><map><key>name</key><string>breast_physics_inout_gain</string><key>value</key><real>10</real><key>weight</key><integer>23</integer></map><key>10010</key><map><key>name</key><string>breast_physics_inout_damping</string><key>value</key><real>0.2000000029802322387695312</real><key>weight</key><integer>51</integer></map><key>10011</key><map><key>name</key><string>belly_physics_mass</string><key>value</key><real>0.1000000014901161193847656</real><key>weight</key><integer>0</integer></map><key>10012</key><map><key>name</key><string>belly_physics_gravity</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>10013</key><map><key>name</key><string>belly_physics_drag</string><key>value</key><real>1</real><key>weight</key><integer>25</integer></map><key>10014</key><map><key>name</key><string>belly_physics_updown_max_effect</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>10015</key><map><key>name</key><string>belly_physics_updown_spring</string><key>value</key><real>10</real><key>weight</key><integer>25</integer></map><key>10016</key><map><key>name</key><string>belly_physics_updown_gain</string><key>value</key><real>10</real><key>weight</key><integer>23</integer></map><key>10017</key><map><key>name</key><string>belly_physics_updown_damping</string><key>value</key><real>0.2000000029802322387695312</real><key>weight</key><integer>51</integer></map><key>10018</key><map><key>name</key><string>butt_physics_mass</string><key>value</key><real>0.1000000014901161193847656</real><key>weight</key><integer>0</integer></map><key>10019</key><map><key>name</key><string>butt_physics_gravity</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>10020</key><map><key>name</key><string>butt_physics_drag</string><key>value</key><real>1</real><key>weight</key><integer>25</integer></map><key>10021</key><map><key>name</key><string>butt_physics_updown_max_effect</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>10022</key><map><key>name</key><string>butt_physics_updown_spring</string><key>value</key><real>10</real><key>weight</key><integer>25</integer></map><key>10023</key><map><key>name</key><string>butt_physics_updown_gain</string><key>value</key><real>10</real><key>weight</key><integer>23</integer></map><key>10024</key><map><key>name</key><string>butt_physics_updown_damping</string><key>value</key><real>0.2000000029802322387695312</real><key>weight</key><integer>51</integer></map><key>10025</key><map><key>name</key><string>butt_physics_leftright_max_effect</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>10026</key><map><key>name</key><string>butt_physics_leftright_spring</string><key>value</key><real>10</real><key>weight</key><integer>25</integer></map><key>10027</key><map><key>name</key><string>butt_physics_leftright_gain</string><key>value</key><real>10</real><key>weight</key><integer>23</integer></map><key>10028</key><map><key>name</key><string>butt_physics_leftright_damping</string><key>value</key><real>0.2000000029802322387695312</real><key>weight</key><integer>51</integer></map><key>10029</key><map><key>name</key><string>breast_physics_leftright_max_effect</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>10030</key><map><key>name</key><string>breast_physics_leftright_spring</string><key>value</key><real>10</real><key>weight</key><integer>25</integer></map><key>10031</key><map><key>name</key><string>breast_physics_leftright_gain</string><key>value</key><real>10</real><key>weight</key><integer>23</integer></map><key>10032</key><map><key>name</key><string>breast_physics_leftright_damping</string><key>value</key><real>0.2000000029802322387695312</real><key>weight</key><integer>51</integer></map><key>105</key><map><key>name</key><string>breast size</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>108</key><map><key>name</key><string>rainbow color</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>11</key><map><key>name</key><string>noble_nose_bridge</string><key>value</key><real>0.03999999910593032836914062</real><key>weight</key><integer>68</integer></map><key>110</key><map><key>name</key><string>red skin</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>11000</key><map><key>name</key><string>appearancemessage_version</string><key>value</key><real>1</real><key>weight</key><integer>1</integer></map><key>11001</key><map><key>name</key><string>hover</string><key>value</key><real>0</real><key>weight</key><integer>127</integer></map><key>111</key><map><key>name</key><string>pigment</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>112</key><map><key>name</key><string>rainbow color</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>113</key><map><key>name</key><string>red hair</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>114</key><map><key>name</key><string>blonde hair</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>115</key><map><key>name</key><string>white hair</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>116</key><map><key>name</key><string>rosy complexion</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>117</key><map><key>name</key><string>lip pinkness</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>119</key><map><key>name</key><string>eyebrow size</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>12</key><map><key>name</key><string>jowls</string><key>value</key><real>0</real><key>weight</key><integer>42</integer></map><key>13</key><map><key>name</key><string>cleft_chin_upper</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>130</key><map><key>name</key><string>front fringe</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>131</key><map><key>name</key><string>side fringe</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>132</key><map><key>name</key><string>back fringe</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>133</key><map><key>name</key><string>hair front</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>134</key><map><key>name</key><string>hair sides</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>135</key><map><key>name</key><string>hair back</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>136</key><map><key>name</key><string>hair sweep</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>137</key><map><key>name</key><string>hair tilt</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>14</key><map><key>name</key><string>high_cheek_bones</string><key>value</key><real>0</real><key>weight</key><integer>85</integer></map><key>140</key><map><key>name</key><string>hair_part_middle</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>141</key><map><key>name</key><string>hair_part_right</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>142</key><map><key>name</key><string>hair_part_left</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>143</key><map><key>name</key><string>hair_sides_full</string><key>value</key><real>-4</real><key>weight</key><integer>0</integer></map><key>15</key><map><key>name</key><string>ears_out</string><key>value</key><real>0</real><key>weight</key><integer>63</integer></map><key>150</key><map><key>name</key><string>body definition</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>155</key><map><key>name</key><string>lip width</string><key>value</key><real>-0.12999999523162841796875</real><key>weight</key><integer>89</integer></map><key>157</key><map><key>name</key><string>belly size</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>16</key><map><key>name</key><string>pointy_eyebrows</string><key>value</key><real>0.4099999964237213134765625</real><key>weight</key><integer>66</integer></map><key>162</key><map><key>name</key><string>facial definition</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>163</key><map><key>name</key><string>wrinkles</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>165</key><map><key>name</key><string>freckles</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>166</key><map><key>name</key><string>sideburns</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>167</key><map><key>name</key><string>moustache</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>168</key><map><key>name</key><string>soulpatch</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>169</key><map><key>name</key><string>chin curtains</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>17</key><map><key>name</key><string>square_jaw</string><key>value</key><real>0</real><key>weight</key><integer>85</integer></map><key>177</key><map><key>name</key><string>hair_rumpled</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>18</key><map><key>name</key><string>puffy_upper_cheeks</string><key>value</key><real>0</real><key>weight</key><integer>95</integer></map><key>181</key><map><key>name</key><string>hair_big_front</string><key>value</key><real>-1</real><key>weight</key><integer>0</integer></map><key>182</key><map><key>name</key><string>hair_big_top</string><key>value</key><real>-1</real><key>weight</key><integer>0</integer></map><key>183</key><map><key>name</key><string>hair_big_back</string><key>value</key><real>-1</real><key>weight</key><integer>0</integer></map><key>184</key><map><key>name</key><string>hair_spiked</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>185</key><map><key>name</key><string>deep_chin</string><key>value</key><real>-0.439999997615814208984375</real><key>weight</key><integer>71</integer></map><key>19</key><map><key>name</key><string>upturned_nose_tip</string><key>value</key><real>-0.1000000014901161193847656</real><key>weight</key><integer>142</integer></map><key>192</key><map><key>name</key><string>bangs_part_middle</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>193</key><map><key>name</key><string>head shape</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>196</key><map><key>name</key><string>eye spacing</string><key>value</key><real>-0.589999973773956298828125</real><key>weight</key><integer>119</integer></map><key>198</key><map><key>name</key><string>heel height</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>2</key><map><key>name</key><string>nose_big_out</string><key>value</key><real>0.1599999964237213134765625</real><key>weight</key><integer>74</integer></map><key>20</key><map><key>name</key><string>bulbous_nose</string><key>value</key><real>0.560000002384185791015625</real><key>weight</key><integer>135</integer></map><key>21</key><map><key>name</key><string>upper_eyelid_fold</string><key>value</key><real>0.07000000029802322387695312</real><key>weight</key><integer>45</integer></map><key>22</key><map><key>name</key><string>attached_earlobes</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>23</key><map><key>name</key><string>baggy_eyes</string><key>value</key><real>0.4199999868869781494140625</real><key>weight</key><integer>117</integer></map><key>24</key><map><key>name</key><string>wide_eyes</string><key>value</key><real>-0.660000026226043701171875</real><key>weight</key><integer>61</integer></map><key>25</key><map><key>name</key><string>wide_lip_cleft</string><key>value</key><real>0.5099999904632568359375</real><key>weight</key><integer>145</integer></map><key>27</key><map><key>name</key><string>wide_nose_bridge</string><key>value</key><real>0.01999999955296516418457031</real><key>weight</key><integer>134</integer></map><key>31</key><map><key>name</key><string>arced_eyebrows</string><key>value</key><real>1.03999996185302734375</real><key>weight</key><integer>132</integer></map><key>33</key><map><key>name</key><string>height</string><key>value</key><real>-0.4099999964237213134765625</real><key>weight</key><integer>112</integer></map><key>34</key><map><key>name</key><string>thickness</string><key>value</key><real>0.4000000059604644775390625</real><key>weight</key><integer>127</integer></map><key>35</key><map><key>name</key><string>big_ears</string><key>value</key><real>0</real><key>weight</key><integer>85</integer></map><key>36</key><map><key>name</key><string>shoulders</string><key>value</key><real>-0.4900000095367431640625</real><key>weight</key><integer>104</integer></map><key>37</key><map><key>name</key><string>hip width</string><key>value</key><real>0</real><key>weight</key><integer>136</integer></map><key>38</key><map><key>name</key><string>torso length</string><key>value</key><real>0.4199999868869781494140625</real><key>weight</key><integer>181</integer></map><key>4</key><map><key>name</key><string>broad_nostrils</string><key>value</key><real>-0.2300000041723251342773438</real><key>weight</key><integer>45</integer></map><key>5</key><map><key>name</key><string>cleft_chin</string><key>value</key><real>-0.1000000014901161193847656</real><key>weight</key><integer>0</integer></map><key>503</key><map><key>name</key><string>platform height</string><key>value</key><real>0.1000000014901161193847656</real><key>weight</key><integer>25</integer></map><key>505</key><map><key>name</key><string>lip thickness</string><key>value</key><real>0.64999997615814208984375</real><key>weight</key><integer>165</integer></map><key>506</key><map><key>name</key><string>mouth_height</string><key>value</key><real>-0.03999999910593032836914062</real><key>weight</key><integer>124</integer></map><key>507</key><map><key>name</key><string>breast_gravity</string><key>value</key><real>0</real><key>weight</key><integer>109</integer></map><key>508</key><map><key>name</key><string>shoe_platform_width</string><key>value</key><real>-0.519999980926513671875</real><key>weight</key><integer>40</integer></map><key>513</key><map><key>name</key><string>heel shape</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>514</key><map><key>name</key><string>toe shape</string><key>value</key><real>0.0900000035762786865234375</real><key>weight</key><integer>22</integer></map><key>515</key><map><key>name</key><string>foot_size</string><key>value</key><real>-0.2000000029802322387695312</real><key>weight</key><integer>51</integer></map><key>517</key><map><key>name</key><string>wide_nose</string><key>value</key><real>0.1199999973177909851074219</real><key>weight</key><integer>105</integer></map><key>518</key><map><key>name</key><string>eyelashes_long</string><key>value</key><real>-0.300000011920928955078125</real><key>weight</key><integer>0</integer></map><key>6</key><map><key>name</key><string>bulbous_nose_tip</string><key>value</key><real>-0.300000011920928955078125</real><key>weight</key><integer>0</integer></map><key>603</key><map><key>name</key><string>sleeve length</string><key>value</key><real>0.4000000059604644775390625</real><key>weight</key><integer>100</integer></map><key>604</key><map><key>name</key><string>bottom</string><key>value</key><real>0.85000002384185791015625</real><key>weight</key><integer>216</integer></map><key>605</key><map><key>name</key><string>collar front</string><key>value</key><real>0.839999973773956298828125</real><key>weight</key><integer>214</integer></map><key>606</key><map><key>name</key><string>sleeve length</string><key>value</key><real>0.800000011920928955078125</real><key>weight</key><integer>204</integer></map><key>607</key><map><key>name</key><string>collar front</string><key>value</key><real>0.800000011920928955078125</real><key>weight</key><integer>204</integer></map><key>608</key><map><key>name</key><string>bottom length lower</string><key>value</key><real>0.800000011920928955078125</real><key>weight</key><integer>204</integer></map><key>609</key><map><key>name</key><string>open jacket</string><key>value</key><real>0.2000000029802322387695312</real><key>weight</key><integer>51</integer></map><key>616</key><map><key>name</key><string>shoe height</string><key>value</key><real>0.300000011920928955078125</real><key>weight</key><integer>76</integer></map><key>617</key><map><key>name</key><string>socks length</string><key>value</key><real>0.3499999940395355224609375</real><key>weight</key><integer>89</integer></map><key>619</key><map><key>name</key><string>pants length</string><key>value</key><real>0.300000011920928955078125</real><key>weight</key><integer>76</integer></map><key>624</key><map><key>name</key><string>pants waist</string><key>value</key><real>0.800000011920928955078125</real><key>weight</key><integer>204</integer></map><key>625</key><map><key>name</key><string>leg_pantflair</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>629</key><map><key>name</key><string>forehead angle</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>637</key><map><key>name</key><string>body fat</string><key>value</key><real>0.009999999776482582092285156</real><key>weight</key><integer>2</integer></map><key>638</key><map><key>name</key><string>low_crotch</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>646</key><map><key>name</key><string>egg_head</string><key>value</key><real>0</real><key>weight</key><integer>144</integer></map><key>647</key><map><key>name</key><string>squash_stretch_head</string><key>value</key><real>0</real><key>weight</key><integer>85</integer></map><key>649</key><map><key>name</key><string>torso muscles</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>650</key><map><key>name</key><string>eyelid_corner_up</string><key>value</key><real>-0.670000016689300537109375</real><key>weight</key><integer>64</integer></map><key>652</key><map><key>name</key><string>leg muscles</string><key>value</key><real>0.4900000095367431640625</real><key>weight</key><integer>124</integer></map><key>653</key><map><key>name</key><string>tall_lips</string><key>value</key><real>0.2599999904632568359375</real><key>weight</key><integer>107</integer></map><key>654</key><map><key>name</key><string>shoe_toe_thick</string><key>value</key><real>0.05999999865889549255371094</real><key>weight</key><integer>7</integer></map><key>656</key><map><key>name</key><string>crooked_nose</string><key>value</key><real>0</real><key>weight</key><integer>127</integer></map><key>659</key><map><key>name</key><string>mouth corner</string><key>value</key><real>0.5099999904632568359375</real><key>weight</key><integer>130</integer></map><key>662</key><map><key>name</key><string>face shear</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>663</key><map><key>name</key><string>shift_mouth</string><key>value</key><real>-0.2000000029802322387695312</real><key>weight</key><integer>114</integer></map><key>664</key><map><key>name</key><string>pop_eye</string><key>value</key><real>0.12999999523162841796875</real><key>weight</key><integer>140</integer></map><key>665</key><map><key>name</key><string>jaw_jut</string><key>value</key><real>0.03999999910593032836914062</real><key>weight</key><integer>130</integer></map><key>674</key><map><key>name</key><string>hair_shear_back</string><key>value</key><real>-0.300000011920928955078125</real><key>weight</key><integer>59</integer></map><key>675</key><map><key>name</key><string>hand size</string><key>value</key><real>0.02999999932944774627685547</real><key>weight</key><integer>140</integer></map><key>676</key><map><key>name</key><string>love_handles</string><key>value</key><real>-0.430000007152557373046875</real><key>weight</key><integer>48</integer></map><key>678</key><map><key>name</key><string>torso muscles</string><key>value</key><real>0.37000000476837158203125</real><key>weight</key><integer>94</integer></map><key>682</key><map><key>name</key><string>head size</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>683</key><map><key>name</key><string>neck thickness</string><key>value</key><real>-0.1400000005960464477539062</real><key>weight</key><integer>110</integer></map><key>684</key><map><key>name</key><string>breast_female_cleavage</string><key>value</key><real>0</real><key>weight</key><integer>47</integer></map><key>685</key><map><key>name</key><string>chest_male_no_pecs</string><key>value</key><real>0.1400000005960464477539062</real><key>weight</key><integer>101</integer></map><key>690</key><map><key>name</key><string>eye size</string><key>value</key><real>0.3300000131130218505859375</real><key>weight</key><integer>84</integer></map><key>692</key><map><key>name</key><string>leg length</string><key>value</key><real>0.2399999946355819702148438</real><key>weight</key><integer>158</integer></map><key>693</key><map><key>name</key><string>arm length</string><key>value</key><real>0.1000000014901161193847656</real><key>weight</key><integer>140</integer></map><key>7</key><map><key>name</key><string>weak_chin</string><key>value</key><real>0</real><key>weight</key><integer>127</integer></map><key>700</key><map><key>name</key><string>lipstick color</string><key>value</key><real>0.25</real><key>weight</key><integer>63</integer></map><key>701</key><map><key>name</key><string>lipstick</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>702</key><map><key>name</key><string>lipgloss</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>703</key><map><key>name</key><string>eyeliner</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>704</key><map><key>name</key><string>blush</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>705</key><map><key>name</key><string>blush color</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>706</key><map><key>name</key><string>out shdw opacity</string><key>value</key><real>0.60000002384185791015625</real><key>weight</key><integer>127</integer></map><key>707</key><map><key>name</key><string>outer shadow</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>708</key><map><key>name</key><string>out shdw color</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>709</key><map><key>name</key><string>inner shadow</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>710</key><map><key>name</key><string>nail polish</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>711</key><map><key>name</key><string>blush opacity</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>712</key><map><key>name</key><string>in shdw color</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>713</key><map><key>name</key><string>in shdw opacity</string><key>value</key><real>0.699999988079071044921875</real><key>weight</key><integer>159</integer></map><key>714</key><map><key>name</key><string>eyeliner color</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>715</key><map><key>name</key><string>nail polish color</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>750</key><map><key>name</key><string>eyebrow density</string><key>value</key><real>0.64999997615814208984375</real><key>weight</key><integer>165</integer></map><key>752</key><map><key>name</key><string>hair thickness</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>753</key><map><key>name</key><string>saddlebags</string><key>value</key><real>0.05999999865889549255371094</real><key>weight</key><integer>40</integer></map><key>754</key><map><key>name</key><string>hair_taper_back</string><key>value</key><real>0</real><key>weight</key><integer>85</integer></map><key>755</key><map><key>name</key><string>hair_taper_front</string><key>value</key><real>0.05000000074505805969238281</real><key>weight</key><integer>131</integer></map><key>756</key><map><key>name</key><string>neck length</string><key>value</key><real>-0.07999999821186065673828125</real><key>weight</key><integer>117</integer></map><key>757</key><map><key>name</key><string>lower_eyebrows</string><key>value</key><real>-1.60000002384185791015625</real><key>weight</key><integer>102</integer></map><key>758</key><map><key>name</key><string>lower_bridge_nose</string><key>value</key><real>-1.0499999523162841796875</real><key>weight</key><integer>38</integer></map><key>759</key><map><key>name</key><string>low_septum_nose</string><key>value</key><real>0.670000016689300537109375</real><key>weight</key><integer>170</integer></map><key>760</key><map><key>name</key><string>jaw_angle</string><key>value</key><real>0</real><key>weight</key><integer>95</integer></map><key>762</key><map><key>name</key><string>hair_shear_front</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>763</key><map><key>name</key><string>hair volume</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>764</key><map><key>name</key><string>lip_cleft_deep</string><key>value</key><real>-0.5</real><key>weight</key><integer>0</integer></map><key>765</key><map><key>name</key><string>puffy_lower_lids</string><key>value</key><real>1.019999980926513671875</real><key>weight</key><integer>120</integer></map><key>769</key><map><key>name</key><string>eye depth</string><key>value</key><real>0.519999980926513671875</real><key>weight</key><integer>132</integer></map><key>773</key><map><key>name</key><string>head length</string><key>value</key><real>0.5</real><key>weight</key><integer>127</integer></map><key>775</key><map><key>name</key><string>body freckles</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>779</key><map><key>name</key><string>collar back</string><key>value</key><real>0.839999973773956298828125</real><key>weight</key><integer>214</integer></map><key>780</key><map><key>name</key><string>collar back</string><key>value</key><real>0.800000011920928955078125</real><key>weight</key><integer>204</integer></map><key>781</key><map><key>name</key><string>collar back</string><key>value</key><real>0.7799999713897705078125</real><key>weight</key><integer>198</integer></map><key>785</key><map><key>name</key><string>pigtails</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>789</key><map><key>name</key><string>ponytail</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>795</key><map><key>name</key><string>butt size</string><key>value</key><real>0.4099999964237213134765625</real><key>weight</key><integer>104</integer></map><key>796</key><map><key>name</key><string>pointy_ears</string><key>value</key><real>0</real><key>weight</key><integer>30</integer></map><key>799</key><map><key>name</key><string>lip ratio</string><key>value</key><real>0.449999988079071044921875</real><key>weight</key><integer>114</integer></map><key>8</key><map><key>name</key><string>double_chin</string><key>value</key><real>0</real><key>weight</key><integer>63</integer></map><key>80</key><map><key>name</key><string>male</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>800</key><map><key>name</key><string>sleeve length</string><key>value</key><real>0.88999998569488525390625</real><key>weight</key><integer>226</integer></map><key>801</key><map><key>name</key><string>shirt bottom</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>802</key><map><key>name</key><string>collar front</string><key>value</key><real>0.7799999713897705078125</real><key>weight</key><integer>198</integer></map><key>803</key><map><key>name</key><string>shirt_red</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>804</key><map><key>name</key><string>shirt_green</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>805</key><map><key>name</key><string>shirt_blue</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>806</key><map><key>name</key><string>pants_red</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>807</key><map><key>name</key><string>pants_green</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>808</key><map><key>name</key><string>pants_blue</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>812</key><map><key>name</key><string>shoes_red</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>813</key><map><key>name</key><string>shoes_green</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>814</key><map><key>name</key><string>waist height</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>815</key><map><key>name</key><string>pants length</string><key>value</key><real>0.800000011920928955078125</real><key>weight</key><integer>204</integer></map><key>816</key><map><key>name</key><string>loose lower clothing</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>817</key><map><key>name</key><string>shoes_blue</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>818</key><map><key>name</key><string>socks_red</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>819</key><map><key>name</key><string>socks_green</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>820</key><map><key>name</key><string>socks_blue</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>821</key><map><key>name</key><string>undershirt_red</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>822</key><map><key>name</key><string>undershirt_green</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>823</key><map><key>name</key><string>undershirt_blue</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>824</key><map><key>name</key><string>underpants_red</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>825</key><map><key>name</key><string>underpants_green</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>826</key><map><key>name</key><string>underpants_blue</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>827</key><map><key>name</key><string>gloves_red</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>828</key><map><key>name</key><string>loose upper clothing</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>829</key><map><key>name</key><string>gloves_green</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>830</key><map><key>name</key><string>gloves_blue</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>834</key><map><key>name</key><string>jacket_red</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>835</key><map><key>name</key><string>jacket_green</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>836</key><map><key>name</key><string>jacket_blue</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>840</key><map><key>name</key><string>shirtsleeve_flair</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>841</key><map><key>name</key><string>bowed_legs</string><key>value</key><real>0</real><key>weight</key><integer>127</integer></map><key>842</key><map><key>name</key><string>hip length</string><key>value</key><real>-0.800000011920928955078125</real><key>weight</key><integer>25</integer></map><key>844</key><map><key>name</key><string>glove fingers</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>848</key><map><key>name</key><string>skirt_bustle</string><key>value</key><real>0.2000000029802322387695312</real><key>weight</key><integer>25</integer></map><key>858</key><map><key>name</key><string>skirt length</string><key>value</key><real>0.4000000059604644775390625</real><key>weight</key><integer>100</integer></map><key>859</key><map><key>name</key><string>slit front</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>860</key><map><key>name</key><string>slit back</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>861</key><map><key>name</key><string>slit left</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>862</key><map><key>name</key><string>slit right</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>863</key><map><key>name</key><string>skirt_looseness</string><key>value</key><real>0.333000004291534423828125</real><key>weight</key><integer>84</integer></map><key>868</key><map><key>name</key><string>shirt wrinkles</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>869</key><map><key>name</key><string>pants wrinkles</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>877</key><map><key>name</key><string>jacket wrinkles</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map><key>879</key><map><key>name</key><string>male_package</string><key>value</key><real>-0.1000000014901161193847656</real><key>weight</key><integer>40</integer></map><key>880</key><map><key>name</key><string>eyelid_inner_corner_up</string><key>value</key><real>-0.819999992847442626953125</real><key>weight</key><integer>48</integer></map><key>921</key><map><key>name</key><string>skirt_red</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>922</key><map><key>name</key><string>skirt_green</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>923</key><map><key>name</key><string>skirt_blue</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>93</key><map><key>name</key><string>glove length</string><key>value</key><real>0.800000011920928955078125</real><key>weight</key><integer>203</integer></map><key>98</key><map><key>name</key><string>eye lightness</string><key>value</key><real>1</real><key>weight</key><integer>255</integer></map><key>99</key><map><key>name</key><string>eye color</string><key>value</key><real>0</real><key>weight</key><integer>0</integer></map></map><key>dump_joint_offsets</key><array><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mPelvis</string><key>pos</key><array><real>0</real><real>0</real><real>1.08198797702789306640625</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mSpine1</string><key>pos</key><array><real>0</real><real>0</real><real>0.08407299965620040893554688</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mSpine2</string><key>pos</key><array><real>0</real><real>0</real><real>-0.08407299965620040893554688</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mTorso</string><key>pos</key><array><real>0</real><real>0</real><real>0.08407299965620040893554688</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mSpine3</string><key>pos</key><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mSpine4</string><key>pos</key><array><real>0.01536799967288970947265625</real><real>0</real><real>-0.2048770040273666381835938</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mChest</string><key>pos</key><array><real>-0.01536799967288970947265625</real><real>0</real><real>0.2048770040273666381835938</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mNeck</string><key>pos</key><array><real>-0.009507000446319580078125</real><real>0</real><real>0.251107990741729736328125</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mCollarLeft</string><key>pos</key><array><real>-0.02092700079083442687988281</real><real>0.084665000438690185546875</real><real>0.1653960049152374267578125</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mShoulderLeft</string><key>pos</key><array><real>0</real><real>0.07900000363588333129882812</real><real>0</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mElbowLeft</string><key>pos</key><array><real>0</real><real>0.2479999959468841552734375</real><real>0</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mCollarRight</string><key>pos</key><array><real>-0.02092700079083442687988281</real><real>-0.08500000089406967163085938</real><real>0.1653960049152374267578125</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mShoulderRight</string><key>pos</key><array><real>0</real><real>-0.079418003559112548828125</real><real>0</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mElbowRight</string><key>pos</key><array><real>0</real><real>-0.2479999959468841552734375</real><real>0</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mHipRight</string><key>pos</key><array><real>0.03361999988555908203125</real><real>-0.12880599498748779296875</real><real>-0.04108599945902824401855469</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mKneeRight</string><key>pos</key><array><real>-0.000780000002123415470123291</real><real>0.04863499850034713745117188</real><real>-0.4909220039844512939453125</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mAnkleRight</string><key>pos</key><array><real>-0.02886899933218955993652344</real><real>0</real><real>-0.468493998050689697265625</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mHipLeft</string><key>pos</key><array><real>0.0337570011615753173828125</real><real>0.1267649978399276733398438</real><real>-0.04099800065159797668457031</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mKneeLeft</string><key>pos</key><array><real>-0.0008870000019669532775878906</real><real>-0.04556800052523612976074219</real><real>-0.49105298519134521484375</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mAnkleLeft</string><key>pos</key><array><real>-0.02888699993491172790527344</real><real>0.001378000015392899513244629</real><real>-0.46844899654388427734375</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mTail1</string><key>pos</key><array><real>-0.127954006195068359375</real><real>0</real><real>0.001858999952673912048339844</real></array></map><map><key>mesh_id</key><uuid>270bb701-8643-c4b3-6a93-7a2b6503b30a</uuid><key>name</key><string>mTail2</string><key>pos</key><array><real>-0.01885000057518482208251953</real><real>0</real><real>-0.094934999942779541015625</real></array></map></array><key>params</key><array><integer>33</integer><integer>74</integer><integer>45</integer><integer>0</integer><integer>0</integer><integer>127</integer><integer>63</integer><integer>85</integer><integer>68</integer><integer>42</integer><integer>0</integer><integer>85</integer><integer>63</integer><integer>66</integer><integer>85</integer><integer>95</integer><integer>142</integer><integer>135</integer><integer>45</integer><integer>0</integer><integer>117</integer><integer>61</integer><integer>145</integer><integer>134</integer><integer>132</integer><integer>112</integer><integer>127</integer><integer>85</integer><integer>104</integer><integer>136</integer><integer>181</integer><integer>255</integer><integer>203</integer><integer>255</integer><integer>0</integer><integer>127</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>127</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>127</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>89</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>71</integer><integer>0</integer><integer>127</integer><integer>119</integer><integer>0</integer><integer>25</integer><integer>165</integer><integer>124</integer><integer>109</integer><integer>40</integer><integer>0</integer><integer>22</integer><integer>51</integer><integer>105</integer><integer>0</integer><integer>100</integer><integer>216</integer><integer>214</integer><integer>204</integer><integer>204</integer><integer>204</integer><integer>51</integer><integer>76</integer><integer>89</integer><integer>76</integer><integer>204</integer><integer>0</integer><integer>127</integer><integer>2</integer><integer>0</integer><integer>144</integer><integer>85</integer><integer>127</integer><integer>64</integer><integer>124</integer><integer>107</integer><integer>7</integer><integer>127</integer><integer>130</integer><integer>127</integer><integer>114</integer><integer>140</integer><integer>130</integer><integer>59</integer><integer>140</integer><integer>48</integer><integer>94</integer><integer>127</integer><integer>110</integer><integer>47</integer><integer>101</integer><integer>84</integer><integer>158</integer><integer>140</integer><integer>63</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>127</integer><integer>127</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>127</integer><integer>0</integer><integer>159</integer><integer>0</integer><integer>0</integer><integer>165</integer><integer>127</integer><integer>40</integer><integer>85</integer><integer>131</integer><integer>117</integer><integer>102</integer><integer>38</integer><integer>170</integer><integer>95</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>120</integer><integer>132</integer><integer>127</integer><integer>0</integer><integer>214</integer><integer>204</integer><integer>198</integer><integer>0</integer><integer>0</integer><integer>104</integer><integer>30</integer><integer>114</integer><integer>226</integer><integer>255</integer><integer>198</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>204</integer><integer>0</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>0</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>0</integer><integer>127</integer><integer>25</integer><integer>255</integer><integer>25</integer><integer>100</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>84</integer><integer>0</integer><integer>0</integer><integer>0</integer><integer>40</integer><integer>48</integer><integer>255</integer><integer>255</integer><integer>255</integer><integer>0</integer><integer>0</integer><integer>25</integer><integer>0</integer><integer>25</integer><integer>23</integer><integer>51</integer><integer>0</integer><integer>25</integer><integer>23</integer><integer>51</integer><integer>0</integer><integer>0</integer><integer>25</integer><integer>0</integer><integer>25</integer><integer>23</integer><integer>51</integer><integer>0</integer><integer>0</integer><integer>25</integer><integer>0</integer><integer>25</integer><integer>23</integer><integer>51</integer><integer>0</integer><integer>25</integer><integer>23</integer><integer>51</integer><integer>0</integer><integer>25</integer><integer>23</integer><integer>51</integer><integer>1</integer><integer>127</integer></array><key>slot_textures</key><map><key>aux1</key><map><key>hash_id</key><uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid><key>texture_ids</key><array /></map><key>aux2</key><map><key>hash_id</key><uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid><key>texture_ids</key><array /></map><key>aux3</key><map><key>hash_id</key><uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid><key>texture_ids</key><array /></map><key>eyes</key><map><key>hash_id</key><uuid>812bffac-704c-d4bb-487d-0674ccbd5d9d</uuid><key>texture_ids</key><array><uuid>5748decc-f629-461c-9a36-a35a221fe21f</uuid><uuid>579e320c-0f16-2a1d-2018-2a00cc657068</uuid></array></map><key>hair</key><map><key>hash_id</key><uuid>fc7ad735-99b6-aaf1-a1bf-676ea304b624</uuid><key>texture_ids</key><array><uuid>3cc3add8-6ff0-0640-79ba-b15137f64008</uuid><uuid>5748decc-f629-461c-9a36-a35a221fe21f</uuid></array></map><key>head</key><map><key>hash_id</key><uuid>799f44a9-82ec-78bd-7800-3e17367229fa</uuid><key>texture_ids</key><array><uuid>5748decc-f629-461c-9a36-a35a221fe21f</uuid><uuid>9e460914-daed-b03f-0f2a-afbe67833b11</uuid><uuid>a21d4081-601e-f9f0-0acc-9192c72863dc</uuid></array></map><key>leftarm</key><map><key>hash_id</key><uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid><key>texture_ids</key><array /></map><key>leftleg</key><map><key>hash_id</key><uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid><key>texture_ids</key><array /></map><key>lower</key><map><key>hash_id</key><uuid>6d752c11-c33a-43c4-8631-3f8a6722ba59</uuid><key>texture_ids</key><array><uuid>5748decc-f629-461c-9a36-a35a221fe21f</uuid><uuid>8dcd4a48-2d37-4909-9f78-f7a9eb4ef903</uuid><uuid>ab169525-d46c-918b-3195-7f2b92fd76c5</uuid><uuid>b5b09502-8305-af43-cc4e-7238cb715b11</uuid><uuid>d9413239-769d-abc9-e929-4fa98f52c07b</uuid></array></map><key>skirt</key><map><key>hash_id</key><uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid><key>texture_ids</key><array /></map><key>upper</key><map><key>hash_id</key><uuid>5b4d5c23-3073-26d1-8d68-78d5bfa308e4</uuid><key>texture_ids</key><array><uuid>5748decc-f629-461c-9a36-a35a221fe21f</uuid><uuid>a85bf749-952d-3835-d9ac-a307c780930c</uuid><uuid>b5d465f9-ca8e-8ba4-efd8-ee8929c592b8</uuid></array></map></map><key>success</key><boolean>1</boolean></map></llsd>
diff --git a/indra/llappearanceutility/tests/texture.llsd.binary b/indra/llappearanceutility/tests/texture.llsd.binary
new file mode 100644
index 0000000000..6b4f34831c
--- /dev/null
+++ b/indra/llappearanceutility/tests/texture.llsd.binary
Binary files differ
diff --git a/indra/llappearanceutility/tests/texture.llsd.output b/indra/llappearanceutility/tests/texture.llsd.output
new file mode 100644
index 0000000000..6c7690decc
--- /dev/null
+++ b/indra/llappearanceutility/tests/texture.llsd.output
Binary files differ
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index 9278d3c488..18e29fb194 100644
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -54,3 +54,7 @@ endif()
if( TARGET ll::fmodstudio )
target_link_libraries( llaudio ll::fmodstudio )
endif()
+
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llaudio REUSE_FROM llprecompiled)
+endif ()
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt
index bc45eb474a..1f019e6aef 100644
--- a/indra/llcharacter/CMakeLists.txt
+++ b/indra/llcharacter/CMakeLists.txt
@@ -70,3 +70,7 @@ target_link_libraries(
llfilesystem
llxml
)
+
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llcharacter REUSE_FROM llprecompiled)
+endif ()
diff --git a/indra/llcharacter/lleditingmotion.h b/indra/llcharacter/lleditingmotion.h
index f94756d43d..a3c0ee94b7 100644
--- a/indra/llcharacter/lleditingmotion.h
+++ b/indra/llcharacter/lleditingmotion.h
@@ -42,8 +42,7 @@
//-----------------------------------------------------------------------------
// class LLEditingMotion
//-----------------------------------------------------------------------------
-LL_ALIGN_PREFIX(16)
-class LLEditingMotion :
+class alignas(16) LLEditingMotion :
public LLMotion
{
LL_ALIGN_NEW
@@ -110,11 +109,11 @@ public:
//-------------------------------------------------------------------------
// joint states to be animated
//-------------------------------------------------------------------------
- LL_ALIGN_16(LLJoint mParentJoint);
- LL_ALIGN_16(LLJoint mShoulderJoint);
- LL_ALIGN_16(LLJoint mElbowJoint);
- LL_ALIGN_16(LLJoint mWristJoint);
- LL_ALIGN_16(LLJoint mTarget);
+ LLJoint mParentJoint;
+ LLJoint mShoulderJoint;
+ LLJoint mElbowJoint;
+ LLJoint mWristJoint;
+ LLJoint mTarget;
LLJointSolverRP3 mIKSolver;
LLCharacter *mCharacter;
@@ -129,7 +128,7 @@ public:
static S32 sHandPose;
static S32 sHandPosePriority;
LLVector3 mLastSelectPt;
-} LL_ALIGN_POSTFIX(16);
+};
#endif // LL_LLKEYFRAMEMOTION_H
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index b58dc797f8..481fb0a1bb 100644
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -86,8 +86,7 @@ inline bool operator!=(const LLVector3OverrideMap& a, const LLVector3OverrideMap
//-----------------------------------------------------------------------------
// class LLJoint
//-----------------------------------------------------------------------------
-LL_ALIGN_PREFIX(16)
-class LLJoint
+class alignas(16) LLJoint
{
LL_ALIGN_NEW
public:
@@ -118,7 +117,7 @@ public:
};
protected:
// explicit transformation members
- LL_ALIGN_16(LLMatrix4a mWorldMatrix);
+ LLMatrix4a mWorldMatrix;
LLXformMatrix mXform;
std::string mName;
@@ -302,6 +301,6 @@ public:
// These are used in checks of whether a pos/scale override is considered significant.
bool aboveJointPosThreshold(const LLVector3& pos) const;
bool aboveJointScaleThreshold(const LLVector3& scale) const;
-} LL_ALIGN_POSTFIX(16);
+};
#endif // LL_LLJOINT_H
diff --git a/indra/llcharacter/llkeyframestandmotion.h b/indra/llcharacter/llkeyframestandmotion.h
index df458c7a0c..7d1acb7c5a 100644
--- a/indra/llcharacter/llkeyframestandmotion.h
+++ b/indra/llcharacter/llkeyframestandmotion.h
@@ -37,8 +37,7 @@
//-----------------------------------------------------------------------------
// class LLKeyframeStandMotion
//-----------------------------------------------------------------------------
-LL_ALIGN_PREFIX(16)
-class LLKeyframeStandMotion :
+class alignas(16) LLKeyframeStandMotion :
public LLKeyframeMotion
{
LL_ALIGN_NEW
@@ -112,7 +111,7 @@ public:
bool mTrackAnkles;
S32 mFrameNum;
-} LL_ALIGN_POSTFIX(16);
+};
#endif // LL_LLKEYFRAMESTANDMOTION_H
diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h
index f2032220e0..fbcd482211 100644
--- a/indra/llcharacter/llpose.h
+++ b/indra/llcharacter/llpose.h
@@ -80,8 +80,7 @@ public:
const S32 JSB_NUM_JOINT_STATES = 6;
-LL_ALIGN_PREFIX(16)
-class LLJointStateBlender
+class alignas(16) LLJointStateBlender
{
LL_ALIGN_NEW
protected:
@@ -98,8 +97,8 @@ public:
void resetCachedJoint();
public:
- LL_ALIGN_16(LLJoint mJointCache);
-} LL_ALIGN_POSTFIX(16);
+ LLJoint mJointCache;
+};
class LLMotion;
diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h
index 3caddb9c62..c99577ed80 100644
--- a/indra/llcharacter/llvisualparam.h
+++ b/indra/llcharacter/llvisualparam.h
@@ -100,8 +100,7 @@ protected:
// An interface class for a generalized parametric modification of the avatar mesh
// Contains data that is specific to each Avatar
//-----------------------------------------------------------------------------
-LL_ALIGN_PREFIX(16)
-class LLVisualParam
+class alignas(16) LLVisualParam
{
public:
typedef boost::function<LLVisualParam*(S32)> visual_param_mapper;
@@ -180,6 +179,6 @@ protected:
S32 mID; // id for storing weight/morphtarget compares compactly
LLVisualParamInfo *mInfo;
EParamLocation mParamLocation; // where does this visual param live?
-} LL_ALIGN_POSTFIX(16);
+};
#endif // LL_LLVisualParam_H
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index daa1def726..f8c24368b2 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -68,7 +68,7 @@ set(llcommon_SOURCE_FILES
llmetricperformancetester.cpp
llmortician.cpp
llmutex.cpp
- llptrto.cpp
+ llptrto.cpp
llpredicate.cpp
llprocess.cpp
llprocessor.cpp
@@ -108,7 +108,7 @@ set(llcommon_SOURCE_FILES
workqueue.cpp
StackWalker.cpp
)
-
+
set(llcommon_HEADER_FILES
CMakeLists.txt
@@ -255,14 +255,28 @@ set(llcommon_HEADER_FILES
workqueue.h
StackWalker.h
)
-
+
if (DARWIN)
list(APPEND llcommon_HEADER_FILES llsys_objc.h)
list(APPEND llcommon_SOURCE_FILES llsys_objc.mm)
+
+ set_source_files_properties(
+ llsys_objc.mm
+ PROPERTIES
+ SKIP_PRECOMPILE_HEADERS TRUE
+ )
endif (DARWIN)
if (USE_TRACY)
list(APPEND llcommon_SOURCE_FILES llprofiler.cpp)
+
+ # Skip precompiled headers on these files due to special compilation needs
+ set_source_files_properties(
+ llfasttimer.cpp
+ llprofiler.cpp
+ PROPERTIES
+ SKIP_PRECOMPILE_HEADERS TRUE
+ )
endif ()
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
@@ -280,8 +294,12 @@ target_link_libraries(
ll::sse2neon
)
-target_include_directories(llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
-target_include_directories(llcommon PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(llcommon PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(llcommon PRIVATE ${CMAKE_SOURCE_DIR}/llmath)
+
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llcommon REUSE_FROM llprecompiled)
+endif ()
add_dependencies(llcommon stage_third_party_libs)
diff --git a/indra/llcommon/StackWalker.cpp b/indra/llcommon/StackWalker.cpp
index e9ae1723fb..77ae4db4bd 100644
--- a/indra/llcommon/StackWalker.cpp
+++ b/indra/llcommon/StackWalker.cpp
@@ -785,6 +785,8 @@ private:
case 8: //SymVirtual:
szSymType = "Virtual";
break;
+ case NumSymTypes:
+ break;
}
}
LPCSTR pdbName = Module.LoadedImageName;
diff --git a/indra/llcommon/classic_callback.h b/indra/llcommon/classic_callback.h
index 009c25d67c..8a6ac7f7ff 100644
--- a/indra/llcommon/classic_callback.h
+++ b/indra/llcommon/classic_callback.h
@@ -184,8 +184,8 @@ protected:
template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()>
auto makeClassicCallback(CALLABLE&& callable)
{
- return std::move(ClassicCallback<SIGNATURE, USERDATA, CALLABLE>
- (std::forward<CALLABLE>(callable)));
+ return ClassicCallback<SIGNATURE, USERDATA, CALLABLE>
+ (std::forward<CALLABLE>(callable));
}
/*****************************************************************************
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index c532620daa..73b50d0a50 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -58,14 +58,6 @@
void setup_signals();
void default_unix_signal_handler(int signum, siginfo_t *info, void *);
-#if LL_LINUX
-#else
-// Called by breakpad exception handler after the minidump has been generated.
-bool unix_post_minidump_callback(const char *dump_dir,
- const char *minidump_id,
- void *context, bool succeeded);
-#endif
-
# if LL_DARWIN
/* OSX doesn't support SIGRT* */
S32 LL_SMACKDOWN_SIGNAL = SIGUSR1;
@@ -720,47 +712,4 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
}
}
-bool unix_post_minidump_callback(const char *dump_dir,
- const char *minidump_id,
- void *context, bool succeeded)
-{
- // Copy minidump file path into fixed buffer in the app instance to avoid
- // heap allocations in a crash handler.
-
- // path format: <dump_dir>/<minidump_id>.dmp
- auto dirPathLength = strlen(dump_dir);
- auto idLength = strlen(minidump_id);
-
- // The path must not be truncated.
- llassert((dirPathLength + idLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH);
-
- char * path = LLApp::instance()->getMiniDumpFilename();
- auto remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
- strncpy(path, dump_dir, remaining);
- remaining -= dirPathLength;
- path += dirPathLength;
- if (remaining > 0 && dirPathLength > 0 && path[-1] != '/')
- {
- *path++ = '/';
- --remaining;
- }
- if (remaining > 0)
- {
- strncpy(path, minidump_id, remaining);
- remaining -= idLength;
- path += idLength;
- strncpy(path, ".dmp", remaining);
- }
-
- LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL;
- LLApp::runErrorHandler();
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- clear_signals();
- return false;
-#else
- return true;
-#endif
-}
#endif // !WINDOWS
-
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index 01763c49aa..ff5f262036 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -230,11 +230,11 @@ bool LLVolatileAPRPool::isFull()
bool _ll_apr_warn_status(apr_status_t status, const char* file, int line)
{
if(APR_SUCCESS == status) return false;
-#if !LL_LINUX
+
char buf[MAX_STRING]; /* Flawfinder: ignore */
apr_strerror(status, buf, sizeof(buf));
LL_WARNS("APR") << "APR: " << file << ":" << line << " " << buf << LL_ENDL;
-#endif
+
return true;
}
diff --git a/indra/llcommon/llatomic.cpp b/indra/llcommon/llatomic.cpp
index d200bb0406..cff5e01225 100644
--- a/indra/llcommon/llatomic.cpp
+++ b/indra/llcommon/llatomic.cpp
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "llatomic.h"
//============================================================================
diff --git a/indra/llcommon/llcallbacklist.cpp b/indra/llcommon/llcallbacklist.cpp
index 3d5d30bd90..8fb7823f04 100644
--- a/indra/llcommon/llcallbacklist.cpp
+++ b/indra/llcommon/llcallbacklist.cpp
@@ -24,6 +24,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "llcallbacklist.h"
#include "lleventtimer.h"
#include "llerrorlegacy.h"
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 7a22eaf203..bf8801c46b 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -47,30 +47,13 @@ void* ll_tracy_new(size_t size)
return ptr;
}
-void* ll_tracy_aligned_new(size_t size, size_t alignment)
-{
- void* ptr = ll_aligned_malloc_fallback(size, alignment);
- if (!ptr)
- {
- throw std::bad_alloc();
- }
- LL_PROFILE_ALLOC(ptr, size);
- return ptr;
-}
-
void ll_tracy_delete(void* ptr)
{
LL_PROFILE_FREE(ptr);
(free)(ptr);
}
-void ll_tracy_aligned_delete(void* ptr)
-{
- LL_PROFILE_FREE(ptr);
- ll_aligned_free_fallback(ptr);
-}
-
-void* operator new(size_t size)
+void* operator new(std::size_t size)
{
return ll_tracy_new(size);
}
@@ -80,24 +63,41 @@ void* operator new[](std::size_t count)
return ll_tracy_new(count);
}
-void* operator new(size_t size, std::align_val_t align)
+void operator delete(void *ptr) noexcept
{
- return ll_tracy_aligned_new(size, (size_t)align);
+ ll_tracy_delete(ptr);
}
-void* operator new[](std::size_t count, std::align_val_t align)
+void operator delete[](void* ptr) noexcept
{
- return ll_tracy_aligned_new(count, (size_t)align);
+ ll_tracy_delete(ptr);
}
-void operator delete(void *ptr) noexcept
+#if !defined(LL_LINUX)
+
+void* ll_tracy_aligned_new(size_t size, size_t alignment)
{
- ll_tracy_delete(ptr);
+ void* ptr = ll_aligned_malloc_fallback(size, alignment);
+ if (!ptr)
+ {
+ throw std::bad_alloc();
+ }
+ return ptr;
}
-void operator delete[](void* ptr) noexcept
+void ll_tracy_aligned_delete(void* ptr)
{
- ll_tracy_delete(ptr);
+ ll_aligned_free_fallback(ptr);
+}
+
+void* operator new(size_t size, std::align_val_t align)
+{
+ return ll_tracy_aligned_new(size, (size_t)align);
+}
+
+void* operator new[](std::size_t count, std::align_val_t align)
+{
+ return ll_tracy_aligned_new(count, (size_t)align);
}
void operator delete(void *ptr, std::align_val_t align) noexcept
@@ -110,6 +110,8 @@ void operator delete[](void* ptr, std::align_val_t align) noexcept
ll_tracy_aligned_delete(ptr);
}
+#endif
+
#endif // TRACY_ENABLE && !LL_PROFILER_ENABLE_TRACY_OPENGL
//static
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 5205699b92..b4cdf3cbda 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -131,11 +131,7 @@ void LLDate::toStream(std::ostream& s) const
}
s << std::dec << std::setfill('0');
-#if( LL_WINDOWS || __GNUC__ > 2)
s << std::right;
-#else
- s.setf(ios::right);
-#endif
s << std::setw(4) << (exp_time.tm_year + 1900)
<< '-' << std::setw(2) << (exp_time.tm_mon + 1)
<< '-' << std::setw(2) << (exp_time.tm_mday)
diff --git a/indra/llcommon/lldeadmantimer.cpp b/indra/llcommon/lldeadmantimer.cpp
index f9c14d7c24..45c01eb84a 100644
--- a/indra/llcommon/lldeadmantimer.cpp
+++ b/indra/llcommon/lldeadmantimer.cpp
@@ -25,6 +25,7 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
#include "lldeadmantimer.h"
diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h
index 232987da14..0481e45351 100644
--- a/indra/llcommon/lldefs.h
+++ b/indra/llcommon/lldefs.h
@@ -28,6 +28,7 @@
#define LL_LLDEFS_H
#include "stdtypes.h"
+#include <cassert>
#include <type_traits>
// Often used array indices
@@ -169,6 +170,38 @@ constexpr U32 MAXADDRSTR = 17; // 123.567.901.345 = 15 chars + \0 +
// llclampb(a) // clamps a to [0 .. 255]
//
+// llless(d0, d1) safely compares d0 < d1 even if one is signed and the other
+// is unsigned. A simple (d0 < d1) expression converts the signed operand to
+// unsigned before comparing. If the signed operand is negative, that flips
+// the negative value to a huge positive value, producing the wrong answer!
+// llless() specifically addresses that case.
+template <typename T0, typename T1>
+constexpr bool llless(T0 d0, T1 d1)
+{
+ if constexpr (std::is_signed_v<T0> && ! std::is_signed_v<T1>)
+ {
+ // T0 signed, T1 unsigned: negative d0 is less than any unsigned d1
+ if (d0 < 0)
+ return true;
+ // both are non-negative: explicitly cast to avoid C4018
+ return std::make_unsigned_t<T0>(d0) < d1;
+ }
+ else if constexpr (! std::is_signed_v<T0> && std::is_signed_v<T1>)
+ {
+ // T0 unsigned, T1 signed: any unsigned d0 is greater than negative d1
+ if (d1 < 0)
+ return false;
+ // both are non-negative: explicitly cast to avoid C4018
+ return d0 < std::make_unsigned_t<T1>(d1);
+ }
+ else
+ {
+ // both T0 and T1 are signed, or both are unsigned:
+ // straightforward comparison works
+ return d0 < d1;
+ }
+}
+
// recursion tail
template <typename T>
constexpr auto llmax(T data)
@@ -180,7 +213,7 @@ template <typename T0, typename T1, typename... Ts>
constexpr auto llmax(T0 d0, T1 d1, Ts... rest)
{
auto maxrest = llmax(d1, rest...);
- return (d0 > maxrest)? d0 : maxrest;
+ return llless(maxrest, d0)? d0 : maxrest;
}
// recursion tail
@@ -194,12 +227,28 @@ template <typename T0, typename T1, typename... Ts>
constexpr auto llmin(T0 d0, T1 d1, Ts... rest)
{
auto minrest = llmin(d1, rest...);
- return (d0 < minrest) ? d0 : minrest;
+ return llless(d0, minrest) ? d0 : minrest;
}
template <typename A, typename MIN, typename MAX>
constexpr A llclamp(A a, MIN minval, MAX maxval)
{
+ // The only troublesome case is if A is unsigned and either minval or
+ // maxval is both signed and negative. Casting a negative number to
+ // unsigned flips it to a huge positive number, making this llclamp() call
+ // ineffective.
+ if constexpr (! std::is_signed_v<A>)
+ {
+ if constexpr (std::is_signed_v<MIN>)
+ {
+ assert(minval >= 0);
+ }
+ if constexpr (std::is_signed_v<MAX>)
+ {
+ assert(maxval >= 0);
+ }
+ }
+
A aminval{ static_cast<A>(minval) }, amaxval{ static_cast<A>(maxval) };
if ( a < aminval )
{
@@ -225,7 +274,7 @@ constexpr LLDATATYPE llclampb(LLDATATYPE a)
}
template <class LLDATATYPE>
-inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs)
+constexpr void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs)
{
std::swap(lhs, rhs);
}
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 3411e9c6bb..fc08ec8c8f 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -133,6 +133,7 @@ namespace {
RecordToFile(const std::string& filename):
mName(filename)
{
+ showMultiline(true);
mFile.open(filename.c_str(), std::ios_base::out | std::ios_base::app);
if (!mFile)
{
@@ -344,6 +345,51 @@ namespace {
}
};
#endif
+
+#if LL_PROFILER_CONFIGURATION >= LL_PROFILER_CONFIG_TRACY
+ class RecordToTracy : public LLError::Recorder
+ {
+ public:
+ RecordToTracy()
+ {
+ this->showMultiline(true);
+ this->showTags(false);
+ this->showLocation(false);
+ }
+
+ virtual bool enabled() override { return LLError::getEnabledLogTypesMask() & 0x12; }
+
+ virtual void recordMessage(LLError::ELevel level, const std::string& message) override
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
+ switch (level)
+ {
+ case LLError::LEVEL_DEBUG:
+ {
+ TracyMessageC(message.c_str(), message.size(), tracy::Color::Turquoise);
+ break;
+ }
+ default:
+ case LLError::LEVEL_NONE:
+ case LLError::LEVEL_INFO:
+ {
+ TracyMessageC(message.c_str(), message.size(), tracy::Color::White);
+ break;
+ }
+ case LLError::LEVEL_WARN:
+ {
+ TracyMessageC(message.c_str(), message.size(), tracy::Color::Yellow);
+ break;
+ }
+ case LLError::LEVEL_ERROR:
+ {
+ TracyMessageC(message.c_str(), message.size(), tracy::Color::Red);
+ break;
+ }
+ }
+ }
+ };
+#endif
}
@@ -759,6 +805,11 @@ namespace
LLError::addRecorder(recordToWinDebug);
#endif
+#if LL_PROFILER_CONFIGURATION >= LL_PROFILER_CONFIG_TRACY
+ LLError::RecorderPtr recordToTracy(new RecordToTracy());
+ LLError::addRecorder(recordToTracy);
+#endif
+
LogControlFile& e = LogControlFile::fromDirectory(user_dir, app_dir);
// NOTE: We want to explicitly load the file before we add it to the event timer
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index 41893a35e5..343cc47e4c 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -91,13 +91,8 @@ const int LL_ERR_NOERR = 0;
#define llverify(func) do {if (func) {}} while(0)
#endif
-#ifdef LL_WINDOWS
#define LL_STATIC_ASSERT(func, msg) static_assert(func, msg)
-#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) static_assert(false, msg)
-#else
-#define LL_STATIC_ASSERT(func, msg) BOOST_STATIC_ASSERT(func)
-#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) BOOST_STATIC_ASSERT(sizeof(type) != 0 && false);
-#endif
+#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) static_assert(sizeof(type) != 0 && false, msg)
/** Error Logging Facility
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 1c5fe9d2f5..c5a7a0e56b 100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -387,6 +387,11 @@ void BlockTimer::logStats()
}
+#if defined(LL_GNUC) && GCC_VERSION >= 130000
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wnonnull"
+#endif
+
//static
void BlockTimer::dumpCurTimes()
{
@@ -418,8 +423,12 @@ void BlockTimer::dumpCurTimes()
<< num_calls << " calls";
LL_INFOS() << out_str.str() << LL_ENDL;
+ }
}
-}
+
+#if defined(LL_GNUC) && GCC_VERSION >= 130000
+# pragma GCC diagnostic push
+#endif
//static
void BlockTimer::writeLog(std::ostream& os)
diff --git a/indra/llcommon/llfindlocale.cpp b/indra/llcommon/llfindlocale.cpp
index b4bcc80ac4..d606a6fdb9 100644
--- a/indra/llcommon/llfindlocale.cpp
+++ b/indra/llcommon/llfindlocale.cpp
@@ -134,7 +134,7 @@ accumulate_locstring(const char *str, FL_Locale *l) {
return 0;
}
-
+#ifndef LL_WINDOWS
static int
accumulate_env(const char *name, FL_Locale *l) {
char *env;
@@ -148,7 +148,7 @@ accumulate_env(const char *name, FL_Locale *l) {
free(lang); free(country); free(variant);
return 0;
}
-
+#endif
static void
canonise_fl(FL_Locale *l) {
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 92b26354a1..5a7f27e688 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -28,6 +28,8 @@
#ifndef LL_LLINSTANCETRACKER_H
#define LL_LLINSTANCETRACKER_H
+#include "llpreprocessor.h"
+
#include <map>
#include <set>
#include <vector>
@@ -244,6 +246,7 @@ public:
}
protected:
+ LL_UBSAN_SUPRESS_VPTR
LLInstanceTracker(const KEY& key)
{
// We do not intend to manage the lifespan of this object with
@@ -482,6 +485,7 @@ public:
using key_snapshot_of = instance_snapshot_of<SUBCLASS>;
protected:
+ LL_UBSAN_SUPRESS_VPTR
LLInstanceTracker()
{
// Since we do not intend for this shared_ptr to manage lifespan, give
diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp
index e36c1d0a4c..abb0df0b87 100644
--- a/indra/llcommon/llkeybind.cpp
+++ b/indra/llcommon/llkeybind.cpp
@@ -114,15 +114,6 @@ void LLKeyData::reset()
mIgnoreMasks = false;
}
-LLKeyData& LLKeyData::operator=(const LLKeyData& rhs)
-{
- mMouse = rhs.mMouse;
- mKey = rhs.mKey;
- mMask = rhs.mMask;
- mIgnoreMasks = rhs.mIgnoreMasks;
- return *this;
-}
-
bool LLKeyData::operator==(const LLKeyData& rhs)
{
if (mMouse != rhs.mMouse) return false;
diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h
index 1bbb2fadb5..0a9d4600cc 100644
--- a/indra/llcommon/llkeybind.h
+++ b/indra/llcommon/llkeybind.h
@@ -43,7 +43,6 @@ public:
bool isEmpty() const;
bool empty() const { return isEmpty(); };
void reset();
- LLKeyData& operator=(const LLKeyData& rhs);
bool operator==(const LLKeyData& rhs);
bool operator!=(const LLKeyData& rhs);
diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp
index c8ca586e7f..b05fd2e21b 100644
--- a/indra/llcommon/llmd5.cpp
+++ b/indra/llcommon/llmd5.cpp
@@ -255,13 +255,15 @@ void LLMD5::raw_digest(unsigned char* s) const
memcpy(s, digest, 16); /* Flawfinder: ignore */
}
-#if LL_DARWIN
+#if LL_CLANG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
void LLMD5::hex_digest(char* s) const
{
+ if(!s) return;
+
if (!finalized)
{
std::cerr << "LLMD5::hex_digest: Can't get digest if you haven't "
@@ -278,7 +280,7 @@ void LLMD5::hex_digest(char* s) const
s[32] = '\0';
}
-#if LL_DARWIN
+#if LL_CLANG
#pragma clang diagnostic pop
#endif
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index ba48319a16..9617e30f0b 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -146,9 +146,6 @@ void LLMemory::updateMemoryInfo()
LL_WARNS() << "task_info failed" << LL_ENDL;
}
#elif defined(LL_LINUX)
- // Use sysinfo() to get the total physical memory.
- struct sysinfo info;
- sysinfo(&info);
sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(LLMemory::getCurrentRSS())); // represents the RAM allocated by this process only (in line with the windows implementation)
#else
//not valid for other systems for now.
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index adc556d180..a25387d321 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -48,6 +48,9 @@ class LLMutex ;
#define LL_ALIGN_OF __align_of__
#endif
+#if defined(LL_X86_64) || defined(LL_ARM64)
+#define LL_DEFAULT_HEAP_ALIGN 16
+#else
#if LL_WINDOWS
#define LL_DEFAULT_HEAP_ALIGN 8
#elif LL_DARWIN
@@ -55,7 +58,7 @@ class LLMutex ;
#elif LL_LINUX
#define LL_DEFAULT_HEAP_ALIGN 8
#endif
-
+#endif
LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
@@ -89,22 +92,6 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
(uintptr_t(address) + 0x3F) & ~0x3F);
}
-#if LL_LINUX || LL_DARWIN
-
-#define LL_ALIGN_PREFIX(x)
-#define LL_ALIGN_POSTFIX(x) __attribute__((aligned(x)))
-
-#elif LL_WINDOWS
-
-#define LL_ALIGN_PREFIX(x) __declspec(align(x))
-#define LL_ALIGN_POSTFIX(x)
-
-#else
-#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined"
-#endif
-
-#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
-
#define LL_ALIGN_NEW \
public: \
void* operator new(size_t size) \
@@ -127,7 +114,6 @@ public: \
ll_aligned_free_16(ptr); \
}
-
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// for enable buffer overrun detection predefine LL_DEBUG_BUFFER_OVERRUN in current library
@@ -143,6 +129,10 @@ public: \
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
#if defined(LL_WINDOWS)
void* ret = _aligned_malloc(size, align);
+ #elif defined(LL_LINUX)
+ void *ret;
+ if (0 != posix_memalign(&ret, align, size))
+ return nullptr;
#else
char* aligned = NULL;
void* mem = malloc( size + (align - 1) + sizeof(void*) );
@@ -165,6 +155,8 @@ public: \
LL_PROFILE_FREE(ptr);
#if defined(LL_WINDOWS)
_aligned_free(ptr);
+ #elif defined(LL_LINUX)
+ free(ptr);
#else
if (ptr)
{
@@ -179,10 +171,10 @@ public: \
inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16().
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
-#if defined(LL_WINDOWS)
+#if LL_DEFAULT_HEAP_ALIGN == 16
+ void* ret = malloc(size); // default osx and 64-bit malloc is 16 byte aligned.
+#elif defined(LL_WINDOWS)
void* ret = _aligned_malloc(size, 16);
-#elif defined(LL_DARWIN)
- void* ret = malloc(size); // default osx malloc is 16 byte aligned.
#else
void *ret;
if (0 != posix_memalign(&ret, 16, size))
@@ -196,10 +188,10 @@ inline void ll_aligned_free_16(void *p)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
LL_PROFILE_FREE(p);
-#if defined(LL_WINDOWS)
+#if LL_DEFAULT_HEAP_ALIGN == 16
+ free(p);
+#elif defined(LL_WINDOWS)
_aligned_free(p);
-#elif defined(LL_DARWIN)
- return free(p);
#else
free(p); // posix_memalign() is compatible with heap deallocator
#endif
@@ -209,10 +201,10 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // r
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
LL_PROFILE_FREE(ptr);
-#if defined(LL_WINDOWS)
+#if LL_DEFAULT_HEAP_ALIGN == 16
+ void* ret = realloc(ptr,size); // default osx and 64bit malloc is 16 byte aligned.
+#elif defined(LL_WINDOWS)
void* ret = _aligned_realloc(ptr, size, 16);
-#elif defined(LL_DARWIN)
- void* ret = realloc(ptr,size); // default osx malloc is 16 byte aligned.
#else
//FIXME: memcpy is SLOW
void* ret = ll_aligned_malloc_16(size);
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index b2a9734548..104d3cc186 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -61,35 +61,48 @@
# define LL_UNLIKELY(EXPR) (EXPR)
#endif
-
// Figure out differences between compilers
-#if defined(__GNUC__)
+#if defined(__MSVC_VER__) || defined(_MSC_VER)
+ #ifndef LL_MSVC
+ #define LL_MSVC 1
+ #endif
+
+ // Clang CL is MSVC-like but also supports its own macros
+ #if defined(__clang__)
+ #ifndef LL_CLANG
+ #define LL_CLANG 1
+ #endif
+ #endif
+#elif defined(__clang__)
+ #define CLANG_VERSION (__clang_major__ * 10000 \
+ + __clang_minor__ * 100 \
+ + __clang_patchlevel__)
+ #ifndef LL_CLANG
+ #define LL_CLANG 1
+ #endif
+#elif defined(__GNUC__)
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#ifndef LL_GNUC
#define LL_GNUC 1
#endif
-#elif defined(__MSVC_VER__) || defined(_MSC_VER)
- #ifndef LL_MSVC
- #define LL_MSVC 1
- #endif
#endif
// Set up CPU architecture defines
#if LL_MSVC && defined(_M_ARM64)
# define LL_ARM64 1
-#elif LL_GNUC && (defined(__arm64__) || defined(__aarch64__))
+#elif (LL_GNUC || LL_CLANG) && (defined(__arm64__) || defined(__aarch64__))
# define LL_ARM64 1
#elif LL_MSVC && _M_X64
# define LL_X86_64 1
# define LL_X86 1
#elif LL_MSVC && _M_IX86
# define LL_X86 1
-#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) )
+#elif (LL_GNUC || LL_CLANG) && ( defined(__amd64__) || defined(__x86_64__) )
# define LL_X86_64 1
# define LL_X86 1
-#elif LL_GNUC && ( defined(__i386__) )
+#elif (LL_GNUC || LL_CLANG) && ( defined(__i386__) )
# define LL_X86 1
#endif
@@ -106,16 +119,6 @@
#endif
-// Although thread_local is now a standard storage class, we can't just
-// #define LL_THREAD_LOCAL as thread_local because the *usage* is different.
-// We'll have to take the time to change LL_THREAD_LOCAL declarations by hand.
-#if LL_WINDOWS
-# define LL_THREAD_LOCAL __declspec(thread)
-#else
-# define LL_THREAD_LOCAL __thread
-#endif
-
-
#if defined(LL_WINDOWS)
#define BOOST_REGEX_NO_LIB 1
#define CURL_STATICLIB 1
@@ -140,7 +143,7 @@
#define LL_DLLIMPORT
#endif // LL_WINDOWS
-#if __clang__ || ! defined(LL_WINDOWS)
+#if LL_CLANG || ! defined(LL_WINDOWS)
// Only on Windows, and only with the Microsoft compiler (vs. clang) is
// wchar_t potentially not a distinct type.
#define LL_WCHAR_T_NATIVE 1
@@ -201,6 +204,13 @@
#define LL_PRETTY_FUNCTION __PRETTY_FUNCTION__
#endif
+// vptr warning supression funtionality for undefined behavior sanitizer
+#if LL_CLANG || LL_GNUC
+# define LL_UBSAN_SUPRESS_VPTR __attribute__((no_sanitize("vptr")))
+#else
+# define LL_UBSAN_SUPRESS_VPTR
+#endif
+
#if LL_ARM64
#define GLM_FORCE_NEON 1
#else
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp
index 912e596c3f..2164fc1ad5 100644
--- a/indra/llcommon/llprocess.cpp
+++ b/indra/llcommon/llprocess.cpp
@@ -176,14 +176,14 @@ public:
// In general, our streambuf might contain a number of different
// physical buffers; iterate over those.
bool keepwriting = true;
- for (const_buffer_sequence::const_iterator bufi(bufs.begin()), bufend(bufs.end());
+ 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 = boost::asio::buffer_cast<const char*>(*bufi);
- std::size_t remainlen = boost::asio::buffer_size(*bufi);
+ const char* remainptr = static_cast<const char*>(bufi->data());
+ std::size_t remainlen = bufi->size();
while (remainlen)
{
// Tackle the current buffer in discrete chunks. On
@@ -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 (mutable_buffer_sequence::const_iterator bufi(bufs.begin()), bufend(bufs.end());
+ 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));
+ std::size_t toread(bufi->size());
apr_size_t gotten(toread);
apr_status_t err = apr_file_read(mPipe,
- boost::asio::buffer_cast<void*>(*bufi),
+ bufi->data(),
&gotten);
// EAGAIN is exactly what we want from a nonblocking pipe.
// Rather than waiting for data, it should return immediately.
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 718f471321..464578c2d9 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -741,7 +741,7 @@ private:
// *NOTE:Mani - I didn't find any docs that assure me that machdep.cpu.feature_bits will always be
// The feature bits I think it is. Here's a test:
-#ifndef LL_RELEASE_FOR_DOWNLOAD
+#if !defined(LL_RELEASE_FOR_DOWNLOAD) && !defined(LL_ARM64)
#if defined(__i386__) && defined(__PIC__)
/* %ebx may be the PIC register. */
#define __cpuid(level, a, b, c, d) \
@@ -808,6 +808,20 @@ private:
};
#elif LL_LINUX
+
+// *NOTE:Mani - eww, macros! srry.
+#define LLPI_SET_INFO_STRING(llpi_id, cpuinfo_id) \
+ if (!cpuinfo[cpuinfo_id].empty()) \
+ { setInfo(llpi_id, cpuinfo[cpuinfo_id]);}
+
+#define LLPI_SET_INFO_INT(llpi_id, cpuinfo_id) \
+ {\
+ S32 result; \
+ if (!cpuinfo[cpuinfo_id].empty() \
+ && LLStringUtil::convertToS32(cpuinfo[cpuinfo_id], result)) \
+ { setInfo(llpi_id, result);} \
+ }
+
const char CPUINFO_FILE[] = "/proc/cpuinfo";
class LLProcessorInfoLinuxImpl : public LLProcessorInfoImpl
@@ -819,8 +833,32 @@ public:
}
virtual ~LLProcessorInfoLinuxImpl() {}
+
private:
+ F64 getCPUMaxMHZ()
+ {
+ // Nicky: We just look into cpu0. In theory we could iterate over all cores
+ // "/sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_max_freq"
+ // But those should not fluctuate that much?
+ llifstream fIn{ "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" };
+
+ if( !fIn.is_open() )
+ return 0.0;
+
+ std::string strLine;
+ fIn >> strLine;
+ if( strLine.empty() )
+ return 0.0l;
+
+ F64 mhz {};
+ if( !LLStringUtil::convertToF64(strLine, mhz ) )
+ return 0.0;
+
+ mhz = mhz / 1000.0;
+ return mhz;
+ }
+
void get_proc_cpuinfo()
{
std::map< std::string, std::string > cpuinfo;
@@ -855,24 +893,17 @@ private:
}
# if LL_X86
-// *NOTE:Mani - eww, macros! srry.
-#define LLPI_SET_INFO_STRING(llpi_id, cpuinfo_id) \
- if (!cpuinfo[cpuinfo_id].empty()) \
- { setInfo(llpi_id, cpuinfo[cpuinfo_id]);}
-
-#define LLPI_SET_INFO_INT(llpi_id, cpuinfo_id) \
- {\
- S32 result; \
- if (!cpuinfo[cpuinfo_id].empty() \
- && LLStringUtil::convertToS32(cpuinfo[cpuinfo_id], result)) \
- { setInfo(llpi_id, result);} \
+ F64 mhzFromSys = getCPUMaxMHZ();
+ F64 mhzFromProc {};
+ if( !LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhzFromProc ) )
+ mhzFromProc = 0.0;
+ if (mhzFromSys > 1.0 && mhzFromSys > mhzFromProc )
+ {
+ setInfo( eFrequency, mhzFromSys );
}
-
- F64 mhz;
- if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz)
- && 200.0 < mhz && mhz < 10000.0)
+ else if ( 200.0 < mhzFromProc && mhzFromProc < 10000.0)
{
- setInfo(eFrequency,(F64)(mhz));
+ setInfo(eFrequency,(F64)(mhzFromProc));
}
LLPI_SET_INFO_STRING(eBrandName, "model name");
@@ -882,7 +913,7 @@ private:
LLPI_SET_INFO_INT(eModel, "model");
- S32 family;
+ S32 family{};
if (!cpuinfo["cpu family"].empty()
&& LLStringUtil::convertToS32(cpuinfo["cpu family"], family))
{
diff --git a/indra/llcommon/llprocinfo.cpp b/indra/llcommon/llprocinfo.cpp
index 69be00e14a..9fe4af2103 100644
--- a/indra/llcommon/llprocinfo.cpp
+++ b/indra/llcommon/llprocinfo.cpp
@@ -25,6 +25,7 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
#include "llprocinfo.h"
diff --git a/indra/llcommon/llprofiler.cpp b/indra/llcommon/llprofiler.cpp
index bdddabf977..b2ac7723d4 100644
--- a/indra/llcommon/llprofiler.cpp
+++ b/indra/llcommon/llprofiler.cpp
@@ -25,6 +25,6 @@
* $/LicenseInfo$
*/
-#include "linden_common.h"
+#include "llpreprocessor.h"
#include "TracyClient.cpp"
diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h
index 5fb32d6280..7c77d94475 100644
--- a/indra/llcommon/llprofiler.h
+++ b/indra/llcommon/llprofiler.h
@@ -76,7 +76,16 @@
#if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE)
#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER
+ #include "llpreprocessor.h"
+
+#if defined(LL_GNUC) && GCC_VERSION >= 130000
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wnonnull"
+#endif
#include "tracy/Tracy.hpp"
+#if defined(LL_GNUC) && GCC_VERSION >= 130000
+# pragma GCC diagnostic push
+#endif
// Enable RenderDoc labeling
//#define LL_PROFILER_ENABLE_RENDER_DOC 0
diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp
index 2c51e6f07f..513613f543 100644
--- a/indra/llcommon/llrand.cpp
+++ b/indra/llcommon/llrand.cpp
@@ -58,9 +58,26 @@
* to restore uniform distribution.
*/
-// gRandomGenerator is a stateful static object, which is therefore not
+// pRandomGenerator is a stateful static object, which is therefore not
// inherently thread-safe.
-static thread_local LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
+//We use a pointer to not construct a huge object in the TLS space, sadly this is necessary
+// due to libcef.so on Linux being compiled with TLS model initial-exec (resulting in
+// FLAG STATIC_TLS, see readelf libcef.so). CEFs own TLS objects + LLRandLagFib2281 then will exhaust the
+// available TLS space, causing media failure.
+
+static thread_local std::unique_ptr< LLRandLagFib2281 > pRandomGenerator = nullptr;
+
+namespace {
+ F64 ll_internal_get_rand()
+ {
+ if( !pRandomGenerator )
+ {
+ pRandomGenerator.reset(new LLRandLagFib2281(LLUUID::getRandomSeed( ) ));
+ }
+
+ return(*pRandomGenerator)();
+ }
+}
// no default implementation, only specific F64 and F32 specializations
template <typename REAL>
@@ -73,7 +90,7 @@ inline F64 ll_internal_random<F64>()
// CPUs (or at least multi-threaded processes) seem to
// occasionally give an obviously incorrect random number -- like
// 5^15 or something. Sooooo, clamp it as described above.
- F64 rv{ gRandomGenerator() };
+ F64 rv{ ll_internal_get_rand() };
if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0);
return rv;
}
@@ -85,7 +102,7 @@ inline F32 ll_internal_random<F32>()
// Per Monty, it's important to clamp using the correct fmodf() rather
// than expanding to F64 for fmod() and then truncating back to F32. Prior
// to this change, we were getting sporadic ll_frand() == 1.0 results.
- F32 rv{ narrow<F64>(gRandomGenerator()) };
+ F32 rv{ narrow<F64>(ll_internal_get_rand()) };
if(!((rv >= 0.0f) && (rv < 1.0f))) return fmodf(rv, 1.0f);
return rv;
}
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 77fe545c3f..ea6d6a308a 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -32,7 +32,6 @@
#include "llbase64.h"
#include "llerror.h"
-#include "../llmath/llmath.h"
#include "llformat.h"
#include "llsdserialize.h"
#include "stringize.h"
@@ -291,10 +290,10 @@ namespace
};
LLSD::Boolean ImplReal::asBoolean() const
- { return !llisnan(mValue) && mValue != 0.0; }
+ { return !std::isnan(mValue) && mValue != 0.0; }
LLSD::Integer ImplReal::asInteger() const
- { return !llisnan(mValue) ? (LLSD::Integer)mValue : 0; }
+ { return !std::isnan(mValue) ? (LLSD::Integer)mValue : 0; }
LLSD::String ImplReal::asString() const
{ return llformat("%lg", mValue); }
diff --git a/indra/llcommon/llsdjson.cpp b/indra/llcommon/llsdjson.cpp
index 655869a704..542a3c26e3 100644
--- a/indra/llcommon/llsdjson.cpp
+++ b/indra/llcommon/llsdjson.cpp
@@ -33,7 +33,6 @@
#include "llsdutil.h"
#include "llerror.h"
-#include "../llmath/llmath.h"
#include <boost/json/src.hpp>
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 37af366a20..3cc960698e 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -1424,11 +1424,7 @@ S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr,
case LLSD::TypeBoolean:
if(mBoolAlpha ||
-#if( LL_WINDOWS || __GNUC__ > 2)
(ostr.flags() & std::ios::boolalpha)
-#else
- (ostr.flags() & 0x0100)
-#endif
)
{
ostr << (data.asBoolean()
@@ -2397,6 +2393,7 @@ U8* unzip_llsdNavMesh( bool& valid, size_t& outsize, std::istream& is, S32 size
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
+ [[fallthrough]];
case Z_DATA_ERROR:
case Z_MEM_ERROR:
inflateEnd(&strm);
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index dbd89118c9..fd01484128 100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
@@ -503,7 +503,7 @@ bool filter_llsd_with_template(
* Helpers for llsd_matches()
*****************************************************************************/
// raw data used for LLSD::Type lookup
-struct Data
+struct LLSDData
{
LLSD::Type type;
const char* name;
@@ -534,7 +534,7 @@ public:
{
LL_PROFILE_ZONE_SCOPED;
- for (const Data *di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di)
+ for (const LLSDData*di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di)
{
mMap[di->type] = di->name;
}
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index 0088eeec67..779d822970 100644
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -523,18 +523,8 @@ llbind2nd(const _Operation& __oper, const _Tp& __x)
inline
bool before(const std::type_info* lhs, const std::type_info* rhs)
{
-#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
- // If we're building on Linux with gcc, and it's either gcc 3.x or
- // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on
- // Mac too, and some people build with gcc on Windows (cygwin or mingw).
- // On Linux, different load modules may produce different type_info*
- // pointers for the same type. Have to compare name strings to get good
- // results.
- return strcmp(lhs->name(), rhs->name()) < 0;
-#else // not Linux, or gcc 4.4+
// Just use before(), as we normally would
return lhs->before(*rhs);
-#endif
}
/**
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 270ca40086..e3335ca4aa 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -509,57 +509,46 @@ const S32 LLOSInfo::getOSBitness() const
return mOSBitness;
}
-//static
-U32 LLOSInfo::getProcessVirtualSizeKB()
-{
- U32 virtual_size = 0;
-#if LL_LINUX
-# define STATUS_SIZE 2048
- LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb");
- if (status_filep)
- {
- S32 numRead = 0;
- char buff[STATUS_SIZE]; /* Flawfinder: ignore */
+namespace {
- size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep);
- buff[nbytes] = '\0';
+ U32 readFromProcStat( std::string entryName )
+ {
+ U32 val{};
+#if LL_LINUX
+ constexpr U32 STATUS_SIZE = 2048;
- // All these guys return numbers in KB
- char *memp = strstr(buff, "VmSize:");
- if (memp)
+ LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb");
+ if (status_filep)
{
- numRead += sscanf(memp, "%*s %u", &virtual_size);
+ char buff[STATUS_SIZE]; /* Flawfinder: ignore */
+
+ size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep);
+ buff[nbytes] = '\0';
+
+ // All these guys return numbers in KB
+ char *memp = strstr(buff, entryName.c_str());
+ if (memp)
+ {
+ (void) sscanf(memp, "%*s %u", &val);
+ }
+ fclose(status_filep);
}
- fclose(status_filep);
- }
#endif
- return virtual_size;
+ return val;
+ }
+
}
//static
-U32 LLOSInfo::getProcessResidentSizeKB()
+U32 LLOSInfo::getProcessVirtualSizeKB()
{
- U32 resident_size = 0;
-#if LL_LINUX
- LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb");
- if (status_filep != NULL)
- {
- S32 numRead = 0;
- char buff[STATUS_SIZE]; /* Flawfinder: ignore */
-
- size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep);
- buff[nbytes] = '\0';
+ return readFromProcStat( "VmSize:" );
+}
- // All these guys return numbers in KB
- char *memp = strstr(buff, "VmRSS:");
- if (memp)
- {
- numRead += sscanf(memp, "%*s %u", &resident_size);
- }
- fclose(status_filep);
- }
-#endif
- return resident_size;
+//static
+U32 LLOSInfo::getProcessResidentSizeKB()
+{
+ return readFromProcStat( "VmRSS:" );
}
//static
@@ -724,7 +713,7 @@ public:
void add(const LLSD::String& name, const T& value,
typename boost::enable_if<boost::is_integral<T> >::type* = 0)
{
- mStats[name] = LLSD::Integer(value);
+ mStats[name] = LLSD::Integer(llmin<T>(value, S32_MAX));
}
// Store every floating-point type as LLSD::Real.
@@ -833,57 +822,8 @@ void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb)
}
#elif LL_LINUX
- // mStatsMap is derived from MEMINFO_FILE:
- // $ cat /proc/meminfo
- // MemTotal: 4108424 kB
- // MemFree: 1244064 kB
- // Buffers: 85164 kB
- // Cached: 1990264 kB
- // SwapCached: 0 kB
- // Active: 1176648 kB
- // Inactive: 1427532 kB
- // Active(anon): 529152 kB
- // Inactive(anon): 15924 kB
- // Active(file): 647496 kB
- // Inactive(file): 1411608 kB
- // Unevictable: 16 kB
- // Mlocked: 16 kB
- // HighTotal: 3266316 kB
- // HighFree: 721308 kB
- // LowTotal: 842108 kB
- // LowFree: 522756 kB
- // SwapTotal: 6384632 kB
- // SwapFree: 6384632 kB
- // Dirty: 28 kB
- // Writeback: 0 kB
- // AnonPages: 528820 kB
- // Mapped: 89472 kB
- // Shmem: 16324 kB
- // Slab: 159624 kB
- // SReclaimable: 145168 kB
- // SUnreclaim: 14456 kB
- // KernelStack: 2560 kB
- // PageTables: 5560 kB
- // NFS_Unstable: 0 kB
- // Bounce: 0 kB
- // WritebackTmp: 0 kB
- // CommitLimit: 8438844 kB
- // Committed_AS: 1271596 kB
- // VmallocTotal: 122880 kB
- // VmallocUsed: 65252 kB
- // VmallocChunk: 52356 kB
- // HardwareCorrupted: 0 kB
- // HugePages_Total: 0
- // HugePages_Free: 0
- // HugePages_Rsvd: 0
- // HugePages_Surp: 0
- // Hugepagesize: 2048 kB
- // DirectMap4k: 434168 kB
- // DirectMap2M: 477184 kB
- // (could also run 'free', but easier to read a file than run a program)
- LLSD statsMap(loadStatsMap());
-
- avail_mem_kb = (U32Kilobytes)statsMap["MemFree"].asInteger();
+ U64 phys = U64(getpagesize()) * U64(get_avphys_pages());
+ avail_mem_kb = U64Bytes(phys);
#else
//do not know how to collect available memory info for other systems.
//leave it blank here for now.
@@ -1083,7 +1023,7 @@ LLSD LLMemoryInfo::loadStatsMap()
}
#elif LL_LINUX
- std::ifstream meminfo(MEMINFO_FILE);
+ llifstream meminfo(MEMINFO_FILE);
if (meminfo.is_open())
{
// MemTotal: 4108424 kB
@@ -1123,9 +1063,10 @@ LLSD LLMemoryInfo::loadStatsMap()
LLSD::String key(matched[1].first, matched[1].second);
LLSD::String value_str(matched[2].first, matched[2].second);
LLSD::Integer value(0);
+ S64 intval = 0;
try
{
- value = boost::lexical_cast<LLSD::Integer>(value_str);
+ intval = llclamp(boost::lexical_cast<S64>(value_str), S32_MIN, S32_MAX);
}
catch (const boost::bad_lexical_cast&)
{
@@ -1134,6 +1075,7 @@ LLSD LLMemoryInfo::loadStatsMap()
<< line << LL_ENDL;
continue;
}
+ value = LLSD::Integer(intval);
// Store this statistic.
stats.add(key, value);
}
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 692941a892..e1f0d531cf 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -42,6 +42,10 @@
#include <sched.h>
#endif
+#if LL_DARWIN || LL_LINUX
+#include <pthread.h>
+#endif
+
#ifdef LL_WINDOWS
@@ -56,25 +60,32 @@ typedef struct tagTHREADNAME_INFO
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
+#endif
-void set_thread_name( DWORD dwThreadID, const char* threadName)
+void set_thread_name(const char* threadName)
{
+#if LL_WINDOWS
THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = threadName;
- info.dwThreadID = dwThreadID;
- info.dwFlags = 0;
+ info.dwType = 0x1000;
+ info.szName = threadName;
+ info.dwThreadID = GetCurrentThreadId();
+ info.dwFlags = 0;
__try
{
- ::RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR*)&info );
+ ::RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (ULONG_PTR*)&info);
}
- __except(EXCEPTION_CONTINUE_EXECUTION)
+ __except (EXCEPTION_CONTINUE_EXECUTION)
{
}
-}
+#elif LL_DARWIN
+ std::string truncated_name(std::string_view(threadName).substr(0, 15));
+ pthread_setname_np(truncated_name.c_str());
+#elif LL_LINUX
+ std::string truncated_name(std::string_view(threadName).substr(0, 15));
+ pthread_setname_np(pthread_self(), truncated_name.c_str());
#endif
-
+}
//----------------------------------------------------------------------------
// Usage:
@@ -148,27 +159,12 @@ LL_COMMON_API bool assert_main_thread()
return false;
}
-// this function has become moot
-void LLThread::registerThreadID() {}
-
//
// Handed to the APR thread creation function
//
void LLThread::threadRun()
{
-#ifdef LL_WINDOWS
- set_thread_name(-1, mName.c_str());
-
-#if 0 // probably a bad idea, see usage of SetThreadIdealProcessor in LLWindowWin32)
- HANDLE hThread = GetCurrentThread();
- if (hThread)
- {
- SetThreadAffinityMask(hThread, (DWORD_PTR) 0xFFFFFFFFFFFFFFFE);
- }
-#endif
-
-#endif
-
+ set_thread_name(mName.c_str());
LL_PROFILER_SET_THREAD_NAME( mName.c_str() );
// this is the first point at which we're actually running in the new thread
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 8794ac93aa..b97d479abc 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -28,10 +28,11 @@
#define LL_LLTHREAD_H
#include "llapr.h"
-#include "boost/intrusive_ptr.hpp"
#include "llrefcount.h"
#include <thread>
+extern void set_thread_name(const char* threadName);
+
namespace LLTrace
{
class ThreadRecorder;
@@ -86,11 +87,6 @@ public:
id_t getID() const { return mID; }
- // Called by threads *not* created via LLThread to register some
- // internal state used by LLMutex. You must call this once early
- // in the running thread to prevent collisions with the main thread.
- static void registerThreadID();
-
private:
bool mPaused;
std::thread::native_handle_type mNativeHandle; // for termination in case of issues
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index c23adca7e8..f010f0e961 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -32,11 +32,6 @@
#include "lltracethreadrecorder.h"
#include "llthread.h"
-inline F64 lerp(F64 a, F64 b, F64 u)
-{
- return a + ((b - a) * u);
-}
-
namespace LLTrace
{
@@ -302,7 +297,7 @@ F64 Recording::getMean( const StatType<SampleAccumulator>& stat )
{
t = (F64)active_accumulator->getSampleCount() / (F64)div;
}
- return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
+ return std::lerp(accumulator.getMean(), active_accumulator->getMean(), t);
}
else
{
@@ -388,7 +383,7 @@ F64 Recording::getMean( const StatType<EventAccumulator>& stat )
{
t = (F64)active_accumulator->getSampleCount() / (F64)div;
}
- return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
+ return std::lerp(accumulator.getMean(), active_accumulator->getMean(), t);
}
else
{
diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h
index f1e4c2bc78..6b98a6bc49 100644
--- a/indra/llcommon/stdtypes.h
+++ b/indra/llcommon/stdtypes.h
@@ -38,6 +38,11 @@ typedef signed short S16;
typedef unsigned short U16;
typedef signed int S32;
typedef unsigned int U32;
+typedef long long int S64;
+typedef long long unsigned int U64;
+
+#define S64L(a) (a##LL)
+#define U64L(a) (a##ULL)
// to express an index that might go negative
// (ssize_t is provided by SOME compilers, don't collide)
@@ -62,21 +67,6 @@ typedef wchar_t llwchar;
#define LLWCHAR_IS_WCHAR_T 1
#endif
-#if LL_WINDOWS
-typedef signed __int64 S64;
-// probably should be 'hyper' or similiar
-#define S64L(a) (a)
-typedef unsigned __int64 U64;
-#define U64L(a) (a)
-#else
-typedef long long int S64;
-typedef long long unsigned int U64;
-#if LL_DARWIN || LL_LINUX
-#define S64L(a) (a##LL)
-#define U64L(a) (a##ULL)
-#endif
-#endif
-
typedef float F32;
typedef double F64;
@@ -121,10 +111,6 @@ typedef U8 LLPCode;
#define LL_ARRAY_SIZE( _kArray ) ( sizeof( (_kArray) ) / sizeof( _kArray[0] ) )
-#if LL_LINUX && __GNUC__ <= 2
-typedef int intptr_t;
-#endif
-
/*****************************************************************************
* Narrowing
*****************************************************************************/
diff --git a/indra/llcommon/tests/commonmisc_test.cpp b/indra/llcommon/tests/commonmisc_test.cpp
index b1a284225e..80be26dfeb 100644
--- a/indra/llcommon/tests/commonmisc_test.cpp
+++ b/indra/llcommon/tests/commonmisc_test.cpp
@@ -503,7 +503,7 @@ namespace tut
result_str = (const char*) result;
ensure_equals("U64_to_str converted 1.4", val_str, result_str);
- val = U64L(-1); // 0xFFFFFFFFFFFFFFFF == 18446744073709551615
+ val = U64(-1); // 0xFFFFFFFFFFFFFFFF == 18446744073709551615
val_str = "18446744073709551615";
U64_to_str(val, result, sizeof(result));
result_str = (const char*) result;
@@ -619,7 +619,7 @@ namespace tut
val = U64_to_F64(U64L(2));
ensure_equals("U64_to_F64 converted 3.6", val, result);
- result = U64L(0x7FFFFFFFFFFFFFFF) * 1.0L; // 0x7FFFFFFFFFFFFFFF
+ result = F64(0x7FFFFFFFFFFFFFFF) * 1.0; // 0x7FFFFFFFFFFFFFFF
val = U64_to_F64(U64L(0x7FFFFFFFFFFFFFFF));
ensure_equals("U64_to_F64 converted 3.7", val, result);
}
diff --git a/indra/llcommon/tests/lldependencies_test.cpp b/indra/llcommon/tests/lldependencies_test.cpp
index 84eb41b5fe..0a4f0f38da 100644
--- a/indra/llcommon/tests/lldependencies_test.cpp
+++ b/indra/llcommon/tests/lldependencies_test.cpp
@@ -233,19 +233,7 @@ namespace tut
StringList keys(make<StringList>(list_of("The")("brown")("dog.")("fox")("jumps")("lazy")("over")("quick")("the")("yellow")));
ensure_equals(instance_from_range<StringList>(deps.get_key_range()), keys);
-#if (! defined(__GNUC__)) || (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
- // This is the succinct way, works on modern compilers
ensure_equals(instance_from_range<StringList>(make_transform_range(deps.get_range(), extract_key)), keys);
-#else // gcc 3.3
- StringDeps::range got_range(deps.get_range());
- StringDeps::iterator kni = got_range.begin(), knend = got_range.end();
- StringList::iterator ki = keys.begin(), kend = keys.end();
- for ( ; kni != knend && ki != kend; ++kni, ++ki)
- {
- ensure_equals(kni->first, *ki);
- }
- ensure("get_range() returns proper length", kni == knend && ki == kend);
-#endif // gcc 3.3
// blow off get_node_range() because they're all LLDependenciesEmpty instances
}
diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp
index 3ec429530c..653f64f1b6 100644
--- a/indra/llcommon/tests/llerror_test.cpp
+++ b/indra/llcommon/tests/llerror_test.cpp
@@ -59,8 +59,10 @@ static const char* FieldName[] =
namespace
{
-#ifdef __clang__
+#if defined(LL_CLANG)
# pragma clang diagnostic ignored "-Wunused-function"
+#elif defined(LL_GNUC)
+# pragma GCC diagnostic ignored "-Wunused-function"
#endif
void test_that_error_h_includes_enough_things_to_compile_a_message()
{
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index 13422612d6..4a88d69ded 100644
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -95,7 +95,7 @@ static std::string readfile(const std::string& pathname, const std::string& desc
{
use_desc = "in " + pathname;
}
- std::ifstream inf(pathname.c_str());
+ llifstream inf(pathname.c_str());
std::string output;
if (!std::getline(inf, output))
{
@@ -126,6 +126,8 @@ void waitfor(LLProcess& proc, int timeout=60)
{
yield();
}
+ // Pump once more after the process exits to flush any final events such as EOF.
+ yield(0);
std::string msg = "process took longer than " + std::to_string(timeout) + " seconds to terminate";
tut::ensure(msg, i < timeout);
}
@@ -137,6 +139,8 @@ void waitfor(LLProcess::handle h, const std::string& desc, int timeout=60)
{
yield();
}
+ // Pump once more after the process exits to flush any final events such as EOF.
+ yield(0);
std::string msg = "process took longer than " + std::to_string(timeout) + " seconds to terminate";
tut::ensure(msg, i < timeout);
}
@@ -182,7 +186,7 @@ struct PythonProcessLauncher
const char* APR_LOG = getenv("APR_LOG");
if (APR_LOG && *APR_LOG)
{
- std::ifstream inf(APR_LOG);
+ llifstream inf(APR_LOG);
if (! inf.is_open())
{
LL_WARNS() << "Couldn't open '" << APR_LOG << "'" << LL_ENDL;
@@ -834,7 +838,7 @@ namespace tut
// How do we know it's not terminated? By making it respond to
// a specific stimulus in a specific way.
{
- std::ofstream outf(to.getName().c_str());
+ llofstream outf(to.getName().c_str());
outf << "go";
} // flush and close.
// now wait for the script to terminate... one way or another.
@@ -897,7 +901,7 @@ namespace tut
// How do we know it's not terminated? By making it respond to
// a specific stimulus in a specific way.
{
- std::ofstream outf(to.getName().c_str());
+ llofstream outf(to.getName().c_str());
outf << "go";
} // flush and close.
// now wait for the script to terminate... one way or another.
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index fae9f7023f..ee315051d8 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -2117,7 +2117,7 @@ namespace tut
" f.write(lenformat.pack(len(serialized)))\n"
" f.write(serialized)\n";});
- std::ifstream inf(file.getName().c_str());
+ llifstream inf(file.getName().c_str());
LLSD item;
try
{
diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp
index b18712b8e9..f4366b2059 100644
--- a/indra/llcommon/tests/llstring_test.cpp
+++ b/indra/llcommon/tests/llstring_test.cpp
@@ -377,7 +377,7 @@ namespace tut
{
F32 value;
std::string str_val("2147483647"); //0x7FFFFFFF
- ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647);
+ ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647.f);
str_val = "0";
ensure("2: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 0);
@@ -399,7 +399,7 @@ namespace tut
{
F64 value;
std::string str_val("9223372036854775807"); //0x7FFFFFFFFFFFFFFF
- ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807LL);
+ ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807.0);
str_val = "0";
ensure("2: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 0.0F);
diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp
index 451e60c083..6adbdffba8 100644
--- a/indra/llcommon/threadpool.cpp
+++ b/indra/llcommon/threadpool.cpp
@@ -78,6 +78,7 @@ void LL::ThreadPoolBase::start()
std::string tname{ stringize(mName, ':', (i+1), '/', mThreadCount) };
mThreads.emplace_back(tname, [this, tname]()
{
+ set_thread_name(tname.c_str());
LL_PROFILER_SET_THREAD_NAME(tname.c_str());
run(tname);
});
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index fa37d23126..fbc25a7cd5 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -86,6 +86,7 @@ list(APPEND llcorehttp_SOURCE_FILES ${llcorehttp_HEADER_FILES})
add_library (llcorehttp ${llcorehttp_SOURCE_FILES})
target_link_libraries(
llcorehttp
+ llmath
llcommon
ll::libcurl
ll::openssl
@@ -98,6 +99,10 @@ target_include_directories( llcorehttp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
# lead to circular dependencies (or in case of cmake, the first project declaring it's dependencies wins)
target_include_directories( llcorehttp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../llmessage)
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llcorehttp REUSE_FROM llprecompiled)
+endif ()
+
# tests
set(LLCOREHTTP_TESTS ON CACHE BOOL
"Build and run llcorehttp integration tests specifically")
@@ -157,6 +162,7 @@ if (LL_TESTS AND LLCOREHTTP_TESTS)
set_target_properties(http_texture_load
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
+ FOLDER "Tests"
)
if (WINDOWS)
@@ -169,6 +175,13 @@ if (LL_TESTS AND LLCOREHTTP_TESTS)
)
endif (WINDOWS)
+ if(DARWIN)
+ set_target_properties(http_texture_load
+ PROPERTIES
+ OSX_ARCHITECTURES ${LL_MACOS_TEST_ARCHITECTURE}
+ )
+ endif()
+
target_link_libraries(http_texture_load ${example_libs})
endif (LL_TESTS AND LLCOREHTTP_TESTS)
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index 5880fb7e87..03a2eab8e3 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -283,12 +283,11 @@ void HttpService::shutdown()
// requested to stop.
void HttpService::threadRun(LLCoreInt::HttpThread * thread)
{
+ set_thread_name("HttpService");
LL_PROFILER_SET_THREAD_NAME("HttpService");
boost::this_thread::disable_interruption di;
- LLThread::registerThreadID();
-
ELoopSpeed loop(REQUEST_SLEEP);
while (! mExitRequested)
{
diff --git a/indra/llcorehttp/llhttpconstants.h b/indra/llcorehttp/llhttpconstants.h
index 71c1dfa173..d05d0f1af1 100755
--- a/indra/llcorehttp/llhttpconstants.h
+++ b/indra/llcorehttp/llhttpconstants.h
@@ -100,6 +100,8 @@ extern const std::string HTTP_VERB_POST;
extern const std::string HTTP_VERB_DELETE;
extern const std::string HTTP_VERB_MOVE;
extern const std::string HTTP_VERB_OPTIONS;
+extern const std::string HTTP_VERB_PATCH;
+extern const std::string HTTP_VERB_COPY;
enum EHTTPMethod
{
diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt
deleted file mode 100644
index 6ac73c0d32..0000000000
--- a/indra/llcrashlogger/CMakeLists.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- cmake -*-
-
-project(llcrashlogger)
-
-include(00-Common)
-include(LLCoreHttp)
-include(LLCommon)
-
-set(llcrashlogger_SOURCE_FILES
- llcrashlogger.cpp
- llcrashlock.cpp
- )
-
-set(llcrashlogger_HEADER_FILES
- CMakeLists.txt
- llcrashlogger.h
- llcrashlock.h
- )
-
-list(APPEND llcrashlogger_SOURCE_FILES ${llcrashlogger_HEADER_FILES})
-
-add_library(llcrashlogger ${llcrashlogger_SOURCE_FILES})
-target_link_libraries( llcrashlogger llcommon llmessage llcorehttp llxml llfilesystem )
diff --git a/indra/llcrashlogger/README.txt b/indra/llcrashlogger/README.txt
deleted file mode 100644
index 6932a8d9c3..0000000000
--- a/indra/llcrashlogger/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-This component is no longer used in Linden Lab builds.
-Change requests to support continued use by open source
-builds are welcome.
diff --git a/indra/llcrashlogger/llcrashlock.cpp b/indra/llcrashlogger/llcrashlock.cpp
deleted file mode 100644
index bc34f6798f..0000000000
--- a/indra/llcrashlogger/llcrashlock.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- * @file llformat.cpp
- * @date January 2007
- * @brief string formatting utility
- *
- * $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 "linden_common.h"
-
-#include "llapr.h" // thread-related functions
-#include "llcrashlock.h"
-#include "lldir.h"
-#include "llsd.h"
-#include "llsdserialize.h"
-#include "llframetimer.h"
-#include <boost/filesystem.hpp>
-#include <string>
-#include <iostream>
-#include <stdio.h>
-
-
-#if LL_WINDOWS //For windows platform.
-#include <llwin32headers.h>
-#include <TlHelp32.h>
-
-bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname)
-{
- std::wstring wpname = ll_convert_string_to_wide(pname);
-
- HANDLE snapshot;
- PROCESSENTRY32 pe32{};
-
- bool matched = false;
-
- snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (snapshot == INVALID_HANDLE_VALUE)
- {
- return false;
- }
- else
- {
- pe32.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(snapshot, &pe32))
- {
- do {
- std::wstring wexecname = pe32.szExeFile;
- std::string execname = ll_convert_wide_to_string(wexecname);
- if (!wpname.compare(pe32.szExeFile))
- {
- if (pid == (U32)pe32.th32ProcessID)
- {
- matched = true;
- break;
- }
- }
- } while (Process32Next(snapshot, &pe32));
- }
- }
-
- CloseHandle(snapshot);
- return matched;
-}
-
-#else //Everyone Else
-bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname)
-{
- //Will boost.process ever become a reality?
- std::stringstream cmd;
-
- cmd << "pgrep '" << pname << "' | grep '^" << pid << "$'";
- return (!system(cmd.str().c_str()));
-}
-#endif //Everyone else.
-
-
-LLCrashLock::LLCrashLock() : mCleanUp(true), mWaitingPID(0)
-{
-}
-
-void LLCrashLock::setCleanUp(bool cleanup)
-{
- mCleanUp = cleanup; //Allow cleanup to be disabled for debugging.
-}
-
-LLSD LLCrashLock::getLockFile(std::string filename)
-{
- LLSD lock_sd = LLSD::emptyMap();
-
- llifstream ifile(filename.c_str());
-
- if (ifile.is_open())
- {
- LLSDSerialize::fromXML(lock_sd, ifile);
- ifile.close();
- }
-
- return lock_sd;
-}
-
-bool LLCrashLock::putLockFile(std::string filename, const LLSD& data)
-{
- bool result = true;
- llofstream ofile(filename.c_str());
-
- if (!LLSDSerialize::toXML(data,ofile))
- {
- result=false;
- }
- ofile.close();
- return result;
-}
-
-bool LLCrashLock::requestMaster( F32 timeout )
-{
- if (mMaster.empty())
- {
- mMaster = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- "crash_master.lock");
- }
-
- LLSD lock_sd=getLockFile(mMaster);
-
- if (lock_sd.has("pid"))
- {
- mWaitingPID = lock_sd["pid"].asInteger();
- if ( isProcessAlive(mWaitingPID, gDirUtilp->getExecutableFilename()) )
- {
- mTimer.resetWithExpiry(timeout);
- return false;
- }
- }
-
- U32 pid = getpid();
- lock_sd["pid"] = (LLSD::Integer)pid;
- return putLockFile(mMaster,lock_sd);
-}
-
-bool LLCrashLock::checkMaster()
-{
- if (mWaitingPID)
- {
- return (!isProcessAlive(mWaitingPID, gDirUtilp->getExecutableFilename()));
- }
- return false;
-}
-
-bool LLCrashLock::isWaiting()
-{
- return !mTimer.hasExpired();
-}
-
-void LLCrashLock::releaseMaster()
-{
- //Yeeeeeeehaw
- unlink(mMaster.c_str());
-}
-
-LLSD LLCrashLock::getProcessList()
-{
- if (mDumpTable.empty())
- {
- mDumpTable= gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- "crash_table.lock");
- }
- return getLockFile(mDumpTable);
-}
-
-//static
-bool LLCrashLock::fileExists(std::string filename)
-{
-#ifdef LL_WINDOWS // or BOOST_WINDOWS_API
- boost::filesystem::path file_path(ll_convert<std::wstring>(filename));
-#else
- boost::filesystem::path file_path(filename);
-#endif
- return boost::filesystem::exists(file_path);
-}
-
-void LLCrashLock::cleanupProcess(std::string proc_dir)
-{
-#ifdef LL_WINDOWS // or BOOST_WINDOWS_API
- boost::filesystem::path dir_path(ll_convert<std::wstring>(proc_dir));
-#else
- boost::filesystem::path dir_path(proc_dir);
-#endif
- boost::filesystem::remove_all(dir_path);
-}
-
-bool LLCrashLock::putProcessList(const LLSD& proc_sd)
-{
- return putLockFile(mDumpTable,proc_sd);
-}
diff --git a/indra/llcrashlogger/llcrashlock.h b/indra/llcrashlogger/llcrashlock.h
deleted file mode 100644
index b20555b746..0000000000
--- a/indra/llcrashlogger/llcrashlock.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file llcrashlock.h
- * @brief Maintainence of disk locking files for crash reporting
- *
- * $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_CRASHLOCK_H
-#define LL_CRASHLOCK_H
-
-#include "llframetimer.h"
-
-class LLSD;
-
-#if !LL_WINDOWS //For non-windows platforms.
-#include <signal.h>
-#endif
-
-//Crash reporter will now be kicked off by the viewer but otherwise
-//run independent of the viewer.
-
-class LLCrashLock
-{
-public:
- LLCrashLock();
- bool requestMaster( F32 timeout=300.0); //Wait until timeout for master lock.
- bool checkMaster(); //True if available. False if not.
- void releaseMaster( ); //Release master lockfile.
- bool isLockPresent(std::string filename); //Check if lockfile exists.
- bool isProcessAlive(U32 pid, const std::string& pname); //Check if pid is alive.
- bool isWaiting(); //Waiting for master lock to be released.
- LLSD getProcessList(); //Get next process pid/dir pairs
- void cleanupProcess(std::string proc_dir); //Remove from list, clean up working dir.
- bool putProcessList(const LLSD& processlist); //Write pid/dir pairs back to disk.
- static bool fileExists(std::string filename);
-
-
- //getters
- S32 getPID();
-
- //setters
- void setCleanUp(bool cleanup=true);
- void setSaveName(std::string savename);
-private:
- LLSD getLockFile(std::string filename);
- bool putLockFile(std::string filename, const LLSD& data);
- bool mCleanUp;
- std::string mMaster;
- std::string mDumpTable;
- U32 mWaitingPID; //The process we're waiting on if any.
- LLFrameTimer mTimer;
-};
-
-#endif // LL_CRASHLOCK_H
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
deleted file mode 100644
index d5c585b45e..0000000000
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ /dev/null
@@ -1,682 +0,0 @@
- /**
-* @file llcrashlogger.cpp
-* @brief Crash logger implementation
-*
-* $LicenseInfo:firstyear=2003&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 <cstdio>
-#include <cstdlib>
-#include <sstream>
-#include <map>
-
-#include "llcrashlogger.h"
-#include "llcrashlock.h"
-#include "linden_common.h"
-#include "llstring.h"
-#include "indra_constants.h" // CRASH_BEHAVIOR_...
-#include "llerror.h"
-#include "llerrorcontrol.h"
-#include "lltimer.h"
-#include "lldir.h"
-#include "llfile.h"
-#include "llsdserialize.h"
-#include "llproxy.h"
-#include "llcorehttputil.h"
-#include "llhttpsdhandler.h"
-#include "httpcommon.h"
-#include "httpresponse.h"
-#include "llcleanup.h"
-
-#include <curl/curl.h>
-#include <openssl/crypto.h>
-
-bool gBreak = false;
-bool gSent = false;
-
-int LLCrashLogger::ssl_mutex_count = 0;
-LLCoreInt::HttpMutex ** LLCrashLogger::ssl_mutex_list = NULL;
-
-#define CRASH_UPLOAD_RETRIES 3 /* seconds */
-#define CRASH_UPLOAD_TIMEOUT 180 /* seconds */
-
-class LLCrashLoggerHandler : public LLHttpSDHandler
-{
- LOG_CLASS(LLCrashLoggerHandler);
-public:
- LLCrashLoggerHandler() {}
-
-protected:
- virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
- virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
-
-};
-
-void LLCrashLoggerHandler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
-{
- LL_DEBUGS("CRASHREPORT") << "Request to " << response->getRequestURL() << "succeeded" << LL_ENDL;
- gBreak = true;
- gSent = true;
-}
-
-void LLCrashLoggerHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
-{
- LL_WARNS("CRASHREPORT") << "Request to " << response->getRequestURL()
- << " failed: " << status.toString() << LL_ENDL;
- gBreak = true;
-}
-
-LLCrashLogger::LLCrashLogger() :
- mCrashBehavior(CRASH_BEHAVIOR_ALWAYS_SEND),
- mCrashInPreviousExec(false),
- mCrashSettings("CrashSettings"),
- mSentCrashLogs(false),
- mCrashHost("")
-{
-}
-
-LLCrashLogger::~LLCrashLogger()
-{
-
-}
-
-// TRIM_SIZE must remain larger than LINE_SEARCH_SIZE.
-const int TRIM_SIZE = 128000;
-const int LINE_SEARCH_DIST = 500;
-const std::string SKIP_TEXT = "\n ...Skipping... \n";
-void trimSLLog(std::string& sllog)
-{
- if(sllog.length() > TRIM_SIZE * 2)
- {
- std::string::iterator head = sllog.begin() + TRIM_SIZE;
- std::string::iterator tail = sllog.begin() + sllog.length() - TRIM_SIZE;
- std::string::iterator new_head = std::find(head, head - LINE_SEARCH_DIST, '\n');
- if(new_head != head - LINE_SEARCH_DIST)
- {
- head = new_head;
- }
-
- std::string::iterator new_tail = std::find(tail, tail + LINE_SEARCH_DIST, '\n');
- if(new_tail != tail + LINE_SEARCH_DIST)
- {
- tail = new_tail;
- }
-
- sllog.erase(head, tail);
- sllog.insert(head, SKIP_TEXT.begin(), SKIP_TEXT.end());
- }
-}
-
-std::string getStartupStateFromLog(std::string& sllog)
-{
- std::string startup_state = "STATE_FIRST";
- std::string startup_token = "Startup state changing from ";
-
- auto index = sllog.rfind(startup_token);
- if (index < 0 || index + startup_token.length() > sllog.length()) {
- return startup_state;
- }
-
- // find new line
- char cur_char = sllog[index + startup_token.length()];
- std::string::size_type newline_loc = index + startup_token.length();
- while(cur_char != '\n' && newline_loc < sllog.length())
- {
- newline_loc++;
- cur_char = sllog[newline_loc];
- }
-
- // get substring and find location of " to "
- std::string state_line = sllog.substr(index, newline_loc - index);
- std::string::size_type state_index = state_line.find(" to ");
- startup_state = state_line.substr(state_index + 4, state_line.length() - state_index - 4);
-
- return startup_state;
-}
-
-bool LLCrashLogger::readFromXML(LLSD& dest, const std::string& filename )
-{
- std::string db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,filename);
- llifstream log_file(db_file_name.c_str());
-
- // Look for it in the given file
- if (log_file.is_open())
- {
- LLSDSerialize::fromXML(dest, log_file);
- log_file.close();
- return true;
- }
- else
- {
- LL_WARNS("CRASHREPORT") << "Failed to open " << db_file_name << LL_ENDL;
- }
- return false;
-}
-
-void LLCrashLogger::mergeLogs( LLSD src_sd )
-{
- LLSD::map_iterator iter = src_sd.beginMap();
- LLSD::map_iterator end = src_sd.endMap();
- for( ; iter != end; ++iter)
- {
- mDebugLog[iter->first] = iter->second;
- }
-}
-
-bool LLCrashLogger::readMinidump(std::string minidump_path)
-{
- size_t length=0;
-
- llifstream minidump_stream(minidump_path.c_str(), std::ios_base::in | std::ios_base::binary);
- if (minidump_stream.is_open())
- {
- minidump_stream.seekg(0, std::ios::end);
- length = (size_t)minidump_stream.tellg();
- LL_WARNS("CRASHREPORT") << "minidump length "<< length <<LL_ENDL;
- minidump_stream.seekg(0, std::ios::beg);
-
- LLSD::Binary data;
- data.resize(length);
-
- minidump_stream.read(reinterpret_cast<char *>(&(data[0])),length);
- minidump_stream.close();
-
- mCrashInfo["Minidump"] = data;
- }
- else
- {
- LL_WARNS("CRASHREPORT") << "failed to open minidump "<<minidump_path<<LL_ENDL;
- }
-
- return length > 0;
-}
-
-void LLCrashLogger::gatherFiles()
-{
- updateApplication("Gathering logs...");
-
- LLSD static_sd;
- LLSD dynamic_sd;
- //if we ever want to change the endpoint we send crashes to
- //we can construct a file download ( a la feature table filename for example)
- //containing the new endpoint
- LLSD endpoint;
- std::string grid;
- std::string fqdn;
-
- bool has_logs = readFromXML( static_sd, "static_debug_info.log" );
- has_logs |= readFromXML( dynamic_sd, "dynamic_debug_info.log" );
-
-
- if ( has_logs )
- {
- mDebugLog = static_sd;
- mergeLogs(dynamic_sd);
- mCrashInPreviousExec = mDebugLog["CrashNotHandled"].asBoolean();
-
- mFileMap["SecondLifeLog"] = mDebugLog["SLLog"].asString();
- mFileMap["SettingsXml"] = mDebugLog["SettingsFilename"].asString();
- mFileMap["CrashHostUrl"] = loadCrashURLSetting();
- if(mDebugLog.has("CAFilename"))
- {
- LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_CA_FILE,
- LLCore::HttpRequest::GLOBAL_POLICY_ID, mDebugLog["CAFilename"].asString(), NULL);
- }
- else
- {
- LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_CA_FILE,
- LLCore::HttpRequest::GLOBAL_POLICY_ID, gDirUtilp->getCAFile(), NULL);
- }
-
- LL_INFOS("CRASHREPORT") << "Using log file from debug log " << mFileMap["SecondLifeLog"] << LL_ENDL;
- LL_INFOS("CRASHREPORT") << "Using settings file from debug log " << mFileMap["SettingsXml"] << LL_ENDL;
- }
- else
- {
- // Figure out the filename of the second life log
- LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_CA_FILE,
- LLCore::HttpRequest::GLOBAL_POLICY_ID, gDirUtilp->getCAFile(), NULL);
-
- mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
- mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");
- }
-
- if (!gDirUtilp->fileExists(mFileMap["SecondLifeLog"]) ) //We would prefer to get this from the per-run but here's our fallback.
- {
- mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old");
- }
-
- gatherPlatformSpecificFiles();
-
-
- if ( has_logs && (mFileMap["CrashHostUrl"] != "") )
- {
- mCrashHost = mFileMap["CrashHostUrl"];
- }
-
- //default to agni, per product
- mAltCrashHost = "http://viewercrashreport.agni.lindenlab.com/cgi-bin/viewercrashreceiver.py";
-
- mCrashInfo["DebugLog"] = mDebugLog;
- mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"stats.log");
-
- updateApplication("Encoding files...");
-
- for(std::map<std::string, std::string>::iterator itr = mFileMap.begin(); itr != mFileMap.end(); ++itr)
- {
- std::string file = (*itr).second;
- if (!file.empty())
- {
- LL_DEBUGS("CRASHREPORT") << "trying to read " << itr->first << ": " << file << LL_ENDL;
- llifstream f(file.c_str());
- if(f.is_open())
- {
- std::stringstream s;
- s << f.rdbuf();
-
- std::string crash_info = s.str();
- if(itr->first == "SecondLifeLog")
- {
- if(!mCrashInfo["DebugLog"].has("StartupState"))
- {
- mCrashInfo["DebugLog"]["StartupState"] = getStartupStateFromLog(crash_info);
- }
- trimSLLog(crash_info);
- }
-
- mCrashInfo[(*itr).first] = LLStringFn::strip_invalid_xml(rawstr_to_utf8(crash_info));
- }
- else
- {
- LL_WARNS("CRASHREPORT") << "Failed to open file " << file << LL_ENDL;
- }
- }
- else
- {
- LL_DEBUGS("CRASHREPORT") << "empty file in list for " << itr->first << LL_ENDL;
- }
- }
-
- std::string minidump_path;
- // Add minidump as binary.
- bool has_minidump = mDebugLog.has("MinidumpPath");
-
- if (has_minidump)
- {
- minidump_path = mDebugLog["MinidumpPath"].asString();
- has_minidump = readMinidump(minidump_path);
- }
- else
- {
- LL_WARNS("CRASHREPORT") << "DebugLog does not have MinidumpPath" << LL_ENDL;
- }
-
- if (!has_minidump) //Viewer was probably so hosed it couldn't write remaining data. Try brute force.
- {
- //Look for a filename at least 30 characters long in the dump dir which contains the characters MDMP as the first 4 characters in the file.
- typedef std::vector<std::string> vec;
- std::string pathname = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"");
- LL_WARNS("CRASHREPORT") << "Searching for minidump in " << pathname << LL_ENDL;
- vec file_vec = gDirUtilp->getFilesInDir(pathname);
- for(vec::const_iterator iter=file_vec.begin(); !has_minidump && iter!=file_vec.end(); ++iter)
- {
- if ( ( iter->length() > 30 ) && (iter->rfind(".dmp") == (iter->length()-4) ) )
- {
- std::string fullname = pathname + *iter;
- llifstream fdat(fullname.c_str(), std::ifstream::binary);
- if (fdat)
- {
- char buf[5];
- fdat.read(buf,4);
- fdat.close();
- if (!strncmp(buf,"MDMP",4))
- {
- minidump_path = *iter;
- has_minidump = readMinidump(fullname);
- mDebugLog["MinidumpPath"] = fullname;
- }
- else
- {
- LL_DEBUGS("CRASHREPORT") << "MDMP not found in " << fullname << LL_ENDL;
- }
- }
- else
- {
- LL_DEBUGS("CRASHREPORT") << "failed to open " << fullname << LL_ENDL;
- }
- }
- else
- {
- LL_DEBUGS("CRASHREPORT") << "Name does not match minidump name pattern " << *iter << LL_ENDL;
- }
- }
- }
- else
- {
- LL_WARNS("CRASHREPORT") << "readMinidump returned no minidump" << LL_ENDL;
- }
-}
-
-LLSD LLCrashLogger::constructPostData()
-{
- return mCrashInfo;
-}
-
-const char* const CRASH_SETTINGS_FILE = "settings_crash_behavior.xml";
-
-std::string LLCrashLogger::loadCrashURLSetting()
-{
-
- // First check user_settings (in the user's home dir)
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
- if (! mCrashSettings.loadFromFile(filename))
- {
- // Next check app_settings (in the SL program dir)
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, CRASH_SETTINGS_FILE);
- mCrashSettings.loadFromFile(filename);
- }
-
- if (! mCrashSettings.controlExists("CrashHostUrl"))
- {
- return "";
- }
- else
- {
- return mCrashSettings.getString("CrashHostUrl");
- }
-}
-
-bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout)
-{
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setTimeout(timeout);
- httpOpts->setSSLVerifyPeer(false);
-
- for(int i = 0; i < retries; ++i)
- {
- updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));
-
- LL_INFOS("CRASHREPORT") << "POST crash data to " << host << LL_ENDL;
- LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(httpRequest.get(), LLCore::HttpRequest::DEFAULT_POLICY_ID,
- host, data, httpOpts, LLCore::HttpHeaders::ptr_t(), LLCore::HttpHandler::ptr_t(new LLCrashLoggerHandler));
-
- if (handle == LLCORE_HTTP_HANDLE_INVALID)
- {
- LLCore::HttpStatus status = httpRequest->getStatus();
- LL_WARNS("CRASHREPORT") << "Request POST failed to " << host << " with status of [" <<
- status.getType() << "]\"" << status.toString() << "\"" << LL_ENDL;
- return false;
- }
-
- while(!gBreak)
- {
- ms_sleep(250);
- updateApplication(); // No new message, just pump the IO
- httpRequest->update(0L);
- }
- if(gSent)
- {
- return gSent;
- }
-
- LL_WARNS("CRASHREPORT") << "Failed to send crash report to \"" << host << "\"" << LL_ENDL;
- }
- return gSent;
-}
-
-bool LLCrashLogger::sendCrashLog(std::string dump_dir)
-{
-
- gDirUtilp->setDumpDir( dump_dir );
-
- std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- "SecondLifeCrashReport");
- std::string report_file = dump_path + ".log";
-
- LL_DEBUGS("CRASHREPORT") << "sending " << report_file << LL_ENDL;
-
- gatherFiles();
-
- LLSD post_data;
- post_data = constructPostData();
-
- updateApplication("Sending reports...");
-
- llofstream out_file(report_file.c_str());
- LLSDSerialize::toPrettyXML(post_data, out_file);
- out_file.flush();
- out_file.close();
-
- bool sent = false;
-
- if(mCrashHost != "")
- {
- LL_WARNS("CRASHREPORT") << "Sending crash data to server from CrashHostUrl '" << mCrashHost << "'" << LL_ENDL;
-
- std::string msg = "Using override crash server... ";
- msg = msg+mCrashHost.c_str();
- updateApplication(msg.c_str());
-
- sent = runCrashLogPost(mCrashHost, post_data, std::string("Sending to server"), CRASH_UPLOAD_RETRIES, CRASH_UPLOAD_TIMEOUT);
- }
-
- if(!sent)
- {
- updateApplication("Using default server...");
- sent = runCrashLogPost(mAltCrashHost, post_data, std::string("Sending to default server"), CRASH_UPLOAD_RETRIES, CRASH_UPLOAD_TIMEOUT);
- }
-
- mSentCrashLogs = sent;
-
- return sent;
-}
-
-bool LLCrashLogger::sendCrashLogs()
-{
- LLSD locks = mKeyMaster.getProcessList();
- LLSD newlocks = LLSD::emptyArray();
-
- LLSD opts = getOptionData(PRIORITY_COMMAND_LINE);
- LLSD rec;
-
- if ( opts.has("pid") && opts.has("dumpdir") && opts.has("procname") )
- {
- rec["pid"]=opts["pid"];
- rec["dumpdir"]=opts["dumpdir"];
- rec["procname"]=opts["procname"];
- }
-
- if (locks.isArray())
- {
- for (LLSD::array_iterator lock=locks.beginArray();
- lock !=locks.endArray();
- ++lock)
- {
- if ( (*lock).has("pid") && (*lock).has("dumpdir") && (*lock).has("procname") )
- {
- if ( mKeyMaster.isProcessAlive( (*lock)["pid"].asInteger(), (*lock)["procname"].asString() ) )
- {
- newlocks.append(*lock);
- }
- else
- {
- //TODO: This is a hack but I didn't want to include boost in another file or retest everything related to lldir
- if (LLCrashLock::fileExists((*lock)["dumpdir"].asString()))
- {
- //the viewer cleans up the log directory on clean shutdown
- //but is ignorant of the locking table.
- if (!sendCrashLog((*lock)["dumpdir"].asString()))
- {
- newlocks.append(*lock); //Failed to send log so don't delete it.
- }
- else
- {
- mKeyMaster.cleanupProcess((*lock)["dumpdir"].asString());
- }
- }
- }
- }
- else
- {
- LL_INFOS() << "Discarding corrupted entry from lock table." << LL_ENDL;
- }
- }
- }
-
- if (rec)
- {
- newlocks.append(rec);
- }
-
- mKeyMaster.putProcessList(newlocks);
- return true;
-}
-
-void LLCrashLogger::updateApplication(const std::string& message)
-{
- if (!message.empty()) LL_INFOS("CRASHREPORT") << message << LL_ENDL;
-}
-
-bool LLCrashLogger::init()
-{
- LL_DEBUGS("CRASHREPORT") << LL_ENDL;
-
- LLCore::LLHttp::initialize();
-
- // We assume that all the logs we're looking for reside on the current drive
- gDirUtilp->initAppDirs("SecondLife");
-
- LLError::initForApplication(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""), gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
-
- // Default to the product name "Second Life" (this is overridden by the -name argument)
- mProductName = "Second Life";
-
- // Rename current log file to ".old"
- std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log.old");
- std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log");
-
- LLFile::rename(log_file.c_str(), old_log_file.c_str());
-
- // Set the log file to crashreport.log
- LLError::logToFile(log_file); //NOTE: Until this line, LL_INFOS LL_WARNS, etc are blown to the ether.
-
- LL_INFOS("CRASHREPORT") << "Crash reporter file rotation complete." << LL_ENDL;
-
- // Handle locking
- bool locked = mKeyMaster.requestMaster(); //Request master locking file. wait time is defaulted to 300S
-
- while (!locked && mKeyMaster.isWaiting())
- {
- LL_INFOS("CRASHREPORT") << "Waiting for lock." << LL_ENDL;
-#if LL_WINDOWS
- Sleep(1000);
-#else
- ::sleep(1);
-#endif
- locked = mKeyMaster.checkMaster();
- }
-
- if (!locked)
- {
- LL_WARNS("CRASHREPORT") << "Unable to get master lock. Another crash reporter may be hung." << LL_ENDL;
- return false;
- }
-
- mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ALWAYS_SEND,
- "Controls behavior when viewer crashes "
- "(0 = ask before sending crash report, "
- "1 = always send crash report, "
- "2 = never send crash report)");
-
- init_curl();
- LLCore::HttpRequest::createService();
- LLCore::HttpRequest::startThread();
-
- return true;
-}
-
-// For cleanup code common to all platforms.
-void LLCrashLogger::commonCleanup()
-{
- term_curl();
- LLError::logToFile(""); //close crashreport.log
- SUBSYSTEM_CLEANUP(LLProxy);
-}
-
-void LLCrashLogger::init_curl()
-{
- curl_global_init(CURL_GLOBAL_ALL);
-
- ssl_mutex_count = CRYPTO_num_locks();
- if (ssl_mutex_count > 0)
- {
- ssl_mutex_list = new LLCoreInt::HttpMutex *[ssl_mutex_count];
-
- for (int i(0); i < ssl_mutex_count; ++i)
- {
- ssl_mutex_list[i] = new LLCoreInt::HttpMutex;
- }
-
- CRYPTO_set_locking_callback(ssl_locking_callback);
- CRYPTO_THREADID_set_callback(ssl_thread_id_callback);
- }
-}
-
-
-void LLCrashLogger::term_curl()
-{
- CRYPTO_set_locking_callback(NULL);
- for (int i(0); i < ssl_mutex_count; ++i)
- {
- delete ssl_mutex_list[i];
- }
- delete[] ssl_mutex_list;
-}
-
-
-void LLCrashLogger::ssl_thread_id_callback(CRYPTO_THREADID* pthreadid)
-{
-#if LL_WINDOWS
- CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread());
-#else
- CRYPTO_THREADID_set_pointer(pthreadid, reinterpret_cast<void*>(pthread_self()));
-#endif
-}
-
-
-void LLCrashLogger::ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */)
-{
- if (type >= 0 && type < ssl_mutex_count)
- {
- if (mode & CRYPTO_LOCK)
- {
- ssl_mutex_list[type]->lock();
- }
- else
- {
- ssl_mutex_list[type]->unlock();
- }
- }
-}
-
diff --git a/indra/llcrashlogger/llcrashlogger.h b/indra/llcrashlogger/llcrashlogger.h
deleted file mode 100644
index e5bf19434a..0000000000
--- a/indra/llcrashlogger/llcrashlogger.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
-* @file llcrashlogger.h
-* @brief Crash Logger Definition
-*
-* $LicenseInfo:firstyear=2003&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 LLCRASHLOGGER_H
-#define LLCRASHLOGGER_H
-
-#include <vector>
-
-#include "linden_common.h"
-
-#include "llapp.h"
-#include "llsd.h"
-#include "llcontrol.h"
-#include "llcrashlock.h"
-#include "_mutex.h"
-
-// We shouldn't have to know the exact declaration of CRYPTO_THREADID, but VS
-// 2017 complains if we forward-declare it as simply 'struct CRYPTO_THREADID'.
-struct crypto_threadid_st;
-typedef crypto_threadid_st CRYPTO_THREADID;
-
-// Crash reporter behavior
-const S32 CRASH_BEHAVIOR_ASK = 0;
-const S32 CRASH_BEHAVIOR_ALWAYS_SEND = 1;
-const S32 CRASH_BEHAVIOR_NEVER_SEND = 2;
-
-class LLCrashLogger : public LLApp
-{
-public:
- LLCrashLogger();
- virtual ~LLCrashLogger();
- std::string loadCrashURLSetting();
- bool readFromXML(LLSD& dest, const std::string& filename );
- void gatherFiles();
- void mergeLogs( LLSD src_sd );
-
- virtual void gatherPlatformSpecificFiles() {}
- bool sendCrashLog(std::string dump_dir);
- bool sendCrashLogs();
- LLSD constructPostData();
- virtual void updateApplication(const std::string& message = LLStringUtil::null);
- virtual bool init();
- virtual bool frame() = 0;
- virtual bool cleanup() = 0;
- void commonCleanup();
- void setUserText(const std::string& text) { mCrashInfo["UserNotes"] = text; }
- S32 getCrashBehavior() { return mCrashBehavior; }
- bool runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout);
- bool readMinidump(std::string minidump_path);
-
-protected:
- static void init_curl();
- static void term_curl();
- static void ssl_thread_id_callback(CRYPTO_THREADID*);
- static void ssl_locking_callback(int mode, int type, const char * file, int line);
-
- S32 mCrashBehavior;
- bool mCrashInPreviousExec;
- std::map<std::string, std::string> mFileMap;
- std::string mGridName;
- LLControlGroup mCrashSettings;
- std::string mProductName;
- LLSD mCrashInfo;
- std::string mCrashHost;
- std::string mAltCrashHost;
- LLSD mDebugLog;
- bool mSentCrashLogs;
- LLCrashLock mKeyMaster;
-
- static int ssl_mutex_count;
- static LLCoreInt::HttpMutex ** ssl_mutex_list;
-
-};
-
-#endif //LLCRASHLOGGER_H
diff --git a/indra/llfilesystem/CMakeLists.txt b/indra/llfilesystem/CMakeLists.txt
index 9f24f75eab..a552e4bdbc 100644
--- a/indra/llfilesystem/CMakeLists.txt
+++ b/indra/llfilesystem/CMakeLists.txt
@@ -28,6 +28,12 @@ if (DARWIN)
LIST(APPEND llfilesystem_SOURCE_FILES lldir_utils_objc.h)
LIST(APPEND llfilesystem_SOURCE_FILES lldir_mac.cpp)
LIST(APPEND llfilesystem_HEADER_FILES lldir_mac.h)
+
+ set_source_files_properties(
+ lldir_utils_objc.mm
+ PROPERTIES
+ SKIP_PRECOMPILE_HEADERS TRUE
+ )
endif (DARWIN)
if (LINUX)
@@ -52,10 +58,15 @@ list(APPEND llfilesystem_SOURCE_FILES ${llfilesystem_HEADER_FILES})
add_library (llfilesystem ${llfilesystem_SOURCE_FILES})
target_link_libraries(llfilesystem
+ llmath
llcommon
)
target_include_directories( llfilesystem INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llfilesystem REUSE_FROM llprecompiled)
+endif ()
+
# Add tests
if (LL_TESTS)
include(LLAddBuildTest)
diff --git a/indra/llfilesystem/lldir_win32.cpp b/indra/llfilesystem/lldir_win32.cpp
index 58c080c982..9624b1197f 100644
--- a/indra/llfilesystem/lldir_win32.cpp
+++ b/indra/llfilesystem/lldir_win32.cpp
@@ -52,7 +52,7 @@ namespace
// This is called so early that we can't count on static objects being
// properly constructed yet, so declare a pointer instead of an instance.
- std::ofstream* prelogf = nullptr;
+ llofstream* prelogf = nullptr;
void prelog(const std::string& message)
{
@@ -208,7 +208,7 @@ LLDir_Win32::LLDir_Win32()
{
// successfully created logdir, plunk a log file there
std::string logfilename(add(mOSUserDir, "lldir.log"));
- std::ofstream logfile(logfilename.c_str());
+ llofstream logfile(logfilename.c_str());
if (! logfile.is_open())
{
report(std::cerr);
diff --git a/indra/llfilesystem/lldiriterator.cpp b/indra/llfilesystem/lldiriterator.cpp
index e8c37389d2..b736a577bd 100644
--- a/indra/llfilesystem/lldiriterator.cpp
+++ b/indra/llfilesystem/lldiriterator.cpp
@@ -24,6 +24,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "lldiriterator.h"
#include "fix_macros.h"
diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp
index e971e1885a..c75df16b7d 100644
--- a/indra/llfilesystem/lldiskcache.cpp
+++ b/indra/llfilesystem/lldiskcache.cpp
@@ -112,6 +112,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 ((*iter).path().string().find(CACHE_FILENAME_PREFIX) != std::string::npos)
@@ -150,6 +154,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;
@@ -176,6 +184,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/tests/lldir_test.cpp b/indra/llfilesystem/tests/lldir_test.cpp
index d7d57fa86f..4fa5769f65 100644
--- a/indra/llfilesystem/tests/lldir_test.cpp
+++ b/indra/llfilesystem/tests/lldir_test.cpp
@@ -27,12 +27,14 @@
#include "linden_common.h"
+#include <filesystem>
#include "llstring.h"
#include "tests/StringVec.h"
#include "../lldir.h"
#include "../lldiriterator.h"
#include "../test/lltut.h"
+#include "../test/namedtempfile.h"
#include "stringize.h"
#include <boost/assign/list_of.hpp>
@@ -425,23 +427,19 @@ namespace tut
return path;
}
- std::string makeTestDir( const std::string& dirbase )
+ std::string makeTestDir( )
{
- int counter;
- std::string uniqueDir;
- bool foundUnused;
- std::string delim = gDirUtilp->getDirDelimiter();
+ auto p = NamedTempFile::temp_path();
+ std::filesystem::create_directories(p.native());
- for (counter=0, foundUnused=false; !foundUnused; counter++ )
- {
- char counterStr[3];
- snprintf(counterStr, sizeof(counterStr), "%02d", counter);
- uniqueDir = dirbase + counterStr;
- foundUnused = ! ( LLFile::isdir(uniqueDir) || LLFile::isfile(uniqueDir) );
- }
- ensure("test directory '" + uniqueDir + "' creation failed", !LLFile::mkdir(uniqueDir));
+ std::string ret = p.string();
- return uniqueDir + delim; // HACK - apparently, the trailing delimiter is needed...
+ // There's an implicit assumtion all over this code that the returned path ends with "/" (or "\")
+
+ if(ret.size() >= 1 && ret[ ret.size()-1 ] != std::filesystem::path::preferred_separator )
+ ret += std::filesystem::path::preferred_separator;
+
+ return ret;
}
static const char* DirScanFilename[5] = { "file1.abc", "file2.abc", "file1.xyz", "file2.xyz", "file1.mno" };
@@ -497,8 +495,9 @@ namespace tut
// Create the same 5 file names of the two directories
- std::string dir1 = makeTestDir(dirTemp + "LLDirIterator");
- std::string dir2 = makeTestDir(dirTemp + "LLDirIterator");
+ std::string dir1 = makeTestDir();
+ std::string dir2 = makeTestDir();
+
std::string dir1files[5];
std::string dir2files[5];
for (int i=0; i<5; i++)
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index cc75c463bc..a81808343f 100644
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -63,6 +63,10 @@ target_link_libraries(llimage
ll::libjpeg
)
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llimage REUSE_FROM llprecompiled)
+endif ()
+
# Add tests
if (LL_TESTS)
SET(llimage_TEST_SOURCE_FILES
diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt
index 93e85668dd..b7ef696b20 100644
--- a/indra/llimagej2coj/CMakeLists.txt
+++ b/indra/llimagej2coj/CMakeLists.txt
@@ -27,3 +27,6 @@ target_link_libraries( llimagej2coj
ll::openjpeg
)
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llimagej2coj REUSE_FROM llprecompiled)
+endif ()
diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt
index 93a586759f..22966bc55b 100644
--- a/indra/llinventory/CMakeLists.txt
+++ b/indra/llinventory/CMakeLists.txt
@@ -59,6 +59,10 @@ add_library (llinventory ${llinventory_SOURCE_FILES})
target_link_libraries( llinventory llcommon llmath llmessage llxml )
target_include_directories( llinventory INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llinventory REUSE_FROM llprecompiled)
+endif ()
+
#add unit tests
if (LL_TESTS)
INCLUDE(LLAddBuildTest)
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp
index d7a94d61a5..fe2503966e 100644
--- a/indra/llinventory/llsettingsbase.cpp
+++ b/indra/llinventory/llsettingsbase.cpp
@@ -25,6 +25,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "llsettingsbase.h"
#include "llmath.h"
@@ -757,7 +759,7 @@ void LLSettingsBlender::update(const LLSettingsBase::BlendFactor& blendf)
F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_in)
{
LLSettingsBase::TrackPosition blendf = (F32)blendf_in;
- llassert(!isnan(blendf));
+ llassert(!std::isnan(blendf));
if (blendf >= 1.0)
{
triggerComplete();
diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp
index 2baf140e6a..ebd8602c8d 100644
--- a/indra/llinventory/llsettingsdaycycle.cpp
+++ b/indra/llinventory/llsettingsdaycycle.cpp
@@ -25,6 +25,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "llsettingsdaycycle.h"
#include "llerror.h"
#include <algorithm>
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 4957cf3c02..fd3e49041c 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -25,6 +25,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "llsettingssky.h"
#include "indra_constants.h"
#include <algorithm>
diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp
index b5d59dc497..427f06457f 100644
--- a/indra/llinventory/llsettingswater.cpp
+++ b/indra/llinventory/llsettingswater.cpp
@@ -24,6 +24,7 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+#include "linden_common.h"
#include "llsettingswater.h"
#include <algorithm>
diff --git a/indra/llkdu/include_kdu_xxxx.h b/indra/llkdu/include_kdu_xxxx.h
index 3db417a6cb..acd23fa6c0 100644
--- a/indra/llkdu/include_kdu_xxxx.h
+++ b/indra/llkdu/include_kdu_xxxx.h
@@ -16,7 +16,7 @@
// #include "include_kdu_xxxx.h"
// // kdu_xxxx #undef'ed by include_kdu_xxxx.h
-#if __clang__
+#if LL_CLANG
// don't *really* want to rebuild KDU so turn off specific warnings for this header
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wself-assign-field"
diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp
index bc52a15c4a..09425fc001 100644
--- a/indra/llkdu/tests/llimagej2ckdu_test.cpp
+++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp
@@ -29,7 +29,7 @@
// Class to test
#include "llimagej2ckdu.h"
-#if __clang__
+#if LL_CLANG
// For this source, it's true that private fields in llkdumem.h are unused.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index bd860adc31..fb57e5db11 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -99,10 +99,14 @@ set(llmath_HEADER_FILES
list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES})
-add_library (llmath ${llmath_SOURCE_FILES})
+add_library(llmath ${llmath_SOURCE_FILES})
target_link_libraries(llmath llcommon llmeshoptimizer ll::sse2neon)
-target_include_directories( llmath INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(llmath INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llmath REUSE_FROM llprecompiled)
+endif ()
# Add tests
if (LL_TESTS)
diff --git a/indra/llmath/llcalc.cpp b/indra/llmath/llcalc.cpp
index e060b5df58..311e1e7059 100644
--- a/indra/llmath/llcalc.cpp
+++ b/indra/llmath/llcalc.cpp
@@ -116,17 +116,6 @@ void LLCalc::clearAllVariables()
mVariables.clear();
}
-/*
-void LLCalc::updateVariables(LLSD& vars)
-{
- LLSD::map_iterator cIt = vars.beginMap();
- for(; cIt != vars.endMap(); cIt++)
- {
- setVar(cIt->first, (F32)(LLSD::Real)cIt->second);
- }
-}
-*/
-
bool LLCalc::evalString(const std::string& expression, F32& result)
{
std::string expr_upper = expression;
diff --git a/indra/llmath/llcalc.h b/indra/llmath/llcalc.h
index 09672eb13b..14797de996 100644
--- a/indra/llmath/llcalc.h
+++ b/indra/llmath/llcalc.h
@@ -73,10 +73,9 @@ public:
void setVar(const std::string& name, const F32& value);
void clearVar(const std::string& name);
void clearAllVariables();
-// void updateVariables(LLSD& vars);
bool evalString(const std::string& expression, F32& result);
- std::string::size_type getLastErrorPos() { return mLastErrorPos; }
+ std::string::size_type getLastErrorPos() const { return mLastErrorPos; }
static LLCalc* getInstance();
static void cleanUp();
@@ -89,10 +88,6 @@ private:
calc_map_t mConstants;
calc_map_t mVariables;
- // *TODO: Add support for storing user defined variables, and stored functions.
- // Will need UI work, and a means to save them between sessions.
-// calc_map_t mUserVariables;
-
// "There shall be only one"
static LLCalc* sInstance;
};
diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h
index ea71752ebc..fe4e6bb1a4 100644
--- a/indra/llmath/llcalcparser.h
+++ b/indra/llmath/llcalcparser.h
@@ -27,6 +27,13 @@
#ifndef LL_CALCPARSER_H
#define LL_CALCPARSER_H
+#include "llpreprocessor.h"
+
+#if defined(LL_GNUC) && GCC_VERSION >= 130000
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wdangling-pointer"
+#endif
+
#include <boost/spirit/include/classic_attribute.hpp>
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_error_handling.hpp>
@@ -35,6 +42,10 @@
#include <boost/spirit/include/classic_symbols.hpp>
using namespace boost::spirit::classic;
+#if defined(LL_GNUC) && GCC_VERSION >= 130000
+# pragma GCC diagnostic pop
+#endif
+
#include "llcalc.h"
#include "llmath.h"
@@ -131,14 +142,14 @@ struct LLCalcParser : grammar<LLCalcParser>
power =
unary_expr[power.value = arg1] >>
- *('^' >> assert_syntax(unary_expr[power.value = phoenix::bind(&powf)(power.value, arg1)]))
+ *('^' >> assert_syntax(unary_expr[power.value = phoenix::bind(&LLCalcParser::_pow)(self, power.value, arg1)]))
;
term =
power[term.value = arg1] >>
*(('*' >> assert_syntax(power[term.value *= arg1])) |
('/' >> assert_syntax(power[term.value /= arg1])) |
- ('%' >> assert_syntax(power[term.value = phoenix::bind(&fmodf)(term.value, arg1)]))
+ ('%' >> assert_syntax(power[term.value = phoenix::bind(&LLCalcParser::_fmod)(self, term.value, arg1)]))
)
;
@@ -177,10 +188,11 @@ private:
F32 _floor(const F32& a) const { return (F32)llfloor(a); }
F32 _ceil(const F32& a) const { return (F32)llceil(a); }
F32 _atan2(const F32& a,const F32& b) const { return atan2(a,b); }
+ F32 _pow(const F32& a, const F32& b) const { return powf(a, b); }
+ F32 _fmod(const F32&a, const F32& b) const { return fmodf(a, b); }
LLCalc::calc_map_t* mConstants;
LLCalc::calc_map_t* mVariables;
-// LLCalc::calc_map_t* mUserVariables;
F32& mResult;
};
diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h
index 6201761c46..3863588407 100644
--- a/indra/llmath/llcamera.h
+++ b/indra/llmath/llcamera.h
@@ -60,10 +60,10 @@ constexpr F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
// roll(), pitch(), yaw()
// etc...
-LL_ALIGN_PREFIX(16)
-class LLCamera
+class alignas(16) LLCamera
: public LLCoordFrame
{
+ LL_ALIGN_NEW
public:
LLCamera(const LLCamera& rhs)
{
@@ -120,9 +120,9 @@ public:
};
private:
- LL_ALIGN_16(LLPlane mAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
- LL_ALIGN_16(LLPlane mRegionPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in a local region space, derived from mAgentPlanes
- LL_ALIGN_16(LLPlane mLastAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]);
+ LLPlane mAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
+ LLPlane mRegionPlanes[AGENT_PLANE_USER_CLIP_NUM]; //frustum planes in a local region space, derived from mAgentPlanes
+ LLPlane mLastAgentPlanes[AGENT_PLANE_USER_CLIP_NUM];
U8 mPlaneMask[PLANE_MASK_NUM]; // 8 for alignment
F32 mView; // angle between top and bottom frustum planes in radians.
@@ -218,7 +218,7 @@ protected:
void calculateFrustumPlanes();
void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom);
void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2);
-} LL_ALIGN_POSTFIX(16);
+};
#endif
diff --git a/indra/llmath/llmatrix3a.cpp b/indra/llmath/llmatrix3a.cpp
index c0b00201cf..904c9de2a1 100644
--- a/indra/llmath/llmatrix3a.cpp
+++ b/indra/llmath/llmatrix3a.cpp
@@ -28,7 +28,7 @@
#include "llmath.h"
-static LL_ALIGN_16(const F32 M_IDENT_3A[12]) =
+alignas(16) static const F32 M_IDENT_3A[12] =
{ 1.f, 0.f, 0.f, 0.f, // Column 1
0.f, 1.f, 0.f, 0.f, // Column 2
0.f, 0.f, 1.f, 0.f }; // Column 3
diff --git a/indra/llmath/llmatrix3a.h b/indra/llmath/llmatrix3a.h
index 9b173c22ed..742a2488fd 100644
--- a/indra/llmath/llmatrix3a.h
+++ b/indra/llmath/llmatrix3a.h
@@ -40,8 +40,9 @@
// LLMatrix3a is the base class for LLRotation, which should be used instead any time you're dealing with a
// rotation matrix.
-class LLMatrix3a
+class alignas(16) LLMatrix3a
{
+ LL_ALIGN_NEW
public:
// Utility function for quickly transforming an array of LLVector4a's
@@ -111,7 +112,7 @@ public:
protected:
- LL_ALIGN_16(LLVector4a mColumns[3]);
+ LLVector4a mColumns[3];
};
diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h
index 377203098e..2967949993 100644
--- a/indra/llmath/llmatrix4a.h
+++ b/indra/llmath/llmatrix4a.h
@@ -31,10 +31,11 @@
#include "m4math.h"
#include "m3math.h"
-class LLMatrix4a
+class alignas(16) LLMatrix4a
{
+ LL_ALIGN_NEW
public:
- LL_ALIGN_16(LLVector4a mMatrix[4]);
+ LLVector4a mMatrix[4];
LLMatrix4a() = default;
diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h
index 832004bb64..822e6a7b6f 100644
--- a/indra/llmath/llplane.h
+++ b/indra/llmath/llplane.h
@@ -36,10 +36,9 @@
// The plane normal = [A, B, C]
// The closest approach = D / sqrt(A*A + B*B + C*C)
-
-LL_ALIGN_PREFIX(16)
-class LLPlane
+class alignas(16) LLPlane
{
+ LL_ALIGN_NEW
public:
// Constructors
@@ -102,7 +101,7 @@ public:
private:
LLVector4a mV;
-} LL_ALIGN_POSTFIX(16);
+};
static_assert(std::is_trivial<LLPlane>::value, "LLPlane must be a trivial type");
diff --git a/indra/llmath/llquantize.h b/indra/llmath/llquantize.h
index e8d880122e..2a53fdbf84 100644
--- a/indra/llmath/llquantize.h
+++ b/indra/llmath/llquantize.h
@@ -29,16 +29,16 @@
#define LL_LLQUANTIZE_H
const U16 U16MAX = 65535;
-LL_ALIGN_16( const F32 F_U16MAX_4A[4] ) = { 65535.f, 65535.f, 65535.f, 65535.f };
+alignas(16) const F32 F_U16MAX_4A[4] = { 65535.f, 65535.f, 65535.f, 65535.f };
const F32 OOU16MAX = 1.f/(F32)(U16MAX);
-LL_ALIGN_16( const F32 F_OOU16MAX_4A[4] ) = { OOU16MAX, OOU16MAX, OOU16MAX, OOU16MAX };
+alignas(16) const F32 F_OOU16MAX_4A[4] = { OOU16MAX, OOU16MAX, OOU16MAX, OOU16MAX };
const U8 U8MAX = 255;
-LL_ALIGN_16( const F32 F_U8MAX_4A[4] ) = { 255.f, 255.f, 255.f, 255.f };
+alignas(16) const F32 F_U8MAX_4A[4] = { 255.f, 255.f, 255.f, 255.f };
const F32 OOU8MAX = 1.f/(F32)(U8MAX);
-LL_ALIGN_16( const F32 F_OOU8MAX_4A[4] ) = { OOU8MAX, OOU8MAX, OOU8MAX, OOU8MAX };
+alignas(16) const F32 F_OOU8MAX_4A[4] = { OOU8MAX, OOU8MAX, OOU8MAX, OOU8MAX };
const U8 FIRSTVALIDCHAR = 54;
const U8 MAXSTRINGVAL = U8MAX - FIRSTVALIDCHAR; //we don't allow newline or null
diff --git a/indra/llmath/llquaternion2.h b/indra/llmath/llquaternion2.h
index c9dcc4573f..d73e1a0ca2 100644
--- a/indra/llmath/llquaternion2.h
+++ b/indra/llmath/llquaternion2.h
@@ -40,8 +40,9 @@
/////////////////////////////
#include "llquaternion.h"
-class LLQuaternion2
+class alignas(16) LLQuaternion2
{
+ LL_ALIGN_NEW
public:
//////////////////////////
diff --git a/indra/llmath/llquaternion2.inl b/indra/llmath/llquaternion2.inl
index ce5ed73926..2ebc8e0bfb 100644
--- a/indra/llmath/llquaternion2.inl
+++ b/indra/llmath/llquaternion2.inl
@@ -57,7 +57,7 @@ inline LLVector4a& LLQuaternion2::getVector4aRw()
// Set this quaternion to the conjugate of src
inline void LLQuaternion2::setConjugate(const LLQuaternion2& src)
{
- static LL_ALIGN_16( const U32 F_QUAT_INV_MASK_4A[4] ) = { 0x80000000, 0x80000000, 0x80000000, 0x00000000 };
+ alignas(16) static const U32 F_QUAT_INV_MASK_4A[4] = { 0x80000000, 0x80000000, 0x80000000, 0x00000000 };
mQ = _mm_xor_ps(src.mQ, *reinterpret_cast<const LLQuad*>(&F_QUAT_INV_MASK_4A));
}
diff --git a/indra/llmath/llsimdtypes.inl b/indra/llmath/llsimdtypes.inl
index 125f4b9df5..20ea7640b6 100644
--- a/indra/llmath/llsimdtypes.inl
+++ b/indra/llmath/llsimdtypes.inl
@@ -61,7 +61,7 @@ inline LLSimdScalar operator/(const LLSimdScalar& a, const LLSimdScalar& b)
inline LLSimdScalar operator-(const LLSimdScalar& a)
{
- static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 };
+ alignas(16) static const U32 signMask[4] = {0x80000000, 0x80000000, 0x80000000, 0x80000000 };
ll_assert_aligned(signMask,16);
return _mm_xor_ps(*reinterpret_cast<const LLQuad*>(signMask), a);
}
@@ -146,7 +146,7 @@ inline LLSimdScalar& LLSimdScalar::operator/=(const LLSimdScalar& rhs)
inline LLSimdScalar LLSimdScalar::getAbs() const
{
- static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
+ alignas(16) static const U32 F_ABS_MASK_4A[4] = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
ll_assert_aligned(F_ABS_MASK_4A,16);
return _mm_and_ps( mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A));
}
diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp
index b81d50f0f9..6bdc97e420 100644
--- a/indra/llmath/llvector4a.cpp
+++ b/indra/llmath/llvector4a.cpp
@@ -101,7 +101,7 @@ void LLVector4a::quantize8( const LLVector4a& low, const LLVector4a& high )
// 8-bit quantization means we can do with just 12 bits of reciprocal accuracy
const LLVector4a oneOverDelta = _mm_rcp_ps(delta.mQ);
// {
-// static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f };
+// alignas(16) static const F32 F_TWO_4A[4] = { 2.f, 2.f, 2.f, 2.f };
// LLVector4a two; two.load4a( F_TWO_4A );
//
// // Here we use _mm_rcp_ps plus one round of newton-raphson
@@ -146,7 +146,7 @@ void LLVector4a::quantize16( const LLVector4a& low, const LLVector4a& high )
// 16-bit quantization means we need a round of Newton-Raphson
LLVector4a oneOverDelta;
{
- static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f };
+ alignas(16) static const F32 F_TWO_4A[4] = { 2.f, 2.f, 2.f, 2.f };
ll_assert_aligned(F_TWO_4A,16);
LLVector4a two; two.load4a( F_TWO_4A );
diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl
index 443a46c317..b6e2a4fce5 100644
--- a/indra/llmath/llvector4a.inl
+++ b/indra/llmath/llvector4a.inl
@@ -196,7 +196,7 @@ inline void LLVector4a::setDiv(const LLVector4a& a, const LLVector4a& b)
// Set this to the element-wise absolute value of src
inline void LLVector4a::setAbs(const LLVector4a& src)
{
- static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
+ alignas(16) static const U32 F_ABS_MASK_4A[4] = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
mQ = _mm_and_ps(src.mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A));
}
@@ -448,7 +448,7 @@ inline void LLVector4a::normalize3fast_checked(LLVector4a* d)
// Return true if this vector is normalized with respect to x,y,z up to tolerance
inline LLBool32 LLVector4a::isNormalized3( F32 tolerance ) const
{
- static LL_ALIGN_16(const U32 ones[4]) = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 };
+ alignas(16) static const U32 ones[4] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 };
LLSimdScalar tol = _mm_load_ss( &tolerance );
tol = _mm_mul_ss( tol, tol );
LLVector4a lenSquared; lenSquared.setAllDot3( *this, *this );
@@ -460,7 +460,7 @@ inline LLBool32 LLVector4a::isNormalized3( F32 tolerance ) const
// Return true if this vector is normalized with respect to all components up to tolerance
inline LLBool32 LLVector4a::isNormalized4( F32 tolerance ) const
{
- static LL_ALIGN_16(const U32 ones[4]) = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 };
+ alignas(16) static const U32 ones[4] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 };
LLSimdScalar tol = _mm_load_ss( &tolerance );
tol = _mm_mul_ss( tol, tol );
LLVector4a lenSquared; lenSquared.setAllDot4( *this, *this );
@@ -507,7 +507,7 @@ inline void LLVector4a::setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F3
inline LLBool32 LLVector4a::isFinite3() const
{
- static LL_ALIGN_16(const U32 nanOrInfMask[4]) = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 };
+ alignas(16) static const U32 nanOrInfMask[4] = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 };
ll_assert_aligned(nanOrInfMask,16);
const __m128i nanOrInfMaskV = *reinterpret_cast<const __m128i*> (nanOrInfMask);
const __m128i maskResult = _mm_and_si128( _mm_castps_si128(mQ), nanOrInfMaskV );
@@ -517,7 +517,7 @@ inline LLBool32 LLVector4a::isFinite3() const
inline LLBool32 LLVector4a::isFinite4() const
{
- static LL_ALIGN_16(const U32 nanOrInfMask[4]) = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 };
+ alignas(16) static const U32 nanOrInfMask[4] = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 };
const __m128i nanOrInfMaskV = *reinterpret_cast<const __m128i*> (nanOrInfMask);
const __m128i maskResult = _mm_and_si128( _mm_castps_si128(mQ), nanOrInfMaskV );
const LLVector4Logical equalityCheck = _mm_castsi128_ps(_mm_cmpeq_epi32( maskResult, nanOrInfMaskV ));
diff --git a/indra/llmath/llvector4logical.h b/indra/llmath/llvector4logical.h
index 77cb5862e5..411971c42d 100644
--- a/indra/llmath/llvector4logical.h
+++ b/indra/llmath/llvector4logical.h
@@ -39,7 +39,7 @@
// contact someone with SSE experience (Falcon, Richard, Davep, e.g.)
////////////////////////////
-static LL_ALIGN_16(const U32 S_V4LOGICAL_MASK_TABLE[4*4]) =
+alignas(16) static const U32 S_V4LOGICAL_MASK_TABLE[4*4] =
{
0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,
@@ -77,7 +77,7 @@ public:
// Invert this mask
inline LLVector4Logical& invert()
{
- static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ alignas(16) static const U32 allOnes[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
ll_assert_aligned(allOnes,16);
mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) );
return *this;
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index b3cb278d59..dfad66040e 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2348,7 +2348,9 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
const LLSD::Binary& pos = mdl[i]["Position"].asBinary();
const LLSD::Binary& norm = mdl[i]["Normal"].asBinary();
+#if 0 // keep this code for now in case we decide to add support for on-the-wire tangents
const LLSD::Binary& tangent = mdl[i]["Tangent"].asBinary();
+#endif
const LLSD::Binary& tc = mdl[i]["TexCoord0"].asBinary();
const LLSD::Binary& idx = mdl[i]["TriangleList"].asBinary();
diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h
index 1d74644715..4200e0d5a1 100644
--- a/indra/llmath/llvolumeoctree.h
+++ b/indra/llmath/llvolumeoctree.h
@@ -53,7 +53,7 @@ public:
}
- LL_ALIGN_16(LLVector4a mPositionGroup);
+ LLVector4a mPositionGroup;
const LLVector4a* mV[3];
U32 mIndex[3];
@@ -99,8 +99,8 @@ public:
public:
- LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
- LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
+ LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects)
+ LLVector4a mExtents[2]; // extents (min, max) of this node and all its children
};
class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>
diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp
index eb6fa4a3b8..f41ebe82aa 100644
--- a/indra/llmath/tests/alignment_test.cpp
+++ b/indra/llmath/tests/alignment_test.cpp
@@ -46,8 +46,7 @@ typedef test_group<alignment_test> alignment_test_t;
typedef alignment_test_t::object alignment_test_object_t;
tut::alignment_test_t tut_alignment_test("LLAlignment");
-LL_ALIGN_PREFIX(16)
-class MyVector4a
+class alignas(16) MyVector4a
{
public:
void* operator new(size_t size)
@@ -71,7 +70,7 @@ public:
}
LLQuad mQ;
-} LL_ALIGN_POSTFIX(16);
+};
// Verify that aligned allocators perform as advertised.
diff --git a/indra/llmeshoptimizer/CMakeLists.txt b/indra/llmeshoptimizer/CMakeLists.txt
index dfac44c296..5b1ab9d8e4 100644
--- a/indra/llmeshoptimizer/CMakeLists.txt
+++ b/indra/llmeshoptimizer/CMakeLists.txt
@@ -30,5 +30,9 @@ target_link_libraries(llmeshoptimizer
llmath
ll::meshoptimizer)
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llmeshoptimizer REUSE_FROM llprecompiled)
+endif ()
+
# Add tests
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index b2757a7306..46f28abc9c 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -194,6 +194,10 @@ target_link_libraries(
)
target_include_directories( llmessage INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llmessage REUSE_FROM llprecompiled)
+endif ()
+
# tests
if (LL_TESTS)
SET(llmessage_TEST_SOURCE_FILES
diff --git a/indra/llmessage/llavatarname.h b/indra/llmessage/llavatarname.h
index eec966d51b..86b2931ed9 100644
--- a/indra/llmessage/llavatarname.h
+++ b/indra/llmessage/llavatarname.h
@@ -32,7 +32,7 @@
class LLSD;
-class LL_COMMON_API LLAvatarName
+class LLAvatarName
{
public:
LLAvatarName();
diff --git a/indra/llmessage/llbufferstream.cpp b/indra/llmessage/llbufferstream.cpp
index 2c745f6fe4..cb5a4c1824 100644
--- a/indra/llmessage/llbufferstream.cpp
+++ b/indra/llmessage/llbufferstream.cpp
@@ -234,17 +234,10 @@ int LLBufferStreamBuf::sync()
}
// virtual
-#if( LL_WINDOWS || __GNUC__ > 2)
LLBufferStreamBuf::pos_type LLBufferStreamBuf::seekoff(
LLBufferStreamBuf::off_type off,
std::ios::seekdir way,
std::ios::openmode which)
-#else
-streampos LLBufferStreamBuf::seekoff(
- streamoff off,
- std::ios::seekdir way,
- std::ios::openmode which)
-#endif
{
if(!mBuffer
|| ((way == std::ios::beg) && (off < 0))
@@ -319,12 +312,8 @@ streampos LLBufferStreamBuf::seekoff(
}
}
-#if( LL_WINDOWS || __GNUC__ > 2 )
S32 rv = (S32)(intptr_t)address;
return (pos_type)rv;
-#else
- return (streampos)address;
-#endif
}
diff --git a/indra/llmessage/llbufferstream.h b/indra/llmessage/llbufferstream.h
index ac1aa49e81..e0a7d8c642 100644
--- a/indra/llmessage/llbufferstream.h
+++ b/indra/llmessage/llbufferstream.h
@@ -48,10 +48,8 @@ public:
virtual ~LLBufferStreamBuf();
protected:
-#if( LL_WINDOWS || __GNUC__ > 2 )
typedef std::streambuf::pos_type pos_type;
typedef std::streambuf::off_type off_type;
-#endif
/* @name streambuf vrtual implementations
*/
@@ -87,17 +85,10 @@ protected:
* or both masked together.
* @return Returns the new position or an invalid position on failure.
*/
-#if( LL_WINDOWS || __GNUC__ > 2)
virtual pos_type seekoff(
off_type off,
std::ios::seekdir way,
std::ios::openmode which);
-#else
- virtual streampos seekoff(
- streamoff off,
- std::ios::seekdir way,
- std::ios::openmode which);
-#endif
/*
* @brief Get s sequence of characters from the input
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 64f660d0ce..4980e0a1da 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -780,6 +780,7 @@ void LLCacheName::Impl::processPendingAsks()
void LLCacheName::Impl::processPendingReplies()
{
// First call all the callbacks, because they might send messages.
+ // Todo: needs cleanup logic, otherwise invalid ids might stay here indefinitely
for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it)
{
PendingReply* reply = *it;
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 78cca47456..9d940d8d71 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -23,6 +23,8 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "llexperiencecache.h"
#include "llavatarname.h"
diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp
index d4cf95c1e3..b626637862 100644
--- a/indra/llmessage/llpartdata.cpp
+++ b/indra/llmessage/llpartdata.cpp
@@ -331,7 +331,7 @@ bool LLPartSysData::isNullPS(const S32 block_num)
S32 size;
// Check size of block
- size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
+ size = gMessageSystem->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_PSBlock);
if (!size)
{
@@ -344,7 +344,7 @@ bool LLPartSysData::isNullPS(const S32 block_num)
return true;
}
- gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE);
+ gMessageSystem->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_PSBlock, ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE);
LLDataPackerBinaryBuffer dp(ps_data_block, size);
if (size > PS_LEGACY_DATA_BLOCK_SIZE)
@@ -373,7 +373,7 @@ bool LLPartSysData::unpackBlock(const S32 block_num)
U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE];
// Check size of block
- S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
+ S32 size = gMessageSystem->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_PSBlock);
if (size > PS_MAX_DATA_BLOCK_SIZE)
{
@@ -382,7 +382,7 @@ bool LLPartSysData::unpackBlock(const S32 block_num)
}
// Get from message
- gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE);
+ gMessageSystem->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_PSBlock, ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE);
LLDataPackerBinaryBuffer dp(ps_data_block, size);
diff --git a/indra/llmessage/llstoredmessage.cpp b/indra/llmessage/llstoredmessage.cpp
index 39696ea235..ff8afde657 100644
--- a/indra/llmessage/llstoredmessage.cpp
+++ b/indra/llmessage/llstoredmessage.cpp
@@ -24,6 +24,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "llstoredmessage.h"
LLStoredMessage::LLStoredMessage(const std::string& name, const LLSD& message) : mMessage(message), mName(name)
diff --git a/indra/llmessage/lltemplatemessagedispatcher.cpp b/indra/llmessage/lltemplatemessagedispatcher.cpp
index edbeb4acc1..02e5b56c8d 100644
--- a/indra/llmessage/lltemplatemessagedispatcher.cpp
+++ b/indra/llmessage/lltemplatemessagedispatcher.cpp
@@ -24,6 +24,7 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
#include "lltemplatemessagedispatcher.h"
diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp
index b62288590e..850d73e910 100644
--- a/indra/llmessage/lltemplatemessagereader.cpp
+++ b/indra/llmessage/lltemplatemessagereader.cpp
@@ -118,6 +118,9 @@ void LLTemplateMessageReader::getData(const char *blockname, const char *varname
{
switch( vardata_size )
{
+ case 0:
+ // This is here to prevent a memcpy from a null value which is undefined behavior.
+ break;
case 1:
*((U8*)datap) = *((U8*)vardata.getData());
break;
diff --git a/indra/llphysicsextensionsos/CMakeLists.txt b/indra/llphysicsextensionsos/CMakeLists.txt
index c04115ef26..ff1b703dc7 100644
--- a/indra/llphysicsextensionsos/CMakeLists.txt
+++ b/indra/llphysicsextensionsos/CMakeLists.txt
@@ -43,5 +43,9 @@ if(WINDOWS)
target_compile_options(llphysicsextensionsos PRIVATE /bigobj)
endif()
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llphysicsextensionsos REUSE_FROM llprecompiled)
+endif ()
+
# Add tests
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index e008a4093e..f67975365a 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -36,5 +36,10 @@ list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
add_library (llplugin ${llplugin_SOURCE_FILES})
target_include_directories( llplugin INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries( llplugin llcommon llmath llmessage llxml )
+
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llplugin REUSE_FROM llprecompiled)
+endif ()
+
add_subdirectory(slplugin)
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 77a4b08af5..803574f9fa 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -34,7 +34,7 @@
#include "llcontrol.h"
extern LLControlGroup gSavedSettings;
-#if LL_DARWIN
+#if LL_DARWIN || LL_LINUX
extern bool gHiDPISupport;
#endif
@@ -372,7 +372,7 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
}
-#if LL_DARWIN
+#if LL_DARWIN || LL_LINUX
if (!gHiDPISupport)
#endif
{
@@ -1015,6 +1015,15 @@ void LLPluginClassMedia::enableMediaPluginDebugging( bool enable )
sendMessage( message );
}
+#if LL_LINUX
+void LLPluginClassMedia::enablePipeWireVolumeCatcher( bool enable )
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "enable_pipewire_volume_catcher");
+ message.setValueBoolean( "enable", enable );
+ sendMessage( message );
+}
+#endif
+
void LLPluginClassMedia::setTarget(const std::string &target)
{
mTarget = target;
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 71522bcd7d..bfede4e9c1 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -134,6 +134,10 @@ public:
// Text may be unicode (utf8 encoded)
bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data);
+#if LL_LINUX
+ void enablePipeWireVolumeCatcher( bool enable );
+#endif
+
static std::string sOIDcookieUrl;
static std::string sOIDcookieName;
static std::string sOIDcookieValue;
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 4df3e306cb..f746160ada 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -18,6 +18,12 @@ if (DARWIN)
list(APPEND SLPlugin_HEADER_FILES
slplugin-objc.h
)
+
+ set_source_files_properties(
+ slplugin-objc.mm
+ PROPERTIES
+ SKIP_PRECOMPILE_HEADERS TRUE
+ )
endif (DARWIN)
if (SLPlugin_HEADER_FILES)
@@ -37,6 +43,10 @@ target_link_libraries(SLPlugin
ll::pluginlibraries
)
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(SLPlugin REUSE_FROM llprecompiled)
+endif ()
+
if (WINDOWS)
set_target_properties(SLPlugin
PROPERTIES
diff --git a/indra/llprecompiled/CMakeLists.txt b/indra/llprecompiled/CMakeLists.txt
new file mode 100644
index 0000000000..ea230f4a98
--- /dev/null
+++ b/indra/llprecompiled/CMakeLists.txt
@@ -0,0 +1,53 @@
+# -*- cmake -*-
+
+project(llprecompiled)
+
+include(00-Common)
+include(APR)
+include(bugsplat)
+include(Linking)
+include(Boost)
+include(LLSharedLibs)
+include(ZLIBNG)
+include(Tracy)
+include(EXPAT)
+include(SSE2NEON)
+
+set(llprecompiled_SOURCE_FILES
+ cmake_dummy.cpp
+ )
+
+add_library (llprecompiled ${llprecompiled_SOURCE_FILES})
+
+target_include_directories(llprecompiled PRIVATE
+ ${CMAKE_SOURCE_DIR}/${LIBS_OPEN_PREFIX}llmath
+ )
+
+target_link_libraries(llprecompiled
+ llcommon
+ ll::apr
+ ll::expat
+ ll::zlib-ng
+ ll::boost
+ ll::oslibraries
+ ll::tracy
+ ll::sse2neon
+ )
+
+target_precompile_headers(llprecompiled PRIVATE
+ [["linden_common.h"]]
+ [["llwin32headers.h"]]
+ [["llprofiler.h"]]
+ [["llmath.h"]]
+ <boost/bind.hpp>
+ <boost/fiber/fiber.hpp>
+ <boost/fiber/fss.hpp>
+ <boost/fiber/future/promise.hpp>
+ <boost/fiber/future/future.hpp>
+ <boost/function.hpp>
+ <boost/function_types/function_arity.hpp>
+ <boost/iterator/transform_iterator.hpp>
+ <boost/iterator/indirect_iterator.hpp>
+ <boost/range/iterator_range.hpp>
+ <boost/signals2.hpp>
+ )
diff --git a/indra/newview/llappviewerlinux_api_dbus.h b/indra/llprecompiled/cmake_dummy.cpp
index 2f4492bd7a..21a47a9b14 100644
--- a/indra/newview/llappviewerlinux_api_dbus.h
+++ b/indra/llprecompiled/cmake_dummy.cpp
@@ -1,6 +1,5 @@
/**
- * @file llappviewerlinux_api_dbus.h
- * @brief DBus-glib symbol handling
+ * @file cmake_dummy.cpp
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,22 +22,3 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-#include "linden_common.h"
-
-#if LL_DBUS_ENABLED
-
-extern "C" {
-#include <dbus/dbus-glib.h>
-}
-
-#define DBUSGLIB_DYLIB_DEFAULT_NAME "libdbus-glib-1.so.2"
-
-bool grab_dbus_syms(std::string dbus_dso_name);
-void ungrab_dbus_syms();
-
-#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) extern RTN (*ll##DBUSSYM)(__VA_ARGS__)
-#include "llappviewerlinux_api_dbus_syms_raw.inc"
-#undef LL_DBUS_SYM
-
-#endif // LL_DBUS_ENABLED
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index ff0cad58d6..f05be03034 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -79,6 +79,10 @@ else()
)
endif ()
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llprimitive REUSE_FROM llprecompiled)
+endif ()
+
#add unit tests
if (LL_TESTS)
INCLUDE(LLAddBuildTest)
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index 81ebe631c5..71fc2b4fc0 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -1078,7 +1078,7 @@ bool LLDAELoader::OpenFile(const std::string& filename)
LLModel* mdl = *i;
if(mdl->getStatus() != LLModel::NO_ERRORS)
{
- setLoadState(ERROR_MODEL + mdl->getStatus()) ;
+ setLoadState(static_cast<U32>(ERROR_MODEL) + static_cast<U32>(mdl->getStatus()));
return false; //abort
}
diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp
index 4992b282f3..b417f095ca 100644
--- a/indra/llprimitive/llmaterialid.cpp
+++ b/indra/llprimitive/llmaterialid.cpp
@@ -56,20 +56,11 @@ LLMaterialID::LLMaterialID(const void* pMemory)
set(pMemory);
}
-LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID)
-{
- copyFromOtherMaterialID(pOtherMaterialID);
-}
-
LLMaterialID::LLMaterialID(const LLUUID& lluid)
{
set(lluid.mData);
}
-LLMaterialID::~LLMaterialID()
-{
-}
-
bool LLMaterialID::operator == (const LLMaterialID& pOtherMaterialID) const
{
return (compareToOtherMaterialID(pOtherMaterialID) == 0);
@@ -100,12 +91,6 @@ bool LLMaterialID::operator >= (const LLMaterialID& pOtherMaterialID) const
return (compareToOtherMaterialID(pOtherMaterialID) >= 0);
}
-LLMaterialID& LLMaterialID::operator = (const LLMaterialID& pOtherMaterialID)
-{
- copyFromOtherMaterialID(pOtherMaterialID);
- return (*this);
-}
-
bool LLMaterialID::isNull() const
{
return (compareToOtherMaterialID(LLMaterialID::null) == 0);
@@ -168,18 +153,12 @@ std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id)
return s;
}
-
void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID)
{
llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8)));
memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8));
}
-void LLMaterialID::copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID)
-{
- memcpy(mID, pOtherMaterialID.get(), MATERIAL_ID_SIZE * sizeof(U8));
-}
-
int LLMaterialID::compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const
{
int retVal = 0;
diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h
index bd6256d961..cec0965441 100644
--- a/indra/llprimitive/llmaterialid.h
+++ b/indra/llprimitive/llmaterialid.h
@@ -39,9 +39,7 @@ public:
LLMaterialID(const LLSD& pMaterialID);
LLMaterialID(const LLSD::Binary& pMaterialID);
LLMaterialID(const void* pMemory);
- LLMaterialID(const LLMaterialID& pOtherMaterialID);
LLMaterialID(const LLUUID& lluid);
- ~LLMaterialID();
bool operator == (const LLMaterialID& pOtherMaterialID) const;
bool operator != (const LLMaterialID& pOtherMaterialID) const;
@@ -51,8 +49,6 @@ public:
bool operator > (const LLMaterialID& pOtherMaterialID) const;
bool operator >= (const LLMaterialID& pOtherMaterialID) const;
- LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID);
-
bool isNull() const;
const U8* get() const;
@@ -77,7 +73,6 @@ public:
private:
void parseFromBinary(const LLSD::Binary& pMaterialID);
- void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID);
int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const;
U8 mID[MATERIAL_ID_SIZE];
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index ac88af18f0..26448069c6 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -40,8 +40,7 @@ class domMesh;
#define MAX_MODEL_FACES 8
-LL_ALIGN_PREFIX(16)
-class LLMeshSkinInfo : public LLRefCount
+class alignas(16) LLMeshSkinInfo : public LLRefCount
{
LL_ALIGN_NEW
public:
@@ -65,17 +64,16 @@ public:
// cached multiply of mBindShapeMatrix and mInvBindMatrix
matrix_list_t mBindPoseMatrix;
- LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);
+ LLMatrix4a mBindShapeMatrix;
float mPelvisOffset;
bool mLockScaleIfJointPosition;
bool mInvalidJointsScrubbed;
bool mJointNumsInitialized;
U64 mHash = 0;
-} LL_ALIGN_POSTFIX(16);
+};
-LL_ALIGN_PREFIX(16)
-class LLModel : public LLVolume
+class alignas(16) LLModel : public LLVolume
{
LL_ALIGN_NEW
public:
@@ -323,7 +321,7 @@ public:
// A model/object can only have 8 faces, spillover faces will
// be moved to new model/object and assigned a submodel id.
int mSubmodelID;
-} LL_ALIGN_POSTFIX(16);
+};
typedef std::vector<LLPointer<LLModel> > model_list;
typedef std::queue<LLPointer<LLModel> > model_queue;
diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp
index 0383659f62..bce5f6adce 100644
--- a/indra/llprimitive/llmodelloader.cpp
+++ b/indra/llprimitive/llmodelloader.cpp
@@ -24,6 +24,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "llmodelloader.h"
#include "llapp.h"
diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp
index 68f3f5ffac..c70a8f6483 100644
--- a/indra/llprimitive/llprimtexturelist.cpp
+++ b/indra/llprimitive/llprimtexturelist.cpp
@@ -137,7 +137,7 @@ S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry& te)
// we're changing an existing entry
llassert(mEntryList[index]);
delete (mEntryList[index]);
- if (&te)
+ if (te != LLTextureEntry::null)
{
mEntryList[index] = te.newCopy();
}
diff --git a/indra/llprimitive/tests/llprimitive_test.cpp b/indra/llprimitive/tests/llprimitive_test.cpp
index 0213a3e8b6..75c3613ece 100644
--- a/indra/llprimitive/tests/llprimitive_test.cpp
+++ b/indra/llprimitive/tests/llprimitive_test.cpp
@@ -71,9 +71,7 @@ private:
S32 mCurrDetailTest;
};
-LLMaterialID::LLMaterialID() {}
-LLMaterialID::LLMaterialID(LLMaterialID const &m) = default;
-LLMaterialID::~LLMaterialID() {}
+LLMaterialID::LLMaterialID() = default;
void LLMaterialID::set(void const*) { }
U8 const * LLMaterialID::get() const { return mID; }
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index ccff7c7a8c..2449c0d0bf 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -23,7 +23,6 @@ set(llrender_SOURCE_FILES
llglslshader.cpp
llgltexture.cpp
llimagegl.cpp
- llpostprocess.cpp
llrender.cpp
llrender2dutils.cpp
llrendernavprim.cpp
@@ -56,7 +55,6 @@ set(llrender_HEADER_FILES
llgltexture.h
llgltypes.h
llimagegl.h
- llpostprocess.h
llrender.h
llrender2dutils.h
llrendernavprim.h
@@ -76,23 +74,26 @@ if (BUILD_HEADLESS)
add_library (llrenderheadless
${llrender_SOURCE_FILES}
)
-
- set_property(TARGET llrenderheadless
- PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
- )
+ target_include_directories(llrenderheadless INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(llrenderheadless
llcommon
llimage
llmath
- llrender
llxml
llfilesystem
+ llwindowheadless
+ ll::freetype
+ OpenGL::GL
)
+
+ if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llrenderheadless REUSE_FROM llprecompiled)
+ endif()
endif (BUILD_HEADLESS)
add_library (llrender ${llrender_SOURCE_FILES})
-target_include_directories( llrender INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(llrender INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
@@ -104,7 +105,15 @@ target_link_libraries(llrender
llxml
llwindow
ll::freetype
+ )
+
+if (NOT USE_SDL_WINDOW)
+target_link_libraries(llrender
OpenGL::GL
- OpenGL::GLU
)
+endif()
+
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llrender REUSE_FROM llprecompiled)
+endif ()
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index d13b98e274..25277f1341 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -27,8 +27,6 @@
// This file sets some global GL parameters, and implements some
// useful functions for GL operations.
-#define GLH_EXT_SINGLE_FILE
-
#include "linden_common.h"
#include "boost/tokenizer.hpp"
@@ -54,6 +52,15 @@
#include <glm/gtc/matrix_access.hpp>
#include "glm/gtc/type_ptr.hpp"
+#if LL_SDL_WINDOW
+# include "llwindowsdl.h"
+# include "SDL3/SDL.h"
+# define LL_GET_PROC_ADDRESS(func) SDL_GL_GetProcAddress(func)
+#elif LL_WINDOWS
+# include "llwindowwin32.h"
+# define LL_GET_PROC_ADDRESS(func) LLWindowWin32::getProcAddress(func)
+#endif
+
#if LL_WINDOWS
#include "lldxhardware.h"
#endif
@@ -62,10 +69,8 @@
//#define GL_STATE_VERIFY
#endif
-
bool gDebugSession = false;
bool gDebugGLSession = false;
-bool gClothRipple = false;
bool gHeadlessClient = false;
bool gNonInteractive = false;
bool gGLActive = false;
@@ -211,13 +216,16 @@ void ll_close_fail_log()
LLMatrix4 gGLObliqueProjectionInverse;
-#define LL_GL_NAME_POOLING 0
-
std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
-#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
+#if LL_GL_FUNC_POINTER
#if LL_WINDOWS
+// WGL_ARB_pixel_format
+PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = nullptr;
+PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB = nullptr;
+PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = nullptr;
+
// WGL_ARB_create_context
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr;
@@ -235,14 +243,93 @@ PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC wglBlitContextFramebufferAMD = n
// WGL_EXT_swap_control
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = nullptr;
+#endif
+#if LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+// GLX_MESA_query_renderer
+PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC glXQueryCurrentRendererIntegerMESA = nullptr;
+PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC glXQueryCurrentRendererStringMESA = nullptr;
+PFNGLXQUERYRENDERERINTEGERMESAPROC glXQueryRendererIntegerMESA = nullptr;
+PFNGLXQUERYRENDERERSTRINGMESAPROC glXQueryRendererStringMESA = nullptr;
#endif
+#if LL_LINUX && LL_WAYLAND &&!LL_MESA_HEADLESS
+// EGL_VERSION_1_0
+PFNEGLQUERYSTRINGPROC eglQueryString = nullptr;
+#endif
+
+// GL_VERSION_1_0
+PFNGLCLEARCOLORPROC glClearColor = nullptr;
+PFNGLCLEARPROC glClear = nullptr;
+PFNGLCOLORMASKPROC glColorMask = nullptr;
+PFNGLBLENDFUNCPROC glBlendFunc = nullptr;
+PFNGLLOGICOPPROC glLogicOp = nullptr;
+PFNGLFRONTFACEPROC glFrontFace = nullptr;
+PFNGLCULLFACEPROC glCullFace = nullptr;
+PFNGLPOINTSIZEPROC glPointSize = nullptr;
+PFNGLLINEWIDTHPROC glLineWidth = nullptr;
+PFNGLPOLYGONMODEPROC glPolygonMode = nullptr;
+PFNGLSCISSORPROC glScissor = nullptr;
+PFNGLDRAWBUFFERPROC glDrawBuffer = nullptr;
+PFNGLREADBUFFERPROC glReadBuffer = nullptr;
+PFNGLENABLEPROC glEnable = nullptr;
+PFNGLDISABLEPROC glDisable = nullptr;
+PFNGLISENABLEDPROC glIsEnabled = nullptr;
+PFNGLGETBOOLEANVPROC glGetBooleanv = nullptr;
+PFNGLGETDOUBLEVPROC glGetDoublev = nullptr;
+PFNGLGETFLOATVPROC glGetFloatv = nullptr;
+PFNGLGETINTEGERVPROC glGetIntegerv = nullptr;
+PFNGLGETERRORPROC glGetError = nullptr;
+PFNGLGETSTRINGPROC glGetString = nullptr;
+PFNGLFINISHPROC glFinish = nullptr;
+PFNGLFLUSHPROC glFlush = nullptr;
+PFNGLHINTPROC glHint = nullptr;
+PFNGLCLEARDEPTHPROC glClearDepth = nullptr;
+PFNGLDEPTHFUNCPROC glDepthFunc = nullptr;
+PFNGLDEPTHMASKPROC glDepthMask = nullptr;
+PFNGLDEPTHRANGEPROC glDepthRange = nullptr;
+PFNGLVIEWPORTPROC glViewport = nullptr;
+PFNGLPIXELSTOREFPROC glPixelStoref = nullptr;
+PFNGLPIXELSTOREIPROC glPixelStorei = nullptr;
+PFNGLREADPIXELSPROC glReadPixels = nullptr;
+PFNGLSTENCILFUNCPROC glStencilFunc = nullptr;
+PFNGLSTENCILMASKPROC glStencilMask = nullptr;
+PFNGLSTENCILOPPROC glStencilOp = nullptr;
+PFNGLCLEARSTENCILPROC glClearStencil = nullptr;
+PFNGLTEXPARAMETERFPROC glTexParameterf = nullptr;
+PFNGLTEXPARAMETERIPROC glTexParameteri = nullptr;
+PFNGLTEXPARAMETERFVPROC glTexParameterfv = nullptr;
+PFNGLTEXPARAMETERIVPROC glTexParameteriv = nullptr;
+PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv = nullptr;
+PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv = nullptr;
+PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv = nullptr;
+PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv = nullptr;
+PFNGLTEXIMAGE1DPROC glTexImage1D = nullptr;
+PFNGLTEXIMAGE2DPROC glTexImage2D = nullptr;
+PFNGLGETTEXIMAGEPROC glGetTexImage = nullptr;
+
+// GL_VERSION_1_1
+PFNGLDRAWARRAYSPROC glDrawArrays = nullptr;
+PFNGLDRAWELEMENTSPROC glDrawElements = nullptr;
+PFNGLGETPOINTERVPROC glGetPointerv = nullptr;
+PFNGLPOLYGONOFFSETPROC glPolygonOffset = nullptr;
+PFNGLCOPYTEXIMAGE1DPROC glCopyTexImage1D = nullptr;
+PFNGLCOPYTEXIMAGE2DPROC glCopyTexImage2D = nullptr;
+PFNGLCOPYTEXSUBIMAGE1DPROC glCopyTexSubImage1D = nullptr;
+PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D = nullptr;
+PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D = nullptr;
+PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D = nullptr;
+PFNGLBINDTEXTUREPROC glBindTexture = nullptr;
+PFNGLDELETETEXTURESPROC glDeleteTextures = nullptr;
+PFNGLGENTEXTURESPROC glGenTextures = nullptr;
+PFNGLISTEXTUREPROC glIsTexture = nullptr;
+
+
// GL_VERSION_1_2
-//PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = nullptr;
-//PFNGLTEXIMAGE3DPROC glTexImage3D = nullptr;
-//PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = nullptr;
-//PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D = nullptr;
+PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = nullptr;
+PFNGLTEXIMAGE3DPROC glTexImage3D = nullptr;
+PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = nullptr;
+PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D = nullptr;
// GL_VERSION_1_3
PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr;
@@ -254,43 +341,6 @@ PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D = nullptr;
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D = nullptr;
PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glCompressedTexSubImage1D = nullptr;
PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage = nullptr;
-PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture = nullptr;
-PFNGLMULTITEXCOORD1DPROC glMultiTexCoord1d = nullptr;
-PFNGLMULTITEXCOORD1DVPROC glMultiTexCoord1dv = nullptr;
-PFNGLMULTITEXCOORD1FPROC glMultiTexCoord1f = nullptr;
-PFNGLMULTITEXCOORD1FVPROC glMultiTexCoord1fv = nullptr;
-PFNGLMULTITEXCOORD1IPROC glMultiTexCoord1i = nullptr;
-PFNGLMULTITEXCOORD1IVPROC glMultiTexCoord1iv = nullptr;
-PFNGLMULTITEXCOORD1SPROC glMultiTexCoord1s = nullptr;
-PFNGLMULTITEXCOORD1SVPROC glMultiTexCoord1sv = nullptr;
-PFNGLMULTITEXCOORD2DPROC glMultiTexCoord2d = nullptr;
-PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv = nullptr;
-PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f = nullptr;
-PFNGLMULTITEXCOORD2FVPROC glMultiTexCoord2fv = nullptr;
-PFNGLMULTITEXCOORD2IPROC glMultiTexCoord2i = nullptr;
-PFNGLMULTITEXCOORD2IVPROC glMultiTexCoord2iv = nullptr;
-PFNGLMULTITEXCOORD2SPROC glMultiTexCoord2s = nullptr;
-PFNGLMULTITEXCOORD2SVPROC glMultiTexCoord2sv = nullptr;
-PFNGLMULTITEXCOORD3DPROC glMultiTexCoord3d = nullptr;
-PFNGLMULTITEXCOORD3DVPROC glMultiTexCoord3dv = nullptr;
-PFNGLMULTITEXCOORD3FPROC glMultiTexCoord3f = nullptr;
-PFNGLMULTITEXCOORD3FVPROC glMultiTexCoord3fv = nullptr;
-PFNGLMULTITEXCOORD3IPROC glMultiTexCoord3i = nullptr;
-PFNGLMULTITEXCOORD3IVPROC glMultiTexCoord3iv = nullptr;
-PFNGLMULTITEXCOORD3SPROC glMultiTexCoord3s = nullptr;
-PFNGLMULTITEXCOORD3SVPROC glMultiTexCoord3sv = nullptr;
-PFNGLMULTITEXCOORD4DPROC glMultiTexCoord4d = nullptr;
-PFNGLMULTITEXCOORD4DVPROC glMultiTexCoord4dv = nullptr;
-PFNGLMULTITEXCOORD4FPROC glMultiTexCoord4f = nullptr;
-PFNGLMULTITEXCOORD4FVPROC glMultiTexCoord4fv = nullptr;
-PFNGLMULTITEXCOORD4IPROC glMultiTexCoord4i = nullptr;
-PFNGLMULTITEXCOORD4IVPROC glMultiTexCoord4iv = nullptr;
-PFNGLMULTITEXCOORD4SPROC glMultiTexCoord4s = nullptr;
-PFNGLMULTITEXCOORD4SVPROC glMultiTexCoord4sv = nullptr;
-PFNGLLOADTRANSPOSEMATRIXFPROC glLoadTransposeMatrixf = nullptr;
-PFNGLLOADTRANSPOSEMATRIXDPROC glLoadTransposeMatrixd = nullptr;
-PFNGLMULTTRANSPOSEMATRIXFPROC glMultTransposeMatrixf = nullptr;
-PFNGLMULTTRANSPOSEMATRIXDPROC glMultTransposeMatrixd = nullptr;
// GL_VERSION_1_4
PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate = nullptr;
@@ -300,44 +350,6 @@ PFNGLPOINTPARAMETERFPROC glPointParameterf = nullptr;
PFNGLPOINTPARAMETERFVPROC glPointParameterfv = nullptr;
PFNGLPOINTPARAMETERIPROC glPointParameteri = nullptr;
PFNGLPOINTPARAMETERIVPROC glPointParameteriv = nullptr;
-PFNGLFOGCOORDFPROC glFogCoordf = nullptr;
-PFNGLFOGCOORDFVPROC glFogCoordfv = nullptr;
-PFNGLFOGCOORDDPROC glFogCoordd = nullptr;
-PFNGLFOGCOORDDVPROC glFogCoorddv = nullptr;
-PFNGLFOGCOORDPOINTERPROC glFogCoordPointer = nullptr;
-PFNGLSECONDARYCOLOR3BPROC glSecondaryColor3b = nullptr;
-PFNGLSECONDARYCOLOR3BVPROC glSecondaryColor3bv = nullptr;
-PFNGLSECONDARYCOLOR3DPROC glSecondaryColor3d = nullptr;
-PFNGLSECONDARYCOLOR3DVPROC glSecondaryColor3dv = nullptr;
-PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f = nullptr;
-PFNGLSECONDARYCOLOR3FVPROC glSecondaryColor3fv = nullptr;
-PFNGLSECONDARYCOLOR3IPROC glSecondaryColor3i = nullptr;
-PFNGLSECONDARYCOLOR3IVPROC glSecondaryColor3iv = nullptr;
-PFNGLSECONDARYCOLOR3SPROC glSecondaryColor3s = nullptr;
-PFNGLSECONDARYCOLOR3SVPROC glSecondaryColor3sv = nullptr;
-PFNGLSECONDARYCOLOR3UBPROC glSecondaryColor3ub = nullptr;
-PFNGLSECONDARYCOLOR3UBVPROC glSecondaryColor3ubv = nullptr;
-PFNGLSECONDARYCOLOR3UIPROC glSecondaryColor3ui = nullptr;
-PFNGLSECONDARYCOLOR3UIVPROC glSecondaryColor3uiv = nullptr;
-PFNGLSECONDARYCOLOR3USPROC glSecondaryColor3us = nullptr;
-PFNGLSECONDARYCOLOR3USVPROC glSecondaryColor3usv = nullptr;
-PFNGLSECONDARYCOLORPOINTERPROC glSecondaryColorPointer = nullptr;
-PFNGLWINDOWPOS2DPROC glWindowPos2d = nullptr;
-PFNGLWINDOWPOS2DVPROC glWindowPos2dv = nullptr;
-PFNGLWINDOWPOS2FPROC glWindowPos2f = nullptr;
-PFNGLWINDOWPOS2FVPROC glWindowPos2fv = nullptr;
-PFNGLWINDOWPOS2IPROC glWindowPos2i = nullptr;
-PFNGLWINDOWPOS2IVPROC glWindowPos2iv = nullptr;
-PFNGLWINDOWPOS2SPROC glWindowPos2s = nullptr;
-PFNGLWINDOWPOS2SVPROC glWindowPos2sv = nullptr;
-PFNGLWINDOWPOS3DPROC glWindowPos3d = nullptr;
-PFNGLWINDOWPOS3DVPROC glWindowPos3dv = nullptr;
-PFNGLWINDOWPOS3FPROC glWindowPos3f = nullptr;
-PFNGLWINDOWPOS3FVPROC glWindowPos3fv = nullptr;
-PFNGLWINDOWPOS3IPROC glWindowPos3i = nullptr;
-PFNGLWINDOWPOS3IVPROC glWindowPos3iv = nullptr;
-PFNGLWINDOWPOS3SPROC glWindowPos3s = nullptr;
-PFNGLWINDOWPOS3SVPROC glWindowPos3sv = nullptr;
// GL_VERSION_1_5
PFNGLGENQUERIESPROC glGenQueries = nullptr;
@@ -613,36 +625,6 @@ PFNGLVERTEXATTRIBP3UIPROC glVertexAttribP3ui = nullptr;
PFNGLVERTEXATTRIBP3UIVPROC glVertexAttribP3uiv = nullptr;
PFNGLVERTEXATTRIBP4UIPROC glVertexAttribP4ui = nullptr;
PFNGLVERTEXATTRIBP4UIVPROC glVertexAttribP4uiv = nullptr;
-PFNGLVERTEXP2UIPROC glVertexP2ui = nullptr;
-PFNGLVERTEXP2UIVPROC glVertexP2uiv = nullptr;
-PFNGLVERTEXP3UIPROC glVertexP3ui = nullptr;
-PFNGLVERTEXP3UIVPROC glVertexP3uiv = nullptr;
-PFNGLVERTEXP4UIPROC glVertexP4ui = nullptr;
-PFNGLVERTEXP4UIVPROC glVertexP4uiv = nullptr;
-PFNGLTEXCOORDP1UIPROC glTexCoordP1ui = nullptr;
-PFNGLTEXCOORDP1UIVPROC glTexCoordP1uiv = nullptr;
-PFNGLTEXCOORDP2UIPROC glTexCoordP2ui = nullptr;
-PFNGLTEXCOORDP2UIVPROC glTexCoordP2uiv = nullptr;
-PFNGLTEXCOORDP3UIPROC glTexCoordP3ui = nullptr;
-PFNGLTEXCOORDP3UIVPROC glTexCoordP3uiv = nullptr;
-PFNGLTEXCOORDP4UIPROC glTexCoordP4ui = nullptr;
-PFNGLTEXCOORDP4UIVPROC glTexCoordP4uiv = nullptr;
-PFNGLMULTITEXCOORDP1UIPROC glMultiTexCoordP1ui = nullptr;
-PFNGLMULTITEXCOORDP1UIVPROC glMultiTexCoordP1uiv = nullptr;
-PFNGLMULTITEXCOORDP2UIPROC glMultiTexCoordP2ui = nullptr;
-PFNGLMULTITEXCOORDP2UIVPROC glMultiTexCoordP2uiv = nullptr;
-PFNGLMULTITEXCOORDP3UIPROC glMultiTexCoordP3ui = nullptr;
-PFNGLMULTITEXCOORDP3UIVPROC glMultiTexCoordP3uiv = nullptr;
-PFNGLMULTITEXCOORDP4UIPROC glMultiTexCoordP4ui = nullptr;
-PFNGLMULTITEXCOORDP4UIVPROC glMultiTexCoordP4uiv = nullptr;
-PFNGLNORMALP3UIPROC glNormalP3ui = nullptr;
-PFNGLNORMALP3UIVPROC glNormalP3uiv = nullptr;
-PFNGLCOLORP3UIPROC glColorP3ui = nullptr;
-PFNGLCOLORP3UIVPROC glColorP3uiv = nullptr;
-PFNGLCOLORP4UIPROC glColorP4ui = nullptr;
-PFNGLCOLORP4UIVPROC glColorP4uiv = nullptr;
-PFNGLSECONDARYCOLORP3UIPROC glSecondaryColorP3ui = nullptr;
-PFNGLSECONDARYCOLORP3UIVPROC glSecondaryColorP3uiv = nullptr;
// GL_VERSION_4_0
PFNGLMINSAMPLESHADINGPROC glMinSampleShading = nullptr;
@@ -962,18 +944,6 @@ PFNGLGETNUNIFORMFVPROC glGetnUniformfv = nullp
PFNGLGETNUNIFORMIVPROC glGetnUniformiv = nullptr;
PFNGLGETNUNIFORMUIVPROC glGetnUniformuiv = nullptr;
PFNGLREADNPIXELSPROC glReadnPixels = nullptr;
-PFNGLGETNMAPDVPROC glGetnMapdv = nullptr;
-PFNGLGETNMAPFVPROC glGetnMapfv = nullptr;
-PFNGLGETNMAPIVPROC glGetnMapiv = nullptr;
-PFNGLGETNPIXELMAPFVPROC glGetnPixelMapfv = nullptr;
-PFNGLGETNPIXELMAPUIVPROC glGetnPixelMapuiv = nullptr;
-PFNGLGETNPIXELMAPUSVPROC glGetnPixelMapusv = nullptr;
-PFNGLGETNPOLYGONSTIPPLEPROC glGetnPolygonStipple = nullptr;
-PFNGLGETNCOLORTABLEPROC glGetnColorTable = nullptr;
-PFNGLGETNCONVOLUTIONFILTERPROC glGetnConvolutionFilter = nullptr;
-PFNGLGETNSEPARABLEFILTERPROC glGetnSeparableFilter = nullptr;
-PFNGLGETNHISTOGRAMPROC glGetnHistogram = nullptr;
-PFNGLGETNMINMAXPROC glGetnMinmax = nullptr;
PFNGLTEXTUREBARRIERPROC glTextureBarrier = nullptr;
// GL_VERSION_4_6
@@ -1010,7 +980,8 @@ LLGLManager::LLGLManager() :
mGLSLVersionMinor(0),
mVRAM(0),
mGLMaxVertexRange(0),
- mGLMaxIndexRange(0)
+ mGLMaxIndexRange(0),
+ mGLMaxTextureSize(0)
{
}
@@ -1020,14 +991,23 @@ LLGLManager::LLGLManager() :
void LLGLManager::initWGL()
{
#if LL_WINDOWS && !LL_MESA_HEADLESS
- if (!glh_init_extensions("WGL_ARB_pixel_format"))
+ reloadExtensionsString();
+
+ if (mGLExtensions.contains("WGL_ARB_pixel_format"))
+ {
+ wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)LL_GET_PROC_ADDRESS("wglGetPixelFormatAttribivARB");
+ wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)LL_GET_PROC_ADDRESS("wglGetPixelFormatAttribfvARB");
+ wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)LL_GET_PROC_ADDRESS("wglChoosePixelFormatARB");
+ }
+ else
{
LL_WARNS("RenderInit") << "No ARB pixel format extensions" << LL_ENDL;
}
- if (ExtensionExists("WGL_ARB_create_context",gGLHExts.mSysExts))
+ // WGL_ARB_create_context
+ if (mGLExtensions.contains("WGL_ARB_create_context"))
{
- GLH_EXT_NAME(wglCreateContextAttribsARB) = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
+ wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)LL_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
}
else
{
@@ -1036,72 +1016,151 @@ void LLGLManager::initWGL()
// For retreiving information per AMD adapter,
// because we can't trust curently selected/default one when there are multiple
- mHasAMDAssociations = ExtensionExists("WGL_AMD_gpu_association", gGLHExts.mSysExts);
+ mHasAMDAssociations = mGLExtensions.contains("WGL_AMD_gpu_association");
if (mHasAMDAssociations)
{
- GLH_EXT_NAME(wglGetGPUIDsAMD) = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
- GLH_EXT_NAME(wglGetGPUInfoAMD) = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
+ wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)LL_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
+ wglGetGPUInfoAMD = (PFNWGLGETGPUINFOAMDPROC)LL_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
+ wglGetContextGPUIDAMD = (PFNWGLGETCONTEXTGPUIDAMDPROC)LL_GET_PROC_ADDRESS("wglGetContextGPUIDAMD");
+ wglCreateAssociatedContextAMD = (PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC)LL_GET_PROC_ADDRESS("wglCreateAssociatedContextAMD");
+ wglCreateAssociatedContextAttribsAMD = (PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)LL_GET_PROC_ADDRESS("wglCreateAssociatedContextAttribsAMD");
+ wglDeleteAssociatedContextAMD = (PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC)LL_GET_PROC_ADDRESS("wglDeleteAssociatedContextAMD");
+ wglMakeAssociatedContextCurrentAMD = (PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)LL_GET_PROC_ADDRESS("wglMakeAssociatedContextCurrentAMD");
+ wglGetCurrentAssociatedContextAMD = (PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC)LL_GET_PROC_ADDRESS("wglGetCurrentAssociatedContextAMD");
+ wglBlitContextFramebufferAMD = (PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC)LL_GET_PROC_ADDRESS("wglBlitContextFramebufferAMD");
+
}
- mHasNVXGpuMemoryInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
- if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
+ // WGL_EXT_swap_control
+ if (mGLExtensions.contains("WGL_EXT_swap_control"))
{
- GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
+ wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)LL_GET_PROC_ADDRESS("wglSwapIntervalEXT");
+ wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)LL_GET_PROC_ADDRESS("wglGetSwapIntervalEXT");
}
- if( !glh_init_extensions("WGL_ARB_pbuffer") )
+ if(!mGLExtensions.contains("WGL_ARB_pbuffer"))
{
LL_WARNS("RenderInit") << "No ARB WGL PBuffer extensions" << LL_ENDL;
}
- if( !glh_init_extensions("WGL_ARB_render_texture") )
+ if(!mGLExtensions.contains("WGL_ARB_render_texture"))
{
LL_WARNS("RenderInit") << "No ARB WGL render texture extensions" << LL_ENDL;
}
#endif
}
-// return false if unable (or unwilling due to old drivers) to init GL
-bool LLGLManager::initGL()
+void LLGLManager::initGLX()
{
- if (mInited)
- {
- LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
- }
+#if LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+ if (!mIsX11)
+ return;
+
+ reloadExtensionsString();
-#if 0 && LL_WINDOWS
- if (!glGetStringi)
+ mHasGLXMESAQueryRenderer = mGLExtensions.contains("GLX_MESA_query_renderer");
+ if (mHasGLXMESAQueryRenderer)
{
- glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi");
+ glXQueryCurrentRendererIntegerMESA = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)LL_GET_PROC_ADDRESS("glXQueryCurrentRendererIntegerMESA");
+ glXQueryCurrentRendererStringMESA = (PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC)LL_GET_PROC_ADDRESS("glXQueryCurrentRendererStringMESA");
+ glXQueryRendererIntegerMESA = (PFNGLXQUERYRENDERERINTEGERMESAPROC)LL_GET_PROC_ADDRESS("glXQueryRendererIntegerMESA");
+ glXQueryRendererStringMESA = (PFNGLXQUERYRENDERERSTRINGMESAPROC)LL_GET_PROC_ADDRESS("glXQueryRendererStringMESA");
}
+#endif
+}
- //reload extensions string (may have changed after using wglCreateContextAttrib)
- if (glGetStringi)
- {
- std::stringstream str;
+void LLGLManager::initEGL()
+{
+#if LL_LINUX && LL_WAYLAND && !LL_MESA_HEADLESS
+ if (!mIsWayland)
+ return;
- GLint count = 0;
- glGetIntegerv(GL_NUM_EXTENSIONS, &count);
- for (GLint i = 0; i < count; ++i)
- {
- std::string ext = ll_safe_string((const char*) glGetStringi(GL_EXTENSIONS, i));
- str << ext << " ";
- LL_DEBUGS("GLExtensions") << ext << LL_ENDL;
- }
+ reloadExtensionsString();
+
+ // EGL_VERSION_1_0
+ eglQueryString = (PFNEGLQUERYSTRINGPROC)LL_GET_PROC_ADDRESS("eglQueryString");
+
+ LL_INFOS("RenderInit") << "EGL_VENDOR " << ll_safe_string((const char *)eglQueryString(SDL_EGL_GetCurrentDisplay(), EGL_VENDOR)) << LL_ENDL;
+ LL_INFOS("RenderInit") << "EGL_VERSION " << ll_safe_string((const char *)eglQueryString(SDL_EGL_GetCurrentDisplay(), EGL_VERSION)) << LL_ENDL;
+#endif
+}
- {
- PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
- wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
- if(wglGetExtensionsStringARB)
- {
- str << (const char*) wglGetExtensionsStringARB(wglGetCurrentDC());
- }
- }
- free(gGLHExts.mSysExts);
- std::string extensions = str.str();
- gGLHExts.mSysExts = strdup(extensions.c_str());
+// return false if unable (or unwilling due to old drivers) to init GL
+bool LLGLManager::initGL()
+{
+ if (mInited)
+ {
+ LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
}
+
+#if LL_GL_FUNC_POINTER
+ // OpenGL 1.0 and 1.1 always exist
+ // GL_VERSION_1_0
+ glClearColor = (PFNGLCLEARCOLORPROC)LL_GET_PROC_ADDRESS("glClearColor");
+ glClear = (PFNGLCLEARPROC)LL_GET_PROC_ADDRESS("glClear");
+ glColorMask = (PFNGLCOLORMASKPROC)LL_GET_PROC_ADDRESS("glColorMask");
+ glBlendFunc = (PFNGLBLENDFUNCPROC)LL_GET_PROC_ADDRESS("glBlendFunc");
+ glLogicOp = (PFNGLLOGICOPPROC)LL_GET_PROC_ADDRESS("glLogicOp");
+ glFrontFace = (PFNGLFRONTFACEPROC)LL_GET_PROC_ADDRESS("glFrontFace");
+ glCullFace = (PFNGLCULLFACEPROC)LL_GET_PROC_ADDRESS("glCullFace");;
+ glPointSize = (PFNGLPOINTSIZEPROC)LL_GET_PROC_ADDRESS("glPointSize");
+ glLineWidth = (PFNGLLINEWIDTHPROC)LL_GET_PROC_ADDRESS("glLineWidth");
+ glPolygonMode = (PFNGLPOLYGONMODEPROC)LL_GET_PROC_ADDRESS("glPolygonMode");
+ glScissor = (PFNGLSCISSORPROC)LL_GET_PROC_ADDRESS("glScissor");
+ glDrawBuffer = (PFNGLDRAWBUFFERPROC)LL_GET_PROC_ADDRESS("glDrawBuffer");
+ glReadBuffer = (PFNGLREADBUFFERPROC)LL_GET_PROC_ADDRESS("glReadBuffer");
+ glEnable = (PFNGLENABLEPROC)LL_GET_PROC_ADDRESS("glEnable");
+ glDisable = (PFNGLDISABLEPROC)LL_GET_PROC_ADDRESS("glDisable");
+ glIsEnabled = (PFNGLISENABLEDPROC)LL_GET_PROC_ADDRESS("glIsEnabled");
+ glGetBooleanv = (PFNGLGETBOOLEANVPROC)LL_GET_PROC_ADDRESS("glGetBooleanv");
+ glGetDoublev = (PFNGLGETDOUBLEVPROC)LL_GET_PROC_ADDRESS("glGetDoublev");
+ glGetFloatv = (PFNGLGETFLOATVPROC)LL_GET_PROC_ADDRESS("glGetFloatv");
+ glGetIntegerv = (PFNGLGETINTEGERVPROC)LL_GET_PROC_ADDRESS("glGetIntegerv");
+ glGetError = (PFNGLGETERRORPROC)LL_GET_PROC_ADDRESS("glGetError");
+ glGetString = (PFNGLGETSTRINGPROC)LL_GET_PROC_ADDRESS("glGetString");
+ glFinish = (PFNGLFINISHPROC)LL_GET_PROC_ADDRESS("glFinish");
+ glFlush = (PFNGLFLUSHPROC)LL_GET_PROC_ADDRESS("glFlush");
+ glHint = (PFNGLHINTPROC)LL_GET_PROC_ADDRESS("glHint");
+ glClearDepth = (PFNGLCLEARDEPTHPROC)LL_GET_PROC_ADDRESS("glClearDepth");
+ glDepthFunc = (PFNGLDEPTHFUNCPROC)LL_GET_PROC_ADDRESS("glDepthFunc");
+ glDepthMask = (PFNGLDEPTHMASKPROC)LL_GET_PROC_ADDRESS("glDepthMask");
+ glDepthRange = (PFNGLDEPTHRANGEPROC)LL_GET_PROC_ADDRESS("glDepthRange");
+ glViewport = (PFNGLVIEWPORTPROC)LL_GET_PROC_ADDRESS("glViewport");
+ glPixelStoref = (PFNGLPIXELSTOREFPROC)LL_GET_PROC_ADDRESS("glPixelStoref");
+ glPixelStorei = (PFNGLPIXELSTOREIPROC)LL_GET_PROC_ADDRESS("glPixelStorei");
+ glReadPixels = (PFNGLREADPIXELSPROC)LL_GET_PROC_ADDRESS("glReadPixels");
+ glStencilFunc = (PFNGLSTENCILFUNCPROC)LL_GET_PROC_ADDRESS("glStencilFunc");
+ glStencilMask = (PFNGLSTENCILMASKPROC)LL_GET_PROC_ADDRESS("glStencilMask");
+ glStencilOp = (PFNGLSTENCILOPPROC)LL_GET_PROC_ADDRESS("glStencilOp");
+ glClearStencil = (PFNGLCLEARSTENCILPROC)LL_GET_PROC_ADDRESS("glClearStencil");
+ glTexParameterf = (PFNGLTEXPARAMETERFPROC)LL_GET_PROC_ADDRESS("glTexParameterf");
+ glTexParameteri = (PFNGLTEXPARAMETERIPROC)LL_GET_PROC_ADDRESS("glTexParameteri");
+ glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)LL_GET_PROC_ADDRESS("glTexParameterfv");
+ glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glTexParameteriv");
+ glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)LL_GET_PROC_ADDRESS("glGetTexParameterfv");
+ glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetTexParameteriv");
+ glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC)LL_GET_PROC_ADDRESS("glGetTexLevelParameterfv");
+ glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetTexLevelParameteriv");
+ glTexImage1D = (PFNGLTEXIMAGE1DPROC)LL_GET_PROC_ADDRESS("glTexImage1D");
+ glTexImage2D = (PFNGLTEXIMAGE2DPROC)LL_GET_PROC_ADDRESS("glTexImage2D");
+ glGetTexImage = (PFNGLGETTEXIMAGEPROC)LL_GET_PROC_ADDRESS("glGetTexImage");
+
+ // GL_VERSION_1_1
+ glDrawArrays = (PFNGLDRAWARRAYSPROC)LL_GET_PROC_ADDRESS("glDrawArrays");
+ glDrawElements = (PFNGLDRAWELEMENTSPROC)LL_GET_PROC_ADDRESS("glDrawElements");
+ glGetPointerv = (PFNGLGETPOINTERVPROC)LL_GET_PROC_ADDRESS("glGetPointerv");
+ glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)LL_GET_PROC_ADDRESS("glPolygonOffset");
+ glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)LL_GET_PROC_ADDRESS("glCopyTexImage1D");
+ glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)LL_GET_PROC_ADDRESS("glCopyTexImage2D");
+ glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC)LL_GET_PROC_ADDRESS("glCopyTexSubImage1D");
+ glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)LL_GET_PROC_ADDRESS("glCopyTexSubImage2D");
+ glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC)LL_GET_PROC_ADDRESS("glTexSubImage1D");
+ glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)LL_GET_PROC_ADDRESS("glTexSubImage2D");
+ glBindTexture = (PFNGLBINDTEXTUREPROC)LL_GET_PROC_ADDRESS("glBindTexture");
+ glDeleteTextures = (PFNGLDELETETEXTURESPROC)LL_GET_PROC_ADDRESS("glDeleteTextures");
+ glGenTextures = (PFNGLGENTEXTURESPROC)LL_GET_PROC_ADDRESS("glGenTextures");
+ glIsTexture = (PFNGLISTEXTUREPROC)LL_GET_PROC_ADDRESS("glIsTexture");
#endif
// Extract video card strings and convert to upper case to
@@ -1137,7 +1196,11 @@ bool LLGLManager::initGL()
// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
// from being recognized as ATI.
// NOTE: AMD has been pretty good about not breaking this check, do not rename without good reason
- if (mGLVendor.substr(0,4) == "ATI ")
+ if (mGLVendor.substr(0,4) == "ATI "
+#if LL_LINUX
+ || mGLVendor.find("AMD") != std::string::npos
+#endif //LL_LINUX
+ )
{
mGLVendorShort = "AMD";
// *TODO: Fix this?
@@ -1203,16 +1266,46 @@ bool LLGLManager::initGL()
{
LL_WARNS("RenderInit") << "VRAM Detected (AMDAssociations):" << mVRAM << LL_ENDL;
}
- }
- else if (mHasNVXGpuMemoryInfo)
+ } else
+#endif
+
+#if LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+ if(mHasGLXMESAQueryRenderer && mVRAM == 0)
{
- GLint mem_kb = 0;
- glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &mem_kb);
- mVRAM = mem_kb / 1024;
+ unsigned int vram_val = 0;
+ if(glXQueryCurrentRendererIntegerMESA(GLX_RENDERER_VIDEO_MEMORY_MESA, &vram_val))
+ {
+ gGLManager.mVRAM = vram_val;
- if (mVRAM != 0)
+ if (mVRAM != 0)
+ {
+ LL_WARNS("RenderInit") << "VRAM Detected (GLXMesaQueryRenderer):" << mVRAM << LL_ENDL;
+ }
+ }
+ }
+#endif
+
+#if LL_WINDOWS || LL_LINUX
+ {
+ if (mHasNVXGpuMemoryInfo && mVRAM == 0)
{
- LL_WARNS("RenderInit") << "VRAM Detected (NVXGpuMemoryInfo):" << mVRAM << LL_ENDL;
+ GLint mem_kb = 0;
+ glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &mem_kb);
+ mVRAM = mem_kb / 1024;
+
+ if (mVRAM != 0)
+ {
+ LL_WARNS("RenderInit") << "VRAM Detected (NVXGpuMemoryInfo):" << mVRAM << LL_ENDL;
+ }
+ }
+
+ if (mHasATIMemInfo && mVRAM == 0)
+ { //ask the gl how much vram is free at startup and attempt to use no more than half of that
+ S32 meminfo[4];
+ glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
+
+ mVRAM = meminfo[0] / 1024;
+ LL_INFOS("RenderInit") << "VRAM Detected (ATIMemInfo):" << mVRAM << LL_ENDL;
}
}
#endif
@@ -1232,6 +1325,9 @@ bool LLGLManager::initGL()
glGetIntegerv(GL_MAX_VARYING_VECTORS, &mMaxVaryingVectors);
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &mMaxUniformBlockSize);
+ // If outside the allowed range, glLineWidth fails with "invalid value".
+ glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, mAliasedLineRange.mV);
+
// sanity clamp max uniform block size to 64k just in case
// there's some implementation that reports a crazy value
mMaxUniformBlockSize = llmin(mMaxUniformBlockSize, 65536);
@@ -1263,12 +1359,9 @@ void LLGLManager::getGLInfo(LLSD& info)
}
#if !LL_MESA_HEADLESS
- std::string all_exts = ll_safe_string((const char *)gGLHExts.mSysExts);
- boost::char_separator<char> sep(" ");
- boost::tokenizer<boost::char_separator<char> > tok(all_exts, sep);
- for(boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
+ for (const auto& ext : mGLExtensions)
{
- info["GLInfo"]["GLExtensions"].append(*i);
+ info["GLInfo"]["GLExtensions"].append(ext);
}
#endif
}
@@ -1291,8 +1384,12 @@ std::string LLGLManager::getGLInfoString()
}
#if !LL_MESA_HEADLESS
- std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
- LLStringUtil::replaceChar(all_exts, ' ', '\n');
+ std::string all_exts;
+ for (const auto& ext : mGLExtensions)
+ {
+ all_exts += ext;
+ all_exts += '\n';
+ }
info_str += std::string("GL_EXTENSIONS:\n") + all_exts + std::string("\n");
#endif
@@ -1315,9 +1412,13 @@ void LLGLManager::printGLInfoString()
}
#if !LL_MESA_HEADLESS
- std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
- LLStringUtil::replaceChar(all_exts, ' ', '\n');
- LL_DEBUGS("RenderInit") << "GL_EXTENSIONS:\n" << all_exts << LL_ENDL;
+ std::string all_exts;
+ for (const auto& ext : mGLExtensions)
+ {
+ all_exts += ext;
+ all_exts += '\n';
+ }
+ LL_INFOS("RenderInit") << "GL_EXTENSIONS:\n" << all_exts << LL_ENDL;
#endif
}
@@ -1376,24 +1477,104 @@ void LLGLManager::shutdownGL()
// these are used to turn software blending on. They appear in the Debug/Avatar menu
// presence of vertex skinning/blending or vertex programs will set these to false by default.
-void LLGLManager::initExtensions()
+void LLGLManager::reloadExtensionsString()
{
+ mGLExtensions.clear();
+
+ //reload extensions string
+ // I am deeply sorry for how ugly this is. - Rye
+#if LL_GL_FUNC_POINTER
+ PFNGLGETSTRINGIPROC llglGetStringi = (PFNGLGETSTRINGIPROC)LL_GET_PROC_ADDRESS("glGetStringi");
+ PFNGLGETINTEGERVPROC llglGetIntegerv = (PFNGLGETINTEGERVPROC)LL_GET_PROC_ADDRESS("glGetIntegerv");
+ if (llglGetStringi && llglGetIntegerv)
+ {
+ GLint num_extensions = 0;
+ llglGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
+ for (GLint i = 0; i < num_extensions; ++i) {
+ mGLExtensions.insert(ll_safe_string((char const*)llglGetStringi(GL_EXTENSIONS, i)));
+ }
+ }
+#else
+ {
+ GLint num_extensions = 0;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
+ for (GLint i = 0; i < num_extensions; ++i) {
+ mGLExtensions.insert(ll_safe_string((char const*)glGetStringi(GL_EXTENSIONS, i)));
+ }
#if LL_DARWIN
- GLint num_extensions = 0;
- std::string all_extensions{""};
- glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
- for(GLint i = 0; i < num_extensions; ++i) {
- char const * extension = (char const *)glGetStringi(GL_EXTENSIONS, i);
- all_extensions += extension;
- all_extensions += ' ';
+ if (num_extensions > 0)
+ {
+ mGLExtensions.insert("GL_ARB_multitexture");
+ mGLExtensions.insert("GL_ARB_texture_cube_map");
+ mGLExtensions.insert("GL_ARB_texture_compression");
+ }
+#endif
}
- if (num_extensions)
+#endif
+
+#if LL_WINDOWS
{
- all_extensions += "GL_ARB_multitexture GL_ARB_texture_cube_map GL_ARB_texture_compression "; // These are in 3.2 core, but not listed by OSX
- gGLHExts.mSysExts = strdup(all_extensions.data());
+ PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)LL_GET_PROC_ADDRESS("wglGetExtensionsStringARB");
+ if (wglGetExtensionsStringARB)
+ {
+ std::string wgl_exts = ll_safe_string((const char*)wglGetExtensionsStringARB(wglGetCurrentDC()));
+ boost::char_separator<char> sep(" ");
+ boost::tokenizer<boost::char_separator<char> > tok(wgl_exts, sep);
+ for (boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
+ {
+ mGLExtensions.insert(*i);
+ }
+ }
}
#endif
+#if LL_SDL_WINDOW && LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+ if (mIsX11)
+ {
+ if (LLWindowSDL::sX11Data.xdisplay && LLWindowSDL::sX11Data.xwindow)
+ {
+ typedef const char *(*PFNEGLXQUERYEXTENSIONSSTRINGPROC) (Display *dpy, int screen );
+ PFNEGLXQUERYEXTENSIONSSTRINGPROC llglXQueryExtensionsString = (PFNEGLXQUERYEXTENSIONSSTRINGPROC)LL_GET_PROC_ADDRESS("glXQueryExtensionsString");
+ if (llglXQueryExtensionsString)
+ {
+ std::string glx_exts = ll_safe_string((const char*)llglXQueryExtensionsString(LLWindowSDL::sX11Data.xdisplay, LLWindowSDL::sX11Data.xscreen));
+ boost::char_separator<char> sep(" ");
+ boost::tokenizer<boost::char_separator<char> > tok(glx_exts, sep);
+ for (boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
+ {
+ mGLExtensions.insert(*i);
+ }
+ }
+ }
+ }
+#endif
+
+#if LL_SDL_WINDOW && LL_LINUX && LL_WAYLAND && !LL_MESA_HEADLESS
+ if (mIsWayland)
+ {
+ SDL_EGLDisplay egl_display = SDL_EGL_GetCurrentDisplay();
+ if (egl_display)
+ {
+ PFNEGLQUERYSTRINGPROC lleglQueryString = (PFNEGLQUERYSTRINGPROC)LL_GET_PROC_ADDRESS("eglQueryString");
+ if (lleglQueryString)
+ {
+ std::string egl_exts = ll_safe_string((const char*)lleglQueryString((EGLDisplay)egl_display, EGL_EXTENSIONS));
+ boost::char_separator<char> sep(" ");
+ boost::tokenizer<boost::char_separator<char> > tok(egl_exts, sep);
+ for (boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
+ {
+ mGLExtensions.insert(*i);
+ }
+ }
+ }
+ }
+#endif
+}
+
+void LLGLManager::initExtensions()
+{
+ reloadExtensionsString();
+
// NOTE: version checks against mGLVersion should bias down by 0.01 because of F32 errors
// OpenGL 4.x capabilities
@@ -1401,11 +1582,14 @@ void LLGLManager::initExtensions()
mHasTransformFeedback = mGLVersion >= 3.99f;
mHasDebugOutput = mGLVersion >= 4.29f;
mHasAnisotropic = mGLVersion >= 4.59f;
- if(!mHasAnisotropic && gGLHExts.mSysExts)
+ if(!mHasAnisotropic)
{
- mHasAnisotropic = ExtensionExists("GL_EXT_texture_filter_anisotropic", gGLHExts.mSysExts);
+ mHasAnisotropic = mGLExtensions.contains("GL_EXT_texture_filter_anisotropic");
}
+ mHasNVXGpuMemoryInfo = mGLExtensions.contains("GL_NVX_gpu_memory_info");
+ mHasATIMemInfo = mGLExtensions.contains("GL_ATI_meminfo"); //Basic AMD method, also see mHasAMDAssociations
+
// Misc
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
@@ -1413,846 +1597,706 @@ void LLGLManager::initExtensions()
mInited = true;
-#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
- LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
-
-#if LL_WINDOWS
- // WGL_AMD_gpu_association
- wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
- wglGetGPUInfoAMD = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
- wglGetContextGPUIDAMD = (PFNWGLGETCONTEXTGPUIDAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetContextGPUIDAMD");
- wglCreateAssociatedContextAMD = (PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateAssociatedContextAMD");
- wglCreateAssociatedContextAttribsAMD = (PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateAssociatedContextAttribsAMD");
- wglDeleteAssociatedContextAMD = (PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglDeleteAssociatedContextAMD");
- wglMakeAssociatedContextCurrentAMD = (PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglMakeAssociatedContextCurrentAMD");
- wglGetCurrentAssociatedContextAMD = (PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetCurrentAssociatedContextAMD");
- wglBlitContextFramebufferAMD = (PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglBlitContextFramebufferAMD");
-
- // WGL_EXT_swap_control
- wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
- wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetSwapIntervalEXT");
-
- // WGL_ARB_create_context
- wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
-#endif
-
-
+#if LL_GL_FUNC_POINTER
// Load entire OpenGL API through GetProcAddress, leaving sections beyond mGLVersion unloaded
+ LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
// GL_VERSION_1_2
if (mGLVersion < 1.19f)
{
return;
}
- glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
- glTexImage3D = (PFNGLTEXIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexImage3D");
- glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexSubImage3D");
- glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyTexSubImage3D");
-
+ glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)LL_GET_PROC_ADDRESS("glDrawRangeElements");
+ glTexImage3D = (PFNGLTEXIMAGE3DPROC)LL_GET_PROC_ADDRESS("glTexImage3D");
+ glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)LL_GET_PROC_ADDRESS("glTexSubImage3D");
+ glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)LL_GET_PROC_ADDRESS("glCopyTexSubImage3D");
// GL_VERSION_1_3
if (mGLVersion < 1.29f)
{
return;
}
- glActiveTexture = (PFNGLACTIVETEXTUREPROC)GLH_EXT_GET_PROC_ADDRESS("glActiveTexture");
- glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glSampleCoverage");
- glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexImage3D");
- glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexImage2D");
- glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexImage1D");
- glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexSubImage3D");
- glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexSubImage2D");
- glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexSubImage1D");
- glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCompressedTexImage");
- glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)GLH_EXT_GET_PROC_ADDRESS("glClientActiveTexture");
- glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1d");
- glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1dv");
- glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1f");
- glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1fv");
- glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1i");
- glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1iv");
- glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1s");
- glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1sv");
- glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2d");
- glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2dv");
- glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2f");
- glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2fv");
- glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2i");
- glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2iv");
- glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2s");
- glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2sv");
- glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3d");
- glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3dv");
- glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3f");
- glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3fv");
- glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3i");
- glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3iv");
- glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3s");
- glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3sv");
- glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4d");
- glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4dv");
- glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4f");
- glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4fv");
- glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4i");
- glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4iv");
- glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4s");
- glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4sv");
- glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)GLH_EXT_GET_PROC_ADDRESS("glLoadTransposeMatrixf");
- glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)GLH_EXT_GET_PROC_ADDRESS("glLoadTransposeMatrixd");
- glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)GLH_EXT_GET_PROC_ADDRESS("glMultTransposeMatrixf");
- glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)GLH_EXT_GET_PROC_ADDRESS("glMultTransposeMatrixd");
+ glActiveTexture = (PFNGLACTIVETEXTUREPROC)LL_GET_PROC_ADDRESS("glActiveTexture");
+ glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)LL_GET_PROC_ADDRESS("glSampleCoverage");
+ glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)LL_GET_PROC_ADDRESS("glCompressedTexImage3D");
+ glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)LL_GET_PROC_ADDRESS("glCompressedTexImage2D");
+ glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)LL_GET_PROC_ADDRESS("glCompressedTexImage1D");
+ glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)LL_GET_PROC_ADDRESS("glCompressedTexSubImage3D");
+ glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)LL_GET_PROC_ADDRESS("glCompressedTexSubImage2D");
+ glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)LL_GET_PROC_ADDRESS("glCompressedTexSubImage1D");
+ glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)LL_GET_PROC_ADDRESS("glGetCompressedTexImage");
// GL_VERSION_1_4
if (mGLVersion < 1.39f)
{
return;
}
- glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparate");
- glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawArrays");
- glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawElements");
- glPointParameterf = (PFNGLPOINTPARAMETERFPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterf");
- glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfv");
- glPointParameteri = (PFNGLPOINTPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameteri");
- glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameteriv");
- glFogCoordf = (PFNGLFOGCOORDFPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordf");
- glFogCoordfv = (PFNGLFOGCOORDFVPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordfv");
- glFogCoordd = (PFNGLFOGCOORDDPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordd");
- glFogCoorddv = (PFNGLFOGCOORDDVPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoorddv");
- glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordPointer");
- glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3b");
- glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3bv");
- glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3d");
- glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3dv");
- glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3f");
- glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3fv");
- glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3i");
- glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3iv");
- glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3s");
- glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3sv");
- glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3ub");
- glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3ubv");
- glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3ui");
- glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3uiv");
- glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3us");
- glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3usv");
- glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColorPointer");
- glWindowPos2d = (PFNGLWINDOWPOS2DPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2d");
- glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2dv");
- glWindowPos2f = (PFNGLWINDOWPOS2FPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2f");
- glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2fv");
- glWindowPos2i = (PFNGLWINDOWPOS2IPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2i");
- glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2iv");
- glWindowPos2s = (PFNGLWINDOWPOS2SPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2s");
- glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2sv");
- glWindowPos3d = (PFNGLWINDOWPOS3DPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3d");
- glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3dv");
- glWindowPos3f = (PFNGLWINDOWPOS3FPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3f");
- glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3fv");
- glWindowPos3i = (PFNGLWINDOWPOS3IPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3i");
- glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3iv");
- glWindowPos3s = (PFNGLWINDOWPOS3SPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3s");
- glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3sv");
+ glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)LL_GET_PROC_ADDRESS("glBlendFuncSeparate");
+ glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)LL_GET_PROC_ADDRESS("glMultiDrawArrays");
+ glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)LL_GET_PROC_ADDRESS("glMultiDrawElements");
+ glPointParameterf = (PFNGLPOINTPARAMETERFPROC)LL_GET_PROC_ADDRESS("glPointParameterf");
+ glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)LL_GET_PROC_ADDRESS("glPointParameterfv");
+ glPointParameteri = (PFNGLPOINTPARAMETERIPROC)LL_GET_PROC_ADDRESS("glPointParameteri");
+ glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glPointParameteriv");
// GL_VERSION_1_5
if (mGLVersion < 1.49f)
{
return;
}
- glGenQueries = (PFNGLGENQUERIESPROC)GLH_EXT_GET_PROC_ADDRESS("glGenQueries");
- glDeleteQueries = (PFNGLDELETEQUERIESPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteQueries");
- glIsQuery = (PFNGLISQUERYPROC)GLH_EXT_GET_PROC_ADDRESS("glIsQuery");
- glBeginQuery = (PFNGLBEGINQUERYPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginQuery");
- glEndQuery = (PFNGLENDQUERYPROC)GLH_EXT_GET_PROC_ADDRESS("glEndQuery");
- glGetQueryiv = (PFNGLGETQUERYIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryiv");
- glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectiv");
- glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuiv");
- glBindBuffer = (PFNGLBINDBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBuffer");
- glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteBuffers");
- glGenBuffers = (PFNGLGENBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenBuffers");
- glIsBuffer = (PFNGLISBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glIsBuffer");
- glBufferData = (PFNGLBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferData");
- glBufferSubData = (PFNGLBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferSubData");
- glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferSubData");
- glMapBuffer = (PFNGLMAPBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glMapBuffer");
- glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glUnmapBuffer");
- glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferParameteriv");
- glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferPointerv");
+ glGenQueries = (PFNGLGENQUERIESPROC)LL_GET_PROC_ADDRESS("glGenQueries");
+ glDeleteQueries = (PFNGLDELETEQUERIESPROC)LL_GET_PROC_ADDRESS("glDeleteQueries");
+ glIsQuery = (PFNGLISQUERYPROC)LL_GET_PROC_ADDRESS("glIsQuery");
+ glBeginQuery = (PFNGLBEGINQUERYPROC)LL_GET_PROC_ADDRESS("glBeginQuery");
+ glEndQuery = (PFNGLENDQUERYPROC)LL_GET_PROC_ADDRESS("glEndQuery");
+ glGetQueryiv = (PFNGLGETQUERYIVPROC)LL_GET_PROC_ADDRESS("glGetQueryiv");
+ glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)LL_GET_PROC_ADDRESS("glGetQueryObjectiv");
+ glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)LL_GET_PROC_ADDRESS("glGetQueryObjectuiv");
+ glBindBuffer = (PFNGLBINDBUFFERPROC)LL_GET_PROC_ADDRESS("glBindBuffer");
+ glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)LL_GET_PROC_ADDRESS("glDeleteBuffers");
+ glGenBuffers = (PFNGLGENBUFFERSPROC)LL_GET_PROC_ADDRESS("glGenBuffers");
+ glIsBuffer = (PFNGLISBUFFERPROC)LL_GET_PROC_ADDRESS("glIsBuffer");
+ glBufferData = (PFNGLBUFFERDATAPROC)LL_GET_PROC_ADDRESS("glBufferData");
+ glBufferSubData = (PFNGLBUFFERSUBDATAPROC)LL_GET_PROC_ADDRESS("glBufferSubData");
+ glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)LL_GET_PROC_ADDRESS("glGetBufferSubData");
+ glMapBuffer = (PFNGLMAPBUFFERPROC)LL_GET_PROC_ADDRESS("glMapBuffer");
+ glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)LL_GET_PROC_ADDRESS("glUnmapBuffer");
+ glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetBufferParameteriv");
+ glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)LL_GET_PROC_ADDRESS("glGetBufferPointerv");
// GL_VERSION_2_0
if (mGLVersion < 1.9f)
{
return;
}
- glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendEquationSeparate");
- glDrawBuffers = (PFNGLDRAWBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawBuffers");
- glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)GLH_EXT_GET_PROC_ADDRESS("glStencilOpSeparate");
- glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)GLH_EXT_GET_PROC_ADDRESS("glStencilFuncSeparate");
- glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)GLH_EXT_GET_PROC_ADDRESS("glStencilMaskSeparate");
- glAttachShader = (PFNGLATTACHSHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glAttachShader");
- glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocation");
- glCompileShader = (PFNGLCOMPILESHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glCompileShader");
- glCreateProgram = (PFNGLCREATEPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateProgram");
- glCreateShader = (PFNGLCREATESHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateShader");
- glDeleteProgram = (PFNGLDELETEPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteProgram");
- glDeleteShader = (PFNGLDELETESHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteShader");
- glDetachShader = (PFNGLDETACHSHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glDetachShader");
- glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArray");
- glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArray");
- glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttrib");
- glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniform");
- glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)GLH_EXT_GET_PROC_ADDRESS("glGetAttachedShaders");
- glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocation");
- glGetProgramiv = (PFNGLGETPROGRAMIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramiv");
- glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramInfoLog");
- glGetShaderiv = (PFNGLGETSHADERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetShaderiv");
- glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)GLH_EXT_GET_PROC_ADDRESS("glGetShaderInfoLog");
- glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetShaderSource");
- glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocation");
- glGetUniformfv = (PFNGLGETUNIFORMFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformfv");
- glGetUniformiv = (PFNGLGETUNIFORMIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformiv");
- glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdv");
- glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfv");
- glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribiv");
- glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribPointerv");
- glIsProgram = (PFNGLISPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glIsProgram");
- glIsShader = (PFNGLISSHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glIsShader");
- glLinkProgram = (PFNGLLINKPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glLinkProgram");
- glShaderSource = (PFNGLSHADERSOURCEPROC)GLH_EXT_GET_PROC_ADDRESS("glShaderSource");
- glUseProgram = (PFNGLUSEPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glUseProgram");
- glUniform1f = (PFNGLUNIFORM1FPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1f");
- glUniform2f = (PFNGLUNIFORM2FPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2f");
- glUniform3f = (PFNGLUNIFORM3FPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3f");
- glUniform4f = (PFNGLUNIFORM4FPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4f");
- glUniform1i = (PFNGLUNIFORM1IPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1i");
- glUniform2i = (PFNGLUNIFORM2IPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2i");
- glUniform3i = (PFNGLUNIFORM3IPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3i");
- glUniform4i = (PFNGLUNIFORM4IPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4i");
- glUniform1fv = (PFNGLUNIFORM1FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1fv");
- glUniform2fv = (PFNGLUNIFORM2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2fv");
- glUniform3fv = (PFNGLUNIFORM3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3fv");
- glUniform4fv = (PFNGLUNIFORM4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4fv");
- glUniform1iv = (PFNGLUNIFORM1IVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1iv");
- glUniform2iv = (PFNGLUNIFORM2IVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2iv");
- glUniform3iv = (PFNGLUNIFORM3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3iv");
- glUniform4iv = (PFNGLUNIFORM4IVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4iv");
- glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fv");
- glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fv");
- glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fv");
- glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glValidateProgram");
- glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1d");
- glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dv");
- glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1f");
- glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fv");
- glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1s");
- glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sv");
- glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2d");
- glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dv");
- glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2f");
- glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fv");
- glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2s");
- glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sv");
- glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3d");
- glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dv");
- glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3f");
- glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fv");
- glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3s");
- glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sv");
- glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nbv");
- glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Niv");
- glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nsv");
- glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nub");
- glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nubv");
- glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nuiv");
- glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nusv");
- glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bv");
- glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4d");
- glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dv");
- glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4f");
- glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fv");
- glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4iv");
- glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4s");
- glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sv");
- glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubv");
- glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uiv");
- glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usv");
- glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointer");
+ glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)LL_GET_PROC_ADDRESS("glBlendEquationSeparate");
+ glDrawBuffers = (PFNGLDRAWBUFFERSPROC)LL_GET_PROC_ADDRESS("glDrawBuffers");
+ glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)LL_GET_PROC_ADDRESS("glStencilOpSeparate");
+ glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)LL_GET_PROC_ADDRESS("glStencilFuncSeparate");
+ glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)LL_GET_PROC_ADDRESS("glStencilMaskSeparate");
+ glAttachShader = (PFNGLATTACHSHADERPROC)LL_GET_PROC_ADDRESS("glAttachShader");
+ glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)LL_GET_PROC_ADDRESS("glBindAttribLocation");
+ glCompileShader = (PFNGLCOMPILESHADERPROC)LL_GET_PROC_ADDRESS("glCompileShader");
+ glCreateProgram = (PFNGLCREATEPROGRAMPROC)LL_GET_PROC_ADDRESS("glCreateProgram");
+ glCreateShader = (PFNGLCREATESHADERPROC)LL_GET_PROC_ADDRESS("glCreateShader");
+ glDeleteProgram = (PFNGLDELETEPROGRAMPROC)LL_GET_PROC_ADDRESS("glDeleteProgram");
+ glDeleteShader = (PFNGLDELETESHADERPROC)LL_GET_PROC_ADDRESS("glDeleteShader");
+ glDetachShader = (PFNGLDETACHSHADERPROC)LL_GET_PROC_ADDRESS("glDetachShader");
+ glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)LL_GET_PROC_ADDRESS("glDisableVertexAttribArray");
+ glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)LL_GET_PROC_ADDRESS("glEnableVertexAttribArray");
+ glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)LL_GET_PROC_ADDRESS("glGetActiveAttrib");
+ glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)LL_GET_PROC_ADDRESS("glGetActiveUniform");
+ glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)LL_GET_PROC_ADDRESS("glGetAttachedShaders");
+ glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)LL_GET_PROC_ADDRESS("glGetAttribLocation");
+ glGetProgramiv = (PFNGLGETPROGRAMIVPROC)LL_GET_PROC_ADDRESS("glGetProgramiv");
+ glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)LL_GET_PROC_ADDRESS("glGetProgramInfoLog");
+ glGetShaderiv = (PFNGLGETSHADERIVPROC)LL_GET_PROC_ADDRESS("glGetShaderiv");
+ glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)LL_GET_PROC_ADDRESS("glGetShaderInfoLog");
+ glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)LL_GET_PROC_ADDRESS("glGetShaderSource");
+ glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)LL_GET_PROC_ADDRESS("glGetUniformLocation");
+ glGetUniformfv = (PFNGLGETUNIFORMFVPROC)LL_GET_PROC_ADDRESS("glGetUniformfv");
+ glGetUniformiv = (PFNGLGETUNIFORMIVPROC)LL_GET_PROC_ADDRESS("glGetUniformiv");
+ glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)LL_GET_PROC_ADDRESS("glGetVertexAttribdv");
+ glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)LL_GET_PROC_ADDRESS("glGetVertexAttribfv");
+ glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)LL_GET_PROC_ADDRESS("glGetVertexAttribiv");
+ glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)LL_GET_PROC_ADDRESS("glGetVertexAttribPointerv");
+ glIsProgram = (PFNGLISPROGRAMPROC)LL_GET_PROC_ADDRESS("glIsProgram");
+ glIsShader = (PFNGLISSHADERPROC)LL_GET_PROC_ADDRESS("glIsShader");
+ glLinkProgram = (PFNGLLINKPROGRAMPROC)LL_GET_PROC_ADDRESS("glLinkProgram");
+ glShaderSource = (PFNGLSHADERSOURCEPROC)LL_GET_PROC_ADDRESS("glShaderSource");
+ glUseProgram = (PFNGLUSEPROGRAMPROC)LL_GET_PROC_ADDRESS("glUseProgram");
+ glUniform1f = (PFNGLUNIFORM1FPROC)LL_GET_PROC_ADDRESS("glUniform1f");
+ glUniform2f = (PFNGLUNIFORM2FPROC)LL_GET_PROC_ADDRESS("glUniform2f");
+ glUniform3f = (PFNGLUNIFORM3FPROC)LL_GET_PROC_ADDRESS("glUniform3f");
+ glUniform4f = (PFNGLUNIFORM4FPROC)LL_GET_PROC_ADDRESS("glUniform4f");
+ glUniform1i = (PFNGLUNIFORM1IPROC)LL_GET_PROC_ADDRESS("glUniform1i");
+ glUniform2i = (PFNGLUNIFORM2IPROC)LL_GET_PROC_ADDRESS("glUniform2i");
+ glUniform3i = (PFNGLUNIFORM3IPROC)LL_GET_PROC_ADDRESS("glUniform3i");
+ glUniform4i = (PFNGLUNIFORM4IPROC)LL_GET_PROC_ADDRESS("glUniform4i");
+ glUniform1fv = (PFNGLUNIFORM1FVPROC)LL_GET_PROC_ADDRESS("glUniform1fv");
+ glUniform2fv = (PFNGLUNIFORM2FVPROC)LL_GET_PROC_ADDRESS("glUniform2fv");
+ glUniform3fv = (PFNGLUNIFORM3FVPROC)LL_GET_PROC_ADDRESS("glUniform3fv");
+ glUniform4fv = (PFNGLUNIFORM4FVPROC)LL_GET_PROC_ADDRESS("glUniform4fv");
+ glUniform1iv = (PFNGLUNIFORM1IVPROC)LL_GET_PROC_ADDRESS("glUniform1iv");
+ glUniform2iv = (PFNGLUNIFORM2IVPROC)LL_GET_PROC_ADDRESS("glUniform2iv");
+ glUniform3iv = (PFNGLUNIFORM3IVPROC)LL_GET_PROC_ADDRESS("glUniform3iv");
+ glUniform4iv = (PFNGLUNIFORM4IVPROC)LL_GET_PROC_ADDRESS("glUniform4iv");
+ glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix2fv");
+ glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix3fv");
+ glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix4fv");
+ glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)LL_GET_PROC_ADDRESS("glValidateProgram");
+ glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)LL_GET_PROC_ADDRESS("glVertexAttrib1d");
+ glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib1dv");
+ glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)LL_GET_PROC_ADDRESS("glVertexAttrib1f");
+ glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib1fv");
+ glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)LL_GET_PROC_ADDRESS("glVertexAttrib1s");
+ glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib1sv");
+ glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)LL_GET_PROC_ADDRESS("glVertexAttrib2d");
+ glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib2dv");
+ glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)LL_GET_PROC_ADDRESS("glVertexAttrib2f");
+ glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib2fv");
+ glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)LL_GET_PROC_ADDRESS("glVertexAttrib2s");
+ glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib2sv");
+ glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)LL_GET_PROC_ADDRESS("glVertexAttrib3d");
+ glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib3dv");
+ glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)LL_GET_PROC_ADDRESS("glVertexAttrib3f");
+ glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib3fv");
+ glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)LL_GET_PROC_ADDRESS("glVertexAttrib3s");
+ glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib3sv");
+ glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4Nbv");
+ glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4Niv");
+ glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4Nsv");
+ glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4Nub");
+ glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4Nubv");
+ glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4Nuiv");
+ glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4Nusv");
+ glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4bv");
+ glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4d");
+ glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4dv");
+ glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4f");
+ glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4fv");
+ glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4iv");
+ glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4s");
+ glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4sv");
+ glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4ubv");
+ glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4uiv");
+ glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)LL_GET_PROC_ADDRESS("glVertexAttrib4usv");
+ glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)LL_GET_PROC_ADDRESS("glVertexAttribPointer");
// GL_VERSION_2_1
if (mGLVersion < 2.09f)
{
return;
}
- glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2x3fv");
- glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x2fv");
- glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2x4fv");
- glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4x2fv");
- glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4fv");
- glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4x3fv");
+ glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix2x3fv");
+ glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix3x2fv");
+ glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix2x4fv");
+ glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix4x2fv");
+ glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix3x4fv");
+ glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix4x3fv");
// GL_VERSION_3_0
if (mGLVersion < 2.99f)
{
return;
}
- glColorMaski = (PFNGLCOLORMASKIPROC)GLH_EXT_GET_PROC_ADDRESS("glColorMaski");
- glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBooleani_v");
- glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetIntegeri_v");
- glEnablei = (PFNGLENABLEIPROC)GLH_EXT_GET_PROC_ADDRESS("glEnablei");
- glDisablei = (PFNGLDISABLEIPROC)GLH_EXT_GET_PROC_ADDRESS("glDisablei");
- glIsEnabledi = (PFNGLISENABLEDIPROC)GLH_EXT_GET_PROC_ADDRESS("glIsEnabledi");
- glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginTransformFeedback");
- glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");
- glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange");
- glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBufferBase");
- glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
- glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTransformFeedbackVarying");
- glClampColor = (PFNGLCLAMPCOLORPROC)GLH_EXT_GET_PROC_ADDRESS("glClampColor");
- glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginConditionalRender");
- glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)GLH_EXT_GET_PROC_ADDRESS("glEndConditionalRender");
- glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer");
- glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribIiv");
- glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribIuiv");
- glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI1i");
- glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI2i");
- glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI3i");
- glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4i");
- glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI1ui");
- glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI2ui");
- glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI3ui");
- glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4ui");
- glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI1iv");
- glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI2iv");
- glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI3iv");
- glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4iv");
- glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI1uiv");
- glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI2uiv");
- glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI3uiv");
- glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4uiv");
- glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4bv");
- glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4sv");
- glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4ubv");
- glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4usv");
- glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformuiv");
- glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glBindFragDataLocation");
- glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFragDataLocation");
- glUniform1ui = (PFNGLUNIFORM1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1ui");
- glUniform2ui = (PFNGLUNIFORM2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2ui");
- glUniform3ui = (PFNGLUNIFORM3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3ui");
- glUniform4ui = (PFNGLUNIFORM4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4ui");
- glUniform1uiv = (PFNGLUNIFORM1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1uiv");
- glUniform2uiv = (PFNGLUNIFORM2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2uiv");
- glUniform3uiv = (PFNGLUNIFORM3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3uiv");
- glUniform4uiv = (PFNGLUNIFORM4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4uiv");
- glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexParameterIiv");
- glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexParameterIuiv");
- glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTexParameterIiv");
- glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTexParameterIuiv");
- glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferiv");
- glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferuiv");
- glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferfv");
- glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferfi");
- glGetStringi = (PFNGLGETSTRINGIPROC)GLH_EXT_GET_PROC_ADDRESS("glGetStringi");
- glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glIsRenderbuffer");
- glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBindRenderbuffer");
- glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteRenderbuffers");
- glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenRenderbuffers");
- glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorage");
- glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetRenderbufferParameteriv");
- glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glIsFramebuffer");
- glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBindFramebuffer");
- glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteFramebuffers");
- glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenFramebuffers");
- glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)GLH_EXT_GET_PROC_ADDRESS("glCheckFramebufferStatus");
- glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture1D");
- glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture2D");
- glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture3D");
- glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferRenderbuffer");
- glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameteriv");
- glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmap");
- glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBlitFramebuffer");
- glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageMultisample");
- glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferTextureLayer");
- glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glMapBufferRange");
- glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glFlushMappedBufferRange");
- glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)GLH_EXT_GET_PROC_ADDRESS("glBindVertexArray");
- glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteVertexArrays");
- glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenVertexArrays");
- glIsVertexArray = (PFNGLISVERTEXARRAYPROC)GLH_EXT_GET_PROC_ADDRESS("glIsVertexArray");
+ glColorMaski = (PFNGLCOLORMASKIPROC)LL_GET_PROC_ADDRESS("glColorMaski");
+ glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)LL_GET_PROC_ADDRESS("glGetBooleani_v");
+ glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)LL_GET_PROC_ADDRESS("glGetIntegeri_v");
+ glEnablei = (PFNGLENABLEIPROC)LL_GET_PROC_ADDRESS("glEnablei");
+ glDisablei = (PFNGLDISABLEIPROC)LL_GET_PROC_ADDRESS("glDisablei");
+ glIsEnabledi = (PFNGLISENABLEDIPROC)LL_GET_PROC_ADDRESS("glIsEnabledi");
+ glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)LL_GET_PROC_ADDRESS("glBeginTransformFeedback");
+ glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)LL_GET_PROC_ADDRESS("glEndTransformFeedback");
+ glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)LL_GET_PROC_ADDRESS("glBindBufferRange");
+ glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)LL_GET_PROC_ADDRESS("glBindBufferBase");
+ glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)LL_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
+ glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)LL_GET_PROC_ADDRESS("glGetTransformFeedbackVarying");
+ glClampColor = (PFNGLCLAMPCOLORPROC)LL_GET_PROC_ADDRESS("glClampColor");
+ glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)LL_GET_PROC_ADDRESS("glBeginConditionalRender");
+ glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)LL_GET_PROC_ADDRESS("glEndConditionalRender");
+ glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)LL_GET_PROC_ADDRESS("glVertexAttribIPointer");
+ glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)LL_GET_PROC_ADDRESS("glGetVertexAttribIiv");
+ glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)LL_GET_PROC_ADDRESS("glGetVertexAttribIuiv");
+ glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)LL_GET_PROC_ADDRESS("glVertexAttribI1i");
+ glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)LL_GET_PROC_ADDRESS("glVertexAttribI2i");
+ glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)LL_GET_PROC_ADDRESS("glVertexAttribI3i");
+ glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)LL_GET_PROC_ADDRESS("glVertexAttribI4i");
+ glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)LL_GET_PROC_ADDRESS("glVertexAttribI1ui");
+ glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)LL_GET_PROC_ADDRESS("glVertexAttribI2ui");
+ glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)LL_GET_PROC_ADDRESS("glVertexAttribI3ui");
+ glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)LL_GET_PROC_ADDRESS("glVertexAttribI4ui");
+ glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI1iv");
+ glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI2iv");
+ glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI3iv");
+ glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI4iv");
+ glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI1uiv");
+ glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI2uiv");
+ glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI3uiv");
+ glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI4uiv");
+ glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI4bv");
+ glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI4sv");
+ glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI4ubv");
+ glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)LL_GET_PROC_ADDRESS("glVertexAttribI4usv");
+ glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)LL_GET_PROC_ADDRESS("glGetUniformuiv");
+ glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)LL_GET_PROC_ADDRESS("glBindFragDataLocation");
+ glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)LL_GET_PROC_ADDRESS("glGetFragDataLocation");
+ glUniform1ui = (PFNGLUNIFORM1UIPROC)LL_GET_PROC_ADDRESS("glUniform1ui");
+ glUniform2ui = (PFNGLUNIFORM2UIPROC)LL_GET_PROC_ADDRESS("glUniform2ui");
+ glUniform3ui = (PFNGLUNIFORM3UIPROC)LL_GET_PROC_ADDRESS("glUniform3ui");
+ glUniform4ui = (PFNGLUNIFORM4UIPROC)LL_GET_PROC_ADDRESS("glUniform4ui");
+ glUniform1uiv = (PFNGLUNIFORM1UIVPROC)LL_GET_PROC_ADDRESS("glUniform1uiv");
+ glUniform2uiv = (PFNGLUNIFORM2UIVPROC)LL_GET_PROC_ADDRESS("glUniform2uiv");
+ glUniform3uiv = (PFNGLUNIFORM3UIVPROC)LL_GET_PROC_ADDRESS("glUniform3uiv");
+ glUniform4uiv = (PFNGLUNIFORM4UIVPROC)LL_GET_PROC_ADDRESS("glUniform4uiv");
+ glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)LL_GET_PROC_ADDRESS("glTexParameterIiv");
+ glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)LL_GET_PROC_ADDRESS("glTexParameterIuiv");
+ glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)LL_GET_PROC_ADDRESS("glGetTexParameterIiv");
+ glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)LL_GET_PROC_ADDRESS("glGetTexParameterIuiv");
+ glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)LL_GET_PROC_ADDRESS("glClearBufferiv");
+ glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)LL_GET_PROC_ADDRESS("glClearBufferuiv");
+ glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)LL_GET_PROC_ADDRESS("glClearBufferfv");
+ glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)LL_GET_PROC_ADDRESS("glClearBufferfi");
+ glGetStringi = (PFNGLGETSTRINGIPROC)LL_GET_PROC_ADDRESS("glGetStringi");
+ glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)LL_GET_PROC_ADDRESS("glIsRenderbuffer");
+ glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)LL_GET_PROC_ADDRESS("glBindRenderbuffer");
+ glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)LL_GET_PROC_ADDRESS("glDeleteRenderbuffers");
+ glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)LL_GET_PROC_ADDRESS("glGenRenderbuffers");
+ glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)LL_GET_PROC_ADDRESS("glRenderbufferStorage");
+ glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetRenderbufferParameteriv");
+ glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)LL_GET_PROC_ADDRESS("glIsFramebuffer");
+ glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)LL_GET_PROC_ADDRESS("glBindFramebuffer");
+ glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)LL_GET_PROC_ADDRESS("glDeleteFramebuffers");
+ glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)LL_GET_PROC_ADDRESS("glGenFramebuffers");
+ glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)LL_GET_PROC_ADDRESS("glCheckFramebufferStatus");
+ glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)LL_GET_PROC_ADDRESS("glFramebufferTexture1D");
+ glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)LL_GET_PROC_ADDRESS("glFramebufferTexture2D");
+ glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)LL_GET_PROC_ADDRESS("glFramebufferTexture3D");
+ glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)LL_GET_PROC_ADDRESS("glFramebufferRenderbuffer");
+ glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameteriv");
+ glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)LL_GET_PROC_ADDRESS("glGenerateMipmap");
+ glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)LL_GET_PROC_ADDRESS("glBlitFramebuffer");
+ glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)LL_GET_PROC_ADDRESS("glRenderbufferStorageMultisample");
+ glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)LL_GET_PROC_ADDRESS("glFramebufferTextureLayer");
+ glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)LL_GET_PROC_ADDRESS("glMapBufferRange");
+ glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)LL_GET_PROC_ADDRESS("glFlushMappedBufferRange");
+ glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)LL_GET_PROC_ADDRESS("glBindVertexArray");
+ glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)LL_GET_PROC_ADDRESS("glDeleteVertexArrays");
+ glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)LL_GET_PROC_ADDRESS("glGenVertexArrays");
+ glIsVertexArray = (PFNGLISVERTEXARRAYPROC)LL_GET_PROC_ADDRESS("glIsVertexArray");
// GL_VERSION_3_1
if (mGLVersion < 3.09f)
{
return;
}
- glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawArraysInstanced");
- glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsInstanced");
- glTexBuffer = (PFNGLTEXBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glTexBuffer");
- glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glPrimitiveRestartIndex");
- glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyBufferSubData");
- glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformIndices");
- glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformsiv");
- glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformName");
- glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformBlockIndex");
- glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformBlockiv");
- glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformBlockName");
- glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformBlockBinding");
+ glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)LL_GET_PROC_ADDRESS("glDrawArraysInstanced");
+ glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)LL_GET_PROC_ADDRESS("glDrawElementsInstanced");
+ glTexBuffer = (PFNGLTEXBUFFERPROC)LL_GET_PROC_ADDRESS("glTexBuffer");
+ glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)LL_GET_PROC_ADDRESS("glPrimitiveRestartIndex");
+ glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)LL_GET_PROC_ADDRESS("glCopyBufferSubData");
+ glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)LL_GET_PROC_ADDRESS("glGetUniformIndices");
+ glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)LL_GET_PROC_ADDRESS("glGetActiveUniformsiv");
+ glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)LL_GET_PROC_ADDRESS("glGetActiveUniformName");
+ glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)LL_GET_PROC_ADDRESS("glGetUniformBlockIndex");
+ glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)LL_GET_PROC_ADDRESS("glGetActiveUniformBlockiv");
+ glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)LL_GET_PROC_ADDRESS("glGetActiveUniformBlockName");
+ glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)LL_GET_PROC_ADDRESS("glUniformBlockBinding");
// GL_VERSION_3_2
if (mGLVersion < 3.19f)
{
return;
}
- glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsBaseVertex");
- glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElementsBaseVertex");
- glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsInstancedBaseVertex");
- glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawElementsBaseVertex");
- glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)GLH_EXT_GET_PROC_ADDRESS("glProvokingVertex");
- glFenceSync = (PFNGLFENCESYNCPROC)GLH_EXT_GET_PROC_ADDRESS("glFenceSync");
- glIsSync = (PFNGLISSYNCPROC)GLH_EXT_GET_PROC_ADDRESS("glIsSync");
- glDeleteSync = (PFNGLDELETESYNCPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteSync");
- glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)GLH_EXT_GET_PROC_ADDRESS("glClientWaitSync");
- glWaitSync = (PFNGLWAITSYNCPROC)GLH_EXT_GET_PROC_ADDRESS("glWaitSync");
- glGetInteger64v = (PFNGLGETINTEGER64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetInteger64v");
- glGetSynciv = (PFNGLGETSYNCIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSynciv");
- glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetInteger64i_v");
- glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferParameteri64v");
- glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture");
- glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTexImage2DMultisample");
- glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample");
- glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
- glSampleMaski = (PFNGLSAMPLEMASKIPROC)GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
+ glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)LL_GET_PROC_ADDRESS("glDrawElementsBaseVertex");
+ glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)LL_GET_PROC_ADDRESS("glDrawRangeElementsBaseVertex");
+ glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)LL_GET_PROC_ADDRESS("glDrawElementsInstancedBaseVertex");
+ glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)LL_GET_PROC_ADDRESS("glMultiDrawElementsBaseVertex");
+ glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)LL_GET_PROC_ADDRESS("glProvokingVertex");
+ glFenceSync = (PFNGLFENCESYNCPROC)LL_GET_PROC_ADDRESS("glFenceSync");
+ glIsSync = (PFNGLISSYNCPROC)LL_GET_PROC_ADDRESS("glIsSync");
+ glDeleteSync = (PFNGLDELETESYNCPROC)LL_GET_PROC_ADDRESS("glDeleteSync");
+ glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)LL_GET_PROC_ADDRESS("glClientWaitSync");
+ glWaitSync = (PFNGLWAITSYNCPROC)LL_GET_PROC_ADDRESS("glWaitSync");
+ glGetInteger64v = (PFNGLGETINTEGER64VPROC)LL_GET_PROC_ADDRESS("glGetInteger64v");
+ glGetSynciv = (PFNGLGETSYNCIVPROC)LL_GET_PROC_ADDRESS("glGetSynciv");
+ glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)LL_GET_PROC_ADDRESS("glGetInteger64i_v");
+ glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)LL_GET_PROC_ADDRESS("glGetBufferParameteri64v");
+ glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)LL_GET_PROC_ADDRESS("glFramebufferTexture");
+ glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)LL_GET_PROC_ADDRESS("glTexImage2DMultisample");
+ glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)LL_GET_PROC_ADDRESS("glTexImage3DMultisample");
+ glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)LL_GET_PROC_ADDRESS("glGetMultisamplefv");
+ glSampleMaski = (PFNGLSAMPLEMASKIPROC)LL_GET_PROC_ADDRESS("glSampleMaski");
// GL_VERSION_3_3
if (mGLVersion < 3.29f)
{
return;
}
- glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)GLH_EXT_GET_PROC_ADDRESS("glBindFragDataLocationIndexed");
- glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFragDataIndex");
- glGenSamplers = (PFNGLGENSAMPLERSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenSamplers");
- glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteSamplers");
- glIsSampler = (PFNGLISSAMPLERPROC)GLH_EXT_GET_PROC_ADDRESS("glIsSampler");
- glBindSampler = (PFNGLBINDSAMPLERPROC)GLH_EXT_GET_PROC_ADDRESS("glBindSampler");
- glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameteri");
- glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameteriv");
- glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameterf");
- glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameterfv");
- glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameterIiv");
- glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameterIuiv");
- glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSamplerParameteriv");
- glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSamplerParameterIiv");
- glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSamplerParameterfv");
- glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSamplerParameterIuiv");
- glQueryCounter = (PFNGLQUERYCOUNTERPROC)GLH_EXT_GET_PROC_ADDRESS("glQueryCounter");
- glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjecti64v");
- glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectui64v");
- glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribDivisor");
- glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP1ui");
- glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP1uiv");
- glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP2ui");
- glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP2uiv");
- glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP3ui");
- glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP3uiv");
- glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP4ui");
- glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP4uiv");
- glVertexP2ui = (PFNGLVERTEXP2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP2ui");
- glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP2uiv");
- glVertexP3ui = (PFNGLVERTEXP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP3ui");
- glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP3uiv");
- glVertexP4ui = (PFNGLVERTEXP4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP4ui");
- glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP4uiv");
- glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP1ui");
- glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP1uiv");
- glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP2ui");
- glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP2uiv");
- glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP3ui");
- glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP3uiv");
- glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP4ui");
- glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP4uiv");
- glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP1ui");
- glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP1uiv");
- glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP2ui");
- glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP2uiv");
- glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP3ui");
- glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP3uiv");
- glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP4ui");
- glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP4uiv");
- glNormalP3ui = (PFNGLNORMALP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glNormalP3ui");
- glNormalP3uiv = (PFNGLNORMALP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glNormalP3uiv");
- glColorP3ui = (PFNGLCOLORP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glColorP3ui");
- glColorP3uiv = (PFNGLCOLORP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glColorP3uiv");
- glColorP4ui = (PFNGLCOLORP4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glColorP4ui");
- glColorP4uiv = (PFNGLCOLORP4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glColorP4uiv");
- glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColorP3ui");
- glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColorP3uiv");
+ glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)LL_GET_PROC_ADDRESS("glBindFragDataLocationIndexed");
+ glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)LL_GET_PROC_ADDRESS("glGetFragDataIndex");
+ glGenSamplers = (PFNGLGENSAMPLERSPROC)LL_GET_PROC_ADDRESS("glGenSamplers");
+ glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)LL_GET_PROC_ADDRESS("glDeleteSamplers");
+ glIsSampler = (PFNGLISSAMPLERPROC)LL_GET_PROC_ADDRESS("glIsSampler");
+ glBindSampler = (PFNGLBINDSAMPLERPROC)LL_GET_PROC_ADDRESS("glBindSampler");
+ glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)LL_GET_PROC_ADDRESS("glSamplerParameteri");
+ glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glSamplerParameteriv");
+ glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)LL_GET_PROC_ADDRESS("glSamplerParameterf");
+ glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)LL_GET_PROC_ADDRESS("glSamplerParameterfv");
+ glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)LL_GET_PROC_ADDRESS("glSamplerParameterIiv");
+ glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)LL_GET_PROC_ADDRESS("glSamplerParameterIuiv");
+ glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetSamplerParameteriv");
+ glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)LL_GET_PROC_ADDRESS("glGetSamplerParameterIiv");
+ glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)LL_GET_PROC_ADDRESS("glGetSamplerParameterfv");
+ glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)LL_GET_PROC_ADDRESS("glGetSamplerParameterIuiv");
+ glQueryCounter = (PFNGLQUERYCOUNTERPROC)LL_GET_PROC_ADDRESS("glQueryCounter");
+ glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)LL_GET_PROC_ADDRESS("glGetQueryObjecti64v");
+ glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)LL_GET_PROC_ADDRESS("glGetQueryObjectui64v");
+ glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)LL_GET_PROC_ADDRESS("glVertexAttribDivisor");
+ glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)LL_GET_PROC_ADDRESS("glVertexAttribP1ui");
+ glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)LL_GET_PROC_ADDRESS("glVertexAttribP1uiv");
+ glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)LL_GET_PROC_ADDRESS("glVertexAttribP2ui");
+ glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)LL_GET_PROC_ADDRESS("glVertexAttribP2uiv");
+ glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)LL_GET_PROC_ADDRESS("glVertexAttribP3ui");
+ glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)LL_GET_PROC_ADDRESS("glVertexAttribP3uiv");
+ glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)LL_GET_PROC_ADDRESS("glVertexAttribP4ui");
+ glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)LL_GET_PROC_ADDRESS("glVertexAttribP4uiv");
// GL_VERSION_4_0
if (mGLVersion < 3.99f)
{
return;
}
- glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC)GLH_EXT_GET_PROC_ADDRESS("glMinSampleShading");
- glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendEquationi");
- glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendEquationSeparatei");
- glBlendFunci = (PFNGLBLENDFUNCIPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendFunci");
- glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparatei");
- glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawArraysIndirect");
- glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsIndirect");
- glUniform1d = (PFNGLUNIFORM1DPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1d");
- glUniform2d = (PFNGLUNIFORM2DPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2d");
- glUniform3d = (PFNGLUNIFORM3DPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3d");
- glUniform4d = (PFNGLUNIFORM4DPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4d");
- glUniform1dv = (PFNGLUNIFORM1DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1dv");
- glUniform2dv = (PFNGLUNIFORM2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2dv");
- glUniform3dv = (PFNGLUNIFORM3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3dv");
- glUniform4dv = (PFNGLUNIFORM4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4dv");
- glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2dv");
- glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3dv");
- glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4dv");
- glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2x3dv");
- glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2x4dv");
- glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x2dv");
- glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4dv");
- glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4x2dv");
- glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4x3dv");
- glGetUniformdv = (PFNGLGETUNIFORMDVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformdv");
- glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSubroutineUniformLocation");
- glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSubroutineIndex");
- glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveSubroutineUniformiv");
- glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveSubroutineUniformName");
- glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveSubroutineName");
- glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformSubroutinesuiv");
- glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformSubroutineuiv");
- glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramStageiv");
- glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glPatchParameteri");
- glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glPatchParameterfv");
- glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glBindTransformFeedback");
- glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteTransformFeedbacks");
- glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenTransformFeedbacks");
- glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glIsTransformFeedback");
- glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glPauseTransformFeedback");
- glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glResumeTransformFeedback");
- glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawTransformFeedback");
- glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawTransformFeedbackStream");
- glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginQueryIndexed");
- glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC)GLH_EXT_GET_PROC_ADDRESS("glEndQueryIndexed");
- glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryIndexediv");
+ glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC)LL_GET_PROC_ADDRESS("glMinSampleShading");
+ glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)LL_GET_PROC_ADDRESS("glBlendEquationi");
+ glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)LL_GET_PROC_ADDRESS("glBlendEquationSeparatei");
+ glBlendFunci = (PFNGLBLENDFUNCIPROC)LL_GET_PROC_ADDRESS("glBlendFunci");
+ glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)LL_GET_PROC_ADDRESS("glBlendFuncSeparatei");
+ glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)LL_GET_PROC_ADDRESS("glDrawArraysIndirect");
+ glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)LL_GET_PROC_ADDRESS("glDrawElementsIndirect");
+ glUniform1d = (PFNGLUNIFORM1DPROC)LL_GET_PROC_ADDRESS("glUniform1d");
+ glUniform2d = (PFNGLUNIFORM2DPROC)LL_GET_PROC_ADDRESS("glUniform2d");
+ glUniform3d = (PFNGLUNIFORM3DPROC)LL_GET_PROC_ADDRESS("glUniform3d");
+ glUniform4d = (PFNGLUNIFORM4DPROC)LL_GET_PROC_ADDRESS("glUniform4d");
+ glUniform1dv = (PFNGLUNIFORM1DVPROC)LL_GET_PROC_ADDRESS("glUniform1dv");
+ glUniform2dv = (PFNGLUNIFORM2DVPROC)LL_GET_PROC_ADDRESS("glUniform2dv");
+ glUniform3dv = (PFNGLUNIFORM3DVPROC)LL_GET_PROC_ADDRESS("glUniform3dv");
+ glUniform4dv = (PFNGLUNIFORM4DVPROC)LL_GET_PROC_ADDRESS("glUniform4dv");
+ glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix2dv");
+ glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix3dv");
+ glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix4dv");
+ glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix2x3dv");
+ glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix2x4dv");
+ glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix3x2dv");
+ glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix3x4dv");
+ glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix4x2dv");
+ glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC)LL_GET_PROC_ADDRESS("glUniformMatrix4x3dv");
+ glGetUniformdv = (PFNGLGETUNIFORMDVPROC)LL_GET_PROC_ADDRESS("glGetUniformdv");
+ glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)LL_GET_PROC_ADDRESS("glGetSubroutineUniformLocation");
+ glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC)LL_GET_PROC_ADDRESS("glGetSubroutineIndex");
+ glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)LL_GET_PROC_ADDRESS("glGetActiveSubroutineUniformiv");
+ glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)LL_GET_PROC_ADDRESS("glGetActiveSubroutineUniformName");
+ glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC)LL_GET_PROC_ADDRESS("glGetActiveSubroutineName");
+ glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC)LL_GET_PROC_ADDRESS("glUniformSubroutinesuiv");
+ glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC)LL_GET_PROC_ADDRESS("glGetUniformSubroutineuiv");
+ glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC)LL_GET_PROC_ADDRESS("glGetProgramStageiv");
+ glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)LL_GET_PROC_ADDRESS("glPatchParameteri");
+ glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC)LL_GET_PROC_ADDRESS("glPatchParameterfv");
+ glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)LL_GET_PROC_ADDRESS("glBindTransformFeedback");
+ glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC)LL_GET_PROC_ADDRESS("glDeleteTransformFeedbacks");
+ glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)LL_GET_PROC_ADDRESS("glGenTransformFeedbacks");
+ glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC)LL_GET_PROC_ADDRESS("glIsTransformFeedback");
+ glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC)LL_GET_PROC_ADDRESS("glPauseTransformFeedback");
+ glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC)LL_GET_PROC_ADDRESS("glResumeTransformFeedback");
+ glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)LL_GET_PROC_ADDRESS("glDrawTransformFeedback");
+ glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)LL_GET_PROC_ADDRESS("glDrawTransformFeedbackStream");
+ glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC)LL_GET_PROC_ADDRESS("glBeginQueryIndexed");
+ glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC)LL_GET_PROC_ADDRESS("glEndQueryIndexed");
+ glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC)LL_GET_PROC_ADDRESS("glGetQueryIndexediv");
// GL_VERSION_4_1
if (mGLVersion < 4.09f)
{
return;
}
- glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)GLH_EXT_GET_PROC_ADDRESS("glReleaseShaderCompiler");
- glShaderBinary = (PFNGLSHADERBINARYPROC)GLH_EXT_GET_PROC_ADDRESS("glShaderBinary");
- glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glGetShaderPrecisionFormat");
- glDepthRangef = (PFNGLDEPTHRANGEFPROC)GLH_EXT_GET_PROC_ADDRESS("glDepthRangef");
- glClearDepthf = (PFNGLCLEARDEPTHFPROC)GLH_EXT_GET_PROC_ADDRESS("glClearDepthf");
- glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramBinary");
- glProgramBinary = (PFNGLPROGRAMBINARYPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramBinary");
- glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramParameteri");
- glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC)GLH_EXT_GET_PROC_ADDRESS("glUseProgramStages");
- glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glActiveShaderProgram");
- glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateShaderProgramv");
- glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC)GLH_EXT_GET_PROC_ADDRESS("glBindProgramPipeline");
- glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramPipelines");
- glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC)GLH_EXT_GET_PROC_ADDRESS("glGenProgramPipelines");
- glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC)GLH_EXT_GET_PROC_ADDRESS("glIsProgramPipeline");
- glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramPipelineiv");
- glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1i");
- glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1iv");
- glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1f");
- glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1fv");
- glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1d");
- glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1dv");
- glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1ui");
- glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1uiv");
- glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2i");
- glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2iv");
- glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2f");
- glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2fv");
- glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2d");
- glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2dv");
- glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2ui");
- glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2uiv");
- glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3i");
- glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3iv");
- glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3f");
- glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3fv");
- glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3d");
- glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3dv");
- glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3ui");
- glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3uiv");
- glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4i");
- glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4iv");
- glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4f");
- glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4fv");
- glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4d");
- glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4dv");
- glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4ui");
- glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4uiv");
- glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2fv");
- glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3fv");
- glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4fv");
- glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2dv");
- glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3dv");
- glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4dv");
- glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2x3fv");
- glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3x2fv");
- glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2x4fv");
- glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4x2fv");
- glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3x4fv");
- glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4x3fv");
- glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2x3dv");
- glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3x2dv");
- glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2x4dv");
- glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4x2dv");
- glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3x4dv");
- glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4x3dv");
- glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC)GLH_EXT_GET_PROC_ADDRESS("glValidateProgramPipeline");
- glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramPipelineInfoLog");
- glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL1d");
- glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL2d");
- glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL3d");
- glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL4d");
- glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL1dv");
- glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL2dv");
- glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL3dv");
- glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL4dv");
- glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribLPointer");
- glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribLdv");
- glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)GLH_EXT_GET_PROC_ADDRESS("glViewportArrayv");
- glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)GLH_EXT_GET_PROC_ADDRESS("glViewportIndexedf");
- glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC)GLH_EXT_GET_PROC_ADDRESS("glViewportIndexedfv");
- glScissorArrayv = (PFNGLSCISSORARRAYVPROC)GLH_EXT_GET_PROC_ADDRESS("glScissorArrayv");
- glScissorIndexed = (PFNGLSCISSORINDEXEDPROC)GLH_EXT_GET_PROC_ADDRESS("glScissorIndexed");
- glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC)GLH_EXT_GET_PROC_ADDRESS("glScissorIndexedv");
- glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)GLH_EXT_GET_PROC_ADDRESS("glDepthRangeArrayv");
- glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC)GLH_EXT_GET_PROC_ADDRESS("glDepthRangeIndexed");
- glGetFloati_v = (PFNGLGETFLOATI_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFloati_v");
- glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetDoublei_v");
+ glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)LL_GET_PROC_ADDRESS("glReleaseShaderCompiler");
+ glShaderBinary = (PFNGLSHADERBINARYPROC)LL_GET_PROC_ADDRESS("glShaderBinary");
+ glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)LL_GET_PROC_ADDRESS("glGetShaderPrecisionFormat");
+ glDepthRangef = (PFNGLDEPTHRANGEFPROC)LL_GET_PROC_ADDRESS("glDepthRangef");
+ glClearDepthf = (PFNGLCLEARDEPTHFPROC)LL_GET_PROC_ADDRESS("glClearDepthf");
+ glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)LL_GET_PROC_ADDRESS("glGetProgramBinary");
+ glProgramBinary = (PFNGLPROGRAMBINARYPROC)LL_GET_PROC_ADDRESS("glProgramBinary");
+ glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)LL_GET_PROC_ADDRESS("glProgramParameteri");
+ glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC)LL_GET_PROC_ADDRESS("glUseProgramStages");
+ glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC)LL_GET_PROC_ADDRESS("glActiveShaderProgram");
+ glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC)LL_GET_PROC_ADDRESS("glCreateShaderProgramv");
+ glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC)LL_GET_PROC_ADDRESS("glBindProgramPipeline");
+ glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC)LL_GET_PROC_ADDRESS("glDeleteProgramPipelines");
+ glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC)LL_GET_PROC_ADDRESS("glGenProgramPipelines");
+ glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC)LL_GET_PROC_ADDRESS("glIsProgramPipeline");
+ glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC)LL_GET_PROC_ADDRESS("glGetProgramPipelineiv");
+ glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC)LL_GET_PROC_ADDRESS("glProgramUniform1i");
+ glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC)LL_GET_PROC_ADDRESS("glProgramUniform1iv");
+ glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC)LL_GET_PROC_ADDRESS("glProgramUniform1f");
+ glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC)LL_GET_PROC_ADDRESS("glProgramUniform1fv");
+ glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC)LL_GET_PROC_ADDRESS("glProgramUniform1d");
+ glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC)LL_GET_PROC_ADDRESS("glProgramUniform1dv");
+ glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC)LL_GET_PROC_ADDRESS("glProgramUniform1ui");
+ glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC)LL_GET_PROC_ADDRESS("glProgramUniform1uiv");
+ glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC)LL_GET_PROC_ADDRESS("glProgramUniform2i");
+ glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC)LL_GET_PROC_ADDRESS("glProgramUniform2iv");
+ glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC)LL_GET_PROC_ADDRESS("glProgramUniform2f");
+ glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC)LL_GET_PROC_ADDRESS("glProgramUniform2fv");
+ glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC)LL_GET_PROC_ADDRESS("glProgramUniform2d");
+ glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC)LL_GET_PROC_ADDRESS("glProgramUniform2dv");
+ glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC)LL_GET_PROC_ADDRESS("glProgramUniform2ui");
+ glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC)LL_GET_PROC_ADDRESS("glProgramUniform2uiv");
+ glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC)LL_GET_PROC_ADDRESS("glProgramUniform3i");
+ glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC)LL_GET_PROC_ADDRESS("glProgramUniform3iv");
+ glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC)LL_GET_PROC_ADDRESS("glProgramUniform3f");
+ glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC)LL_GET_PROC_ADDRESS("glProgramUniform3fv");
+ glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC)LL_GET_PROC_ADDRESS("glProgramUniform3d");
+ glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC)LL_GET_PROC_ADDRESS("glProgramUniform3dv");
+ glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC)LL_GET_PROC_ADDRESS("glProgramUniform3ui");
+ glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC)LL_GET_PROC_ADDRESS("glProgramUniform3uiv");
+ glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC)LL_GET_PROC_ADDRESS("glProgramUniform4i");
+ glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC)LL_GET_PROC_ADDRESS("glProgramUniform4iv");
+ glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC)LL_GET_PROC_ADDRESS("glProgramUniform4f");
+ glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC)LL_GET_PROC_ADDRESS("glProgramUniform4fv");
+ glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC)LL_GET_PROC_ADDRESS("glProgramUniform4d");
+ glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC)LL_GET_PROC_ADDRESS("glProgramUniform4dv");
+ glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC)LL_GET_PROC_ADDRESS("glProgramUniform4ui");
+ glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC)LL_GET_PROC_ADDRESS("glProgramUniform4uiv");
+ glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix2fv");
+ glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix3fv");
+ glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix4fv");
+ glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix2dv");
+ glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix3dv");
+ glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix4dv");
+ glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix2x3fv");
+ glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix3x2fv");
+ glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix2x4fv");
+ glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix4x2fv");
+ glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix3x4fv");
+ glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix4x3fv");
+ glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix2x3dv");
+ glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix3x2dv");
+ glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix2x4dv");
+ glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix4x2dv");
+ glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix3x4dv");
+ glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)LL_GET_PROC_ADDRESS("glProgramUniformMatrix4x3dv");
+ glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC)LL_GET_PROC_ADDRESS("glValidateProgramPipeline");
+ glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC)LL_GET_PROC_ADDRESS("glGetProgramPipelineInfoLog");
+ glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC)LL_GET_PROC_ADDRESS("glVertexAttribL1d");
+ glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC)LL_GET_PROC_ADDRESS("glVertexAttribL2d");
+ glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC)LL_GET_PROC_ADDRESS("glVertexAttribL3d");
+ glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC)LL_GET_PROC_ADDRESS("glVertexAttribL4d");
+ glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC)LL_GET_PROC_ADDRESS("glVertexAttribL1dv");
+ glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC)LL_GET_PROC_ADDRESS("glVertexAttribL2dv");
+ glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC)LL_GET_PROC_ADDRESS("glVertexAttribL3dv");
+ glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC)LL_GET_PROC_ADDRESS("glVertexAttribL4dv");
+ glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)LL_GET_PROC_ADDRESS("glVertexAttribLPointer");
+ glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC)LL_GET_PROC_ADDRESS("glGetVertexAttribLdv");
+ glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)LL_GET_PROC_ADDRESS("glViewportArrayv");
+ glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)LL_GET_PROC_ADDRESS("glViewportIndexedf");
+ glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC)LL_GET_PROC_ADDRESS("glViewportIndexedfv");
+ glScissorArrayv = (PFNGLSCISSORARRAYVPROC)LL_GET_PROC_ADDRESS("glScissorArrayv");
+ glScissorIndexed = (PFNGLSCISSORINDEXEDPROC)LL_GET_PROC_ADDRESS("glScissorIndexed");
+ glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC)LL_GET_PROC_ADDRESS("glScissorIndexedv");
+ glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)LL_GET_PROC_ADDRESS("glDepthRangeArrayv");
+ glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC)LL_GET_PROC_ADDRESS("glDepthRangeIndexed");
+ glGetFloati_v = (PFNGLGETFLOATI_VPROC)LL_GET_PROC_ADDRESS("glGetFloati_v");
+ glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC)LL_GET_PROC_ADDRESS("glGetDoublei_v");
// GL_VERSION_4_2
if (mGLVersion < 4.19f)
{
return;
}
- glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawArraysInstancedBaseInstance");
- glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsInstancedBaseInstance");
- glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsInstancedBaseVertexBaseInstance");
- glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetInternalformativ");
- glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveAtomicCounterBufferiv");
- glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)GLH_EXT_GET_PROC_ADDRESS("glBindImageTexture");
- glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)GLH_EXT_GET_PROC_ADDRESS("glMemoryBarrier");
- glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexStorage1D");
- glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexStorage2D");
- glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexStorage3D");
- glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawTransformFeedbackInstanced");
- glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawTransformFeedbackStreamInstanced");
+ glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)LL_GET_PROC_ADDRESS("glDrawArraysInstancedBaseInstance");
+ glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)LL_GET_PROC_ADDRESS("glDrawElementsInstancedBaseInstance");
+ glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)LL_GET_PROC_ADDRESS("glDrawElementsInstancedBaseVertexBaseInstance");
+ glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)LL_GET_PROC_ADDRESS("glGetInternalformativ");
+ glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)LL_GET_PROC_ADDRESS("glGetActiveAtomicCounterBufferiv");
+ glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)LL_GET_PROC_ADDRESS("glBindImageTexture");
+ glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)LL_GET_PROC_ADDRESS("glMemoryBarrier");
+ glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)LL_GET_PROC_ADDRESS("glTexStorage1D");
+ glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)LL_GET_PROC_ADDRESS("glTexStorage2D");
+ glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)LL_GET_PROC_ADDRESS("glTexStorage3D");
+ glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)LL_GET_PROC_ADDRESS("glDrawTransformFeedbackInstanced");
+ glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)LL_GET_PROC_ADDRESS("glDrawTransformFeedbackStreamInstanced");
// GL_VERSION_4_3
if (mGLVersion < 4.29f)
{
return;
}
- glClearBufferData = (PFNGLCLEARBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferData");
- glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferSubData");
- glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)GLH_EXT_GET_PROC_ADDRESS("glDispatchCompute");
- glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC)GLH_EXT_GET_PROC_ADDRESS("glDispatchComputeIndirect");
- glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyImageSubData");
- glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferParameteri");
- glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferParameteriv");
- glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetInternalformati64v");
- glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateTexSubImage");
- glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateTexImage");
- glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateBufferSubData");
- glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateBufferData");
- glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateFramebuffer");
- glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateSubFramebuffer");
- glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawArraysIndirect");
- glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawElementsIndirect");
- glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramInterfaceiv");
- glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramResourceIndex");
- glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramResourceName");
- glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramResourceiv");
- glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramResourceLocation");
- glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramResourceLocationIndex");
- glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)GLH_EXT_GET_PROC_ADDRESS("glShaderStorageBlockBinding");
- glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glTexBufferRange");
- glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTexStorage2DMultisample");
- glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTexStorage3DMultisample");
- glTextureView = (PFNGLTEXTUREVIEWPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureView");
- glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBindVertexBuffer");
- glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribFormat");
- glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIFormat");
- glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribLFormat");
- glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribBinding");
- glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexBindingDivisor");
- glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControl");
- glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)GLH_EXT_GET_PROC_ADDRESS("glDebugMessageInsert");
- glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glDebugMessageCallback");
- glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)GLH_EXT_GET_PROC_ADDRESS("glGetDebugMessageLog");
- glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)GLH_EXT_GET_PROC_ADDRESS("glPushDebugGroup");
- glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)GLH_EXT_GET_PROC_ADDRESS("glPopDebugGroup");
- glObjectLabel = (PFNGLOBJECTLABELPROC)GLH_EXT_GET_PROC_ADDRESS("glObjectLabel");
- glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)GLH_EXT_GET_PROC_ADDRESS("glGetObjectLabel");
- glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)GLH_EXT_GET_PROC_ADDRESS("glObjectPtrLabel");
- glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)GLH_EXT_GET_PROC_ADDRESS("glGetObjectPtrLabel");
+ glClearBufferData = (PFNGLCLEARBUFFERDATAPROC)LL_GET_PROC_ADDRESS("glClearBufferData");
+ glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC)LL_GET_PROC_ADDRESS("glClearBufferSubData");
+ glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)LL_GET_PROC_ADDRESS("glDispatchCompute");
+ glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC)LL_GET_PROC_ADDRESS("glDispatchComputeIndirect");
+ glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)LL_GET_PROC_ADDRESS("glCopyImageSubData");
+ glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)LL_GET_PROC_ADDRESS("glFramebufferParameteri");
+ glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetFramebufferParameteriv");
+ glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC)LL_GET_PROC_ADDRESS("glGetInternalformati64v");
+ glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC)LL_GET_PROC_ADDRESS("glInvalidateTexSubImage");
+ glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC)LL_GET_PROC_ADDRESS("glInvalidateTexImage");
+ glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC)LL_GET_PROC_ADDRESS("glInvalidateBufferSubData");
+ glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)LL_GET_PROC_ADDRESS("glInvalidateBufferData");
+ glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC)LL_GET_PROC_ADDRESS("glInvalidateFramebuffer");
+ glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC)LL_GET_PROC_ADDRESS("glInvalidateSubFramebuffer");
+ glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC)LL_GET_PROC_ADDRESS("glMultiDrawArraysIndirect");
+ glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)LL_GET_PROC_ADDRESS("glMultiDrawElementsIndirect");
+ glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)LL_GET_PROC_ADDRESS("glGetProgramInterfaceiv");
+ glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC)LL_GET_PROC_ADDRESS("glGetProgramResourceIndex");
+ glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)LL_GET_PROC_ADDRESS("glGetProgramResourceName");
+ glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)LL_GET_PROC_ADDRESS("glGetProgramResourceiv");
+ glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)LL_GET_PROC_ADDRESS("glGetProgramResourceLocation");
+ glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)LL_GET_PROC_ADDRESS("glGetProgramResourceLocationIndex");
+ glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)LL_GET_PROC_ADDRESS("glShaderStorageBlockBinding");
+ glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)LL_GET_PROC_ADDRESS("glTexBufferRange");
+ glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC)LL_GET_PROC_ADDRESS("glTexStorage2DMultisample");
+ glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC)LL_GET_PROC_ADDRESS("glTexStorage3DMultisample");
+ glTextureView = (PFNGLTEXTUREVIEWPROC)LL_GET_PROC_ADDRESS("glTextureView");
+ glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)LL_GET_PROC_ADDRESS("glBindVertexBuffer");
+ glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)LL_GET_PROC_ADDRESS("glVertexAttribFormat");
+ glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)LL_GET_PROC_ADDRESS("glVertexAttribIFormat");
+ glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC)LL_GET_PROC_ADDRESS("glVertexAttribLFormat");
+ glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)LL_GET_PROC_ADDRESS("glVertexAttribBinding");
+ glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)LL_GET_PROC_ADDRESS("glVertexBindingDivisor");
+ glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)LL_GET_PROC_ADDRESS("glDebugMessageControl");
+ glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)LL_GET_PROC_ADDRESS("glDebugMessageInsert");
+ glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)LL_GET_PROC_ADDRESS("glDebugMessageCallback");
+ glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)LL_GET_PROC_ADDRESS("glGetDebugMessageLog");
+ glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)LL_GET_PROC_ADDRESS("glPushDebugGroup");
+ glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)LL_GET_PROC_ADDRESS("glPopDebugGroup");
+ glObjectLabel = (PFNGLOBJECTLABELPROC)LL_GET_PROC_ADDRESS("glObjectLabel");
+ glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)LL_GET_PROC_ADDRESS("glGetObjectLabel");
+ glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)LL_GET_PROC_ADDRESS("glObjectPtrLabel");
+ glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)LL_GET_PROC_ADDRESS("glGetObjectPtrLabel");
// GL_VERSION_4_4
if (mGLVersion < 4.39f)
{
return;
}
- glBufferStorage = (PFNGLBUFFERSTORAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferStorage");
- glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glClearTexImage");
- glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glClearTexSubImage");
- glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBuffersBase");
- glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBuffersRange");
- glBindTextures = (PFNGLBINDTEXTURESPROC)GLH_EXT_GET_PROC_ADDRESS("glBindTextures");
- glBindSamplers = (PFNGLBINDSAMPLERSPROC)GLH_EXT_GET_PROC_ADDRESS("glBindSamplers");
- glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)GLH_EXT_GET_PROC_ADDRESS("glBindImageTextures");
- glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glBindVertexBuffers");
+ glBufferStorage = (PFNGLBUFFERSTORAGEPROC)LL_GET_PROC_ADDRESS("glBufferStorage");
+ glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)LL_GET_PROC_ADDRESS("glClearTexImage");
+ glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC)LL_GET_PROC_ADDRESS("glClearTexSubImage");
+ glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC)LL_GET_PROC_ADDRESS("glBindBuffersBase");
+ glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC)LL_GET_PROC_ADDRESS("glBindBuffersRange");
+ glBindTextures = (PFNGLBINDTEXTURESPROC)LL_GET_PROC_ADDRESS("glBindTextures");
+ glBindSamplers = (PFNGLBINDSAMPLERSPROC)LL_GET_PROC_ADDRESS("glBindSamplers");
+ glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)LL_GET_PROC_ADDRESS("glBindImageTextures");
+ glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC)LL_GET_PROC_ADDRESS("glBindVertexBuffers");
// GL_VERSION_4_5
if (mGLVersion < 4.49f)
{
return;
}
- glClipControl = (PFNGLCLIPCONTROLPROC)GLH_EXT_GET_PROC_ADDRESS("glClipControl");
- glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateTransformFeedbacks");
- glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackBufferBase");
- glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackBufferRange");
- glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTransformFeedbackiv");
- glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTransformFeedbacki_v");
- glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTransformFeedbacki64_v");
- glCreateBuffers = (PFNGLCREATEBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateBuffers");
- glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedBufferStorage");
- glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedBufferData");
- glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedBufferSubData");
- glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyNamedBufferSubData");
- glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedBufferData");
- glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedBufferSubData");
- glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glMapNamedBuffer");
- glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glMapNamedBufferRange");
- glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glUnmapNamedBuffer");
- glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glFlushMappedNamedBufferRange");
- glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedBufferParameteriv");
- glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedBufferParameteri64v");
- glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedBufferPointerv");
- glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedBufferSubData");
- glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateFramebuffers");
- glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferRenderbuffer");
- glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferParameteri");
- glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferTexture");
- glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferTextureLayer");
- glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferDrawBuffer");
- glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferDrawBuffers");
- glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferReadBuffer");
- glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateNamedFramebufferData");
- glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateNamedFramebufferSubData");
- glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedFramebufferiv");
- glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedFramebufferuiv");
- glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedFramebufferfv");
- glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedFramebufferfi");
- glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBlitNamedFramebuffer");
- glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)GLH_EXT_GET_PROC_ADDRESS("glCheckNamedFramebufferStatus");
- glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedFramebufferParameteriv");
- glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedFramebufferAttachmentParameteriv");
- glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateRenderbuffers");
- glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedRenderbufferStorage");
- glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedRenderbufferStorageMultisample");
- glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedRenderbufferParameteriv");
- glCreateTextures = (PFNGLCREATETEXTURESPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateTextures");
- glTextureBuffer = (PFNGLTEXTUREBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureBuffer");
- glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureBufferRange");
- glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureStorage1D");
- glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureStorage2D");
- glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureStorage3D");
- glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureStorage2DMultisample");
- glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureStorage3DMultisample");
- glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureSubImage1D");
- glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureSubImage2D");
- glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureSubImage3D");
- glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTextureSubImage1D");
- glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTextureSubImage2D");
- glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTextureSubImage3D");
- glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyTextureSubImage1D");
- glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyTextureSubImage2D");
- glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyTextureSubImage3D");
- glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameterf");
- glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameterfv");
- glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameteri");
- glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameterIiv");
- glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameterIuiv");
- glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameteriv");
- glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)GLH_EXT_GET_PROC_ADDRESS("glGenerateTextureMipmap");
- glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC)GLH_EXT_GET_PROC_ADDRESS("glBindTextureUnit");
- glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureImage");
- glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCompressedTextureImage");
- glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureLevelParameterfv");
- glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureLevelParameteriv");
- glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureParameterfv");
- glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureParameterIiv");
- glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureParameterIuiv");
- glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureParameteriv");
- glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateVertexArrays");
- glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC)GLH_EXT_GET_PROC_ADDRESS("glDisableVertexArrayAttrib");
- glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC)GLH_EXT_GET_PROC_ADDRESS("glEnableVertexArrayAttrib");
- glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayElementBuffer");
- glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayVertexBuffer");
- glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayVertexBuffers");
- glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayAttribBinding");
- glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayAttribFormat");
- glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayAttribIFormat");
- glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayAttribLFormat");
- glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayBindingDivisor");
- glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexArrayiv");
- glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexArrayIndexediv");
- glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexArrayIndexed64iv");
- glCreateSamplers = (PFNGLCREATESAMPLERSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateSamplers");
- glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateProgramPipelines");
- glCreateQueries = (PFNGLCREATEQUERIESPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateQueries");
- glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryBufferObjecti64v");
- glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryBufferObjectiv");
- glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryBufferObjectui64v");
- glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryBufferObjectuiv");
- glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC)GLH_EXT_GET_PROC_ADDRESS("glMemoryBarrierByRegion");
- glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureSubImage");
- glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCompressedTextureSubImage");
- glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC)GLH_EXT_GET_PROC_ADDRESS("glGetGraphicsResetStatus");
- glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnCompressedTexImage");
- glGetnTexImage = (PFNGLGETNTEXIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnTexImage");
- glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnUniformdv");
- glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnUniformfv");
- glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnUniformiv");
- glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnUniformuiv");
- glReadnPixels = (PFNGLREADNPIXELSPROC)GLH_EXT_GET_PROC_ADDRESS("glReadnPixels");
- glGetnMapdv = (PFNGLGETNMAPDVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnMapdv");
- glGetnMapfv = (PFNGLGETNMAPFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnMapfv");
- glGetnMapiv = (PFNGLGETNMAPIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnMapiv");
- glGetnPixelMapfv = (PFNGLGETNPIXELMAPFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnPixelMapfv");
- glGetnPixelMapuiv = (PFNGLGETNPIXELMAPUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnPixelMapuiv");
- glGetnPixelMapusv = (PFNGLGETNPIXELMAPUSVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnPixelMapusv");
- glGetnPolygonStipple = (PFNGLGETNPOLYGONSTIPPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnPolygonStipple");
- glGetnColorTable = (PFNGLGETNCOLORTABLEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnColorTable");
- glGetnConvolutionFilter = (PFNGLGETNCONVOLUTIONFILTERPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnConvolutionFilter");
- glGetnSeparableFilter = (PFNGLGETNSEPARABLEFILTERPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnSeparableFilter");
- glGetnHistogram = (PFNGLGETNHISTOGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnHistogram");
- glGetnMinmax = (PFNGLGETNMINMAXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnMinmax");
- glTextureBarrier = (PFNGLTEXTUREBARRIERPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureBarrier");
+ glClipControl = (PFNGLCLIPCONTROLPROC)LL_GET_PROC_ADDRESS("glClipControl");
+ glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC)LL_GET_PROC_ADDRESS("glCreateTransformFeedbacks");
+ glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)LL_GET_PROC_ADDRESS("glTransformFeedbackBufferBase");
+ glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)LL_GET_PROC_ADDRESS("glTransformFeedbackBufferRange");
+ glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC)LL_GET_PROC_ADDRESS("glGetTransformFeedbackiv");
+ glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC)LL_GET_PROC_ADDRESS("glGetTransformFeedbacki_v");
+ glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC)LL_GET_PROC_ADDRESS("glGetTransformFeedbacki64_v");
+ glCreateBuffers = (PFNGLCREATEBUFFERSPROC)LL_GET_PROC_ADDRESS("glCreateBuffers");
+ glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC)LL_GET_PROC_ADDRESS("glNamedBufferStorage");
+ glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC)LL_GET_PROC_ADDRESS("glNamedBufferData");
+ glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC)LL_GET_PROC_ADDRESS("glNamedBufferSubData");
+ glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC)LL_GET_PROC_ADDRESS("glCopyNamedBufferSubData");
+ glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC)LL_GET_PROC_ADDRESS("glClearNamedBufferData");
+ glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC)LL_GET_PROC_ADDRESS("glClearNamedBufferSubData");
+ glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC)LL_GET_PROC_ADDRESS("glMapNamedBuffer");
+ glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC)LL_GET_PROC_ADDRESS("glMapNamedBufferRange");
+ glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC)LL_GET_PROC_ADDRESS("glUnmapNamedBuffer");
+ glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)LL_GET_PROC_ADDRESS("glFlushMappedNamedBufferRange");
+ glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetNamedBufferParameteriv");
+ glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)LL_GET_PROC_ADDRESS("glGetNamedBufferParameteri64v");
+ glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC)LL_GET_PROC_ADDRESS("glGetNamedBufferPointerv");
+ glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC)LL_GET_PROC_ADDRESS("glGetNamedBufferSubData");
+ glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC)LL_GET_PROC_ADDRESS("glCreateFramebuffers");
+ glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)LL_GET_PROC_ADDRESS("glNamedFramebufferRenderbuffer");
+ glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)LL_GET_PROC_ADDRESS("glNamedFramebufferParameteri");
+ glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)LL_GET_PROC_ADDRESS("glNamedFramebufferTexture");
+ glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)LL_GET_PROC_ADDRESS("glNamedFramebufferTextureLayer");
+ glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)LL_GET_PROC_ADDRESS("glNamedFramebufferDrawBuffer");
+ glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)LL_GET_PROC_ADDRESS("glNamedFramebufferDrawBuffers");
+ glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)LL_GET_PROC_ADDRESS("glNamedFramebufferReadBuffer");
+ glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)LL_GET_PROC_ADDRESS("glInvalidateNamedFramebufferData");
+ glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)LL_GET_PROC_ADDRESS("glInvalidateNamedFramebufferSubData");
+ glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)LL_GET_PROC_ADDRESS("glClearNamedFramebufferiv");
+ glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)LL_GET_PROC_ADDRESS("glClearNamedFramebufferuiv");
+ glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)LL_GET_PROC_ADDRESS("glClearNamedFramebufferfv");
+ glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)LL_GET_PROC_ADDRESS("glClearNamedFramebufferfi");
+ glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC)LL_GET_PROC_ADDRESS("glBlitNamedFramebuffer");
+ glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)LL_GET_PROC_ADDRESS("glCheckNamedFramebufferStatus");
+ glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetNamedFramebufferParameteriv");
+ glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetNamedFramebufferAttachmentParameteriv");
+ glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC)LL_GET_PROC_ADDRESS("glCreateRenderbuffers");
+ glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC)LL_GET_PROC_ADDRESS("glNamedRenderbufferStorage");
+ glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)LL_GET_PROC_ADDRESS("glNamedRenderbufferStorageMultisample");
+ glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetNamedRenderbufferParameteriv");
+ glCreateTextures = (PFNGLCREATETEXTURESPROC)LL_GET_PROC_ADDRESS("glCreateTextures");
+ glTextureBuffer = (PFNGLTEXTUREBUFFERPROC)LL_GET_PROC_ADDRESS("glTextureBuffer");
+ glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC)LL_GET_PROC_ADDRESS("glTextureBufferRange");
+ glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC)LL_GET_PROC_ADDRESS("glTextureStorage1D");
+ glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC)LL_GET_PROC_ADDRESS("glTextureStorage2D");
+ glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC)LL_GET_PROC_ADDRESS("glTextureStorage3D");
+ glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)LL_GET_PROC_ADDRESS("glTextureStorage2DMultisample");
+ glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)LL_GET_PROC_ADDRESS("glTextureStorage3DMultisample");
+ glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC)LL_GET_PROC_ADDRESS("glTextureSubImage1D");
+ glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC)LL_GET_PROC_ADDRESS("glTextureSubImage2D");
+ glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC)LL_GET_PROC_ADDRESS("glTextureSubImage3D");
+ glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)LL_GET_PROC_ADDRESS("glCompressedTextureSubImage1D");
+ glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)LL_GET_PROC_ADDRESS("glCompressedTextureSubImage2D");
+ glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)LL_GET_PROC_ADDRESS("glCompressedTextureSubImage3D");
+ glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC)LL_GET_PROC_ADDRESS("glCopyTextureSubImage1D");
+ glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC)LL_GET_PROC_ADDRESS("glCopyTextureSubImage2D");
+ glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC)LL_GET_PROC_ADDRESS("glCopyTextureSubImage3D");
+ glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC)LL_GET_PROC_ADDRESS("glTextureParameterf");
+ glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC)LL_GET_PROC_ADDRESS("glTextureParameterfv");
+ glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC)LL_GET_PROC_ADDRESS("glTextureParameteri");
+ glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC)LL_GET_PROC_ADDRESS("glTextureParameterIiv");
+ glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC)LL_GET_PROC_ADDRESS("glTextureParameterIuiv");
+ glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glTextureParameteriv");
+ glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)LL_GET_PROC_ADDRESS("glGenerateTextureMipmap");
+ glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC)LL_GET_PROC_ADDRESS("glBindTextureUnit");
+ glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC)LL_GET_PROC_ADDRESS("glGetTextureImage");
+ glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)LL_GET_PROC_ADDRESS("glGetCompressedTextureImage");
+ glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC)LL_GET_PROC_ADDRESS("glGetTextureLevelParameterfv");
+ glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetTextureLevelParameteriv");
+ glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC)LL_GET_PROC_ADDRESS("glGetTextureParameterfv");
+ glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC)LL_GET_PROC_ADDRESS("glGetTextureParameterIiv");
+ glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC)LL_GET_PROC_ADDRESS("glGetTextureParameterIuiv");
+ glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC)LL_GET_PROC_ADDRESS("glGetTextureParameteriv");
+ glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC)LL_GET_PROC_ADDRESS("glCreateVertexArrays");
+ glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC)LL_GET_PROC_ADDRESS("glDisableVertexArrayAttrib");
+ glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC)LL_GET_PROC_ADDRESS("glEnableVertexArrayAttrib");
+ glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC)LL_GET_PROC_ADDRESS("glVertexArrayElementBuffer");
+ glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC)LL_GET_PROC_ADDRESS("glVertexArrayVertexBuffer");
+ glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC)LL_GET_PROC_ADDRESS("glVertexArrayVertexBuffers");
+ glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC)LL_GET_PROC_ADDRESS("glVertexArrayAttribBinding");
+ glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC)LL_GET_PROC_ADDRESS("glVertexArrayAttribFormat");
+ glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC)LL_GET_PROC_ADDRESS("glVertexArrayAttribIFormat");
+ glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC)LL_GET_PROC_ADDRESS("glVertexArrayAttribLFormat");
+ glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC)LL_GET_PROC_ADDRESS("glVertexArrayBindingDivisor");
+ glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC)LL_GET_PROC_ADDRESS("glGetVertexArrayiv");
+ glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC)LL_GET_PROC_ADDRESS("glGetVertexArrayIndexediv");
+ glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC)LL_GET_PROC_ADDRESS("glGetVertexArrayIndexed64iv");
+ glCreateSamplers = (PFNGLCREATESAMPLERSPROC)LL_GET_PROC_ADDRESS("glCreateSamplers");
+ glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC)LL_GET_PROC_ADDRESS("glCreateProgramPipelines");
+ glCreateQueries = (PFNGLCREATEQUERIESPROC)LL_GET_PROC_ADDRESS("glCreateQueries");
+ glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC)LL_GET_PROC_ADDRESS("glGetQueryBufferObjecti64v");
+ glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC)LL_GET_PROC_ADDRESS("glGetQueryBufferObjectiv");
+ glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC)LL_GET_PROC_ADDRESS("glGetQueryBufferObjectui64v");
+ glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC)LL_GET_PROC_ADDRESS("glGetQueryBufferObjectuiv");
+ glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC)LL_GET_PROC_ADDRESS("glMemoryBarrierByRegion");
+ glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC)LL_GET_PROC_ADDRESS("glGetTextureSubImage");
+ glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)LL_GET_PROC_ADDRESS("glGetCompressedTextureSubImage");
+ glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC)LL_GET_PROC_ADDRESS("glGetGraphicsResetStatus");
+ glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC)LL_GET_PROC_ADDRESS("glGetnCompressedTexImage");
+ glGetnTexImage = (PFNGLGETNTEXIMAGEPROC)LL_GET_PROC_ADDRESS("glGetnTexImage");
+ glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC)LL_GET_PROC_ADDRESS("glGetnUniformdv");
+ glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC)LL_GET_PROC_ADDRESS("glGetnUniformfv");
+ glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC)LL_GET_PROC_ADDRESS("glGetnUniformiv");
+ glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC)LL_GET_PROC_ADDRESS("glGetnUniformuiv");
+ glReadnPixels = (PFNGLREADNPIXELSPROC)LL_GET_PROC_ADDRESS("glReadnPixels");
+ glTextureBarrier = (PFNGLTEXTUREBARRIERPROC)LL_GET_PROC_ADDRESS("glTextureBarrier");
// GL_VERSION_4_6
if (mGLVersion < 4.59f)
{
return;
}
- glSpecializeShader = (PFNGLSPECIALIZESHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glSpecializeShader");
- glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawArraysIndirectCount");
- glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawElementsIndirectCount");
- glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC)GLH_EXT_GET_PROC_ADDRESS("glPolygonOffsetClamp");
+ glSpecializeShader = (PFNGLSPECIALIZESHADERPROC)LL_GET_PROC_ADDRESS("glSpecializeShader");
+ glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)LL_GET_PROC_ADDRESS("glMultiDrawArraysIndirectCount");
+ glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)LL_GET_PROC_ADDRESS("glMultiDrawElementsIndirectCount");
+ glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC)LL_GET_PROC_ADDRESS("glPolygonOffsetClamp");
-#endif
+#endif // LL_GL_FUNC_POINTER
}
void rotate_quat(LLQuaternion& rotation)
@@ -2267,6 +2311,39 @@ void flush_glerror()
glGetError();
}
+const std::string getGLErrorString(GLenum error)
+{
+ switch(error)
+ {
+ case GL_NO_ERROR:
+ return "No Error";
+ case GL_INVALID_ENUM:
+ return "Invalid Enum";
+ case GL_INVALID_VALUE:
+ return "Invalid Value";
+ case GL_INVALID_OPERATION:
+ return "Invalid Operation";
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ return "Invalid Framebuffer Operation";
+ case GL_OUT_OF_MEMORY:
+ return "Out of Memory";
+#ifdef GL_STACK_UNDERFLOW
+ case GL_STACK_UNDERFLOW:
+ return "Stack Underflow";
+#endif
+#ifdef GL_STACK_OVERFLOW
+ case GL_STACK_OVERFLOW:
+ return "Stack Overflow";
+#endif
+#ifdef GL_TABLE_TOO_LARGE
+ case GL_TABLE_TOO_LARGE:
+ return "Table too large";
+#endif
+ default:
+ return "UNKNOWN ERROR";
+ }
+}
+
//this function outputs gl error to the log file, does not crash the code.
void log_glerror()
{
@@ -2279,17 +2356,8 @@ void log_glerror()
error = glGetError();
while (LL_UNLIKELY(error))
{
- GLubyte const * gl_error_msg = gluErrorString(error);
- if (NULL != gl_error_msg)
- {
- LL_WARNS() << "GL Error: " << error << " GL Error String: " << gl_error_msg << LL_ENDL ;
- }
- else
- {
- // gluErrorString returns NULL for some extensions' error codes.
- // you'll probably have to grep for the number in glext.h.
- LL_WARNS() << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
- }
+ std::string gl_error_msg = getGLErrorString(error);
+ LL_WARNS() << "GL Error: 0x" << std::hex << error << std::dec << " GL Error String: " << gl_error_msg << LL_ENDL;
error = glGetError();
}
}
@@ -2303,27 +2371,12 @@ void do_assert_glerror()
if (LL_UNLIKELY(error))
{
quit = true;
- GLubyte const * gl_error_msg = gluErrorString(error);
- if (NULL != gl_error_msg)
- {
- LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL;
- LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL;
-
- if (gDebugSession)
- {
- gFailLog << "GL Error:" << gl_error_msg << std::endl;
- }
- }
- else
+ std::string gl_error_msg = getGLErrorString(error);
+ LL_WARNS("RenderState") << "GL Error: 0x" << std::hex << error << std::dec << LL_ENDL;
+ LL_WARNS("RenderState") << "GL Error String: " << gl_error_msg << LL_ENDL;
+ if (gDebugSession)
{
- // gluErrorString returns NULL for some extensions' error codes.
- // you'll probably have to grep for the number in glext.h.
- LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
-
- if (gDebugSession)
- {
- gFailLog << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << std::endl;
- }
+ gFailLog << "GL Error: 0x" << std::hex << error << std::dec << " GL Error String: " << gl_error_msg << std::endl;
}
}
@@ -2407,11 +2460,10 @@ void LLGLState::resetTextureStates()
gGL.flush();
GLint maxTextureUnits;
- glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
for (S32 j = maxTextureUnits-1; j >=0; j--)
{
gGL.getTexUnit(j)->activate();
- glClientActiveTexture(GL_TEXTURE0+j);
j == 0 ? gGL.getTexUnit(j)->enable(LLTexUnit::TT_TEXTURE) : gGL.getTexUnit(j)->disable();
}
}
@@ -2566,6 +2618,7 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
{
return;
}
+ LL_INFOS() << "GL: " << version << LL_ENDL;
version_string->assign(version);
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 24ba4d6deb..5098478c22 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -33,6 +33,8 @@
#include <boost/unordered_map.hpp>
#include <list>
+#include "llglheaders.h"
+
#include "llerror.h"
#include "v4color.h"
#include "llstring.h"
@@ -42,7 +44,6 @@
#include "llgltypes.h"
#include "llinstancetracker.h"
-#include "llglheaders.h"
#include "glm/mat4x4.hpp"
extern bool gDebugGL;
@@ -69,7 +70,9 @@ public:
bool initGL();
void shutdownGL();
- void initWGL(); // Initializes stupid WGL extensions
+ void initWGL(); // Initializes WGL extensions
+ void initGLX(); // Initializes GLX extensions
+ void initEGL(); // Initializes EGL extensions
std::string getRawGLString(); // For sending to simulator
@@ -89,6 +92,7 @@ public:
F32 mMaxAnisotropy = 0.f;
S32 mMaxUniformBlockSize = 0;
S32 mMaxVaryingVectors = 0;
+ LLVector2 mAliasedLineRange = LLVector2(1.f, 1.f);
// GL 4.x capabilities
bool mHasCubeMapArray = false;
@@ -99,6 +103,8 @@ public:
// Vendor-specific extensions
bool mHasAMDAssociations = false;
bool mHasNVXGpuMemoryInfo = false;
+ bool mHasATIMemInfo = false;
+ bool mHasGLXMESAQueryRenderer = false;
bool mIsAMD;
bool mIsNVIDIA;
@@ -140,7 +146,16 @@ public:
// In ALL CAPS
std::string mGLRenderer;
+ // GL Extension String
+ std::set<std::string> mGLExtensions;
+
+#if LL_LINUX
+ bool mIsX11 = false;
+ bool mIsWayland = false;
+#endif
+
private:
+ void reloadExtensionsString();
void initExtensions();
void initGLStates();
};
@@ -262,19 +277,6 @@ protected:
bool mIsEnabled;
};
-// New LLGLState class wrappers that don't depend on actual GL flags.
-class LLGLEnableBlending : public LLGLState
-{
-public:
- LLGLEnableBlending(bool enable);
-};
-
-class LLGLEnableAlphaReject : public LLGLState
-{
-public:
- LLGLEnableAlphaReject(bool enable);
-};
-
// Enable with functor
class LLGLEnableFunc : LLGLState
{
@@ -419,67 +421,4 @@ extern bool gHeadlessClient;
extern bool gNonInteractive;
extern bool gGLActive;
-// Deal with changing glext.h definitions for newer SDK versions, specifically
-// with MAC OSX 10.5 -> 10.6
-
-
-#ifndef GL_DEPTH_ATTACHMENT
-#define GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT
-#endif
-
-#ifndef GL_STENCIL_ATTACHMENT
-#define GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT
-#endif
-
-#ifndef GL_FRAMEBUFFER
-#define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
-#define GL_DRAW_FRAMEBUFFER GL_DRAW_FRAMEBUFFER_EXT
-#define GL_READ_FRAMEBUFFER GL_READ_FRAMEBUFFER_EXT
-#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT
-#define GL_FRAMEBUFFER_UNSUPPORTED GL_FRAMEBUFFER_UNSUPPORTED_EXT
-#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
-#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
-#define glGenFramebuffers glGenFramebuffersEXT
-#define glBindFramebuffer glBindFramebufferEXT
-#define glCheckFramebufferStatus glCheckFramebufferStatusEXT
-#define glBlitFramebuffer glBlitFramebufferEXT
-#define glDeleteFramebuffers glDeleteFramebuffersEXT
-#define glFramebufferRenderbuffer glFramebufferRenderbufferEXT
-#define glFramebufferTexture2D glFramebufferTexture2DEXT
-#endif
-
-#ifndef GL_RENDERBUFFER
-#define GL_RENDERBUFFER GL_RENDERBUFFER_EXT
-#define glGenRenderbuffers glGenRenderbuffersEXT
-#define glBindRenderbuffer glBindRenderbufferEXT
-#define glRenderbufferStorage glRenderbufferStorageEXT
-#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT
-#define glDeleteRenderbuffers glDeleteRenderbuffersEXT
-#endif
-
-#ifndef GL_COLOR_ATTACHMENT
-#define GL_COLOR_ATTACHMENT GL_COLOR_ATTACHMENT_EXT
-#endif
-
-#ifndef GL_COLOR_ATTACHMENT0
-#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
-#endif
-
-#ifndef GL_COLOR_ATTACHMENT1
-#define GL_COLOR_ATTACHMENT1 GL_COLOR_ATTACHMENT1_EXT
-#endif
-
-#ifndef GL_COLOR_ATTACHMENT2
-#define GL_COLOR_ATTACHMENT2 GL_COLOR_ATTACHMENT2_EXT
-#endif
-
-#ifndef GL_COLOR_ATTACHMENT3
-#define GL_COLOR_ATTACHMENT3 GL_COLOR_ATTACHMENT3_EXT
-#endif
-
-
-#ifndef GL_DEPTH24_STENCIL8
-#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
-#endif
-
#endif // LL_LLGL_H
diff --git a/indra/llrender/llglcommonfunc.cpp b/indra/llrender/llglcommonfunc.cpp
index 13b08de7cc..bf4d337b50 100644
--- a/indra/llrender/llglcommonfunc.cpp
+++ b/indra/llrender/llglcommonfunc.cpp
@@ -24,6 +24,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "llglheaders.h"
#include "llglcommonfunc.h"
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 3d4dc5e698..a3d63810f5 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -27,35 +27,119 @@
#ifndef LL_LLGLHEADERS_H
#define LL_LLGLHEADERS_H
-#if LL_MESA
-//----------------------------------------------------------------------------
-// MESA headers
-// quotes so we get libraries/.../GL/ version
+#if LL_WINDOWS || LL_MESA_HEADLESS || LL_SDL_WINDOW || LL_LINUX
+ //----------------------------------------------------------------------------
+ // LL_WINDOWS || LL_MESA_HEADLESS || LL_SDL_WINDOW || LL_LINUX
+
+#if LL_MESA_HEADLESS
#define GL_GLEXT_PROTOTYPES 1
-#include "GL/gl.h"
-#include "GL/glext.h"
-#include "GL/glu.h"
+#else
+#define LL_GL_FUNC_POINTER 1
+#endif
+
+ // windows gl headers depend on things like APIENTRY, so include windows.
+#include "llwin32headers.h"
-// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly
-# define __APPLE__
-# include "GL/glh_extensions.h"
-# undef __APPLE__
+// quotes so we get libraries/.../GL/ version
+#include "GL/glcorearb.h"
-#elif LL_WINDOWS
-//----------------------------------------------------------------------------
-// LL_WINDOWS
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+#include "GL/wglext.h"
+#endif
-// windows gl headers depend on things like APIENTRY, so include windows.
-#include "llwin32headers.h"
+#if LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+#define GLX_GLXEXT_LEGACY
+#define __gl_h_ 1
+#include "GL/glx.h"
+#include "GL/glxext.h"
+#endif
+
+#if LL_LINUX && LL_WAYLAND && !LL_MESA_HEADLESS
+#define EGL_EGL_PROTOTYPES 0
+#include "EGL/egl.h"
+#endif
+#elif LL_DARWIN
//----------------------------------------------------------------------------
-#include <GL/gl.h>
-#include <GL/glu.h>
+// LL_DARWIN
-// quotes so we get libraries/.../GL/ version
+#define GL_GLEXT_LEGACY 1
+#include <OpenGL/gl3.h>
+
+#define GL_EXT_separate_specular_color 1
+#define GL_GLEXT_PROTOTYPES 1
#include "GL/glext.h"
-#include "GL/glh_extensions.h"
+#endif // LL_MESA_HEADLESS / LL_SDL_WINDOW // LL_LINUX / LL_WINDOWS / LL_DARWIN
+
+// GL_NVX_gpu_memory_info constants
+#ifndef GL_NVX_gpu_memory_info
+#define GL_NVX_gpu_memory_info
+#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
+#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
+#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
+#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
+#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
+#endif
+
+// GL_ATI_meminfo constants
+#ifndef GL_ATI_meminfo
+#define GL_ATI_meminfo
+#define GL_VBO_FREE_MEMORY_ATI 0x87FB
+#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
+#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
+#endif
+
+// GL_EXT_texture_sRGB constants
+#ifndef GL_EXT_texture_sRGB
+#define GL_EXT_texture_sRGB 1
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB8_EXT 0x8C41
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
+#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
+#define GL_SLUMINANCE_EXT 0x8C46
+#define GL_SLUMINANCE8_EXT 0x8C47
+#define GL_COMPRESSED_SRGB_EXT 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
+#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#endif /* GL_EXT_texture_sRGB */
+
+// GL_ARB_vertex_buffer_object constants
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_ARB_vertex_buffer_object 1
+#define GL_STREAM_DRAW_ARB 0x88E0
+#define GL_STREAM_READ_ARB 0x88E1
+#define GL_STREAM_COPY_ARB 0x88E2
+#define GL_STATIC_DRAW_ARB 0x88E4
+#define GL_STATIC_READ_ARB 0x88E5
+#define GL_STATIC_COPY_ARB 0x88E6
+#define GL_DYNAMIC_DRAW_ARB 0x88E8
+#define GL_DYNAMIC_READ_ARB 0x88E9
+#define GL_DYNAMIC_COPY_ARB 0x88EA
+#endif
+
+// Deprecated OpenGL defines we still use
+#define GL_COLOR_INDEX 0x1900
+#define GL_ALPHA 0x1906
+#define GL_ALPHA8 0x803C
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_LUMINANCE8 0x8040
+#define GL_LUMINANCE8_ALPHA8 0x8045
+#define GL_COMPRESSED_ALPHA 0x84E9
+#define GL_COMPRESSED_LUMINANCE 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+
+#if LL_GL_FUNC_POINTER
+
+#if LL_WINDOWS
// WGL_AMD_gpu_association
extern PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD;
extern PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD;
@@ -74,6 +158,98 @@ extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
// WGL_ARB_create_context
extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
+// WGL_ARB_pixel_format
+extern PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB;
+extern PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB;
+extern PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
+
+#endif // LL_WINDOWS
+
+#if LL_LINUX && LL_X11 && !LL_MESA_HEADLESS
+// GLX_MESA_query_renderer
+extern PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC glXQueryCurrentRendererIntegerMESA;
+extern PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC glXQueryCurrentRendererStringMESA;
+extern PFNGLXQUERYRENDERERINTEGERMESAPROC glXQueryRendererIntegerMESA;
+extern PFNGLXQUERYRENDERERSTRINGMESAPROC glXQueryRendererStringMESA;
+#endif
+
+#if LL_LINUX && LL_WAYLAND &&!LL_MESA_HEADLESS
+extern PFNEGLQUERYSTRINGPROC eglQueryString;
+#endif
+
+// We get all functions via getProcAddress when using SDL
+// GL_VERSION_1_0
+extern PFNGLCULLFACEPROC glCullFace;
+extern PFNGLFRONTFACEPROC glFrontFace;
+extern PFNGLHINTPROC glHint;
+extern PFNGLLINEWIDTHPROC glLineWidth;
+extern PFNGLPOINTSIZEPROC glPointSize;
+extern PFNGLPOLYGONMODEPROC glPolygonMode;
+extern PFNGLSCISSORPROC glScissor;
+extern PFNGLTEXPARAMETERFPROC glTexParameterf;
+extern PFNGLTEXPARAMETERFVPROC glTexParameterfv;
+extern PFNGLTEXPARAMETERIPROC glTexParameteri;
+extern PFNGLTEXPARAMETERIVPROC glTexParameteriv;
+extern PFNGLTEXIMAGE1DPROC glTexImage1D;
+extern PFNGLTEXIMAGE2DPROC glTexImage2D;
+extern PFNGLDRAWBUFFERPROC glDrawBuffer;
+extern PFNGLCLEARPROC glClear;
+extern PFNGLCLEARCOLORPROC glClearColor;
+extern PFNGLCLEARSTENCILPROC glClearStencil;
+extern PFNGLCLEARDEPTHPROC glClearDepth;
+extern PFNGLSTENCILMASKPROC glStencilMask;
+extern PFNGLCOLORMASKPROC glColorMask;
+extern PFNGLDEPTHMASKPROC glDepthMask;
+extern PFNGLDISABLEPROC glDisable;
+extern PFNGLENABLEPROC glEnable;
+extern PFNGLFINISHPROC glFinish;
+extern PFNGLFLUSHPROC glFlush;
+extern PFNGLBLENDFUNCPROC glBlendFunc;
+extern PFNGLLOGICOPPROC glLogicOp;
+extern PFNGLSTENCILFUNCPROC glStencilFunc;
+extern PFNGLSTENCILOPPROC glStencilOp;
+extern PFNGLDEPTHFUNCPROC glDepthFunc;
+extern PFNGLPIXELSTOREFPROC glPixelStoref;
+extern PFNGLPIXELSTOREIPROC glPixelStorei;
+extern PFNGLREADBUFFERPROC glReadBuffer;
+extern PFNGLREADPIXELSPROC glReadPixels;
+extern PFNGLGETBOOLEANVPROC glGetBooleanv;
+extern PFNGLGETDOUBLEVPROC glGetDoublev;
+extern PFNGLGETERRORPROC glGetError;
+extern PFNGLGETFLOATVPROC glGetFloatv;
+extern PFNGLGETINTEGERVPROC glGetIntegerv;
+extern PFNGLGETSTRINGPROC glGetString;
+extern PFNGLGETTEXIMAGEPROC glGetTexImage;
+extern PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv;
+extern PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv;
+extern PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv;
+extern PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv;
+extern PFNGLISENABLEDPROC glIsEnabled;
+extern PFNGLDEPTHRANGEPROC glDepthRange;
+extern PFNGLVIEWPORTPROC glViewport;
+
+// GL_VERSION_1_1
+extern PFNGLDRAWARRAYSPROC glDrawArrays;
+extern PFNGLDRAWELEMENTSPROC glDrawElements;
+extern PFNGLGETPOINTERVPROC glGetPointerv;
+extern PFNGLPOLYGONOFFSETPROC glPolygonOffset;
+extern PFNGLCOPYTEXIMAGE1DPROC glCopyTexImage1D;
+extern PFNGLCOPYTEXIMAGE2DPROC glCopyTexImage2D;
+extern PFNGLCOPYTEXSUBIMAGE1DPROC glCopyTexSubImage1D;
+extern PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D;
+extern PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D;
+extern PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D;
+extern PFNGLBINDTEXTUREPROC glBindTexture;
+extern PFNGLDELETETEXTURESPROC glDeleteTextures;
+extern PFNGLGENTEXTURESPROC glGenTextures;
+extern PFNGLISTEXTUREPROC glIsTexture;
+
+// GL_VERSION_1_2
+extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements;
+extern PFNGLTEXIMAGE3DPROC glTexImage3D;
+extern PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D;
+extern PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D;
+
// GL_VERSION_1_3
extern PFNGLACTIVETEXTUREPROC glActiveTexture;
extern PFNGLSAMPLECOVERAGEPROC glSampleCoverage;
@@ -84,43 +260,6 @@ extern PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D;
extern PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D;
extern PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glCompressedTexSubImage1D;
extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
-extern PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture;
-extern PFNGLMULTITEXCOORD1DPROC glMultiTexCoord1d;
-extern PFNGLMULTITEXCOORD1DVPROC glMultiTexCoord1dv;
-extern PFNGLMULTITEXCOORD1FPROC glMultiTexCoord1f;
-extern PFNGLMULTITEXCOORD1FVPROC glMultiTexCoord1fv;
-extern PFNGLMULTITEXCOORD1IPROC glMultiTexCoord1i;
-extern PFNGLMULTITEXCOORD1IVPROC glMultiTexCoord1iv;
-extern PFNGLMULTITEXCOORD1SPROC glMultiTexCoord1s;
-extern PFNGLMULTITEXCOORD1SVPROC glMultiTexCoord1sv;
-extern PFNGLMULTITEXCOORD2DPROC glMultiTexCoord2d;
-extern PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv;
-extern PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f;
-extern PFNGLMULTITEXCOORD2FVPROC glMultiTexCoord2fv;
-extern PFNGLMULTITEXCOORD2IPROC glMultiTexCoord2i;
-extern PFNGLMULTITEXCOORD2IVPROC glMultiTexCoord2iv;
-extern PFNGLMULTITEXCOORD2SPROC glMultiTexCoord2s;
-extern PFNGLMULTITEXCOORD2SVPROC glMultiTexCoord2sv;
-extern PFNGLMULTITEXCOORD3DPROC glMultiTexCoord3d;
-extern PFNGLMULTITEXCOORD3DVPROC glMultiTexCoord3dv;
-extern PFNGLMULTITEXCOORD3FPROC glMultiTexCoord3f;
-extern PFNGLMULTITEXCOORD3FVPROC glMultiTexCoord3fv;
-extern PFNGLMULTITEXCOORD3IPROC glMultiTexCoord3i;
-extern PFNGLMULTITEXCOORD3IVPROC glMultiTexCoord3iv;
-extern PFNGLMULTITEXCOORD3SPROC glMultiTexCoord3s;
-extern PFNGLMULTITEXCOORD3SVPROC glMultiTexCoord3sv;
-extern PFNGLMULTITEXCOORD4DPROC glMultiTexCoord4d;
-extern PFNGLMULTITEXCOORD4DVPROC glMultiTexCoord4dv;
-extern PFNGLMULTITEXCOORD4FPROC glMultiTexCoord4f;
-extern PFNGLMULTITEXCOORD4FVPROC glMultiTexCoord4fv;
-extern PFNGLMULTITEXCOORD4IPROC glMultiTexCoord4i;
-extern PFNGLMULTITEXCOORD4IVPROC glMultiTexCoord4iv;
-extern PFNGLMULTITEXCOORD4SPROC glMultiTexCoord4s;
-extern PFNGLMULTITEXCOORD4SVPROC glMultiTexCoord4sv;
-extern PFNGLLOADTRANSPOSEMATRIXFPROC glLoadTransposeMatrixf;
-extern PFNGLLOADTRANSPOSEMATRIXDPROC glLoadTransposeMatrixd;
-extern PFNGLMULTTRANSPOSEMATRIXFPROC glMultTransposeMatrixf;
-extern PFNGLMULTTRANSPOSEMATRIXDPROC glMultTransposeMatrixd;
// GL_VERSION_1_4
extern PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
@@ -130,44 +269,6 @@ extern PFNGLPOINTPARAMETERFPROC glPointParameterf;
extern PFNGLPOINTPARAMETERFVPROC glPointParameterfv;
extern PFNGLPOINTPARAMETERIPROC glPointParameteri;
extern PFNGLPOINTPARAMETERIVPROC glPointParameteriv;
-extern PFNGLFOGCOORDFPROC glFogCoordf;
-extern PFNGLFOGCOORDFVPROC glFogCoordfv;
-extern PFNGLFOGCOORDDPROC glFogCoordd;
-extern PFNGLFOGCOORDDVPROC glFogCoorddv;
-extern PFNGLFOGCOORDPOINTERPROC glFogCoordPointer;
-extern PFNGLSECONDARYCOLOR3BPROC glSecondaryColor3b;
-extern PFNGLSECONDARYCOLOR3BVPROC glSecondaryColor3bv;
-extern PFNGLSECONDARYCOLOR3DPROC glSecondaryColor3d;
-extern PFNGLSECONDARYCOLOR3DVPROC glSecondaryColor3dv;
-extern PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f;
-extern PFNGLSECONDARYCOLOR3FVPROC glSecondaryColor3fv;
-extern PFNGLSECONDARYCOLOR3IPROC glSecondaryColor3i;
-extern PFNGLSECONDARYCOLOR3IVPROC glSecondaryColor3iv;
-extern PFNGLSECONDARYCOLOR3SPROC glSecondaryColor3s;
-extern PFNGLSECONDARYCOLOR3SVPROC glSecondaryColor3sv;
-extern PFNGLSECONDARYCOLOR3UBPROC glSecondaryColor3ub;
-extern PFNGLSECONDARYCOLOR3UBVPROC glSecondaryColor3ubv;
-extern PFNGLSECONDARYCOLOR3UIPROC glSecondaryColor3ui;
-extern PFNGLSECONDARYCOLOR3UIVPROC glSecondaryColor3uiv;
-extern PFNGLSECONDARYCOLOR3USPROC glSecondaryColor3us;
-extern PFNGLSECONDARYCOLOR3USVPROC glSecondaryColor3usv;
-extern PFNGLSECONDARYCOLORPOINTERPROC glSecondaryColorPointer;
-extern PFNGLWINDOWPOS2DPROC glWindowPos2d;
-extern PFNGLWINDOWPOS2DVPROC glWindowPos2dv;
-extern PFNGLWINDOWPOS2FPROC glWindowPos2f;
-extern PFNGLWINDOWPOS2FVPROC glWindowPos2fv;
-extern PFNGLWINDOWPOS2IPROC glWindowPos2i;
-extern PFNGLWINDOWPOS2IVPROC glWindowPos2iv;
-extern PFNGLWINDOWPOS2SPROC glWindowPos2s;
-extern PFNGLWINDOWPOS2SVPROC glWindowPos2sv;
-extern PFNGLWINDOWPOS3DPROC glWindowPos3d;
-extern PFNGLWINDOWPOS3DVPROC glWindowPos3dv;
-extern PFNGLWINDOWPOS3FPROC glWindowPos3f;
-extern PFNGLWINDOWPOS3FVPROC glWindowPos3fv;
-extern PFNGLWINDOWPOS3IPROC glWindowPos3i;
-extern PFNGLWINDOWPOS3IVPROC glWindowPos3iv;
-extern PFNGLWINDOWPOS3SPROC glWindowPos3s;
-extern PFNGLWINDOWPOS3SVPROC glWindowPos3sv;
// GL_VERSION_1_5
extern PFNGLGENQUERIESPROC glGenQueries;
@@ -443,36 +544,6 @@ extern PFNGLVERTEXATTRIBP3UIPROC glVertexAttribP3ui;
extern PFNGLVERTEXATTRIBP3UIVPROC glVertexAttribP3uiv;
extern PFNGLVERTEXATTRIBP4UIPROC glVertexAttribP4ui;
extern PFNGLVERTEXATTRIBP4UIVPROC glVertexAttribP4uiv;
-extern PFNGLVERTEXP2UIPROC glVertexP2ui;
-extern PFNGLVERTEXP2UIVPROC glVertexP2uiv;
-extern PFNGLVERTEXP3UIPROC glVertexP3ui;
-extern PFNGLVERTEXP3UIVPROC glVertexP3uiv;
-extern PFNGLVERTEXP4UIPROC glVertexP4ui;
-extern PFNGLVERTEXP4UIVPROC glVertexP4uiv;
-extern PFNGLTEXCOORDP1UIPROC glTexCoordP1ui;
-extern PFNGLTEXCOORDP1UIVPROC glTexCoordP1uiv;
-extern PFNGLTEXCOORDP2UIPROC glTexCoordP2ui;
-extern PFNGLTEXCOORDP2UIVPROC glTexCoordP2uiv;
-extern PFNGLTEXCOORDP3UIPROC glTexCoordP3ui;
-extern PFNGLTEXCOORDP3UIVPROC glTexCoordP3uiv;
-extern PFNGLTEXCOORDP4UIPROC glTexCoordP4ui;
-extern PFNGLTEXCOORDP4UIVPROC glTexCoordP4uiv;
-extern PFNGLMULTITEXCOORDP1UIPROC glMultiTexCoordP1ui;
-extern PFNGLMULTITEXCOORDP1UIVPROC glMultiTexCoordP1uiv;
-extern PFNGLMULTITEXCOORDP2UIPROC glMultiTexCoordP2ui;
-extern PFNGLMULTITEXCOORDP2UIVPROC glMultiTexCoordP2uiv;
-extern PFNGLMULTITEXCOORDP3UIPROC glMultiTexCoordP3ui;
-extern PFNGLMULTITEXCOORDP3UIVPROC glMultiTexCoordP3uiv;
-extern PFNGLMULTITEXCOORDP4UIPROC glMultiTexCoordP4ui;
-extern PFNGLMULTITEXCOORDP4UIVPROC glMultiTexCoordP4uiv;
-extern PFNGLNORMALP3UIPROC glNormalP3ui;
-extern PFNGLNORMALP3UIVPROC glNormalP3uiv;
-extern PFNGLCOLORP3UIPROC glColorP3ui;
-extern PFNGLCOLORP3UIVPROC glColorP3uiv;
-extern PFNGLCOLORP4UIPROC glColorP4ui;
-extern PFNGLCOLORP4UIVPROC glColorP4uiv;
-extern PFNGLSECONDARYCOLORP3UIPROC glSecondaryColorP3ui;
-extern PFNGLSECONDARYCOLORP3UIVPROC glSecondaryColorP3uiv;
// GL_VERSION_4_0
extern PFNGLMINSAMPLESHADINGPROC glMinSampleShading;
@@ -522,7 +593,7 @@ extern PFNGLBEGINQUERYINDEXEDPROC glBeginQueryIndexed;
extern PFNGLENDQUERYINDEXEDPROC glEndQueryIndexed;
extern PFNGLGETQUERYINDEXEDIVPROC glGetQueryIndexediv;
- // GL_VERSION_4_1
+// GL_VERSION_4_1
extern PFNGLRELEASESHADERCOMPILERPROC glReleaseShaderCompiler;
extern PFNGLSHADERBINARYPROC glShaderBinary;
extern PFNGLGETSHADERPRECISIONFORMATPROC glGetShaderPrecisionFormat;
@@ -792,18 +863,6 @@ extern PFNGLGETNUNIFORMFVPROC glGetnUniformfv;
extern PFNGLGETNUNIFORMIVPROC glGetnUniformiv;
extern PFNGLGETNUNIFORMUIVPROC glGetnUniformuiv;
extern PFNGLREADNPIXELSPROC glReadnPixels;
-extern PFNGLGETNMAPDVPROC glGetnMapdv;
-extern PFNGLGETNMAPFVPROC glGetnMapfv;
-extern PFNGLGETNMAPIVPROC glGetnMapiv;
-extern PFNGLGETNPIXELMAPFVPROC glGetnPixelMapfv;
-extern PFNGLGETNPIXELMAPUIVPROC glGetnPixelMapuiv;
-extern PFNGLGETNPIXELMAPUSVPROC glGetnPixelMapusv;
-extern PFNGLGETNPOLYGONSTIPPLEPROC glGetnPolygonStipple;
-extern PFNGLGETNCOLORTABLEPROC glGetnColorTable;
-extern PFNGLGETNCONVOLUTIONFILTERPROC glGetnConvolutionFilter;
-extern PFNGLGETNSEPARABLEFILTERPROC glGetnSeparableFilter;
-extern PFNGLGETNHISTOGRAMPROC glGetnHistogram;
-extern PFNGLGETNMINMAXPROC glGetnMinmax;
extern PFNGLTEXTUREBARRIERPROC glTextureBarrier;
// GL_VERSION_4_6
@@ -812,252 +871,6 @@ extern PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glMultiDrawArraysIndirectCount;
extern PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glMultiDrawElementsIndirectCount;
extern PFNGLPOLYGONOFFSETCLAMPPROC glPolygonOffsetClamp;
-
-#elif LL_DARWIN
-//----------------------------------------------------------------------------
-// LL_DARWIN
-
-#define GL_GLEXT_LEGACY
-#include <OpenGL/gl.h>
-#include <OpenGL/glu.h>
-
-#define GL_EXT_separate_specular_color 1
-#define GL_GLEXT_PROTOTYPES
-#include "GL/glext.h"
-
-#include "GL/glh_extensions.h"
-
-// These symbols don't exist on 10.3.9, so they have to be declared weak. Redeclaring them here fixes the problem.
-// Note that they also must not be called on 10.3.9. This should be taken care of by a runtime check for the existence of the GL extension.
-#include <AvailabilityMacros.h>
-
-//GL_EXT_blend_func_separate
-extern void glBlendFuncSeparateEXT(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) ;
-
-// GL_EXT_framebuffer_object
-extern GLboolean glIsRenderbufferEXT(GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glBindRenderbufferEXT(GLenum target, GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glDeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glGenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glRenderbufferStorageEXT(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glGetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern GLboolean glIsFramebufferEXT(GLuint framebuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glBindFramebufferEXT(GLenum target, GLuint framebuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glDeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glGenFramebuffersEXT(GLsizei n, GLuint *framebuffers) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern GLenum glCheckFramebufferStatusEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glFramebufferTexture1DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glFramebufferTexture3DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, GLenum pname, GLint *params) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-
-#ifndef GL_ARB_framebuffer_object
-#define glGenerateMipmap glGenerateMipmapEXT
-#define GL_MAX_SAMPLES 0x8D57
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//
-// Define map buffer range headers on Mac
-//
-#ifndef GL_ARB_map_buffer_range
-#define GL_MAP_READ_BIT 0x0001
-#define GL_MAP_WRITE_BIT 0x0002
-#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
-#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
-#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
-#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
-#endif
-
-//
-// Define multisample headers on Mac
-//
-#ifndef GL_ARB_texture_multisample
-#define GL_SAMPLE_POSITION 0x8E50
-#define GL_SAMPLE_MASK 0x8E51
-#define GL_SAMPLE_MASK_VALUE 0x8E52
-#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
-#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
-#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
-#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
-#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
-#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
-#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
-#define GL_TEXTURE_SAMPLES 0x9106
-#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
-#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
-#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
-#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
-#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
-#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
-#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
-#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
-#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
-#define GL_MAX_INTEGER_SAMPLES 0x9110
-#endif
-
-//
-// Define vertex buffer object headers on Mac
-//
-#ifndef GL_ARB_vertex_buffer_object
-#define GL_BUFFER_SIZE_ARB 0x8764
-#define GL_BUFFER_USAGE_ARB 0x8765
-#define GL_ARRAY_BUFFER_ARB 0x8892
-#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
-#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
-#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
-#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
-#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
-#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
-#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
-#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
-#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
-#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
-#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
-#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
-#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
-#define GL_READ_ONLY_ARB 0x88B8
-#define GL_WRITE_ONLY_ARB 0x88B9
-#define GL_READ_WRITE_ARB 0x88BA
-#define GL_BUFFER_ACCESS_ARB 0x88BB
-#define GL_BUFFER_MAPPED_ARB 0x88BC
-#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
-#define GL_STREAM_DRAW_ARB 0x88E0
-#define GL_STREAM_READ_ARB 0x88E1
-#define GL_STREAM_COPY_ARB 0x88E2
-#define GL_STATIC_DRAW_ARB 0x88E4
-#define GL_STATIC_READ_ARB 0x88E5
-#define GL_STATIC_COPY_ARB 0x88E6
-#define GL_DYNAMIC_DRAW_ARB 0x88E8
-#define GL_DYNAMIC_READ_ARB 0x88E9
-#define GL_DYNAMIC_COPY_ARB 0x88EA
-#endif
-
-
-
-#ifndef GL_ARB_vertex_buffer_object
-/* GL types for handling large vertex buffer objects */
-typedef intptr_t GLintptr;
-typedef intptr_t GLsizeiptr;
-#endif
-
-
-#ifndef GL_ARB_vertex_buffer_object
-#define GL_ARB_vertex_buffer_object 1
-#ifdef GL_GLEXT_FUNCTION_POINTERS
-typedef void (* glBindBufferARBProcPtr) (GLenum target, GLuint buffer);
-typedef void (* glDeleteBufferARBProcPtr) (GLsizei n, const GLuint *buffers);
-typedef void (* glGenBuffersARBProcPtr) (GLsizei n, GLuint *buffers);
-typedef GLboolean (* glIsBufferARBProcPtr) (GLuint buffer);
-typedef void (* glBufferDataARBProcPtr) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
-typedef void (* glBufferSubDataARBProcPtr) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
-typedef void (* glGetBufferSubDataARBProcPtr) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
-typedef GLvoid* (* glMapBufferARBProcPtr) (GLenum target, GLenum access); /* Flawfinder: ignore */
-typedef GLboolean (* glUnmapBufferARBProcPtr) (GLenum target);
-typedef void (* glGetBufferParameterivARBProcPtr) (GLenum target, GLenum pname, GLint *params);
-typedef void (* glGetBufferPointervARBProcPtr) (GLenum target, GLenum pname, GLvoid* *params);
-#else
-extern void glBindBufferARB (GLenum, GLuint);
-extern void glDeleteBuffersARB (GLsizei, const GLuint *);
-extern void glGenBuffersARB (GLsizei, GLuint *);
-extern GLboolean glIsBufferARB (GLuint);
-extern void glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum);
-extern void glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *);
-extern void glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *);
-extern GLvoid* glMapBufferARB (GLenum, GLenum);
-extern GLboolean glUnmapBufferARB (GLenum);
-extern void glGetBufferParameterivARB (GLenum, GLenum, GLint *);
-extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
-#endif /* GL_GLEXT_FUNCTION_POINTERS */
-#endif
-
-#ifndef GL_ARB_texture_rg
-#define GL_RG 0x8227
-#define GL_RG_INTEGER 0x8228
-#define GL_R8 0x8229
-#define GL_R16 0x822A
-#define GL_RG8 0x822B
-#define GL_RG16 0x822C
-#define GL_R16F 0x822D
-#define GL_R32F 0x822E
-#define GL_RG16F 0x822F
-#define GL_RG32F 0x8230
-#define GL_R8I 0x8231
-#define GL_R8UI 0x8232
-#define GL_R16I 0x8233
-#define GL_R16UI 0x8234
-#define GL_R32I 0x8235
-#define GL_R32UI 0x8236
-#define GL_RG8I 0x8237
-#define GL_RG8UI 0x8238
-#define GL_RG16I 0x8239
-#define GL_RG16UI 0x823A
-#define GL_RG32I 0x823B
-#define GL_RG32UI 0x823C
-#endif
-
-// May be needed for DARWIN...
-// #ifndef GL_ARB_compressed_tex_image
-// #define GL_ARB_compressed_tex_image 1
-// #ifdef GL_GLEXT_FUNCTION_POINTERS
-// typedef void (* glCompressedTexImage1D) (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid*);
-// typedef void (* glCompressedTexImage2D) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*);
-// typedef void (* glCompressedTexImage3D) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*);
-// typedef void (* glCompressedTexSubImage1D) (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid*);
-// typedef void (* glCompressedTexSubImage2D) (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*);
-// typedef void (* glCompressedTexSubImage3D) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*);
-// typedef void (* glGetCompressedTexImage) (GLenum, GLint, GLvoid*);
-// #else
-// extern void glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid*);
-// extern void glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*);
-// extern void glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*);
-// extern void glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid*);
-// extern void glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*);
-// extern void glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*);
-// extern void glGetCompressedTexImage (GLenum, GLint, GLvoid*);
-// #endif /* GL_GLEXT_FUNCTION_POINTERS */
-// #endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#include <OpenGL/gl.h>
-
-#endif // LL_MESA / LL_WINDOWS / LL_DARWIN
-
-// Even when GL_ARB_depth_clamp is available in the driver, the (correct)
-// headers, and therefore GL_DEPTH_CLAMP might not be defined.
-// In that case GL_DEPTH_CLAMP_NV should be defined, but why not just
-// use the known numeric.
-//
-// To avoid #ifdef's in the code. Just define this here.
-#ifndef GL_DEPTH_CLAMP
-// Probably (still) called GL_DEPTH_CLAMP_NV.
-#define GL_DEPTH_CLAMP 0x864F
-#endif
-
-//GL_NVX_gpu_memory_info constants
-#ifndef GL_NVX_gpu_memory_info
-#define GL_NVX_gpu_memory_info
-#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
-#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
-#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
-#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
-#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
-#endif
-
-//GL_ATI_meminfo constants
-#ifndef GL_ATI_meminfo
-#define GL_ATI_meminfo
-#define GL_VBO_FREE_MEMORY_ATI 0x87FB
-#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
-#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
#endif
#if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL
diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h
index 9bb980d7ad..8248e83044 100644
--- a/indra/llrender/llglstates.h
+++ b/indra/llrender/llglstates.h
@@ -166,31 +166,4 @@ public:
//----------------------------------------------------------------------------
-class LLGLSSpecular
-{
-public:
- F32 mShininess;
- LLGLSSpecular(const LLColor4& color, F32 shininess)
- {
- mShininess = shininess;
- if (mShininess > 0.0f)
- {
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color.mV);
- S32 shiny = (S32)(shininess*128.f);
- shiny = llclamp(shiny,0,128);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, shiny);
- }
- }
- ~LLGLSSpecular()
- {
- if (mShininess > 0.f)
- {
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, LLColor4(0.f,0.f,0.f,0.f).mV);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
- }
- }
-};
-
-//----------------------------------------------------------------------------
-
#endif
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 97ea6f67bd..3165cb313b 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -138,7 +138,6 @@ U32 LLImageGL::sUniqueCount = 0;
U32 LLImageGL::sBindCount = 0;
S32 LLImageGL::sCount = 0;
-bool LLImageGL::sGlobalUseAnisotropic = false;
F32 LLImageGL::sLastFrameTime = 0.f;
LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
bool LLImageGL::sCompressTextures = false;
@@ -837,14 +836,6 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32
mMipLevels = wpo2(llmax(w, h));
- //use legacy mipmap generation mode (note: making this condional can cause rendering issues)
- // -- but making it not conditional triggers deprecation warnings when core profile is enabled
- // (some rendering issues while core profile is enabled are acceptable at this point in time)
- if (!LLRender::sGLCoreProfile)
- {
- glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
- }
-
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
@@ -860,7 +851,6 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32
stop_glerror();
}
- if (LLRender::sGLCoreProfile)
{
LL_PROFILE_GPU_ZONE("generate mip map");
glGenerateMipmap(mTarget);
@@ -1053,7 +1043,11 @@ U32 type_width_from_pixtype(U32 pixtype)
bool should_stagger_image_set(bool compressed)
{
-#if LL_DARWIN
+#if LL_MESA_HEADLESS
+ return false;
+#elif LL_LINUX
+ return !compressed && on_main_thread() && gGLManager.mIsNVIDIA;
+#elif LL_DARWIN
return !compressed && on_main_thread() && gGLManager.mIsAMD;
#else
// glTexSubImage2D doesn't work with compressed textures on select tested Nvidia GPUs on Windows 10 -Cosmic,2023-03-08
@@ -2006,7 +2000,7 @@ bool LLImageGL::getIsResident(bool test_now)
{
if (mTexName != 0)
{
- glAreTexturesResident(1, (GLuint*)&mTexName, &mIsResident);
+ mIsResident = true;
}
else
{
@@ -2141,7 +2135,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
case GL_SRGB_ALPHA:
mAlphaStride = 4;
break;
- case GL_BGRA_EXT:
+ case GL_BGRA:
mAlphaStride = 4;
break;
default:
@@ -2178,7 +2172,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
if( mAlphaStride < 1 || //unsupported format
mAlphaOffset < 0 || //unsupported type
- (mFormatPrimary == GL_BGRA_EXT && mFormatType != GL_UNSIGNED_BYTE)) //unknown situation
+ (mFormatPrimary == GL_BGRA && mFormatType != GL_UNSIGNED_BYTE)) //unknown situation
{
LL_WARNS() << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << LL_ENDL;
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 6b4492c09e..773b647d69 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -285,7 +285,6 @@ public:
// Global memory statistics
static U32 sBindCount; // Tracks number of texture binds for current frame
static U32 sUniqueCount; // Tracks number of unique texture binds for current frame
- static bool sGlobalUseAnisotropic;
static LLImageGL* sDefaultGLTexture ;
static bool sAutomatedTest;
static bool sCompressTextures; //use GL texture compression
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
deleted file mode 100644
index eef7193c92..0000000000
--- a/indra/llrender/llpostprocess.cpp
+++ /dev/null
@@ -1,454 +0,0 @@
-/**
- * @file llpostprocess.cpp
- * @brief LLPostProcess class implementation
- *
- * $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 "linden_common.h"
-
-#include "llpostprocess.h"
-#include "llglslshader.h"
-#include "llsdserialize.h"
-#include "llrender.h"
-
-static LLStaticHashedString sRenderTexture("RenderTexture");
-static LLStaticHashedString sBrightness("brightness");
-static LLStaticHashedString sContrast("contrast");
-static LLStaticHashedString sContrastBase("contrastBase");
-static LLStaticHashedString sSaturation("saturation");
-static LLStaticHashedString sLumWeights("lumWeights");
-static LLStaticHashedString sNoiseTexture("NoiseTexture");
-static LLStaticHashedString sBrightMult("brightMult");
-static LLStaticHashedString sNoiseStrength("noiseStrength");
-static LLStaticHashedString sExtractLow("extractLow");
-static LLStaticHashedString sExtractHigh("extractHigh");
-static LLStaticHashedString sBloomStrength("bloomStrength");
-static LLStaticHashedString sTexelSize("texelSize");
-static LLStaticHashedString sBlurDirection("blurDirection");
-static LLStaticHashedString sBlurWidth("blurWidth");
-
-LLPostProcess * gPostProcess = NULL;
-
-static const unsigned int NOISE_SIZE = 512;
-
-LLPostProcess::LLPostProcess(void) :
- initialized(false),
- mAllEffects(LLSD::emptyMap()),
- screenW(1), screenH(1)
-{
- mSceneRenderTexture = NULL ;
- mNoiseTexture = NULL ;
- mTempBloomTexture = NULL ;
-
- noiseTextureScale = 1.0f;
-
- /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.
- std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
- LL_DEBUGS("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL;
-
- llifstream effectsXML(pathName);
-
- if (effectsXML)
- {
- LLPointer<LLSDParser> parser = new LLSDXMLParser();
-
- parser->parse(effectsXML, mAllEffects, LLSDSerialize::SIZE_UNLIMITED);
- }
-
- if (!mAllEffects.has("default"))
- {
- LLSD & defaultEffect = (mAllEffects["default"] = LLSD::emptyMap());
-
- defaultEffect["enable_night_vision"] = LLSD::Boolean(false);
- defaultEffect["enable_bloom"] = LLSD::Boolean(false);
- defaultEffect["enable_color_filter"] = LLSD::Boolean(false);
-
- /// NVG Defaults
- defaultEffect["brightness_multiplier"] = 3.0;
- defaultEffect["noise_size"] = 25.0;
- defaultEffect["noise_strength"] = 0.4;
-
- // TODO BTest potentially add this to tweaks?
- noiseTextureScale = 1.0f;
-
- /// Bloom Defaults
- defaultEffect["extract_low"] = 0.95;
- defaultEffect["extract_high"] = 1.0;
- defaultEffect["bloom_width"] = 2.25;
- defaultEffect["bloom_strength"] = 1.5;
-
- /// Color Filter Defaults
- defaultEffect["brightness"] = 1.0;
- defaultEffect["contrast"] = 1.0;
- defaultEffect["saturation"] = 1.0;
-
- LLSD& contrastBase = (defaultEffect["contrast_base"] = LLSD::emptyArray());
- contrastBase.append(1.0);
- contrastBase.append(1.0);
- contrastBase.append(1.0);
- contrastBase.append(0.5);
- }
-
- setSelectedEffect("default");
- */
-}
-
-LLPostProcess::~LLPostProcess(void)
-{
- invalidate() ;
-}
-
-// static
-void LLPostProcess::initClass(void)
-{
- //this will cause system to crash at second time login
- //if first time login fails due to network connection --- bao
- //***llassert_always(gPostProcess == NULL);
- //replaced by the following line:
- if(gPostProcess)
- return ;
-
-
- gPostProcess = new LLPostProcess();
-}
-
-// static
-void LLPostProcess::cleanupClass()
-{
- delete gPostProcess;
- gPostProcess = NULL;
-}
-
-void LLPostProcess::setSelectedEffect(std::string const & effectName)
-{
- mSelectedEffectName = effectName;
- static_cast<LLSD &>(tweaks) = mAllEffects[effectName];
-}
-
-void LLPostProcess::saveEffect(std::string const & effectName)
-{
- /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.
- mAllEffects[effectName] = tweaks;
-
- std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
- //LL_INFOS() << "Saving PostProcess Effects settings to " << pathName << LL_ENDL;
-
- llofstream effectsXML(pathName);
-
- LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
-
- formatter->format(mAllEffects, effectsXML);
- */
-}
-void LLPostProcess::invalidate()
-{
- mSceneRenderTexture = NULL ;
- mNoiseTexture = NULL ;
- mTempBloomTexture = NULL ;
- initialized = false ;
-}
-
-void LLPostProcess::apply(unsigned int width, unsigned int height)
-{
- if (!initialized || width != screenW || height != screenH){
- initialize(width, height);
- }
- if (shadersEnabled()){
- doEffects();
- }
-}
-
-void LLPostProcess::initialize(unsigned int width, unsigned int height)
-{
- screenW = width;
- screenH = height;
- createTexture(mSceneRenderTexture, screenW, screenH);
- initialized = true;
-
- checkError();
- createNightVisionShader();
- createBloomShader();
- createColorFilterShader();
- checkError();
-}
-
-inline bool LLPostProcess::shadersEnabled(void)
-{
- return (tweaks.useColorFilter().asBoolean() ||
- tweaks.useNightVisionShader().asBoolean() ||
- tweaks.useBloomShader().asBoolean() );
-
-}
-
-void LLPostProcess::applyShaders(void)
-{
- if (tweaks.useColorFilter()){
- applyColorFilterShader();
- checkError();
- }
- if (tweaks.useNightVisionShader()){
- /// If any of the above shaders have been called update the frame buffer;
- if (tweaks.useColorFilter())
- {
- U32 tex = mSceneRenderTexture->getTexName() ;
- copyFrameBuffer(tex, screenW, screenH);
- }
- applyNightVisionShader();
- checkError();
- }
- if (tweaks.useBloomShader()){
- /// If any of the above shaders have been called update the frame buffer;
- if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean())
- {
- U32 tex = mSceneRenderTexture->getTexName() ;
- copyFrameBuffer(tex, screenW, screenH);
- }
- applyBloomShader();
- checkError();
- }
-}
-
-void LLPostProcess::applyColorFilterShader(void)
-{
-
-}
-
-void LLPostProcess::createColorFilterShader(void)
-{
- /// Define uniform names
- colorFilterUniforms[sRenderTexture] = 0;
- colorFilterUniforms[sBrightness] = 0;
- colorFilterUniforms[sContrast] = 0;
- colorFilterUniforms[sContrastBase] = 0;
- colorFilterUniforms[sSaturation] = 0;
- colorFilterUniforms[sLumWeights] = 0;
-}
-
-void LLPostProcess::applyNightVisionShader(void)
-{
-
-}
-
-void LLPostProcess::createNightVisionShader(void)
-{
- /// Define uniform names
- nightVisionUniforms[sRenderTexture] = 0;
- nightVisionUniforms[sNoiseTexture] = 0;
- nightVisionUniforms[sBrightMult] = 0;
- nightVisionUniforms[sNoiseStrength] = 0;
- nightVisionUniforms[sLumWeights] = 0;
-
- createNoiseTexture(mNoiseTexture);
-}
-
-void LLPostProcess::applyBloomShader(void)
-{
-
-}
-
-void LLPostProcess::createBloomShader(void)
-{
- createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5));
-
- /// Create Bloom Extract Shader
- bloomExtractUniforms[sRenderTexture] = 0;
- bloomExtractUniforms[sExtractLow] = 0;
- bloomExtractUniforms[sExtractHigh] = 0;
- bloomExtractUniforms[sLumWeights] = 0;
-
- /// Create Bloom Blur Shader
- bloomBlurUniforms[sRenderTexture] = 0;
- bloomBlurUniforms[sBloomStrength] = 0;
- bloomBlurUniforms[sTexelSize] = 0;
- bloomBlurUniforms[sBlurDirection] = 0;
- bloomBlurUniforms[sBlurWidth] = 0;
-}
-
-void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLuint & prog)
-{
- /// Find uniform locations and insert into map
- glslUniforms::iterator i;
- for (i = uniforms.begin(); i != uniforms.end(); ++i){
- i->second = glGetUniformLocation(prog, i->first.String().c_str());
- }
-}
-
-void LLPostProcess::doEffects(void)
-{
- /// Save GL State
- glPushAttrib(GL_ALL_ATTRIB_BITS);
- glPushClientAttrib(GL_ALL_ATTRIB_BITS);
-
- /// Copy the screen buffer to the render texture
- {
- U32 tex = mSceneRenderTexture->getTexName() ;
- copyFrameBuffer(tex, screenW, screenH);
- }
-
- /// Clear the frame buffer.
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- /// Change to an orthogonal view
- viewOrthogonal(screenW, screenH);
-
- checkError();
- applyShaders();
-
- LLGLSLShader::unbind();
- checkError();
-
- /// Change to a perspective view
- viewPerspective();
-
- /// Reset GL State
- glPopClientAttrib();
- glPopAttrib();
- checkError();
-}
-
-void LLPostProcess::copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height)
-{
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture);
- glCopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 0, 0, width, height, 0);
-}
-
-void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadType type)
-{
-
-}
-
-void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height)
-{
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.ortho( 0.f, (GLfloat) width , (GLfloat) height , 0.f, -1.f, 1.f );
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
-}
-
-void LLPostProcess::viewPerspective(void)
-{
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-}
-
-void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height)
-{
- viewPerspective();
- viewOrthogonal(width, height);
-}
-
-void LLPostProcess::createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height)
-{
- std::vector<GLubyte> data(width * height * 4, 0) ;
-
- texture = new LLImageGL(false) ;
- if(texture->createGLTexture())
- {
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName());
- glTexImage2D(GL_TEXTURE_RECTANGLE, 0, 4, width, height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- }
-}
-
-void LLPostProcess::createNoiseTexture(LLPointer<LLImageGL>& texture)
-{
- std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE);
- for (unsigned int i = 0; i < NOISE_SIZE; i++){
- for (unsigned int k = 0; k < NOISE_SIZE; k++){
- buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f);
- }
- }
-
- texture = new LLImageGL(false) ;
- if(texture->createGLTexture())
- {
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName());
- LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- }
-}
-
-bool LLPostProcess::checkError(void)
-{
- GLenum glErr;
- bool retCode = false;
-
- glErr = glGetError();
- while (glErr != GL_NO_ERROR)
- {
- // shaderErrorLog << (const char *) gluErrorString(glErr) << std::endl;
- char const * err_str_raw = (const char *) gluErrorString(glErr);
-
- if(err_str_raw == NULL)
- {
- std::ostringstream err_builder;
- err_builder << "unknown error number " << glErr;
- mShaderErrorString = err_builder.str();
- }
- else
- {
- mShaderErrorString = err_str_raw;
- }
-
- retCode = true;
- glErr = glGetError();
- }
- return retCode;
-}
-
-void LLPostProcess::checkShaderError(GLuint shader)
-{
- GLint infologLength = 0;
- GLint charsWritten = 0;
- GLchar *infoLog;
-
- checkError(); // Check for OpenGL errors
-
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength);
-
- checkError(); // Check for OpenGL errors
-
- if (infologLength > 0)
- {
- infoLog = (GLchar *)malloc(infologLength);
- if (infoLog == NULL)
- {
- /// Could not allocate infolog buffer
- return;
- }
- glGetProgramInfoLog(shader, infologLength, &charsWritten, infoLog);
- // shaderErrorLog << (char *) infoLog << std::endl;
- mShaderErrorString = (char *) infoLog;
- free(infoLog);
- }
- checkError(); // Check for OpenGL errors
-}
diff --git a/indra/llrender/llpostprocess.h b/indra/llrender/llpostprocess.h
deleted file mode 100644
index b5b7549efb..0000000000
--- a/indra/llrender/llpostprocess.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/**
- * @file llpostprocess.h
- * @brief LLPostProcess 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_POSTPROCESS_H
-#define LL_POSTPROCESS_H
-
-#include <map>
-#include <fstream>
-#include "llgl.h"
-#include "llglheaders.h"
-#include "llstaticstringtable.h"
-
-class LLPostProcess
-{
-public:
-
- typedef enum _QuadType {
- QUAD_NORMAL,
- QUAD_NOISE,
- QUAD_BLOOM_EXTRACT,
- QUAD_BLOOM_COMBINE
- } QuadType;
-
- /// GLSL Shader Encapsulation Struct
- typedef LLStaticStringTable<GLuint> glslUniforms;
-
- struct PostProcessTweaks : public LLSD {
- inline PostProcessTweaks() : LLSD(LLSD::emptyMap())
- {
- }
-
- inline LLSD & brightMult() {
- return (*this)["brightness_multiplier"];
- }
-
- inline LLSD & noiseStrength() {
- return (*this)["noise_strength"];
- }
-
- inline LLSD & noiseSize() {
- return (*this)["noise_size"];
- }
-
- inline LLSD & extractLow() {
- return (*this)["extract_low"];
- }
-
- inline LLSD & extractHigh() {
- return (*this)["extract_high"];
- }
-
- inline LLSD & bloomWidth() {
- return (*this)["bloom_width"];
- }
-
- inline LLSD & bloomStrength() {
- return (*this)["bloom_strength"];
- }
-
- inline LLSD & brightness() {
- return (*this)["brightness"];
- }
-
- inline LLSD & contrast() {
- return (*this)["contrast"];
- }
-
- inline LLSD & contrastBaseR() {
- return (*this)["contrast_base"][0];
- }
-
- inline LLSD & contrastBaseG() {
- return (*this)["contrast_base"][1];
- }
-
- inline LLSD & contrastBaseB() {
- return (*this)["contrast_base"][2];
- }
-
- inline LLSD & contrastBaseIntensity() {
- return (*this)["contrast_base"][3];
- }
-
- inline LLSD & saturation() {
- return (*this)["saturation"];
- }
-
- inline LLSD & useNightVisionShader() {
- return (*this)["enable_night_vision"];
- }
-
- inline LLSD & useBloomShader() {
- return (*this)["enable_bloom"];
- }
-
- inline LLSD & useColorFilter() {
- return (*this)["enable_color_filter"];
- }
-
-
- inline F32 getBrightMult() const {
- return F32((*this)["brightness_multiplier"].asReal());
- }
-
- inline F32 getNoiseStrength() const {
- return F32((*this)["noise_strength"].asReal());
- }
-
- inline F32 getNoiseSize() const {
- return F32((*this)["noise_size"].asReal());
- }
-
- inline F32 getExtractLow() const {
- return F32((*this)["extract_low"].asReal());
- }
-
- inline F32 getExtractHigh() const {
- return F32((*this)["extract_high"].asReal());
- }
-
- inline F32 getBloomWidth() const {
- return F32((*this)["bloom_width"].asReal());
- }
-
- inline F32 getBloomStrength() const {
- return F32((*this)["bloom_strength"].asReal());
- }
-
- inline F32 getBrightness() const {
- return F32((*this)["brightness"].asReal());
- }
-
- inline F32 getContrast() const {
- return F32((*this)["contrast"].asReal());
- }
-
- inline F32 getContrastBaseR() const {
- return F32((*this)["contrast_base"][0].asReal());
- }
-
- inline F32 getContrastBaseG() const {
- return F32((*this)["contrast_base"][1].asReal());
- }
-
- inline F32 getContrastBaseB() const {
- return F32((*this)["contrast_base"][2].asReal());
- }
-
- inline F32 getContrastBaseIntensity() const {
- return F32((*this)["contrast_base"][3].asReal());
- }
-
- inline F32 getSaturation() const {
- return F32((*this)["saturation"].asReal());
- }
-
- };
-
- bool initialized;
- PostProcessTweaks tweaks;
-
- // the map of all availible effects
- LLSD mAllEffects;
-
-private:
- LLPointer<LLImageGL> mSceneRenderTexture ;
- LLPointer<LLImageGL> mNoiseTexture ;
- LLPointer<LLImageGL> mTempBloomTexture ;
-
-public:
- LLPostProcess(void);
-
- ~LLPostProcess(void);
-
- void apply(unsigned int width, unsigned int height);
- void invalidate() ;
-
- /// Perform global initialization for this class.
- static void initClass(void);
-
- // Cleanup of global data that's only inited once per class.
- static void cleanupClass();
-
- void setSelectedEffect(std::string const & effectName);
-
- inline std::string const & getSelectedEffect(void) const {
- return mSelectedEffectName;
- }
-
- void saveEffect(std::string const & effectName);
-
-private:
- /// read in from file
- std::string mShaderErrorString;
- unsigned int screenW;
- unsigned int screenH;
-
- float noiseTextureScale;
-
- /// Shader Uniforms
- glslUniforms nightVisionUniforms;
- glslUniforms bloomExtractUniforms;
- glslUniforms bloomBlurUniforms;
- glslUniforms colorFilterUniforms;
-
- // the name of currently selected effect in mAllEffects
- // invariant: tweaks == mAllEffects[mSelectedEffectName]
- std::string mSelectedEffectName;
-
- /// General functions
- void initialize(unsigned int width, unsigned int height);
- void doEffects(void);
- void applyShaders(void);
- bool shadersEnabled(void);
-
- /// Night Vision Functions
- void createNightVisionShader(void);
- void applyNightVisionShader(void);
-
- /// Bloom Functions
- void createBloomShader(void);
- void applyBloomShader(void);
-
- /// Color Filter Functions
- void createColorFilterShader(void);
- void applyColorFilterShader(void);
-
- /// OpenGL Helper Functions
- void getShaderUniforms(glslUniforms & uniforms, GLuint & prog);
- void createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height);
- void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height);
- void createNoiseTexture(LLPointer<LLImageGL>& texture);
- bool checkError(void);
- void checkShaderError(GLuint shader);
- void drawOrthoQuad(unsigned int width, unsigned int height, QuadType type);
- void viewOrthogonal(unsigned int width, unsigned int height);
- void changeOrthogonal(unsigned int width, unsigned int height);
- void viewPerspective(void);
-};
-
-extern LLPostProcess * gPostProcess;
-
-
-#endif // LL_POSTPROCESS_H
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 57be8570af..ab88e4868e 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -38,7 +38,11 @@
#include "hbxxh.h"
#include "glm/gtc/type_ptr.hpp"
-#if LL_WINDOWS
+#if GL_ARB_debug_output
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+
extern void APIENTRY gl_debug_callback(GLenum source,
GLenum type,
GLuint id,
@@ -67,20 +71,12 @@ S32 gGLViewport[4];
U32 LLRender::sUICalls = 0;
U32 LLRender::sUIVerts = 0;
U32 LLTexUnit::sWhiteTexture = 0;
+F32 LLRender::sAnisotropicFilteringLevel = 0.f;
bool LLRender::sGLCoreProfile = false;
bool LLRender::sNsightDebugSupport = false;
LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f);
bool LLRender::sClassicMode = false;
-struct LLVBCache
-{
- LLPointer<LLVertexBuffer> vb;
- std::chrono::steady_clock::time_point touched;
-};
-
-static std::unordered_map<U64, LLVBCache> sVBCache;
-static thread_local std::list<LLVertexBufferData> *sBufferDataList = nullptr;
-
static const GLenum sGLTextureType[] =
{
GL_TEXTURE_2D,
@@ -529,9 +525,11 @@ void LLTexUnit::setTextureFilteringOptionFast(LLTexUnit::eTextureFilterOptions o
if (gGLManager.mHasAnisotropic)
{
- if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC)
+ if (option == TFO_ANISOTROPIC && LLRender::sAnisotropicFilteringLevel > 1.f)
{
- glTexParameterf(sGLTextureType[tex_type], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy);
+ F32 aniso_level = llclamp(LLRender::sAnisotropicFilteringLevel, 1.f, gGLManager.mMaxAnisotropy);
+ glTexParameterf(sGLTextureType[tex_type], GL_TEXTURE_MAX_ANISOTROPY, aniso_level);
+
}
else
{
@@ -540,82 +538,6 @@ void LLTexUnit::setTextureFilteringOptionFast(LLTexUnit::eTextureFilterOptions o
}
}
-GLint LLTexUnit::getTextureSource(eTextureBlendSrc src)
-{
- switch(src)
- {
- // All four cases should return the same value.
- case TBS_PREV_COLOR:
- case TBS_PREV_ALPHA:
- case TBS_ONE_MINUS_PREV_COLOR:
- case TBS_ONE_MINUS_PREV_ALPHA:
- return GL_PREVIOUS;
-
- // All four cases should return the same value.
- case TBS_TEX_COLOR:
- case TBS_TEX_ALPHA:
- case TBS_ONE_MINUS_TEX_COLOR:
- case TBS_ONE_MINUS_TEX_ALPHA:
- return GL_TEXTURE;
-
- // All four cases should return the same value.
- case TBS_VERT_COLOR:
- case TBS_VERT_ALPHA:
- case TBS_ONE_MINUS_VERT_COLOR:
- case TBS_ONE_MINUS_VERT_ALPHA:
- return GL_PRIMARY_COLOR;
-
- // All four cases should return the same value.
- case TBS_CONST_COLOR:
- case TBS_CONST_ALPHA:
- case TBS_ONE_MINUS_CONST_COLOR:
- case TBS_ONE_MINUS_CONST_ALPHA:
- return GL_CONSTANT;
-
- default:
- LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << LL_ENDL;
- return GL_PRIMARY_COLOR;
- }
-}
-
-GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
-{
- switch(src)
- {
- // All four cases should return the same value.
- case TBS_PREV_COLOR:
- case TBS_TEX_COLOR:
- case TBS_VERT_COLOR:
- case TBS_CONST_COLOR:
- return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
-
- // All four cases should return the same value.
- case TBS_PREV_ALPHA:
- case TBS_TEX_ALPHA:
- case TBS_VERT_ALPHA:
- case TBS_CONST_ALPHA:
- return GL_SRC_ALPHA;
-
- // All four cases should return the same value.
- case TBS_ONE_MINUS_PREV_COLOR:
- case TBS_ONE_MINUS_TEX_COLOR:
- case TBS_ONE_MINUS_VERT_COLOR:
- case TBS_ONE_MINUS_CONST_COLOR:
- return (isAlpha) ? GL_ONE_MINUS_SRC_ALPHA : GL_ONE_MINUS_SRC_COLOR;
-
- // All four cases should return the same value.
- case TBS_ONE_MINUS_PREV_ALPHA:
- case TBS_ONE_MINUS_TEX_ALPHA:
- case TBS_ONE_MINUS_VERT_ALPHA:
- case TBS_ONE_MINUS_CONST_ALPHA:
- return GL_ONE_MINUS_SRC_ALPHA;
-
- default:
- LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Source Color or Alpha instead." << LL_ENDL;
- return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
- }
-}
-
// Useful for debugging that you've manually assigned a texture operation to the correct
// texture unit based on the currently set active texture in opengl.
void LLTexUnit::debugTextureUnit(void)
@@ -845,7 +767,7 @@ LLRender::~LLRender()
bool LLRender::init(bool needs_vertex_buffer)
{
-#if LL_WINDOWS
+#if GL_ARB_debug_output && !LL_DARWIN
if (gGLManager.mHasDebugOutput && gDebugGL)
{ //setup debug output callback
//glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
@@ -899,7 +821,9 @@ void LLRender::initVertexBuffer()
void LLRender::resetVertexBuffer()
{
- mBuffer = NULL;
+ mBuffer = nullptr;
+ mBufferDataList = nullptr;
+ mVBCache.clear();
}
void LLRender::shutdown()
@@ -1096,7 +1020,7 @@ void LLRender::syncMatrices()
S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
if (loc > -1)
{
- if (cached_mvp_mdv_hash != mMatHash[MM_PROJECTION] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
+ if (cached_mvp_mdv_hash != mMatHash[MM_MODELVIEW] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
{
U32 mdv = MM_MODELVIEW;
cached_mvp = mat;
@@ -1506,21 +1430,21 @@ void LLRender::clearErrors()
void LLRender::beginList(std::list<LLVertexBufferData> *list)
{
- if (sBufferDataList)
+ if (mBufferDataList)
{
LL_ERRS() << "beginList called while another list is open." << LL_ENDL;
}
llassert(LLGLSLShader::sCurBoundShaderPtr == &gUIProgram);
flush();
- sBufferDataList = list;
+ mBufferDataList = list;
}
void LLRender::endList()
{
- if (sBufferDataList)
+ if (mBufferDataList)
{
flush();
- sBufferDataList = nullptr;
+ mBufferDataList = nullptr;
}
else
{
@@ -1608,10 +1532,10 @@ void LLRender::flush()
U32 attribute_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask;
- if (sBufferDataList)
+ if (mBufferDataList)
{
vb = genBuffer(attribute_mask, count);
- sBufferDataList->emplace_back(
+ mBufferDataList->emplace_back(
vb,
mMode,
count,
@@ -1671,9 +1595,9 @@ LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count)
// To leverage this, we maintain a running hash of the vertex stream being
// built up before a flush, and then check that hash against a VB
// cache just before creating a vertex buffer in VRAM
- std::unordered_map<U64, LLVBCache>::iterator cache = sVBCache.find(vhash);
+ std::unordered_map<U64, LLVBCache>::iterator cache = mVBCache.find(vhash);
- if (cache != sVBCache.end())
+ if (cache != mVBCache.end())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hit");
// cache hit, just use the cached buffer
@@ -1685,7 +1609,7 @@ LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count)
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss");
vb = genBuffer(attribute_mask, count);
- sVBCache[vhash] = { vb , std::chrono::steady_clock::now() };
+ mVBCache[vhash] = { vb , std::chrono::steady_clock::now() };
static U32 miss_count = 0;
miss_count++;
@@ -1697,11 +1621,11 @@ LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count)
using namespace std::chrono_literals;
// every 1024 misses, clean the cache of any VBs that haven't been touched in the last second
- for (std::unordered_map<U64, LLVBCache>::iterator iter = sVBCache.begin(); iter != sVBCache.end(); )
+ for (std::unordered_map<U64, LLVBCache>::iterator iter = mVBCache.begin(); iter != mVBCache.end(); )
{
if (now - iter->second.touched > 1s)
{
- iter = sVBCache.erase(iter);
+ iter = mVBCache.erase(iter);
}
else
{
@@ -2002,6 +1926,17 @@ void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a)
}
}
+void LLRender::setLineWidth(F32 width)
+{
+ gGL.flush();
+
+ width = llclamp(width, gGLManager.mAliasedLineRange[0], gGLManager.mAliasedLineRange[1]);
+ if(mLineWidth != width)
+ {
+ mLineWidth = width;
+ glLineWidth(width);
+ }
+}
void LLRender::debugTexUnits(void)
{
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 0801c12fb4..4bfc5723ee 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -46,7 +46,9 @@
#include <boost/align/aligned_allocator.hpp>
#include <array>
+#include <chrono>
#include <list>
+#include <vector>
class LLVertexBuffer;
class LLCubeMap;
@@ -235,8 +237,6 @@ protected:
bool mHasMipMaps;
void debugTextureUnit(void);
- GLint getTextureSource(eTextureBlendSrc src);
- GLint getTextureSourceType(eTextureBlendSrc src, bool isAlpha = false);
};
class LLLightState
@@ -467,6 +467,8 @@ public:
LLLightState* getLight(U32 index);
void setAmbientLightColor(const LLColor4& color);
+ void setLineWidth(F32 width);
+
LLTexUnit* getTexUnit(U32 index);
U32 getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
@@ -487,6 +489,7 @@ public:
public:
static U32 sUICalls;
static U32 sUIVerts;
+ static F32 sAnisotropicFilteringLevel;
static bool sGLCoreProfile;
static bool sNsightDebugSupport;
static LLVector2 sUIGLScaleFactor;
@@ -512,7 +515,8 @@ private:
U32 mCount;
U32 mMode;
U32 mCurrTextureUnitIndex;
- bool mCurrColorMask[4];
+ bool mCurrColorMask[4];
+ F32 mLineWidth = 1.f;
LLPointer<LLVertexBuffer> mBuffer;
LLStrider<LLVector4a> mVerticesp;
@@ -529,6 +533,15 @@ private:
std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 16> > mUIOffset;
std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 16> > mUIScale;
+
+ struct LLVBCache
+ {
+ LLPointer<LLVertexBuffer> vb;
+ std::chrono::steady_clock::time_point touched;
+ };
+
+ std::unordered_map<U64, LLVBCache> mVBCache;
+ std::list<LLVertexBufferData>* mBufferDataList = nullptr;
};
extern F32 gGLModelView[16];
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index 5b08c29d64..e9d2212a67 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -833,8 +833,7 @@ void gl_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& c
{
gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
- gGL.flush();
- glLineWidth(2.5f);
+ gGL.setLineWidth(2.5f);
gGL.begin(LLRender::LINES);
{
@@ -843,7 +842,7 @@ void gl_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& c
}
gGL.end();
- LLRender2D::setLineWidth(1.f);
+ gGL.setLineWidth(1.f);
}
void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, bool filled, F32 start_angle, F32 end_angle)
@@ -1798,16 +1797,8 @@ void LLRender2D::loadIdentity()
// static
void LLRender2D::setLineWidth(F32 width)
{
- gGL.flush();
- // If outside the allowed range, glLineWidth fails with "invalid value".
- // On Darwin, the range is [1, 1].
- static GLfloat range[2]{0.0};
- if (range[1] == 0)
- {
- glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range);
- }
width *= lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f);
- glLineWidth(llclamp(width, range[0], range[1]));
+ gGL.setLineWidth(width);
}
LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index e9bbdeead5..9cdd02f403 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1048,7 +1048,6 @@ void LLShaderMgr::clearShaderCache()
LL_INFOS("ShaderMgr") << "Removing shader cache at " << shader_cache << LL_ENDL;
const std::string mask = "*";
gDirUtilp->deleteFilesInDir(shader_cache, mask);
- LLFile::rmdir(shader_cache);
mShaderBinaryCache.clear();
}
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/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 908e94b24c..b543a12281 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -272,6 +272,10 @@ target_link_libraries(llui
llcommon
)
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llui REUSE_FROM llprecompiled)
+endif ()
+
# Add tests
if(LL_TESTS)
include(LLAddBuildTest)
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index 4068741978..3507d3f34a 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -124,6 +124,11 @@ public:
virtual bool isDirty() const; // Returns true if the user has modified this control.
virtual void resetDirty(); // Clear dirty state
+ LLTextBox* getTextBox() // Provide direct access to label textbox control
+ {
+ return mLabel;
+ }
+
protected:
virtual std::string _getSearchText() const
{
diff --git a/indra/llui/llemojihelper.h b/indra/llui/llemojihelper.h
index 26840eef94..0dc74b1a74 100644
--- a/indra/llui/llemojihelper.h
+++ b/indra/llui/llemojihelper.h
@@ -69,5 +69,5 @@ private:
boost::signals2::connection mHelperCommitConn;
boost::signals2::connection mHelperCloseConn;
std::function<void(llwchar)> mEmojiCommitCb;
- bool mIsHideDisabled;
+ bool mIsHideDisabled = false;
};
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 52a5e3dbd6..f609fe8105 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -248,6 +248,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mShortTitle(p.short_title),
mSingleInstance(p.single_instance),
mReuseInstance(p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance), // reuse single-instance floaters by default
+ mIsReuseInitialized(p.reuse_instance.isProvided()),
mKey(key),
mCanTearOff(p.can_tear_off),
mCanMinimize(p.can_minimize),
@@ -3351,6 +3352,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
mLegacyHeaderHeight = p.legacy_header_height;
mSingleInstance = p.single_instance;
mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance;
+ mIsReuseInitialized = p.reuse_instance.isProvided();
mDefaultRelativeX = p.rel_x;
mDefaultRelativeY = p.rel_y;
diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index a3108d77e8..bdf88768c3 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -98,6 +98,7 @@ const LLSD LLScrollListCell::getAltValue() const
LLScrollListIcon::LLScrollListIcon(const LLScrollListCell::Params& p)
: LLScrollListCell(p),
mIcon(LLUI::getUIImage(p.value().asString())),
+ mIconSize(0),
mColor(p.color),
mAlignment(p.font_halign)
{}
@@ -140,20 +141,32 @@ void LLScrollListIcon::setValue(const LLSD& value)
}
}
-
void LLScrollListIcon::setColor(const LLColor4& color)
{
mColor = color;
}
+void LLScrollListIcon::setIconSize(S32 size)
+{
+ mIconSize = size;
+}
+
S32 LLScrollListIcon::getWidth() const
{
// if no specified fix width, use width of icon
- if (LLScrollListCell::getWidth() == 0 && mIcon.notNull())
+ if (LLScrollListCell::getWidth() != 0)
+ {
+ return LLScrollListCell::getWidth();
+ }
+ if (mIconSize != 0)
+ {
+ return mIconSize;
+ }
+ if (mIcon.notNull())
{
return mIcon->getWidth();
}
- return LLScrollListCell::getWidth();
+ return 0;
}
@@ -161,16 +174,23 @@ void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_col
{
if (mIcon)
{
+ S32 draw_width = mIcon->getWidth();
+ S32 draw_height = mIcon->getHeight();
+ if (mIconSize != 0)
+ {
+ draw_width = mIconSize;
+ draw_height = mIconSize;
+ } // else will draw full icon even if cell is smaller
switch(mAlignment)
{
case LLFontGL::LEFT:
- mIcon->draw(0, 0, mColor);
+ mIcon->draw(0, 0, draw_width, draw_height, mColor);
break;
case LLFontGL::RIGHT:
- mIcon->draw(getWidth() - mIcon->getWidth(), 0, mColor);
+ mIcon->draw(getWidth() - draw_width, 0, draw_width, draw_height, mColor);
break;
case LLFontGL::HCENTER:
- mIcon->draw((getWidth() - mIcon->getWidth()) / 2, 0, mColor);
+ mIcon->draw((getWidth() - draw_width) / 2, 0, draw_width, draw_height, mColor);
break;
default:
break;
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index 7dded3c0b7..f0a0f216b4 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -197,11 +197,13 @@ public:
/*virtual*/ const LLSD getValue() const;
/*virtual*/ void setColor(const LLColor4&);
/*virtual*/ void setValue(const LLSD& value);
+ void setIconSize(S32 size);
private:
LLPointer<LLUIImage> mIcon;
LLColor4 mColor;
LLFontGL::HAlign mAlignment;
+ S32 mIconSize;
};
diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h
index 5636c068d8..3bd8eb1f75 100644
--- a/indra/llui/llviewereventrecorder.h
+++ b/indra/llui/llviewereventrecorder.h
@@ -75,7 +75,7 @@ public:
bool logEvents;
std::string mLogFilename;
- llofstream mLog;
+ llofstream mLog;
private:
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 08b3df87ab..aacaef9257 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -12,12 +12,14 @@ project(llwindow)
include(00-Common)
include(DragDrop)
+include(Linking)
include(LLCommon)
include(LLImage)
include(LLWindow)
include(UI)
include(ViewerMiscLibs)
include(GLM)
+include(SDL3)
set(llwindow_SOURCE_FILES
llcursortypes.cpp
@@ -58,34 +60,24 @@ set(llwindow_LINK_LIBRARIES
ll::glm
ll::glext
ll::uilibraries
- ll::SDL
)
-# Libraries on which this library depends, needed for Linux builds
-# Sort by high-level to low-level
-if (LINUX)
+
+if (USE_SDL_WINDOW)
list(APPEND viewer_SOURCE_FILES
+ llsdl.cpp
llkeyboardsdl.cpp
llwindowsdl.cpp
)
list(APPEND viewer_HEADER_FILES
+ llsdl.h
llkeyboardsdl.h
llwindowsdl.h
)
- if (BUILD_HEADLESS)
- set(llwindowheadless_LINK_LIBRARIES
- ${LLCOMMON_LIBRARIES}
- ${LLIMAGE_LIBRARIES}
- ${LLMATH_LIBRARIES}
- ${LLRENDER_HEADLESS_LIBRARIES}
- ${LLFILESYSTEM_LIBRARIES}
- ${LLWINDOW_HEADLESS_LIBRARIES}
- ${LLXML_LIBRARIES}
- fontconfig # For FCInit and other FC* functions.
- )
- endif (BUILD_HEADLESS)
-
-endif (LINUX)
+ list(APPEND llwindow_LINK_LIBRARIES
+ ll::SDL3
+ )
+endif ()
if (DARWIN)
list(APPEND llwindow_SOURCE_FILES
@@ -109,6 +101,13 @@ if (DARWIN)
PROPERTIES
COMPILE_FLAGS "-fpascal-strings"
)
+
+ set_source_files_properties(
+ llwindowmacosx-objc.mm
+ llopenglview-objc.mm
+ PROPERTIES
+ SKIP_PRECOMPILE_HEADERS TRUE
+ )
endif (DARWIN)
@@ -133,32 +132,55 @@ if (WINDOWS)
)
endif (WINDOWS)
-if (SOLARIS)
- list(APPEND llwindow_SOURCE_FILES
- llwindowsolaris.cpp
- )
- list(APPEND llwindow_HEADER_FILES
- llwindowsolaris.h
- )
-endif (SOLARIS)
if (BUILD_HEADLESS)
set(llwindowheadless_SOURCE_FILES
- llwindowmesaheadless.cpp
- llmousehandler.cpp
- )
+ llcursortypes.cpp
+ llkeyboard.cpp
+ llkeyboardheadless.cpp
+ llwindowheadless.cpp
+ llwindowcallbacks.cpp
+ llwindow.cpp
+ llwindowmesaheadless.cpp
+ llmousehandler.cpp
+ )
+
set(llwindowheadless_HEADER_FILES
- llwindowmesaheadless.h
- llmousehandler.h
- )
+ llcursortypes.h
+ llkeyboard.h
+ llkeyboardheadless.h
+ llwindowheadless.h
+ llwindowcallbacks.h
+ llwindowmesaheadless.h
+ llmousehandler.h
+ )
+
add_library (llwindowheadless
- ${llwindow_SOURCE_FILES}
${llwindowheadless_SOURCE_FILES}
+ ${llwindowheadless_HEADER_FILES}
)
- set_property(TARGET llwindowheadless
- PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
- )
- target_link_libraries (llwindowheadless ${llwindowheadless_LINK_LIBRARIES} dl)
+
+ target_compile_definitions( llwindowheadless PUBLIC LL_MESA_HEADLESS=1 )
+
+ target_link_libraries (llwindowheadless
+ llcommon
+ llimage
+ llmath
+ llrenderheadless
+ llfilesystem
+ llxml
+ ll::glm
+ ll::glext
+ ll::zlib-ng
+ PkgConfig::OSMESA
+ fontconfig
+ dl
+ )
+ target_include_directories(llwindowheadless INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+
+ if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llwindowheadless REUSE_FROM llprecompiled)
+ endif ()
endif (BUILD_HEADLESS)
if (llwindow_HEADER_FILES)
@@ -172,14 +194,16 @@ endif (llwindow_HEADER_FILES)
${viewer_SOURCE_FILES}
)
-if (SDL_FOUND)
- set_property(TARGET llwindow
- PROPERTY COMPILE_DEFINITIONS LL_SDL=1
- )
-endif (SDL_FOUND)
+target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
+target_include_directories(llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+
+if (USE_SDL_WINDOW)
+ target_compile_definitions( llwindow PUBLIC LL_SDL_WINDOW=1 )
+endif()
- target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
- target_include_directories(llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llwindow REUSE_FROM llprecompiled)
+endif ()
if (DARWIN)
target_link_libraries(llwindow ${CARBON_LIBRARY})
diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp
index 33eebdadd1..761b4a1870 100644
--- a/indra/llwindow/llkeyboard.cpp
+++ b/indra/llwindow/llkeyboard.cpp
@@ -41,7 +41,6 @@ std::map<KEY,std::string> LLKeyboard::sKeysToNames;
std::map<std::string,KEY> LLKeyboard::sNamesToKeys;
LLKeyStringTranslatorFunc* LLKeyboard::mStringTranslator = NULL; // Used for l10n + PC/Mac/Linux accelerator labeling
-
//
// Class Implementation
//
@@ -162,6 +161,7 @@ void LLKeyboard::resetKeyDownAndHandle()
mCallbacks->handleTranslatedKeyUp(i, mask);
}
}
+ mCurTranslatedKey = KEY_NONE;
}
// BUG this has to be called when an OS dialog is shown, otherwise modifier key state
@@ -195,12 +195,10 @@ void LLKeyboard::resetKeys()
}
-bool LLKeyboard::translateKey(const U16 os_key, KEY *out_key)
+bool LLKeyboard::translateKey(const NATIVE_KEY_TYPE os_key, KEY *out_key)
{
- std::map<U16, KEY>::iterator iter;
-
// Only translate keys in the map, ignore all other keys for now
- iter = mTranslateKeyMap.find(os_key);
+ auto iter = mTranslateKeyMap.find(os_key);
if (iter == mTranslateKeyMap.end())
{
//LL_WARNS() << "Unknown virtual key " << os_key << LL_ENDL;
@@ -214,11 +212,9 @@ bool LLKeyboard::translateKey(const U16 os_key, KEY *out_key)
}
}
-
-U16 LLKeyboard::inverseTranslateKey(const KEY translated_key)
+LLKeyboard::NATIVE_KEY_TYPE LLKeyboard::inverseTranslateKey(const KEY translated_key)
{
- std::map<KEY, U16>::iterator iter;
- iter = mInvTranslateKeyMap.find(translated_key);
+ auto iter = mInvTranslateKeyMap.find(translated_key);
if (iter == mInvTranslateKeyMap.end())
{
return 0;
@@ -230,7 +226,7 @@ U16 LLKeyboard::inverseTranslateKey(const KEY translated_key)
}
-bool LLKeyboard::handleTranslatedKeyDown(KEY translated_key, U32 translated_mask)
+bool LLKeyboard::handleTranslatedKeyDown(KEY translated_key, MASK translated_mask)
{
bool handled = false;
bool repeated = false;
@@ -258,7 +254,7 @@ bool LLKeyboard::handleTranslatedKeyDown(KEY translated_key, U32 translated_mask
}
-bool LLKeyboard::handleTranslatedKeyUp(KEY translated_key, U32 translated_mask)
+bool LLKeyboard::handleTranslatedKeyUp(KEY translated_key, MASK translated_mask)
{
bool handled = false;
if( mKeyLevel[translated_key] )
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index 713eb7aec2..b4ab562cd5 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -55,6 +55,13 @@ class LLWindowCallbacks;
class LLKeyboard
{
public:
+#ifdef LL_SDL_WINDOW
+ // linux relies on SDL2 which uses U32 for its native key type
+ typedef U32 NATIVE_KEY_TYPE;
+#else
+ // on non-linux platforms we can get by with a smaller native key type
+ typedef U16 NATIVE_KEY_TYPE;
+#endif
LLKeyboard();
virtual ~LLKeyboard();
@@ -67,16 +74,15 @@ public:
bool getKeyDown(const KEY key) { return mKeyLevel[key]; }
bool getKeyRepeated(const KEY key) { return mKeyRepeated[key]; }
- bool translateKey(const U16 os_key, KEY *translated_key);
- U16 inverseTranslateKey(const KEY translated_key);
- bool handleTranslatedKeyUp(KEY translated_key, U32 translated_mask); // Translated into "Linden" keycodes
- bool handleTranslatedKeyDown(KEY translated_key, U32 translated_mask); // Translated into "Linden" keycodes
-
+ bool translateKey(const NATIVE_KEY_TYPE os_key, KEY *translated_key);
+ NATIVE_KEY_TYPE inverseTranslateKey(const KEY translated_key);
+ bool handleTranslatedKeyUp(KEY translated_key, MASK translated_mask); // Translated into "Linden" keycodes
+ bool handleTranslatedKeyDown(KEY translated_key, MASK translated_mask); // Translated into "Linden" keycodes
- virtual bool handleKeyUp(const U16 key, MASK mask) = 0;
- virtual bool handleKeyDown(const U16 key, MASK mask) = 0;
+ virtual bool handleKeyUp(const NATIVE_KEY_TYPE key, MASK mask) = 0;
+ virtual bool handleKeyDown(const NATIVE_KEY_TYPE key, MASK mask) = 0;
-#ifdef LL_DARWIN
+#if LL_DARWIN && !LL_SDL_WINDOW
// We only actually use this for macOS.
virtual void handleModifier(MASK mask) = 0;
#endif // LL_DARWIN
@@ -111,8 +117,8 @@ protected:
void addKeyName(KEY key, const std::string& name);
protected:
- std::map<U16, KEY> mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs
- std::map<KEY, U16> mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys
+ std::map<NATIVE_KEY_TYPE, KEY> mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs
+ std::map<KEY, NATIVE_KEY_TYPE> mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys
LLWindowCallbacks *mCallbacks;
LLTimer mKeyLevelTimer[KEY_COUNT]; // Time since level was set
diff --git a/indra/llwindow/llkeyboardheadless.cpp b/indra/llwindow/llkeyboardheadless.cpp
index 8669a5b41a..50d03aaf20 100644
--- a/indra/llwindow/llkeyboardheadless.cpp
+++ b/indra/llwindow/llkeyboardheadless.cpp
@@ -31,21 +31,23 @@
LLKeyboardHeadless::LLKeyboardHeadless()
{ }
-void LLKeyboardHeadless::resetMaskKeys()
-{ }
-
-
-bool LLKeyboardHeadless::handleKeyDown(const U16 key, const U32 mask)
-{ return false; }
+bool LLKeyboardHeadless::handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask)
+{
+ return false;
+}
+bool LLKeyboardHeadless::handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask)
+{
+ return false;
+}
-bool LLKeyboardHeadless::handleKeyUp(const U16 key, const U32 mask)
-{ return false; }
+void LLKeyboardHeadless::resetMaskKeys()
+{ }
MASK LLKeyboardHeadless::currentMask(bool for_mouse_event)
{ return MASK_NONE; }
-#ifdef LL_DARWIN
+#if LL_DARWIN && !LL_SDL_WINDOW
void LLKeyboardHeadless::handleModifier(MASK mask)
{
@@ -65,6 +67,7 @@ void LLKeyboardHeadless::scanKeyboard()
mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]);
}
}
+ mCurScanKey = KEY_NONE;
// Reset edges for next frame
for (S32 key = 0; key < KEY_COUNT; key++)
diff --git a/indra/llwindow/llkeyboardheadless.h b/indra/llwindow/llkeyboardheadless.h
index 2528f0e3f1..364fb03fe7 100644
--- a/indra/llwindow/llkeyboardheadless.h
+++ b/indra/llwindow/llkeyboardheadless.h
@@ -33,15 +33,15 @@ class LLKeyboardHeadless : public LLKeyboard
{
public:
LLKeyboardHeadless();
- /*virtual*/ ~LLKeyboardHeadless() {};
+ ~LLKeyboardHeadless() = default;
- /*virtual*/ bool handleKeyUp(const U16 key, MASK mask);
- /*virtual*/ bool handleKeyDown(const U16 key, MASK mask);
- /*virtual*/ void resetMaskKeys();
- /*virtual*/ MASK currentMask(bool for_mouse_event);
- /*virtual*/ void scanKeyboard();
-#ifdef LL_DARWIN
- /*virtual*/ void handleModifier(MASK mask);
+ bool handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override;
+ bool handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override;
+ void resetMaskKeys() override;
+ MASK currentMask(bool for_mouse_event) override;
+ void scanKeyboard() override;
+#if LL_DARWIN && !LL_SDL_WINDOW
+ void handleModifier(MASK mask) override;
#endif
};
diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index 89ff7c6d3f..1a403e5d94 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -162,7 +162,7 @@ LLKeyboardMacOSX::LLKeyboardMacOSX()
void LLKeyboardMacOSX::resetMaskKeys()
{
- U32 mask = getModifiers();
+ MASK mask = getModifiers();
// MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().
// It looks a bit suspicious, as it won't correct for keys that have been released.
@@ -187,7 +187,7 @@ void LLKeyboardMacOSX::resetMaskKeys()
}
/*
-static bool translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &outMask)
+static bool translateKeyMac(const U16 key, const MASK mask, KEY &outKey, U32 &outMask)
{
// Translate the virtual keycode into the keycodes the keyboard system expects.
U16 virtualKey = (mask >> 24) & 0x0000007F;
@@ -203,7 +203,7 @@ void LLKeyboardMacOSX::handleModifier(MASK mask)
updateModifiers(mask);
}
-MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
+MASK LLKeyboardMacOSX::updateModifiers(const MASK mask)
{
// translate the mask
MASK out_mask = 0;
@@ -226,7 +226,7 @@ MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
return out_mask;
}
-bool LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask)
+bool LLKeyboardMacOSX::handleKeyDown(const U16 key, MASK mask)
{
KEY translated_key = 0;
U32 translated_mask = 0;
@@ -243,7 +243,7 @@ bool LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask)
}
-bool LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask)
+bool LLKeyboardMacOSX::handleKeyUp(const U16 key, MASK mask)
{
KEY translated_key = 0;
U32 translated_mask = 0;
@@ -262,7 +262,7 @@ bool LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask)
MASK LLKeyboardMacOSX::currentMask(bool for_mouse_event)
{
MASK result = MASK_NONE;
- U32 mask = getModifiers();
+ MASK mask = getModifiers();
if (mask & MAC_SHIFT_KEY) result |= MASK_SHIFT;
if (mask & MAC_CTRL_KEY) result |= MASK_CONTROL;
@@ -291,6 +291,7 @@ void LLKeyboardMacOSX::scanKeyboard()
mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]);
}
}
+ mCurScanKey = KEY_NONE;
// Reset edges for next frame
for (key = 0; key < KEY_COUNT; key++)
diff --git a/indra/llwindow/llkeyboardmacosx.h b/indra/llwindow/llkeyboardmacosx.h
index 92ab5c9a85..c824e7b713 100644
--- a/indra/llwindow/llkeyboardmacosx.h
+++ b/indra/llwindow/llkeyboardmacosx.h
@@ -42,17 +42,17 @@ class LLKeyboardMacOSX : public LLKeyboard
{
public:
LLKeyboardMacOSX();
- /*virtual*/ ~LLKeyboardMacOSX() {};
+ ~LLKeyboardMacOSX() = default;
- /*virtual*/ bool handleKeyUp(const U16 key, MASK mask);
- /*virtual*/ bool handleKeyDown(const U16 key, MASK mask);
- /*virtual*/ void resetMaskKeys();
- /*virtual*/ MASK currentMask(bool for_mouse_event);
- /*virtual*/ void scanKeyboard();
- /*virtual*/ void handleModifier(MASK mask);
+ bool handleKeyUp(const NATIVE_KEY_TYPE key, MASK mask) override;
+ bool handleKeyDown(const NATIVE_KEY_TYPE key, MASK mask) override;
+ void resetMaskKeys() override;
+ MASK currentMask(bool for_mouse_event) override;
+ void scanKeyboard() override;
+ void handleModifier(MASK mask) override;
protected:
- MASK updateModifiers(const U32 mask);
+ MASK updateModifiers(const MASK mask);
void setModifierKeyLevel( KEY key, bool new_state );
bool translateNumpadKey( const U16 os_key, KEY *translated_key );
U16 inverseTranslateNumpadKey(const KEY translated_key);
diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp
index 97198f0cc0..803a5b8c23 100644
--- a/indra/llwindow/llkeyboardsdl.cpp
+++ b/indra/llwindow/llkeyboardsdl.cpp
@@ -24,12 +24,11 @@
* $/LicenseInfo$
*/
-#if LL_SDL
-
#include "linden_common.h"
#include "llkeyboardsdl.h"
#include "llwindowcallbacks.h"
-#include "SDL/SDL.h"
+
+#include "SDL3/SDL_keycode.h"
LLKeyboardSDL::LLKeyboardSDL()
{
@@ -40,7 +39,7 @@ LLKeyboardSDL::LLKeyboardSDL()
// Virtual key mappings from SDL_keysym.h ...
// SDL maps the letter keys to the ASCII you'd expect, but it's lowercase...
- U16 cur_char;
+ LLKeyboard::NATIVE_KEY_TYPE cur_char;
for (cur_char = 'A'; cur_char <= 'Z'; cur_char++)
{
mTranslateKeyMap[cur_char] = cur_char;
@@ -74,7 +73,6 @@ LLKeyboardSDL::LLKeyboardSDL()
mTranslateKeyMap[SDLK_RIGHT] = KEY_RIGHT;
mTranslateKeyMap[SDLK_UP] = KEY_UP;
mTranslateKeyMap[SDLK_DOWN] = KEY_DOWN;
- mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE;
mTranslateKeyMap[SDLK_KP_ENTER] = KEY_RETURN;
mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE;
mTranslateKeyMap[SDLK_BACKSPACE] = KEY_BACKSPACE;
@@ -115,36 +113,35 @@ LLKeyboardSDL::LLKeyboardSDL()
mTranslateKeyMap[SDLK_COMMA] = ',';
mTranslateKeyMap[SDLK_MINUS] = '-';
mTranslateKeyMap[SDLK_PERIOD] = '.';
- mTranslateKeyMap[SDLK_BACKQUOTE] = '`';
+ mTranslateKeyMap[SDLK_GRAVE] = '`';
mTranslateKeyMap[SDLK_SLASH] = KEY_DIVIDE;
mTranslateKeyMap[SDLK_SEMICOLON] = ';';
mTranslateKeyMap[SDLK_LEFTBRACKET] = '[';
mTranslateKeyMap[SDLK_BACKSLASH] = '\\';
mTranslateKeyMap[SDLK_RIGHTBRACKET] = ']';
- mTranslateKeyMap[SDLK_QUOTE] = '\'';
+ mTranslateKeyMap[SDLK_APOSTROPHE] = '\'';
// Build inverse map
- std::map<U16, KEY>::iterator iter;
- for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++)
+ for (auto iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++)
{
mInvTranslateKeyMap[iter->second] = iter->first;
}
// numpad map
- mTranslateNumpadMap[SDLK_KP0] = KEY_PAD_INS;
- mTranslateNumpadMap[SDLK_KP1] = KEY_PAD_END;
- mTranslateNumpadMap[SDLK_KP2] = KEY_PAD_DOWN;
- mTranslateNumpadMap[SDLK_KP3] = KEY_PAD_PGDN;
- mTranslateNumpadMap[SDLK_KP4] = KEY_PAD_LEFT;
- mTranslateNumpadMap[SDLK_KP5] = KEY_PAD_CENTER;
- mTranslateNumpadMap[SDLK_KP6] = KEY_PAD_RIGHT;
- mTranslateNumpadMap[SDLK_KP7] = KEY_PAD_HOME;
- mTranslateNumpadMap[SDLK_KP8] = KEY_PAD_UP;
- mTranslateNumpadMap[SDLK_KP9] = KEY_PAD_PGUP;
+ mTranslateNumpadMap[SDLK_KP_0] = KEY_PAD_INS;
+ mTranslateNumpadMap[SDLK_KP_1] = KEY_PAD_END;
+ mTranslateNumpadMap[SDLK_KP_2] = KEY_PAD_DOWN;
+ mTranslateNumpadMap[SDLK_KP_3] = KEY_PAD_PGDN;
+ mTranslateNumpadMap[SDLK_KP_4] = KEY_PAD_LEFT;
+ mTranslateNumpadMap[SDLK_KP_5] = KEY_PAD_CENTER;
+ mTranslateNumpadMap[SDLK_KP_6] = KEY_PAD_RIGHT;
+ mTranslateNumpadMap[SDLK_KP_7] = KEY_PAD_HOME;
+ mTranslateNumpadMap[SDLK_KP_8] = KEY_PAD_UP;
+ mTranslateNumpadMap[SDLK_KP_9] = KEY_PAD_PGUP;
mTranslateNumpadMap[SDLK_KP_PERIOD] = KEY_PAD_DEL;
// build inverse numpad map
- for (iter = mTranslateNumpadMap.begin();
+ for (auto iter = mTranslateNumpadMap.begin();
iter != mTranslateNumpadMap.end();
iter++)
{
@@ -154,45 +151,45 @@ LLKeyboardSDL::LLKeyboardSDL()
void LLKeyboardSDL::resetMaskKeys()
{
- SDLMod mask = SDL_GetModState();
+ SDL_Keymod mask = SDL_GetModState();
// MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().
// It looks a bit suspicious, as it won't correct for keys that have been released.
// Is this the way it's supposed to work?
- if(mask & KMOD_SHIFT)
+ if(mask & SDL_KMOD_SHIFT)
{
mKeyLevel[KEY_SHIFT] = true;
}
- if(mask & KMOD_CTRL)
+ if(mask & SDL_KMOD_CTRL)
{
mKeyLevel[KEY_CONTROL] = true;
}
- if(mask & KMOD_ALT)
+ if(mask & SDL_KMOD_ALT)
{
mKeyLevel[KEY_ALT] = true;
}
}
-MASK LLKeyboardSDL::updateModifiers(const U32 mask)
+MASK LLKeyboardSDL::updateModifiers(const MASK mask)
{
// translate the mask
MASK out_mask = MASK_NONE;
- if(mask & KMOD_SHIFT)
+ if(mask & SDL_KMOD_SHIFT)
{
out_mask |= MASK_SHIFT;
}
- if(mask & KMOD_CTRL)
+ if(mask & SDL_KMOD_CTRL)
{
out_mask |= MASK_CONTROL;
}
- if(mask & KMOD_ALT)
+ if(mask & SDL_KMOD_ALT)
{
out_mask |= MASK_ALT;
}
@@ -201,37 +198,37 @@ MASK LLKeyboardSDL::updateModifiers(const U32 mask)
}
-static U16 adjustNativekeyFromUnhandledMask(const U16 key, const U32 mask)
+LLKeyboard::NATIVE_KEY_TYPE adjustNativekeyFromUnhandledMask(const LLKeyboard::NATIVE_KEY_TYPE key, const MASK mask)
{
// SDL doesn't automatically adjust the keysym according to
// whether NUMLOCK is engaged, so we massage the keysym manually.
- U16 rtn = key;
- if (!(mask & KMOD_NUM))
+ LLKeyboard::NATIVE_KEY_TYPE rtn = key;
+ if (!(mask & SDL_KMOD_NUM))
{
switch (key)
{
- case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break;
- case SDLK_KP0: rtn = SDLK_INSERT; break;
- case SDLK_KP1: rtn = SDLK_END; break;
- case SDLK_KP2: rtn = SDLK_DOWN; break;
- case SDLK_KP3: rtn = SDLK_PAGEDOWN; break;
- case SDLK_KP4: rtn = SDLK_LEFT; break;
- case SDLK_KP6: rtn = SDLK_RIGHT; break;
- case SDLK_KP7: rtn = SDLK_HOME; break;
- case SDLK_KP8: rtn = SDLK_UP; break;
- case SDLK_KP9: rtn = SDLK_PAGEUP; break;
+ case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break;
+ case SDLK_KP_0: rtn = SDLK_INSERT; break;
+ case SDLK_KP_1: rtn = SDLK_END; break;
+ case SDLK_KP_2: rtn = SDLK_DOWN; break;
+ case SDLK_KP_3: rtn = SDLK_PAGEDOWN; break;
+ case SDLK_KP_4: rtn = SDLK_LEFT; break;
+ case SDLK_KP_6: rtn = SDLK_RIGHT; break;
+ case SDLK_KP_7: rtn = SDLK_HOME; break;
+ case SDLK_KP_8: rtn = SDLK_UP; break;
+ case SDLK_KP_9: rtn = SDLK_PAGEUP; break;
}
}
return rtn;
}
-bool LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask)
+bool LLKeyboardSDL::handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, const MASK mask)
{
- U16 adjusted_nativekey;
+ LLKeyboard::NATIVE_KEY_TYPE adjusted_nativekey;
KEY translated_key = 0;
- U32 translated_mask = MASK_NONE;
- bool handled = false;
+ MASK translated_mask = MASK_NONE;
+ bool handled = false;
adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask);
@@ -246,12 +243,12 @@ bool LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask)
}
-bool LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask)
+bool LLKeyboardSDL::handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, const MASK mask)
{
- U16 adjusted_nativekey;
+ LLKeyboard::NATIVE_KEY_TYPE adjusted_nativekey;
KEY translated_key = 0;
U32 translated_mask = MASK_NONE;
- bool handled = false;
+ bool handled = false;
adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask);
@@ -268,16 +265,20 @@ bool LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask)
MASK LLKeyboardSDL::currentMask(bool for_mouse_event)
{
MASK result = MASK_NONE;
- SDLMod mask = SDL_GetModState();
+ SDL_Keymod mask = SDL_GetModState();
- if (mask & KMOD_SHIFT) result |= MASK_SHIFT;
- if (mask & KMOD_CTRL) result |= MASK_CONTROL;
- if (mask & KMOD_ALT) result |= MASK_ALT;
+ if (mask & SDL_KMOD_SHIFT)
+ result |= MASK_SHIFT;
+ if (mask & SDL_KMOD_CTRL)
+ result |= MASK_CONTROL;
+ if (mask & SDL_KMOD_ALT)
+ result |= MASK_ALT;
// For keyboard events, consider Meta keys equivalent to Control
if (!for_mouse_event)
{
- if (mask & KMOD_META) result |= MASK_CONTROL;
+ if (mask & SDL_KMOD_GUI)
+ result |= MASK_CONTROL;
}
return result;
@@ -296,6 +297,7 @@ void LLKeyboardSDL::scanKeyboard()
mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]);
}
}
+ mCurScanKey = KEY_NONE;
// Reset edges for next frame
for (S32 key = 0; key < KEY_COUNT; key++)
@@ -310,15 +312,347 @@ void LLKeyboardSDL::scanKeyboard()
}
-bool LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key)
+bool LLKeyboardSDL::translateNumpadKey( const LLKeyboard::NATIVE_KEY_TYPE os_key, KEY *translated_key)
{
return translateKey(os_key, translated_key);
}
-U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key)
+LLKeyboard::NATIVE_KEY_TYPE LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key)
{
return inverseTranslateKey(translated_key);
}
-#endif
+enum class WindowsVK : U32
+{
+ LL_VK_UNKNOWN = 0,
+ LL_VK_CANCEL = 0x03,
+ LL_VK_BACK = 0x08,
+ LL_VK_TAB = 0x09,
+ LL_VK_CLEAR = 0x0C,
+ LL_VK_RETURN = 0x0D,
+ LL_VK_SHIFT = 0x10,
+ LL_VK_CONTROL = 0x11,
+ LL_VK_MENU = 0x12,
+ LL_VK_PAUSE = 0x13,
+ LL_VK_CAPITAL = 0x14,
+ LL_VK_KANA = 0x15,
+ LL_VK_HANGUL = 0x15,
+ LL_VK_JUNJA = 0x17,
+ LL_VK_FINAL = 0x18,
+ LL_VK_HANJA = 0x19,
+ LL_VK_KANJI = 0x19,
+ LL_VK_ESCAPE = 0x1B,
+ LL_VK_CONVERT = 0x1C,
+ LL_VK_NONCONVERT = 0x1D,
+ LL_VK_ACCEPT = 0x1E,
+ LL_VK_MODECHANGE = 0x1F,
+ LL_VK_SPACE = 0x20,
+ LL_VK_PRIOR = 0x21,
+ LL_VK_NEXT = 0x22,
+ LL_VK_END = 0x23,
+ LL_VK_HOME = 0x24,
+ LL_VK_LEFT = 0x25,
+ LL_VK_UP = 0x26,
+ LL_VK_RIGHT = 0x27,
+ LL_VK_DOWN = 0x28,
+ LL_VK_SELECT = 0x29,
+ LL_VK_PRINT = 0x2A,
+ LL_VK_EXECUTE = 0x2B,
+ LL_VK_SNAPSHOT = 0x2C,
+ LL_VK_INSERT = 0x2D,
+ LL_VK_DELETE = 0x2E,
+ LL_VK_HELP = 0x2F,
+ LL_VK_0 = 0x30,
+ LL_VK_1 = 0x31,
+ LL_VK_2 = 0x32,
+ LL_VK_3 = 0x33,
+ LL_VK_4 = 0x34,
+ LL_VK_5 = 0x35,
+ LL_VK_6 = 0x36,
+ LL_VK_7 = 0x37,
+ LL_VK_8 = 0x38,
+ LL_VK_9 = 0x39,
+ LL_VK_A = 0x41,
+ LL_VK_B = 0x42,
+ LL_VK_C = 0x43,
+ LL_VK_D = 0x44,
+ LL_VK_E = 0x45,
+ LL_VK_F = 0x46,
+ LL_VK_G = 0x47,
+ LL_VK_H = 0x48,
+ LL_VK_I = 0x49,
+ LL_VK_J = 0x4A,
+ LL_VK_K = 0x4B,
+ LL_VK_L = 0x4C,
+ LL_VK_M = 0x4D,
+ LL_VK_N = 0x4E,
+ LL_VK_O = 0x4F,
+ LL_VK_P = 0x50,
+ LL_VK_Q = 0x51,
+ LL_VK_R = 0x52,
+ LL_VK_S = 0x53,
+ LL_VK_T = 0x54,
+ LL_VK_U = 0x55,
+ LL_VK_V = 0x56,
+ LL_VK_W = 0x57,
+ LL_VK_X = 0x58,
+ LL_VK_Y = 0x59,
+ LL_VK_Z = 0x5A,
+ LL_VK_LWIN = 0x5B,
+ LL_VK_RWIN = 0x5C,
+ LL_VK_APPS = 0x5D,
+ LL_VK_SLEEP = 0x5F,
+ LL_VK_NUMPAD0 = 0x60,
+ LL_VK_NUMPAD1 = 0x61,
+ LL_VK_NUMPAD2 = 0x62,
+ LL_VK_NUMPAD3 = 0x63,
+ LL_VK_NUMPAD4 = 0x64,
+ LL_VK_NUMPAD5 = 0x65,
+ LL_VK_NUMPAD6 = 0x66,
+ LL_VK_NUMPAD7 = 0x67,
+ LL_VK_NUMPAD8 = 0x68,
+ LL_VK_NUMPAD9 = 0x69,
+ LL_VK_MULTIPLY = 0x6A,
+ LL_VK_ADD = 0x6B,
+ LL_VK_SEPARATOR = 0x6C,
+ LL_VK_SUBTRACT = 0x6D,
+ LL_VK_DECIMAL = 0x6E,
+ LL_VK_DIVIDE = 0x6F,
+ LL_VK_F1 = 0x70,
+ LL_VK_F2 = 0x71,
+ LL_VK_F3 = 0x72,
+ LL_VK_F4 = 0x73,
+ LL_VK_F5 = 0x74,
+ LL_VK_F6 = 0x75,
+ LL_VK_F7 = 0x76,
+ LL_VK_F8 = 0x77,
+ LL_VK_F9 = 0x78,
+ LL_VK_F10 = 0x79,
+ LL_VK_F11 = 0x7A,
+ LL_VK_F12 = 0x7B,
+ LL_VK_F13 = 0x7C,
+ LL_VK_F14 = 0x7D,
+ LL_VK_F15 = 0x7E,
+ LL_VK_F16 = 0x7F,
+ LL_VK_F17 = 0x80,
+ LL_VK_F18 = 0x81,
+ LL_VK_F19 = 0x82,
+ LL_VK_F20 = 0x83,
+ LL_VK_F21 = 0x84,
+ LL_VK_F22 = 0x85,
+ LL_VK_F23 = 0x86,
+ LL_VK_F24 = 0x87,
+ LL_VK_NUMLOCK = 0x90,
+ LL_VK_SCROLL = 0x91,
+ LL_VK_LSHIFT = 0xA0,
+ LL_VK_RSHIFT = 0xA1,
+ LL_VK_LCONTROL = 0xA2,
+ LL_VK_RCONTROL = 0xA3,
+ LL_VK_LMENU = 0xA4,
+ LL_VK_RMENU = 0xA5,
+ LL_VK_BROWSER_BACK = 0xA6,
+ LL_VK_BROWSER_FORWARD = 0xA7,
+ LL_VK_BROWSER_REFRESH = 0xA8,
+ LL_VK_BROWSER_STOP = 0xA9,
+ LL_VK_BROWSER_SEARCH = 0xAA,
+ LL_VK_BROWSER_FAVORITES = 0xAB,
+ LL_VK_BROWSER_HOME = 0xAC,
+ LL_VK_VOLUME_MUTE = 0xAD,
+ LL_VK_VOLUME_DOWN = 0xAE,
+ LL_VK_VOLUME_UP = 0xAF,
+ LL_VK_MEDIA_NEXT_TRACK = 0xB0,
+ LL_VK_MEDIA_PREV_TRACK = 0xB1,
+ LL_VK_MEDIA_STOP = 0xB2,
+ LL_VK_MEDIA_PLAY_PAUSE = 0xB3,
+ LL_VK_MEDIA_LAUNCH_MAIL = 0xB4,
+ LL_VK_MEDIA_LAUNCH_MEDIA_SELECT = 0xB5,
+ LL_VK_MEDIA_LAUNCH_APP1 = 0xB6,
+ LL_VK_MEDIA_LAUNCH_APP2 = 0xB7,
+ LL_VK_OEM_1 = 0xBA,
+ LL_VK_OEM_PLUS = 0xBB,
+ LL_VK_OEM_COMMA = 0xBC,
+ LL_VK_OEM_MINUS = 0xBD,
+ LL_VK_OEM_PERIOD = 0xBE,
+ LL_VK_OEM_2 = 0xBF,
+ LL_VK_OEM_3 = 0xC0,
+ LL_VK_OEM_4 = 0xDB,
+ LL_VK_OEM_5 = 0xDC,
+ LL_VK_OEM_6 = 0xDD,
+ LL_VK_OEM_7 = 0xDE,
+ LL_VK_OEM_8 = 0xDF,
+ LL_VK_OEM_102 = 0xE2,
+ LL_VK_PROCESSKEY = 0xE5,
+ LL_VK_PACKET = 0xE7,
+ LL_VK_ATTN = 0xF6,
+ LL_VK_CRSEL = 0xF7,
+ LL_VK_EXSEL = 0xF8,
+ LL_VK_EREOF = 0xF9,
+ LL_VK_PLAY = 0xFA,
+ LL_VK_ZOOM = 0xFB,
+ LL_VK_NONAME = 0xFC,
+ LL_VK_PA1 = 0xFD,
+ LL_VK_OEM_CLEAR = 0xFE,
+};
+
+std::map< U32, U32 > mSDL2_to_Win;
+
+U32 LLKeyboardSDL::mapSDL2toWin( U32 aSymbol )
+{
+ // <FS:ND> Map SDLK_ virtual keys to Windows LL_VK_ virtual keys.
+ // Text is handled via unicode input (SDL_TEXTINPUT event) and does not need to be translated into LL_VK_ values as those match already.
+ if( mSDL2_to_Win.empty() )
+ {
+
+ mSDL2_to_Win[ SDLK_BACKSPACE ] = (U32)WindowsVK::LL_VK_BACK;
+ mSDL2_to_Win[ SDLK_TAB ] = (U32)WindowsVK::LL_VK_TAB;
+ mSDL2_to_Win[ 12 ] = (U32)WindowsVK::LL_VK_CLEAR;
+ mSDL2_to_Win[ SDLK_RETURN ] = (U32)WindowsVK::LL_VK_RETURN;
+ mSDL2_to_Win[ 19 ] = (U32)WindowsVK::LL_VK_PAUSE;
+ mSDL2_to_Win[ SDLK_ESCAPE ] = (U32)WindowsVK::LL_VK_ESCAPE;
+ mSDL2_to_Win[ SDLK_SPACE ] = (U32)WindowsVK::LL_VK_SPACE;
+ mSDL2_to_Win[ SDLK_APOSTROPHE ] = (U32)WindowsVK::LL_VK_OEM_7;
+ mSDL2_to_Win[ SDLK_COMMA ] = (U32)WindowsVK::LL_VK_OEM_COMMA;
+ mSDL2_to_Win[ SDLK_MINUS ] = (U32)WindowsVK::LL_VK_OEM_MINUS;
+ mSDL2_to_Win[ SDLK_PERIOD ] = (U32)WindowsVK::LL_VK_OEM_PERIOD;
+ mSDL2_to_Win[ SDLK_SLASH ] = (U32)WindowsVK::LL_VK_OEM_2;
+
+ mSDL2_to_Win[ SDLK_0 ] = (U32)WindowsVK::LL_VK_0;
+ mSDL2_to_Win[ SDLK_1 ] = (U32)WindowsVK::LL_VK_1;
+ mSDL2_to_Win[ SDLK_2 ] = (U32)WindowsVK::LL_VK_2;
+ mSDL2_to_Win[ SDLK_3 ] = (U32)WindowsVK::LL_VK_3;
+ mSDL2_to_Win[ SDLK_4 ] = (U32)WindowsVK::LL_VK_4;
+ mSDL2_to_Win[ SDLK_5 ] = (U32)WindowsVK::LL_VK_5;
+ mSDL2_to_Win[ SDLK_6 ] = (U32)WindowsVK::LL_VK_6;
+ mSDL2_to_Win[ SDLK_7 ] = (U32)WindowsVK::LL_VK_7;
+ mSDL2_to_Win[ SDLK_8 ] = (U32)WindowsVK::LL_VK_8;
+ mSDL2_to_Win[ SDLK_9 ] = (U32)WindowsVK::LL_VK_9;
+
+ mSDL2_to_Win[ SDLK_SEMICOLON ] = (U32)WindowsVK::LL_VK_OEM_1;
+ mSDL2_to_Win[ SDLK_LESS ] = (U32)WindowsVK::LL_VK_OEM_102;
+ mSDL2_to_Win[ SDLK_EQUALS ] = (U32)WindowsVK::LL_VK_OEM_PLUS;
+ mSDL2_to_Win[ SDLK_KP_EQUALS ] = (U32)WindowsVK::LL_VK_OEM_PLUS;
+
+ mSDL2_to_Win[ SDLK_LEFTBRACKET ] = (U32)WindowsVK::LL_VK_OEM_4;
+ mSDL2_to_Win[ SDLK_BACKSLASH ] = (U32)WindowsVK::LL_VK_OEM_5;
+ mSDL2_to_Win[ SDLK_RIGHTBRACKET ] = (U32)WindowsVK::LL_VK_OEM_6;
+ mSDL2_to_Win[ SDLK_GRAVE ] = (U32)WindowsVK::LL_VK_OEM_8;
+
+ mSDL2_to_Win[ SDLK_A ] = (U32)WindowsVK::LL_VK_A;
+ mSDL2_to_Win[ SDLK_B ] = (U32)WindowsVK::LL_VK_B;
+ mSDL2_to_Win[ SDLK_C ] = (U32)WindowsVK::LL_VK_C;
+ mSDL2_to_Win[ SDLK_D ] = (U32)WindowsVK::LL_VK_D;
+ mSDL2_to_Win[ SDLK_E ] = (U32)WindowsVK::LL_VK_E;
+ mSDL2_to_Win[ SDLK_F ] = (U32)WindowsVK::LL_VK_F;
+ mSDL2_to_Win[ SDLK_G ] = (U32)WindowsVK::LL_VK_G;
+ mSDL2_to_Win[ SDLK_H ] = (U32)WindowsVK::LL_VK_H;
+ mSDL2_to_Win[ SDLK_I ] = (U32)WindowsVK::LL_VK_I;
+ mSDL2_to_Win[ SDLK_J ] = (U32)WindowsVK::LL_VK_J;
+ mSDL2_to_Win[ SDLK_K ] = (U32)WindowsVK::LL_VK_K;
+ mSDL2_to_Win[ SDLK_L ] = (U32)WindowsVK::LL_VK_L;
+ mSDL2_to_Win[ SDLK_M ] = (U32)WindowsVK::LL_VK_M;
+ mSDL2_to_Win[ SDLK_N ] = (U32)WindowsVK::LL_VK_N;
+ mSDL2_to_Win[ SDLK_O ] = (U32)WindowsVK::LL_VK_O;
+ mSDL2_to_Win[ SDLK_P ] = (U32)WindowsVK::LL_VK_P;
+ mSDL2_to_Win[ SDLK_Q ] = (U32)WindowsVK::LL_VK_Q;
+ mSDL2_to_Win[ SDLK_R ] = (U32)WindowsVK::LL_VK_R;
+ mSDL2_to_Win[ SDLK_S ] = (U32)WindowsVK::LL_VK_S;
+ mSDL2_to_Win[ SDLK_T ] = (U32)WindowsVK::LL_VK_T;
+ mSDL2_to_Win[ SDLK_Y ] = (U32)WindowsVK::LL_VK_U;
+ mSDL2_to_Win[ SDLK_V ] = (U32)WindowsVK::LL_VK_V;
+ mSDL2_to_Win[ SDLK_W ] = (U32)WindowsVK::LL_VK_W;
+ mSDL2_to_Win[ SDLK_X ] = (U32)WindowsVK::LL_VK_X;
+ mSDL2_to_Win[ SDLK_Y ] = (U32)WindowsVK::LL_VK_Y;
+ mSDL2_to_Win[ SDLK_Z ] = (U32)WindowsVK::LL_VK_Z;
+ mSDL2_to_Win[ SDLK_DELETE ] = (U32)WindowsVK::LL_VK_DELETE;
+
+
+ mSDL2_to_Win[ SDLK_NUMLOCKCLEAR ] = (U32)WindowsVK::LL_VK_NUMLOCK;
+ mSDL2_to_Win[ SDLK_SCROLLLOCK ] = (U32)WindowsVK::LL_VK_SCROLL;
+
+ mSDL2_to_Win[ SDLK_HELP ] = (U32)WindowsVK::LL_VK_HELP;
+ mSDL2_to_Win[ SDLK_PRINTSCREEN ] = (U32)WindowsVK::LL_VK_SNAPSHOT;
+ mSDL2_to_Win[ SDLK_CANCEL ] = (U32)WindowsVK::LL_VK_CANCEL;
+ mSDL2_to_Win[ SDLK_APPLICATION ] = (U32)WindowsVK::LL_VK_APPS;
+
+ mSDL2_to_Win[ SDLK_UNKNOWN ] = (U32)WindowsVK::LL_VK_UNKNOWN;
+ mSDL2_to_Win[ SDLK_BACKSPACE ] = (U32)WindowsVK::LL_VK_BACK;
+ mSDL2_to_Win[ SDLK_TAB ] = (U32)WindowsVK::LL_VK_TAB;
+ mSDL2_to_Win[ SDLK_CLEAR ] = (U32)WindowsVK::LL_VK_CLEAR;
+ mSDL2_to_Win[ SDLK_RETURN ] = (U32)WindowsVK::LL_VK_RETURN;
+ mSDL2_to_Win[ SDLK_PAUSE ] = (U32)WindowsVK::LL_VK_PAUSE;
+ mSDL2_to_Win[ SDLK_ESCAPE ] = (U32)WindowsVK::LL_VK_ESCAPE;
+ mSDL2_to_Win[ SDLK_DELETE ] = (U32)WindowsVK::LL_VK_DELETE;
+
+ mSDL2_to_Win[ SDLK_KP_PERIOD ] = (U32)WindowsVK::LL_VK_DELETE; // LL_VK_DECIMAL?
+ mSDL2_to_Win[ SDLK_KP_DIVIDE ] = (U32)WindowsVK::LL_VK_DIVIDE;
+ mSDL2_to_Win[ SDLK_KP_MULTIPLY] = (U32)WindowsVK::LL_VK_MULTIPLY;
+ mSDL2_to_Win[ SDLK_KP_MINUS ] = (U32)WindowsVK::LL_VK_OEM_MINUS; // LL_VK_SUBSTRACT?
+ mSDL2_to_Win[ SDLK_KP_PLUS ] = (U32)WindowsVK::LL_VK_OEM_PLUS; // LL_VK_ADD?
+ mSDL2_to_Win[ SDLK_KP_ENTER ] = (U32)WindowsVK::LL_VK_RETURN;
+ mSDL2_to_Win[ SDLK_KP_0 ] = (U32)WindowsVK::LL_VK_INSERT;
+ mSDL2_to_Win[ SDLK_KP_1 ] = (U32)WindowsVK::LL_VK_END;
+ mSDL2_to_Win[ SDLK_KP_2 ] = (U32)WindowsVK::LL_VK_DOWN;
+ mSDL2_to_Win[ SDLK_KP_3 ] = (U32)WindowsVK::LL_VK_NEXT;
+ mSDL2_to_Win[ SDLK_KP_4 ] = (U32)WindowsVK::LL_VK_LEFT;
+ mSDL2_to_Win[ SDLK_KP_5 ] = (U32)WindowsVK::LL_VK_NUMPAD5;
+ mSDL2_to_Win[ SDLK_KP_6 ] = (U32)WindowsVK::LL_VK_RIGHT;
+ mSDL2_to_Win[ SDLK_KP_7 ] = (U32)WindowsVK::LL_VK_HOME;
+ mSDL2_to_Win[ SDLK_KP_8 ] = (U32)WindowsVK::LL_VK_UP;
+ mSDL2_to_Win[ SDLK_KP_9 ] = (U32)WindowsVK::LL_VK_PRIOR;
+
+ // ?
+
+ mSDL2_to_Win[ SDLK_UP ] = (U32)WindowsVK::LL_VK_UP;
+ mSDL2_to_Win[ SDLK_DOWN ] = (U32)WindowsVK::LL_VK_DOWN;
+ mSDL2_to_Win[ SDLK_RIGHT ] = (U32)WindowsVK::LL_VK_RIGHT;
+ mSDL2_to_Win[ SDLK_LEFT ] = (U32)WindowsVK::LL_VK_LEFT;
+ mSDL2_to_Win[ SDLK_INSERT ] = (U32)WindowsVK::LL_VK_INSERT;
+ mSDL2_to_Win[ SDLK_HOME ] = (U32)WindowsVK::LL_VK_HOME;
+ mSDL2_to_Win[ SDLK_END ] = (U32)WindowsVK::LL_VK_END;
+ mSDL2_to_Win[ SDLK_PAGEUP ] = (U32)WindowsVK::LL_VK_PRIOR;
+ mSDL2_to_Win[ SDLK_PAGEDOWN ] = (U32)WindowsVK::LL_VK_NEXT;
+ mSDL2_to_Win[ SDLK_F1 ] = (U32)WindowsVK::LL_VK_F1;
+ mSDL2_to_Win[ SDLK_F2 ] = (U32)WindowsVK::LL_VK_F2;
+ mSDL2_to_Win[ SDLK_F3 ] = (U32)WindowsVK::LL_VK_F3;
+ mSDL2_to_Win[ SDLK_F4 ] = (U32)WindowsVK::LL_VK_F4;
+ mSDL2_to_Win[ SDLK_F5 ] = (U32)WindowsVK::LL_VK_F5;
+ mSDL2_to_Win[ SDLK_F6 ] = (U32)WindowsVK::LL_VK_F6;
+ mSDL2_to_Win[ SDLK_F7 ] = (U32)WindowsVK::LL_VK_F7;
+ mSDL2_to_Win[ SDLK_F8 ] = (U32)WindowsVK::LL_VK_F8;
+ mSDL2_to_Win[ SDLK_F9 ] = (U32)WindowsVK::LL_VK_F9;
+ mSDL2_to_Win[ SDLK_F10 ] = (U32)WindowsVK::LL_VK_F10;
+ mSDL2_to_Win[ SDLK_F11 ] = (U32)WindowsVK::LL_VK_F11;
+ mSDL2_to_Win[ SDLK_F12 ] = (U32)WindowsVK::LL_VK_F12;
+ mSDL2_to_Win[ SDLK_F13 ] = (U32)WindowsVK::LL_VK_F13;
+ mSDL2_to_Win[ SDLK_F14 ] = (U32)WindowsVK::LL_VK_F14;
+ mSDL2_to_Win[ SDLK_F15 ] = (U32)WindowsVK::LL_VK_F15;
+ mSDL2_to_Win[ SDLK_CAPSLOCK ] = (U32)WindowsVK::LL_VK_CAPITAL;
+ mSDL2_to_Win[ SDLK_RSHIFT ] = (U32)WindowsVK::LL_VK_SHIFT;
+ mSDL2_to_Win[ SDLK_LSHIFT ] = (U32)WindowsVK::LL_VK_SHIFT;
+ mSDL2_to_Win[ SDLK_RCTRL ] = (U32)WindowsVK::LL_VK_CONTROL;
+ mSDL2_to_Win[ SDLK_LCTRL ] = (U32)WindowsVK::LL_VK_CONTROL;
+ mSDL2_to_Win[ SDLK_RALT ] = (U32)WindowsVK::LL_VK_MENU;
+ mSDL2_to_Win[ SDLK_LALT ] = (U32)WindowsVK::LL_VK_MENU;
+
+ mSDL2_to_Win[ SDLK_MENU ] = (U32)WindowsVK::LL_VK_MENU;
+
+ // LL_VK_MODECHANGE ?
+ // mSDL2_to_Win[ SDLK_MODE ] = (U32)WindowsVK::LL_VK_MODE;
+
+ // ?
+ // mSDL2_to_Win[ SDLK_SYSREQ ] = (U32)WindowsVK::LL_VK_SYSREQ;
+ // mSDL2_to_Win[ SDLK_POWER ] = (U32)WindowsVK::LL_VK_POWER;
+ // mSDL2_to_Win[ SDLK_UNDO ] = (U32)WindowsVK::LL_VK_UNDO;
+ // mSDL2_to_Win[ SDLK_KP_EQUALS ] = (U32)WindowsVK::LL_VK_EQUALS;
+ // mSDL2_to_Win[ 311 ] = (U32)WindowsVK::LL_VK_LWIN;
+ // mSDL2_to_Win[ 312 ] = (U32)WindowsVK::LL_VK_RWIN;
+ // mSDL2_to_Win[ SDLK_COLON ] = ?
+ }
+
+ auto itr = mSDL2_to_Win.find( aSymbol );
+ if( itr != mSDL2_to_Win.end() )
+ return itr->second;
+
+ return aSymbol;
+}
diff --git a/indra/llwindow/llkeyboardsdl.h b/indra/llwindow/llkeyboardsdl.h
index fd348b28f2..f23b4cca6c 100644
--- a/indra/llwindow/llkeyboardsdl.h
+++ b/indra/llwindow/llkeyboardsdl.h
@@ -28,28 +28,31 @@
#define LL_LLKEYBOARDSDL_H
#include "llkeyboard.h"
-#include "SDL/SDL.h"
+#include "SDL3/SDL.h"
class LLKeyboardSDL : public LLKeyboard
{
public:
LLKeyboardSDL();
- /*virtual*/ ~LLKeyboardSDL() {};
+ ~LLKeyboardSDL() = default;
- /*virtual*/ bool handleKeyUp(const U16 key, MASK mask);
- /*virtual*/ bool handleKeyDown(const U16 key, MASK mask);
- /*virtual*/ void resetMaskKeys();
- /*virtual*/ MASK currentMask(bool for_mouse_event);
- /*virtual*/ void scanKeyboard();
+ bool handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override;
+ bool handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override;
+ void resetMaskKeys() override;
+ MASK currentMask(bool for_mouse_event) override;
+ void scanKeyboard() override;
protected:
- MASK updateModifiers(const U32 mask);
+ MASK updateModifiers(const MASK mask);
void setModifierKeyLevel( KEY key, bool new_state );
- bool translateNumpadKey( const U16 os_key, KEY *translated_key );
- U16 inverseTranslateNumpadKey(const KEY translated_key);
+ bool translateNumpadKey( const LLKeyboard::NATIVE_KEY_TYPE os_key, KEY *translated_key );
+ LLKeyboard::NATIVE_KEY_TYPE inverseTranslateNumpadKey(const KEY translated_key);
private:
- std::map<U16, KEY> mTranslateNumpadMap; // special map for translating OS keys to numpad keys
- std::map<KEY, U16> mInvTranslateNumpadMap; // inverse of the above
+ std::map<LLKeyboard::NATIVE_KEY_TYPE, KEY> mTranslateNumpadMap; // special map for translating OS keys to numpad keys
+ std::map<KEY, LLKeyboard::NATIVE_KEY_TYPE> mInvTranslateNumpadMap; // inverse of the above
+
+public:
+ static U32 mapSDL2toWin( U32 );
};
#endif
diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp
index 8d6b8d9b93..4ef0b493a5 100644
--- a/indra/llwindow/llkeyboardwin32.cpp
+++ b/indra/llwindow/llkeyboardwin32.cpp
@@ -197,7 +197,7 @@ MASK LLKeyboardWin32::updateModifiers()
// mask is ignored, except for extended flag -- we poll the modifier keys for the other flags
-bool LLKeyboardWin32::handleKeyDown(const U16 key, MASK mask)
+bool LLKeyboardWin32::handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask)
{
KEY translated_key;
U32 translated_mask;
@@ -214,7 +214,7 @@ bool LLKeyboardWin32::handleKeyDown(const U16 key, MASK mask)
}
// mask is ignored, except for extended flag -- we poll the modifier keys for the other flags
-bool LLKeyboardWin32::handleKeyUp(const U16 key, MASK mask)
+bool LLKeyboardWin32::handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask)
{
KEY translated_key;
U32 translated_mask;
diff --git a/indra/llwindow/llkeyboardwin32.h b/indra/llwindow/llkeyboardwin32.h
index d0dfc5cfdd..fa223a2904 100644
--- a/indra/llwindow/llkeyboardwin32.h
+++ b/indra/llwindow/llkeyboardwin32.h
@@ -37,15 +37,16 @@ class LLKeyboardWin32 : public LLKeyboard
{
public:
LLKeyboardWin32();
- /*virtual*/ ~LLKeyboardWin32() {};
+ ~LLKeyboardWin32() = default;
- /*virtual*/ bool handleKeyUp(const U16 key, MASK mask);
- /*virtual*/ bool handleKeyDown(const U16 key, MASK mask);
- /*virtual*/ void resetMaskKeys();
- /*virtual*/ MASK currentMask(bool for_mouse_event);
- /*virtual*/ void scanKeyboard();
- bool translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key);
- U16 inverseTranslateExtendedKey(const KEY translated_key);
+ bool handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override;
+ bool handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override;
+ void resetMaskKeys() override;
+ MASK currentMask(bool for_mouse_event) override;
+ void scanKeyboard() override;
+
+ bool translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key);
+ U16 inverseTranslateExtendedKey(const KEY translated_key);
protected:
MASK updateModifiers();
diff --git a/indra/llwindow/llmousehandler.cpp b/indra/llwindow/llmousehandler.cpp
index eeceab502a..959dde70b4 100644
--- a/indra/llwindow/llmousehandler.cpp
+++ b/indra/llwindow/llmousehandler.cpp
@@ -24,6 +24,8 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "llmousehandler.h"
//virtual
diff --git a/indra/llwindow/llsdl.cpp b/indra/llwindow/llsdl.cpp
new file mode 100644
index 0000000000..1df9f38a6d
--- /dev/null
+++ b/indra/llwindow/llsdl.cpp
@@ -0,0 +1,149 @@
+/**
+ * @file llsdl.cpp
+ * @brief SDL2 initialization
+ *
+ * $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 <initializer_list>
+#include <list>
+
+#include "SDL3/SDL.h"
+
+#ifndef LL_SDL_APP
+#define SDL_MAIN_HANDLED 1
+#include "SDL3/SDL_main.h"
+#endif
+
+#include "llerror.h"
+#include "llwindow.h"
+
+bool gSDLMainHandled = false;
+
+void sdl_logger(void *userdata, int category, SDL_LogPriority priority, const char *message)
+{
+ switch (priority)
+ {
+ case SDL_LOG_PRIORITY_TRACE:
+ case SDL_LOG_PRIORITY_VERBOSE:
+ case SDL_LOG_PRIORITY_DEBUG:
+ LL_DEBUGS("SDL") << "log='" << message << "'" << LL_ENDL;
+ break;
+ case SDL_LOG_PRIORITY_INFO:
+ LL_INFOS("SDL") << "log='" << message << "'" << LL_ENDL;
+ break;
+ case SDL_LOG_PRIORITY_WARN:
+ case SDL_LOG_PRIORITY_ERROR:
+ case SDL_LOG_PRIORITY_CRITICAL:
+ LL_WARNS("SDL") << "log='" << message << "'" << LL_ENDL;
+ break;
+ case SDL_LOG_PRIORITY_INVALID:
+ default:
+ break;
+ }
+}
+
+void init_sdl(const std::string& app_name)
+{
+#ifndef LL_SDL_APP
+ if (!gSDLMainHandled)
+ {
+ SDL_SetMainReady();
+ }
+#endif
+
+ SDL_SetLogOutputFunction(&sdl_logger, nullptr);
+
+ const int c_sdl_version = SDL_VERSION;
+ LL_INFOS() << "Compiled against SDL "
+ << SDL_VERSIONNUM_MAJOR(c_sdl_version) << "."
+ << SDL_VERSIONNUM_MINOR(c_sdl_version) << "."
+ << SDL_VERSIONNUM_MICRO(c_sdl_version) << LL_ENDL;
+ const int r_sdl_version = SDL_GetVersion();
+ LL_INFOS() << "Running with SDL "
+ << SDL_VERSIONNUM_MAJOR(r_sdl_version) << "."
+ << SDL_VERSIONNUM_MINOR(r_sdl_version) << "."
+ << SDL_VERSIONNUM_MICRO(r_sdl_version) << LL_ENDL;
+
+#if LL_WINDOWS && defined(LL_SDL_WINDOW)
+ Uint32 style = 0;
+#if defined(CS_BYTEALIGNCLIENT) && defined(CS_OWNDC)
+ style = (CS_BYTEALIGNCLIENT | CS_OWNDC);
+#endif
+ SDL_RegisterApp(app_name.c_str(), style, nullptr);
+#endif
+
+#if LL_SDL_WINDOW
+ // For linux we SDL_INIT_VIDEO and _AUDIO
+ std::initializer_list<std::tuple< char const*, char const * > > hintList =
+ {
+ {SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR,"0"},
+ {SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH,"1"},
+ {SDL_HINT_MOUSE_EMULATE_WARP_WITH_RELATIVE,"0"},
+ {SDL_HINT_MOUSE_RELATIVE_WARP_MOTION,"1"},
+ {SDL_HINT_KEYCODE_OPTIONS,"french_numbers,latin_letters"}
+ };
+
+ for (auto hint: hintList)
+ {
+ SDL_SetHint(std::get<0>(hint), std::get<1>(hint));
+ }
+
+ std::initializer_list<std::tuple<uint32_t, char const*, bool>> initList=
+ {
+ {SDL_INIT_VIDEO,"SDL_INIT_VIDEO", true},
+ {SDL_INIT_JOYSTICK,"SDL_INIT_JOYSTICK", true},
+ {SDL_INIT_GAMEPAD,"SDL_INIT_GAMEPAD", true},
+ };
+#else
+ // For non-linux platforms we still SDL_INIT_VIDEO because it is a pre-requisite
+ // for SDL_INIT_GAMECONTROLLER.
+ std::initializer_list<std::tuple<uint32_t, char const*, bool>> initList=
+ {
+ {SDL_INIT_VIDEO,"SDL_INIT_VIDEO", false},
+ };
+#endif // LL_LINUX
+ // We SDL_INIT_GAMECONTROLLER later in the startup process to make it
+ // more likely we'll catch initial SDL_CONTROLLERDEVICEADDED events.
+
+ for (auto subSystem : initList)
+ {
+ if (!SDL_InitSubSystem(std::get<0>(subSystem)))
+ {
+ LL_WARNS() << "SDL_InitSubSystem for " << std::get<1>(subSystem) << " failed " << SDL_GetError() << LL_ENDL;
+
+ if (std::get<2>(subSystem))
+ {
+ OSMessageBox("SDL_Init() failure", "error", OSMB_OK);
+ return;
+ }
+ }
+ }
+}
+
+void quit_sdl()
+{
+#if LL_WINDOWS && defined(LL_SDL_WINDOW)
+ SDL_UnregisterApp();
+#endif
+ SDL_Quit();
+}
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h b/indra/llwindow/llsdl.h
index cae11a5cb3..1a8a12c61c 100644
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
+++ b/indra/llwindow/llsdl.h
@@ -1,9 +1,7 @@
/**
- * @file llmediaimplgstreamer.h
- * @author Tofu Linden
- * @brief implementation that supports media playback via GStreamer.
+ * @file llsdl.h
+ * @brief SDL2 initialization
*
- * @cond
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
@@ -24,30 +22,13 @@
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
- * @endcond
*/
-// header guard
-#ifndef llmediaimplgstreamer_h
-#define llmediaimplgstreamer_h
+#pragma once
-#if LL_GSTREAMER010_ENABLED
+#include "llpreprocessor.h"
-extern "C" {
-#include <stdio.h>
-#include <gst/gst.h>
+extern bool gSDLMainHandled;
-#include "apr_pools.h"
-#include "apr_dso.h"
-}
-
-
-extern "C" {
-gboolean llmediaimplgstreamer_bus_callback (GstBus *bus,
- GstMessage *message,
- gpointer data);
-}
-
-#endif // LL_GSTREAMER010_ENABLED
-
-#endif // llmediaimplgstreamer_h
+void init_sdl(const std::string& app_name);
+void quit_sdl();
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index eb11a28360..2313aeda50 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -29,7 +29,7 @@
#if LL_MESA_HEADLESS
#include "llwindowmesaheadless.h"
-#elif LL_SDL
+#elif LL_SDL_WINDOW
#include "llwindowsdl.h"
#elif LL_WINDOWS
#include "llwindowwin32.h"
@@ -39,6 +39,9 @@
#include "llerror.h"
#include "llkeyboard.h"
+#if LL_SDL_WINDOW && !defined(LL_MESA_HEADLESS)
+#include "llsdl.h"
+#endif
#include "llwindowcallbacks.h"
@@ -74,14 +77,15 @@ S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)
LL_WARNS() << "OSMessageBox: " << text << LL_ENDL;
#if LL_MESA_HEADLESS // !!! *FIX: (?)
return OSBTN_OK;
+#elif LL_SDL_WINDOW
+ result = OSMessageBoxSDL(text, caption, type);
#elif LL_WINDOWS
result = OSMessageBoxWin32(text, caption, type);
#elif LL_DARWIN
result = OSMessageBoxMacOSX(text, caption, type);
-#elif LL_SDL
- result = OSMessageBoxSDL(text, caption, type);
#else
-#error("OSMessageBox not implemented for this platform!")
+ LL_WARNS() << "OSMessageBox not implemented for this platform!" << LL_ENDL;
+ return OSBTN_OK;
#endif
if (was_visible)
@@ -182,12 +186,6 @@ bool LLWindow::dialogColorPicker(F32 *r, F32 *g, F32 *b)
return false;
}
-void *LLWindow::getMediaWindow()
-{
- // Default to returning the platform window.
- return getPlatformWindow();
-}
-
bool LLWindow::setSize(LLCoordScreen size)
{
if (!getMaximized())
@@ -258,12 +256,12 @@ bool LLWindow::copyTextToPrimary(const LLWString &src)
// static
std::vector<std::string> LLWindow::getDynamicFallbackFontList()
{
-#if LL_WINDOWS
+#if LL_SDL_WINDOW && !LL_MESA_HEADLESS
+ return LLWindowSDL::getDynamicFallbackFontList();
+#elif LL_WINDOWS
return LLWindowWin32::getDynamicFallbackFontList();
#elif LL_DARWIN
return LLWindowMacOSX::getDynamicFallbackFontList();
-#elif LL_SDL
- return LLWindowSDL::getDynamicFallbackFontList();
#else
return std::vector<std::string>();
#endif
@@ -272,7 +270,9 @@ std::vector<std::string> LLWindow::getDynamicFallbackFontList()
// static
std::vector<std::string> LLWindow::getDisplaysResolutionList()
{
-#if LL_WINDOWS
+#if LL_SDL_WINDOW && !LL_MESA_HEADLESS
+ return LLWindowSDL::getDisplaysResolutionList();
+#elif LL_WINDOWS
return LLWindowWin32::getDisplaysResolutionList();
#elif LL_DARWIN
return LLWindowMacOSX::getDisplaysResolutionList();
@@ -341,14 +341,17 @@ bool LLSplashScreen::isVisible()
// static
LLSplashScreen *LLSplashScreen::create()
{
-#if LL_MESA_HEADLESS || LL_SDL // !!! *FIX: (?)
- return 0;
+#if LL_MESA_HEADLESS
+ return nullptr;
+#elif LL_SDL_WINDOW
+ return new LLSplashScreenSDL;
#elif LL_WINDOWS
return new LLSplashScreenWin32;
#elif LL_DARWIN
return new LLSplashScreenMacOSX;
#else
-#error("LLSplashScreen not implemented on this platform!")
+ LL_WARNS() << ("LLSplashScreen not implemented on this platform!") << LL_ENDL;
+ return nullptr;
#endif
}
@@ -358,7 +361,9 @@ void LLSplashScreen::show()
{
if (!gSplashScreenp)
{
-#if LL_WINDOWS && !LL_MESA_HEADLESS
+#if LL_SDL_WINDOW && !LL_MESA_HEADLESS
+ gSplashScreenp = new LLSplashScreenSDL;
+#elif LL_WINDOWS && !LL_MESA_HEADLESS
gSplashScreenp = new LLSplashScreenWin32;
#elif LL_DARWIN
gSplashScreenp = new LLSplashScreenMacOSX;
@@ -412,15 +417,19 @@ LLWindow* LLWindowManager::createWindow(
{
LLWindow* new_window;
+#if LL_SDL_WINDOW && !defined(LL_MESA_HEADLESS)
+ init_sdl(name);
+#endif
+
if (use_gl)
{
#if LL_MESA_HEADLESS
new_window = new LLWindowMesaHeadless(callbacks,
title, name, x, y, width, height, flags,
fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth);
-#elif LL_SDL
+#elif LL_SDL_WINDOW
new_window = new LLWindowSDL(callbacks,
- title, x, y, width, height, flags,
+ title, name, x, y, width, height, flags,
fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
#elif LL_WINDOWS
new_window = new LLWindowWin32(callbacks,
@@ -461,6 +470,9 @@ bool LLWindowManager::destroyWindow(LLWindow* window)
window->close();
sWindowList.erase(window);
+#if LL_SDL_WINDOW && !defined(LL_MESA_HEADLESS)
+ quit_sdl();
+#endif
delete window;
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 7a5404e615..2d8fc80b9e 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -92,7 +92,7 @@ public:
virtual bool setCursorPosition(LLCoordWindow position) = 0;
virtual bool getCursorPosition(LLCoordWindow *position) = 0;
-#if LL_WINDOWS
+#if LL_WINDOWS && !LL_SDL_WINDOW
virtual bool getCursorDelta(LLCoordCommon* delta) = 0;
#endif
virtual bool isWrapMouse() const = 0;
@@ -174,9 +174,6 @@ public:
// return a platform-specific window reference (HWND on Windows, WindowRef on the Mac, Gtk window on Linux)
virtual void *getPlatformWindow() = 0;
-// return the platform-specific window reference we use to initialize llmozlib (HWND on Windows, WindowRef on the Mac, Gtk window on Linux)
- virtual void *getMediaWindow();
-
// control platform's Language Text Input mechanisms.
virtual void allowLanguageTextInput(LLPreeditor *preeditor, bool b) {}
virtual void setLanguageTextInput( const LLCoordGL & pos ) {};
diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h
index dc7b833013..8b7b0ef55c 100644
--- a/indra/llwindow/llwindowheadless.h
+++ b/indra/llwindow/llwindowheadless.h
@@ -60,7 +60,7 @@ public:
/*virtual*/ void toggleVSync(bool enable_vsync) override { }
/*virtual*/ bool setCursorPosition(LLCoordWindow position) override {return false;}
/*virtual*/ bool getCursorPosition(LLCoordWindow *position) override {return false;}
-#if LL_WINDOWS
+#if LL_WINDOWS && !LL_SDL_WINDOW
/*virtual*/ bool getCursorDelta(LLCoordCommon* delta) override { return false; }
#endif
/*virtual*/ bool isWrapMouse() const override { return true; }
diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h
index 0bf8c46a30..47cd6320b1 100644
--- a/indra/llwindow/llwindowmesaheadless.h
+++ b/indra/llwindow/llwindowmesaheadless.h
@@ -30,70 +30,75 @@
#if LL_MESA_HEADLESS
#include "llwindow.h"
-#include "GL/glu.h"
#include "GL/osmesa.h"
class LLWindowMesaHeadless : public LLWindow
{
public:
- /*virtual*/ void show() {};
- /*virtual*/ void hide() {};
- /*virtual*/ void close() {};
- /*virtual*/ bool getVisible() {return false;};
- /*virtual*/ bool getMinimized() {return false;};
- /*virtual*/ bool getMaximized() {return false;};
- /*virtual*/ bool maximize() {return false;};
- /*virtual*/ void minimize() {};
- /*virtual*/ void restore() {};
- /*virtual*/ bool getFullscreen() {return false;};
- /*virtual*/ bool getPosition(LLCoordScreen *position) {return false;};
- /*virtual*/ bool getSize(LLCoordScreen *size) {return false;};
- /*virtual*/ bool getSize(LLCoordWindow *size) {return false;};
- /*virtual*/ bool setPosition(LLCoordScreen position) {return false;};
- /*virtual*/ bool setSizeImpl(LLCoordScreen size) {return false;};
- /*virtual*/ bool switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, const LLCoordScreen * const posp = NULL) {return false;};
- /*virtual*/ bool setCursorPosition(LLCoordWindow position) {return false;};
- /*virtual*/ bool getCursorPosition(LLCoordWindow *position) {return false;};
- /*virtual*/ void showCursor() {};
- /*virtual*/ void hideCursor() {};
- /*virtual*/ void showCursorFromMouseMove() {};
- /*virtual*/ void hideCursorUntilMouseMove() {};
- /*virtual*/ bool isCursorHidden() {return false;};
- /*virtual*/ void updateCursor() {};
- //virtual ECursorType getCursor() { return mCurrentCursor; };
- /*virtual*/ void captureMouse() {};
- /*virtual*/ void releaseMouse() {};
- /*virtual*/ void setMouseClipping( bool b ) {};
- /*virtual*/ bool isClipboardTextAvailable() {return false; };
- /*virtual*/ bool pasteTextFromClipboard(LLWString &dst) {return false; };
- /*virtual*/ bool copyTextToClipboard(const LLWString &src) {return false; };
- /*virtual*/ void flashIcon(F32 seconds) {};
- /*virtual*/ F32 getGamma() {return 1.0f; };
- /*virtual*/ bool setGamma(const F32 gamma) {return false; }; // Set the gamma
- /*virtual*/ bool restoreGamma() {return false; }; // Restore original gamma table (before updating gamma)
- /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { /* FSAA not supported yet on Mesa headless.*/ }
- /*virtual*/ U32 getFSAASamples() { return 0; }
- //virtual ESwapMethod getSwapMethod() { return mSwapMethod; }
- /*virtual*/ void gatherInput() {};
- /*virtual*/ void delayInputProcessing() {};
- /*virtual*/ void swapBuffers();
- /*virtual*/ void restoreGLContext() {};
+ void show() override {};
+ void hide() override {};
+ void close() override {};
+ bool getVisible() override {return false;};
+ bool getMinimized() override {return false;};
+ bool getMaximized() override {return false;};
+ bool maximize() override {return false;};
+ void minimize() override {};
+ void restore() override {};
+ bool getFullscreen() {return false;};
+ bool getPosition(LLCoordScreen *position) override {return false;};
+ bool getSize(LLCoordScreen *size) override {return false;};
+ bool getSize(LLCoordWindow *size) override {return false;};
+ bool setPosition(LLCoordScreen position) override {return false;};
+ bool setSizeImpl(LLCoordScreen size) override {return false;};
+ bool switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, const LLCoordScreen * const posp = NULL) override {return false;};
+ bool setCursorPosition(LLCoordWindow position) override {return false;};
+ bool getCursorPosition(LLCoordWindow *position) override {return false;};
+ bool isWrapMouse() const override { return true; }
+ void showCursor() override {};
+ void hideCursor() override {};
+ void showCursorFromMouseMove() override {};
+ void hideCursorUntilMouseMove() override {};
+ bool isCursorHidden() override {return false;};
+ void updateCursor() override {};
+ //virtual ECursorType getCursor() override { return mCurrentCursor; };
+ void captureMouse() override {};
+ void releaseMouse() override {};
+ void setMouseClipping( bool b ) override {};
+ bool isClipboardTextAvailable() override {return false; };
+ bool pasteTextFromClipboard(LLWString &dst) override {return false; };
+ bool copyTextToClipboard(const LLWString &src) override {return false; };
+ void flashIcon(F32 seconds) override {};
+ F32 getGamma() override {return 1.0f; };
+ bool setGamma(const F32 gamma) override {return false; }; // Set the gamma
+ bool restoreGamma() override {return false; }; // Restore original gamma table (before updating gamma)
+ void setFSAASamples(const U32 fsaa_samples) override { /* FSAA not supported yet on Mesa headless.*/ }
+ U32 getFSAASamples() override { return 0; }
+ //virtual ESwapMethod getSwapMethod() override { return mSwapMethod; }
+ void gatherInput() override {};
+ void delayInputProcessing() override {};
+ void swapBuffers() override;
+
+ void* createSharedContext()override{return nullptr;};
+ void makeContextCurrent(void* context)override{};
+ void destroySharedContext(void* context)override{};
+ void toggleVSync(bool enable_vsync) override {};
+ bool setSizeImpl(LLCoordWindow size) override { return false; };
// handy coordinate space conversion routines
- /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordWindow *to) { return false; };
- /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordScreen *to) { return false; };
- /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordGL *to) { return false; };
- /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordWindow *to) { return false; };
- /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordGL *to) { return false; };
- /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordScreen *to) { return false; };
+ bool convertCoords(LLCoordScreen from, LLCoordWindow *to) override { return false; };
+ bool convertCoords(LLCoordWindow from, LLCoordScreen *to) override { return false; };
+ bool convertCoords(LLCoordWindow from, LLCoordGL *to) override { return false; };
+ bool convertCoords(LLCoordGL from, LLCoordWindow *to) override { return false; };
+ bool convertCoords(LLCoordScreen from, LLCoordGL *to) override { return false; };
+ bool convertCoords(LLCoordGL from, LLCoordScreen *to) override { return false; };
- /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) { return NULL; };
- /*virtual*/ F32 getNativeAspectRatio() { return 1.0f; };
- /*virtual*/ F32 getPixelAspectRatio() { return 1.0f; };
- /*virtual*/ void setNativeAspectRatio(F32 ratio) {}
+ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override { return NULL; };
+ F32 getNativeAspectRatio() override { return 1.0f; };
+ F32 getPixelAspectRatio() override { return 1.0f; };
+ void setNativeAspectRatio(F32 ratio) override {}
- /*virtual*/ void *getPlatformWindow() { return 0; };
- /*virtual*/ void bringToFront() {};
+ void *getPlatformWindow() override { return 0; };
+ void bringToFront() override {};
LLWindowMesaHeadless(LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
@@ -112,9 +117,9 @@ public:
LLSplashScreenMesaHeadless() {};
virtual ~LLSplashScreenMesaHeadless() {};
- /*virtual*/ void showImpl() {};
- /*virtual*/ void updateImpl(const std::string& mesg) {};
- /*virtual*/ void hideImpl() {};
+ void showImpl() override {};
+ void updateImpl(const std::string& mesg) override {};
+ void hideImpl() override {};
};
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 05be319c0b..3fc0257a7f 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -25,8 +25,6 @@
* $/LicenseInfo$
*/
-#if LL_SDL
-
#include "linden_common.h"
#include "llwindowsdl.h"
@@ -39,197 +37,84 @@
#include "llstring.h"
#include "lldir.h"
#include "llfindlocale.h"
+#include "llpreeditor.h"
+#include "llsdl.h"
-#if LL_GTK
-extern "C" {
-# include "gtk/gtk.h"
-}
-#include <locale.h>
-#endif // LL_GTK
+#if LL_LINUX
+#ifdef LL_GLIB
+#include <glib.h>
+#endif
extern "C" {
# include "fontconfig/fontconfig.h"
}
-#if LL_LINUX
// not necessarily available on random SDL platforms, so #if LL_LINUX
// for execv(), waitpid(), fork()
-# include <unistd.h>
-# include <sys/types.h>
-# include <sys/wait.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+
+#if LL_X11
+LLWindowSDL::X11_DATA LLWindowSDL::sX11Data = {};
+#endif
+#if LL_WAYLAND
+LLWindowSDL::WAYLAND_DATA LLWindowSDL::sWaylandData = {};
+#endif
#endif // LL_LINUX
-extern bool gDebugWindowProc;
+#if LL_DARWIN
+#include <OpenGL/OpenGL.h>
+#include <Carbon/Carbon.h>
+#include <CoreServices/CoreServices.h>
+#include <CoreGraphics/CGDisplayConfiguration.h>
-const S32 MAX_NUM_RESOLUTIONS = 200;
+bool LLWindowSDL::sUseMultGL = false;
+#endif
+
+bool gHiDPISupport = true;
-// static variable for ATI mouse cursor crash work-around:
-static bool ATIbug = false;
+const S32 MAX_NUM_RESOLUTIONS = 200;
+const S32 DEFAULT_REFRESH_RATE = 60;
//
// LLWindowSDL
//
-#if LL_X11
-# include <X11/Xutil.h>
-#endif //LL_X11
-
// TOFU HACK -- (*exactly* the same hack as LLWindowMacOSX for a similar
// set of reasons): Stash a pointer to the LLWindowSDL object here and
// maintain in the constructor and destructor. This assumes that there will
// be only one object of this class at any time. Currently this is true.
-static LLWindowSDL *gWindowImplementation = NULL;
-
-
-void maybe_lock_display(void)
-{
- if (gWindowImplementation && gWindowImplementation->Lock_Display) {
- gWindowImplementation->Lock_Display();
- }
-}
-
-
-void maybe_unlock_display(void)
-{
- if (gWindowImplementation && gWindowImplementation->Unlock_Display) {
- gWindowImplementation->Unlock_Display();
- }
-}
-
-
-#if LL_GTK
-// Lazily initialize and check the runtime GTK version for goodness.
-// static
-bool LLWindowSDL::ll_try_gtk_init(void)
-{
- static bool done_gtk_diag = false;
- static bool gtk_is_good = false;
- static bool done_setlocale = false;
- static bool tried_gtk_init = false;
-
- if (!done_setlocale)
- {
- LL_INFOS() << "Starting GTK Initialization." << LL_ENDL;
- maybe_lock_display();
- gtk_disable_setlocale();
- maybe_unlock_display();
- done_setlocale = true;
- }
-
- if (!tried_gtk_init)
- {
- tried_gtk_init = true;
- if (!g_thread_supported ()) g_thread_init (NULL);
- maybe_lock_display();
- gtk_is_good = gtk_init_check(NULL, NULL);
- maybe_unlock_display();
- if (!gtk_is_good)
- LL_WARNS() << "GTK Initialization failed." << LL_ENDL;
- }
-
- if (gtk_is_good && !done_gtk_diag)
- {
- LL_INFOS() << "GTK Initialized." << LL_ENDL;
- LL_INFOS() << "- Compiled against GTK version "
- << GTK_MAJOR_VERSION << "."
- << GTK_MINOR_VERSION << "."
- << GTK_MICRO_VERSION << LL_ENDL;
- LL_INFOS() << "- Running against GTK version "
- << gtk_major_version << "."
- << gtk_minor_version << "."
- << gtk_micro_version << LL_ENDL;
- maybe_lock_display();
- const gchar* gtk_warning = gtk_check_version(
- GTK_MAJOR_VERSION,
- GTK_MINOR_VERSION,
- GTK_MICRO_VERSION);
- maybe_unlock_display();
- if (gtk_warning)
- {
- LL_WARNS() << "- GTK COMPATIBILITY WARNING: " <<
- gtk_warning << LL_ENDL;
- gtk_is_good = false;
- } else {
- LL_INFOS() << "- GTK version is good." << LL_ENDL;
- }
-
- done_gtk_diag = true;
- }
-
- return gtk_is_good;
-}
-#endif // LL_GTK
-
-
-#if LL_X11
-// static
-Window LLWindowSDL::get_SDL_XWindowID(void)
-{
- if (gWindowImplementation) {
- return gWindowImplementation->mSDL_XWindowID;
- }
- return None;
-}
-
-//static
-Display* LLWindowSDL::get_SDL_Display(void)
-{
- if (gWindowImplementation) {
- return gWindowImplementation->mSDL_Display;
- }
- return NULL;
-}
-#endif // LL_X11
-
+static LLWindowSDL *gWindowImplementation = nullptr;
LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,
- const std::string& title, S32 x, S32 y, S32 width,
- S32 height, U32 flags,
- bool fullscreen, bool clearBg,
- bool disable_vsync, bool use_gl,
- bool ignore_pixel_depth, U32 fsaa_samples)
- : LLWindow(callbacks, fullscreen, flags),
- Lock_Display(NULL),
- Unlock_Display(NULL), mGamma(1.0f)
+ const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
+ S32 height, U32 flags,
+ bool fullscreen, bool clearBg,
+ bool enable_vsync, bool use_gl,
+ bool ignore_pixel_depth, U32 fsaa_samples)
+ : LLWindow(callbacks, fullscreen, flags),
+ mGamma(1.0f), mFlashing(false)
{
+ SDL_GL_LoadLibrary(nullptr);
+
// Initialize the keyboard
gKeyboard = new LLKeyboardSDL();
gKeyboard->setCallbacks(callbacks);
- // Note that we can't set up key-repeat until after SDL has init'd video
-
- // Ignore use_gl for now, only used for drones on PC
- mWindow = NULL;
- mNeedsResize = false;
- mOverrideAspectRatio = 0.f;
- mGrabbyKeyFlags = 0;
- mReallyCapturedCount = 0;
- mHaveInputFocus = -1;
- mIsMinimized = -1;
- mFSAASamples = fsaa_samples;
-
-#if LL_X11
- mSDL_XWindowID = None;
- mSDL_Display = NULL;
-#endif // LL_X11
-
-#if LL_GTK
- // We MUST be the first to initialize GTK so that GTK doesn't get badly
- // initialized with a non-C locale and cause lots of serious random
- // weirdness.
- ll_try_gtk_init();
-#endif // LL_GTK
// Assume 4:3 aspect ratio until we know better
- mOriginalAspectRatio = 1024.0 / 768.0;
+ mNativeAspectRatio = 1024.f / 768.f;
if (title.empty())
- mWindowTitle = "SDL Window"; // *FIX: (?)
+ mWindowTitle = "Second Life";
else
mWindowTitle = title;
// Create the GL context and set it up for windowed or fullscreen, as appropriate.
- if(createContext(x, y, width, height, 32, fullscreen, disable_vsync))
+ if(createContext(x, y, width, height, 32, fullscreen, enable_vsync))
{
+ gGLManager.initWGL();
gGLManager.initGL();
//start with arrow cursor
@@ -241,14 +126,6 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,
// Stash an object pointer for OSMessageBox()
gWindowImplementation = this;
-
-#if LL_X11
- mFlashing = false;
-#endif // LL_X11
-
- mKeyScanCode = 0;
- mKeyVirtualKey = 0;
- mKeyModifiers = KMOD_NONE;
}
static SDL_Surface *Load_BMP_Resource(const char *basename)
@@ -258,480 +135,377 @@ static SDL_Surface *Load_BMP_Resource(const char *basename)
// Figure out where our BMP is living on the disk
snprintf(path_buffer, PATH_BUFFER_SIZE-1, "%s%sres-sdl%s%s",
- gDirUtilp->getAppRODataDir().c_str(),
- gDirUtilp->getDirDelimiter().c_str(),
- gDirUtilp->getDirDelimiter().c_str(),
- basename);
+ gDirUtilp->getAppRODataDir().c_str(),
+ gDirUtilp->getDirDelimiter().c_str(),
+ gDirUtilp->getDirDelimiter().c_str(),
+ basename);
path_buffer[PATH_BUFFER_SIZE-1] = '\0';
return SDL_LoadBMP(path_buffer);
}
-#if LL_X11
-// This is an XFree86/XOrg-specific hack for detecting the amount of Video RAM
-// on this machine. It works by searching /var/log/var/log/Xorg.?.log or
-// /var/log/XFree86.?.log for a ': (VideoRAM ?|Memory): (%d+) kB' regex, where
-// '?' is the X11 display number derived from $DISPLAY
-static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str)
+void LLWindowSDL::setTitle(const std::string title)
{
- const int line_buf_size = 1000;
- char line_buf[line_buf_size];
- while (fgets(line_buf, line_buf_size, fp))
- {
- //LL_DEBUGS() << "XLOG: " << line_buf << LL_ENDL;
-
- // Why the ad-hoc parser instead of using a regex? Our
- // favourite regex implementation - libboost_regex - is
- // quite a heavy and troublesome dependency for the client, so
- // it seems a shame to introduce it for such a simple task.
- // *FIXME: libboost_regex is a dependency now anyway, so we may
- // as well use it instead of this hand-rolled nonsense.
- const char *part1_template = prefix_str;
- const char part2_template[] = " kB";
- char *part1 = strstr(line_buf, part1_template);
- if (part1) // found start of matching line
- {
- part1 = &part1[strlen(part1_template)]; // -> after
- char *part2 = strstr(part1, part2_template);
- if (part2) // found end of matching line
- {
- // now everything between part1 and part2 is
- // supposed to be numeric, describing the
- // number of kB of Video RAM supported
- int rtn = 0;
- for (; part1 < part2; ++part1)
- {
- if (*part1 < '0' || *part1 > '9')
- {
- // unexpected char, abort parse
- rtn = 0;
- break;
- }
- rtn *= 10;
- rtn += (*part1) - '0';
- }
- if (rtn > 0)
- {
- // got the kB number. return it now.
- return rtn;
- }
- }
- }
- }
- return 0; // 'could not detect'
+ SDL_SetWindowTitle( mWindow, title.c_str() );
}
-static int x11_detect_VRAM_kb()
+void LLWindowSDL::tryFindFullscreenSize( int &width, int &height )
{
- std::string x_log_location("/var/log/");
- std::string fname;
- int rtn = 0; // 'could not detect'
- int display_num = 0;
- FILE *fp;
- char *display_env = getenv("DISPLAY"); // e.g. :0 or :0.0 or :1.0 etc
- // parse DISPLAY number so we can go grab the right log file
- if (display_env[0] == ':' &&
- display_env[1] >= '0' && display_env[1] <= '9')
- {
- display_num = display_env[1] - '0';
- }
+ LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL;
- // *TODO: we could be smarter and see which of Xorg/XFree86 has the
- // freshest time-stamp.
-
- // Try Xorg log first
- fname = x_log_location;
- fname += "Xorg.";
- fname += ('0' + display_num);
- fname += ".log";
- fp = fopen(fname.c_str(), "r");
- if (fp)
+ // If the requested width or height is 0, find the best default for the monitor.
+ if(width == 0 || height == 0)
{
- LL_INFOS() << "Looking in " << fname
- << " for VRAM info..." << LL_ENDL;
- rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: ");
- fclose(fp);
- if (0 == rtn)
+ // Scan through the list of modes, looking for one which has:
+ // height between 700 and 800
+ // aspect ratio closest to the user's original mode
+ S32 resolutionCount = 0;
+ LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount);
+
+ if(resolutionList != nullptr)
{
- fp = fopen(fname.c_str(), "r");
- if (fp)
+ F32 closestAspect = 0;
+ U32 closestHeight = 0;
+ U32 closestWidth = 0;
+
+ LL_INFOS() << "createContext: searching for a display mode, original aspect is " << mNativeAspectRatio << LL_ENDL;
+
+ for(S32 i=0; i < resolutionCount; i++)
{
- rtn = x11_detect_VRAM_kb_fp(fp, ": Video RAM: ");
- fclose(fp);
- if (0 == rtn)
+ F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight;
+
+ LL_INFOS() << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL;
+
+ if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) &&
+ (fabs(aspect - mNativeAspectRatio) < fabs(closestAspect - mNativeAspectRatio)))
{
- fp = fopen(fname.c_str(), "r");
- if (fp)
- {
- rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: ");
- fclose(fp);
- }
+ LL_INFOS() << " (new closest mode) " << LL_ENDL;
+
+ // This is the closest mode we've seen yet.
+ closestWidth = resolutionList[i].mWidth;
+ closestHeight = resolutionList[i].mHeight;
+ closestAspect = aspect;
}
}
+
+ width = closestWidth;
+ height = closestHeight;
}
}
- else
+
+ if(width == 0 || height == 0)
{
- LL_INFOS() << "Could not open " << fname
- << " - skipped." << LL_ENDL;
- // Try old XFree86 log otherwise
- fname = x_log_location;
- fname += "XFree86.";
- fname += ('0' + display_num);
- fname += ".log";
- fp = fopen(fname.c_str(), "r");
- if (fp)
- {
- LL_INFOS() << "Looking in " << fname
- << " for VRAM info..." << LL_ENDL;
- rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: ");
- fclose(fp);
- if (0 == rtn)
- {
- fp = fopen(fname.c_str(), "r");
- if (fp)
- {
- rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: ");
- fclose(fp);
- }
- }
- }
- else
- {
- LL_INFOS() << "Could not open " << fname
- << " - skipped." << LL_ENDL;
- }
+ // Mode search failed for some reason. Use the old-school default.
+ width = 1024;
+ height = 768;
}
- return rtn;
}
-#endif // LL_X11
-bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool disable_vsync)
+bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool enable_vsync)
{
- //bool glneedsinit = false;
-
- LL_INFOS() << "createContext, fullscreen=" << fullscreen <<
- " size=" << width << "x" << height << LL_ENDL;
+ LL_INFOS() << "createContext, fullscreen=" << fullscreen << " size=" << width << "x" << height << LL_ENDL;
// captures don't survive contexts
mGrabbyKeyFlags = 0;
- mReallyCapturedCount = 0;
- if (SDL_Init(SDL_INIT_VIDEO) < 0)
- {
- LL_INFOS() << "sdl_init() failed! " << SDL_GetError() << LL_ENDL;
- setupFailure("sdl_init() failure, window creation error", "error", OSMB_OK);
- return false;
- }
+ if (width == 0)
+ width = 1024;
+ if (height == 0)
+ width = 768;
+ if (x == 0)
+ x = SDL_WINDOWPOS_UNDEFINED;
+ if (y == 0)
+ y = SDL_WINDOWPOS_UNDEFINED;
- SDL_version c_sdl_version;
- SDL_VERSION(&c_sdl_version);
- LL_INFOS() << "Compiled against SDL "
- << int(c_sdl_version.major) << "."
- << int(c_sdl_version.minor) << "."
- << int(c_sdl_version.patch) << LL_ENDL;
- const SDL_version *r_sdl_version;
- r_sdl_version = SDL_Linked_Version();
- LL_INFOS() << " Running against SDL "
- << int(r_sdl_version->major) << "."
- << int(r_sdl_version->minor) << "."
- << int(r_sdl_version->patch) << LL_ENDL;
+ mFullscreen = fullscreen;
+
+ // Setup default backing colors
+ GLint redBits{8}, greenBits{8}, blueBits{8}, alphaBits{8};
+ GLint depthBits{24}, stencilBits{8};
+
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, redBits);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, greenBits);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, blueBits);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, alphaBits);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- const SDL_VideoInfo *video_info = SDL_GetVideoInfo( );
- if (!video_info)
+ SDL_GLContextFlag context_flags{};
+ if(LLRender::sGLCoreProfile)
{
- LL_INFOS() << "SDL_GetVideoInfo() failed! " << SDL_GetError() << LL_ENDL;
- setupFailure("SDL_GetVideoInfo() failed, Window creation error", "Error", OSMB_OK);
- return false;
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+#if LL_DARWIN
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
+ context_flags |= SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG;
+#endif
}
- if (video_info->current_h > 0)
+ if (gDebugGL)
{
- mOriginalAspectRatio = (float)video_info->current_w / (float)video_info->current_h;
- LL_INFOS() << "Original aspect ratio was " << video_info->current_w << ":" << video_info->current_h << "=" << mOriginalAspectRatio << LL_ENDL;
+ context_flags |= SDL_GL_CONTEXT_DEBUG_FLAG;
}
- SDL_EnableUNICODE(1);
- SDL_WM_SetCaption(mWindowTitle.c_str(), mWindowTitle.c_str());
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, context_flags);
+ SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
- // Set the application icon.
- SDL_Surface *bmpsurface;
- bmpsurface = Load_BMP_Resource("ll_icon.BMP");
- if (bmpsurface)
+ if(mFullscreen)
{
- // This attempts to give a black-keyed mask to the icon.
- SDL_SetColorKey(bmpsurface,
- SDL_SRCCOLORKEY,
- SDL_MapRGB(bmpsurface->format, 0,0,0) );
- SDL_WM_SetIcon(bmpsurface, NULL);
- // The SDL examples cheerfully avoid freeing the icon
- // surface, but I'm betting that's leaky.
- SDL_FreeSurface(bmpsurface);
- bmpsurface = NULL;
+ tryFindFullscreenSize(width, height);
}
- // note: these SetAttributes make Tom's 9600-on-AMD64 fail to
- // get a visual, but it's broken anyway when it does, and without
- // these SetAttributes we might easily get an avoidable substandard
- // visual to work with on most other machines.
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24);
- // We need stencil support for a few (minor) things.
- if (!getenv("LL_GL_NO_STENCIL"))
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, (bits <= 16) ? 1 : 8);
-
- // *FIX: try to toggle vsync here?
-
- mFullscreen = fullscreen;
-
- int sdlflags = SDL_OPENGL | SDL_RESIZABLE | SDL_ANYFORMAT;
-
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_PropertiesID props = SDL_CreateProperties();
+ SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, mWindowTitle.c_str());
+ SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, x);
+ SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y);
+ SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
+ SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, true);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, mFullscreen);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIDDEN_BOOLEAN, true);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, gHiDPISupport);
- if (mFSAASamples > 0)
+ mWindow = SDL_CreateWindowWithProperties(props);
+ if (mWindow == nullptr)
{
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, mFSAASamples);
+ LL_WARNS() << "Window creation failure. SDL: " << SDL_GetError() << LL_ENDL;
+ setupFailure("Window creation error", "Error", OSMB_OK);
+ SDL_DestroyProperties(props);
+ return false;
}
+ SDL_DestroyProperties(props); // Free properties once window is created
- mSDLFlags = sdlflags;
+ // Create the context
+ mContext = SDL_GL_CreateContext(mWindow);
+ if(!mContext)
+ {
+ LL_WARNS() << "Cannot create GL context " << SDL_GetError() << LL_ENDL;
+ setupFailure("GL Context creation error", "Error", OSMB_OK);
+ return false;
+ }
- if (mFullscreen)
+ if (!SDL_GL_MakeCurrent(mWindow, mContext))
{
- LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL;
+ LL_WARNS() << "Failed to make context current. SDL: " << SDL_GetError() << LL_ENDL;
+ setupFailure("GL Context failed to set current failure", "Error", OSMB_OK);
+ return false;
+ }
- // If the requested width or height is 0, find the best default for the monitor.
- if((width == 0) || (height == 0))
+ const SDL_DisplayMode* displayMode = SDL_GetCurrentDisplayMode(SDL_GetDisplayForWindow(mWindow));
+ if(displayMode)
+ {
+ mRefreshRate = ll_round(displayMode->refresh_rate);
+ mNativeAspectRatio = ((F32)displayMode->w) / ((F32)displayMode->h);
+ if(mFullscreen)
{
- // Scan through the list of modes, looking for one which has:
- // height between 700 and 800
- // aspect ratio closest to the user's original mode
- S32 resolutionCount = 0;
- LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount);
-
- if(resolutionList != NULL)
- {
- F32 closestAspect = 0;
- U32 closestHeight = 0;
- U32 closestWidth = 0;
- int i;
-
- LL_INFOS() << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL;
+ mFullscreenWidth = displayMode->w;
+ mFullscreenHeight = displayMode->h;
+ mFullscreenRefresh = ll_round(displayMode->refresh_rate);
- for(i=0; i < resolutionCount; i++)
- {
- F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight;
-
- LL_INFOS() << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL;
-
- if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) &&
- (fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio)))
- {
- LL_INFOS() << " (new closest mode) " << LL_ENDL;
-
- // This is the closest mode we've seen yet.
- closestWidth = resolutionList[i].mWidth;
- closestHeight = resolutionList[i].mHeight;
- closestAspect = aspect;
- }
- }
-
- width = closestWidth;
- height = closestHeight;
- }
+ LL_INFOS() << "Running at " << mFullscreenWidth
+ << "x" << mFullscreenHeight
+ << " @ " << mFullscreenRefresh
+ << LL_ENDL;
}
-
- if((width == 0) || (height == 0))
+ }
+ else
+ {
+ LL_WARNS() << "Failed to get current display mode and refresh rate" << LL_ENDL;
+ mRefreshRate = 0;
+ mNativeAspectRatio = 1024.f / 768.f;
+ if(mFullscreen) // Fallback to window size
{
- // Mode search failed for some reason. Use the old-school default.
- width = 1024;
- height = 768;
+ SDL_GetWindowSize(mWindow, &mFullscreenWidth, &mFullscreenHeight);
+ mFullscreenRefresh = -1;
}
+ }
- mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN);
- if (!mWindow && bits > 16)
- {
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
- mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN);
- }
+ if(mRefreshRate == 0) // We failed to get a valid refresh rate above
+ {
+ mRefreshRate = DEFAULT_REFRESH_RATE;
+ }
- if (mWindow)
- {
- mFullscreen = true;
- mFullscreenWidth = mWindow->w;
- mFullscreenHeight = mWindow->h;
- mFullscreenBits = mWindow->format->BitsPerPixel;
- mFullscreenRefresh = -1;
+ /* Grab the window manager specific information */
+#if LL_LINUX
+ if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0)
+ {
+ LL_INFOS() << "Running under X11" << LL_ENDL;
+ mServerProtocol = X11;
- LL_INFOS() << "Running at " << mFullscreenWidth
- << "x" << mFullscreenHeight
- << "x" << mFullscreenBits
- << " @ " << mFullscreenRefresh
- << LL_ENDL;
- }
- else
+ gGLManager.mIsX11 = true;
+
+#if LL_X11
+ sX11Data.xdisplay = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr);
+ sX11Data.xwindow = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
+ sX11Data.xscreen = (int)SDL_GetNumberProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_X11_SCREEN_NUMBER, -1);
+ if (sX11Data.xdisplay && sX11Data.xwindow)
{
- LL_WARNS() << "createContext: fullscreen creation failure. SDL: " << SDL_GetError() << LL_ENDL;
- // No fullscreen support
- mFullscreen = false;
- mFullscreenWidth = -1;
- mFullscreenHeight = -1;
- mFullscreenBits = -1;
- mFullscreenRefresh = -1;
- std::string error = llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height);
- OSMessageBox(error, "Error", OSMB_OK);
}
- }
+#endif
- if(!mFullscreen && (mWindow == NULL))
+ gGLManager.initGLX();
+ }
+ else if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0)
{
- if (width == 0)
- width = 1024;
- if (height == 0)
- width = 768;
+ LL_INFOS() << "Running under Wayland" << LL_ENDL;
+ mServerProtocol = Wayland;
- LL_INFOS() << "createContext: creating window " << width << "x" << height << "x" << bits << LL_ENDL;
- mWindow = SDL_SetVideoMode(width, height, bits, sdlflags);
- if (!mWindow && bits > 16)
- {
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
- mWindow = SDL_SetVideoMode(width, height, bits, sdlflags);
- }
+ gGLManager.mIsWayland = true;
- if (!mWindow)
+#if LL_WAYLAND
+ sWaylandData.display = (struct wl_display *)SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nullptr);
+ sWaylandData.surface = (struct wl_surface *)SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr);
+ if (sWaylandData.display && sWaylandData.surface)
{
- LL_WARNS() << "createContext: window creation failure. SDL: " << SDL_GetError() << LL_ENDL;
- setupFailure("Window creation error", "Error", OSMB_OK);
- return false;
}
- } else if (!mFullscreen && (mWindow != NULL))
- {
- LL_INFOS() << "createContext: SKIPPING - !fullscreen, but +mWindow " << width << "x" << height << "x" << bits << LL_ENDL;
- }
+#endif
- // Detect video memory size.
-# if LL_X11
- gGLManager.mVRAM = x11_detect_VRAM_kb() / 1024;
- if (gGLManager.mVRAM != 0)
- {
- LL_INFOS() << "X11 log-parser detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL;
- } else
-# endif // LL_X11
- {
- // fallback to letting SDL detect VRAM.
- // note: I've not seen SDL's detection ever actually find
- // VRAM != 0, but if SDL *does* detect it then that's a bonus.
- gGLManager.mVRAM = video_info->video_mem / 1024;
- if (gGLManager.mVRAM != 0)
+ gGLManager.initEGL();
+
+ // If set (XWayland) remove DISPLAY, this will prompt dullahan to also use Wayland
+ if(getenv("DISPLAY"))
{
- LL_INFOS() << "SDL detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL;
+ unsetenv("DISPLAY");
}
}
- // If VRAM is not detected, that is handled later
-
- // *TODO: Now would be an appropriate time to check for some
- // explicitly unsupported cards.
- //const char* RENDERER = (const char*) glGetString(GL_RENDERER);
-
- GLint depthBits, stencilBits, redBits, greenBits, blueBits, alphaBits;
+#endif
- glGetIntegerv(GL_RED_BITS, &redBits);
- glGetIntegerv(GL_GREEN_BITS, &greenBits);
- glGetIntegerv(GL_BLUE_BITS, &blueBits);
- glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
- glGetIntegerv(GL_DEPTH_BITS, &depthBits);
- glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
+ SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits);
+ SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits);
+ SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits);
+ SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alphaBits);
+ SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depthBits);
+ SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencilBits);
LL_INFOS() << "GL buffer:" << LL_ENDL;
- LL_INFOS() << " Red Bits " << S32(redBits) << LL_ENDL;
- LL_INFOS() << " Green Bits " << S32(greenBits) << LL_ENDL;
- LL_INFOS() << " Blue Bits " << S32(blueBits) << LL_ENDL;
- LL_INFOS() << " Alpha Bits " << S32(alphaBits) << LL_ENDL;
- LL_INFOS() << " Depth Bits " << S32(depthBits) << LL_ENDL;
- LL_INFOS() << " Stencil Bits " << S32(stencilBits) << LL_ENDL;
+ LL_INFOS() << " Red Bits " << S32(redBits) << LL_ENDL;
+ LL_INFOS() << " Green Bits " << S32(greenBits) << LL_ENDL;
+ LL_INFOS() << " Blue Bits " << S32(blueBits) << LL_ENDL;
+ LL_INFOS() << " Alpha Bits " << S32(alphaBits) << LL_ENDL;
+ LL_INFOS() << " Depth Bits " << S32(depthBits) << LL_ENDL;
+ LL_INFOS() << " Stencil Bits " << S32(stencilBits) << LL_ENDL;
GLint colorBits = redBits + greenBits + blueBits + alphaBits;
- // fixme: actually, it's REALLY important for picking that we get at
- // least 8 bits each of red,green,blue. Alpha we can be a bit more
- // relaxed about if we have to.
if (colorBits < 32)
{
- close();
setupFailure(
- "Second Life requires True Color (32-bit) to run in a window.\n"
- "Please go to Control Panels -> Display -> Settings and\n"
- "set the screen to 32-bit color.\n"
- "Alternately, if you choose to run fullscreen, Second Life\n"
- "will automatically adjust the screen each time it runs.",
- "Error",
- OSMB_OK);
+ "Second Life requires True Color (32-bit) to run in a window.\n"
+ "Please go to Control Panels -> Display -> Settings and\n"
+ "set the screen to 32-bit color.\n"
+ "Alternately, if you choose to run fullscreen, Second Life\n"
+ "will automatically adjust the screen each time it runs.",
+ "Error",
+ OSMB_OK);
return false;
}
-#if 0 // *FIX: we're going to brave it for now...
- if (alphaBits < 8)
+ LL_PROFILER_GPU_CONTEXT;
+
+ // Enable vertical sync
+ toggleVSync(enable_vsync);
+
+#if LL_DARWIN
+ setUseMultGL(sUseMultGL);
+
+ // Get vram via CGL on macos
+ gGLManager.mVRAM = getVramSize();
+#endif
+
+ // Set the application icon.
+ SDL_Surface* bmpsurface = Load_BMP_Resource("ll_icon.BMP");
+ if (bmpsurface)
{
- close();
- setupFailure(
- "Second Life is unable to run because it can't get an 8 bit alpha\n"
- "channel. Usually this is due to video card driver issues.\n"
- "Please make sure you have the latest video card drivers installed.\n"
- "Also be sure your monitor is set to True Color (32-bit) in\n"
- "Control Panels -> Display -> Settings.\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
- return false;
+ SDL_SetWindowIcon(mWindow, bmpsurface);
+ SDL_DestroySurface(bmpsurface);
+ bmpsurface = nullptr;
}
-#endif
-#if LL_X11
- /* Grab the window manager specific information */
- SDL_SysWMinfo info;
- SDL_VERSION(&info.version);
- if ( SDL_GetWMInfo(&info) )
+ SDL_StartTextInput(mWindow);
+ return true;
+}
+
+void* LLWindowSDL::createSharedContext()
+{
+ SDL_PropertiesID props = SDL_CreateProperties();
+ SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, "Second Life OSR Utility");
+ SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, 1);
+ SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, 1);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, false);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIDDEN_BOOLEAN, true);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN, false);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_UTILITY_BOOLEAN, true);
+ SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, gHiDPISupport);
+
+ auto osr_window = SDL_CreateWindowWithProperties(props);
+ if (osr_window == nullptr)
{
- /* Save the information for later use */
- if ( info.subsystem == SDL_SYSWM_X11 )
- {
- mSDL_Display = info.info.x11.display;
- mSDL_XWindowID = info.info.x11.wmwindow;
- Lock_Display = info.info.x11.lock_func;
- Unlock_Display = info.info.x11.unlock_func;
- }
- else
- {
- LL_WARNS() << "We're not running under X11? Wild."
- << LL_ENDL;
- }
+ SDL_DestroyProperties(props);
+ return nullptr;
}
- else
+ SDL_DestroyProperties(props); // Free properties once window is created
+ SDL_GLContext pContext = SDL_GL_CreateContext(osr_window);
+
+ // Hack to ensure main window context is bound
+ SDL_GL_MakeCurrent(mWindow, mContext);
+
+ if (!pContext)
{
- LL_WARNS() << "We're not running under any known WM. Wild."
- << LL_ENDL;
+ LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL;
+ SDL_DestroyWindow(osr_window);
+ return nullptr;
}
-#endif // LL_X11
+ {
+ LLMutexLock osr_lock(&mOSRMutex);
+ mOSRContexts.emplace(pContext, osr_window);
+ }
- //make sure multisampling is disabled by default
- glDisable(GL_MULTISAMPLE_ARB);
+ LL_DEBUGS() << "Creating shared OpenGL context successful!" << LL_ENDL;
+ return (void*)pContext;
+}
- // We need to do this here, once video is init'd
- if (-1 == SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,
- SDL_DEFAULT_REPEAT_INTERVAL))
- LL_WARNS() << "Couldn't enable key-repeat: " << SDL_GetError() <<LL_ENDL;
+void LLWindowSDL::makeContextCurrent(void* contextPtr)
+{
+ LLMutexLock osr_lock(&mOSRMutex);
+ auto it = mOSRContexts.find((SDL_GLContext)contextPtr);
+ if(it != mOSRContexts.end())
+ {
+ SDL_GL_MakeCurrent((SDL_Window*)it->second, (SDL_GLContext)it->first);
+ }
+ LL_PROFILER_GPU_CONTEXT;
+}
- // Don't need to get the current gamma, since there's a call that restores it to the system defaults.
- return true;
+void LLWindowSDL::destroySharedContext(void* contextPtr)
+{
+ LLMutexLock osr_lock(&mOSRMutex);
+ auto it = mOSRContexts.find((SDL_GLContext)contextPtr);
+ if(it != mOSRContexts.end())
+ {
+ SDL_GL_DestroyContext((SDL_GLContext)it->first);
+ mDeadOSRWindows.push_back((SDL_Window*)it->second);
+ }
}
+void LLWindowSDL::toggleVSync(bool enable_vsync)
+{
+ if (!enable_vsync)
+ {
+ LL_INFOS("Window") << "Disabling vertical sync" << LL_ENDL;
+ SDL_GL_SetSwapInterval(0);
+ }
+ else
+ {
+ LL_INFOS("Window") << "Enabling vertical sync" << LL_ENDL;
+ SDL_GL_SetSwapInterval(1);
+ }
+}
// changing fullscreen resolution, or switching between windowed and fullscreen mode.
-bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, const LLCoordScreen * const posp)
+bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool enable_vsync, const LLCoordScreen * const posp)
{
const bool needsRebuild = true; // Just nuke the context and start over.
bool result = true;
@@ -741,9 +515,10 @@ bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool
if(needsRebuild)
{
destroyContext();
- result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync);
+ result = createContext(0, 0, size.mX, size.mY, 32, fullscreen, enable_vsync);
if (result)
{
+ gGLManager.initWGL();
gGLManager.initGL();
//start with arrow cursor
@@ -761,69 +536,96 @@ void LLWindowSDL::destroyContext()
{
LL_INFOS() << "destroyContext begins" << LL_ENDL;
-#if LL_X11
- mSDL_Display = NULL;
- mSDL_XWindowID = None;
- Lock_Display = NULL;
- Unlock_Display = NULL;
-#endif // LL_X11
+ {
+ LLMutexLock osr_lock(&mOSRMutex);
+ for(SDL_Window* pWindow : mDeadOSRWindows)
+ {
+ SDL_DestroyWindow(pWindow);
+ }
+ mDeadOSRWindows.clear();
+ }
+
+ // Stop unicode input
+ SDL_StopTextInput(mWindow);
// Clean up remaining GL state before blowing away window
LL_INFOS() << "shutdownGL begins" << LL_ENDL;
gGLManager.shutdownGL();
- LL_INFOS() << "SDL_QuitSS/VID begins" << LL_ENDL;
- SDL_QuitSubSystem(SDL_INIT_VIDEO); // *FIX: this might be risky...
- mWindow = NULL;
+ LL_INFOS() << "Destroying SDL cursors" << LL_ENDL;
+ quitCursors();
+
+ if (mContext)
+ {
+ LL_INFOS() << "Destroying SDL GL Context" << LL_ENDL;
+ SDL_GL_DestroyContext(mContext);
+ mContext = nullptr;
+ }
+ else
+ {
+ LL_INFOS() << "SDL GL Context already destroyed" << LL_ENDL;
+ }
+
+ if (mWindow)
+ {
+ LL_INFOS() << "Destroying SDL Window" << LL_ENDL;
+ SDL_DestroyWindow(mWindow);
+ mWindow = nullptr;
+ }
+ else
+ {
+ LL_INFOS() << "SDL Window already destroyed" << LL_ENDL;
+ }
+ LL_INFOS() << "destroyContext end" << LL_ENDL;
}
LLWindowSDL::~LLWindowSDL()
{
- quitCursors();
destroyContext();
- if(mSupportedResolutions != NULL)
- {
- delete []mSupportedResolutions;
- }
+ delete[] mSupportedResolutions;
- gWindowImplementation = NULL;
+ gWindowImplementation = nullptr;
}
void LLWindowSDL::show()
{
- // *FIX: What to do with SDL?
+ if (mWindow)
+ {
+ SDL_ShowWindow(mWindow);
+ SDL_RaiseWindow(mWindow);
+ }
}
void LLWindowSDL::hide()
{
- // *FIX: What to do with SDL?
+ if (mWindow)
+ {
+ SDL_HideWindow(mWindow);
+ }
}
-//virtual
void LLWindowSDL::minimize()
{
- // *FIX: What to do with SDL?
+ if (mWindow)
+ {
+ SDL_MinimizeWindow(mWindow);
+ }
}
-//virtual
void LLWindowSDL::restore()
{
- // *FIX: What to do with SDL?
+ if (mWindow)
+ {
+ SDL_RestoreWindow(mWindow);
+ }
}
-
// close() destroys all OS-specific code associated with a window.
// Usually called from LLWindowManager::destroyWindow()
void LLWindowSDL::close()
{
- // Is window is already closed?
- // if (!mWindow)
- // {
- // return;
- // }
-
// Make sure cursor is visible and we haven't mangled the clipping state.
setMouseClipping(false);
showCursor();
@@ -833,134 +635,127 @@ void LLWindowSDL::close()
bool LLWindowSDL::isValid()
{
- return (mWindow != NULL);
+ return mWindow != nullptr;
}
bool LLWindowSDL::getVisible()
{
- bool result = false;
-
- // *FIX: This isn't really right...
- // Then what is?
+ bool result = true;
if (mWindow)
{
- result = true;
+ SDL_WindowFlags flags = SDL_GetWindowFlags(mWindow);
+ if (flags & SDL_WINDOW_HIDDEN)
+ {
+ result = false;
+ }
}
-
- return(result);
+ return result;
}
bool LLWindowSDL::getMinimized()
{
bool result = false;
-
- if (mWindow && (1 == mIsMinimized))
+ if (mWindow)
{
- result = true;
+ SDL_WindowFlags flags = SDL_GetWindowFlags(mWindow);
+ if (flags & SDL_WINDOW_MINIMIZED)
+ {
+ result = true;
+ }
}
- return(result);
+ return result;
}
bool LLWindowSDL::getMaximized()
{
bool result = false;
-
if (mWindow)
{
- // TODO
+ SDL_WindowFlags flags = SDL_GetWindowFlags(mWindow);
+ if (flags & SDL_WINDOW_MAXIMIZED)
+ {
+ result = true;
+ }
}
- return(result);
+ return result;
}
bool LLWindowSDL::maximize()
{
- // TODO
+ if (mWindow)
+ {
+ SDL_MaximizeWindow(mWindow);
+ return true;
+ }
return false;
}
-bool LLWindowSDL::getFullscreen()
-{
- return mFullscreen;
-}
-
bool LLWindowSDL::getPosition(LLCoordScreen *position)
{
- // *FIX: can anything be done with this?
- position->mX = 0;
- position->mY = 0;
- return true;
+ if (mWindow)
+ {
+ SDL_GetWindowPosition(mWindow, &position->mX, &position->mY);
+ return true;
+ }
+ return false;
}
bool LLWindowSDL::getSize(LLCoordScreen *size)
{
if (mWindow)
{
- size->mX = mWindow->w;
- size->mY = mWindow->h;
- return (true);
+ SDL_GetWindowSize(mWindow, &size->mX, &size->mY);
+ return true;
}
- return (false);
+ return false;
}
bool LLWindowSDL::getSize(LLCoordWindow *size)
{
if (mWindow)
{
- size->mX = mWindow->w;
- size->mY = mWindow->h;
- return (true);
+ SDL_GetWindowSizeInPixels(mWindow, &size->mX, &size->mY);
+ return true;
}
- return (false);
+ return false;
}
bool LLWindowSDL::setPosition(const LLCoordScreen position)
{
- if(mWindow)
+ if (mWindow)
{
- // *FIX: (?)
- //MacMoveWindow(mWindow, position.mX, position.mY, false);
+ SDL_SetWindowPosition(mWindow, position.mX, position.mY);
+ return true;
}
- return true;
+ return false;
}
-bool LLWindowSDL::setSizeImpl(const LLCoordScreen size)
+template< typename T > bool setSizeImpl( const T& newSize, SDL_Window *pWin )
{
- if(mWindow)
- {
- // Push a resize event onto SDL's queue - we'll handle it
- // when it comes out again.
- SDL_Event event;
- event.type = SDL_VIDEORESIZE;
- event.resize.w = size.mX;
- event.resize.h = size.mY;
- SDL_PushEvent(&event); // copied into queue
+ if( !pWin )
+ return false;
- return true;
- }
+ SDL_WindowFlags winFlags = SDL_GetWindowFlags(pWin);
- return false;
+ if( winFlags & SDL_WINDOW_MAXIMIZED)
+ SDL_RestoreWindow(pWin);
+
+ SDL_SetWindowSize(pWin, newSize.mX, newSize.mY);
+ return true;
}
-bool LLWindowSDL::setSizeImpl(const LLCoordWindow size)
+bool LLWindowSDL::setSizeImpl(const LLCoordScreen size)
{
- if(mWindow)
- {
- // Push a resize event onto SDL's queue - we'll handle it
- // when it comes out again.
- SDL_Event event;
- event.type = SDL_VIDEORESIZE;
- event.resize.w = size.mX;
- event.resize.h = size.mY;
- SDL_PushEvent(&event); // copied into queue
-
- return true;
- }
+ return ::setSizeImpl( size, mWindow );
+}
- return false;
+bool LLWindowSDL::setSizeImpl(const LLCoordWindow size)
+{
+ return ::setSizeImpl( size, mWindow );
}
@@ -968,8 +763,9 @@ void LLWindowSDL::swapBuffers()
{
if (mWindow)
{
- SDL_GL_SwapBuffers();
+ SDL_GL_SwapWindow(mWindow);
}
+ LL_PROFILER_GPU_COLLECT;
}
U32 LLWindowSDL::getFSAASamples()
@@ -984,22 +780,23 @@ void LLWindowSDL::setFSAASamples(const U32 samples)
F32 LLWindowSDL::getGamma()
{
- return 1/mGamma;
+ return 1.f / mGamma;
}
bool LLWindowSDL::restoreGamma()
{
- //CGDisplayRestoreColorSyncSettings();
- SDL_SetGamma(1.0f, 1.0f, 1.0f);
return true;
}
bool LLWindowSDL::setGamma(const F32 gamma)
{
- mGamma = gamma;
- if (mGamma == 0) mGamma = 0.1f;
- mGamma = 1/mGamma;
- SDL_SetGamma(mGamma, mGamma, mGamma);
+ if (mWindow)
+ {
+ mGamma = gamma;
+ if (mGamma == 0)
+ mGamma = 0.1f;
+ mGamma = 1.f / mGamma;
+ }
return true;
}
@@ -1008,12 +805,13 @@ bool LLWindowSDL::isCursorHidden()
return mCursorHidden;
}
-
-
// Constrains the mouse to the window.
-void LLWindowSDL::setMouseClipping( bool b )
+void LLWindowSDL::setMouseClipping(bool b)
{
- //SDL_WM_GrabInput(b ? SDL_GRAB_ON : SDL_GRAB_OFF);
+ if (mWindow)
+ {
+ SDL_SetWindowMouseGrab(mWindow, b);
+ }
}
// virtual
@@ -1021,38 +819,16 @@ void LLWindowSDL::setMinSize(U32 min_width, U32 min_height, bool enforce_immedia
{
LLWindow::setMinSize(min_width, min_height, enforce_immediately);
-#if LL_X11
- // Set the minimum size limits for X11 window
- // so the window manager doesn't allow resizing below those limits.
- XSizeHints* hints = XAllocSizeHints();
- hints->flags |= PMinSize;
- hints->min_width = mMinWindowWidth;
- hints->min_height = mMinWindowHeight;
-
- XSetWMNormalHints(mSDL_Display, mSDL_XWindowID, hints);
-
- XFree(hints);
-#endif
+ if (mWindow && min_width > 0 && min_height > 0)
+ {
+ SDL_SetWindowMinimumSize(mWindow, mMinWindowWidth, mMinWindowHeight);
+ }
}
bool LLWindowSDL::setCursorPosition(const LLCoordWindow position)
{
- bool result = true;
- LLCoordScreen screen_pos;
-
- if (!convertCoords(position, &screen_pos))
- {
- return false;
- }
-
- //LL_INFOS() << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << LL_ENDL;
-
- // do the actual forced cursor move.
- SDL_WarpMouse(screen_pos.mX, screen_pos.mY);
-
- //LL_INFOS() << llformat("llcw %d,%d -> scr %d,%d", position.mX, position.mY, screen_pos.mX, screen_pos.mY) << LL_ENDL;
-
- return result;
+ SDL_WarpMouseInWindow(mWindow, (F32)position.mX, (F32)position.mY);
+ return true;
}
bool LLWindowSDL::getCursorPosition(LLCoordWindow *position)
@@ -1060,54 +836,34 @@ bool LLWindowSDL::getCursorPosition(LLCoordWindow *position)
//Point cursor_point;
LLCoordScreen screen_pos;
- //GetMouse(&cursor_point);
- int x, y;
+ float x, y;
SDL_GetMouseState(&x, &y);
- screen_pos.mX = x;
- screen_pos.mY = y;
+ screen_pos.mX = (S32)x;
+ screen_pos.mY = (S32)y;
return convertCoords(screen_pos, position);
}
-
F32 LLWindowSDL::getNativeAspectRatio()
{
-#if 0
+ if (mOverrideAspectRatio > 0.f)
+ {
+ return mOverrideAspectRatio;
+ }
+ else if (mNativeAspectRatio > 0.f)
+ {
+ // we grabbed this value at startup, based on the user's desktop settings
+ return mNativeAspectRatio;
+ }
+
// RN: this hack presumes that the largest supported resolution is monitor-limited
// and that pixels in that mode are square, therefore defining the native aspect ratio
// of the monitor...this seems to work to a close approximation for most CRTs/LCDs
S32 num_resolutions;
LLWindowResolution* resolutions = getSupportedResolutions(num_resolutions);
-
return ((F32)resolutions[num_resolutions - 1].mWidth / (F32)resolutions[num_resolutions - 1].mHeight);
- //rn: AC
-#endif
-
- // MBW -- there are a couple of bad assumptions here. One is that the display list won't include
- // ridiculous resolutions nobody would ever use. The other is that the list is in order.
-
- // New assumptions:
- // - pixels are square (the only reasonable choice, really)
- // - The user runs their display at a native resolution, so the resolution of the display
- // when the app is launched has an aspect ratio that matches the monitor.
-
- //RN: actually, the assumption that there are no ridiculous resolutions (above the display's native capabilities) has
- // been born out in my experience.
- // Pixels are often not square (just ask the people who run their LCDs at 1024x768 or 800x600 when running fullscreen, like me)
- // The ordering of display list is a blind assumption though, so we should check for max values
- // Things might be different on the Mac though, so I'll defer to MBW
-
- // The constructor for this class grabs the aspect ratio of the monitor before doing any resolution
- // switching, and stashes it in mOriginalAspectRatio. Here, we just return it.
-
- if (mOverrideAspectRatio > 0.f)
- {
- return mOverrideAspectRatio;
- }
-
- return mOriginalAspectRatio;
}
F32 LLWindowSDL::getPixelAspectRatio()
@@ -1130,104 +886,26 @@ F32 LLWindowSDL::getPixelAspectRatio()
// dialogs are still usable in fullscreen.
void LLWindowSDL::beforeDialog()
{
- bool running_x11 = false;
-#if LL_X11
- running_x11 = (mSDL_XWindowID != None);
-#endif //LL_X11
-
LL_INFOS() << "LLWindowSDL::beforeDialog()" << LL_ENDL;
if (SDLReallyCaptureInput(false)) // must ungrab input so popup works!
{
- if (mFullscreen)
- {
- // need to temporarily go non-fullscreen; bless SDL
- // for providing a SDL_WM_ToggleFullScreen() - though
- // it only works in X11
- if (running_x11 && mWindow)
- {
- SDL_WM_ToggleFullScreen(mWindow);
- }
- }
- }
-
-#if LL_X11
- if (mSDL_Display)
- {
- // Everything that we/SDL asked for should happen before we
- // potentially hand control over to GTK.
- maybe_lock_display();
- XSync(mSDL_Display, False);
- maybe_unlock_display();
+ if (mFullscreen && mWindow )
+ SDL_SetWindowFullscreen( mWindow, 0 );
}
-#endif // LL_X11
-
-#if LL_GTK
- // this is a good time to grab some GTK version information for
- // diagnostics, if not already done.
- ll_try_gtk_init();
-#endif // LL_GTK
-
- maybe_lock_display();
}
void LLWindowSDL::afterDialog()
{
- bool running_x11 = false;
-#if LL_X11
- running_x11 = (mSDL_XWindowID != None);
-#endif //LL_X11
-
LL_INFOS() << "LLWindowSDL::afterDialog()" << LL_ENDL;
- maybe_unlock_display();
-
- if (mFullscreen)
- {
- // need to restore fullscreen mode after dialog - only works
- // in X11
- if (running_x11 && mWindow)
- {
- SDL_WM_ToggleFullScreen(mWindow);
- }
- }
+ if (mFullscreen && mWindow )
+ SDL_SetWindowFullscreen( mWindow, 0 );
}
-
-#if LL_X11
-// set/reset the XWMHints flag for 'urgency' that usually makes the icon flash
-void LLWindowSDL::x11_set_urgent(bool urgent)
-{
- if (mSDL_Display && !mFullscreen)
- {
- XWMHints *wm_hints;
-
- LL_INFOS() << "X11 hint for urgency, " << urgent << LL_ENDL;
-
- maybe_lock_display();
- wm_hints = XGetWMHints(mSDL_Display, mSDL_XWindowID);
- if (!wm_hints)
- wm_hints = XAllocWMHints();
-
- if (urgent)
- wm_hints->flags |= XUrgencyHint;
- else
- wm_hints->flags &= ~XUrgencyHint;
-
- XSetWMHints(mSDL_Display, mSDL_XWindowID, wm_hints);
- XFree(wm_hints);
- XSync(mSDL_Display, False);
- maybe_unlock_display();
- }
-}
-#endif // LL_X11
-
void LLWindowSDL::flashIcon(F32 seconds)
{
-#if !LL_X11
- LL_INFOS() << "Stub LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL;
-#else
- LL_INFOS() << "X11 LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL;
+ LL_INFOS() << "LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL;
F32 remaining_time = mFlashTimer.getRemainingTimeF32();
if (remaining_time < seconds)
@@ -1235,132 +913,71 @@ void LLWindowSDL::flashIcon(F32 seconds)
mFlashTimer.reset();
mFlashTimer.setTimerExpirySec(remaining_time);
- x11_set_urgent(true);
+ SDL_FlashWindow(mWindow, SDL_FLASH_UNTIL_FOCUSED);
mFlashing = true;
-#endif // LL_X11
}
-
-#if LL_GTK
-bool LLWindowSDL::isClipboardTextAvailable()
+void LLWindowSDL::maybeStopFlashIcon()
{
- if (ll_try_gtk_init())
+ if (mFlashing && mFlashTimer.hasExpired())
{
- GtkClipboard * const clipboard =
- gtk_clipboard_get(GDK_NONE);
- return gtk_clipboard_wait_is_text_available(clipboard) ?
- true : false;
+ mFlashing = false;
+ SDL_FlashWindow( mWindow, SDL_FLASH_CANCEL );
}
- return false; // failure
}
-bool LLWindowSDL::pasteTextFromClipboard(LLWString &text)
+bool LLWindowSDL::isClipboardTextAvailable()
{
- if (ll_try_gtk_init())
+ return SDL_HasClipboardText();
+}
+
+bool LLWindowSDL::pasteTextFromClipboard(LLWString &dst)
+{
+ if (isClipboardTextAvailable())
{
- GtkClipboard * const clipboard =
- gtk_clipboard_get(GDK_NONE);
- gchar * const data = gtk_clipboard_wait_for_text(clipboard);
+ char* data = SDL_GetClipboardText();
if (data)
{
- text = LLWString(utf8str_to_wstring(data));
- g_free(data);
+ dst = LLWString(utf8str_to_wstring(data));
+ SDL_free(data);
return true;
}
}
- return false; // failure
+ return false;
}
-bool LLWindowSDL::copyTextToClipboard(const LLWString &text)
+bool LLWindowSDL::copyTextToClipboard(const LLWString& text)
{
- if (ll_try_gtk_init())
- {
- const std::string utf8 = wstring_to_utf8str(text);
- GtkClipboard * const clipboard =
- gtk_clipboard_get(GDK_NONE);
- gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length());
- return true;
- }
- return false; // failure
+ const std::string utf8 = wstring_to_utf8str(text);
+ return SDL_SetClipboardText(utf8.c_str());
}
-
bool LLWindowSDL::isPrimaryTextAvailable()
{
- if (ll_try_gtk_init())
- {
- GtkClipboard * const clipboard =
- gtk_clipboard_get(GDK_SELECTION_PRIMARY);
- return gtk_clipboard_wait_is_text_available(clipboard) ?
- true : false;
- }
- return false; // failure
+ return SDL_HasPrimarySelectionText();
}
-bool LLWindowSDL::pasteTextFromPrimary(LLWString &text)
+bool LLWindowSDL::pasteTextFromPrimary(LLWString &dst)
{
- if (ll_try_gtk_init())
+ if (isPrimaryTextAvailable())
{
- GtkClipboard * const clipboard =
- gtk_clipboard_get(GDK_SELECTION_PRIMARY);
- gchar * const data = gtk_clipboard_wait_for_text(clipboard);
+ char* data = SDL_GetPrimarySelectionText();
if (data)
{
- text = LLWString(utf8str_to_wstring(data));
- g_free(data);
+ dst = LLWString(utf8str_to_wstring(data));
+ SDL_free(data);
return true;
}
}
- return false; // failure
-}
-
-bool LLWindowSDL::copyTextToPrimary(const LLWString &text)
-{
- if (ll_try_gtk_init())
- {
- const std::string utf8 = wstring_to_utf8str(text);
- GtkClipboard * const clipboard =
- gtk_clipboard_get(GDK_SELECTION_PRIMARY);
- gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length());
- return true;
- }
- return false; // failure
-}
-
-#else
-
-bool LLWindowSDL::isClipboardTextAvailable()
-{
- return false; // unsupported
-}
-
-bool LLWindowSDL::pasteTextFromClipboard(LLWString &dst)
-{
- return false; // unsupported
-}
-
-bool LLWindowSDL::copyTextToClipboard(const LLWString &s)
-{
- return false; // unsupported
-}
-
-bool LLWindowSDL::isPrimaryTextAvailable()
-{
- return false; // unsupported
-}
-
-bool LLWindowSDL::pasteTextFromPrimary(LLWString &dst)
-{
- return false; // unsupported
+ return false;
}
-bool LLWindowSDL::copyTextToPrimary(const LLWString &s)
+bool LLWindowSDL::copyTextToPrimary(const LLWString& text)
{
- return false; // unsupported
+ const std::string utf8 = wstring_to_utf8str(text);
+ return SDL_SetPrimarySelectionText(utf8.c_str());
}
-#endif // LL_GTK
-
LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_resolutions)
{
if (!mSupportedResolutions)
@@ -1368,28 +985,21 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso
mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS];
mNumSupportedResolutions = 0;
- SDL_Rect **modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
- if ( (modes != NULL) && (modes != ((SDL_Rect **) -1)) )
- {
- int count = 0;
- while (*modes && count<MAX_NUM_RESOLUTIONS) // they're sorted biggest to smallest, so find end...
- {
- modes++;
- count++;
- }
-
- while (count--)
- {
- modes--;
- SDL_Rect *r = *modes;
- int w = r->w;
- int h = r->h;
+ SDL_DisplayID display = SDL_GetPrimaryDisplay();
+ int num_modes = 0;
+ SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(display, &num_modes);
+ num_modes = llclamp(num_modes, 0, MAX_NUM_RESOLUTIONS);
+ if (modes) {
+ for (int i = 0; i < num_modes; ++i) {
+ SDL_DisplayMode *mode = modes[i];
+ int w = mode->w;
+ int h = mode->h;
if ((w >= 800) && (h >= 600))
{
// make sure we don't add the same resolution multiple times!
if ( (mNumSupportedResolutions == 0) ||
- ((mSupportedResolutions[mNumSupportedResolutions-1].mWidth != w) &&
- (mSupportedResolutions[mNumSupportedResolutions-1].mHeight != h)) )
+ ((mSupportedResolutions[mNumSupportedResolutions-1].mWidth != w) &&
+ (mSupportedResolutions[mNumSupportedResolutions-1].mHeight != h)) )
{
mSupportedResolutions[mNumSupportedResolutions].mWidth = w;
mSupportedResolutions[mNumSupportedResolutions].mHeight = h;
@@ -1397,6 +1007,7 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso
}
}
}
+ SDL_free(modes);
}
}
@@ -1404,13 +1015,42 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso
return mSupportedResolutions;
}
+//static
+std::vector<std::string> LLWindowSDL::getDisplaysResolutionList()
+{
+ std::vector<std::string> ret;
+ if (gWindowImplementation)
+ {
+ S32 resolutionCount = 0;
+ LLWindowResolution* resolutionList = gWindowImplementation->getSupportedResolutions(resolutionCount);
+ if (resolutionList != nullptr)
+ {
+ for (S32 i = 0; i < resolutionCount; i++)
+ {
+ const LLWindowResolution& resolution = resolutionList[i];
+ ret.push_back(std::to_string(resolution.mWidth) + "x" + std::to_string(resolution.mHeight));
+ }
+ }
+ }
+ return ret;
+}
+
+
bool LLWindowSDL::convertCoords(LLCoordGL from, LLCoordWindow *to)
{
if (!to)
return false;
- to->mX = from.mX;
- to->mY = mWindow->h - from.mY - 1;
+ if (!mWindow)
+ return false;
+
+ S32 height;
+ SDL_GetWindowSizeInPixels(mWindow, nullptr, &height);
+
+ float pixel_scale = SDL_GetWindowPixelDensity(mWindow);
+
+ to->mX = from.mX / pixel_scale;
+ to->mY = (height - from.mY - 1) / pixel_scale;
return true;
}
@@ -1420,8 +1060,15 @@ bool LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordGL* to)
if (!to)
return false;
- to->mX = from.mX;
- to->mY = mWindow->h - from.mY - 1;
+ if (!mWindow)
+ return false;
+ S32 height;
+ SDL_GetWindowSize(mWindow, nullptr, &height);
+
+ float pixel_scale = SDL_GetWindowPixelDensity(mWindow);
+
+ to->mX = from.mX * pixel_scale;
+ to->mY = (height - from.mY - 1) * pixel_scale;
return true;
}
@@ -1434,7 +1081,7 @@ bool LLWindowSDL::convertCoords(LLCoordScreen from, LLCoordWindow* to)
// In the fullscreen case, window and screen coordinates are the same.
to->mX = from.mX;
to->mY = from.mY;
- return (true);
+ return true;
}
bool LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordScreen *to)
@@ -1445,29 +1092,26 @@ bool LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordScreen *to)
// In the fullscreen case, window and screen coordinates are the same.
to->mX = from.mX;
to->mY = from.mY;
- return (true);
+ return true;
}
bool LLWindowSDL::convertCoords(LLCoordScreen from, LLCoordGL *to)
{
LLCoordWindow window_coord;
- return(convertCoords(from, &window_coord) && convertCoords(window_coord, to));
+ return convertCoords(from, &window_coord) && convertCoords(window_coord, to);
}
bool LLWindowSDL::convertCoords(LLCoordGL from, LLCoordScreen *to)
{
LLCoordWindow window_coord;
- return(convertCoords(from, &window_coord) && convertCoords(window_coord, to));
+ return convertCoords(from, &window_coord) && convertCoords(window_coord, to);
}
-
-
-
void LLWindowSDL::setupFailure(const std::string& text, const std::string& caption, U32 type)
{
- destroyContext();
+ close();
OSMessageBox(text, caption, type);
}
@@ -1482,13 +1126,13 @@ bool LLWindowSDL::SDLReallyCaptureInput(bool capture)
else
mReallyCapturedCount = 0;
- SDL_GrabMode wantmode, newmode;
+ bool wantGrab;
if (mReallyCapturedCount <= 0) // uncapture
{
- wantmode = SDL_GRAB_OFF;
+ wantGrab = false;
} else // capture
{
- wantmode = SDL_GRAB_ON;
+ wantGrab = true;
}
if (mReallyCapturedCount < 0) // yuck, imbalance.
@@ -1497,64 +1141,32 @@ bool LLWindowSDL::SDLReallyCaptureInput(bool capture)
LL_WARNS() << "ReallyCapture count was < 0" << LL_ENDL;
}
+ bool newGrab = wantGrab;
if (!mFullscreen) /* only bother if we're windowed anyway */
{
-#if LL_X11
- if (mSDL_Display)
+ int result;
+ if (wantGrab)
{
- /* we dirtily mix raw X11 with SDL so that our pointer
- isn't (as often) constrained to the limits of the
- window while grabbed, which feels nicer and
- hopefully eliminates some reported 'sticky pointer'
- problems. We use raw X11 instead of
- SDL_WM_GrabInput() because the latter constrains
- the pointer to the window and also steals all
- *keyboard* input from the window manager, which was
- frustrating users. */
- int result;
- if (wantmode == SDL_GRAB_ON)
- {
- //LL_INFOS() << "X11 POINTER GRABBY" << LL_ENDL;
- //newmode = SDL_WM_GrabInput(wantmode);
- maybe_lock_display();
- result = XGrabPointer(mSDL_Display, mSDL_XWindowID,
- True, 0, GrabModeAsync,
- GrabModeAsync,
- None, None, CurrentTime);
- maybe_unlock_display();
- if (GrabSuccess == result)
- newmode = SDL_GRAB_ON;
- else
- newmode = SDL_GRAB_OFF;
- } else if (wantmode == SDL_GRAB_OFF)
- {
- //LL_INFOS() << "X11 POINTER UNGRABBY" << LL_ENDL;
- newmode = SDL_GRAB_OFF;
- //newmode = SDL_WM_GrabInput(SDL_GRAB_OFF);
-
- maybe_lock_display();
- XUngrabPointer(mSDL_Display, CurrentTime);
- // Make sure the ungrab happens RIGHT NOW.
- XSync(mSDL_Display, False);
- maybe_unlock_display();
- } else
- {
- newmode = SDL_GRAB_QUERY; // neutral
- }
- } else // not actually running on X11, for some reason
- newmode = wantmode;
-#endif // LL_X11
- } else {
- // pretend we got what we wanted, when really we don't care.
- newmode = wantmode;
+ // LL_INFOS() << "X11 POINTER GRABBY" << LL_ENDL;
+ result = SDL_SetWindowMouseGrab(mWindow, true);
+ if (0 == result)
+ newGrab = true;
+ else
+ newGrab = false;
+ }
+ else
+ {
+ newGrab = false;
+ result = SDL_SetWindowMouseGrab(mWindow, false);
+ }
}
+ // pretend we got what we wanted, when really we don't care.
// return boolean success for whether we ended up in the desired state
- return (capture && SDL_GRAB_ON==newmode) ||
- (!capture && SDL_GRAB_OFF==newmode);
+ return capture == newGrab;
}
-U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey keysym, bool gain)
+U32 LLWindowSDL::SDLCheckGrabbyKeys(U32 keysym, bool gain)
{
/* part of the fix for SL-13243: Some popular window managers like
to totally eat alt-drag for the purposes of moving windows. We
@@ -1572,16 +1184,16 @@ U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey keysym, bool gain)
U32 mask = 0;
switch (keysym)
{
- case SDLK_LALT:
- mask = 1U << 0; break;
- case SDLK_RALT:
- mask = 1U << 1; break;
- case SDLK_LCTRL:
- mask = 1U << 2; break;
- case SDLK_RCTRL:
- mask = 1U << 3; break;
- default:
- break;
+ case SDLK_LALT:
+ mask = 1U << 0; break;
+ case SDLK_RALT:
+ mask = 1U << 1; break;
+ case SDLK_LCTRL:
+ mask = 1U << 2; break;
+ case SDLK_RCTRL:
+ mask = 1U << 3; break;
+ default:
+ break;
}
if (gain)
@@ -1595,371 +1207,265 @@ U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey keysym, bool gain)
return mGrabbyKeyFlags;
}
-
-void check_vm_bloat()
+// virtual
+void LLWindowSDL::processMiscNativeEvents()
{
-#if LL_LINUX
- // watch our own VM and RSS sizes, warn if we bloated rapidly
- static const std::string STATS_FILE = "/proc/self/stat";
- FILE *fp = fopen(STATS_FILE.c_str(), "r");
- if (fp)
{
- static long long last_vm_size = 0;
- static long long last_rss_size = 0;
- const long long significant_vm_difference = 250 * 1024*1024;
- const long long significant_rss_difference = 50 * 1024*1024;
- long long this_vm_size = 0;
- long long this_rss_size = 0;
-
- ssize_t res;
- size_t dummy;
- char *ptr = NULL;
- for (int i=0; i<22; ++i) // parse past the values we don't want
+ LLMutexLock osr_lock(&mOSRMutex);
+ for(SDL_Window* pWindow : mDeadOSRWindows)
{
- res = getdelim(&ptr, &dummy, ' ', fp);
- if (-1 == res)
- {
- LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL;
- goto finally;
- }
- free(ptr);
- ptr = NULL;
+ SDL_DestroyWindow(pWindow);
}
- // 23rd space-delimited entry is vsize
- res = getdelim(&ptr, &dummy, ' ', fp);
- llassert(ptr);
- if (-1 == res)
+ mDeadOSRWindows.clear();
+ }
+}
+
+void LLWindowSDL::gatherInput()
+{
+ // This is for the case where SDL is not driving the main event loop
+ if(!gSDLMainHandled)
+ {
+ SDL_Event event;
+
+ // Handle all outstanding SDL events
+ while (SDL_PollEvent(&event))
{
- LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL;
- goto finally;
+ handleEvent(event);
}
- this_vm_size = atoll(ptr);
- free(ptr);
- ptr = NULL;
- // 24th space-delimited entry is RSS
- res = getdelim(&ptr, &dummy, ' ', fp);
- llassert(ptr);
- if (-1 == res)
+ }
+
+ updateCursor();
+
+ // This is a good time to stop flashing the icon if our mFlashTimer has
+ // expired.
+ if (mFlashing && mFlashTimer.hasExpired())
+ {
+ SDL_FlashWindow(mWindow, SDL_FLASH_CANCEL);
+ mFlashing = false;
+ }
+}
+
+SDL_AppResult LLWindowSDL::handleEvent(const SDL_Event& event)
+{
+ switch(event.type)
+ {
+ case SDL_EVENT_MOUSE_MOTION:
{
- LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL;
- goto finally;
+ LLCoordWindow winCoord(llfloor(event.motion.x), llfloor(event.motion.y));
+ LLCoordGL openGlCoord;
+ convertCoords(winCoord, &openGlCoord);
+ mCallbacks->handleMouseMove(this, openGlCoord, gKeyboard->currentMask(true));
+ break;
}
- this_rss_size = getpagesize() * atoll(ptr);
- free(ptr);
- ptr = NULL;
-
- LL_INFOS() << "VM SIZE IS NOW " << (this_vm_size/(1024*1024)) << " MB, RSS SIZE IS NOW " << (this_rss_size/(1024*1024)) << " MB" << LL_ENDL;
- if (llabs(last_vm_size - this_vm_size) >
- significant_vm_difference)
+ case SDL_EVENT_MOUSE_WHEEL:
{
- if (this_vm_size > last_vm_size)
+ if(event.wheel.integer_y != 0)
{
- LL_WARNS() << "VM size grew by " << (this_vm_size - last_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL;
+ mCallbacks->handleScrollWheel(this, -event.wheel.integer_y);
}
- else
+ if (event.wheel.integer_x != 0)
{
- LL_INFOS() << "VM size shrank by " << (last_vm_size - this_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL;
+ mCallbacks->handleScrollHWheel(this, -event.wheel.integer_x);
}
+ break;
}
- if (llabs(last_rss_size - this_rss_size) >
- significant_rss_difference)
+ case SDL_EVENT_MOUSE_BUTTON_DOWN:
{
- if (this_rss_size > last_rss_size)
+ LLCoordWindow winCoord(llfloor(event.button.x), llfloor(event.button.y));
+ LLCoordGL openGlCoord;
+ convertCoords(winCoord, &openGlCoord);
+ MASK mask = gKeyboard->currentMask(true);
+
+ if (event.button.button == SDL_BUTTON_LEFT) // left
+ {
+ if (event.button.clicks == 2)
+ mCallbacks->handleDoubleClick(this, openGlCoord, mask);
+ else
+ mCallbacks->handleMouseDown(this, openGlCoord, mask);
+ }
+ else if (event.button.button == SDL_BUTTON_RIGHT)
{
- LL_WARNS() << "RSS size grew by " << (this_rss_size - last_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL;
+ mCallbacks->handleRightMouseDown(this, openGlCoord, mask);
+ }
+ else if (event.button.button == SDL_BUTTON_MIDDLE) // middle
+ {
+ mCallbacks->handleMiddleMouseDown(this, openGlCoord, mask);
}
else
{
- LL_INFOS() << "RSS size shrank by " << (last_rss_size - this_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL;
+ mCallbacks->handleOtherMouseDown(this, openGlCoord, mask, event.button.button);
}
- }
-
- last_rss_size = this_rss_size;
- last_vm_size = this_vm_size;
-finally:
- if (NULL != ptr)
- {
- free(ptr);
- ptr = NULL;
+ break;
}
- fclose(fp);
- }
-#endif // LL_LINUX
-}
+ case SDL_EVENT_MOUSE_BUTTON_UP:
+ {
+ LLCoordWindow winCoord(llfloor(event.button.x), llfloor(event.button.y));
+ LLCoordGL openGlCoord;
+ convertCoords(winCoord, &openGlCoord);
+ MASK mask = gKeyboard->currentMask(true);
-// virtual
-void LLWindowSDL::processMiscNativeEvents()
-{
-#if LL_GTK
- // Pump GTK events to avoid starvation for:
- // * DBUS servicing
- // * Anything else which quietly hooks into the default glib/GTK loop
- if (ll_try_gtk_init())
- {
- // Yuck, Mozilla's GTK callbacks play with the locale - push/pop
- // the locale to protect it, as exotic/non-C locales
- // causes our code lots of general critical weirdness
- // and crashness. (SL-35450)
- static std::string saved_locale;
- saved_locale = ll_safe_string(setlocale(LC_ALL, NULL));
+ if (event.button.button == SDL_BUTTON_LEFT) // left
+ {
+ mCallbacks->handleMouseUp(this, openGlCoord, mask);
+ }
+ else if (event.button.button == SDL_BUTTON_RIGHT) // right
+ {
+ mCallbacks->handleRightMouseUp(this, openGlCoord, mask);
+ }
+ else if (event.button.button == SDL_BUTTON_MIDDLE) // middle
+ {
+ mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask);
+ }
+ else
+ {
+ mCallbacks->handleOtherMouseUp(this, openGlCoord, mask, event.button.button);
+ }
- // Pump until we've nothing left to do or passed 1/15th of a
- // second pumping for this frame.
- static LLTimer pump_timer;
- pump_timer.reset();
- pump_timer.setTimerExpirySec(1.0f / 15.0f);
- do {
- // Always do at least one non-blocking pump
- gtk_main_iteration_do(false);
- } while (gtk_events_pending() &&
- !pump_timer.hasExpired());
+ break;
+ }
- setlocale(LC_ALL, saved_locale.c_str() );
- }
-#endif // LL_GTK
+ case SDL_EVENT_KEY_DOWN:
+ {
+ mKeyVirtualKey = event.key.key;
+ mKeyModifiers = event.key.mod;
- // hack - doesn't belong here - but this is just for debugging
- if (getenv("LL_DEBUG_BLOAT"))
- {
- check_vm_bloat();
- }
-}
+ if (mKeyVirtualKey == SDLK_RETURN2 || mKeyVirtualKey == SDLK_KP_ENTER)
+ {
+ mKeyVirtualKey = SDLK_RETURN;
+ }
-void LLWindowSDL::gatherInput()
-{
- const Uint32 CLICK_THRESHOLD = 300; // milliseconds
- static int leftClick = 0;
- static int rightClick = 0;
- static Uint32 lastLeftDown = 0;
- static Uint32 lastRightDown = 0;
- SDL_Event event;
+ gKeyboard->handleKeyDown(mKeyVirtualKey, mKeyModifiers);
- // Handle all outstanding SDL events
- while (SDL_PollEvent(&event))
- {
- switch (event.type)
- {
- case SDL_MOUSEMOTION:
+ if (mKeyVirtualKey == SDLK_RETURN)
{
- LLCoordWindow winCoord(event.button.x, event.button.y);
- LLCoordGL openGlCoord;
- convertCoords(winCoord, &openGlCoord);
- MASK mask = gKeyboard->currentMask(true);
- mCallbacks->handleMouseMove(this, openGlCoord, mask);
- break;
+ // fix return key not working when capslock, scrolllock or numlock are enabled
+ mKeyModifiers &= (~(SDL_KMOD_NUM | SDL_KMOD_CAPS | SDL_KMOD_MODE | SDL_KMOD_SCROLL));
+ mCallbacks->handleUnicodeChar(mKeyVirtualKey, gKeyboard->currentMask(false));
}
- case SDL_KEYDOWN:
- mKeyScanCode = event.key.keysym.scancode;
- mKeyVirtualKey = event.key.keysym.unicode;
- mKeyModifiers = event.key.keysym.mod;
-
- gKeyboard->handleKeyDown(event.key.keysym.sym, event.key.keysym.mod);
// part of the fix for SL-13243
- if (SDLCheckGrabbyKeys(event.key.keysym.sym, true) != 0)
+ if (SDLCheckGrabbyKeys(mKeyVirtualKey, true) != 0)
SDLReallyCaptureInput(true);
+ break;
+ }
+
+ case SDL_EVENT_KEY_UP:
+ {
+ mKeyVirtualKey = event.key.key;
+ mKeyModifiers = event.key.mod;
- if (event.key.keysym.unicode)
+ if (mKeyVirtualKey == SDLK_RETURN2 || mKeyVirtualKey == SDLK_KP_ENTER)
{
- handleUnicodeUTF16(event.key.keysym.unicode,
- gKeyboard->currentMask(false));
+ mKeyVirtualKey = SDLK_RETURN;
}
- break;
- case SDL_KEYUP:
- mKeyScanCode = event.key.keysym.scancode;
- mKeyVirtualKey = event.key.keysym.unicode;
- mKeyModifiers = event.key.keysym.mod;
-
- if (SDLCheckGrabbyKeys(event.key.keysym.sym, false) == 0)
+ gKeyboard->handleKeyUp(mKeyVirtualKey, mKeyModifiers);
+ if (SDLCheckGrabbyKeys(mKeyVirtualKey, false) == 0)
SDLReallyCaptureInput(false); // part of the fix for SL-13243
-
- gKeyboard->handleKeyUp(event.key.keysym.sym, event.key.keysym.mod);
break;
+ }
- case SDL_MOUSEBUTTONDOWN:
- {
- bool isDoubleClick = false;
- LLCoordWindow winCoord(event.button.x, event.button.y);
- LLCoordGL openGlCoord;
- convertCoords(winCoord, &openGlCoord);
- MASK mask = gKeyboard->currentMask(true);
-
- if (event.button.button == SDL_BUTTON_LEFT) // SDL doesn't manage double clicking...
- {
- Uint32 now = SDL_GetTicks();
- if ((now - lastLeftDown) > CLICK_THRESHOLD)
- leftClick = 1;
- else
- {
- if (++leftClick >= 2)
- {
- leftClick = 0;
- isDoubleClick = true;
- }
- }
- lastLeftDown = now;
- }
- else if (event.button.button == SDL_BUTTON_RIGHT)
- {
- Uint32 now = SDL_GetTicks();
- if ((now - lastRightDown) > CLICK_THRESHOLD)
- rightClick = 1;
- else
- {
- if (++rightClick >= 2)
- {
- rightClick = 0;
- isDoubleClick = true;
- }
- }
- lastRightDown = now;
- }
-
- if (event.button.button == SDL_BUTTON_LEFT) // left
- {
- if (isDoubleClick)
- mCallbacks->handleDoubleClick(this, openGlCoord, mask);
- else
- mCallbacks->handleMouseDown(this, openGlCoord, mask);
- }
-
- else if (event.button.button == SDL_BUTTON_RIGHT) // right
- {
- mCallbacks->handleRightMouseDown(this, openGlCoord, mask);
- }
-
- else if (event.button.button == SDL_BUTTON_MIDDLE) // middle
- {
- mCallbacks->handleMiddleMouseDown(this, openGlCoord, mask);
- }
- else if (event.button.button == 4) // mousewheel up...thanks to X11 for making SDL consider these "buttons".
- mCallbacks->handleScrollWheel(this, -1);
- else if (event.button.button == 5) // mousewheel down...thanks to X11 for making SDL consider these "buttons".
- mCallbacks->handleScrollWheel(this, 1);
-
- break;
- }
-
- case SDL_MOUSEBUTTONUP:
+ case SDL_EVENT_TEXT_INPUT:
+ {
+ auto string = utf8str_to_wstring(event.text.text);
+ MASK current_mask = gKeyboard->currentMask(false);
+ for (auto key : string)
{
- LLCoordWindow winCoord(event.button.x, event.button.y);
- LLCoordGL openGlCoord;
- convertCoords(winCoord, &openGlCoord);
- MASK mask = gKeyboard->currentMask(true);
-
- if (event.button.button == SDL_BUTTON_LEFT) // left
- mCallbacks->handleMouseUp(this, openGlCoord, mask);
- else if (event.button.button == SDL_BUTTON_RIGHT) // right
- mCallbacks->handleRightMouseUp(this, openGlCoord, mask);
- else if (event.button.button == SDL_BUTTON_MIDDLE) // middle
- mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask);
- // don't handle mousewheel here...
-
- break;
+ mKeyVirtualKey = key;
+ mCallbacks->handleUnicodeChar(key, current_mask);
}
+ break;
+ }
- case SDL_VIDEOEXPOSE: // VIDEOEXPOSE doesn't specify the damage, but hey, it's OpenGL...repaint the whole thing!
- mCallbacks->handlePaint(this, 0, 0, mWindow->w, mWindow->h);
- break;
-
- case SDL_VIDEORESIZE: // *FIX: handle this?
- {
- LL_INFOS() << "Handling a resize event: " << event.resize.w <<
- "x" << event.resize.h << LL_ENDL;
-
- S32 width = llmax(event.resize.w, (S32)mMinWindowWidth);
- S32 height = llmax(event.resize.h, (S32)mMinWindowHeight);
-
- // *FIX: I'm not sure this is necessary!
- mWindow = SDL_SetVideoMode(width, height, 32, mSDLFlags);
- if (!mWindow)
+ case SDL_EVENT_WINDOW_EXPOSED:
{
- // *FIX: More informative dialog?
- LL_INFOS() << "Could not recreate context after resize! Quitting..." << LL_ENDL;
- if(mCallbacks->handleCloseRequest(this, false))
- {
- // Get the app to initiate cleanup.
- mCallbacks->handleQuit(this);
- // The app is responsible for calling destroyWindow when done with GL
- }
- break;
+ mCallbacks->handlePaint(this, 0, 0, 0, 0);
+ break;
}
- mCallbacks->handleResize(this, width, height);
- break;
- }
- case SDL_ACTIVEEVENT:
- if (event.active.state & SDL_APPINPUTFOCUS)
- {
- // Note that for SDL (particularly on X11), keyboard
- // and mouse focus are independent things. Here we are
- // tracking keyboard focus state changes.
-
- // We have to do our own state massaging because SDL
- // can send us two unfocus events in a row for example,
- // which confuses the focus code [SL-24071].
- if (event.active.gain != mHaveInputFocus)
- {
- mHaveInputFocus = !!event.active.gain;
+ case SDL_EVENT_WINDOW_RESIZED:
+ {
+ LL_INFOS() << "Handling a resize event: " << event.window.data1 << "x" << event.window.data2 << LL_ENDL;
+ F32 pixel_density = SDL_GetWindowPixelDensity(mWindow);
+ S32 width = llmax(event.window.data1, (S32)mMinWindowWidth) * pixel_density;
+ S32 height = llmax(event.window.data2, (S32)mMinWindowHeight) * pixel_density;
- if (mHaveInputFocus)
- mCallbacks->handleFocus(this);
- else
- mCallbacks->handleFocusLost(this);
- }
- }
- if (event.active.state & SDL_APPACTIVE)
- {
- // Change in iconification/minimization state.
- if ((!event.active.gain) != mIsMinimized)
+ mCallbacks->handleResize(this, width, height);
+ break;
+ }
+ case SDL_EVENT_WINDOW_MOUSE_ENTER:
+ break;
+ case SDL_EVENT_WINDOW_MOUSE_LEAVE:
+ mCallbacks->handleMouseLeave(this);
+ break;
+ case SDL_EVENT_WINDOW_FOCUS_GAINED:
+ //SDL_SetWindowKeyboardGrab(mWindow, true);
+ mCallbacks->handleFocus(this);
+ break;
+ case SDL_EVENT_WINDOW_FOCUS_LOST:
+ mCallbacks->handleFocusLost(this);
+ //SDL_SetWindowKeyboardGrab(mWindow, false);
+ break;
+ case SDL_EVENT_WINDOW_RESTORED:
+ mCallbacks->handleActivate(this, true);
+ break;
+ case SDL_EVENT_WINDOW_MAXIMIZED:
+ mCallbacks->handleActivate(this, true);
+ break;
+ case SDL_EVENT_WINDOW_MINIMIZED:
+ mCallbacks->handleActivate(this, false);
+ break;
+ case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
+ {
+ // Update refresh rate when changing monitors
+ const SDL_DisplayMode* displayMode = SDL_GetCurrentDisplayMode(event.window.data1);
+ if(displayMode)
{
- mIsMinimized = (!event.active.gain);
-
- mCallbacks->handleActivate(this, !mIsMinimized);
- LL_INFOS() << "SDL deiconification state switched to " << bool(event.active.gain) << LL_ENDL;
+ mRefreshRate = ll_round(displayMode->refresh_rate);
+ mNativeAspectRatio = ((F32)displayMode->w) / ((F32)displayMode->h);
}
- else
+ mCallbacks->handleDisplayChanged();
+ break;
+ }
+ case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
+ {
+ S32 w, h = 0;
+ SDL_GetWindowSizeInPixels(mWindow, &w, &h);
+ mCallbacks->handleDPIChanged(this, getSystemUISize(), w, h);
+ break;
+ }
+ case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
+ {
+ if(mCallbacks->handleCloseRequest(this, true))
{
- LL_INFOS() << "Ignored bogus redundant SDL deiconification state switch to " << bool(event.active.gain) << LL_ENDL;
+ // Get the app to initiate cleanup.
+ mCallbacks->handleQuit(this);
+ // The app is responsible for calling destroyWindow when done with GL
}
- }
- break;
-
- case SDL_QUIT:
- if(mCallbacks->handleCloseRequest(this, true))
- {
- // Get the app to initiate cleanup.
- mCallbacks->handleQuit(this);
- // The app is responsible for calling destroyWindow when done with GL
- }
- break;
- default:
- //LL_INFOS() << "Unhandled SDL event type " << event.type << LL_ENDL;
- break;
+ break;
}
+ default:
+ break;
}
- updateCursor();
+ return SDL_APP_CONTINUE;
+}
-#if LL_X11
- // This is a good time to stop flashing the icon if our mFlashTimer has
- // expired.
- if (mFlashing && mFlashTimer.hasExpired())
- {
- x11_set_urgent(false);
- mFlashing = false;
- }
-#endif // LL_X11
+// static
+SDL_AppResult LLWindowSDL::handleEvents(const SDL_Event& event)
+{
+ if(!gWindowImplementation) return SDL_APP_CONTINUE;
+
+ return gWindowImplementation->handleEvent(event);
}
static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty)
{
- SDL_Cursor *sdlcursor = NULL;
+ SDL_Cursor *sdlcursor = nullptr;
SDL_Surface *bmpsurface;
// Load cursor pixel data from BMP file
@@ -1968,21 +1474,32 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty
{
SDL_Surface *cursurface;
LL_DEBUGS() << "Loaded cursor file " << filename << " "
- << bmpsurface->w << "x" << bmpsurface->h << LL_ENDL;
- cursurface = SDL_CreateRGBSurface (SDL_SWSURFACE,
- bmpsurface->w,
- bmpsurface->h,
- 32,
- SDL_SwapLE32(0xFFU),
- SDL_SwapLE32(0xFF00U),
- SDL_SwapLE32(0xFF0000U),
- SDL_SwapLE32(0xFF000000U));
- SDL_FillRect(cursurface, NULL, SDL_SwapLE32(0x00000000U));
+ << bmpsurface->w << "x" << bmpsurface->h << LL_ENDL;
+ SDL_PixelFormat pix_format = SDL_GetPixelFormatForMasks(32,
+ SDL_Swap32LE(0xFFU),
+ SDL_Swap32LE(0xFF00U),
+ SDL_Swap32LE(0xFF0000U),
+ SDL_Swap32LE(0xFF000000U));
+ if (pix_format == SDL_PIXELFORMAT_UNKNOWN)
+ {
+ return nullptr;
+ }
+
+ const SDL_PixelFormatDetails* pix_format_details = SDL_GetPixelFormatDetails(pix_format);
+ if(!pix_format_details)
+ {
+ return nullptr;
+ }
+
+ cursurface = SDL_CreateSurface(bmpsurface->w,
+ bmpsurface->h,
+ pix_format);
+ SDL_FillSurfaceRect(cursurface, nullptr, SDL_Swap32LE(0x00000000U));
// Blit the cursor pixel data onto a 32-bit RGBA surface so we
// only have to cope with processing one type of pixel format.
- if (0 == SDL_BlitSurface(bmpsurface, NULL,
- cursurface, NULL))
+ if (SDL_BlitSurface(bmpsurface, nullptr,
+ cursurface, nullptr))
{
// n.b. we already checked that width is a multiple of 8.
const int bitmap_bytes = (cursurface->w * cursurface->h) / 8;
@@ -1997,33 +1514,33 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty
for (i=0; i<cursurface->h; ++i) {
for (j=0; j<cursurface->w; ++j) {
U8 *pixelp =
- ((U8*)cursurface->pixels)
- + cursurface->pitch * i
- + j*cursurface->format->BytesPerPixel;
+ ((U8*)cursurface->pixels)
+ + cursurface->pitch * i
+ + j*pix_format_details->bytes_per_pixel;
U8 srcred = pixelp[0];
U8 srcgreen = pixelp[1];
U8 srcblue = pixelp[2];
bool mask_bit = (srcred != 200)
- || (srcgreen != 200)
- || (srcblue != 200);
+ || (srcgreen != 200)
+ || (srcblue != 200);
bool data_bit = mask_bit && (srcgreen <= 80);//not 0x80
unsigned char bit_offset = (cursurface->w/8) * i
- + j/8;
+ + j/8;
cursor_data[bit_offset] |= (data_bit) << (7 - (j&7));
cursor_mask[bit_offset] |= (mask_bit) << (7 - (j&7));
}
}
sdlcursor = SDL_CreateCursor((Uint8*)cursor_data,
- (Uint8*)cursor_mask,
- cursurface->w, cursurface->h,
- hotx, hoty);
+ (Uint8*)cursor_mask,
+ cursurface->w, cursurface->h,
+ hotx, hoty);
delete[] cursor_data;
delete[] cursor_mask;
} else {
LL_WARNS() << "CURSOR BLIT FAILURE, cursurface: " << cursurface << LL_ENDL;
}
- SDL_FreeSurface(cursurface);
- SDL_FreeSurface(bmpsurface);
+ SDL_DestroySurface(cursurface);
+ SDL_DestroySurface(bmpsurface);
} else {
LL_WARNS() << "CURSOR LOAD FAILURE " << filename << LL_ENDL;
}
@@ -2033,12 +1550,6 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty
void LLWindowSDL::updateCursor()
{
- if (ATIbug) {
- // cursor-updating is very flaky when this bug is
- // present; do nothing.
- return;
- }
-
if (mCurrentCursor != mNextCursor)
{
if (mNextCursor < UI_CURSOR_COUNT)
@@ -2050,37 +1561,40 @@ void LLWindowSDL::updateCursor()
sdlcursor = mSDLCursors[UI_CURSOR_ARROW];
if (sdlcursor)
SDL_SetCursor(sdlcursor);
- } else {
+
+ mCurrentCursor = mNextCursor;
+ }
+ else
+ {
LL_WARNS() << "Tried to set invalid cursor number " << mNextCursor << LL_ENDL;
}
- mCurrentCursor = mNextCursor;
}
}
void LLWindowSDL::initCursors()
{
- int i;
// Blank the cursor pointer array for those we may miss.
- for (i=0; i<UI_CURSOR_COUNT; ++i)
+ for (int i=0; i<UI_CURSOR_COUNT; ++i)
{
- mSDLCursors[i] = NULL;
+ mSDLCursors[i] = nullptr;
}
+
// Pre-make an SDL cursor for each of the known cursor types.
// We hardcode the hotspots - to avoid that we'd have to write
// a .cur file loader.
// NOTE: SDL doesn't load RLE-compressed BMP files.
- mSDLCursors[UI_CURSOR_ARROW] = makeSDLCursorFromBMP("llarrow.BMP",0,0);
- mSDLCursors[UI_CURSOR_WAIT] = makeSDLCursorFromBMP("wait.BMP",12,15);
- mSDLCursors[UI_CURSOR_HAND] = makeSDLCursorFromBMP("hand.BMP",7,10);
- mSDLCursors[UI_CURSOR_IBEAM] = makeSDLCursorFromBMP("ibeam.BMP",15,16);
- mSDLCursors[UI_CURSOR_CROSS] = makeSDLCursorFromBMP("cross.BMP",16,14);
- mSDLCursors[UI_CURSOR_SIZENWSE] = makeSDLCursorFromBMP("sizenwse.BMP",14,17);
- mSDLCursors[UI_CURSOR_SIZENESW] = makeSDLCursorFromBMP("sizenesw.BMP",17,17);
- mSDLCursors[UI_CURSOR_SIZEWE] = makeSDLCursorFromBMP("sizewe.BMP",16,14);
- mSDLCursors[UI_CURSOR_SIZENS] = makeSDLCursorFromBMP("sizens.BMP",17,16);
- mSDLCursors[UI_CURSOR_SIZEALL] = makeSDLCursorFromBMP("sizeall.BMP", 17, 17);
- mSDLCursors[UI_CURSOR_NO] = makeSDLCursorFromBMP("llno.BMP",8,8);
- mSDLCursors[UI_CURSOR_WORKING] = makeSDLCursorFromBMP("working.BMP",12,15);
+ mSDLCursors[UI_CURSOR_ARROW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT);
+ mSDLCursors[UI_CURSOR_WAIT] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
+ mSDLCursors[UI_CURSOR_HAND] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER);
+ mSDLCursors[UI_CURSOR_IBEAM] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_TEXT);
+ mSDLCursors[UI_CURSOR_CROSS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR);
+ mSDLCursors[UI_CURSOR_SIZENWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NWSE_RESIZE);
+ mSDLCursors[UI_CURSOR_SIZENESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NESW_RESIZE);
+ mSDLCursors[UI_CURSOR_SIZEWE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_EW_RESIZE);
+ mSDLCursors[UI_CURSOR_SIZENS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NS_RESIZE);
+ mSDLCursors[UI_CURSOR_SIZEALL] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_MOVE);
+ mSDLCursors[UI_CURSOR_NO] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED);
+ mSDLCursors[UI_CURSOR_WORKING] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_PROGRESS);
mSDLCursors[UI_CURSOR_TOOLGRAB] = makeSDLCursorFromBMP("lltoolgrab.BMP",2,13);
mSDLCursors[UI_CURSOR_TOOLLAND] = makeSDLCursorFromBMP("lltoolland.BMP",1,6);
mSDLCursors[UI_CURSOR_TOOLFOCUS] = makeSDLCursorFromBMP("lltoolfocus.BMP",8,5);
@@ -2113,32 +1627,28 @@ void LLWindowSDL::initCursors()
mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END] = makeSDLCursorFromBMP("lltoolpathfindingpathend.BMP", 16, 16);
mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD] = makeSDLCursorFromBMP("lltoolpathfindingpathendadd.BMP", 16, 16);
mSDLCursors[UI_CURSOR_TOOLNO] = makeSDLCursorFromBMP("llno.BMP",8,8);
-
- if (getenv("LL_ATI_MOUSE_CURSOR_BUG") != NULL) {
- LL_INFOS() << "Disabling cursor updating due to LL_ATI_MOUSE_CURSOR_BUG" << LL_ENDL;
- ATIbug = true;
- }
}
void LLWindowSDL::quitCursors()
{
- int i;
if (mWindow)
{
- for (i=0; i<UI_CURSOR_COUNT; ++i)
+ for (int i=0; i<UI_CURSOR_COUNT; ++i)
{
if (mSDLCursors[i])
{
- SDL_FreeCursor(mSDLCursors[i]);
- mSDLCursors[i] = NULL;
+ SDL_DestroyCursor(mSDLCursors[i]);
+ mSDLCursors[i] = nullptr;
}
}
- } else {
+ }
+ else
+ {
// SDL doesn't refcount cursors, so if the window has
// already been destroyed then the cursors have gone with it.
LL_INFOS() << "Skipping quitCursors: mWindow already gone." << LL_ENDL;
- for (i=0; i<UI_CURSOR_COUNT; ++i)
- mSDLCursors[i] = NULL;
+ for (int i=0; i<UI_CURSOR_COUNT; ++i)
+ mSDLCursors[i] = nullptr;
}
}
@@ -2167,7 +1677,7 @@ void LLWindowSDL::hideCursor()
// LL_INFOS() << "hideCursor: hiding" << LL_ENDL;
mCursorHidden = true;
mHideCursorPermanent = true;
- SDL_ShowCursor(0);
+ SDL_HideCursor();
}
else
{
@@ -2182,7 +1692,7 @@ void LLWindowSDL::showCursor()
// LL_INFOS() << "showCursor: showing" << LL_ENDL;
mCursorHidden = false;
mHideCursorPermanent = false;
- SDL_ShowCursor(1);
+ SDL_ShowCursor();
}
else
{
@@ -2207,8 +1717,6 @@ void LLWindowSDL::hideCursorUntilMouseMove()
}
}
-
-
//
// LLSplashScreenSDL - I don't think we'll bother to implement this; it's
// fairly obsolete at this point.
@@ -2233,133 +1741,62 @@ void LLSplashScreenSDL::hideImpl()
{
}
-
-
-#if LL_GTK
-static void response_callback (GtkDialog *dialog,
- gint arg1,
- gpointer user_data)
-{
- gint *response = (gint*)user_data;
- *response = arg1;
- gtk_widget_destroy(GTK_WIDGET(dialog));
- gtk_main_quit();
-}
-
S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type)
{
- S32 rtn = OSBTN_CANCEL;
-
- if(gWindowImplementation != NULL)
- gWindowImplementation->beforeDialog();
+ SDL_MessageBoxData oData = { SDL_MESSAGEBOX_INFORMATION, nullptr, caption.c_str(), text.c_str(), 0, nullptr, nullptr };
+ SDL_MessageBoxButtonData btnOk[] = {{SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, OSBTN_OK, "OK" }};
+ SDL_MessageBoxButtonData btnOkCancel [] = {{SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, OSBTN_OK, "OK" }, {SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, OSBTN_CANCEL, "Cancel"} };
+ SDL_MessageBoxButtonData btnYesNo[] = { {SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, OSBTN_YES, "Yes" }, {SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, OSBTN_NO, "No"} };
- if (LLWindowSDL::ll_try_gtk_init())
+ switch (type)
{
- GtkWidget *win = NULL;
-
- LL_INFOS() << "Creating a dialog because we're in windowed mode and GTK is happy." << LL_ENDL;
-
- GtkDialogFlags flags = GTK_DIALOG_MODAL;
- GtkMessageType messagetype;
- GtkButtonsType buttons;
- switch (type)
- {
default:
case OSMB_OK:
- messagetype = GTK_MESSAGE_WARNING;
- buttons = GTK_BUTTONS_OK;
+ oData.flags = SDL_MESSAGEBOX_WARNING;
+ oData.buttons = btnOk;
+ oData.numbuttons = 1;
break;
case OSMB_OKCANCEL:
- messagetype = GTK_MESSAGE_QUESTION;
- buttons = GTK_BUTTONS_OK_CANCEL;
+ oData.flags = SDL_MESSAGEBOX_INFORMATION;
+ oData.buttons = btnOkCancel;
+ oData.numbuttons = 2;
break;
case OSMB_YESNO:
- messagetype = GTK_MESSAGE_QUESTION;
- buttons = GTK_BUTTONS_YES_NO;
+ oData.flags = SDL_MESSAGEBOX_INFORMATION;
+ oData.buttons = btnYesNo;
+ oData.numbuttons = 2;
break;
- }
- win = gtk_message_dialog_new(NULL, flags, messagetype, buttons, "%s",
- text.c_str());
-
-# if LL_X11
- // Make GTK tell the window manager to associate this
- // dialog with our non-GTK SDL window, which should try
- // to keep it on top etc.
- if (gWindowImplementation &&
- gWindowImplementation->mSDL_XWindowID != None)
- {
- gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin
- GdkWindow *gdkwin = gdk_window_foreign_new(gWindowImplementation->mSDL_XWindowID);
- gdk_window_set_transient_for(GTK_WIDGET(win)->window,
- gdkwin);
- }
-# endif //LL_X11
-
- gtk_window_set_position(GTK_WINDOW(win),
- GTK_WIN_POS_CENTER_ON_PARENT);
-
- gtk_window_set_type_hint(GTK_WINDOW(win),
- GDK_WINDOW_TYPE_HINT_DIALOG);
-
- if (!caption.empty())
- gtk_window_set_title(GTK_WINDOW(win), caption.c_str());
-
- gint response = GTK_RESPONSE_NONE;
- g_signal_connect (win,
- "response",
- G_CALLBACK (response_callback),
- &response);
+ }
- // we should be able to use a gtk_dialog_run(), but it's
- // apparently not written to exist in a world without a higher
- // gtk_main(), so we manage its signal/destruction outselves.
- gtk_widget_show_all (win);
- gtk_main();
+ if(gWindowImplementation != nullptr)
+ gWindowImplementation->beforeDialog();
- //LL_INFOS() << "response: " << response << LL_ENDL;
- switch (response)
- {
- case GTK_RESPONSE_OK: rtn = OSBTN_OK; break;
- case GTK_RESPONSE_YES: rtn = OSBTN_YES; break;
- case GTK_RESPONSE_NO: rtn = OSBTN_NO; break;
- case GTK_RESPONSE_APPLY: rtn = OSBTN_OK; break;
- case GTK_RESPONSE_NONE:
- case GTK_RESPONSE_CANCEL:
- case GTK_RESPONSE_CLOSE:
- case GTK_RESPONSE_DELETE_EVENT:
- default: rtn = OSBTN_CANCEL;
- }
- }
- else
+ int btn{0};
+ if(SDL_ShowMessageBox( &oData, &btn ))
{
- LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL;
- LL_INFOS() << "Skipping dialog because we're in fullscreen mode or GTK is not happy." << LL_ENDL;
- rtn = OSBTN_OK;
+ if(gWindowImplementation != nullptr)
+ gWindowImplementation->afterDialog();
+ return btn;
}
- if(gWindowImplementation != NULL)
+ if(gWindowImplementation != nullptr)
gWindowImplementation->afterDialog();
- return rtn;
+ return OSBTN_CANCEL;
}
-static void color_changed_callback(GtkWidget *widget,
- gpointer user_data)
+bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b)
{
- GtkColorSelection *colorsel = GTK_COLOR_SELECTION(widget);
- GdkColor *colorp = (GdkColor*)user_data;
-
- gtk_color_selection_get_current_color(colorsel, colorp);
+ return false;
}
-
/*
Make the raw keyboard data available - used to poke through to LLQtWebKit so
that Qt/Webkit has access to the virtual keycodes etc. that it needs
*/
LLSD LLWindowSDL::getNativeKeyData()
{
- LLSD result = LLSD::emptyMap();
+ LLSD result = LLSD::emptyMap();
U32 modifiers = 0; // pretend-native modifiers... oh what a tangled web we weave!
@@ -2367,140 +1804,21 @@ LLSD LLWindowSDL::getNativeKeyData()
// what a plugin under GDK under Qt under SL under SDL under X11 considers
// a 'native' modifier mask. this has been sort of reverse-engineered... they *appear*
// to match GDK consts, but that may be co-incidence.
- modifiers |= (mKeyModifiers & KMOD_LSHIFT) ? 0x0001 : 0;
- modifiers |= (mKeyModifiers & KMOD_RSHIFT) ? 0x0001 : 0;// munge these into the same shift
- modifiers |= (mKeyModifiers & KMOD_CAPS) ? 0x0002 : 0;
- modifiers |= (mKeyModifiers & KMOD_LCTRL) ? 0x0004 : 0;
- modifiers |= (mKeyModifiers & KMOD_RCTRL) ? 0x0004 : 0;// munge these into the same ctrl
- modifiers |= (mKeyModifiers & KMOD_LALT) ? 0x0008 : 0;// untested
- modifiers |= (mKeyModifiers & KMOD_RALT) ? 0x0008 : 0;// untested
+ modifiers |= (mKeyModifiers & SDL_KMOD_LSHIFT) ? 0x0001 : 0;
+ modifiers |= (mKeyModifiers & SDL_KMOD_RSHIFT) ? 0x0001 : 0;// munge these into the same shift
+ modifiers |= (mKeyModifiers & SDL_KMOD_CAPS) ? 0x0002 : 0;
+ modifiers |= (mKeyModifiers & SDL_KMOD_LCTRL) ? 0x0004 : 0;
+ modifiers |= (mKeyModifiers & SDL_KMOD_RCTRL) ? 0x0004 : 0;// munge these into the same ctrl
+ modifiers |= (mKeyModifiers & SDL_KMOD_LALT) ? 0x0008 : 0;// untested
+ modifiers |= (mKeyModifiers & SDL_KMOD_RALT) ? 0x0008 : 0;// untested
// *todo: test ALTs - I don't have a case for testing these. Do you?
// *todo: NUM? - I don't care enough right now (and it's not a GDK modifier).
- result["scan_code"] = (S32)mKeyScanCode;
- result["virtual_key"] = (S32)mKeyVirtualKey;
+ result["virtual_key"] = (S32)mKeyVirtualKey;
+ result["virtual_key_win"] = (S32)LLKeyboardSDL::mapSDL2toWin( mKeyVirtualKey );
result["modifiers"] = (S32)modifiers;
-
- return result;
-}
-
-
-bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b)
-{
- bool rtn = false;
-
- beforeDialog();
-
- if (ll_try_gtk_init())
- {
- GtkWidget *win = NULL;
-
- win = gtk_color_selection_dialog_new(NULL);
-
-# if LL_X11
- // Get GTK to tell the window manager to associate this
- // dialog with our non-GTK SDL window, which should try
- // to keep it on top etc.
- if (mSDL_XWindowID != None)
- {
- gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin
- GdkWindow *gdkwin = gdk_window_foreign_new(mSDL_XWindowID);
- gdk_window_set_transient_for(GTK_WIDGET(win)->window,
- gdkwin);
- }
-# endif //LL_X11
-
- GtkColorSelection *colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG(win)->colorsel);
-
- GdkColor color, orig_color;
- orig_color.pixel = 0;
- orig_color.red = guint16(65535 * *r);
- orig_color.green= guint16(65535 * *g);
- orig_color.blue = guint16(65535 * *b);
- color = orig_color;
-
- gtk_color_selection_set_previous_color (colorsel, &color);
- gtk_color_selection_set_current_color (colorsel, &color);
- gtk_color_selection_set_has_palette (colorsel, true);
- gtk_color_selection_set_has_opacity_control(colorsel, false);
-
- gint response = GTK_RESPONSE_NONE;
- g_signal_connect (win,
- "response",
- G_CALLBACK (response_callback),
- &response);
-
- g_signal_connect (G_OBJECT (colorsel), "color_changed",
- G_CALLBACK (color_changed_callback),
- &color);
-
- gtk_window_set_modal(GTK_WINDOW(win), true);
- gtk_widget_show_all(win);
- // hide the help button - we don't service it.
- gtk_widget_hide(GTK_COLOR_SELECTION_DIALOG(win)->help_button);
- gtk_main();
-
- if (response == GTK_RESPONSE_OK &&
- (orig_color.red != color.red
- || orig_color.green != color.green
- || orig_color.blue != color.blue) )
- {
- *r = color.red / 65535.0f;
- *g = color.green / 65535.0f;
- *b = color.blue / 65535.0f;
- rtn = true;
- }
- }
-
- afterDialog();
-
- return rtn;
-}
-#else
-S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type)
-{
- LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL;
- return 0;
-}
-
-bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b)
-{
- return (false);
-}
-#endif // LL_GTK
-
-#if LL_LINUX
-// extracted from spawnWebBrowser for clarity and to eliminate
-// compiler confusion regarding close(int fd) vs. LLWindow::close()
-void exec_cmd(const std::string& cmd, const std::string& arg)
-{
- char* const argv[] = {(char*)cmd.c_str(), (char*)arg.c_str(), NULL};
- fflush(NULL);
- pid_t pid = fork();
- if (pid == 0)
- { // child
- // disconnect from stdin/stdout/stderr, or child will
- // keep our output pipe undesirably alive if it outlives us.
- close(0);
- close(1);
- close(2);
- // end ourself by running the command
- execv(cmd.c_str(), argv); /* Flawfinder: ignore */
- // if execv returns at all, there was a problem.
- LL_WARNS() << "execv failure when trying to start " << cmd << LL_ENDL;
- _exit(1); // _exit because we don't want atexit() clean-up!
- } else {
- if (pid > 0)
- {
- // parent - wait for child to die
- int childExitStatus;
- waitpid(pid, &childExitStatus, 0);
- } else {
- LL_WARNS() << "fork failure." << LL_ENDL;
- }
- }
+ return result;
}
-#endif
// Open a URL with the user's default web browser.
// Must begin with protocol identifier.
@@ -2525,56 +1843,26 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)
LL_INFOS() << "spawn_web_browser: " << escaped_url << LL_ENDL;
-#if LL_LINUX
-# if LL_X11
- if (mSDL_Display)
+ if (!SDL_OpenURL(escaped_url.c_str()))
{
- maybe_lock_display();
- // Just in case - before forking.
- XSync(mSDL_Display, False);
- maybe_unlock_display();
+ LL_WARNS() << "spawn_web_browser failed with error: " << SDL_GetError() << LL_ENDL;
}
-# endif // LL_X11
-
- std::string cmd, arg;
- cmd = gDirUtilp->getAppRODataDir();
- cmd += gDirUtilp->getDirDelimiter();
- cmd += "etc";
- cmd += gDirUtilp->getDirDelimiter();
- cmd += "launch_url.sh";
- arg = escaped_url;
- exec_cmd(cmd, arg);
-#endif // LL_LINUX
LL_INFOS() << "spawn_web_browser returning." << LL_ENDL;
}
-
-void *LLWindowSDL::getPlatformWindow()
+void* LLWindowSDL::getPlatformWindow()
{
-#if LL_GTK && LL_LLMOZLIB_ENABLED
- if (LLWindowSDL::ll_try_gtk_init())
+ void* ret = nullptr;
+ if (mWindow)
{
- maybe_lock_display();
-
- GtkWidget *owin = gtk_window_new(GTK_WINDOW_POPUP);
- // Why a layout widget? A MozContainer would be ideal, but
- // it involves exposing Mozilla headers to mozlib-using apps.
- // A layout widget with a GtkWindow parent has the desired
- // properties of being plain GTK, having a window, and being
- // derived from a GtkContainer.
- GtkWidget *rtnw = gtk_layout_new(NULL, NULL);
- gtk_container_add(GTK_CONTAINER(owin), rtnw);
- gtk_widget_realize(rtnw);
- GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(rtnw), GTK_NO_WINDOW);
-
- maybe_unlock_display();
-
- return rtnw;
+#if LL_WINDOWS
+ ret = SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr);
+#elif LL_DARWIN
+ ret = SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, nullptr);
+#endif
}
-#endif // LL_GTK && LL_LLMOZLIB_ENABLED
- // Unixoid mozilla really needs GTK.
- return NULL;
+ return ret;
}
void LLWindowSDL::bringToFront()
@@ -2582,20 +1870,17 @@ void LLWindowSDL::bringToFront()
// This is currently used when we are 'launched' to a specific
// map position externally.
LL_INFOS() << "bringToFront" << LL_ENDL;
-#if LL_X11
- if (mSDL_Display && !mFullscreen)
+ if (mWindow && !mFullscreen)
{
- maybe_lock_display();
- XRaiseWindow(mSDL_Display, mSDL_XWindowID);
- XSync(mSDL_Display, False);
- maybe_unlock_display();
+ SDL_RaiseWindow(mWindow);
}
-#endif // LL_X11
}
//static
std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
{
+ std::vector<std::string> rtns;
+#if LL_LINUX
// Use libfontconfig to find us a nice ordered list of fallback fonts
// specific to this system.
std::string final_fallback("/usr/share/fonts/truetype/kochi/kochi-gothic.ttf");
@@ -2612,9 +1897,9 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
// renderable range if for some reason our FreeType actually fails
// to use some of the fonts we want it to.
const bool elide_unicode_coverage = true;
- std::vector<std::string> rtns;
- FcFontSet *fs = NULL;
- FcPattern *sortpat = NULL;
+
+ FcFontSet *fs = nullptr;
+ FcPattern *sortpat = nullptr;
LL_INFOS() << "Getting system font list from FontConfig..." << LL_ENDL;
@@ -2623,7 +1908,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
// of languages that can be displayed, but ensures that their
// preferred language is rendered from a single consistent font where
// possible.
- FL_Locale *locale = NULL;
+ FL_Locale *locale = nullptr;
FL_Success success = FL_FindLocale(&locale, FL_MESSAGES);
if (success != 0)
{
@@ -2634,10 +1919,10 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
LL_INFOS("AppInit") << "Variant " << locale->variant << LL_ENDL;
LL_INFOS() << "Preferring fonts of language: "
- << locale->lang
- << LL_ENDL;
+ << locale->lang
+ << LL_ENDL;
sort_order = "lang=" + std::string(locale->lang) + ":"
- + sort_order;
+ + sort_order;
}
}
FL_FreeLocale(&locale);
@@ -2654,8 +1939,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
{
// Sort the list of system fonts from most-to-least-desirable.
FcResult result;
- fs = FcFontSort(NULL, sortpat, elide_unicode_coverage,
- NULL, &result);
+ fs = FcFontSort(nullptr, sortpat, elide_unicode_coverage, nullptr, &result);
FcPatternDestroy(sortpat);
}
@@ -2668,10 +1952,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
for (int i=0; i<fs->nfont; ++i)
{
FcChar8 *filename;
- if (FcResultMatch == FcPatternGetString(fs->fonts[i],
- FC_FILE, 0,
- &filename)
- && filename)
+ if (FcResultMatch == FcPatternGetString(fs->fonts[i], FC_FILE, 0, &filename) && filename)
{
rtns.push_back(std::string((const char*)filename));
if (rtns.size() >= max_font_count_cutoff)
@@ -2682,16 +1963,101 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
}
LL_DEBUGS() << "Using font list: " << LL_ENDL;
- for (std::vector<std::string>::iterator it = rtns.begin();
- it != rtns.end();
- ++it)
+ for (auto it = rtns.begin(); it != rtns.end(); ++it)
{
LL_DEBUGS() << " file: " << *it << LL_ENDL;
}
+
LL_INFOS() << "Using " << rtns.size() << "/" << found_font_count << " system fonts." << LL_ENDL;
rtns.push_back(final_fallback);
+#endif
return rtns;
}
-#endif // LL_SDL
+void LLWindowSDL::setLanguageTextInput(const LLCoordGL& position)
+{
+ LLCoordWindow win_pos;
+ convertCoords( position, &win_pos );
+
+ SDL_Rect r;
+ r.x = win_pos.mX;
+ r.y = win_pos.mY;
+ r.w = 500;
+ r.h = 16;
+
+ SDL_SetTextInputArea(mWindow, &r, 0);
+}
+
+F32 LLWindowSDL::getSystemUISize()
+{
+ if(mWindow)
+ {
+ F32 scale = SDL_GetWindowDisplayScale(mWindow);
+ if (scale > 0.0f)
+ {
+ return scale;
+ }
+ }
+ return 1.f;
+}
+
+#if LL_DARWIN
+// static
+U64 LLWindowSDL::getVramSize()
+{
+ CGLRendererInfoObj info = 0;
+ GLint vram_megabytes = 0;
+ int num_renderers = 0;
+ CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers);
+ if(0 == the_err)
+ {
+ // The name, uses, and other platform definitions of gGLManager.mVRAM suggest that this is supposed to be total vram in MB,
+ // rather than, say, just the texture memory. The two exceptions are:
+ // 1. LLAppViewer::getViewerInfo() puts the value in a field labeled "TEXTURE_MEMORY"
+ // 2. For years, this present function used kCGLRPTextureMemoryMegabytes
+ // Now we use kCGLRPVideoMemoryMegabytes to bring it in line with everything else (except thatone label).
+ CGLDescribeRenderer (info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes);
+ CGLDestroyRendererInfo (info);
+ }
+ else
+ {
+ vram_megabytes = 256;
+ }
+
+ return (U64)vram_megabytes; // return value is in megabytes.
+}
+
+//static
+void LLWindowSDL::setUseMultGL(bool use_mult_gl)
+{
+ bool was_enabled = sUseMultGL;
+
+ sUseMultGL = use_mult_gl;
+
+ if (gGLManager.mInited)
+ {
+ CGLContextObj ctx = CGLGetCurrentContext();
+ //enable multi-threaded OpenGL (whether or not sUseMultGL actually changed)
+ if (sUseMultGL)
+ {
+ CGLError cgl_err = CGLEnable( ctx, kCGLCEMPEngine);
+ if (cgl_err != kCGLNoError )
+ {
+ LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL;
+ sUseMultGL = false;
+ }
+ else
+ {
+ LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
+ }
+ }
+ else if (was_enabled)
+ {
+ CGLDisable( ctx, kCGLCEMPEngine);
+ LL_INFOS("GLInit") << "Multi-threaded OpenGL disabled." << LL_ENDL;
+ }
+ }
+}
+#endif
+
diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h
index 521d52df30..4d4a7a5f65 100644
--- a/indra/llwindow/llwindowsdl.h
+++ b/indra/llwindow/llwindowsdl.h
@@ -31,142 +31,163 @@
#include "llwindow.h"
#include "lltimer.h"
+#include "llmutex.h"
-#include "SDL/SDL.h"
-#include "SDL/SDL_endian.h"
+#include "SDL3/SDL.h"
+#include "SDL3/SDL_endian.h"
-#if LL_X11
-// get X11-specific headers for use in low-level stuff like copy-and-paste support
-#include "SDL/SDL_syswm.h"
+#ifdef LL_WAYLAND
+#include <wayland-client-protocol.h>
#endif
-// AssertMacros.h does bad things.
-#include "fix_macros.h"
-#undef verify
-#undef require
+#if LL_X11
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif
+class LLPreeditor;
-class LLWindowSDL : public LLWindow
+class LLWindowSDL final : public LLWindow
{
public:
- /*virtual*/ void show();
- /*virtual*/ void hide();
- /*virtual*/ void close();
- /*virtual*/ bool getVisible();
- /*virtual*/ bool getMinimized();
- /*virtual*/ bool getMaximized();
- /*virtual*/ bool maximize();
- /*virtual*/ void minimize();
- /*virtual*/ void restore();
- /*virtual*/ bool getFullscreen();
- /*virtual*/ bool getPosition(LLCoordScreen *position);
- /*virtual*/ bool getSize(LLCoordScreen *size);
- /*virtual*/ bool getSize(LLCoordWindow *size);
- /*virtual*/ bool setPosition(LLCoordScreen position);
- /*virtual*/ bool setSizeImpl(LLCoordScreen size);
- /*virtual*/ bool setSizeImpl(LLCoordWindow size);
- /*virtual*/ bool switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, const LLCoordScreen * const posp = NULL);
- /*virtual*/ bool setCursorPosition(LLCoordWindow position);
- /*virtual*/ bool getCursorPosition(LLCoordWindow *position);
- /*virtual*/ bool isWrapMouse() const override { return true; }
- /*virtual*/ void showCursor();
- /*virtual*/ void hideCursor();
- /*virtual*/ void showCursorFromMouseMove();
- /*virtual*/ void hideCursorUntilMouseMove();
- /*virtual*/ bool isCursorHidden();
- /*virtual*/ void updateCursor();
- /*virtual*/ void captureMouse();
- /*virtual*/ void releaseMouse();
- /*virtual*/ void setMouseClipping( bool b );
- /*virtual*/ void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true);
+ void show() override;
+ void hide() override;
+ void restore() override;
+
+ void close() override;
+
+ bool getVisible() override;
+
+ bool getMinimized() override;
+
+ bool getMaximized() override;
+
+ bool maximize() override;
+ void minimize() override;
+
+ bool getPosition(LLCoordScreen *position) override;
+
+ bool getSize(LLCoordScreen *size) override;
+ bool getSize(LLCoordWindow *size) override;
+
+ bool setPosition(LLCoordScreen position) override;
+
+ bool setSizeImpl(LLCoordScreen size) override;
+ bool setSizeImpl(LLCoordWindow size) override;
+
+ bool switchContext(bool fullscreen, const LLCoordScreen &size, bool enable_vsync,
+ const LLCoordScreen *const posp = NULL) override;
+
+ bool setCursorPosition(LLCoordWindow position) override;
- /*virtual*/ bool isClipboardTextAvailable();
- /*virtual*/ bool pasteTextFromClipboard(LLWString &dst);
- /*virtual*/ bool copyTextToClipboard(const LLWString & src);
+ bool getCursorPosition(LLCoordWindow *position) override;
+ bool isWrapMouse() const override { return true; }
+ void showCursor() override;
+ void hideCursor() override;
+ bool isCursorHidden() override;
- /*virtual*/ bool isPrimaryTextAvailable();
- /*virtual*/ bool pasteTextFromPrimary(LLWString &dst);
- /*virtual*/ bool copyTextToPrimary(const LLWString & src);
+ void showCursorFromMouseMove() override;
+ void hideCursorUntilMouseMove() override;
- /*virtual*/ void flashIcon(F32 seconds);
- /*virtual*/ F32 getGamma();
- /*virtual*/ bool setGamma(const F32 gamma); // Set the gamma
- /*virtual*/ U32 getFSAASamples();
- /*virtual*/ void setFSAASamples(const U32 samples);
- /*virtual*/ bool restoreGamma(); // Restore original gamma table (before updating gamma)
- /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; }
- /*virtual*/ void processMiscNativeEvents();
- /*virtual*/ void gatherInput();
- /*virtual*/ void swapBuffers();
- /*virtual*/ void restoreGLContext() {};
+ void updateCursor() override;
- /*virtual*/ void delayInputProcessing() { };
+ void captureMouse() override;
+ void releaseMouse() override;
+
+ void setMouseClipping(bool b) override;
+
+ void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true) override;
+
+ bool isClipboardTextAvailable() override;
+ bool pasteTextFromClipboard(LLWString &dst) override;
+ bool copyTextToClipboard(const LLWString &src) override;
+
+ bool isPrimaryTextAvailable() override;
+ bool pasteTextFromPrimary(LLWString &dst) override;
+ bool copyTextToPrimary(const LLWString &src) override;
+
+ void flashIcon(F32 seconds) override;
+ void maybeStopFlashIcon();
+
+ F32 getGamma() override;
+ bool setGamma(const F32 gamma) override; // Set the gamma
+ bool restoreGamma() override; // Restore original gamma table (before updating gamma)
+
+ U32 getFSAASamples() override;
+ void setFSAASamples(const U32 samples) override;
+
+ void processMiscNativeEvents() override;
+
+ void gatherInput() override;
+
+ SDL_AppResult handleEvent(const SDL_Event& event);
+ static SDL_AppResult handleEvents(const SDL_Event& event);
+
+ void swapBuffers() override;
+
+ void delayInputProcessing() override {};
// handy coordinate space conversion routines
- /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordWindow *to);
- /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordScreen *to);
- /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordGL *to);
- /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordWindow *to);
- /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordGL *to);
- /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordScreen *to);
+ bool convertCoords(LLCoordScreen from, LLCoordWindow *to) override;
+ bool convertCoords(LLCoordWindow from, LLCoordScreen *to) override;
+ bool convertCoords(LLCoordWindow from, LLCoordGL *to) override;
+ bool convertCoords(LLCoordGL from, LLCoordWindow *to) override;
+ bool convertCoords(LLCoordScreen from, LLCoordGL *to) override;
+ bool convertCoords(LLCoordGL from, LLCoordScreen *to) override;
+
+ LLWindowResolution *getSupportedResolutions(S32 &num_resolutions) override;
- /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions);
- /*virtual*/ F32 getNativeAspectRatio();
- /*virtual*/ F32 getPixelAspectRatio();
- /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; }
+ F32 getNativeAspectRatio() override;
+ F32 getPixelAspectRatio() override;
+ void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; }
- /*virtual*/ void beforeDialog();
- /*virtual*/ void afterDialog();
+ void beforeDialog() override;
+ void afterDialog() override;
- /*virtual*/ bool dialogColorPicker(F32 *r, F32 *g, F32 *b);
+ bool dialogColorPicker(F32 *r, F32 *g, F32 *b) override;
- /*virtual*/ void *getPlatformWindow();
- /*virtual*/ void bringToFront();
+ void *getPlatformWindow() override;
- /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
+ void bringToFront() override;
+
+ void setLanguageTextInput(const LLCoordGL& pos) override;
+
+ void spawnWebBrowser(const std::string &escaped_url, bool async) override;
+
+ void setTitle(const std::string title) override;
static std::vector<std::string> getDynamicFallbackFontList();
- // Not great that these are public, but they have to be accessible
- // by non-class code and it's better than making them global.
-#if LL_X11
- Window mSDL_XWindowID;
- Display *mSDL_Display;
-#endif
- void (*Lock_Display)(void);
- void (*Unlock_Display)(void);
+ void *createSharedContext() override;
+ void makeContextCurrent(void *context) override;
+ void destroySharedContext(void *context) override;
+ void toggleVSync(bool enable_vsync) override;
-#if LL_GTK
- // Lazily initialize and check the runtime GTK version for goodness.
- static bool ll_try_gtk_init(void);
-#endif // LL_GTK
+ F32 getSystemUISize() override;
-#if LL_X11
- static Window get_SDL_XWindowID(void);
- static Display* get_SDL_Display(void);
-#endif // LL_X11
+ static std::vector<std::string> getDisplaysResolutionList();
-protected:
- LLWindowSDL(LLWindowCallbacks* callbacks,
- const std::string& title, int x, int y, int width, int height, U32 flags,
- bool fullscreen, bool clearBg, bool disable_vsync, bool use_gl,
- bool ignore_pixel_depth, U32 fsaa_samples);
- ~LLWindowSDL();
+#if LL_DARWIN
+ static U64 getVramSize();
+ static void setUseMultGL(bool use_mult_gl);
+
+ static bool sUseMultGL;
+#endif
- /*virtual*/ bool isValid();
- /*virtual*/ LLSD getNativeKeyData();
+protected:
+ LLWindowSDL(LLWindowCallbacks *callbacks,
+ const std::string &title, const std::string& name, int x, int y, int width, int height, U32 flags,
+ bool fullscreen, bool clearBg, bool enable_vsync, bool use_gl,
+ bool ignore_pixel_depth, U32 fsaa_samples);
- void initCursors();
- void quitCursors();
- void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size);
+ ~LLWindowSDL();
- // Changes display resolution. Returns true if successful
- bool setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh);
+ bool isValid() override;
- // Go back to last fullscreen display resolution.
- bool setFullscreenResolution();
+ LLSD getNativeKeyData() override;
- bool shouldPostQuit() { return mPostQuit; }
+ void initCursors();
+ void quitCursors();
protected:
//
@@ -174,47 +195,67 @@ protected:
//
// create or re-create the GL context/window. Called from the constructor and switchContext().
- bool createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool disable_vsync);
+ bool createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool enable_vsync);
void destroyContext();
- void setupFailure(const std::string& text, const std::string& caption, U32 type);
- void fixWindowSize(void);
- U32 SDLCheckGrabbyKeys(SDLKey keysym, bool gain);
+
+ void setupFailure(const std::string &text, const std::string &caption, U32 type);
+
bool SDLReallyCaptureInput(bool capture);
+ U32 SDLCheckGrabbyKeys(U32 keysym, bool gain);
//
// Platform specific variables
//
- U32 mGrabbyKeyFlags;
- int mReallyCapturedCount;
- SDL_Surface * mWindow;
- std::string mWindowTitle;
- double mOriginalAspectRatio;
- bool mNeedsResize; // Constructor figured out the window is too big, it needs a resize.
- LLCoordScreen mNeedsResizeSize;
- F32 mOverrideAspectRatio;
- F32 mGamma;
- U32 mFSAASamples;
+ U32 mGrabbyKeyFlags = 0;
+ S32 mReallyCapturedCount = 0;
+ SDL_Window *mWindow = nullptr;
+ SDL_GLContext mContext;
+ SDL_Cursor *mSDLCursors[UI_CURSOR_COUNT];
- int mSDLFlags;
-
- SDL_Cursor* mSDLCursors[UI_CURSOR_COUNT];
- int mHaveInputFocus; /* 0=no, 1=yes, else unknown */
- int mIsMinimized; /* 0=no, 1=yes, else unknown */
+ std::string mWindowTitle;
+ F32 mNativeAspectRatio = 0.0f;
+ F32 mOverrideAspectRatio = 0.0f;
+ F32 mGamma = 0.0f;
+ U32 mFSAASamples = 0;
friend class LLWindowManager;
private:
-#if LL_X11
- void x11_set_urgent(bool urgent);
- bool mFlashing;
+ bool mFlashing = false;
LLTimer mFlashTimer;
-#endif //LL_X11
+ U32 mKeyVirtualKey = 0;
+ U32 mKeyModifiers = SDL_KMOD_NONE;
- U32 mKeyScanCode;
- U32 mKeyVirtualKey;
- SDLMod mKeyModifiers;
-};
+ LLMutex mOSRMutex;
+ std::unordered_map<SDL_GLContext, SDL_Window*> mOSRContexts;
+ std::list<SDL_Window*> mDeadOSRWindows;
+
+ void tryFindFullscreenSize(int &aWidth, int &aHeight);
+ enum EServerProtocol{ X11, Wayland, Unknown };
+ EServerProtocol mServerProtocol = Unknown;
+public:
+#if LL_X11
+ // X11
+ struct X11_DATA
+ {
+ Display* xdisplay = nullptr;
+ Window xwindow = 0;
+ int xscreen = -1;
+ };
+ static X11_DATA sX11Data;
+#endif
+
+#if LL_WAYLAND
+ // Wayland
+ struct WAYLAND_DATA
+ {
+ struct wl_display* display = nullptr;
+ struct wl_surface* surface = nullptr;
+ };
+ static WAYLAND_DATA sWaylandData;
+#endif
+};
class LLSplashScreenSDL : public LLSplashScreen
{
@@ -222,9 +263,9 @@ public:
LLSplashScreenSDL();
virtual ~LLSplashScreenSDL();
- /*virtual*/ void showImpl();
- /*virtual*/ void updateImpl(const std::string& mesg);
- /*virtual*/ void hideImpl();
+ void showImpl() override;
+ void updateImpl(const std::string& mesg) override;
+ void hideImpl() override;
};
S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type);
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 824d0f5ec6..011cb0ed9d 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -204,6 +204,7 @@ HKL LLWindowWin32::sWinInputLocale = 0;
DWORD LLWindowWin32::sWinIMEConversionMode = IME_CMODE_NATIVE;
DWORD LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC;
LLCoordWindow LLWindowWin32::sWinIMEWindowPosition(-1,-1);
+HMODULE LLWindowWin32::sGLDLLHandle = nullptr;
static HWND sWindowHandleForMessageBox = NULL;
@@ -458,7 +459,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
mWindowThread = new LLWindowWin32Thread();
//MAINT-516 -- force a load of opengl32.dll just in case windows went sideways
- LoadLibrary(L"opengl32.dll");
+ sGLDLLHandle = LoadLibrary(L"opengl32.dll");
if (mMaxCores != 0)
@@ -1690,6 +1691,8 @@ const S32 max_format = (S32)num_formats - 1;
return false;
}
+ gGLManager.initWGL(); // Reinit WGL functions once we have our full context
+
if (!gGLManager.initGL())
{
LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
@@ -4660,6 +4663,18 @@ F32 LLWindowWin32::getSystemUISize()
}
//static
+PROC WINAPI LLWindowWin32::getProcAddress(const char* func)
+{
+ PROC ret_func = wglGetProcAddress(func);
+ if (!ret_func && sGLDLLHandle)
+ {
+ // Try to fallback to OpenGL32.dll
+ ret_func = GetProcAddress(sGLDLLHandle, func);
+ }
+ return ret_func;
+}
+
+//static
std::vector<std::string> LLWindowWin32::getDisplaysResolutionList()
{
return sMonitorInfo.getResolutionsList();
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 0fc93ad0b1..77217747cc 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -125,6 +125,7 @@ public:
LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url );
+ static PROC WINAPI getProcAddress(const char* func);
static std::vector<std::string> getDisplaysResolutionList();
static std::vector<std::string> getDynamicFallbackFontList();
static void setDPIAwareness();
@@ -244,6 +245,8 @@ protected:
bool mMouseVanish;
+ static HMODULE sGLDLLHandle;
+
// Cached values of GetWindowRect and GetClientRect to be used by app thread
void updateWindowRect();
RECT mRect;
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index 508c2b919b..bc79e2ef19 100644
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -34,6 +34,9 @@ target_link_libraries( llxml
)
target_include_directories( llxml INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llxml REUSE_FROM llprecompiled)
+endif ()
# tests
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
index 972bb7dd2d..600db532d2 100644
--- a/indra/media_plugins/CMakeLists.txt
+++ b/indra/media_plugins/CMakeLists.txt
@@ -1,20 +1,10 @@
# -*- cmake -*-
add_subdirectory(base)
+add_subdirectory(cef)
+add_subdirectory(libvlc)
+add_subdirectory(example)
if (LINUX)
- #add_subdirectory(gstreamer010)
- add_subdirectory(example)
+ add_subdirectory(gstreamer10)
endif (LINUX)
-
-if (DARWIN)
- add_subdirectory(cef)
- add_subdirectory(libvlc)
- add_subdirectory(example)
-endif (DARWIN)
-
-if (WINDOWS)
- add_subdirectory(cef)
- add_subdirectory(libvlc)
- add_subdirectory(example)
-endif (WINDOWS)
diff --git a/indra/media_plugins/base/media_plugin_base.cpp b/indra/media_plugins/base/media_plugin_base.cpp
index ccaa43cfb5..2e1e43d9e8 100644
--- a/indra/media_plugins/base/media_plugin_base.cpp
+++ b/indra/media_plugins/base/media_plugin_base.cpp
@@ -167,6 +167,55 @@ void MediaPluginBase::sendStatus()
sendMessage(message);
}
+#if LL_LINUX
+
+#include <dlfcn.h>
+
+size_t SymbolGrabber::registerSymbol( SymbolToGrab aSymbol )
+{
+ gSymbolsToGrab.emplace_back(aSymbol);
+ return gSymbolsToGrab.size();
+}
+
+bool SymbolGrabber::grabSymbols(std::vector< std::string > const &aDSONames)
+{
+ if (sSymsGrabbed)
+ return true;
+
+ for( std::vector< std::string >::const_iterator itr = aDSONames.begin(); itr != aDSONames.end(); ++itr )
+ {
+ auto pDSO = dlopen( itr->c_str(), RTLD_NOW );
+
+ if( pDSO )
+ {
+ sLoadedLibraries.push_back(pDSO);
+
+ for (auto i = 0; i < gSymbolsToGrab.size(); ++i)
+ {
+ if (!*gSymbolsToGrab[i].mPPFunc)
+ *gSymbolsToGrab[i].mPPFunc = dlsym(pDSO, gSymbolsToGrab[i].mName);
+ }
+ }
+ }
+
+ bool sym_error = false;
+
+ for( auto i = 0; i < gSymbolsToGrab.size(); ++i )
+ {
+ if( gSymbolsToGrab[ i ].mRequired && ! *gSymbolsToGrab[ i ].mPPFunc )
+ sym_error = true;
+ }
+
+ sSymsGrabbed = !sym_error;
+ return sSymsGrabbed;
+}
+
+void SymbolGrabber::ungrabSymbols()
+{
+
+}
+#endif
+
#if LL_WINDOWS
# define LLSYMEXPORT __declspec(dllexport)
@@ -202,3 +251,50 @@ int WINAPI DllEntryPoint( HINSTANCE hInstance, unsigned long reason, void* param
return 1;
}
#endif
+
+#if LL_LINUX
+pid_t getParentPid( pid_t aPid )
+{
+ std::stringstream strm;
+ strm << "/proc/" << aPid << "/status";
+ std::ifstream in{ strm.str() };
+
+ if( !in.is_open() )
+ return 0;
+
+ pid_t res {0};
+ while( !in.eof() && res == 0 )
+ {
+ std::string line;
+ line.resize( 1024, 0 );
+ in.getline( &line[0], line.length() );
+
+ auto i = line.find( "PPid:" );
+
+ if( i == std::string::npos )
+ continue;
+
+ char const *pIn = line.c_str() + 5; // Skip over pid;
+ while( *pIn != 0 && isspace( *pIn ) )
+ ++pIn;
+
+ if( *pIn )
+ res = atoll( pIn );
+ }
+ return res;
+}
+
+bool isPluginPid( pid_t aPid )
+{
+ auto myPid = getpid();
+
+ do
+ {
+ if( aPid == myPid )
+ return true;
+ aPid = getParentPid( aPid );
+ } while( aPid > 1 );
+
+ return false;
+}
+#endif
diff --git a/indra/media_plugins/base/media_plugin_base.h b/indra/media_plugins/base/media_plugin_base.h
index f65c712a66..0f014f8335 100644
--- a/indra/media_plugins/base/media_plugin_base.h
+++ b/indra/media_plugins/base/media_plugin_base.h
@@ -32,6 +32,40 @@
#include "llpluginmessage.h"
#include "llpluginmessageclasses.h"
+#if LL_LINUX
+
+struct SymbolToGrab
+{
+ bool mRequired;
+ char const *mName;
+ void **mPPFunc;
+};
+
+class SymbolGrabber
+{
+public:
+ size_t registerSymbol( SymbolToGrab aSymbol );
+ bool grabSymbols(std::vector< std::string > const &aDSONames);
+ void ungrabSymbols();
+
+private:
+ std::vector< SymbolToGrab > gSymbolsToGrab;
+
+ bool sSymsGrabbed = false;
+ std::vector<void *> sLoadedLibraries;
+};
+
+extern SymbolGrabber gSymbolGrabber;
+
+// extern SymbolGrabber gSymbolGrabber;
+
+#define LL_GRAB_SYM(SYMBOL_GRABBER, REQUIRED, SYMBOL_NAME, RETURN, ...) \
+ RETURN (*ll##SYMBOL_NAME)(__VA_ARGS__) = nullptr; \
+ size_t gRegistered##SYMBOL_NAME = SYMBOL_GRABBER.registerSymbol( \
+ { REQUIRED, #SYMBOL_NAME , (void**)&ll##SYMBOL_NAME} \
+ );
+
+#endif
class MediaPluginBase
{
@@ -126,4 +160,7 @@ int init_media_plugin(
LLPluginInstance::sendMessageFunction *plugin_send_func,
void **plugin_user_data);
-
+#if LL_LINUX
+pid_t getParentPid(pid_t aPid);
+bool isPluginPid(pid_t aPid);
+#endif
diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index dc2d82017d..3a91e398d5 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -10,7 +10,7 @@ include(Linking)
include(PluginAPI)
include(CEFPlugin)
-
+include(GLIB)
### media_plugin_cef
@@ -23,20 +23,38 @@ set(media_plugin_cef_HEADER_FILES
)
# Select which VolumeCatcher implementation to use
-if (LINUX)
- message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n"
- " Please create a volume_catcher implementation for this platform.")
-elseif (DARWIN)
- list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher_null.cpp)
- find_library(CORESERVICES_LIBRARY CoreServices)
- find_library(AUDIOUNIT_LIBRARY AudioUnit)
- set( media_plugin_cef_LINK_LIBRARIES
- ${CORESERVICES_LIBRARY} # for Component Manager calls
- ${AUDIOUNIT_LIBRARY} # for AudioUnit calls
- )
+if (FALSE) # Disable linux volume catcher due to issues dlopening with CEF 139
+ foreach( PULSE_FILE pulse/introspect.h pulse/context.h pulse/subscribe.h pulse/glib-mainloop.h )
+ find_path( PULSE_FILE_${PULSE_FILE}_FOUND ${PULSE_FILE} NO_CACHE)
+ if( NOT PULSE_FILE_${PULSE_FILE}_FOUND )
+ message( "Looking for ${PULSE_FILE} ... not found")
+ message( FATAL_ERROR "Pulse header not found" )
+ else()
+ message( "Looking for ${PULSE_FILE} ... found")
+ endif()
+ endforeach()
+
+ include(FindPipeWire)
+ include_directories(SYSTEM ${PIPEWIRE_INCLUDE_DIRS} ${SPA_INCLUDE_DIRS})
+
+ message( "Building with Linux volume catcher for PipeWire and PulseAudio" )
+
+ list(APPEND media_plugin_cef_HEADER_FILES
+ linux/volume_catcher_linux.h
+ )
+
+ set(LINUX_VOLUME_CATCHER
+ linux/volume_catcher_linux.cpp
+ linux/volume_catcher_pulseaudio.cpp
+ linux/volume_catcher_pipewire.cpp
+ )
+
+ list(APPEND media_plugin_cef_SOURCE_FILES ${LINUX_VOLUME_CATCHER})
elseif (WINDOWS)
list(APPEND media_plugin_cef_SOURCE_FILES windows_volume_catcher.cpp)
-endif (LINUX)
+else()
+ list(APPEND media_plugin_cef_SOURCE_FILES volume_catcher_null.cpp)
+endif ()
list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES})
@@ -45,13 +63,10 @@ add_library(media_plugin_cef
${media_plugin_cef_SOURCE_FILES}
)
-#add_dependencies(media_plugin_cef
-# ${MEDIA_PLUGIN_BASE_LIBRARIES}
-#)
-
target_link_libraries(media_plugin_cef
media_plugin_base
ll::cef
+ ll::glib_headers
)
if (WINDOWS)
@@ -60,9 +75,15 @@ if (WINDOWS)
PROPERTIES
LINK_FLAGS "/MANIFEST:NO /NODEFAULTLIB:LIBCMT /IGNORE:4099"
)
-endif (WINDOWS)
+elseif (DARWIN)
+ find_library(CORESERVICES_LIBRARY CoreServices)
+ find_library(AUDIOUNIT_LIBRARY AudioUnit)
+
+ target_link_libraries(media_plugin_cef
+ ${CORESERVICES_LIBRARY} # for Component Manager calls
+ ${AUDIOUNIT_LIBRARY} # for AudioUnit calls
+ )
-if (DARWIN)
# Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name
set_target_properties(
media_plugin_cef
@@ -73,4 +94,6 @@ if (DARWIN)
LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp"
)
-endif (DARWIN)
+elseif (LINUX)
+ target_link_options(media_plugin_cef PRIVATE "LINKER:--build-id" "LINKER:-rpath,'$ORIGIN:$ORIGIN/../../lib'")
+endif ()
diff --git a/indra/media_plugins/cef/linux/volume_catcher_linux.cpp b/indra/media_plugins/cef/linux/volume_catcher_linux.cpp
new file mode 100644
index 0000000000..7d33242063
--- /dev/null
+++ b/indra/media_plugins/cef/linux/volume_catcher_linux.cpp
@@ -0,0 +1,78 @@
+/**
+ * @file volume_catcher.cpp
+ * @brief Linux volume catcher which will pick an implementation to use
+ *
+ * @cond
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ * @endcond
+ */
+
+#include "volume_catcher_linux.h"
+
+VolumeCatcher::VolumeCatcher()
+{
+}
+
+void VolumeCatcher::onEnablePipeWireVolumeCatcher(bool enable)
+{
+ if (pimpl != nullptr)
+ return;
+
+ if (enable)
+ {
+ LL_DEBUGS() << "volume catcher using pipewire" << LL_ENDL;
+ pimpl = new VolumeCatcherPipeWire();
+ }
+ else
+ {
+ LL_DEBUGS() << "volume catcher using pulseaudio" << LL_ENDL;
+ pimpl = new VolumeCatcherPulseAudio();
+ }
+}
+
+VolumeCatcher::~VolumeCatcher()
+{
+ if (pimpl != nullptr)
+ {
+ delete pimpl;
+ pimpl = nullptr;
+ }
+}
+
+void VolumeCatcher::setVolume(F32 volume)
+{
+ if (pimpl != nullptr) {
+ pimpl->setVolume(volume);
+ }
+}
+
+void VolumeCatcher::setPan(F32 pan)
+{
+ if (pimpl != nullptr)
+ pimpl->setPan(pan);
+}
+
+void VolumeCatcher::pump()
+{
+ if (pimpl != nullptr)
+ pimpl->pump();
+}
diff --git a/indra/media_plugins/cef/linux/volume_catcher_linux.h b/indra/media_plugins/cef/linux/volume_catcher_linux.h
new file mode 100644
index 0000000000..505f9ffb31
--- /dev/null
+++ b/indra/media_plugins/cef/linux/volume_catcher_linux.h
@@ -0,0 +1,149 @@
+/**
+ * @file volume_catcher_impl.h
+ * @brief
+ *
+ * @cond
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ * @endcond
+ */
+
+#ifndef VOLUME_CATCHER_LINUX_H
+#define VOLUME_CATCHER_LINUX_H
+
+#include "linden_common.h"
+
+#include "../volume_catcher.h"
+
+#include <unordered_set>
+#include <mutex>
+
+extern "C" {
+// There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken.
+#include <pulse/glib-mainloop.h>
+#include <pulse/context.h>
+
+#include <pipewire/pipewire.h>
+
+#include "apr_pools.h"
+#include "apr_dso.h"
+}
+
+#include "media_plugin_base.h"
+
+class VolumeCatcherImpl
+{
+public:
+ virtual ~VolumeCatcherImpl() = default;
+
+ virtual void setVolume(F32 volume) = 0; // 0.0 - 1.0
+
+ // Set the left-right pan of audio sources
+ // where -1.0 = left, 0 = center, and 1.0 = right
+ virtual void setPan(F32 pan) = 0;
+
+ virtual void pump() = 0; // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume
+};
+
+class VolumeCatcherPulseAudio : public VolumeCatcherImpl
+{
+public:
+ VolumeCatcherPulseAudio();
+ ~VolumeCatcherPulseAudio();
+
+ void setVolume(F32 volume);
+ void setPan(F32 pan);
+ void pump();
+
+ // for internal use - can't be private because used from our C callbacks
+
+ bool loadsyms(std::string pa_dso_name);
+ void init();
+ void cleanup();
+
+ void update_all_volumes(F32 volume);
+ void update_index_volume(U32 index, F32 volume);
+ void connected_okay();
+
+ std::set<U32> mSinkInputIndices;
+ std::map<U32,U32> mSinkInputNumChannels;
+ F32 mDesiredVolume;
+ pa_glib_mainloop *mMainloop;
+ pa_context *mPAContext;
+ bool mConnected;
+ bool mGotSyms;
+};
+
+class VolumeCatcherPipeWire : public VolumeCatcherImpl
+{
+public:
+ VolumeCatcherPipeWire();
+ ~VolumeCatcherPipeWire();
+
+ bool loadsyms(std::string pw_dso_name);
+ void init();
+ void cleanup();
+
+ // some of these should be private
+
+ void lock();
+ void unlock();
+
+ void setVolume(F32 volume);
+ void setPan(F32 pan);
+ void pump();
+
+ void handleRegistryEventGlobal(
+ uint32_t id, uint32_t permissions, const char* type,
+ uint32_t version, const struct spa_dict* props
+ );
+
+ class ChildNode
+ {
+ public:
+ bool mActive = false;
+
+ pw_proxy* mProxy = nullptr;
+ spa_hook mNodeListener {};
+ spa_hook mProxyListener {};
+ VolumeCatcherPipeWire* mImpl = nullptr;
+
+ void updateVolume();
+ void destroy();
+ };
+
+ bool mGotSyms = false;
+
+ F32 mVolume = 1.0f; // max by default
+ // F32 mPan = 0.0f; // center
+
+ pw_thread_loop* mThreadLoop = nullptr;
+ pw_context* mContext = nullptr;
+ pw_core* mCore = nullptr;
+ pw_registry* mRegistry = nullptr;
+ spa_hook mRegistryListener;
+
+ std::unordered_set<ChildNode*> mChildNodes;
+ std::mutex mChildNodesMutex;
+ std::mutex mCleanupMutex;
+};
+
+#endif // VOLUME_CATCHER_LINUX_H
diff --git a/indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp b/indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp
new file mode 100755
index 0000000000..73ef7fc18c
--- /dev/null
+++ b/indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp
@@ -0,0 +1,333 @@
+/**
+ * @file volume_catcher_pipewire.cpp
+ * @brief A Linux-specific, PipeWire-specific hack to detect and volume-adjust new audio sources
+ *
+ * @cond
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ * @endcond
+ */
+
+/*
+ The high-level design is as follows:
+ 1) Connect to the PipeWire daemon
+ 2) Find all existing and new audio nodes
+ 3) Examine PID and parent PID's to see if it belongs to our process
+ 4) If so, tell PipeWire to adjust the volume of that node
+ 5) Keep a list of all audio nodes and adjust when we setVolume()
+ */
+
+#include "linden_common.h"
+
+#include "volume_catcher_linux.h"
+
+extern "C" {
+#include <spa/pod/builder.h>
+#include <spa/param/props.h>
+}
+
+SymbolGrabber pwSymbolGrabber;
+
+#include "volume_catcher_pipewire_syms.inc"
+
+////////////////////////////////////////////////////
+
+VolumeCatcherPipeWire::VolumeCatcherPipeWire()
+{
+ init();
+}
+
+VolumeCatcherPipeWire::~VolumeCatcherPipeWire()
+{
+ cleanup();
+}
+
+static void registryEventGlobal(
+ void *data, uint32_t id, uint32_t permissions, const char *type,
+ uint32_t version, const struct spa_dict *props)
+{
+ static_cast<VolumeCatcherPipeWire*>(data)->handleRegistryEventGlobal(
+ id, permissions, type, version, props
+ );
+}
+
+static const struct pw_registry_events REGISTRY_EVENTS = {
+ .version = PW_VERSION_REGISTRY_EVENTS,
+ .global = registryEventGlobal,
+};
+
+bool VolumeCatcherPipeWire::loadsyms(std::string pw_dso_name)
+{
+ return pwSymbolGrabber.grabSymbols({ pw_dso_name });
+}
+
+void VolumeCatcherPipeWire::init()
+{
+ LL_DEBUGS() << "init" << LL_ENDL;
+
+ mGotSyms = loadsyms("libpipewire-0.3.so.0");
+
+ if (!mGotSyms)
+ return;
+
+ LL_DEBUGS() << "successfully got symbols" << LL_ENDL;
+
+ llpw_init(nullptr, nullptr);
+
+ mThreadLoop = llpw_thread_loop_new("SL Plugin Volume Adjuster", nullptr);
+
+ if (!mThreadLoop)
+ return;
+
+ // i dont think we need to lock this early
+ // std::lock_guard pwLock(*this);
+
+ mContext = llpw_context_new(
+ llpw_thread_loop_get_loop(mThreadLoop), nullptr, 0
+ );
+
+ if (!mContext)
+ return;
+
+ mCore = llpw_context_connect(mContext, nullptr, 0);
+
+ if (!mCore)
+ return;
+
+ mRegistry = pw_core_get_registry(mCore, PW_VERSION_REGISTRY, 0);
+
+ LL_DEBUGS() << "pw_core_get_registry: " << (mRegistry?"success":"nullptr") << LL_ENDL;
+
+ spa_zero(mRegistryListener);
+
+ pw_registry_add_listener(
+ mRegistry, &mRegistryListener, &REGISTRY_EVENTS, this
+ );
+
+ llpw_thread_loop_start(mThreadLoop);
+
+ LL_DEBUGS() << "thread loop started" << LL_ENDL;
+}
+
+void VolumeCatcherPipeWire::cleanup()
+{
+ {
+ std::unique_lock childNodesLock(mChildNodesMutex);
+ for (auto *childNode: mChildNodes)
+ childNode->destroy();
+
+ mChildNodes.clear();
+ }
+
+ {
+ std::unique_lock pwLock(mCleanupMutex);
+ if (mRegistry)
+ llpw_proxy_destroy((struct pw_proxy *) mRegistry);
+
+ spa_zero(mRegistryListener);
+
+ if (mCore)
+ llpw_core_disconnect(mCore);
+ if (mContext)
+ llpw_context_destroy(mContext);
+ }
+
+ if (!mThreadLoop)
+ return;
+
+ llpw_thread_loop_stop(mThreadLoop);
+ llpw_thread_loop_destroy(mThreadLoop);
+
+ LL_DEBUGS() << "cleanup done" << LL_ENDL;
+}
+
+void VolumeCatcherPipeWire::lock()
+{
+ if (!mThreadLoop)
+ return;
+
+ llpw_thread_loop_lock(mThreadLoop);
+}
+
+void VolumeCatcherPipeWire::unlock()
+{
+ if (!mThreadLoop)
+ return;
+
+ llpw_thread_loop_unlock(mThreadLoop);
+}
+
+const uint32_t channels = 1;
+const float resetVolumes[channels] = { 1.0f };
+
+void VolumeCatcherPipeWire::ChildNode::updateVolume()
+{
+ if (!mActive)
+ return;
+
+ F32 volume = std::clamp(mImpl->mVolume, 0.0f, 1.0f);
+
+ const float volumes[channels] = { volume };
+
+ uint8_t buffer[512];
+
+ spa_pod_builder builder;
+ spa_pod_builder_init(&builder, buffer, sizeof(buffer));
+
+ spa_pod_frame frame;
+ spa_pod_builder_push_object(&builder, &frame, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
+
+ // resets system-wide memorized volume for chromium (not google chrome) to 100%
+ spa_pod_builder_prop(&builder, SPA_PROP_channelVolumes, 0);
+ spa_pod_builder_array(&builder, sizeof(float), SPA_TYPE_Float, channels, resetVolumes);
+
+ // sets temporary volume
+ spa_pod_builder_prop(&builder, SPA_PROP_softVolumes, 0);
+ spa_pod_builder_array(&builder, sizeof(float), SPA_TYPE_Float, channels, volumes);
+
+ spa_pod* pod = static_cast<spa_pod*>(spa_pod_builder_pop(&builder, &frame));
+
+ {
+ std::lock_guard pwLock(*mImpl);
+ pw_node_set_param((pw_node*)mProxy, SPA_PARAM_Props, 0, pod);
+ }
+}
+
+void VolumeCatcherPipeWire::ChildNode::destroy()
+{
+ if (!mActive)
+ return;
+
+ mActive = false;
+
+ {
+ std::unique_lock childNodesLock(mImpl->mChildNodesMutex);
+ mImpl->mChildNodes.erase(this);
+ }
+
+ spa_hook_remove(&mNodeListener);
+ spa_hook_remove(&mProxyListener);
+
+ {
+ std::lock_guard pwLock(*mImpl);
+ llpw_proxy_destroy(mProxy);
+ }
+}
+
+static void nodeEventInfo(void* data, const struct pw_node_info* info)
+{
+ const char* processId = spa_dict_lookup(info->props, PW_KEY_APP_PROCESS_ID);
+
+ if (processId == nullptr)
+ return;
+
+ pid_t pid = atoll(processId);
+
+ if (!isPluginPid(pid))
+ return;
+
+ const char* appName = spa_dict_lookup(info->props, PW_KEY_APP_NAME);
+ LL_DEBUGS() << "got app: " << appName << LL_ENDL;
+
+ auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data);
+ LL_DEBUGS() << "init volume: " << childNode->mImpl->mVolume << LL_ENDL;
+
+ childNode->updateVolume();
+
+ {
+ std::lock_guard childNodesLock(childNode->mImpl->mChildNodesMutex);
+ childNode->mImpl->mChildNodes.insert(childNode);
+ }
+}
+
+static const struct pw_node_events NODE_EVENTS = {
+ .version = PW_VERSION_CLIENT_EVENTS,
+ .info = nodeEventInfo,
+};
+
+static void proxyEventDestroy(void* data)
+{
+ auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data);
+ childNode->destroy();
+}
+
+static void proxyEventRemoved(void* data)
+{
+ auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data);
+ childNode->destroy();
+}
+
+static const struct pw_proxy_events PROXY_EVENTS = {
+ .version = PW_VERSION_PROXY_EVENTS,
+ .destroy = proxyEventDestroy,
+ .removed = proxyEventRemoved,
+};
+
+void VolumeCatcherPipeWire::handleRegistryEventGlobal(
+ uint32_t id, uint32_t permissions, const char *type, uint32_t version,
+ const struct spa_dict *props)
+{
+ if (props == nullptr || type == nullptr || strcmp(type, PW_TYPE_INTERFACE_Node) != 0)
+ return;
+
+ const char* mediaClass = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
+
+ if (mediaClass == nullptr || strcmp(mediaClass, "Stream/Output/Audio") != 0)
+ return;
+
+ pw_proxy* proxy = static_cast<pw_proxy*>(
+ pw_registry_bind(mRegistry, id, type, PW_VERSION_CLIENT, sizeof(ChildNode))
+ );
+
+ auto* const childNode = static_cast<ChildNode*>(llpw_proxy_get_user_data(proxy));
+
+ childNode->mActive = true;
+ childNode->mProxy = proxy;
+ childNode->mImpl = this;
+
+ pw_node_add_listener((pw_node*)proxy, &childNode->mNodeListener, &NODE_EVENTS, childNode);
+ llpw_proxy_add_listener(proxy, &childNode->mProxyListener, &PROXY_EVENTS, childNode);
+}
+
+void VolumeCatcherPipeWire::setVolume(F32 volume)
+{
+ LL_DEBUGS() << "setting volume to: " << volume << LL_ENDL;
+
+ mVolume = volume;
+
+ {
+ std::unique_lock childNodeslock(mChildNodesMutex);
+ std::unordered_set<ChildNode *> copyOfChildNodes(mChildNodes);
+
+ LL_DEBUGS() << "found " << copyOfChildNodes.size() << " child nodes" << LL_ENDL;
+
+ for (auto* childNode : copyOfChildNodes)
+ childNode->updateVolume();
+ }
+}
+
+void VolumeCatcherPipeWire::setPan(F32 pan)
+{
+}
+
+void VolumeCatcherPipeWire::pump()
+{
+}
diff --git a/indra/media_plugins/cef/linux/volume_catcher_pipewire_syms.inc b/indra/media_plugins/cef/linux/volume_catcher_pipewire_syms.inc
new file mode 100644
index 0000000000..dbc0f5f169
--- /dev/null
+++ b/indra/media_plugins/cef/linux/volume_catcher_pipewire_syms.inc
@@ -0,0 +1,26 @@
+#define G pwSymbolGrabber
+
+// required symbols to grab
+LL_GRAB_SYM(G, true, pw_init, void, int *argc, char **argv[]);
+// LL_GRAB_SYM(G, true, pw_main_loop_new, struct pw_main_loop *, const struct spa_dict *props);
+// LL_GRAB_SYM(G, true, pw_main_loop_get_loop, struct pw_loop *, struct pw_main_loop *loop);
+// LL_GRAB_SYM(G, true, pw_main_loop_destroy, void, struct pw_main_loop *loop);
+// LL_GRAB_SYM(G, true, pw_main_loop_run, void, struct pw_main_loop *loop);
+LL_GRAB_SYM(G, true, pw_context_new, struct pw_context *, struct pw_loop *main_loop, struct pw_properties *props, size_t user_data_size);
+LL_GRAB_SYM(G, true, pw_context_destroy, void, struct pw_context *context);
+LL_GRAB_SYM(G, true, pw_context_connect, struct pw_core *, struct pw_context *context, struct pw_properties *properties, size_t user_data_size);
+LL_GRAB_SYM(G, true, pw_thread_loop_new, struct pw_thread_loop *, const char *name, const struct spa_dict *props);
+LL_GRAB_SYM(G, true, pw_thread_loop_destroy, void, struct pw_thread_loop *loop);
+LL_GRAB_SYM(G, true, pw_thread_loop_get_loop, struct pw_loop *, struct pw_thread_loop *loop);
+LL_GRAB_SYM(G, true, pw_thread_loop_start, int, struct pw_thread_loop *loop);
+LL_GRAB_SYM(G, true, pw_thread_loop_stop, void, struct pw_thread_loop *loop);
+LL_GRAB_SYM(G, true, pw_thread_loop_lock, void, struct pw_thread_loop *loop);
+LL_GRAB_SYM(G, true, pw_thread_loop_unlock, void, struct pw_thread_loop *loop);
+LL_GRAB_SYM(G, true, pw_proxy_add_listener, void, struct pw_proxy *proxy, struct spa_hook *listener, const struct pw_proxy_events *events, void *data);
+LL_GRAB_SYM(G, true, pw_proxy_destroy, void, struct pw_proxy *proxy);
+LL_GRAB_SYM(G, true, pw_proxy_get_user_data, void *, struct pw_proxy *proxy);
+LL_GRAB_SYM(G, true, pw_core_disconnect, int, struct pw_core *core);
+
+// optional symbols to grab
+
+#undef G
diff --git a/indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp
new file mode 100755
index 0000000000..f8a48a91fd
--- /dev/null
+++ b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp
@@ -0,0 +1,322 @@
+/**
+ * @file volume_catcher_pulseaudio.cpp
+ * @brief A Linux-specific, PulseAudio-specific hack to detect and volume-adjust new audio sources
+ *
+ * @cond
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ * @endcond
+ */
+
+/*
+ The high-level design is as follows:
+ 1) Connect to the PulseAudio daemon
+ 2) Watch for the creation of new audio players connecting to the daemon (this includes ALSA clients running on the PulseAudio emulation layer, such as Flash plugins)
+ 3) Examine any new audio player's PID to see if it belongs to our own process
+ 4) If so, tell PA to adjust the volume of that audio player ('sink input' in PA parlance)
+ 5) Keep a list of all living audio players that we care about, adjust the volumes of all of them when we get a new setVolume() call
+ */
+
+#include "linden_common.h"
+
+#include "volume_catcher_linux.h"
+
+extern "C" {
+#include <glib.h>
+#include <glib-object.h>
+
+#include <pulse/introspect.h>
+
+#include <pulse/subscribe.h>
+}
+
+SymbolGrabber paSymbolGrabber;
+
+#include "volume_catcher_pulseaudio_syms.inc"
+#include "volume_catcher_pulseaudio_glib_syms.inc"
+
+////////////////////////////////////////////////////
+
+// PulseAudio requires a chain of callbacks with C linkage
+extern "C" {
+ void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata);
+ void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata);
+ void callback_context_state(pa_context *context, void *userdata);
+}
+
+VolumeCatcherPulseAudio::VolumeCatcherPulseAudio()
+ : mDesiredVolume(0.0f),
+ mMainloop(nullptr),
+ mPAContext(nullptr),
+ mConnected(false),
+ mGotSyms(false)
+{
+ init();
+}
+
+VolumeCatcherPulseAudio::~VolumeCatcherPulseAudio()
+{
+ cleanup();
+}
+
+bool VolumeCatcherPulseAudio::loadsyms(std::string pulse_dso_name)
+{
+ return paSymbolGrabber.grabSymbols({ pulse_dso_name });
+}
+
+void VolumeCatcherPulseAudio::init()
+{
+ // try to be as defensive as possible because PA's interface is a
+ // bit fragile and (for our purposes) we'd rather simply not function
+ // than crash
+
+ // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in
+ // libpulse.so.0 - this isn't a great assumption, and the two DSOs should
+ // probably be loaded separately. Our Linux DSO framework needs refactoring,
+ // we do this sort of thing a lot with practically identical logic...
+ mGotSyms = loadsyms("libpulse-mainloop-glib.so.0");
+
+ if (!mGotSyms)
+ mGotSyms = loadsyms("libpulse.so.0");
+
+ if (!mGotSyms)
+ return;
+
+ mMainloop = llpa_glib_mainloop_new(g_main_context_default());
+
+ if (mMainloop)
+ {
+ pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop);
+
+ if (api)
+ {
+ pa_proplist *proplist = llpa_proplist_new();
+
+ if (proplist)
+ {
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player");
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust");
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster");
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1");
+
+ // plain old pa_context_new() is broken!
+ mPAContext = llpa_context_new_with_proplist(api, nullptr, proplist);
+
+ llpa_proplist_free(proplist);
+ }
+ }
+ }
+
+ // Now we've set up a PA context and mainloop, try connecting the
+ // PA context to a PA daemon.
+ if (mPAContext)
+ {
+ llpa_context_set_state_callback(mPAContext, callback_context_state, this);
+ pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN?
+ if (llpa_context_connect(mPAContext, nullptr, cflags, nullptr) >= 0)
+ {
+ // Okay! We haven't definitely connected, but we
+ // haven't definitely failed yet.
+ }
+ else
+ {
+ // Failed to connect to PA manager... we'll leave
+ // things like that. Perhaps we should try again later.
+ }
+ }
+}
+
+void VolumeCatcherPulseAudio::cleanup()
+{
+ mConnected = false;
+
+ if (mGotSyms && mPAContext)
+ {
+ llpa_context_disconnect(mPAContext);
+ llpa_context_unref(mPAContext);
+ }
+
+ mPAContext = nullptr;
+
+ if (mGotSyms && mMainloop)
+ llpa_glib_mainloop_free(mMainloop);
+
+ mMainloop = nullptr;
+}
+
+void VolumeCatcherPulseAudio::setVolume(F32 volume)
+{
+ mDesiredVolume = volume;
+
+ if (!mGotSyms)
+ return;
+
+ if (mConnected && mPAContext)
+ {
+ update_all_volumes(mDesiredVolume);
+ }
+
+ pump();
+}
+
+void VolumeCatcherPulseAudio::setPan(F32 pan)
+{
+}
+
+void VolumeCatcherPulseAudio::pump()
+{
+ gboolean may_block = FALSE;
+ g_main_context_iteration(g_main_context_default(), may_block);
+}
+
+void VolumeCatcherPulseAudio::connected_okay()
+{
+ pa_operation *op;
+
+ // fetch global list of existing sinkinputs
+ if ((op = llpa_context_get_sink_input_info_list(mPAContext,
+ callback_discovered_sinkinput,
+ this)))
+ {
+ llpa_operation_unref(op);
+ }
+
+ // subscribe to future global sinkinput changes
+ llpa_context_set_subscribe_callback(mPAContext,
+ callback_subscription_alert,
+ this);
+ if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t)
+ (PA_SUBSCRIPTION_MASK_SINK_INPUT),
+ nullptr, nullptr)))
+ {
+ llpa_operation_unref(op);
+ }
+}
+
+void VolumeCatcherPulseAudio::update_all_volumes(F32 volume)
+{
+ for (std::set<U32>::iterator it = mSinkInputIndices.begin();
+ it != mSinkInputIndices.end(); ++it)
+ {
+ update_index_volume(*it, volume);
+ }
+}
+
+void VolumeCatcherPulseAudio::update_index_volume(U32 index, F32 volume)
+{
+ static pa_cvolume cvol;
+ llpa_cvolume_set(&cvol, mSinkInputNumChannels[index],
+ llpa_sw_volume_from_linear(volume));
+
+ pa_context *c = mPAContext;
+ uint32_t idx = index;
+ const pa_cvolume *cvolumep = &cvol;
+ pa_context_success_cb_t cb = nullptr; // okay as null
+ void *userdata = nullptr; // okay as null
+
+ pa_operation *op;
+ if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata)))
+ llpa_operation_unref(op);
+}
+
+void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata)
+{
+ VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata);
+ llassert(impl);
+
+ if (0 == eol)
+ {
+ pa_proplist *proplist = sii->proplist;
+ pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID));
+
+ if (isPluginPid( sinkpid )) // does the discovered sinkinput belong to this process?
+ {
+ bool is_new = (impl->mSinkInputIndices.find(sii->index) == impl->mSinkInputIndices.end());
+
+ impl->mSinkInputIndices.insert(sii->index);
+ impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels;
+
+ if (is_new)
+ {
+ // new!
+ impl->update_index_volume(sii->index, impl->mDesiredVolume);
+ }
+ else
+ {
+ // seen it already, do nothing.
+ }
+ }
+ }
+}
+
+void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata)
+{
+ VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata);
+ llassert(impl);
+
+ switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK)
+ {
+ case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
+ if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
+ {
+ // forget this sinkinput, if we were caring about it
+ impl->mSinkInputIndices.erase(index);
+ impl->mSinkInputNumChannels.erase(index);
+ }
+ else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
+ {
+ // ask for more info about this new sinkinput
+ pa_operation *op;
+ if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl)))
+ {
+ llpa_operation_unref(op);
+ }
+ }
+ else
+ {
+ // property change on this sinkinput - we don't care.
+ }
+ break;
+
+ default:;
+ }
+}
+
+void callback_context_state(pa_context *context, void *userdata)
+{
+ VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata);
+ llassert(impl);
+
+ switch (llpa_context_get_state(context))
+ {
+ case PA_CONTEXT_READY:
+ impl->mConnected = true;
+ impl->connected_okay();
+ break;
+ case PA_CONTEXT_TERMINATED:
+ impl->mConnected = false;
+ break;
+ case PA_CONTEXT_FAILED:
+ impl->mConnected = false;
+ break;
+ default:;
+ }
+}
diff --git a/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_glib_syms.inc b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_glib_syms.inc
new file mode 100755
index 0000000000..e9b7196e51
--- /dev/null
+++ b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_glib_syms.inc
@@ -0,0 +1,10 @@
+#define G paSymbolGrabber
+
+// required symbols to grab
+LL_GRAB_SYM(G, true, pa_glib_mainloop_free, void, pa_glib_mainloop* g)
+LL_GRAB_SYM(G, true, pa_glib_mainloop_get_api, pa_mainloop_api*, pa_glib_mainloop* g)
+LL_GRAB_SYM(G, true, pa_glib_mainloop_new, pa_glib_mainloop *, GMainContext *c)
+
+// optional symbols to grab
+
+#undef G
diff --git a/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_syms.inc b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_syms.inc
new file mode 100755
index 0000000000..4859a34405
--- /dev/null
+++ b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_syms.inc
@@ -0,0 +1,29 @@
+#define G paSymbolGrabber
+
+// required symbols to grab
+LL_GRAB_SYM(G, true, pa_context_connect, int, pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api)
+LL_GRAB_SYM(G, true, pa_context_disconnect, void, pa_context *c)
+LL_GRAB_SYM(G, true, pa_context_get_sink_input_info, pa_operation*, pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata)
+LL_GRAB_SYM(G, true, pa_context_get_sink_input_info_list, pa_operation*, pa_context *c, pa_sink_input_info_cb_t cb, void *userdata)
+LL_GRAB_SYM(G, true, pa_context_get_state, pa_context_state_t, pa_context *c)
+LL_GRAB_SYM(G, true, pa_context_new_with_proplist, pa_context*, pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist)
+LL_GRAB_SYM(G, true, pa_context_set_sink_input_volume, pa_operation*, pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata)
+LL_GRAB_SYM(G, true, pa_context_set_state_callback, void, pa_context *c, pa_context_notify_cb_t cb, void *userdata)
+LL_GRAB_SYM(G, true, pa_context_set_subscribe_callback, void, pa_context *c, pa_context_subscribe_cb_t cb, void *userdata)
+LL_GRAB_SYM(G, true, pa_context_subscribe, pa_operation*, pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata)
+LL_GRAB_SYM(G, true, pa_context_unref, void, pa_context *c)
+LL_GRAB_SYM(G, true, pa_cvolume_set, pa_cvolume*, pa_cvolume *a, unsigned channels, pa_volume_t v)
+LL_GRAB_SYM(G, true, pa_operation_unref, void, pa_operation *o)
+LL_GRAB_SYM(G, true, pa_proplist_free, void, pa_proplist* p)
+LL_GRAB_SYM(G, true, pa_proplist_gets, const char*, pa_proplist *p, const char *key)
+LL_GRAB_SYM(G, true, pa_proplist_new, pa_proplist*, void)
+LL_GRAB_SYM(G, true, pa_proplist_sets, int, pa_proplist *p, const char *key, const char *value)
+LL_GRAB_SYM(G, true, pa_sw_volume_from_linear, pa_volume_t, double v)
+// LL_GRAB_SYM(G, true, pa_mainloop_free, void, pa_mainloop *m)
+// LL_GRAB_SYM(G, true, pa_mainloop_get_api, pa_mainloop_api *, pa_mainloop *m)
+// LL_GRAB_SYM(G, true, pa_mainloop_iterate, int, pa_mainloop *m, int block, int *retval)
+// LL_GRAB_SYM(G, true, pa_mainloop_new, pa_mainloop *, void)
+
+// optional symbols to grab
+
+#undef G
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index caf804f915..5693420bb6 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -911,7 +911,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
keyEvent(key_event, native_key_data);
-#elif LL_WINDOWS
+#else
std::string event = message_in.getValue("event");
LLSD native_key_data = message_in.getValueLLSD("native_key_data");
@@ -933,6 +933,13 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
}
+#if LL_LINUX
+ else if (message_name == "enable_pipewire_volume_catcher")
+ {
+ bool enable = message_in.getValueBoolean("enable");
+ mVolumeCatcher.onEnablePipeWireVolumeCatcher(enable);
+ }
+#endif
if (message_name == "pick_file_response")
{
LLSD file_list_llsd = message_in.getValueLLSD("file_list");
@@ -1095,6 +1102,28 @@ void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_dat
mCEFLib->nativeKeyboardEventWin(msg, wparam, lparam);
#endif
+
+#if LL_LINUX
+
+ uint32_t native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); // this is actually the SDL event.key.keysym.sym;
+ uint32_t native_virtual_key_win = (uint32_t)(native_key_data["virtual_key_win"].asInteger());
+ uint32_t native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
+
+ // only for non-printable keysyms, the actual text input is done in unicodeInput() below
+ if (native_virtual_key <= 0x1b || native_virtual_key >= 0x7f)
+ {
+ // set keypad flag, not sure if this even does anything
+ bool keypad = false;
+ if (native_virtual_key_win >= 0x60 && native_virtual_key_win <= 0x6f)
+ {
+ keypad = true;
+ }
+
+ // yes, we send native_virtual_key_win twice because native_virtual_key breaks it
+ mCEFLib->nativeKeyboardEventSDL2(key_event, native_virtual_key, native_modifiers, keypad);
+ }
+
+#endif // LL_LINUX
};
void MediaPluginCEF::unicodeInput(std::string event, LLSD native_key_data = LLSD::emptyMap())
@@ -1125,6 +1154,16 @@ void MediaPluginCEF::unicodeInput(std::string event, LLSD native_key_data = LLSD
U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
mCEFLib->nativeKeyboardEventWin(msg, wparam, lparam);
#endif
+
+#if LL_LINUX
+
+ uint32_t native_scan_code = (uint32_t)(native_key_data["sdl_sym"].asInteger());
+ uint32_t native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
+ uint32_t native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
+
+ mCEFLib->nativeKeyboardEvent(dullahan::KE_KEY_DOWN, native_scan_code, native_virtual_key, native_modifiers);
+
+#endif // LL_LINUX
};
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/media_plugins/cef/volume_catcher.h b/indra/media_plugins/cef/volume_catcher.h
index ea97a24947..806f2a008a 100644
--- a/indra/media_plugins/cef/volume_catcher.h
+++ b/indra/media_plugins/cef/volume_catcher.h
@@ -35,7 +35,7 @@ class VolumeCatcherImpl;
class VolumeCatcher
{
- public:
+public:
VolumeCatcher();
~VolumeCatcher();
@@ -47,8 +47,14 @@ class VolumeCatcher
void pump(); // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume
- private:
+#if LL_LINUX
+ void onEnablePipeWireVolumeCatcher(bool enable);
+#endif
+
+private:
+#if LL_LINUX || LL_WINDOWS
VolumeCatcherImpl *pimpl;
+#endif
};
#endif // VOLUME_CATCHER_H
diff --git a/indra/media_plugins/cef/mac_volume_catcher_null.cpp b/indra/media_plugins/cef/volume_catcher_null.cpp
index c479e24a95..cd5eccca38 100644
--- a/indra/media_plugins/cef/mac_volume_catcher_null.cpp
+++ b/indra/media_plugins/cef/volume_catcher_null.cpp
@@ -1,5 +1,5 @@
/**
- * @file windows_volume_catcher.cpp
+ * @file volume_catcher_null.cpp
* @brief A null implementation of volume level control of all audio channels opened by a process.
* We are using this for the macOS version for now until we can understand how to make the
* exitising mac_volume_catcher.cpp work without the (now, non-existant) QuickTime dependency
@@ -29,67 +29,31 @@
*/
#include "volume_catcher.h"
-#include "llsingleton.h"
-class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl>
-{
- LLSINGLETON(VolumeCatcherImpl);
- // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
- ~VolumeCatcherImpl();
-
-public:
-
- void setVolume(F32 volume);
- void setPan(F32 pan);
-
-private:
- F32 mVolume;
- F32 mPan;
- bool mSystemIsVistaOrHigher;
-};
-
-VolumeCatcherImpl::VolumeCatcherImpl()
-: mVolume(1.0f), // default volume is max
- mPan(0.f) // default pan is centered
-{
-}
-
-VolumeCatcherImpl::~VolumeCatcherImpl()
-{
-}
-
-void VolumeCatcherImpl::setVolume(F32 volume)
-{
- mVolume = volume;
-}
-
-void VolumeCatcherImpl::setPan(F32 pan)
-{ // remember pan for calculating individual channel levels later
- mPan = pan;
-}
/////////////////////////////////////////////////////
VolumeCatcher::VolumeCatcher()
{
- pimpl = VolumeCatcherImpl::getInstance();
}
VolumeCatcher::~VolumeCatcher()
{
- // Let the instance persist until exit.
}
void VolumeCatcher::setVolume(F32 volume)
{
- pimpl->setVolume(volume);
}
void VolumeCatcher::setPan(F32 pan)
{
- pimpl->setPan(pan);
}
void VolumeCatcher::pump()
{
- // No periodic tasks are necessary for this implementation.
}
+
+#if LL_LINUX
+void VolumeCatcher::onEnablePipeWireVolumeCatcher(bool enable)
+{
+}
+#endif
diff --git a/indra/media_plugins/cef/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp
index e7daeb5f74..1e52fee9de 100644
--- a/indra/media_plugins/cef/windows_volume_catcher.cpp
+++ b/indra/media_plugins/cef/windows_volume_catcher.cpp
@@ -44,7 +44,6 @@ public:
private:
F32 mVolume;
F32 mPan;
- bool mSystemIsVistaOrHigher;
};
VolumeCatcherImpl::VolumeCatcherImpl()
diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt
deleted file mode 100644
index 38fc8201bf..0000000000
--- a/indra/media_plugins/gstreamer010/CMakeLists.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- cmake -*-
-
-project(media_plugin_gstreamer010)
-
-include(00-Common)
-include(LLCommon)
-include(LLImage)
-include(LLMath)
-include(LLWindow)
-include(Linking)
-include(PluginAPI)
-include(OpenGL)
-
-include(GStreamer010Plugin)
-
-### media_plugin_gstreamer010
-
-if(NOT ADDRESS_SIZE EQUAL 32)
- if(WINDOWS)
- ##add_definitions(/FIXED:NO)
- else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
- add_definitions(-fPIC)
- endif(WINDOWS)
-endif(NOT ADDRESS_SIZE EQUAL 32)
-
-set(media_plugin_gstreamer010_SOURCE_FILES
- media_plugin_gstreamer010.cpp
- llmediaimplgstreamer_syms.cpp
- llmediaimplgstreamervidplug.cpp
- )
-
-set(media_plugin_gstreamer010_HEADER_FILES
- llmediaimplgstreamervidplug.h
- llmediaimplgstreamer_syms.h
- llmediaimplgstreamertriviallogging.h
- )
-
-add_library(media_plugin_gstreamer010
- SHARED
- ${media_plugin_gstreamer010_SOURCE_FILES}
- )
-
-target_link_libraries(media_plugin_gstreamer010
- media_plugin_base
- ll::gstreamer
- )
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
deleted file mode 100644
index dcc04b37e4..0000000000
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
- * @file llmediaimplgstreamer_syms.cpp
- * @brief dynamic GStreamer symbol-grabbing code
- *
- * @cond
- * $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$
- * @endcond
- */
-
-#if LL_GSTREAMER010_ENABLED
-
-#include <string>
-
-extern "C" {
-#include <gst/gst.h>
-
-#include "apr_pools.h"
-#include "apr_dso.h"
-}
-
-#include "llmediaimplgstreamertriviallogging.h"
-
-#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL
-#include "llmediaimplgstreamer_syms_raw.inc"
-#include "llmediaimplgstreamer_syms_rawv.inc"
-#undef LL_GST_SYM
-
-// a couple of stubs for disgusting reasons
-GstDebugCategory*
-ll_gst_debug_category_new(gchar *name, guint color, gchar *description)
-{
- static GstDebugCategory dummy;
- return &dummy;
-}
-void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname)
-{
-}
-
-static bool sSymsGrabbed = false;
-static apr_pool_t *sSymGSTDSOMemoryPool = NULL;
-static apr_dso_handle_t *sSymGSTDSOHandleG = NULL;
-static apr_dso_handle_t *sSymGSTDSOHandleV = NULL;
-
-
-bool grab_gst_syms(std::string gst_dso_name,
- std::string gst_dso_name_vid)
-{
- if (sSymsGrabbed)
- {
- // already have grabbed good syms
- return TRUE;
- }
-
- bool sym_error = false;
- bool rtn = false;
- apr_status_t rv;
- apr_dso_handle_t *sSymGSTDSOHandle = NULL;
-
-#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0)
-
- //attempt to load the shared libraries
- apr_pool_create(&sSymGSTDSOMemoryPool, NULL);
-
- if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle,
- gst_dso_name.c_str(),
- sSymGSTDSOMemoryPool) ))
- {
- INFOMSG("Found DSO: %s", gst_dso_name.c_str());
-#include "llmediaimplgstreamer_syms_raw.inc"
-
- if ( sSymGSTDSOHandle )
- {
- sSymGSTDSOHandleG = sSymGSTDSOHandle;
- sSymGSTDSOHandle = NULL;
- }
-
- if ( APR_SUCCESS ==
- (rv = apr_dso_load(&sSymGSTDSOHandle,
- gst_dso_name_vid.c_str(),
- sSymGSTDSOMemoryPool) ))
- {
- INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str());
-#include "llmediaimplgstreamer_syms_rawv.inc"
- rtn = !sym_error;
- }
- else
- {
- INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str());
- rtn = false; // failure
- }
- }
- else
- {
- INFOMSG("Couldn't load DSO: %s", gst_dso_name.c_str());
- rtn = false; // failure
- }
-
- if (sym_error)
- {
- WARNMSG("Failed to find necessary symbols in GStreamer libraries.");
- }
-
- if ( sSymGSTDSOHandle )
- {
- sSymGSTDSOHandleV = sSymGSTDSOHandle;
- sSymGSTDSOHandle = NULL;
- }
-#undef LL_GST_SYM
-
- sSymsGrabbed = !!rtn;
- return rtn;
-}
-
-
-void ungrab_gst_syms()
-{
- // should be safe to call regardless of whether we've
- // actually grabbed syms.
-
- if ( sSymGSTDSOHandleG )
- {
- apr_dso_unload(sSymGSTDSOHandleG);
- sSymGSTDSOHandleG = NULL;
- }
-
- if ( sSymGSTDSOHandleV )
- {
- apr_dso_unload(sSymGSTDSOHandleV);
- sSymGSTDSOHandleV = NULL;
- }
-
- if ( sSymGSTDSOMemoryPool )
- {
- apr_pool_destroy(sSymGSTDSOMemoryPool);
- sSymGSTDSOMemoryPool = NULL;
- }
-
- // NULL-out all of the symbols we'd grabbed
-#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0)
-#include "llmediaimplgstreamer_syms_raw.inc"
-#include "llmediaimplgstreamer_syms_rawv.inc"
-#undef LL_GST_SYM
-
- sSymsGrabbed = false;
-}
-
-
-#endif // LL_GSTREAMER010_ENABLED
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h
deleted file mode 100644
index 57d446c7df..0000000000
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * @file llmediaimplgstreamer_syms.h
- * @brief dynamic GStreamer symbol-grabbing code
- *
- * @cond
- * $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$
- * @endcond
- */
-
-#include "linden_common.h"
-
-#if LL_GSTREAMER010_ENABLED
-
-extern "C" {
-#include <gst/gst.h>
-}
-
-bool grab_gst_syms(std::string gst_dso_name,
- std::string gst_dso_name_vid);
-void ungrab_gst_syms();
-
-#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__)
-#include "llmediaimplgstreamer_syms_raw.inc"
-#include "llmediaimplgstreamer_syms_rawv.inc"
-#undef LL_GST_SYM
-
-// regrettable hacks to give us better runtime compatibility with older systems
-#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0)
-#define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0)
-
-// regrettable hacks because GStreamer was not designed for runtime loading
-#undef GST_TYPE_MESSAGE
-#define GST_TYPE_MESSAGE (llgst_message_get_type())
-#undef GST_TYPE_OBJECT
-#define GST_TYPE_OBJECT (llgst_object_get_type())
-#undef GST_TYPE_PIPELINE
-#define GST_TYPE_PIPELINE (llgst_pipeline_get_type())
-#undef GST_TYPE_ELEMENT
-#define GST_TYPE_ELEMENT (llgst_element_get_type())
-#undef GST_TYPE_VIDEO_SINK
-#define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type())
-// more regrettable hacks to stub-out these .h-exposed GStreamer internals
-void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname);
-#undef _gst_debug_register_funcptr
-#define _gst_debug_register_funcptr ll_gst_debug_register_funcptr
-GstDebugCategory* ll_gst_debug_category_new(gchar *name, guint color, gchar *description);
-#undef _gst_debug_category_new
-#define _gst_debug_category_new ll_gst_debug_category_new
-#undef __gst_debug_enabled
-#define __gst_debug_enabled (0)
-
-// more hacks
-#define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M)))
-
-#endif // LL_GSTREAMER010_ENABLED
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc
deleted file mode 100644
index b33e59363d..0000000000
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc
+++ /dev/null
@@ -1,51 +0,0 @@
-
-// required symbols to grab
-LL_GST_SYM(true, gst_pad_peer_accept_caps, gboolean, GstPad *pad, GstCaps *caps);
-LL_GST_SYM(true, gst_buffer_new, GstBuffer*, void);
-LL_GST_SYM(true, gst_buffer_set_caps, void, GstBuffer*, GstCaps *);
-LL_GST_SYM(true, gst_structure_set_value, void, GstStructure *, const gchar *, const GValue*);
-LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err);
-LL_GST_SYM(true, gst_message_get_type, GType, void);
-LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type);
-LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug);
-LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug);
-LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending);
-LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state);
-LL_GST_SYM(true, gst_object_unref, void, gpointer object);
-LL_GST_SYM(true, gst_object_get_type, GType, void);
-LL_GST_SYM(true, gst_pipeline_get_type, GType, void);
-LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline);
-LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data);
-LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name);
-LL_GST_SYM(true, gst_element_get_type, GType, void);
-LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template);
-LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp);
-LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details);
-LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps);
-LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps);
-//LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps);
-LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string);
-LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps);
-LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index);
-LL_GST_SYM(true, gst_caps_copy, GstCaps *, const GstCaps * caps);
-//LL_GST_SYM(true, gst_caps_intersect, GstCaps *, const GstCaps *caps1, const GstCaps *caps2);
-LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type);
-LL_GST_SYM(true, _gst_plugin_register_static, void, GstPluginDesc *desc);
-LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value);
-LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname);
-LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value);
-LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value);
-LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure);
-LL_GST_SYM(true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64);
-
-// optional symbols to grab
-LL_GST_SYM(false, gst_registry_fork_set_enabled, void, gboolean enabled);
-LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled);
-LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent);
-LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug);
-LL_GST_SYM(false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur);
-LL_GST_SYM(false, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano);
-
-// GStreamer 'internal' symbols which may not be visible in some runtimes but are still used in expanded GStreamer header macros - yuck! We'll substitute our own stubs for these.
-//LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname);
-//LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description);
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc
deleted file mode 100644
index 14fbcb48b9..0000000000
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc
+++ /dev/null
@@ -1,5 +0,0 @@
-
-// required symbols to grab
-LL_GST_SYM(true, gst_video_sink_get_type, GType, void);
-
-// optional symbols to grab
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
deleted file mode 100644
index 43ebad6744..0000000000
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * @file llmediaimplgstreamertriviallogging.h
- * @brief minimal logging utilities.
- *
- * @cond
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- * @endcond
- */
-
-#ifndef __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__
-#define __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__
-
-#include <cstdio>
-
-extern "C" {
-#include <sys/types.h>
-#include <unistd.h>
-}
-
-/////////////////////////////////////////////////////////////////////////
-// Debug/Info/Warning macros.
-#define MSGMODULEFOO "(media plugin)"
-#define STDERRMSG(...) do{\
- fprintf(stderr, " pid:%d: ", (int)getpid());\
- fprintf(stderr, MSGMODULEFOO " %s:%d: ", __FUNCTION__, __LINE__);\
- fprintf(stderr, __VA_ARGS__);\
- fputc('\n',stderr);\
- }while(0)
-#define NULLMSG(...) do{}while(0)
-
-#define DEBUGMSG NULLMSG
-#define INFOMSG STDERRMSG
-#define WARNMSG STDERRMSG
-/////////////////////////////////////////////////////////////////////////
-
-#endif /* __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__ */
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
deleted file mode 100644
index acec0f2399..0000000000
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
+++ /dev/null
@@ -1,526 +0,0 @@
-/**
- * @file llmediaimplgstreamervidplug.h
- * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl
- *
- * @cond
- * $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$
- * @endcond
- */
-
-#if LL_GSTREAMER010_ENABLED
-
-#include "linden_common.h"
-
-#include <gst/gst.h>
-#include <gst/video/video.h>
-#include <gst/video/gstvideosink.h>
-
-#include "llmediaimplgstreamer_syms.h"
-#include "llmediaimplgstreamertriviallogging.h"
-
-#include "llmediaimplgstreamervidplug.h"
-
-
-GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug);
-#define GST_CAT_DEFAULT gst_slvideo_debug
-
-
-#define SLV_SIZECAPS ", width=(int)[1,2048], height=(int)[1,2048] "
-#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS
-
-static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE (
- (gchar*)"sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (SLV_ALLCAPS)
- );
-
-GST_BOILERPLATE (GstSLVideo, gst_slvideo, GstVideoSink,
- GST_TYPE_VIDEO_SINK);
-
-static void gst_slvideo_set_property (GObject * object, guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void gst_slvideo_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static void
-gst_slvideo_base_init (gpointer gclass)
-{
- static GstElementDetails element_details = {
- (gchar*)"PluginTemplate",
- (gchar*)"Generic/PluginTemplate",
- (gchar*)"Generic Template Element",
- (gchar*)"Linden Lab"
- };
- GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
- llgst_element_class_add_pad_template (element_class,
- llgst_static_pad_template_get (&sink_factory));
- llgst_element_class_set_details (element_class, &element_details);
-}
-
-
-static void
-gst_slvideo_finalize (GObject * object)
-{
- GstSLVideo *slvideo;
- slvideo = GST_SLVIDEO (object);
- if (slvideo->caps)
- {
- llgst_caps_unref(slvideo->caps);
- }
-
- G_OBJECT_CLASS(parent_class)->finalize (object);
-}
-
-
-static GstFlowReturn
-gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf)
-{
- GstSLVideo *slvideo;
- llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
-
- slvideo = GST_SLVIDEO(bsink);
-
- DEBUGMSG("transferring a frame of %dx%d <- %p (%d)",
- slvideo->width, slvideo->height, GST_BUFFER_DATA(buf),
- slvideo->format);
-
- if (GST_BUFFER_DATA(buf))
- {
- // copy frame and frame info into neutral territory
- GST_OBJECT_LOCK(slvideo);
- slvideo->retained_frame_ready = TRUE;
- slvideo->retained_frame_width = slvideo->width;
- slvideo->retained_frame_height = slvideo->height;
- slvideo->retained_frame_format = slvideo->format;
- int rowbytes =
- SLVPixelFormatBytes[slvideo->retained_frame_format] *
- slvideo->retained_frame_width;
- int needbytes = rowbytes * slvideo->retained_frame_width;
- // resize retained frame hunk only if necessary
- if (needbytes != slvideo->retained_frame_allocbytes)
- {
- delete[] slvideo->retained_frame_data;
- slvideo->retained_frame_data = new unsigned char[needbytes];
- slvideo->retained_frame_allocbytes = needbytes;
-
- }
- // copy the actual frame data to neutral territory -
- // flipped, for GL reasons
- for (int ypos=0; ypos<slvideo->height; ++ypos)
- {
- memcpy(&slvideo->retained_frame_data[(slvideo->height-1-ypos)*rowbytes],
- &(((unsigned char*)GST_BUFFER_DATA(buf))[ypos*rowbytes]),
- rowbytes);
- }
- // done with the shared data
- GST_OBJECT_UNLOCK(slvideo);
- }
-
- return GST_FLOW_OK;
-}
-
-
-static GstStateChangeReturn
-gst_slvideo_change_state(GstElement * element, GstStateChange transition)
-{
- GstSLVideo *slvideo;
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-
- slvideo = GST_SLVIDEO (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- slvideo->fps_n = 0;
- slvideo->fps_d = 1;
- GST_VIDEO_SINK_WIDTH(slvideo) = 0;
- GST_VIDEO_SINK_HEIGHT(slvideo) = 0;
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-
-static GstCaps *
-gst_slvideo_get_caps (GstBaseSink * bsink)
-{
- GstSLVideo *slvideo;
- slvideo = GST_SLVIDEO(bsink);
-
- return llgst_caps_ref (slvideo->caps);
-}
-
-
-/* this function handles the link with other elements */
-static gboolean
-gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps)
-{
- GstSLVideo *filter;
- GstStructure *structure;
-
- GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
-
- filter = GST_SLVIDEO(bsink);
-
- int width, height;
- gboolean ret;
- const GValue *fps;
- const GValue *par;
- structure = llgst_caps_get_structure (caps, 0);
- ret = llgst_structure_get_int (structure, "width", &width);
- ret = ret && llgst_structure_get_int (structure, "height", &height);
- fps = llgst_structure_get_value (structure, "framerate");
- ret = ret && (fps != NULL);
- par = llgst_structure_get_value (structure, "pixel-aspect-ratio");
- if (!ret)
- return FALSE;
-
- INFOMSG("** filter caps set with width=%d, height=%d", width, height);
-
- GST_OBJECT_LOCK(filter);
-
- filter->width = width;
- filter->height = height;
-
- filter->fps_n = llgst_value_get_fraction_numerator(fps);
- filter->fps_d = llgst_value_get_fraction_denominator(fps);
- if (par)
- {
- filter->par_n = llgst_value_get_fraction_numerator(par);
- filter->par_d = llgst_value_get_fraction_denominator(par);
- }
- else
- {
- filter->par_n = 1;
- filter->par_d = 1;
- }
- GST_VIDEO_SINK_WIDTH(filter) = width;
- GST_VIDEO_SINK_HEIGHT(filter) = height;
-
- // crufty lump - we *always* accept *only* RGBX now.
- /*
- filter->format = SLV_PF_UNKNOWN;
- if (0 == strcmp(llgst_structure_get_name(structure),
- "video/x-raw-rgb"))
- {
- int red_mask;
- int green_mask;
- int blue_mask;
- llgst_structure_get_int(structure, "red_mask", &red_mask);
- llgst_structure_get_int(structure, "green_mask", &green_mask);
- llgst_structure_get_int(structure, "blue_mask", &blue_mask);
- if ((unsigned int)red_mask == 0xFF000000 &&
- (unsigned int)green_mask == 0x00FF0000 &&
- (unsigned int)blue_mask == 0x0000FF00)
- {
- filter->format = SLV_PF_RGBX;
- //fprintf(stderr, "\n\nPIXEL FORMAT RGB\n\n");
- } else if ((unsigned int)red_mask == 0x0000FF00 &&
- (unsigned int)green_mask == 0x00FF0000 &&
- (unsigned int)blue_mask == 0xFF000000)
- {
- filter->format = SLV_PF_BGRX;
- //fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n");
- }
- }*/
-
- filter->format = SLV_PF_RGBX;
-
- GST_OBJECT_UNLOCK(filter);
-
- return TRUE;
-}
-
-
-static gboolean
-gst_slvideo_start (GstBaseSink * bsink)
-{
- gboolean ret = TRUE;
-
- GST_SLVIDEO(bsink);
-
- return ret;
-}
-
-static gboolean
-gst_slvideo_stop (GstBaseSink * bsink)
-{
- GstSLVideo *slvideo;
- slvideo = GST_SLVIDEO(bsink);
-
- // free-up retained frame buffer
- GST_OBJECT_LOCK(slvideo);
- slvideo->retained_frame_ready = FALSE;
- delete[] slvideo->retained_frame_data;
- slvideo->retained_frame_data = NULL;
- slvideo->retained_frame_allocbytes = 0;
- GST_OBJECT_UNLOCK(slvideo);
-
- return TRUE;
-}
-
-
-static GstFlowReturn
-gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
- GstCaps * caps, GstBuffer ** buf)
-{
- gint width, height;
- GstStructure *structure = NULL;
- GstSLVideo *slvideo;
- slvideo = GST_SLVIDEO(bsink);
-
- // caps == requested caps
- // we can ignore these and reverse-negotiate our preferred dimensions with
- // the peer if we like - we need to do this to obey dynamic resize requests
- // flowing in from the app.
- structure = llgst_caps_get_structure (caps, 0);
- if (!llgst_structure_get_int(structure, "width", &width) ||
- !llgst_structure_get_int(structure, "height", &height))
- {
- GST_WARNING_OBJECT (slvideo, "no width/height in caps %" GST_PTR_FORMAT, caps);
- return GST_FLOW_NOT_NEGOTIATED;
- }
-
- GstBuffer *newbuf = llgst_buffer_new();
- bool made_bufferdata_ptr = false;
-#define MAXDEPTHHACK 4
-
- GST_OBJECT_LOCK(slvideo);
- if (slvideo->resize_forced_always) // app is giving us a fixed size to work with
- {
- gint slwantwidth, slwantheight;
- slwantwidth = slvideo->resize_try_width;
- slwantheight = slvideo->resize_try_height;
-
- if (slwantwidth != width ||
- slwantheight != height)
- {
- // don't like requested caps, we will issue our own suggestion - copy
- // the requested caps but substitute our own width and height and see
- // if our peer is happy with that.
-
- GstCaps *desired_caps;
- GstStructure *desired_struct;
- desired_caps = llgst_caps_copy (caps);
- desired_struct = llgst_caps_get_structure (desired_caps, 0);
-
- GValue value = {0};
- g_value_init(&value, G_TYPE_INT);
- g_value_set_int(&value, slwantwidth);
- llgst_structure_set_value (desired_struct, "width", &value);
- g_value_unset(&value);
- g_value_init(&value, G_TYPE_INT);
- g_value_set_int(&value, slwantheight);
- llgst_structure_set_value (desired_struct, "height", &value);
-
- if (llgst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo),
- desired_caps))
- {
- // todo: re-use buffers from a pool?
- // todo: set MALLOCDATA to null, set DATA to point straight to shm?
-
- // peer likes our cap suggestion
- DEBUGMSG("peer loves us :)");
- GST_BUFFER_SIZE(newbuf) = slwantwidth * slwantheight * MAXDEPTHHACK;
- GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf));
- GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf);
- llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps);
-
- made_bufferdata_ptr = true;
- } else {
- // peer hates our cap suggestion
- INFOMSG("peer hates us :(");
- llgst_caps_unref(desired_caps);
- }
- }
- }
-
- GST_OBJECT_UNLOCK(slvideo);
-
- if (!made_bufferdata_ptr) // need to fallback to malloc at original size
- {
- GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK;
- GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf));
- GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf);
- llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps);
- }
-
- *buf = GST_BUFFER_CAST(newbuf);
-
- return GST_FLOW_OK;
-}
-
-
-/* initialize the plugin's class */
-static void
-gst_slvideo_class_init (GstSLVideoClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
- GstBaseSinkClass *gstbasesink_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
- gstbasesink_class = (GstBaseSinkClass *) klass;
-
- gobject_class->finalize = gst_slvideo_finalize;
- gobject_class->set_property = gst_slvideo_set_property;
- gobject_class->get_property = gst_slvideo_get_property;
-
- gstelement_class->change_state = gst_slvideo_change_state;
-
-#define LLGST_DEBUG_FUNCPTR(p) (p)
- gstbasesink_class->get_caps = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_caps);
- gstbasesink_class->set_caps = LLGST_DEBUG_FUNCPTR( gst_slvideo_set_caps);
- gstbasesink_class->buffer_alloc=LLGST_DEBUG_FUNCPTR(gst_slvideo_buffer_alloc);
- //gstbasesink_class->get_times = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_times);
- gstbasesink_class->preroll = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame);
- gstbasesink_class->render = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame);
-
- gstbasesink_class->start = LLGST_DEBUG_FUNCPTR (gst_slvideo_start);
- gstbasesink_class->stop = LLGST_DEBUG_FUNCPTR (gst_slvideo_stop);
-
- // gstbasesink_class->unlock = LLGST_DEBUG_FUNCPTR (gst_slvideo_unlock);
-#undef LLGST_DEBUG_FUNCPTR
-}
-
-
-/* initialize the new element
- * instantiate pads and add them to element
- * set functions
- * initialize structure
- */
-static void
-gst_slvideo_init (GstSLVideo * filter,
- GstSLVideoClass * gclass)
-{
- filter->caps = NULL;
- filter->width = -1;
- filter->height = -1;
-
- // this is the info we share with the client app
- GST_OBJECT_LOCK(filter);
- filter->retained_frame_ready = FALSE;
- filter->retained_frame_data = NULL;
- filter->retained_frame_allocbytes = 0;
- filter->retained_frame_width = filter->width;
- filter->retained_frame_height = filter->height;
- filter->retained_frame_format = SLV_PF_UNKNOWN;
- GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS);
- llgst_caps_replace (&filter->caps, caps);
- filter->resize_forced_always = false;
- filter->resize_try_width = -1;
- filter->resize_try_height = -1;
- GST_OBJECT_UNLOCK(filter);
-}
-
-static void
-gst_slvideo_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- llg_return_if_fail (GST_IS_SLVIDEO (object));
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_slvideo_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- llg_return_if_fail (GST_IS_SLVIDEO (object));
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-/* entry point to initialize the plug-in
- * initialize the plug-in itself
- * register the element factories and pad templates
- * register the features
- */
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- DEBUGMSG("PLUGIN INIT");
-
- GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin",
- 0, (gchar*)"Second Life Video Sink");
-
- return llgst_element_register (plugin, "private-slvideo",
- GST_RANK_NONE, GST_TYPE_SLVIDEO);
-}
-
-/* this is the structure that gstreamer looks for to register plugins
- */
-/* NOTE: Can't rely upon GST_PLUGIN_DEFINE_STATIC to self-register, since
- some g++ versions buggily avoid __attribute__((constructor)) functions -
- so we provide an explicit plugin init function.
- */
-#define PACKAGE (gchar*)"packagehack"
-// this macro quietly refers to PACKAGE internally
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- (gchar*)"private-slvideoplugin",
- (gchar*)"SL Video sink plugin",
- plugin_init, (gchar*)"1.0", (gchar*)"LGPL",
- (gchar*)"Second Life",
- (gchar*)"http://www.secondlife.com/");
-#undef PACKAGE
-void gst_slvideo_init_class (void)
-{
- ll_gst_plugin_register_static (&gst_plugin_desc);
- DEBUGMSG("CLASS INIT");
-}
-
-#endif // LL_GSTREAMER010_ENABLED
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h
deleted file mode 100644
index d4e07daf4f..0000000000
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * @file llmediaimplgstreamervidplug.h
- * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl
- *
- * @cond
- * $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$
- * @endcond
- */
-
-#ifndef __GST_SLVIDEO_H__
-#define __GST_SLVIDEO_H__
-
-#if LL_GSTREAMER010_ENABLED
-
-extern "C" {
-#include <gst/gst.h>
-#include <gst/video/video.h>
-#include <gst/video/gstvideosink.h>
-}
-
-G_BEGIN_DECLS
-
-/* #defines don't like whitespacey bits */
-#define GST_TYPE_SLVIDEO \
- (gst_slvideo_get_type())
-#define GST_SLVIDEO(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SLVIDEO,GstSLVideo))
-#define GST_SLVIDEO_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SLVIDEO,GstSLVideoClass))
-#define GST_IS_SLVIDEO(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SLVIDEO))
-#define GST_IS_SLVIDEO_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SLVIDEO))
-
-typedef struct _GstSLVideo GstSLVideo;
-typedef struct _GstSLVideoClass GstSLVideoClass;
-
-typedef enum {
- SLV_PF_UNKNOWN = 0,
- SLV_PF_RGBX = 1,
- SLV_PF_BGRX = 2,
- SLV__END = 3
-} SLVPixelFormat;
-const int SLVPixelFormatBytes[SLV__END] = {1, 4, 4};
-
-struct _GstSLVideo
-{
- GstVideoSink video_sink;
-
- GstCaps *caps;
-
- int fps_n, fps_d;
- int par_n, par_d;
- int height, width;
- SLVPixelFormat format;
-
- // SHARED WITH APPLICATION:
- // Access to the following should be protected by GST_OBJECT_LOCK() on
- // the GstSLVideo object, and should be totally consistent upon UNLOCK
- // (i.e. all written at once to reflect the current retained frame info
- // when the retained frame is updated.)
- bool retained_frame_ready; // new frame ready since flag last reset. (*TODO: could get the writer to wait on a semaphore instead of having the reader poll, potentially making dropped frames somewhat cheaper.)
- unsigned char* retained_frame_data;
- int retained_frame_allocbytes;
- int retained_frame_width, retained_frame_height;
- SLVPixelFormat retained_frame_format;
- // sticky resize info
- bool resize_forced_always;
- int resize_try_width;
- int resize_try_height;
-};
-
-struct _GstSLVideoClass
-{
- GstVideoSinkClass parent_class;
-};
-
-GType gst_slvideo_get_type (void);
-
-void gst_slvideo_init_class (void);
-
-G_END_DECLS
-
-#endif // LL_GSTREAMER010_ENABLED
-
-#endif /* __GST_SLVIDEO_H__ */
diff --git a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
deleted file mode 100644
index 97d1d7d7b5..0000000000
--- a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
+++ /dev/null
@@ -1,1266 +0,0 @@
-/**
- * @file media_plugin_gstreamer010.cpp
- * @brief GStreamer-0.10 plugin for LLMedia API plugin system
- *
- * @cond
- * $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$
- * @endcond
- */
-
-#include "linden_common.h"
-
-#include "llgl.h"
-
-#include "llplugininstance.h"
-#include "llpluginmessage.h"
-#include "llpluginmessageclasses.h"
-#include "media_plugin_base.h"
-
-#if LL_GSTREAMER010_ENABLED
-
-extern "C" {
-#include <gst/gst.h>
-}
-
-#include "llmediaimplgstreamer.h"
-#include "llmediaimplgstreamertriviallogging.h"
-
-#include "llmediaimplgstreamervidplug.h"
-
-#include "llmediaimplgstreamer_syms.h"
-
-//////////////////////////////////////////////////////////////////////////////
-//
-class MediaPluginGStreamer010 : public MediaPluginBase
-{
-public:
- MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~MediaPluginGStreamer010();
-
- /* virtual */ void receiveMessage(const char *message_string);
-
- static bool startup();
- static bool closedown();
-
- gboolean processGSTEvents(GstBus *bus,
- GstMessage *message);
-
-private:
- std::string getVersion();
- bool navigateTo( const std::string urlIn );
- bool seek( double time_sec );
- bool setVolume( float volume );
-
- // misc
- bool pause();
- bool stop();
- bool play(double rate);
- bool getTimePos(double &sec_out);
-
- static const double MIN_LOOP_SEC = 1.0F;
-
- bool mIsLooping;
-
- enum ECommand {
- COMMAND_NONE,
- COMMAND_STOP,
- COMMAND_PLAY,
- COMMAND_FAST_FORWARD,
- COMMAND_FAST_REWIND,
- COMMAND_PAUSE,
- COMMAND_SEEK,
- };
- ECommand mCommand;
-
-private:
- bool unload();
- bool load();
-
- bool update(int milliseconds);
- void mouseDown( int x, int y );
- void mouseUp( int x, int y );
- void mouseMove( int x, int y );
-
- void sizeChanged();
-
- static bool mDoneInit;
-
- guint mBusWatchID;
-
- float mVolume;
-
- int mDepth;
-
- // media NATURAL size
- int mNaturalWidth;
- int mNaturalHeight;
- // media current size
- int mCurrentWidth;
- int mCurrentHeight;
- int mCurrentRowbytes;
- // previous media size so we can detect changes
- int mPreviousWidth;
- int mPreviousHeight;
- // desired render size from host
- int mWidth;
- int mHeight;
- // padded texture size we need to write into
- int mTextureWidth;
- int mTextureHeight;
-
- int mTextureFormatPrimary;
- int mTextureFormatType;
-
- bool mSeekWanted;
- double mSeekDestination;
-
- // Very GStreamer-specific
- GMainLoop *mPump; // event pump for this media
- GstElement *mPlaybin;
- GstElement *mVisualizer;
- GstSLVideo *mVideoSink;
-};
-
-//static
-bool MediaPluginGStreamer010::mDoneInit = false;
-
-MediaPluginGStreamer010::MediaPluginGStreamer010(
- LLPluginInstance::sendMessageFunction host_send_func,
- void *host_user_data ) :
- MediaPluginBase(host_send_func, host_user_data),
- mBusWatchID ( 0 ),
- mCurrentRowbytes ( 4 ),
- mTextureFormatPrimary ( GL_RGBA ),
- mTextureFormatType ( GL_UNSIGNED_INT_8_8_8_8_REV ),
- mSeekWanted(false),
- mSeekDestination(0.0),
- mPump ( NULL ),
- mPlaybin ( NULL ),
- mVisualizer ( NULL ),
- mVideoSink ( NULL ),
- mCommand ( COMMAND_NONE )
-{
- std::ostringstream str;
- INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(getpid()));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-//#define LL_GST_REPORT_STATE_CHANGES
-#ifdef LL_GST_REPORT_STATE_CHANGES
-static char* get_gst_state_name(GstState state)
-{
- switch (state) {
- case GST_STATE_VOID_PENDING: return "VOID_PENDING";
- case GST_STATE_NULL: return "NULL";
- case GST_STATE_READY: return "READY";
- case GST_STATE_PAUSED: return "PAUSED";
- case GST_STATE_PLAYING: return "PLAYING";
- }
- return "(unknown)";
-}
-#endif // LL_GST_REPORT_STATE_CHANGES
-
-gboolean
-MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
- GstMessage *message)
-{
- if (!message)
- return TRUE; // shield against GStreamer bug
-
- if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
- GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
- {
- DEBUGMSG("Got GST message type: %s",
- LLGST_MESSAGE_TYPE_NAME (message));
- }
- else
- {
- // TODO: grok 'duration' message type
- DEBUGMSG("Got GST message type: %s",
- LLGST_MESSAGE_TYPE_NAME (message));
- }
-
- switch (GST_MESSAGE_TYPE (message)) {
- case GST_MESSAGE_BUFFERING: {
- // NEEDS GST 0.10.11+
- if (llgst_message_parse_buffering)
- {
- gint percent = 0;
- llgst_message_parse_buffering(message, &percent);
- DEBUGMSG("GST buffering: %d%%", percent);
- }
- break;
- }
- case GST_MESSAGE_STATE_CHANGED: {
- GstState old_state;
- GstState new_state;
- GstState pending_state;
- llgst_message_parse_state_changed(message,
- &old_state,
- &new_state,
- &pending_state);
-#ifdef LL_GST_REPORT_STATE_CHANGES
- // not generally very useful, and rather spammy.
- DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s",
- get_gst_state_name(old_state),
- get_gst_state_name(new_state),
- get_gst_state_name(pending_state));
-#endif // LL_GST_REPORT_STATE_CHANGES
-
- switch (new_state) {
- case GST_STATE_VOID_PENDING:
- break;
- case GST_STATE_NULL:
- break;
- case GST_STATE_READY:
- setStatus(STATUS_LOADED);
- break;
- case GST_STATE_PAUSED:
- setStatus(STATUS_PAUSED);
- break;
- case GST_STATE_PLAYING:
- setStatus(STATUS_PLAYING);
- break;
- }
- break;
- }
- case GST_MESSAGE_ERROR: {
- GError *err = NULL;
- gchar *debug = NULL;
-
- llgst_message_parse_error (message, &err, &debug);
- WARNMSG("GST error: %s", err?err->message:"(unknown)");
- if (err)
- g_error_free (err);
- g_free (debug);
-
- mCommand = COMMAND_STOP;
-
- setStatus(STATUS_ERROR);
-
- break;
- }
- case GST_MESSAGE_INFO: {
- if (llgst_message_parse_info)
- {
- GError *err = NULL;
- gchar *debug = NULL;
-
- llgst_message_parse_info (message, &err, &debug);
- INFOMSG("GST info: %s", err?err->message:"(unknown)");
- if (err)
- g_error_free (err);
- g_free (debug);
- }
- break;
- }
- case GST_MESSAGE_WARNING: {
- GError *err = NULL;
- gchar *debug = NULL;
-
- llgst_message_parse_warning (message, &err, &debug);
- WARNMSG("GST warning: %s", err?err->message:"(unknown)");
- if (err)
- g_error_free (err);
- g_free (debug);
-
- break;
- }
- case GST_MESSAGE_EOS:
- /* end-of-stream */
- DEBUGMSG("GST end-of-stream.");
- if (mIsLooping)
- {
- DEBUGMSG("looping media...");
- double eos_pos_sec = 0.0F;
- bool got_eos_position = getTimePos(eos_pos_sec);
-
- if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC)
- {
- // if we know that the movie is really short, don't
- // loop it else it can easily become a time-hog
- // because of GStreamer spin-up overhead
- DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec);
- // inject a COMMAND_PAUSE
- mCommand = COMMAND_PAUSE;
- }
- else
- {
-#undef LLGST_LOOP_BY_SEEKING
-// loop with a stop-start instead of a seek, because it actually seems rather
-// faster than seeking on remote streams.
-#ifdef LLGST_LOOP_BY_SEEKING
- // first, try looping by an explicit rewind
- bool seeksuccess = seek(0.0);
- if (seeksuccess)
- {
- play(1.0);
- }
- else
-#endif // LLGST_LOOP_BY_SEEKING
- { // use clumsy stop-start to loop
- DEBUGMSG("didn't loop by rewinding - stopping and starting instead...");
- stop();
- play(1.0);
- }
- }
- }
- else // not a looping media
- {
- // inject a COMMAND_STOP
- mCommand = COMMAND_STOP;
- }
- break;
- default:
- /* unhandled message */
- break;
- }
-
- /* we want to be notified again the next time there is a message
- * on the bus, so return true (false means we want to stop watching
- * for messages on the bus and our callback should not be called again)
- */
- return TRUE;
-}
-
-extern "C" {
-gboolean
-llmediaimplgstreamer_bus_callback (GstBus *bus,
- GstMessage *message,
- gpointer data)
-{
- MediaPluginGStreamer010 *impl = (MediaPluginGStreamer010*)data;
- return impl->processGSTEvents(bus, message);
-}
-} // extern "C"
-
-
-
-bool
-MediaPluginGStreamer010::navigateTo ( const std::string urlIn )
-{
- if (!mDoneInit)
- return false; // error
-
- setStatus(STATUS_LOADING);
-
- DEBUGMSG("Setting media URI: %s", urlIn.c_str());
-
- mSeekWanted = false;
-
- if (NULL == mPump ||
- NULL == mPlaybin)
- {
- setStatus(STATUS_ERROR);
- return false; // error
- }
-
- // set URI
- g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL);
- //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL);
-
- // navigateTo implicitly plays, too.
- play(1.0);
-
- return true;
-}
-
-
-bool
-MediaPluginGStreamer010::update(int milliseconds)
-{
- if (!mDoneInit)
- return false; // error
-
- DEBUGMSG("updating media...");
-
- // sanity check
- if (NULL == mPump ||
- NULL == mPlaybin)
- {
- DEBUGMSG("dead media...");
- return false;
- }
-
- // see if there's an outstanding seek wanted
- if (mSeekWanted &&
- // bleh, GST has to be happy that the movie is really truly playing
- // or it may quietly ignore the seek (with rtsp:// at least).
- (GST_STATE(mPlaybin) == GST_STATE_PLAYING))
- {
- seek(mSeekDestination);
- mSeekWanted = false;
- }
-
- // *TODO: time-limit - but there isn't a lot we can do here, most
- // time is spent in gstreamer's own opaque worker-threads. maybe
- // we can do something sneaky like only unlock the video object
- // for 'milliseconds' and otherwise hold the lock.
- while (g_main_context_pending(g_main_loop_get_context(mPump)))
- {
- g_main_context_iteration(g_main_loop_get_context(mPump), FALSE);
- }
-
- // check for availability of a new frame
-
- if (mVideoSink)
- {
- GST_OBJECT_LOCK(mVideoSink);
- if (mVideoSink->retained_frame_ready)
- {
- DEBUGMSG("NEW FRAME READY");
-
- if (mVideoSink->retained_frame_width != mCurrentWidth ||
- mVideoSink->retained_frame_height != mCurrentHeight)
- // *TODO: also check for change in format
- {
- // just resize container, don't consume frame
- int neww = mVideoSink->retained_frame_width;
- int newh = mVideoSink->retained_frame_height;
-
- int newd = 4;
- mTextureFormatPrimary = GL_RGBA;
- mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV;
-
- /*
- int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format];
- if (SLV_PF_BGRX == mVideoSink->retained_frame_format)
- {
- mTextureFormatPrimary = GL_BGRA;
- mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV;
- }
- else
- {
- mTextureFormatPrimary = GL_RGBA;
- mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV;
- }
- */
-
- GST_OBJECT_UNLOCK(mVideoSink);
-
- mCurrentRowbytes = neww * newd;
- DEBUGMSG("video container resized to %dx%d",
- neww, newh);
-
- mDepth = newd;
- mCurrentWidth = neww;
- mCurrentHeight = newh;
- sizeChanged();
- return true;
- }
-
- if (mPixels &&
- mCurrentHeight <= mHeight &&
- mCurrentWidth <= mWidth &&
- !mTextureSegmentName.empty())
- {
- // we're gonna totally consume this frame - reset 'ready' flag
- mVideoSink->retained_frame_ready = FALSE;
- int destination_rowbytes = mWidth * mDepth;
- for (int row=0; row<mCurrentHeight; ++row)
- {
- memcpy(&mPixels
- [destination_rowbytes * row],
- &mVideoSink->retained_frame_data
- [mCurrentRowbytes * row],
- mCurrentRowbytes);
- }
-
- GST_OBJECT_UNLOCK(mVideoSink);
- DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST");
-
- setDirty(0,0,mCurrentWidth,mCurrentHeight);
- }
- else
- {
- // new frame ready, but we're not ready to
- // consume it.
-
- GST_OBJECT_UNLOCK(mVideoSink);
-
- DEBUGMSG("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize");
- }
-
- return true;
- }
- else
- {
- // nothing to do yet.
- GST_OBJECT_UNLOCK(mVideoSink);
- return true;
- }
- }
-
- return true;
-}
-
-
-void
-MediaPluginGStreamer010::mouseDown( int x, int y )
-{
- // do nothing
-}
-
-void
-MediaPluginGStreamer010::mouseUp( int x, int y )
-{
- // do nothing
-}
-
-void
-MediaPluginGStreamer010::mouseMove( int x, int y )
-{
- // do nothing
-}
-
-
-bool
-MediaPluginGStreamer010::pause()
-{
- DEBUGMSG("pausing media...");
- // todo: error-check this?
- if (mDoneInit && mPlaybin)
- {
- llgst_element_set_state(mPlaybin, GST_STATE_PAUSED);
- return true;
- }
- return false;
-}
-
-bool
-MediaPluginGStreamer010::stop()
-{
- DEBUGMSG("stopping media...");
- // todo: error-check this?
- if (mDoneInit && mPlaybin)
- {
- llgst_element_set_state(mPlaybin, GST_STATE_READY);
- return true;
- }
- return false;
-}
-
-bool
-MediaPluginGStreamer010::play(double rate)
-{
- // NOTE: we don't actually support non-natural rate.
-
- DEBUGMSG("playing media... rate=%f", rate);
- // todo: error-check this?
- if (mDoneInit && mPlaybin)
- {
- llgst_element_set_state(mPlaybin, GST_STATE_PLAYING);
- return true;
- }
- return false;
-}
-
-bool
-MediaPluginGStreamer010::setVolume( float volume )
-{
- // we try to only update volume as conservatively as
- // possible, as many gst-plugins-base versions up to at least
- // November 2008 have critical race-conditions in setting volume - sigh
- if (mVolume == volume)
- return true; // nothing to do, everything's fine
-
- mVolume = volume;
- if (mDoneInit && mPlaybin)
- {
- g_object_set(mPlaybin, "volume", mVolume, NULL);
- return true;
- }
-
- return false;
-}
-
-bool
-MediaPluginGStreamer010::seek(double time_sec)
-{
- bool success = false;
- if (mDoneInit && mPlaybin)
- {
- success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME,
- GstSeekFlags(GST_SEEK_FLAG_FLUSH |
- GST_SEEK_FLAG_KEY_UNIT),
- GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND),
- GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
- }
- DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d",
- float(time_sec), int(success));
- return success;
-}
-
-bool
-MediaPluginGStreamer010::getTimePos(double &sec_out)
-{
- bool got_position = false;
- if (mDoneInit && mPlaybin)
- {
- gint64 pos;
- GstFormat timefmt = GST_FORMAT_TIME;
- got_position =
- llgst_element_query_position &&
- llgst_element_query_position(mPlaybin,
- &timefmt,
- &pos);
- got_position = got_position
- && (timefmt == GST_FORMAT_TIME);
- // GStreamer may have other ideas, but we consider the current position
- // undefined if not PLAYING or PAUSED
- got_position = got_position &&
- (GST_STATE(mPlaybin) == GST_STATE_PLAYING ||
- GST_STATE(mPlaybin) == GST_STATE_PAUSED);
- if (got_position && !GST_CLOCK_TIME_IS_VALID(pos))
- {
- if (GST_STATE(mPlaybin) == GST_STATE_PLAYING)
- {
- // if we're playing then we treat an invalid clock time
- // as 0, for complicated reasons (insert reason here)
- pos = 0;
- }
- else
- {
- got_position = false;
- }
-
- }
- // If all the preconditions succeeded... we can trust the result.
- if (got_position)
- {
- sec_out = double(pos) / double(GST_SECOND); // gst to sec
- }
- }
- return got_position;
-}
-
-bool
-MediaPluginGStreamer010::load()
-{
- if (!mDoneInit)
- return false; // error
-
- setStatus(STATUS_LOADING);
-
- DEBUGMSG("setting up media...");
-
- mIsLooping = false;
- mVolume = 0.1234567; // minor hack to force an initial volume update
-
- // Create a pumpable main-loop for this media
- mPump = g_main_loop_new (NULL, FALSE);
- if (!mPump)
- {
- setStatus(STATUS_ERROR);
- return false; // error
- }
-
- // instantiate a playbin element to do the hard work
- mPlaybin = llgst_element_factory_make ("playbin", "play");
- if (!mPlaybin)
- {
- setStatus(STATUS_ERROR);
- return false; // error
- }
-
- // get playbin's bus
- GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin));
- if (!bus)
- {
- setStatus(STATUS_ERROR);
- return false; // error
- }
- mBusWatchID = llgst_bus_add_watch (bus,
- llmediaimplgstreamer_bus_callback,
- this);
- llgst_object_unref (bus);
-
-#if 0 // not quite stable/correct yet
- // get a visualizer element (bonus feature!)
- char* vis_name = getenv("LL_GST_VIS_NAME");
- if (!vis_name ||
- (vis_name && std::string(vis_name)!="none"))
- {
- if (vis_name)
- {
- mVisualizer = llgst_element_factory_make (vis_name, "vis");
- }
- if (!mVisualizer)
- {
- mVisualizer = llgst_element_factory_make ("libvisual_jess", "vis");
- if (!mVisualizer)
- {
- mVisualizer = llgst_element_factory_make ("goom", "vis");
- if (!mVisualizer)
- {
- mVisualizer = llgst_element_factory_make ("libvisual_lv_scope", "vis");
- if (!mVisualizer)
- {
- // That's okay, we don't NEED this.
- }
- }
- }
- }
- }
-#endif
-
- if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) {
- // instantiate a custom video sink
- mVideoSink =
- GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo"));
- if (!mVideoSink)
- {
- WARNMSG("Could not instantiate private-slvideo element.");
- // todo: cleanup.
- setStatus(STATUS_ERROR);
- return false; // error
- }
-
- // connect the pieces
- g_object_set(mPlaybin, "video-sink", mVideoSink, NULL);
- }
-
- if (mVisualizer)
- {
- g_object_set(mPlaybin, "vis-plugin", mVisualizer, NULL);
- }
-
- return true;
-}
-
-bool
-MediaPluginGStreamer010::unload ()
-{
- if (!mDoneInit)
- return false; // error
-
- DEBUGMSG("unloading media...");
-
- // stop getting callbacks for this bus
- g_source_remove(mBusWatchID);
- mBusWatchID = 0;
-
- if (mPlaybin)
- {
- llgst_element_set_state (mPlaybin, GST_STATE_NULL);
- llgst_object_unref (GST_OBJECT (mPlaybin));
- mPlaybin = NULL;
- }
-
- if (mVisualizer)
- {
- llgst_object_unref (GST_OBJECT (mVisualizer));
- mVisualizer = NULL;
- }
-
- if (mPump)
- {
- g_main_loop_quit(mPump);
- mPump = NULL;
- }
-
- mVideoSink = NULL;
-
- setStatus(STATUS_NONE);
-
- return true;
-}
-
-
-//static
-bool
-MediaPluginGStreamer010::startup()
-{
- // first - check if GStreamer is explicitly disabled
- if (NULL != getenv("LL_DISABLE_GSTREAMER"))
- return false;
-
- // only do global GStreamer initialization once.
- if (!mDoneInit)
- {
- g_thread_init(NULL);
-
- // Init the glib type system - we need it.
- g_type_init();
-
- // Get symbols!
-#if LL_DARWIN
- if (! grab_gst_syms("libgstreamer-0.10.dylib",
- "libgstvideo-0.10.dylib") )
-#elseif LL_WINDOWS
- if (! grab_gst_syms("libgstreamer-0.10.dll",
- "libgstvideo-0.10.dll") )
-#else // linux or other ELFy unixoid
- if (! grab_gst_syms("libgstreamer-0.10.so.0",
- "libgstvideo-0.10.so.0") )
-#endif
- {
- WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled.");
- return false;
- }
-
- if (llgst_segtrap_set_enabled)
- {
- llgst_segtrap_set_enabled(FALSE);
- }
- else
- {
- WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught.");
- }
-
-#if LL_LINUX
- // Gstreamer tries a fork during init, waitpid-ing on it,
- // which conflicts with any installed SIGCHLD handler...
- struct sigaction tmpact, oldact;
- if (llgst_registry_fork_set_enabled) {
- // if we can disable SIGCHLD-using forking behaviour,
- // do it.
- llgst_registry_fork_set_enabled(false);
- }
- else {
- // else temporarily install default SIGCHLD handler
- // while GStreamer initialises
- tmpact.sa_handler = SIG_DFL;
- sigemptyset( &tmpact.sa_mask );
- tmpact.sa_flags = SA_SIGINFO;
- sigaction(SIGCHLD, &tmpact, &oldact);
- }
-#endif // LL_LINUX
-
- // Protect against GStreamer resetting the locale, yuck.
- static std::string saved_locale;
- saved_locale = setlocale(LC_ALL, NULL);
-
- // finally, try to initialize GStreamer!
- GError *err = NULL;
- gboolean init_gst_success = llgst_init_check(NULL, NULL, &err);
-
- // restore old locale
- setlocale(LC_ALL, saved_locale.c_str() );
-
-#if LL_LINUX
- // restore old SIGCHLD handler
- if (!llgst_registry_fork_set_enabled)
- sigaction(SIGCHLD, &oldact, NULL);
-#endif // LL_LINUX
-
- if (!init_gst_success) // fail
- {
- if (err)
- {
- WARNMSG("GST init failed: %s", err->message);
- g_error_free(err);
- }
- else
- {
- WARNMSG("GST init failed for unspecified reason.");
- }
- return false;
- }
-
- // Init our custom plugins - only really need do this once.
- gst_slvideo_init_class();
-
- mDoneInit = true;
- }
-
- return true;
-}
-
-
-void
-MediaPluginGStreamer010::sizeChanged()
-{
- // the shared writing space has possibly changed size/location/whatever
-
- // Check to see whether the movie's NATURAL size has been set yet
- if (1 == mNaturalWidth &&
- 1 == mNaturalHeight)
- {
- mNaturalWidth = mCurrentWidth;
- mNaturalHeight = mCurrentHeight;
- DEBUGMSG("Media NATURAL size better detected as %dx%d",
- mNaturalWidth, mNaturalHeight);
- }
-
- // if the size has changed then the shm has changed and the app needs telling
- if (mCurrentWidth != mPreviousWidth ||
- mCurrentHeight != mPreviousHeight)
- {
- mPreviousWidth = mCurrentWidth;
- mPreviousHeight = mCurrentHeight;
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request");
- message.setValue("name", mTextureSegmentName);
- message.setValueS32("width", mNaturalWidth);
- message.setValueS32("height", mNaturalHeight);
- DEBUGMSG("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight);
- sendMessage(message);
- }
-}
-
-
-
-//static
-bool
-MediaPluginGStreamer010::closedown()
-{
- if (!mDoneInit)
- return false; // error
-
- ungrab_gst_syms();
-
- mDoneInit = false;
-
- return true;
-}
-
-MediaPluginGStreamer010::~MediaPluginGStreamer010()
-{
- DEBUGMSG("MediaPluginGStreamer010 destructor");
-
- closedown();
-
- DEBUGMSG("GStreamer010 closing down");
-}
-
-
-std::string
-MediaPluginGStreamer010::getVersion()
-{
- std::string plugin_version = "GStreamer010 media plugin, GStreamer version ";
- if (mDoneInit &&
- llgst_version)
- {
- guint major, minor, micro, nano;
- llgst_version(&major, &minor, &micro, &nano);
- plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO);
- }
- else
- {
- plugin_version += "(unknown)";
- }
- return plugin_version;
-}
-
-void MediaPluginGStreamer010::receiveMessage(const char *message_string)
-{
- //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
-
- LLPluginMessage message_in;
-
- if(message_in.parse(message_string) >= 0)
- {
- std::string message_class = message_in.getClass();
- std::string message_name = message_in.getName();
- if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
- {
- if(message_name == "init")
- {
- LLPluginMessage message("base", "init_response");
- LLSD versions = LLSD::emptyMap();
- versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION;
- message.setValueLLSD("versions", versions);
-
- if ( load() )
- {
- DEBUGMSG("GStreamer010 media instance set up");
- }
- else
- {
- WARNMSG("GStreamer010 media instance failed to set up");
- }
-
- message.setValue("plugin_version", getVersion());
- sendMessage(message);
- }
- else if(message_name == "idle")
- {
- // no response is necessary here.
- double time = message_in.getValueReal("time");
-
- // Convert time to milliseconds for update()
- update((int)(time * 1000.0f));
- }
- else if(message_name == "cleanup")
- {
- unload();
- closedown();
- }
- else if(message_name == "shm_added")
- {
- SharedSegmentInfo info;
- info.mAddress = message_in.getValuePointer("address");
- info.mSize = (size_t)message_in.getValueS32("size");
- std::string name = message_in.getValue("name");
-
- std::ostringstream str;
- INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress);
-
- mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
- }
- else if(message_name == "shm_remove")
- {
- std::string name = message_in.getValue("name");
-
- DEBUGMSG("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str());
-
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if(iter != mSharedSegments.end())
- {
- if(mPixels == iter->second.mAddress)
- {
- // This is the currently active pixel buffer. Make sure we stop drawing to it.
- mPixels = NULL;
- mTextureSegmentName.clear();
-
- // Make sure the movie decoder is no longer pointed at the shared segment.
- sizeChanged();
- }
- mSharedSegments.erase(iter);
- }
- else
- {
- WARNMSG("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!");
- }
-
- // Send the response so it can be cleaned up.
- LLPluginMessage message("base", "shm_remove_response");
- message.setValue("name", name);
- sendMessage(message);
- }
- else
- {
- std::ostringstream str;
- INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str());
- }
- }
- else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
- {
- if(message_name == "init")
- {
- // Plugin gets to decide the texture parameters to use.
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
- // lame to have to decide this now, it depends on the movie. Oh well.
- mDepth = 4;
-
- mCurrentWidth = 1;
- mCurrentHeight = 1;
- mPreviousWidth = 1;
- mPreviousHeight = 1;
- mNaturalWidth = 1;
- mNaturalHeight = 1;
- mWidth = 1;
- mHeight = 1;
- mTextureWidth = 1;
- mTextureHeight = 1;
-
- message.setValueU32("format", GL_RGBA);
- message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV);
-
- message.setValueS32("depth", mDepth);
- message.setValueS32("default_width", mWidth);
- message.setValueS32("default_height", mHeight);
- message.setValueU32("internalformat", GL_RGBA8);
- message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left.
- message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale
- sendMessage(message);
- }
- else if(message_name == "size_change")
- {
- std::string name = message_in.getValue("name");
- S32 width = message_in.getValueS32("width");
- S32 height = message_in.getValueS32("height");
- S32 texture_width = message_in.getValueS32("texture_width");
- S32 texture_height = message_in.getValueS32("texture_height");
-
- std::ostringstream str;
- INFOMSG("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height);
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
- message.setValue("name", name);
- message.setValueS32("width", width);
- message.setValueS32("height", height);
- message.setValueS32("texture_width", texture_width);
- message.setValueS32("texture_height", texture_height);
- sendMessage(message);
-
- if(!name.empty())
- {
- // Find the shared memory region with this name
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if(iter != mSharedSegments.end())
- {
- INFOMSG("*** Got size change with matching shm, new size is %d x %d", width, height);
- INFOMSG("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height);
-
- mPixels = (unsigned char*)iter->second.mAddress;
- mTextureSegmentName = name;
- mWidth = width;
- mHeight = height;
-
- if (texture_width > 1 ||
- texture_height > 1) // not a dummy size from the app, a real explicit forced size
- {
- INFOMSG("**** = REAL RESIZE REQUEST FROM APP");
-
- GST_OBJECT_LOCK(mVideoSink);
- mVideoSink->resize_forced_always = true;
- mVideoSink->resize_try_width = texture_width;
- mVideoSink->resize_try_height = texture_height;
- GST_OBJECT_UNLOCK(mVideoSink);
- }
-
- mTextureWidth = texture_width;
- mTextureHeight = texture_height;
- }
- }
- }
- else if(message_name == "load_uri")
- {
- std::string uri = message_in.getValue("uri");
- navigateTo( uri );
- sendStatus();
- }
- else if(message_name == "mouse_event")
- {
- std::string event = message_in.getValue("event");
- S32 x = message_in.getValueS32("x");
- S32 y = message_in.getValueS32("y");
-
- if(event == "down")
- {
- mouseDown(x, y);
- }
- else if(event == "up")
- {
- mouseUp(x, y);
- }
- else if(event == "move")
- {
- mouseMove(x, y);
- };
- };
- }
- else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
- {
- if(message_name == "stop")
- {
- stop();
- }
- else if(message_name == "start")
- {
- double rate = 0.0;
- if(message_in.hasValue("rate"))
- {
- rate = message_in.getValueReal("rate");
- }
- // NOTE: we don't actually support rate.
- play(rate);
- }
- else if(message_name == "pause")
- {
- pause();
- }
- else if(message_name == "seek")
- {
- double time = message_in.getValueReal("time");
- // defer the actual seek in case we haven't
- // really truly started yet in which case there
- // is nothing to seek upon
- mSeekWanted = true;
- mSeekDestination = time;
- }
- else if(message_name == "set_loop")
- {
- bool loop = message_in.getValueBoolean("loop");
- mIsLooping = loop;
- }
- else if(message_name == "set_volume")
- {
- double volume = message_in.getValueReal("volume");
- setVolume(volume);
- }
- }
- else
- {
- INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str());
- }
- }
-}
-
-int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
-{
- if (MediaPluginGStreamer010::startup())
- {
- MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data);
- *plugin_send_func = MediaPluginGStreamer010::staticReceiveMessage;
- *plugin_user_data = (void*)self;
-
- return 0; // okay
- }
- else
- {
- return -1; // failed to init
- }
-}
-
-#else // LL_GSTREAMER010_ENABLED
-
-// Stubbed-out class with constructor/destructor (necessary or windows linker
-// will just think its dead code and optimize it all out)
-class MediaPluginGStreamer010 : public MediaPluginBase
-{
-public:
- MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~MediaPluginGStreamer010();
- /* virtual */ void receiveMessage(const char *message_string);
-};
-
-MediaPluginGStreamer010::MediaPluginGStreamer010(
- LLPluginInstance::sendMessageFunction host_send_func,
- void *host_user_data ) :
- MediaPluginBase(host_send_func, host_user_data)
-{
- // no-op
-}
-
-MediaPluginGStreamer010::~MediaPluginGStreamer010()
-{
- // no-op
-}
-
-void MediaPluginGStreamer010::receiveMessage(const char *message_string)
-{
- // no-op
-}
-
-// We're building without GStreamer enabled. Just refuse to initialize.
-int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
-{
- return -1;
-}
-
-#endif // LL_GSTREAMER010_ENABLED
diff --git a/indra/media_plugins/gstreamer10/CMakeLists.txt b/indra/media_plugins/gstreamer10/CMakeLists.txt
new file mode 100644
index 0000000000..279e07b226
--- /dev/null
+++ b/indra/media_plugins/gstreamer10/CMakeLists.txt
@@ -0,0 +1,40 @@
+# -*- cmake -*-
+
+project(media_plugin_gstreamer10)
+
+include(00-Common)
+include(LLCommon)
+include(LLImage)
+include(LLMath)
+include(LLWindow)
+include(Linking)
+include(PluginAPI)
+include(OpenGL)
+include(GLIB)
+
+include(GStreamer10Plugin)
+
+### media_plugin_gstreamer10
+
+set(media_plugin_gstreamer10_SOURCE_FILES
+ media_plugin_gstreamer10.cpp
+ )
+
+set(media_plugin_gstreamer10_HEADER_FILES
+ llmediaimplgstreamer_syms.h
+ )
+
+add_library(media_plugin_gstreamer10
+ SHARED
+ ${media_plugin_gstreamer10_SOURCE_FILES}
+)
+
+target_link_libraries(media_plugin_gstreamer10 media_plugin_base ll::gstreamer10 )
+
+if (WINDOWS)
+ set_target_properties(
+ media_plugin_gstreamer10
+ PROPERTIES
+ LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT"
+ )
+endif (WINDOWS)
diff --git a/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms_raw.inc b/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms_raw.inc
new file mode 100644
index 0000000000..6f5bb04bdf
--- /dev/null
+++ b/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms_raw.inc
@@ -0,0 +1,71 @@
+#define G gstSymbolGrabber
+
+LL_GRAB_SYM(G, true, gst_buffer_new, GstBuffer*, void)
+LL_GRAB_SYM(G, true, gst_structure_set_value, void, GstStructure *, const gchar *, const GValue*)
+LL_GRAB_SYM(G, true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err)
+LL_GRAB_SYM(G, true, gst_message_get_type, GType, void)
+LL_GRAB_SYM(G, true, gst_message_type_get_name, const gchar*, GstMessageType type)
+LL_GRAB_SYM(G, true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug)
+LL_GRAB_SYM(G, true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug)
+LL_GRAB_SYM(G, true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending)
+LL_GRAB_SYM(G, true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state)
+LL_GRAB_SYM(G, true, gst_object_unref, void, gpointer object)
+LL_GRAB_SYM(G, true, gst_object_get_type, GType, void)
+LL_GRAB_SYM(G, true, gst_pipeline_get_type, GType, void)
+LL_GRAB_SYM(G, true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline)
+LL_GRAB_SYM(G, true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data)
+LL_GRAB_SYM(G, true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name)
+LL_GRAB_SYM(G, true, gst_element_get_type, GType, void)
+LL_GRAB_SYM(G, true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template)
+LL_GRAB_SYM(G, true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp)
+LL_GRAB_SYM(G, true, gst_caps_from_string, GstCaps *, const gchar *string)
+LL_GRAB_SYM(G, true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index)
+LL_GRAB_SYM(G, true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type)
+LL_GRAB_SYM(G, true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value)
+LL_GRAB_SYM(G, true, gst_structure_get_value, const GValue *, const GstStructure *structure, const gchar *fieldname)
+LL_GRAB_SYM(G, true, gst_value_get_fraction_numerator, gint, const GValue *value)
+LL_GRAB_SYM(G, true, gst_value_get_fraction_denominator, gint, const GValue *value)
+LL_GRAB_SYM(G, true, gst_structure_get_name, const gchar *, const GstStructure *structure)
+LL_GRAB_SYM(G, true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64)
+
+LL_GRAB_SYM(G, false, gst_registry_fork_set_enabled, void, gboolean enabled)
+LL_GRAB_SYM(G, false, gst_segtrap_set_enabled, void, gboolean enabled)
+LL_GRAB_SYM(G, false, gst_message_parse_buffering, void, GstMessage *message, gint *percent)
+LL_GRAB_SYM(G, false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug)
+LL_GRAB_SYM(G, false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur)
+LL_GRAB_SYM(G, false, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano)
+
+LL_GRAB_SYM(G, true, gst_message_parse_tag, void, GstMessage *, GstTagList **)
+LL_GRAB_SYM(G, true, gst_tag_list_foreach, void, const GstTagList *, GstTagForeachFunc, gpointer)
+LL_GRAB_SYM(G, true, gst_tag_list_get_tag_size, guint, const GstTagList *, const gchar *)
+LL_GRAB_SYM(G, true, gst_tag_list_get_value_index, const GValue *, const GstTagList *, const gchar *, guint)
+
+LL_GRAB_SYM(G, true, gst_caps_new_simple, GstCaps*, const char *, const char*, ... )
+
+LL_GRAB_SYM(G, true, gst_sample_get_caps, GstCaps*, GstSample* )
+LL_GRAB_SYM(G, true, gst_sample_get_buffer, GstBuffer*, GstSample* )
+LL_GRAB_SYM(G, true, gst_buffer_map, gboolean, GstBuffer*, GstMapInfo*, GstMapFlags )
+LL_GRAB_SYM(G, true, gst_buffer_unmap, void, GstBuffer*, GstMapInfo* )
+
+LL_GRAB_SYM(G, true, gst_app_sink_set_caps, void, GstAppSink*, GstCaps const* )
+LL_GRAB_SYM(G, true, gst_app_sink_pull_sample, GstSample*, GstAppSink* )
+
+LL_GRAB_SYM(G, true, g_free, void, gpointer )
+LL_GRAB_SYM(G, true, g_error_free, void, GError* )
+
+LL_GRAB_SYM(G, true, g_main_context_pending, gboolean, GMainContext* )
+LL_GRAB_SYM(G, true, g_main_loop_get_context, GMainContext*, GMainLoop* )
+LL_GRAB_SYM(G, true, g_main_context_iteration, gboolean, GMainContext*, gboolean )
+LL_GRAB_SYM(G, true, g_main_loop_new, GMainLoop*, GMainContext*, gboolean )
+LL_GRAB_SYM(G, true, g_main_loop_quit, void, GMainLoop* )
+LL_GRAB_SYM(G, true, gst_mini_object_unref, void, GstMiniObject* )
+LL_GRAB_SYM(G, true, g_object_set, void, gpointer, gchar const*, ... )
+LL_GRAB_SYM(G, true, g_source_remove, gboolean, guint )
+LL_GRAB_SYM(G, true, g_value_get_string, gchar const*, GValue const* )
+
+LL_GRAB_SYM(G, true, gst_debug_set_active, void, gboolean )
+LL_GRAB_SYM(G, true, gst_debug_add_log_function, void, GstLogFunction, gpointer, GDestroyNotify )
+LL_GRAB_SYM(G, true, gst_debug_set_default_threshold, void, GstDebugLevel )
+LL_GRAB_SYM(G, true, gst_debug_message_get , gchar const*, GstDebugMessage * )
+
+#undef G
diff --git a/indra/media_plugins/gstreamer10/media_plugin_gstreamer10.cpp b/indra/media_plugins/gstreamer10/media_plugin_gstreamer10.cpp
new file mode 100644
index 0000000000..0f45c151a2
--- /dev/null
+++ b/indra/media_plugins/gstreamer10/media_plugin_gstreamer10.cpp
@@ -0,0 +1,958 @@
+/**
+ * @file media_plugin_gstreamer10.cpp
+ * @brief GStreamer-1.0 plugin for LLMedia API plugin system
+ *
+ * @cond
+ * $LicenseInfo:firstyear=2016&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2016, Linden Research, Inc. / Nicky Dasmijn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ * @endcond
+ */
+
+#define FLIP_Y
+
+#include "linden_common.h"
+
+#include "llgl.h"
+
+#include "llplugininstance.h"
+#include "llpluginmessage.h"
+#include "llpluginmessageclasses.h"
+#include "media_plugin_base.h"
+
+#define G_DISABLE_CAST_CHECKS
+extern "C" {
+#include <gst/gst.h>
+#include <gst/app/gstappsink.h>
+}
+
+SymbolGrabber gstSymbolGrabber;
+
+#include "llmediaimplgstreamer_syms_raw.inc"
+
+static inline void llgst_caps_unref( GstCaps * caps )
+{
+ llgst_mini_object_unref( GST_MINI_OBJECT_CAST( caps ) );
+}
+
+static inline void llgst_sample_unref( GstSample *aSample )
+{
+ llgst_mini_object_unref( GST_MINI_OBJECT_CAST( aSample ) );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+class MediaPluginGStreamer10 : public MediaPluginBase
+{
+public:
+ MediaPluginGStreamer10(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~MediaPluginGStreamer10();
+
+ /* virtual */ void receiveMessage(const char *message_string);
+
+ static bool startup();
+ static bool closedown();
+
+ gboolean processGSTEvents(GstBus *bus, GstMessage *message);
+
+private:
+ std::string getVersion();
+ bool navigateTo( const std::string urlIn );
+ bool seek( double time_sec );
+ bool setVolume( float volume );
+
+ // misc
+ bool pause();
+ bool stop();
+ bool play(double rate);
+ bool getTimePos(double &sec_out);
+
+ double MIN_LOOP_SEC = 1.0F;
+ U32 INTERNAL_TEXTURE_SIZE = 1024;
+
+ bool mIsLooping;
+
+ enum ECommand {
+ COMMAND_NONE,
+ COMMAND_STOP,
+ COMMAND_PLAY,
+ COMMAND_FAST_FORWARD,
+ COMMAND_FAST_REWIND,
+ COMMAND_PAUSE,
+ COMMAND_SEEK,
+ };
+ ECommand mCommand;
+
+private:
+ bool unload();
+ bool load();
+
+ bool update(int milliseconds);
+ void mouseDown( int x, int y );
+ void mouseUp( int x, int y );
+ void mouseMove( int x, int y );
+
+ static bool mDoneInit;
+
+ guint mBusWatchID;
+
+ float mVolume;
+
+ int mDepth;
+
+ // padded texture size we need to write into
+ int mTextureWidth;
+ int mTextureHeight;
+
+ bool mSeekWanted;
+ double mSeekDestination;
+
+ // Very GStreamer-specific
+ GMainLoop *mPump; // event pump for this media
+ GstElement *mPlaybin;
+ GstAppSink *mAppSink;
+};
+
+//static
+bool MediaPluginGStreamer10::mDoneInit = false;
+
+MediaPluginGStreamer10::MediaPluginGStreamer10( LLPluginInstance::sendMessageFunction host_send_func,
+ void *host_user_data )
+ : MediaPluginBase(host_send_func, host_user_data)
+ , mBusWatchID ( 0 )
+ , mSeekWanted(false)
+ , mSeekDestination(0.0)
+ , mPump ( nullptr )
+ , mPlaybin ( nullptr )
+ , mAppSink ( nullptr )
+ , mCommand ( COMMAND_NONE )
+{
+}
+
+gboolean MediaPluginGStreamer10::processGSTEvents(GstBus *bus, GstMessage *message)
+{
+ if (!message)
+ return TRUE; // shield against GStreamer bug
+
+ switch (GST_MESSAGE_TYPE (message))
+ {
+ case GST_MESSAGE_BUFFERING:
+ {
+ // NEEDS GST 0.10.11+
+ if (llgst_message_parse_buffering)
+ {
+ gint percent = 0;
+ llgst_message_parse_buffering(message, &percent);
+ }
+ break;
+ }
+ case GST_MESSAGE_STATE_CHANGED:
+ {
+ GstState old_state;
+ GstState new_state;
+ GstState pending_state;
+ llgst_message_parse_state_changed(message,
+ &old_state,
+ &new_state,
+ &pending_state);
+
+ switch (new_state)
+ {
+ case GST_STATE_VOID_PENDING:
+ break;
+ case GST_STATE_NULL:
+ break;
+ case GST_STATE_READY:
+ setStatus(STATUS_LOADED);
+ break;
+ case GST_STATE_PAUSED:
+ setStatus(STATUS_PAUSED);
+ break;
+ case GST_STATE_PLAYING:
+ setStatus(STATUS_PLAYING);
+ break;
+ }
+ break;
+ }
+ case GST_MESSAGE_ERROR:
+ {
+ GError *err = nullptr;
+ gchar *debug = nullptr;
+
+ llgst_message_parse_error (message, &err, &debug);
+ if (err)
+ llg_error_free (err);
+ llg_free (debug);
+
+ mCommand = COMMAND_STOP;
+
+ setStatus(STATUS_ERROR);
+
+ break;
+ }
+ case GST_MESSAGE_INFO:
+ {
+ if (llgst_message_parse_info)
+ {
+ GError *err = nullptr;
+ gchar *debug = nullptr;
+
+ llgst_message_parse_info (message, &err, &debug);
+ if (err)
+ llg_error_free (err);
+ llg_free (debug);
+ }
+ break;
+ }
+ case GST_MESSAGE_WARNING:
+ {
+ GError *err = nullptr;
+ gchar *debug = nullptr;
+
+ llgst_message_parse_warning (message, &err, &debug);
+ if (err)
+ llg_error_free (err);
+ llg_free (debug);
+
+ break;
+ }
+ case GST_MESSAGE_EOS:
+ /* end-of-stream */
+ if (mIsLooping)
+ {
+ double eos_pos_sec = 0.0F;
+ bool got_eos_position = getTimePos(eos_pos_sec);
+
+ if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC)
+ {
+ // if we know that the movie is really short, don't
+ // loop it else it can easily become a time-hog
+ // because of GStreamer spin-up overhead
+ // inject a COMMAND_PAUSE
+ mCommand = COMMAND_PAUSE;
+ }
+ else
+ {
+ stop();
+ play(1.0);
+ }
+ }
+ else // not a looping media
+ {
+ // inject a COMMAND_STOP
+ mCommand = COMMAND_STOP;
+ }
+ break;
+ default:
+ /* unhandled message */
+ break;
+ }
+
+ /* we want to be notified again the next time there is a message
+ * on the bus, so return true (false means we want to stop watching
+ * for messages on the bus and our callback should not be called again)
+ */
+ return TRUE;
+}
+
+extern "C" {
+ gboolean llmediaimplgstreamer_bus_callback (GstBus *bus,
+ GstMessage *message,
+ gpointer data)
+ {
+ MediaPluginGStreamer10 *impl = (MediaPluginGStreamer10*)data;
+ return impl->processGSTEvents(bus, message);
+ }
+} // extern "C"
+
+
+
+bool MediaPluginGStreamer10::navigateTo ( const std::string urlIn )
+{
+ if (!mDoneInit)
+ return false; // error
+
+ setStatus(STATUS_LOADING);
+
+ mSeekWanted = false;
+
+ if (nullptr == mPump || nullptr == mPlaybin)
+ {
+ setStatus(STATUS_ERROR);
+ return false; // error
+ }
+
+ llg_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), nullptr);
+
+ // navigateTo implicitly plays, too.
+ play(1.0);
+
+ return true;
+}
+
+
+class GstSampleUnref
+{
+ GstSample *mT;
+public:
+ GstSampleUnref( GstSample *aT )
+ : mT( aT )
+ { llassert_always( mT ); }
+
+ ~GstSampleUnref( )
+ { llgst_sample_unref( mT ); }
+};
+
+bool MediaPluginGStreamer10::update(int milliseconds)
+{
+ if (!mDoneInit)
+ return false; // error
+
+ // DEBUGMSG("updating media...");
+
+ // sanity check
+ if (nullptr == mPump || nullptr == mPlaybin)
+ {
+ return false;
+ }
+
+ // see if there's an outstanding seek wanted
+ if (mSeekWanted &&
+ // bleh, GST has to be happy that the movie is really truly playing
+ // or it may quietly ignore the seek (with rtsp:// at least).
+ (GST_STATE(mPlaybin) == GST_STATE_PLAYING))
+ {
+ seek(mSeekDestination);
+ mSeekWanted = false;
+ }
+
+ // *TODO: time-limit - but there isn't a lot we can do here, most
+ // time is spent in gstreamer's own opaque worker-threads. maybe
+ // we can do something sneaky like only unlock the video object
+ // for 'milliseconds' and otherwise hold the lock.
+ while (llg_main_context_pending(llg_main_loop_get_context(mPump)))
+ {
+ llg_main_context_iteration(llg_main_loop_get_context(mPump), FALSE);
+ }
+
+ // check for availability of a new frame
+
+ if( !mAppSink )
+ return true;
+
+ if( GST_STATE(mPlaybin) != GST_STATE_PLAYING) // Do not try to pull a sample if not in playing state
+ return true;
+
+ GstSample *pSample = llgst_app_sink_pull_sample( mAppSink );
+ if(!pSample)
+ return false; // Done playing
+
+ GstSampleUnref oSampleUnref( pSample );
+ GstCaps *pCaps = llgst_sample_get_caps ( pSample );
+ if (!pCaps)
+ return false;
+
+ gint width = 0, height = 0;
+ GstStructure *pStruct = llgst_caps_get_structure ( pCaps, 0);
+
+ if(!llgst_structure_get_int ( pStruct, "width", &width) )
+ width = 0;
+ if(!llgst_structure_get_int ( pStruct, "height", &height) )
+ height = 0;
+
+ if( !mPixels || width == 0 || height == 0)
+ return true;
+
+ GstBuffer *pBuffer = llgst_sample_get_buffer ( pSample );
+ GstMapInfo map;
+ llgst_buffer_map ( pBuffer, &map, GST_MAP_READ);
+
+ // Our render buffer is always 1kx1k
+
+ U32 rowSkip = INTERNAL_TEXTURE_SIZE / mTextureHeight;
+ U32 colSkip = INTERNAL_TEXTURE_SIZE / mTextureWidth;
+
+ for (int row = 0; row < mTextureHeight; ++row)
+ {
+ U8 const *pTexelIn = map.data + (row*rowSkip * width *3);
+#ifndef FLIP_Y
+ U8 *pTexelOut = mPixels + (row * mTextureWidth * mDepth );
+#else
+ U8 *pTexelOut = mPixels + ((mTextureHeight-row-1) * mTextureWidth * mDepth );
+#endif
+ for( int col = 0; col < mTextureWidth; ++col )
+ {
+ pTexelOut[ 0 ] = pTexelIn[0];
+ pTexelOut[ 1 ] = pTexelIn[1];
+ pTexelOut[ 2 ] = pTexelIn[2];
+ pTexelOut += mDepth;
+ pTexelIn += colSkip*3;
+ }
+ }
+
+ llgst_buffer_unmap( pBuffer, &map );
+ setDirty(0,0,mTextureWidth,mTextureHeight);
+
+ return true;
+}
+
+void MediaPluginGStreamer10::mouseDown( int x, int y )
+{
+ // do nothing
+}
+
+void MediaPluginGStreamer10::mouseUp( int x, int y )
+{
+ // do nothing
+}
+
+void MediaPluginGStreamer10::mouseMove( int x, int y )
+{
+ // do nothing
+}
+
+
+bool MediaPluginGStreamer10::pause()
+{
+ // todo: error-check this?
+ if (mDoneInit && mPlaybin)
+ {
+ llgst_element_set_state(mPlaybin, GST_STATE_PAUSED);
+ return true;
+ }
+ return false;
+}
+
+bool MediaPluginGStreamer10::stop()
+{
+ // todo: error-check this?
+ if (mDoneInit && mPlaybin)
+ {
+ llgst_element_set_state(mPlaybin, GST_STATE_READY);
+ return true;
+ }
+ return false;
+}
+
+bool MediaPluginGStreamer10::play(double rate)
+{
+ // NOTE: we don't actually support non-natural rate.
+
+ // todo: error-check this?
+ if (mDoneInit && mPlaybin)
+ {
+ llgst_element_set_state(mPlaybin, GST_STATE_PLAYING);
+ return true;
+ }
+ return false;
+}
+
+bool MediaPluginGStreamer10::setVolume( float volume )
+{
+ // we try to only update volume as conservatively as
+ // possible, as many gst-plugins-base versions up to at least
+ // November 2008 have critical race-conditions in setting volume - sigh
+ if (mVolume == volume)
+ return true; // nothing to do, everything's fine
+
+ mVolume = volume;
+ if (mDoneInit && mPlaybin)
+ {
+ llg_object_set(mPlaybin, "volume", mVolume, nullptr);
+ return true;
+ }
+
+ return false;
+}
+
+bool MediaPluginGStreamer10::seek(double time_sec)
+{
+ bool success = false;
+ if (mDoneInit && mPlaybin)
+ {
+ success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME,
+ GstSeekFlags(GST_SEEK_FLAG_FLUSH |
+ GST_SEEK_FLAG_KEY_UNIT),
+ GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND),
+ GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
+ }
+ return success;
+}
+
+bool MediaPluginGStreamer10::getTimePos(double &sec_out)
+{
+ bool got_position = false;
+ if (mDoneInit && mPlaybin)
+ {
+ gint64 pos(0);
+ GstFormat timefmt = GST_FORMAT_TIME;
+ got_position =
+ llgst_element_query_position &&
+ llgst_element_query_position(mPlaybin,
+ &timefmt,
+ &pos);
+ got_position = got_position
+ && (timefmt == GST_FORMAT_TIME);
+ // GStreamer may have other ideas, but we consider the current position
+ // undefined if not PLAYING or PAUSED
+ got_position = got_position &&
+ (GST_STATE(mPlaybin) == GST_STATE_PLAYING ||
+ GST_STATE(mPlaybin) == GST_STATE_PAUSED);
+ if (got_position && !GST_CLOCK_TIME_IS_VALID(pos))
+ {
+ if (GST_STATE(mPlaybin) == GST_STATE_PLAYING)
+ {
+ // if we're playing then we treat an invalid clock time
+ // as 0, for complicated reasons (insert reason here)
+ pos = 0;
+ }
+ else
+ {
+ got_position = false;
+ }
+
+ }
+ // If all the preconditions succeeded... we can trust the result.
+ if (got_position)
+ {
+ sec_out = double(pos) / double(GST_SECOND); // gst to sec
+ }
+ }
+ return got_position;
+}
+
+bool MediaPluginGStreamer10::load()
+{
+ if (!mDoneInit)
+ return false; // error
+
+ setStatus(STATUS_LOADING);
+
+ mIsLooping = false;
+ mVolume = 0.1234567f; // minor hack to force an initial volume update
+
+ // Create a pumpable main-loop for this media
+ mPump = llg_main_loop_new (nullptr, FALSE);
+ if (!mPump)
+ {
+ setStatus(STATUS_ERROR);
+ return false; // error
+ }
+
+ // instantiate a playbin element to do the hard work
+ mPlaybin = llgst_element_factory_make ("playbin", "");
+ if (!mPlaybin)
+ {
+ setStatus(STATUS_ERROR);
+ return false; // error
+ }
+
+ // get playbin's bus
+ GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin));
+ if (!bus)
+ {
+ setStatus(STATUS_ERROR);
+ return false; // error
+ }
+ mBusWatchID = llgst_bus_add_watch (bus,
+ llmediaimplgstreamer_bus_callback,
+ this);
+ llgst_object_unref (bus);
+
+ mAppSink = (GstAppSink*)(llgst_element_factory_make ("appsink", ""));
+
+ GstCaps* pCaps = llgst_caps_new_simple( "video/x-raw",
+ "format", G_TYPE_STRING, "RGB",
+ "width", G_TYPE_INT, INTERNAL_TEXTURE_SIZE,
+ "height", G_TYPE_INT, INTERNAL_TEXTURE_SIZE,
+ nullptr );
+
+ llgst_app_sink_set_caps( mAppSink, pCaps );
+ llgst_caps_unref( pCaps );
+
+ if (!mAppSink)
+ {
+ setStatus(STATUS_ERROR);
+ return false;
+ }
+
+ llg_object_set(mPlaybin, "video-sink", mAppSink, nullptr);
+
+ return true;
+}
+
+bool MediaPluginGStreamer10::unload ()
+{
+ if (!mDoneInit)
+ return false; // error
+
+ // stop getting callbacks for this bus
+ llg_source_remove(mBusWatchID);
+ mBusWatchID = 0;
+
+ if (mPlaybin)
+ {
+ llgst_element_set_state (mPlaybin, GST_STATE_NULL);
+ llgst_object_unref (GST_OBJECT (mPlaybin));
+ mPlaybin = nullptr;
+ }
+
+ if (mPump)
+ {
+ llg_main_loop_quit(mPump);
+ mPump = nullptr;
+ }
+
+ mAppSink = nullptr;
+
+ setStatus(STATUS_NONE);
+
+ return true;
+}
+
+void LogFunction(GstDebugCategory *category, GstDebugLevel level, const gchar *file, const gchar *function, gint line, GObject *object, GstDebugMessage *message, gpointer user_data )
+{
+ std::cerr << file << ":" << line << "(" << function << "): " << llgst_debug_message_get( message ) << std::endl;
+}
+
+//static
+bool MediaPluginGStreamer10::startup()
+{
+ // first - check if GStreamer is explicitly disabled
+ if (nullptr != getenv("LL_DISABLE_GSTREAMER"))
+ return false;
+
+ // only do global GStreamer initialization once.
+ if (!mDoneInit)
+ {
+ ll_init_apr();
+
+ // Get symbols!
+ std::vector< std::string > vctDSONames;
+ vctDSONames.push_back( "libgstreamer-1.0.so.0" );
+ vctDSONames.push_back( "libgstapp-1.0.so.0" );
+ vctDSONames.push_back( "libglib-2.0.so.0" );
+ vctDSONames.push_back( "libgobject-2.0.so" );
+ if( !gstSymbolGrabber.grabSymbols( vctDSONames ) )
+ return false;
+
+ if (llgst_segtrap_set_enabled)
+ {
+ llgst_segtrap_set_enabled(FALSE);
+ }
+
+ // Gstreamer tries a fork during init, waitpid-ing on it,
+ // which conflicts with any installed SIGCHLD handler...
+ struct sigaction tmpact, oldact;
+ if (llgst_registry_fork_set_enabled ) {
+ // if we can disable SIGCHLD-using forking behaviour,
+ // do it.
+ llgst_registry_fork_set_enabled(false);
+ }
+ else {
+ // else temporarily install default SIGCHLD handler
+ // while GStreamer initialises
+ tmpact.sa_handler = SIG_DFL;
+ sigemptyset( &tmpact.sa_mask );
+ tmpact.sa_flags = SA_SIGINFO;
+ sigaction(SIGCHLD, &tmpact, &oldact);
+ }
+ // Protect against GStreamer resetting the locale, yuck.
+ static std::string saved_locale;
+ saved_locale = setlocale(LC_ALL, nullptr);
+
+ llgst_debug_set_default_threshold( GST_LEVEL_WARNING );
+ llgst_debug_add_log_function( LogFunction, nullptr, nullptr );
+ llgst_debug_set_active( false );
+
+ // finally, try to initialize GStreamer!
+ GError *err = nullptr;
+ gboolean init_gst_success = llgst_init_check(nullptr, nullptr, &err);
+
+ // restore old locale
+ setlocale(LC_ALL, saved_locale.c_str() );
+
+ // restore old SIGCHLD handler
+ if (!llgst_registry_fork_set_enabled)
+ sigaction(SIGCHLD, &oldact, nullptr);
+
+ if (!init_gst_success) // fail
+ {
+ if (err)
+ llg_error_free(err);
+ return false;
+ }
+
+ mDoneInit = true;
+ }
+
+ return true;
+}
+
+//static
+bool MediaPluginGStreamer10::closedown()
+{
+ if (!mDoneInit)
+ return false; // error
+
+ gstSymbolGrabber.ungrabSymbols();
+ mDoneInit = false;
+
+ return true;
+}
+
+MediaPluginGStreamer10::~MediaPluginGStreamer10()
+{
+ closedown();
+}
+
+std::string MediaPluginGStreamer10::getVersion()
+{
+ std::string plugin_version = "GStreamer10 media plugin, GStreamer version ";
+ if (mDoneInit &&
+ llgst_version)
+ {
+ guint major, minor, micro, nano;
+ llgst_version(&major, &minor, &micro, &nano);
+ plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor,
+ (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR,
+ (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO);
+ }
+ else
+ {
+ plugin_version += "(unknown)";
+ }
+ return plugin_version;
+}
+
+void MediaPluginGStreamer10::receiveMessage(const char *message_string)
+{
+ LLPluginMessage message_in;
+
+ if(message_in.parse(message_string) >= 0)
+ {
+ std::string message_class = message_in.getClass();
+ std::string message_name = message_in.getName();
+
+ if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+ {
+ if(message_name == "init")
+ {
+ LLPluginMessage message("base", "init_response");
+ LLSD versions = LLSD::emptyMap();
+ versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION;
+ message.setValueLLSD("versions", versions);
+
+ load();
+
+ message.setValue("plugin_version", getVersion());
+ sendMessage(message);
+ }
+ else if(message_name == "idle")
+ {
+ // no response is necessary here.
+ double time = message_in.getValueReal("time");
+
+ // Convert time to milliseconds for update()
+ update((int)(time * 1000.0f));
+ }
+ else if(message_name == "cleanup")
+ {
+ unload();
+ closedown();
+ }
+ else if(message_name == "shm_added")
+ {
+ SharedSegmentInfo info;
+ info.mAddress = message_in.getValuePointer("address");
+ info.mSize = (size_t)message_in.getValueS32("size");
+ std::string name = message_in.getValue("name");
+
+ mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+ }
+ else if(message_name == "shm_remove")
+ {
+ std::string name = message_in.getValue("name");
+
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if(iter != mSharedSegments.end())
+ {
+ if(mPixels == iter->second.mAddress)
+ {
+ // This is the currently active pixel buffer. Make sure we stop drawing to it.
+ mPixels = nullptr;
+ mTextureSegmentName.clear();
+ }
+ mSharedSegments.erase(iter);
+ }
+
+ // Send the response so it can be cleaned up.
+ LLPluginMessage message("base", "shm_remove_response");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ }
+ else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+ {
+ if(message_name == "init")
+ {
+ // Plugin gets to decide the texture parameters to use.
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+ // lame to have to decide this now, it depends on the movie. Oh well.
+ mDepth = 4;
+
+ mTextureWidth = 1;
+ mTextureHeight = 1;
+
+ message.setValueU32("format", GL_RGBA);
+ message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV);
+
+ message.setValueS32("depth", mDepth);
+ message.setValueS32("default_width", INTERNAL_TEXTURE_SIZE );
+ message.setValueS32("default_height", INTERNAL_TEXTURE_SIZE );
+ message.setValueU32("internalformat", GL_RGBA8);
+ message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left.
+ message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale
+ sendMessage(message);
+ }
+ else if(message_name == "size_change")
+ {
+ std::string name = message_in.getValue("name");
+ S32 width = message_in.getValueS32("width");
+ S32 height = message_in.getValueS32("height");
+ S32 texture_width = message_in.getValueS32("texture_width");
+ S32 texture_height = message_in.getValueS32("texture_height");
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+ message.setValue("name", name);
+ message.setValueS32("width", width);
+ message.setValueS32("height", height);
+ message.setValueS32("texture_width", texture_width);
+ message.setValueS32("texture_height", texture_height);
+ sendMessage(message);
+
+ if(!name.empty())
+ {
+ // Find the shared memory region with this name
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if(iter != mSharedSegments.end())
+ {
+ mPixels = (unsigned char*)iter->second.mAddress;
+ mTextureSegmentName = name;
+
+ mTextureWidth = texture_width;
+ mTextureHeight = texture_height;
+ memset( mPixels, 0, mTextureWidth*mTextureHeight*mDepth );
+ }
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request");
+ message.setValue("name", mTextureSegmentName);
+ message.setValueS32("width", INTERNAL_TEXTURE_SIZE );
+ message.setValueS32("height", INTERNAL_TEXTURE_SIZE );
+ sendMessage(message);
+
+ }
+ }
+ else if(message_name == "load_uri")
+ {
+ std::string uri = message_in.getValue("uri");
+ navigateTo( uri );
+ sendStatus();
+ }
+ else if(message_name == "mouse_event")
+ {
+ std::string event = message_in.getValue("event");
+ S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+
+ if(event == "down")
+ {
+ mouseDown(x, y);
+ }
+ else if(event == "up")
+ {
+ mouseUp(x, y);
+ }
+ else if(event == "move")
+ {
+ mouseMove(x, y);
+ };
+ };
+ }
+ else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
+ {
+ if(message_name == "stop")
+ {
+ stop();
+ }
+ else if(message_name == "start")
+ {
+ double rate = 0.0;
+ if(message_in.hasValue("rate"))
+ {
+ rate = message_in.getValueReal("rate");
+ }
+ // NOTE: we don't actually support rate.
+ play(rate);
+ }
+ else if(message_name == "pause")
+ {
+ pause();
+ }
+ else if(message_name == "seek")
+ {
+ double time = message_in.getValueReal("time");
+ // defer the actual seek in case we haven't
+ // really truly started yet in which case there
+ // is nothing to seek upon
+ mSeekWanted = true;
+ mSeekDestination = time;
+ }
+ else if(message_name == "set_loop")
+ {
+ bool loop = message_in.getValueBoolean("loop");
+ mIsLooping = loop;
+ }
+ else if(message_name == "set_volume")
+ {
+ double volume = message_in.getValueReal("volume");
+ setVolume(volume);
+ }
+ }
+ }
+}
+
+int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
+{
+ if( MediaPluginGStreamer10::startup() )
+ {
+ MediaPluginGStreamer10 *self = new MediaPluginGStreamer10(host_send_func, host_user_data);
+ *plugin_send_func = MediaPluginGStreamer10::staticReceiveMessage;
+ *plugin_user_data = (void*)self;
+
+ return 0; // okay
+ }
+ else
+ {
+ return -1; // failed to init
+ }
+}
diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
index ad0ecaf4ab..2356236d16 100644
--- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
+++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
@@ -560,7 +560,7 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
message.setValueS32("default_height", 1024);
message.setValueS32("depth", mDepth);
message.setValueU32("internalformat", GL_RGB);
- message.setValueU32("format", GL_BGRA_EXT);
+ message.setValueU32("format", GL_BGRA);
message.setValueU32("type", GL_UNSIGNED_BYTE);
message.setValueBoolean("coords_opengl", true);
sendMessage(message);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 5ee2915b60..3c6606613c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -13,7 +13,6 @@ include(BuildPackagesInfo)
include(BuildVersion)
include(CMakeCopyIfDifferent)
include(CubemapToEquirectangularJS)
-include(DBusGlib)
include(DragDrop)
if (USE_DISCORD)
include(Discord)
@@ -46,7 +45,6 @@ include(UI)
include(ViewerMiscLibs)
include(ViewerManager)
include(VisualLeakDetector)
-include(VulkanGltf)
include(ZLIBNG)
include(LLPrimitive)
@@ -78,6 +76,8 @@ if (HAVOK)
endif()
endif ()
+configure_file(llversioninfovars.h.in llversioninfovars.h @ONLY)
+
set(viewer_SOURCE_FILES
gltfscenemanager.cpp
gltf/asset.cpp
@@ -219,6 +219,7 @@ set(viewer_SOURCE_FILES
llfloatercreatelandmark.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
+ llfloaterdirectory.cpp
llfloaterdisplayname.cpp
llfloatereditenvironmentbase.cpp
llfloatereditextdaycycle.cpp
@@ -279,7 +280,6 @@ set(viewer_SOURCE_FILES
llfloaterpay.cpp
llfloaterperformance.cpp
llfloaterperms.cpp
- llfloaterpostprocess.cpp
llfloaterprofile.cpp
llfloaterpreference.cpp
llfloaterpreferencesgraphicsadvanced.cpp
@@ -442,11 +442,20 @@ set(viewer_SOURCE_FILES
llpanelblockedlist.cpp
llpanelclassified.cpp
llpanelcontents.cpp
+ llpaneldirbrowser.cpp
+ llpaneldirclassified.cpp
+ llpaneldirevents.cpp
+ llpaneldirgroups.cpp
+ llpaneldirland.cpp
+ llpaneldirpeople.cpp
+ llpaneldirplaces.cpp
+ llpaneldirweb.cpp
llpaneleditsky.cpp
llpaneleditwater.cpp
llpaneleditwearable.cpp
llpanelemojicomplete.cpp
llpanelenvironment.cpp
+ llpaneleventinfo.cpp
llpanelexperiencelisteditor.cpp
llpanelexperiencelog.cpp
llpanelexperiencepicker.cpp
@@ -526,6 +535,7 @@ set(viewer_SOURCE_FILES
llpathfindingobjectlist.cpp
llpathfindingpathtool.cpp
llpbrterrainfeatures.cpp
+ llperfstats.cpp
llpersistentnotificationstorage.cpp
llphysicsmotion.cpp
llphysicsshapebuilderutil.cpp
@@ -719,7 +729,6 @@ set(viewer_SOURCE_FILES
llvoiceclient.cpp
llvoicevisualizer.cpp
llvoicevivox.cpp
- llvoicewebrtc.cpp
llvoinventorylistener.cpp
llvopartgroup.cpp
llvosky.cpp
@@ -896,6 +905,7 @@ set(viewer_HEADER_FILES
llfloatercreatelandmark.h
llfloaterdeleteprefpreset.h
llfloaterdestinations.h
+ llfloaterdirectory.h
llfloaterdisplayname.h
llfloatereditenvironmentbase.h
llfloatereditextdaycycle.h
@@ -960,7 +970,6 @@ set(viewer_HEADER_FILES
llfloaterpay.h
llfloaterperformance.h
llfloaterperms.h
- llfloaterpostprocess.h
llfloaterprofile.h
llfloaterpreference.h
llfloaterpreferencesgraphicsadvanced.h
@@ -1111,11 +1120,20 @@ set(viewer_HEADER_FILES
llpanelblockedlist.h
llpanelclassified.h
llpanelcontents.h
+ llpaneldirbrowser.h
+ llpaneldirclassified.h
+ llpaneldirevents.h
+ llpaneldirgroups.h
+ llpaneldirland.h
+ llpaneldirpeople.h
+ llpaneldirplaces.h
+ llpaneldirweb.h
llpaneleditsky.h
llpaneleditwater.h
llpaneleditwearable.h
llpanelemojicomplete.h
llpanelenvironment.h
+ llpaneleventinfo.h
llpanelexperiencelisteditor.h
llpanelexperiencelog.h
llpanelexperiencepicker.h
@@ -1190,6 +1208,7 @@ set(viewer_HEADER_FILES
llpathfindingobject.h
llpathfindingobjectlist.h
llpathfindingpathtool.h
+ llperfstats.h
llpbrterrainfeatures.h
llpersistentnotificationstorage.h
llphysicsmotion.h
@@ -1389,7 +1408,6 @@ set(viewer_HEADER_FILES
llvoiceclient.h
llvoicevisualizer.h
llvoicevivox.h
- llvoicewebrtc.h
llvoinventorylistener.h
llvopartgroup.h
llvosky.h
@@ -1420,9 +1438,6 @@ set(viewer_HEADER_FILES
VorbisFramework.h
)
- list(APPEND viewer_SOURCE_FILES llperfstats.cpp)
- list(APPEND viewer_HEADER_FILES llperfstats.h)
-
source_group("CMake Rules" FILES ViewerInstall.cmake)
#build_data.json creation moved to viewer_manifest.py MAINT-6413
@@ -1430,11 +1445,10 @@ source_group("CMake Rules" FILES ViewerInstall.cmake)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt"
"${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}\n")
-set_source_files_properties(
- llversioninfo.cpp tests/llversioninfo_test.cpp
- PROPERTIES
- COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
- )
+if (NOT DISABLE_WEBRTC)
+ LIST(APPEND viewer_SOURCE_FILES llvoicewebrtc.cpp)
+ LIST(APPEND viewer_HEADER_FILES llvoicewebrtc.h)
+endif()
if (DARWIN)
LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp)
@@ -1461,7 +1475,6 @@ if (DARWIN)
llappdelegate-objc.mm
PROPERTIES
SKIP_PRECOMPILE_HEADERS TRUE
- COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
# BugsplatMac is a module, imported with @import. That language feature
# demands these -f switches.
# Xcode 10.2 requires that Objective-C++ headers declare nullability of
@@ -1490,14 +1503,6 @@ endif (DARWIN)
if (LINUX)
LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp)
- set_source_files_properties(
- llappviewerlinux.cpp
- PROPERTIES
- COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
- )
- LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
- SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
-
endif (LINUX)
if (WINDOWS)
@@ -1506,11 +1511,6 @@ if (WINDOWS)
llappviewerwin32.cpp
llwindebug.cpp
)
- set_source_files_properties(
- llappviewerwin32.cpp
- PROPERTIES
- COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
- )
list(APPEND viewer_HEADER_FILES
llappviewerwin32.h
@@ -1687,6 +1687,7 @@ set(viewer_APPSETTINGS_FILES
packages-info.txt
featuretable.txt
featuretable_mac.txt
+ featuretable_linux.txt
)
source_group("App Settings" FILES ${viewer_APPSETTINGS_FILES})
@@ -1710,6 +1711,15 @@ set_source_files_properties(${viewer_CHARACTER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
+set(viewer_MISC_FILES
+ viewer_manifest.py
+ )
+
+set_source_files_properties(${viewer_MISC_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND viewer_SOURCE_FILES ${viewer_MISC_FILES})
+
if (WINDOWS)
file(GLOB viewer_INSTALLER_FILES installers/windows/*.nsi)
@@ -1721,13 +1731,6 @@ if (WINDOWS)
list(APPEND viewer_SOURCE_FILES ${viewer_INSTALLER_FILES})
endif (WINDOWS)
-if( DEFINED LLSTARTUP_COMPILE_FLAGS )
- # progress view disables/enables icons based on available packages
- set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
-
- set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
-endif()
-
list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
add_executable(${VIEWER_BINARY_NAME}
@@ -1736,6 +1739,8 @@ add_executable(${VIEWER_BINARY_NAME}
${viewer_SOURCE_FILES}
)
+target_include_directories(${VIEWER_BINARY_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
+
# add package files
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -1984,11 +1989,13 @@ elseif (DARWIN)
target_link_libraries(${VIEWER_BINARY_NAME} llphysicsextensionsos)
endif()
else (WINDOWS)
- # Linux
- set_target_properties(${VIEWER_BINARY_NAME}
- PROPERTIES
- LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Wl,--Map=${VIEWER_BINARY_NAME}.MAP"
- )
+ if (HAVOK OR HAVOK_TPV)
+ # Linux
+ set_target_properties(${VIEWER_BINARY_NAME}
+ PROPERTIES
+ LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -no-pie -Wl,--Map=${VIEWER_BINARY_NAME}.MAP"
+ )
+ endif ()
endif (WINDOWS)
# *NOTE: - this list is very sensitive to ordering, test carefully on all
@@ -2036,7 +2043,6 @@ target_link_libraries(${VIEWER_BINARY_NAME}
llcorehttp
llcommon
llmeshoptimizer
- llwebrtc
lllogin
llprimitive
llappearance
@@ -2047,16 +2053,20 @@ target_link_libraries(${VIEWER_BINARY_NAME}
ll::openxr
)
+if (NOT DISABLE_WEBRTC)
+ target_link_libraries(${VIEWER_BINARY_NAME} llwebrtc )
+endif()
+
if (USE_DISCORD)
- target_link_libraries(${VIEWER_BINARY_NAME} ll::discord_sdk )
+ target_link_libraries(${VIEWER_BINARY_NAME} ll::discord_sdk )
endif ()
if( TARGET ll::intel_memops )
- target_link_libraries(${VIEWER_BINARY_NAME} ll::intel_memops )
+ target_link_libraries(${VIEWER_BINARY_NAME} ll::intel_memops )
endif()
if( TARGET ll::nvapi )
- target_link_libraries(${VIEWER_BINARY_NAME} ll::nvapi )
+ target_link_libraries(${VIEWER_BINARY_NAME} ll::nvapi )
endif()
if ( TARGET llconvexdecomposition )
@@ -2095,14 +2105,13 @@ if (LINUX)
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
SLPlugin
- #media_plugin_gstreamer010
- llcommon
+ media_plugin_cef
+ media_plugin_gstreamer10
+ media_plugin_libvlc
+ media_plugin_example
+ llwebrtc
)
- #if (NOT USE_BUGSPLAT)
- # LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger)
- #endif (NOT USE_BUGSPLAT)
-
add_custom_command(
OUTPUT ${product}.tar.xz
COMMAND ${PYTHON_EXECUTABLE}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f3c3b35d60..62a0ba81db 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5053,6 +5053,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>MediaPluginPipeWireVolumeCatcher</key>
+ <map>
+ <key>Comment</key>
+ <string>Use PipeWire instead of PulseAudio for controlling web media volume.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>MediaPluginForceVLC</key>
+ <map>
+ <key>Comment</key>
+ <string>Force use of VLC based media plugin. (Linux Only)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>MediaControlFadeTime</key>
<map>
<key>Comment</key>
@@ -7219,7 +7241,7 @@
<key>RenderAnisotropic</key>
<map>
<key>Comment</key>
- <string>Render textures using anisotropic filtering</string>
+ <string>[OBSOLETE] Render textures using anisotropic filtering</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -7227,6 +7249,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderAnisotropicLevel</key>
+ <map>
+ <key>Comment</key>
+ <string>Anisotropic filtering strength(0(Disable), 2x, 4x, 8x, 16x</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
<key>RenderAppleUseMultGL</key>
<map>
<key>Comment</key>
@@ -7443,7 +7476,7 @@
<key>RenderHiDPI</key>
<map>
<key>Comment</key>
- <string>Enable support for HiDPI displays, like Retina (macOS ONLY, requires restart)</string>
+ <string>Enable support for HiDPI displays, like Retina (macOS and Linux ONLY, requires restart)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -11107,6 +11140,45 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>ShowPGClassifieds</key>
+ <map>
+ <key>Comment</key>
+ <string>Display results of find classifieds that are flagged as general</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>HideFromEditor</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ShowMatureClassifieds</key>
+ <map>
+ <key>Comment</key>
+ <string>Display results of find classifieds that are flagged as moderate</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>HideFromEditor</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ShowAdultClassifieds</key>
+ <map>
+ <key>Comment</key>
+ <string>Display results of find classifieds that are flagged as adult</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>HideFromEditor</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>ShowPGSims</key>
<map>
<key>Comment</key>
@@ -11146,6 +11218,54 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>ShowPGEvents</key>
+ <map>
+ <key>Comment</key>
+ <string>Display results of find events that are flagged as general</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>HideFromEditor</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ShowMatureGroups</key>
+ <map>
+ <key>Comment</key>
+ <string>Include groups that are flagged as mature to Search results</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>HideFromEditor</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>FindLandArea</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables filtering of land search results by area</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>FindLandPrice</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables filtering of land search results by price</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>ShowNearClip</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl b/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl
index 5837308965..0fa4b32fda 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl
@@ -25,7 +25,6 @@
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
-#extension GL_EXT_gpu_shader4 : enable
/*[EXTRA_CODE_HERE]*/
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
index 5d770948c5..36eac9ed51 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
@@ -27,10 +27,10 @@
out vec3 vary_AdditiveColor;
out vec3 vary_AtmosAttenuation;
-vec3 additive_color;
-vec3 atmos_attenuation;
-vec3 sunlit_color;
-vec3 amblit_color;
+vec3 additive_color = vec3(1.0, 1.0, 1.0);
+vec3 atmos_attenuation = vec3(1.0, 1.0, 1.0);
+vec3 sunlit_color = vec3(1.0, 1.0, 1.0);
+vec3 amblit_color = vec3(1.0, 1.0, 1.0);
vec3 getSunlitColor()
{
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index cc9d72fae6..e405a9ea2d 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -250,8 +250,8 @@ void main()
vec3 amblit_linear = amblit;
vec3 irradiance = amblit;
- vec3 glossenv;
- vec3 legacyenv;
+ vec3 glossenv = vec3(0.0);
+ vec3 legacyenv = vec3(0.0);
sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, frag, pos.xyz, norm.xyz, 0.0, 0.0, true, amblit_linear);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
index 0418f99459..5b5827fd67 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
@@ -188,8 +188,8 @@ void main()
vec3 radiance = vec3(0);
sampleReflectionProbes(irradiance, radiance, vary_position.xy*0.5+0.5, pos.xyz, norm.xyz, gloss, true, amblit);
- vec3 diffuseColor;
- vec3 specularColor;
+ vec3 diffuseColor = vec3(0.0);
+ vec3 specularColor = vec3(0.0);
calcDiffuseSpecular(col.rgb, metallic, diffuseColor, specularColor);
vec3 v = -normalize(pos.xyz);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
index 03dc3d7113..32b788d433 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
@@ -78,9 +78,9 @@ void main()
float env_intensity = vertex_color.a;
- vec3 ambenv;
- vec3 glossenv;
- vec3 legacyenv;
+ vec3 ambenv = vec3(1.0);
+ vec3 glossenv = vec3(0.0);
+ vec3 legacyenv = vec3(0.0);
vec3 norm = normalize(vary_texcoord1.xyz);
vec4 spec = vec4(0,0,0,0);
sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, vec2(0), pos.xyz, norm.xyz, spec.a, env_intensity, false, amblit);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index 5708fc319f..f7505fbfe5 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -337,8 +337,8 @@ void main()
vec3 amblit_linear = amblit;
vec3 ambenv = amblit;
- vec3 glossenv;
- vec3 legacyenv;
+ vec3 glossenv = vec3(0.0);
+ vec3 legacyenv = vec3(0.0);
sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xy*0.5+0.5, pos.xyz, norm.xyz, glossiness, env, true, amblit_linear);
color = ambenv;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 948387a6ed..b3b8d295b9 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -180,8 +180,8 @@ void main()
adjustIrradiance(irradiance, ambocc);
- vec3 diffuseColor;
- vec3 specularColor;
+ vec3 diffuseColor = vec3(0.0);
+ vec3 specularColor = vec3(0.0);
calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor);
vec3 v = -normalize(pos.xyz);
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index 349f3b9a67..d5e00f3a3f 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -122,9 +122,7 @@ vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
vec3 toneMapNoExposure(vec3 color);
-vec3 vN, vT, vB;
-
-vec3 transform_normal(vec3 vNt)
+vec3 transform_normal(vec3 vN, vec3 vT, vec3 vB, vec3 vNt)
{
return normalize(vNt.x * vT + vNt.y * vB + vNt.z * vN);
}
@@ -184,9 +182,9 @@ void main()
{
mirrorClip(vary_position);
- vN = vary_normal;
- vT = vary_tangent;
- vB = cross(vN, vT);
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent;
+ vec3 vB = cross(vN, vT);
vec3 pos = vary_position.xyz;
float linear_depth = 1 / -pos.z;
@@ -222,14 +220,14 @@ void main()
vec3 waver = wavef*3;
- vec3 up = transform_normal(vec3(0,0,1));
+ vec3 up = transform_normal(vN, vT, vB, vec3(0,0,1));
float vdu = -dot(viewVec, up)*2;
vec3 wave_ibl = wavef * normScale;
wave_ibl.z *= 2.0;
- wave_ibl = transform_normal(normalize(wave_ibl));
+ wave_ibl = transform_normal(vN, vT, vB, normalize(wave_ibl));
- vec3 norm = transform_normal(normalize(wavef));
+ vec3 norm = transform_normal(vN, vT, vB, normalize(wavef));
vdu = clamp(vdu, 0, 1);
//wavef.z *= max(vdu*vdu*vdu, 0.1);
@@ -237,7 +235,7 @@ void main()
wavef = normalize(wavef);
//wavef = vec3(0, 0, 1);
- wavef = transform_normal(wavef);
+ wavef = transform_normal(vN, vT, vB, wavef);
float dist2 = dist;
dist = max(dist, 5.0);
@@ -312,7 +310,7 @@ void main()
vec3 colorEmissive = vec3(0);
float ao = 1.0;
- vec3 light_dir = transform_normal(lightDir);
+ vec3 light_dir = transform_normal(vN, vT, vB, lightDir);
float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 1090dd8ffb..eca58938cf 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 74
+version 75
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -27,7 +27,7 @@ version 74
// NOTE: All settings are set to the MIN of applied values, including 'all'!
//
list all
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 16
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
@@ -92,7 +92,7 @@ RenderReflectionProbeCount 1 256
// Low Graphics Settings
//
list Low
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -135,7 +135,7 @@ RenderReflectionProbeCount 1 1
// Medium Low Graphics Settings
//
list LowMid
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
@@ -178,7 +178,7 @@ RenderReflectionProbeCount 1 32
// Medium Graphics Settings (standard)
//
list Mid
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -220,7 +220,7 @@ RenderReflectionProbeCount 1 64
// Medium High Graphics Settings
//
list MidHigh
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 4
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -262,7 +262,7 @@ RenderReflectionProbeCount 1 64
// High Graphics Settings (SSAO + sun shadows)
//
list High
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 4
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -301,10 +301,10 @@ RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 128
//
-// High Ultra Graphics Settings (deferred + SSAO + all shadows)
+// High Ultra Graphics Settings (SSAO + all shadows)
//
list HighUltra
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 4
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -346,7 +346,7 @@ RenderReflectionProbeCount 1 256
// Ultra graphics (REALLY PURTY!)
//
list Ultra
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 8
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarPhysicsLODFactor 1 1.0
@@ -400,10 +400,16 @@ list VRAMGT512
RenderCompressTextures 1 0
//
+// AF Missing or AF < 2
+//
+list AnisotropicMissing
+RenderAnisotropicLevel 0 0
+
+//
// "Default" setups for safe, low, medium, high
//
list safe
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
RenderLocalLightCount 1 0
@@ -419,7 +425,7 @@ RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 0 0
list Intel
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 0
RenderFSAAType 1 0
RenderFSAASamples 1 0
RenderGLContextCoreProfile 1 0
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index d8d4f08429..a160161ef1 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -1,10 +1,10 @@
-version 30
+version 34
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
// defaults. This should be as rare an event as we can manage.
-// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
+// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
//
@@ -27,28 +27,28 @@ version 30
// NOTE: All settings are set to the MIN of applied values, including 'all'!
//
list all
-RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
+RenderAnisotropicLevel 1 16
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
-RenderDelayVBUpdate 1 0
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderFogRatio 1 4.0
RenderGamma 1 0
RenderGlowResolutionPow 1 9
-RenderGround 1 1
RenderMaxPartCount 1 8192
RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 4
+RenderLocalLightCount 1 4096
+RenderTransparentWater 1 1
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 2
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTreeLODFactor 1 1.0
RenderVBOEnable 1 1
RenderVBOMappingDisable 1 1
@@ -61,58 +61,38 @@ Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
+RenderReflectionProbeLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
-RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
-RenderFSAASamples 1 16
+RenderUseStreamVBO 1 1
+RenderFSAAType 1 2
+RenderFSAASamples 1 3
RenderMaxTextureIndex 1 16
+RenderGLContextCoreProfile 1 1
+RenderGLMultiThreadedTextures 1 0
+RenderGLMultiThreadedMedia 1 0
+RenderReflectionProbeResolution 1 128
+RenderScreenSpaceReflections 1 1
RenderMirrors 1 1
-
-//
-// Low Graphics Settings (fixed function)
-//
-list LowFixedFunction
-RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
-RenderAvatarLODFactor 1 0
-RenderAvatarPhysicsLODFactor 1 0
-RenderAvatarMaxNonImpostors 1 3
-RenderAvatarMaxComplexity 1 25000
-RenderFarClip 1 64
-RenderFlexTimeFactor 1 0
-RenderGlowResolutionPow 1 8
-RenderLocalLights 1 0
-RenderMaxPartCount 1 0
-RenderObjectBump 1 0
-RenderReflectionDetail 1 0
-RenderTerrainDetail 1 0
-RenderTerrainLODFactor 1 1
-RenderTransparentWater 1 0
-RenderTreeLODFactor 1 0
-RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
-RenderDeferredSSAO 1 0
-RenderUseAdvancedAtmospherics 1 0
-RenderShadowDetail 1 0
-WLSkyDetail 1 48
-RenderFSAASamples 1 0
-RenderMirrors 1 0
-RenderHeroProbeResolution 1 256
-RenderHeroProbeDistance 1 4
-RenderHeroProbeUpdateRate 1 6
+RenderHeroProbeResolution 1 2048
+RenderHeroProbeDistance 1 16
+RenderHeroProbeUpdateRate 1 6
RenderHeroProbeConservativeUpdateMultiplier 1 16
+RenderDownScaleMethod 1 0
+RenderCASSharpness 1 1
RenderExposure 1 4
RenderTonemapType 1 1
RenderTonemapMix 1 1
+RenderDisableVintageMode 1 1
+RenderMaxTextureResolution 1 2048
+RenderReflectionProbeCount 1 256
//
// Low Graphics Settings
//
list Low
-RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
+RenderAnisotropicLevel 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -120,297 +100,298 @@ RenderAvatarMaxComplexity 1 35000
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
-RenderLocalLights 1 0
+RenderLocalLightCount 1 8
RenderMaxPartCount 1 0
-RenderObjectBump 1 0
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 0
+RenderReflectionsEnabled 1 0
+RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
-RenderTransparentWater 1 0
+RenderTerrainPBRDetail 1 -4
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
-RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
+RenderFSAAType 1 0
RenderFSAASamples 1 0
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 0
RenderMirrors 1 0
RenderHeroProbeResolution 1 256
RenderHeroProbeDistance 1 4
-RenderHeroProbeUpdateRate 1 6
+RenderHeroProbeUpdateRate 1 6
RenderHeroProbeConservativeUpdateMultiplier 1 16
+RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 512
+RenderReflectionProbeCount 1 1
//
// Medium Low Graphics Settings
//
list LowMid
-RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
+RenderAnisotropicLevel 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
+RenderAvatarMaxNonImpostors 1 5
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
RenderMaxPartCount 1 2048
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 256
+RenderTransparentWater 1 0
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
-RenderTransparentWater 1 1
+RenderTerrainPBRDetail 1 -1
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
-RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
+RenderFSAAType 1 0
RenderFSAASamples 1 0
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 0
RenderMirrors 1 0
RenderHeroProbeResolution 1 256
RenderHeroProbeDistance 1 6
RenderHeroProbeUpdateRate 1 3
RenderHeroProbeConservativeUpdateMultiplier 1 16
+RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 1024
+RenderReflectionProbeCount 1 32
//
// Medium Graphics Settings (standard)
//
list Mid
-RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarMaxNonImpostors 1 7
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 512
+RenderTransparentWater 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
-RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 0
+RenderVolumeLODFactor 1 1.25
RenderDeferredSSAO 1 0
-RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
-RenderFSAASamples 1 2
+WLSkyDetail 1 96
+RenderFSAAType 1 1
+RenderFSAASamples 1 1
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 0
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 1
RenderMirrors 1 0
RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 6
RenderHeroProbeUpdateRate 1 3
RenderHeroProbeConservativeUpdateMultiplier 1 16
+RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
+RenderReflectionProbeCount 1 64
//
-// Medium High Graphics Settings (deferred enabled)
+// Medium High Graphics Settings
//
list MidHigh
-RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarMaxNonImpostors 1 9
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 1024
+RenderTransparentWater 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
-RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
-RenderUseAdvancedAtmospherics 1 0
+RenderVolumeLODFactor 1 1.375
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
-RenderFSAASamples 1 2
+WLSkyDetail 1 96
+RenderFSAAType 1 1
+RenderFSAASamples 1 1
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 1
RenderMirrors 1 0
RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 6
RenderHeroProbeUpdateRate 1 2
RenderHeroProbeConservativeUpdateMultiplier 1 8
+RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
+RenderReflectionProbeCount 1 64
//
-// High Graphics Settings (deferred + SSAO)
+// High Graphics Settings (SSAO + sun shadows)
//
list High
-RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
+RenderAnisotropicLevel 1 4
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarMaxNonImpostors 1 11
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 2048
+RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTreeLODFactor 1 0.5
-RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
+RenderVolumeLODFactor 1 1.5
RenderDeferredSSAO 1 1
-RenderUseAdvancedAtmospherics 1 0
-RenderShadowDetail 1 0
-WLSkyDetail 1 48
+RenderShadowDetail 1 1
+WLSkyDetail 1 96
+RenderFSAAType 1 2
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 2
RenderMirrors 1 0
RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 8
RenderHeroProbeUpdateRate 1 2
RenderHeroProbeConservativeUpdateMultiplier 1 8
+RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
+RenderReflectionProbeCount 1 128
//
-// High Ultra Graphics Settings (deferred + SSAO + shadows)
+// High Ultra Graphics Settings (SSAO + all shadows)
//
list HighUltra
-RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
+RenderAnisotropicLevel 1 4
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarMaxNonImpostors 1 16
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
-RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
+RenderVolumeLODFactor 1 1.75
RenderDeferredSSAO 1 1
-RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
-WLSkyDetail 1 48
+WLSkyDetail 1 96
+RenderFSAAType 1 2
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 3
RenderMirrors 1 0
-RenderHeroProbeResolution 1 512
+RenderHeroProbeResolution 1 1024
RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 1
RenderHeroProbeConservativeUpdateMultiplier 1 4
+RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
+RenderReflectionProbeCount 1 256
//
// Ultra graphics (REALLY PURTY!)
//
list Ultra
-RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
+RenderAnisotropicLevel 1 8
RenderAvatarLODFactor 1 1.0
+RenderAvatarMaxNonImpostors 1 16
RenderAvatarPhysicsLODFactor 1 1.0
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
-RenderLocalLights 1 1
+RenderLocalLightCount 1 8192
RenderMaxPartCount 1 8192
-RenderObjectBump 1 1
-RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
-RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
-RenderFSAASamples 1 2
+RenderFSAAType 1 2
+RenderFSAASamples 1 3
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 3
RenderMirrors 1 0
-RenderHeroProbeResolution 1 1024
+RenderHeroProbeResolution 1 2048
RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 1
RenderHeroProbeConservativeUpdateMultiplier 1 4
+RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
+RenderReflectionProbeCount 1 256
//
// Class Unknown Hardware (unknown)
//
list Unknown
-RenderVBOEnable 1 0
RenderShadowDetail 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
-RenderUseAdvancedAtmospherics 1 0
-
-//
-// Class 0 Hardware (just old)
-//
-list Class0
-RenderVBOEnable 1 1
-
-//
-// Class 1 Hardware
-//
-list Class1
-RenderVBOEnable 1 1
-
-//
-// Class 2 Hardware
-//
-list Class2
-RenderVBOEnable 1 1
-
-//
-// Class 3 Hardware
-//
-list Class3
-RenderVBOEnable 1 1
-
-//
-// Class 4 Hardware
-//
-list Class4
-RenderVBOEnable 1 1
-
-//
-// Class 5 Hardware
-//
-list Class5
-RenderVBOEnable 1 1
+RenderMirrors 1 0
+RenderDisableVintageMode 1 0
//
// VRAM > 512MB
@@ -419,339 +400,58 @@ list VRAMGT512
RenderCompressTextures 1 0
//
-// No Pixel Shaders available
-//
-list NoPixelShaders
-RenderAvatarCloth 0 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
-RenderDeferredSSAO 0 0
-RenderUseAdvancedAtmospherics 0 0
-RenderShadowDetail 0 0
-
-//
-// No Vertex Shaders available
+// AF Missing or AF < 2
//
-list NoVertexShaders
-RenderAvatarCloth 0 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
-RenderDeferredSSAO 0 0
-RenderUseAdvancedAtmospherics 0 0
-RenderShadowDetail 0 0
-
-//
-// GL_ARB_map_buffer_range exists
-//
-list MapBufferRange
-RenderVBOMappingDisable 1 1
-
+list AnisotropicMissing
+RenderAnisotropicLevel 0 0
//
// "Default" setups for safe, low, medium, high
//
list safe
-RenderAnisotropic 1 0
-RenderAvatarCloth 0 0
+RenderAnisotropicLevel 1 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
-RenderObjectBump 0 0
-RenderLocalLights 1 0
+RenderLocalLightCount 1 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
+RenderTransparentWater 1 0
RenderDeferredSSAO 0 0
-RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
-
-//
-// CPU based feature masks
-//
-
-// 1Ghz or less (equiv)
-list CPUSlow
-RenderMaxPartCount 1 1024
-
-//
-// RAM based feature masks
-//
-list RAM256MB
-RenderObjectBump 0 0
-
-//
-// Graphics card based feature masks
-//
-list OpenGLPre15
-RenderVBOEnable 1 0
-
-list OpenGLPre30
-RenderDeferred 0 0
-RenderMaxTextureIndex 1 1
+RenderReflectionProbeDetail 0 -1
+RenderMirrors 0 0
+RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 2048
+RenderReflectionProbeCount 0 0
list Intel
-RenderAnisotropic 1 0
-// Avoid some Intel crashes on Linux
-RenderCubeMap 0 0
+RenderAnisotropicLevel 1 0
+RenderFSAAType 1 0
RenderFSAASamples 1 0
+RenderGLContextCoreProfile 1 0
+RenderGLMultiThreadedMedia 1 0
+RenderDownScaleMethod 1 0
-list GeForce2
-RenderAnisotropic 1 0
-RenderMaxPartCount 1 2048
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 1
-
-list SiS
-UseOcclusion 0 0
-
-
-list Intel_830M
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_845G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_855GM
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_865G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_900
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_915GM
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_915G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_945GM
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_945G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_950
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_965
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-UseOcclusion 0 0
-
-list Intel_G33
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Bear_Lake
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Broadwater
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Brookdale
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Montara
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Springdale
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-
-list ATI_FireGL_5200
-RenderVBOEnable 1 0
-WindLightUseAtmosShaders 0 0
-
-
-list ATI_Mobility_Radeon_7xxx
-RenderVBOEnable 0 0
-
-list ATI_Radeon_7xxx
-RenderVBOEnable 0 0
-
-list ATI_All-in-Wonder_Radeon
-RenderVBOEnable 0 0
-
-list ATI_All-in-Wonder_7500
-RenderVBOEnable 0 0
-
-list ATI_Mobility_Radeon_9600
-Disregard96DefaultDrawDistance 1 0
-
-
-/// tweaked ATI to 96 Draw distance
-
-list ATI_Radeon_9000
-Disregard96DefaultDrawDistance 1 0
-list ATI_Radeon_9200
-Disregard96DefaultDrawDistance 1 0
-list ATI_Radeon_9500
-Disregard96DefaultDrawDistance 1 0
-list ATI_Radeon_9600
-Disregard96DefaultDrawDistance 1 0
-
-/// tweaked ATI to 128 draw distance
-
-list ATI_Radeon_X300
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X400
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X500
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X600
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X700
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X1300
-Disregard128DefaultDrawDistance 1 0
-UseStartScreen 0 0
-list ATI_Radeon_X1400
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X1500
-Disregard128DefaultDrawDistance 1 0
-UseStartScreen 0 0
-list ATI_Radeon_X1600
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X1700
-Disregard128DefaultDrawDistance 1 0
-list ATI_Mobility_Radeon_X1xxx
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_HD_2300
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_HD_2400
-Disregard128DefaultDrawDistance 1 0
-list ATI_ASUS_AH24xx
-Disregard128DefaultDrawDistance 1 0
-
-
-// Avatar hardware skinning causes invisible avatars
-// on various ATI chipsets on drivers before 8.2
-
-list ATIOldDriver
-RenderAvatarCloth 0 0
-// Avoid driver crashes with some features on Linux with old ATI drivers
-UseOcclusion 0 0
-WindLightUseAtmosShaders 0 0
-
-
-/// Tweaked NVIDIA
-
-list NVIDIA_GeForce_FX_5100
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_5200
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_5500
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_5600
-Disregard96DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_FX_Go5100
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5200
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5300
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5500
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5600
-Disregard96DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_6100
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_6200
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_6500
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_6600
-Disregard128DefaultDrawDistance 1 0
+list AMD
+RenderGLMultiThreadedTextures 1 0
-list NVIDIA_G73
-Disregard128DefaultDrawDistance 1 0
+list NVIDIA
+RenderGLMultiThreadedMedia 1 1
-list NVIDIA_GeForce_Go_6100
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6200
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6500
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6600
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6700
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6800
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
+list GL3
+RenderFSAAType 0 0
+RenderFSAASamples 0 0
+RenderReflectionsEnabled 0 0
+RenderReflectionProbeDetail 0 0
+RenderMirrors 0 0
+RenderGLMultiThreadedTextures 0 0
+RenderGLMultiThreadedMedia 0 0
+RenderDisableVintageMode 1 0
+RenderReflectionProbeCount 0 0
-list NVIDIA_GeForce_7000
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7100
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7200
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7300
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7400
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7500
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7600
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7700
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7800
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7900
-RenderShaderLightingMaxLevel 1 2
+list TexUnit16orLess
+RenderTerrainPBRDetail 1 -1
-list NVIDIA_GeForce_Go_7200
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7300
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7300_LE
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7400
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7600
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7700
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7800
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7900
-RenderShaderLightingMaxLevel 1 2
+list VaryingVectors16orLess
+RenderTerrainPBRPlanarSampleCount 1 1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index c3e2dd0c41..b75df5e3f2 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 73
+version 74
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -27,7 +27,7 @@ version 73
// NOTE: All settings are set to the MIN of applied values, including 'all'!
//
list all
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 16
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
@@ -92,7 +92,7 @@ RenderReflectionProbeCount 1 256
// Low Graphics Settings
//
list Low
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -135,7 +135,7 @@ RenderReflectionProbeCount 1 1
// Medium Low Graphics Settings
//
list LowMid
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
@@ -178,7 +178,7 @@ RenderReflectionProbeCount 1 32
// Medium Graphics Settings (standard)
//
list Mid
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -220,7 +220,7 @@ RenderReflectionProbeCount 1 64
// Medium High Graphics Settings
//
list MidHigh
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -262,7 +262,7 @@ RenderReflectionProbeCount 1 64
// High Graphics Settings (SSAO + sun shadows)
//
list High
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -304,7 +304,7 @@ RenderReflectionProbeCount 1 128
// High Ultra Graphics Settings (SSAO + all shadows)
//
list HighUltra
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
@@ -346,7 +346,7 @@ RenderReflectionProbeCount 1 256
// Ultra graphics (REALLY PURTY!)
//
list Ultra
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 4
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
@@ -401,10 +401,17 @@ list VRAMGT512
RenderCompressTextures 1 0
//
+//
+// AF Missing or AF < 2
+//
+list AnisotropicMissing
+RenderAnisotropicLevel 0 0
+
+//
// "Default" setups for safe, low, medium, high
//
list safe
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
RenderLocalLightCount 1 0
@@ -434,7 +441,7 @@ RenderGLMultiThreadedMedia 1 0
RenderAppleUseMultGL 1 0
list Intel
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 0
RenderFSAASamples 1 0
RenderGLMultiThreadedTextures 1 0
RenderGLMultiThreadedMedia 1 0
diff --git a/indra/newview/gltf/accessor.cpp b/indra/newview/gltf/accessor.cpp
index f0ad3fa594..900c1da170 100644
--- a/indra/newview/gltf/accessor.cpp
+++ b/indra/newview/gltf/accessor.cpp
@@ -213,7 +213,7 @@ bool Buffer::save(Asset& asset, const std::string& folder)
bin_file += mUri;
- std::ofstream file(bin_file, std::ios::binary);
+ llofstream file(bin_file, std::ios::binary);
if (!file.is_open())
{
LL_WARNS("GLTF") << "Failed to open file: " << bin_file << LL_ENDL;
diff --git a/indra/newview/gltf/asset.cpp b/indra/newview/gltf/asset.cpp
index 28f30ae1c9..daa992b269 100644
--- a/indra/newview/gltf/asset.cpp
+++ b/indra/newview/gltf/asset.cpp
@@ -928,7 +928,7 @@ bool Asset::save(const std::string& filename)
object obj;
serialize(obj);
std::string buffer = boost::json::serialize(obj, {});
- std::ofstream file(filename, std::ios::binary);
+ llofstream file(filename, std::ios::binary);
file.write(buffer.c_str(), buffer.size());
return true;
@@ -1090,7 +1090,7 @@ bool Image::save(Asset& asset, const std::string& folder)
// set URI to non-j2c file for now, but later we'll want to reference the j2c hash
mUri = name + extension;
- std::ofstream file(filename, std::ios::binary);
+ llofstream file(filename, std::ios::binary);
file.write((const char*)buffer.mData.data() + bufferView.mByteOffset, bufferView.mByteLength);
}
else if (mTexture.notNull())
diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp
index 4f8f80129d..c7e598beb7 100644
--- a/indra/newview/gltf/llgltfloader.cpp
+++ b/indra/newview/gltf/llgltfloader.cpp
@@ -489,7 +489,7 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>
}
else
{
- setLoadState(ERROR_MODEL + pModel->getStatus());
+ setLoadState(static_cast<U32>(ERROR_MODEL) + static_cast<U32>(pModel->getStatus()));
delete pModel;
return;
}
@@ -1762,7 +1762,7 @@ std::string LLGLTFLoader::extractTextureToTempFile(S32 textureIndex, const std::
"gltf_embedded_" + texture_type + "_" + std::to_string(sourceIndex) + extension;
// Write the image data to the temporary file
- std::ofstream temp_file(temp_filename, std::ios::binary);
+ llofstream temp_file(temp_filename, std::ios::binary);
if (temp_file.is_open())
{
temp_file.write(reinterpret_cast<const char*>(data_ptr), data_size);
diff --git a/indra/newview/linux_tools/client-readme-joystick.txt b/indra/newview/linux_tools/client-readme-joystick.txt
deleted file mode 100644
index 4f89a73ccb..0000000000
--- a/indra/newview/linux_tools/client-readme-joystick.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-Second Life - Joystick & SpaceNavigator Support README
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-WHAT IS IT?
--=-=-=-=-=-
-
-This feature allows the use of a joystick or other supported multi-axis
-device for controlling your avatar and camera.
-
-REQUIREMENTS
--=-=-=-=-=-=
-
-* A joystick or other generic multi-axis input device supported by your chosen
- version of Linux
-
-- OR -
-
-* A SpaceNavigator device (additional configuration may be required, see below)
-
-Success has been reported on the following systems so far:
-* Ubuntu 7.04 (Feisty) with a generic USB joystick
-* Ubuntu 7.04 (Feisty) with a USB 3DConnexion SpaceNavigator
-* Ubuntu 6.06 (Dapper) with a generic USB joystick
-* Ubuntu 6.06 (Dapper) with a USB 3DConnexion SpaceNavigator
-
-CONFIGURATION
--=-=-=-=-=-=-
-
-SPACE NAVIGATOR: *Important* - do not install the Linux SpaceNavigator
-drivers from the disk included with the device - these are problematic.
-Some distributions of Linux (such as Ubuntu, Gentoo and Mandriva) will
-need some system configuration to make the SpaceNavigator usable by
-applications such as the Second Life Viewer, as follows:
-
-* Mandriva Linux Configuration:
- You need to add two new files to your system. This only needs to be
- done once. These files are available at the 'SpaceNavigator support with
- udev and Linux input framework' section of
- <http://www.aaue.dk/~janoc/index.php?n=Personal.Downloads>
-
-* Ubuntu or Gentoo Linux Configuration:
- For a quick start, you can simply paste the following line into a terminal
- before plugging in your SpaceNavigator - this only needs to be done once:
- sudo bash -c 'echo KERNEL==\"event[0-9]*\", SYSFS{idVendor}==\"046d\", SYSFS{idProduct}==\"c626\", SYMLINK+=\"input/spacenavigator\", GROUP=\"plugdev\", MODE=\"664\" > /etc/udev/rules.d/91-spacenavigator-LL.rules ; echo "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><deviceinfo version=\"0.2\"><device><match key=\"info.product\" contains=\"3Dconnexion SpaceNavigator\"><merge key=\"input.x11_driver\" type=\"string\"></merge></match></device></deviceinfo>" > /etc/hal/fdi/policy/3Dconnexion_SpaceNavigator_LL.fdi'
-
-For more comprehensive Linux SpaceNavigator configuration information please
-see the section 'Installing SpaceNavigator without the official driver' here:
-<http://www.aaue.dk/~janoc/index.php?n=Personal.3DConnexionSpaceNavigatorSupport>
-
-JOYSTICKS: These should be automatically detected and configured on all
-modern distributions of Linux.
-
-ALL: Your joystick or SpaceNavigator should be plugged-in before you start the
-Second Life Viewer, so that it may be detected. If you have multiple input
-devices attached, only the first detected SpaceNavigator or joystick device
-will be available.
-
-Once your system recognises your joystick or SpaceNavigator correctly, you
-can go into the Second Life Viewer's Preferences dialog, click the 'Input &
-Camera' tab, and click the 'Joystick Setup' button. From here you may enable
-and disable joystick support and change some configuration settings such as
-sensitivity. SpaceNavigator users are recommended to click the
-'SpaceNavigator Defaults' button.
-
-KNOWN PROBLEMS
--=-=-=-=-=-=-=
-
-* If your chosen version of Linux treats your joystick/SpaceNavigator as
-if it were a mouse when you plug it in (i.e. it is automatically used to control
-your desktop cursor), then the SL Viewer may detect this device *but* will be
-unable to use it properly.
-
-FURTHER PROBLEMS?
--=-=-=-=-=-=-=-=-
-
-Please report further issues to the public Second Life issue-tracker
-at <http://jira.secondlife.com/> (please note, however, that this is not
-a support forum).
diff --git a/indra/newview/linux_tools/client-readme-voice.txt b/indra/newview/linux_tools/client-readme-voice.txt
deleted file mode 100644
index bfefdf3471..0000000000
--- a/indra/newview/linux_tools/client-readme-voice.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-Second Life - Linux Voice Support README
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-WHAT IS IT?
--=-=-=-=-=-
-
-Linux Voice Support is a feature in testing which allows users of the Linux
-Second Life client to participate in voice-chat with other residents and
-groups inside Second Life, with an appropriate headset/microphone.
-
-REQUIREMENTS
--=-=-=-=-=-=
-
-* A headset/microphone supported by your chosen version of Linux
-* At this time, the PulseAudio audio system is recommended; this software
- is already part of most modern (2009+) Linux desktop systems. Alternatively,
- the ALSA audio system may be used on systems installed from around
- 2007 onwards (again this is likely already installed on your system).
-
-TESTING YOUR SETTINGS
--=-=-=-=-=-=-=-=-=-=-
-
-* The Second Life region 'Voice Echo Canyon' is a great place for testing
-your hardware settings and quality - it will 'echo' your voice back to you
-when you speak.
-
-KNOWN PROBLEMS
--=-=-=-=-=-=-=
-
-* Compatibility with old ALSA-based audio systems (such as Ubuntu Dapper
- from 2006) is poor.
-
-TROUBLESHOOTING
--=-=-=-=-=-=-=-
-
-PROBLEM 1: I don't see a white dot over the head of my avatar or other
- Voice-using avatars.
-SOLUTION:
-a. Ensure that 'Enable voice' is enabled in the 'Sound' section of the
- Preferences window, and that you are in a voice-enabled area.
-b. If the above does not help, exit Second Life and ensure that any
- remaining 'SLVoice' processes (as reported by 'ps', 'top' or similar)
- are killed before restarting.
-
-PROBLEM 2: I have a white dot over my head but I never see (or hear!) anyone
- except myself listed in the Active Speakers dialog when I'm sure that other
- residents nearby are active Voice users.
-SOLUTION: This is an incompatibility between the Voice support and your
- system's audio (ALSA) driver version/configuration.
-a. Back-up and remove your ~/.asoundrc file, re-test.
-b. Check for updates to your kernel, kernel modules and ALSA-related
- packages using your Linux distribution's package-manager - install these,
- reboot and re-test.
-c. Update to the latest version of ALSA manually. For a guide, see the
- 'Update to the Latest Version of ALSA' section of this page:
- <https://help.ubuntu.com/community/HdaIntelSoundHowto> or the official
- documentation on the ALSA site: <http://www.alsa-project.org/> - reboot
- and re-test.
-
-PROBLEM 3: I can hear other people, but they cannot hear me.
-SOLUTION:
-a. Ensure that you have the 'Speak' button (at the bottom of the Second Life
- window) activated while you are trying to speak.
-b. Ensure that your microphone jack is inserted into the correct socket of your
- sound card, where appropriate.
-c. Use your system mixer-setting program (such as the PulseAudio 'volume
- control' applet or the ALSA 'alsamixer' program) to ensure that microphone
- input is set as the active input source and is not muted.
-d. Verify that audio input works in other applications, i.e. Audacity
-
-PROBLEM 4: Other people just hear bursts of loud noise when I speak.
-SOLUTION:
-a. Use your system mixer-setting program or the 'alsamixer' program to ensure
- that microphone Gain/Boost is not set too high.
-
-FURTHER PROBLEMS?
--=-=-=-=-=-=-=-=-
-
-Please report further issues to the public Second Life issue-tracker
-at <http://jira.secondlife.com/> (please note, however, that this is not
-a support forum).
diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt
deleted file mode 100644
index cb8d1af535..0000000000
--- a/indra/newview/linux_tools/client-readme.txt
+++ /dev/null
@@ -1,244 +0,0 @@
-Second Life - Linux Beta README
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-This document contains information about the Second Life Linux
-client, and isn't meant to serve as an introduction to Second
-Life itself - please see <http://www.secondlife.com/whatis/>.
-
-1. Introduction
-2. System Requirements
-3. Installing & Running
-4. Known Issues
-5. Troubleshooting
- 5.1. 'Error creating window.'
- 5.2. System hangs
- 5.3. Blank window after minimizing it
- 5.4. Audio
- 5.5. 'Alt' key for camera controls doesn't work
- 5.6. In-world streaming movie, music and Flash playback
-6. Advanced Troubleshooting
- 6.1. Audio
- 6.2. OpenGL
-7. Obtaining and working with the client source code
-8. Getting more help, and reporting problems
-
-
-1. INTRODUCTION
--=-=-=-=-=-=-=-
-
-Hi! This is a BETA release of the Second Life client for Linux.
-The 'beta' status means that although we're still smoothing-out a few rough
-edges, this version of the client is functionally complete and should
-work quite well 'out of the box' for accessing Second Life.
-
-We encourage you to try it out and let us know of its compatibility
-with your system. Be aware that although this is a 'beta' client, it connects
-to the main Second Life world and changes you make there are permanent.
-
-You will have either obtained this client from secondlife.com (the official
-site) or from a third-party packager; if you encounter any problems then
-we recommend trying the latest official builds from secondlife.com which are
-updated often.
-
-Please enjoy!
-
-
-2. SYSTEM REQUIREMENTS
--=-=-=-=-=-=-=-=-=-=-=
-
-Minimum requirements:
- * Internet Connection: Cable or DSL
- * Computer Processor: 800MHz Pentium III or Athlon or better
- (recommended: 1.5GHz or more)
- * Computer Memory: 512MB (recommended: 768MB or more)
- * Linux Operating System: A reasonably modern 32-bit Linux environment
- is required. If you are running a 64-bit Linux distribution then
- you will need its 32-bit compatibility environment installed, but
- this configuration is not currently supported.
- * PulseAudio or ALSA Linux system sound software. A recent PulseAudio
- is the recommended configuration; see README-linux-voice.txt for more
- information.
- * Video/Graphics Card:
- o nVidia GeForce 2, GeForce 4mx, or better (recommend one of the
- following: 6700, 6800, 7600, 7800, 7900, 8400, 8500, 8600,
- 8800, Go 7400, Go 7600, Go 7800, Go 7900, +)
- o OR ATI Radeon 8500, 9250, or better
- (nVidia cards are recommended for the Linux client)
-
- **NOTE**: Second Life absolutely requires you to have recent, correctly-
- configured OpenGL 3D drivers for your hardware - the graphics drivers
- that came with your operating system may not be good enough! See the
- TROUBLESHOOTING section if you encounter problems starting Second Life.
-
-For a more comfortable experience, the RECOMMENDED hardware for the Second
-Life Linux client is very similar to that for Windows, as detailed at:
-<https://secondlife.com/corporate/sysreqs.php>
-
-
-3. INSTALLING & RUNNING
--=-=-=-=-=-=-=-=-=-=-=-
-
-The Second Life Linux client can entirely run from the directory you have
-unpacked it into - no installation step is required. If you wish to
-perform a separate installation step anyway, you may run './install.sh'
-
-Run ./secondlife from the installation directory to start Second Life.
-
-For in-world MOVIE and MUSIC PLAYBACK, you will need (32-bit) GStreamer 0.10
-installed on your system. This is optional - it is not required for general
-client functionality. If you have GStreamer 0.10 installed, the selection of
-in-world movies you can successfully play will depend on the GStreamer
-plugins you have; if you cannot play a certain in-world movie then you are
-probably missing the appropriate GStreamer plugin on your system - you may
-be able to install it (see TROUBLESHOOTING).
-
-User data is stored in the hidden directory ~/.secondlife by default; you may
-override this location with the SECONDLIFE_USER_DIR environment variable if
-you wish.
-
-
-4. KNOWN ISSUES
--=-=-=-=-=-=-=-
-
-* No significant known issues at this time.
-
-
-5. TROUBLESHOOTING
--=-=-=-=-=-=-=-=-=
-
-The client prints a lot of diagnostic information to the console it was
-run from. Most of this is also replicated in ~/.secondlife/logs/SecondLife.log
-- this is helpful to read when troubleshooting, especially 'WARNING' and
-'ERROR' lines.
-
-VOICE PROBLEMS? See the separate README-linux-voice.txt file for Voice
- troubleshooting information.
-
-SPACENAVIGATOR OR JOYSTICK PROBLEMS? See the separate
- README-linux-joystick.txt file for configuration information.
-
-PROBLEM 1:- Second Life fails to start up, with a warning on the console like:
- 'Error creating window.' or
- 'Unable to create window, be sure screen is set at 32-bit color' or
- 'SDL: Couldn't find matching GLX visual.'
-SOLUTION:- Usually this indicates that your graphics card does not meet
- the minimum requirements, or that your system's OpenGL 3D graphics driver is
- not updated and configured correctly. If you believe that your graphics
- card DOES meet the minimum requirements then you likely need to install the
- official so-called 'non-free' nVidia or ATI (fglrx) graphics drivers; we
- suggest one of the following options:
- * Consult your Linux distribution's documentation for installing these
- official drivers. For example, Ubuntu provides documentation here:
- <https://help.ubuntu.com/community/BinaryDriverHowto>
- * If your distribution does not make it easy, then you can download the
- required Linux drivers straight from your graphics card manufacturer:
- - nVidia cards: <http://www.nvidia.com/object/unix.html>
- - ATI cards: <http://ati.amd.com/support/driver.html>
-
-PROBLEM 2:- My whole system seems to hang when running Second Life.
-SOLUTION:- This is typically a hardware/driver issue. The first thing to
- do is to check that you have the most recent official drivers for your
- graphics card (see PROBLEM 1).
-SOLUTION:- Some residents with ATI cards have reported that running
- 'sudo aticonfig --locked-userpages=off' before running Second Life solves
- their stability issues.
-SOLUTION:- As a last resort, you can disable most of Second Life's advanced
- graphics features by editing the 'secondlife' script and removing the '#'
- from the line which reads '#export LL_GL_NOEXT=x'
-
-PROBLEM 3:- After I minimize the Second Life window, it's just blank when
- it comes back.
-SOLUTION:- Some Linux desktop 'Visual Effects' features are incompatible
- with Second Life. One reported solution is to use your desktop
- configuration program to disable such effects. For example, on Ubuntu 7.10,
- use the desktop toolbar menu to select System -> Preferences -> Appearance,
- then change 'Visual Effects' to 'None'.
-
-PROBLEM 4:- Music and sound effects are silent or very stuttery.
-SOLUTION:- The most common solution is to ensure that you have the 'esd'
- program (part of the 'esound' package) installed and running before you
- start Second Life. Users of Ubuntu (and some other) Linux systems can
- simply run the following to install and configure 'esound':
- sudo apt-get install esound
- For others, simply running 'esd&' from a command-line should get it running.
-
-PROBLEM 5:- Using the 'Alt' key to control the camera doesn't work or just
- moves the Second Life window.
-SOLUTION:- Some window managers eat the Alt key for their own purposes; you
- can configure your window manager to use a different key instead (for
- example, the 'Windows' key!) which will allow the Alt key to function
- properly with mouse actions in Second Life and other applications.
-
-PROBLEM 6:- In-world movie, music, or Flash playback doesn't work for me.
-SOLUTION:- You need to have a working installation of GStreamer 0.10; this
- is usually an optional package for most versions of Linux. If you have
- installed GStreamer 0.10 and you can play some music/movies but not others
- then you need to install a wider selection of GStreamer plugins, either
- from your vendor (i.e. the 'Ugly' plugins) or an appropriate third party.
- For Flash playback, you need to have Flash 10 installed for your normal
- web browser (for example, Firefox). PulseAudio is required for Flash
- volume control / muting to fully function inside Second Life.
-
-
-6. ADVANCED TROUBLESHOOTING
--=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-The 'secondlife' script which launches Second Life contains some
-configuration options for advanced troubleshooters.
-
-* AUDIO - Edit the 'secondlife' script and you will see these audio
- options: LL_BAD_OPENAL_DRIVER, LL_BAD_FMODSTUDIO_DRIVER.
- Second Life tries to use OpenAL, FMODSTUDIO (PULSEAUDIO, ALSA)
- audio drivers in this order; you may uncomment the corresponding LL_BAD_*
- option to skip an audio driver which you believe may be causing you trouble.
-
-* OPENGL - For advanced troubleshooters, the LL_GL_BLACKLIST option lets
- you disable specific GL extensions, each of which is represented by a
- letter ("a"-"o"). If you can narrow down a stability problem on your system
- to just one or two GL extensions then please post details of your hardware
- (and drivers) to the Linux Client Testers forum (see link below) along
- with the minimal LL_GL_BLACKLIST which solves your problems. This will help
- us to improve stability for your hardware while minimally impacting
- performance.
- LL_GL_BASICEXT and LL_GL_NOEXT should be commented-out for this to be useful.
-
-
-7. OBTAINING AND WORKING WITH THE CLIENT SOURCE CODE
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-We're pleased to have released the Second Life client's source code under
-an Open Source license compatible with the 'GPL'. To get involved with client
-development, please see:
-<http://wiki.secondlife.com/wiki/Open_Source_Portal>
-
-
-8. GETTING MORE HELP AND REPORTING PROBLEMS
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-For general help and support with Second Life:
-<http://secondlife.com/community/support.php>
-
-For problems and discussion concerning unofficial (not secondlife.com)
-releases, please contact your packager or the SLDev mailing list:
-<https://lists.secondlife.com/cgi-bin/mailman/listinfo/sldev>
-
-In-world help: Please use the 'Help' menu in the client for various
-non-Linux-specific Second Life help options.
-
-In-world discussion: There is a 'Linux Client Users' group
-inside Second Life which is free to join. You can find it by pressing
-the 'Search' button at the bottom of the window and then selecting the
-'Groups' tab and searching for 'Linux'. This group is useful for discussing
-Linux issues with fellow Linux client users who are online.
-
-The Second Life Issue Tracker:
-<http://jira.secondlife.com/>
-This is the right place for finding known issues and reporting new
-bugs in all Second Life releases if you find that the Troubleshooting
-section in this file hasn't helped (please note, however, that this is
-not a support forum).
-
-Linux Client Testers forum:
-<http://forums.secondlife.com/forumdisplay.php?forumid=263>
-This is a forum where Linux Client users can help each other out and
-discuss the latest updates.
diff --git a/indra/newview/linux_tools/launch_url.sh b/indra/newview/linux_tools/launch_url.sh
deleted file mode 100755
index 404ea36f26..0000000000
--- a/indra/newview/linux_tools/launch_url.sh
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/bin/bash
-
-# This script loads a web page in the 'default' graphical web browser.
-# It MUST return immediately (or soon), so the browser should be
-# launched in the background (thus no text-only browsers).
-# This script does not trust the URL to be well-escaped or shell-safe.
-#
-# On Unixoids we try, in order of decreasing priority:
-# - $BROWSER if set (preferred)
-# - Default GNOME browser
-# - Default KDE browser
-# - x-www-browser
-# - The first browser in $BROWSER_COMMANDS that is found.
-
-URL="$1"
-
-if [ -z "$URL" ]; then
- echo "Usage: $(basename "$0") URL"
- exit
-fi
-
-# restore LD_LIBRARY_PATH from SAVED_LD_LIBRARY_PATH if it exists
-if [ "${SAVED_LD_LIBRARY_PATH+isset}" = "isset" ]; then
- export LD_LIBRARY_PATH="${SAVED_LD_LIBRARY_PATH}"
- echo "$0: Restored library path to '${SAVED_LD_LIBRARY_PATH}'"
-fi
-
-# if $BROWSER is defined, use it.
-XBROWSER=`echo "$BROWSER" |cut -f1 -d:`
-if [ ! -z "$XBROWSER" ]; then
- XBROWSER_CMD=`echo "$XBROWSER" |cut -f1 -d' '`
- # look for $XBROWSER_CMD either literally or in PATH
- if [ -x "$XBROWSER_CMD" ] || which $XBROWSER_CMD >/dev/null; then
- # check for %s string, avoiding bash2-ism of [[ ]]
- if echo "$XBROWSER" | grep %s >/dev/null; then
- # $XBROWSER has %s which needs substituting
- echo "$URL" | xargs -r -i%s $XBROWSER &
- exit
- fi
- # $XBROWSER has no %s, tack URL on the end instead
- $XBROWSER "$URL" &
- exit
- fi
- echo "$0: Couldn't find the browser specified by \$BROWSER ($BROWSER)"
- echo "$0: Trying some others..."
-fi
-
-# Launcher the default GNOME browser.
-if [ ! -z "$GNOME_DESKTOP_SESSION_ID" ] && which gnome-open >/dev/null; then
- gnome-open "$URL" &
- exit
-fi
-
-# Launch the default KDE browser.
-if [ ! -z "$KDE_FULL_SESSION" ] && which kfmclient >/dev/null; then
- kfmclient openURL "$URL" &
- exit
-fi
-
-# List of browser commands that will be tried in the order listed. x-www-browser
-# will be tried first, which is a debian alternative.
-BROWSER_COMMANDS=" \
- x-www-browser \
- firefox \
- mozilla-firefox \
- iceweasel \
- iceape \
- opera \
- epiphany-browser \
- epiphany-gecko \
- epiphany-webkit \
- epiphany \
- mozilla \
- seamonkey \
- galeon \
- dillo \
- netscape"
-for browser_cmd in $BROWSER_COMMANDS; do
- if which $browser_cmd >/dev/null; then
- $browser_cmd "$URL" &
- exit
- fi
-done
-
-echo '$0: Failed to find a known browser. Please consider setting the $BROWSER environment variable.'
-exit 1
diff --git a/indra/newview/linux_tools/refresh_desktop_app_entry.sh b/indra/newview/linux_tools/refresh_desktop_app_entry.sh
index d2b2a732d5..84af7505ea 100755
--- a/indra/newview/linux_tools/refresh_desktop_app_entry.sh
+++ b/indra/newview/linux_tools/refresh_desktop_app_entry.sh
@@ -3,7 +3,7 @@
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
-install_prefix=${RUN_PATH}/..
+install_prefix="$(realpath -- "${RUN_PATH}/..")"
function install_desktop_entry()
{
@@ -13,18 +13,25 @@ function install_desktop_entry()
local desktop_entry="\
[Desktop Entry]\n\
Name=Second Life\n\
+GenericName=Second Life Viewer\n\
Comment=Client for the On-line Virtual World, Second Life\n\
+Path=${installation_prefix}\n\
Exec=${installation_prefix}/secondlife\n\
Icon=${installation_prefix}/secondlife_icon.png\n\
Terminal=false\n\
Type=Application\n\
-Categories=Application;Network;\n\
+Categories=Game;Simulation;\n\
StartupNotify=true\n\
+StartupWMClass="com.secondlife.indra.viewer"\n\
X-Desktop-File-Install-Version=3.0"
echo " - Installing menu entries in ${desktop_entries_dir}"
- mkdir -vp "${desktop_entries_dir}"
- echo -e $desktop_entry > "${desktop_entries_dir}/secondlife-viewer.desktop" || "Failed to install application menu!"
+ WORK_DIR=`mktemp -d`
+ echo -e $desktop_entry > "${WORK_DIR}/secondlife-viewer.desktop" || "Failed to install application menu!"
+ desktop-file-install --dir="${desktop_entries_dir}" ${WORK_DIR}/secondlife-viewer.desktop
+ rm -r $WORK_DIR
+
+ update-desktop-database "${desktop_entries_dir}"
}
if [ "$UID" == "0" ]; then
diff --git a/indra/newview/linux_tools/register_secondlifeprotocol.sh b/indra/newview/linux_tools/register_secondlifeprotocol.sh
index 33c34d7a76..d41e6dd6cb 100755
--- a/indra/newview/linux_tools/register_secondlifeprotocol.sh
+++ b/indra/newview/linux_tools/register_secondlifeprotocol.sh
@@ -6,43 +6,52 @@
HANDLER="$1"
-RUN_PATH=`dirname "$0" || echo .`
+SCRIPTSRC=`readlink -f "$0" || echo "$0"`
+RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
+
+install_prefix="$(realpath -- "${RUN_PATH}/..")"
+
cd "${RUN_PATH}/.."
if [ -z "$HANDLER" ]; then
- HANDLER=`pwd`/etc/handle_secondlifeprotocol.sh
+ HANDLER=$install_prefix/etc/handle_secondlifeprotocol.sh
fi
-# Register handler for GNOME-aware apps
-LLGCONFTOOL2=gconftool-2
-if which ${LLGCONFTOOL2} >/dev/null; then
- (${LLGCONFTOOL2} -s -t string /desktop/gnome/url-handlers/secondlife/command "${HANDLER} \"%s\"" && ${LLGCONFTOOL2} -s -t bool /desktop/gnome/url-handlers/secondlife/enabled true) || echo Warning: Did not register secondlife:// handler with GNOME: ${LLGCONFTOOL2} failed.
-else
- echo Warning: Did not register secondlife:// handler with GNOME: ${LLGCONFTOOL2} not found.
-fi
+function install_desktop_entry()
+{
+ local installation_prefix="$1"
+ local desktop_entries_dir="$2"
+
+ local desktop_entry="\
+[Desktop Entry]\n\
+Name=Second Life SLURL handler\n\
+Path=${installation_prefix}\n\
+Exec=${HANDLER} %u\n\
+Icon=${installation_prefix}/secondlife_icon.png\n\
+Terminal=false\n\
+Type=Application\n\
+StartupNotify=true\n\
+StartupWMClass="com.secondlife.indra.viewer"\n\
+NoDisplay=true\n\
+MimeType=x-scheme-handler/secondlife\n\
+X-Desktop-File-Install-Version=3.0"
-# Register handler for KDE-aware apps
-for LLKDECONFIG in kde-config kde4-config; do
- if [ `which $LLKDECONFIG` ]; then
- LLKDEPROTODIR=`$LLKDECONFIG --path services | cut -d ':' -f 1`
- if [ -d "$LLKDEPROTODIR" ]; then
- LLKDEPROTOFILE=${LLKDEPROTODIR}/secondlife.protocol
- cat > ${LLKDEPROTOFILE} <<EOF || echo Warning: Did not register secondlife:// handler with KDE: Could not write ${LLKDEPROTOFILE}
-[Protocol]
-exec=${HANDLER} '%u'
-protocol=secondlife
-input=none
-output=none
-helper=true
-listing=
-reading=false
-writing=false
-makedir=false
-deleting=false
-EOF
- else
- echo Warning: Did not register secondlife:// handler with KDE: Directory $LLKDEPROTODIR does not exist.
- fi
- fi
-done
+ echo " - Installing protocol entries in ${desktop_entries_dir}"
+ WORK_DIR=`mktemp -d`
+ PROTOCOL_HANDLER="secondlife-protocol.desktop"
+ echo -e $desktop_entry > "${WORK_DIR}/${PROTOCOL_HANDLER}" || "Failed to create desktop file!"
+ desktop-file-install --dir="${desktop_entries_dir}" "${WORK_DIR}/${PROTOCOL_HANDLER}" || "Failed to install desktop file!"
+ rm -r $WORK_DIR
+ xdg-mime default "${desktop_entries_dir}/${PROTOCOL_HANDLER}" x-scheme-handler/secondlife
+
+ update-desktop-database "${desktop_entries_dir}"
+}
+
+if [ "$UID" == "0" ]; then
+ # system-wide
+ install_desktop_entry "$install_prefix" /usr/local/share/applications
+else
+ # user-specific
+ install_desktop_entry "$install_prefix" "$HOME/.local/share/applications"
+fi
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index eb3ead433b..7e7a9a5e49 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -1,48 +1,12 @@
#!/bin/bash
-## Here are some configuration options for Linux Client Testers.
-## These options are for self-assisted troubleshooting during this beta
-## testing phase; you should not usually need to touch them.
+## Here are some configuration options for Linux Client Users.
-## - Avoids using any FMOD STUDIO audio driver.
-#export LL_BAD_FMODSTUDIO_DRIVER=x
## - Avoids using any OpenAL audio driver.
#export LL_BAD_OPENAL_DRIVER=x
-## - Avoids using the FMOD Studio or FMOD Ex PulseAudio audio driver.
-#export LL_BAD_FMOD_PULSEAUDIO=x
-## - Avoids using the FMOD Studio or FMOD Ex ALSA audio driver.
-#export LL_BAD_FMOD_ALSA=x
-
-## - Avoids the optional OpenGL extensions which have proven most problematic
-## on some hardware. Disabling this option may cause BETTER PERFORMANCE but
-## may also cause CRASHES and hangs on some unstable combinations of drivers
-## and hardware.
-## NOTE: This is now disabled by default.
-#export LL_GL_BASICEXT=x
-
-## - Avoids *all* optional OpenGL extensions. This is the safest and least-
-## exciting option. Enable this if you experience stability issues, and
-## report whether it helps in the Linux Client Testers forum.
-#export LL_GL_NOEXT=x
-
-## - For advanced troubleshooters, this lets you disable specific GL
-## extensions, each of which is represented by a letter a-o. If you can
-## narrow down a stability problem on your system to just one or two
-## extensions then please post details of your hardware (and drivers) to
-## the Linux Client Testers forum along with the minimal
-## LL_GL_BLACKLIST which solves your problems.
-#export LL_GL_BLACKLIST=abcdefghijklmno
-
-## - Some ATI/Radeon users report random X server crashes when the mouse
-## cursor changes shape. If you suspect that you are a victim of this
-## driver bug, try enabling this option and report whether it helps:
-#export LL_ATI_MOUSE_CURSOR_BUG=x
-
-if [ "`uname -m`" = "x86_64" ]; then
- echo '64-bit Linux detected.'
-fi
-
+## GL Driver Options
+export mesa_glthread=true
## Everything below this line is just for advanced troubleshooters.
##-------------------------------------------------------------------
@@ -54,32 +18,8 @@ fi
## an unstripped binary before you run.
#export LL_WRAPPER='gdb --args'
#export LL_WRAPPER='valgrind --smc-check=all --error-limit=no --log-file=secondlife.vg --leak-check=full --suppressions=/usr/lib/valgrind/glibc-2.5.supp --suppressions=secondlife-i686.supp'
-
-## - Avoids an often-buggy X feature that doesn't really benefit us anyway.
-export SDL_VIDEO_X11_DGAMOUSE=0
-
-## - Works around a problem with misconfigured 64-bit systems not finding GL
-I386_MULTIARCH="$(dpkg-architecture -ai386 -qDEB_HOST_MULTIARCH 2>/dev/null)"
-MULTIARCH_ERR=$?
-if [ $MULTIARCH_ERR -eq 0 ]; then
- echo 'Multi-arch support detected.'
- MULTIARCH_GL_DRIVERS="/usr/lib/${I386_MULTIARCH}/dri"
- export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:${MULTIARCH_GL_DRIVERS}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri"
-else
- export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri"
-fi
-
-## - The 'scim' GTK IM module widely crashes the viewer. Avoid it.
-if [ "$GTK_IM_MODULE" = "scim" ]; then
- export GTK_IM_MODULE=xim
-fi
-
-## - Automatically work around the ATI mouse cursor crash bug:
-## (this workaround is disabled as most fglrx users do not see the bug)
-#if lsmod | grep fglrx &>/dev/null ; then
-# export LL_ATI_MOUSE_CURSOR_BUG=x
-#fi
-
+#export ASAN_OPTIONS="halt_on_error=0 detect_leaks=1 symbolize=1"
+#export UBSAN_OPTIONS="print_stacktrace=1 print_summary=1 halt_on_error=0"
## Nothing worth editing below this line.
##-------------------------------------------------------------------
@@ -99,24 +39,7 @@ cd "${RUN_PATH}"
## subprocesses that care.
export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
-# if [ -n "$LL_TCMALLOC" ]; then
-# tcmalloc_libs='/usr/lib/libtcmalloc.so.0 /usr/lib/libstacktrace.so.0 /lib/libpthread.so.0'
-# all=1
-# for f in $tcmalloc_libs; do
-# if [ ! -f $f ]; then
-# all=0
-# fi
-# done
-# if [ $all != 1 ]; then
-# echo 'Cannot use tcmalloc libraries: components missing' 1>&2
-# else
-# export LD_PRELOAD=$(echo $tcmalloc_libs | tr ' ' :)
-# if [ -z "$HEAPCHECK" -a -z "$HEAPPROFILE" ]; then
-# export HEAPCHECK=${HEAPCHECK:-normal}
-# fi
-# fi
-#fi
-
+# Add our library directory
export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"
# Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch.
@@ -140,23 +63,4 @@ LL_RUN_ERR=$?
if [ $LL_RUN_ERR -ne 0 ]; then
# generic error running the binary
echo '*** Bad shutdown ($LL_RUN_ERR). ***'
- if [ "$(uname -m)" = "x86_64" ]; then
- echo
- cat << EOFMARKER
-You are running the Second Life Viewer on a x86_64 platform. The
-most common problems when launching the Viewer (particularly
-'bin/do-not-directly-run-secondlife-bin: not found' and 'error while
-loading shared libraries') may be solved by installing your Linux
-distribution's 32-bit compatibility packages.
-For example, on Ubuntu and other Debian-based Linuxes you might run:
-$ sudo apt-get install ia32-libs ia32-libs-gtk ia32-libs-kde ia32-libs-sdl
-EOFMARKER
- fi
fi
-
-echo
-echo '*******************************************************'
-echo 'This is a BETA release of the Second Life linux client.'
-echo 'Thank you for testing!'
-echo 'Please see README-linux.txt before reporting problems.'
-echo
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index af18dca185..6073b19aa8 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -37,6 +37,8 @@
#include "llappviewermacosx-for-objc.h"
#include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported)
+#include "llversioninfovars.h"
+
@implementation LLAppDelegate
@synthesize window;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index e1ed9f842d..ab15fe877e 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -132,15 +132,17 @@
#include "stringize.h"
#include "llcoros.h"
#include "llexception.h"
-#if !LL_LINUX
#include "cef/dullahan_version.h"
#include "vlc/libvlc_version.h"
-#endif // LL_LINUX
#if LL_DARWIN
#include "llwindowmacosx.h"
#endif
+#if LL_SDL_WINDOW
+#include "llwindowsdl.h"
+#endif
+
// Third party library includes
#include <boost/bind.hpp>
#include <boost/algorithm/string.hpp>
@@ -181,7 +183,6 @@
#include "lltracker.h"
#include "llviewerparcelmgr.h"
#include "llworldmapview.h"
-#include "llpostprocess.h"
#include "lldebugview.h"
#include "llconsole.h"
@@ -265,10 +266,6 @@ using namespace LL;
// define a self-registering event API object
#include "llappviewerlistener.h"
-#if LL_LINUX && LL_GTK
-#include "glib.h"
-#endif // (LL_LINUX) && LL_GTK
-
#ifdef LL_DISCORD
#define DISCORDPP_IMPLEMENTATION
#include <discordpp.h>
@@ -294,7 +291,7 @@ extern bool gRandomizeFramerate;
extern bool gPeriodicSlowFrame;
extern bool gDebugGL;
-#if LL_DARWIN
+#if LL_DARWIN || LL_SDL_WINDOW
extern bool gHiDPISupport;
#endif
@@ -551,7 +548,7 @@ static void settings_to_globals()
LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile");
#endif
LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport");
- LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
+ LLRender::sAnisotropicFilteringLevel = static_cast<F32>(gSavedSettings.getU32("RenderAnisotropicLevel"));
LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR);
LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
@@ -577,6 +574,9 @@ static void settings_to_globals()
#if LL_DARWIN
LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL");
+#endif
+
+#if LL_DARWIN || LL_SDL_WINDOW
gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
#endif
}
@@ -1114,7 +1114,7 @@ bool LLAppViewer::init()
gGLActive = false;
-#if LL_RELEASE_FOR_DOWNLOAD
+#if LL_RELEASE_FOR_DOWNLOAD && !LL_LINUX
// Skip updater if this is a non-interactive instance
if (!gSavedSettings.getBOOL("CmdLineSkipUpdater") && !gNonInteractive)
{
@@ -1172,10 +1172,11 @@ bool LLAppViewer::init()
}
}
else
+#endif //LL_RELEASE_FOR_DOWNLOAD
{
+ mUpdaterNotFound = true;
LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL;
}
-#endif //LL_RELEASE_FOR_DOWNLOAD
{
// Iterate over --leap command-line options. But this is a bit tricky: if
@@ -1348,6 +1349,8 @@ bool LLAppViewer::frame()
bool LLAppViewer::doFrame()
{
+ LL_RECORD_BLOCK_TIME(FTM_FRAME);
+ LL_PROFILE_GPU_ZONE("Frame");
#ifdef LL_DISCORD
{
LL_PROFILE_ZONE_NAMED("discord_callbacks");
@@ -1355,8 +1358,6 @@ bool LLAppViewer::doFrame()
}
#endif
- LL_RECORD_BLOCK_TIME(FTM_FRAME);
- LL_PROFILE_GPU_ZONE("Frame");
{
// and now adjust the visuals from previous frame.
if(LLPerfStats::tunables.userAutoTuneEnabled && LLPerfStats::tunables.tuningFlag != LLPerfStats::Tunables::Nothing)
@@ -1880,8 +1881,6 @@ bool LLAppViewer::cleanup()
SUBSYSTEM_CLEANUP(LLAvatarAppearance);
- SUBSYSTEM_CLEANUP(LLPostProcess);
-
LLTracker::cleanupInstance();
// *FIX: This is handled in LLAppViewerWin32::cleanup().
@@ -3388,7 +3387,7 @@ LLSD LLAppViewer::getViewerInfo() const
info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance");
info["TEXTURE_MEMORY"] = LLSD::Integer(gGLManager.mVRAM);
-#if LL_DARWIN
+#if LL_DARWIN || LL_SDL_WINDOW
info["HIDPI"] = gHiDPISupport;
#endif
@@ -3418,7 +3417,6 @@ LLSD LLAppViewer::getViewerInfo() const
info["VOICE_VERSION"] = LLTrans::getString("NotConnected");
}
-#if !LL_LINUX
std::ostringstream cef_ver_codec;
cef_ver_codec << "Dullahan: ";
cef_ver_codec << DULLAHAN_VERSION_MAJOR;
@@ -3444,11 +3442,7 @@ LLSD LLAppViewer::getViewerInfo() const
cef_ver_codec << CHROME_VERSION_PATCH;
info["LIBCEF_VERSION"] = cef_ver_codec.str();
-#else
- info["LIBCEF_VERSION"] = "Undefined";
-#endif
-#if !LL_LINUX
std::ostringstream vlc_ver_codec;
vlc_ver_codec << LIBVLC_VERSION_MAJOR;
vlc_ver_codec << ".";
@@ -3456,9 +3450,6 @@ LLSD LLAppViewer::getViewerInfo() const
vlc_ver_codec << ".";
vlc_ver_codec << LIBVLC_VERSION_REVISION;
info["LIBVLC_VERSION"] = vlc_ver_codec.str();
-#else
- info["LIBVLC_VERSION"] = "Undefined";
-#endif
S32 packets_in = (S32)LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN);
if (packets_in > 0)
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 89d19d180b..c924771816 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -34,30 +34,142 @@
#include "llurldispatcher.h" // SLURL from other app instance
#include "llviewernetwork.h"
#include "llviewercontrol.h"
-#include "llwindowsdl.h"
#include "llmd5.h"
#include "llfindlocale.h"
+#include "llversioninfo.h"
#include <exception>
-#if LL_DBUS_ENABLED
-# include "llappviewerlinux_api_dbus.h"
+#define SDL_MAIN_USE_CALLBACKS
+#include <SDL3/SDL_main.h>
+
+#include "SDL3/SDL.h"
-// regrettable hacks to give us better runtime compatibility with older systems inside llappviewerlinux_api.h:
-#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0)
-#undef g_return_if_fail
-#define g_return_if_fail(COND) llg_return_if_fail(COND)
-// The generated API
-# include "llappviewerlinux_api.h"
+#include "llsdl.h"
+#include "llwindowsdl.h"
+
+#ifdef LL_GLIB
+#include <gio/gio.h>
#endif
+#define VIEWERAPI_SERVICE "com.secondlife.ViewerAppAPIService"
+#define VIEWERAPI_PATH "/com/secondlife/ViewerAppAPI"
+#define VIEWERAPI_INTERFACE "com.secondlife.ViewerAppAPI"
+
+static const char * DBUS_SERVER = "<node name=\"/com/secondlife/ViewerAppAPI\">\n"
+ " <interface name=\"com.secondlife.ViewerAppAPI\">\n"
+ " <annotation name=\"org.freedesktop.DBus.GLib.CSymbol\" value=\"viewer_app_api\"/>\n"
+ " <method name=\"GoSLURL\">\n"
+ " <annotation name=\"org.freedesktop.DBus.GLib.CSymbol\" value=\"dispatchSLURL\"/>\n"
+ " <arg type=\"s\" name=\"slurl\" direction=\"in\" />\n"
+ " </method>\n"
+ " </interface>\n"
+ "</node>";
+
+typedef struct
+{
+ GObject parent;
+} ViewerAppAPI;
+
namespace
{
int gArgC = 0;
char **gArgV = NULL;
+ LLAppViewerLinux* gViewerAppPtr = NULL;
void (*gOldTerminateHandler)() = NULL;
}
+void check_vm_bloat()
+{
+#if LL_LINUX
+ // watch our own VM and RSS sizes, warn if we bloated rapidly
+ static const std::string STATS_FILE = "/proc/self/stat";
+ FILE *fp = fopen(STATS_FILE.c_str(), "r");
+ if (fp)
+ {
+ static long long last_vm_size = 0;
+ static long long last_rss_size = 0;
+ const long long significant_vm_difference = 250 * 1024*1024;
+ const long long significant_rss_difference = 50 * 1024*1024;
+ long long this_vm_size = 0;
+ long long this_rss_size = 0;
+
+ ssize_t res;
+ size_t dummy;
+ char *ptr = nullptr;
+ for (int i=0; i<22; ++i) // parse past the values we don't want
+ {
+ res = getdelim(&ptr, &dummy, ' ', fp);
+ if (-1 == res)
+ {
+ LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL;
+ goto finally;
+ }
+ free(ptr);
+ ptr = nullptr;
+ }
+ // 23rd space-delimited entry is vsize
+ res = getdelim(&ptr, &dummy, ' ', fp);
+ llassert(ptr);
+ if (-1 == res)
+ {
+ LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL;
+ goto finally;
+ }
+ this_vm_size = atoll(ptr);
+ free(ptr);
+ ptr = nullptr;
+ // 24th space-delimited entry is RSS
+ res = getdelim(&ptr, &dummy, ' ', fp);
+ llassert(ptr);
+ if (-1 == res)
+ {
+ LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL;
+ goto finally;
+ }
+ this_rss_size = getpagesize() * atoll(ptr);
+ free(ptr);
+ ptr = nullptr;
+
+ LL_INFOS() << "VM SIZE IS NOW " << (this_vm_size/(1024*1024)) << " MB, RSS SIZE IS NOW " << (this_rss_size/(1024*1024)) << " MB" << LL_ENDL;
+
+ if (llabs(last_vm_size - this_vm_size) > significant_vm_difference)
+ {
+ if (this_vm_size > last_vm_size)
+ {
+ LL_WARNS() << "VM size grew by " << (this_vm_size - last_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "VM size shrank by " << (last_vm_size - this_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL;
+ }
+ }
+
+ if (llabs(last_rss_size - this_rss_size) > significant_rss_difference)
+ {
+ if (this_rss_size > last_rss_size)
+ {
+ LL_WARNS() << "RSS size grew by " << (this_rss_size - last_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "RSS size shrank by " << (last_rss_size - this_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL;
+ }
+ }
+
+ last_rss_size = this_rss_size;
+ last_vm_size = this_vm_size;
+
+finally:
+ if (ptr)
+ {
+ free(ptr);
+ ptr = nullptr;
+ }
+ fclose(fp);
+ }
+#endif // LL_LINUX
+}
static void exceptionTerminateHandler()
{
@@ -71,32 +183,85 @@ static void exceptionTerminateHandler()
gOldTerminateHandler(); // call old terminate() handler
}
-int main( int argc, char **argv )
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv)
{
// Call Tracy first thing to have it allocate memory
// https://github.com/wolfpld/tracy/issues/196
LL_PROFILER_FRAME_END;
LL_PROFILER_SET_THREAD_NAME("App");
+ gSDLMainHandled = true;
+
gArgC = argc;
gArgV = argv;
- LLAppViewer* viewer_app_ptr = new LLAppViewerLinux();
+ gViewerAppPtr = new LLAppViewerLinux();
// install unexpected exception handler
gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
- bool ok = viewer_app_ptr->init();
+ unsetenv( "LD_PRELOAD" ); // <FS:ND/> Get rid of any preloading, we do not want this to happen during startup of plugins.
+
+ // This needs to be set as early as possible
+ SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_NAME_STRING, LLVersionInfo::getInstance()->getChannel().c_str());
+ SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_VERSION_STRING, LLVersionInfo::getInstance()->getVersion().c_str());
+ SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_IDENTIFIER_STRING, "com.secondlife.indra.viewer");
+ SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_CREATOR_STRING, "Linden Research Inc");
+ SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Copyright (c) Linden Research, Inc. 2025");
+ SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_URL_STRING, "https://www.secondlife.com");
+ SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_TYPE_STRING, "game");
+
+ bool ok = gViewerAppPtr->init();
if(!ok)
{
LL_WARNS() << "Application init failed." << LL_ENDL;
- return -1;
+ return SDL_APP_FAILURE;
}
- // Run the application main loop
- while (! viewer_app_ptr->frame())
- {}
+ return SDL_APP_CONTINUE;
+}
+SDL_AppResult SDL_AppIterate(void *appstate)
+{
+ // Run the application main loop
+ if (!gViewerAppPtr->frame())
+ {
+#if LL_GLIB
+ // Pump until we've nothing left to do or passed 1/15th of a
+ // second pumping for this frame.
+ static LLTimer pump_timer;
+ pump_timer.reset();
+ pump_timer.setTimerExpirySec(1.0f / 15.0f);
+ do
+ {
+ g_main_context_iteration(g_main_context_default(), false);
+ } while( g_main_context_pending(g_main_context_default()) && !pump_timer.hasExpired());
+#endif
+
+ // hack - doesn't belong here - but this is just for debugging
+ if (getenv("LL_DEBUG_BLOAT"))
+ {
+ check_vm_bloat();
+ }
+
+ return SDL_APP_CONTINUE;
+ }
+
+ if(LLApp::isError())
+ {
+ return SDL_APP_FAILURE;
+ }
+
+ return SDL_APP_SUCCESS;
+}
+
+SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
+{
+ return LLWindowSDL::handleEvents(*event);
+}
+
+void SDL_AppQuit(void *appstate, SDL_AppResult result)
+{
if (!LLApp::isError())
{
//
@@ -104,29 +269,15 @@ int main( int argc, char **argv )
// the assumption is that the error handler is responsible for doing
// app cleanup if there was a problem.
//
- viewer_app_ptr->cleanup();
+ gViewerAppPtr->cleanup();
}
- delete viewer_app_ptr;
- viewer_app_ptr = NULL;
- return 0;
-}
-LLAppViewerLinux::LLAppViewerLinux()
-{
-}
-
-LLAppViewerLinux::~LLAppViewerLinux()
-{
+ delete gViewerAppPtr;
+ gViewerAppPtr = nullptr;
}
bool LLAppViewerLinux::init()
{
- // g_thread_init() must be called before *any* use of glib, *and*
- // before any mutexes are held, *and* some of our third-party
- // libraries likes to use glib functions; in short, do this here
- // really early in app startup!
- if (!g_thread_supported ()) g_thread_init (NULL);
-
bool success = LLAppViewer::init();
#if LL_SEND_CRASH_REPORTS
@@ -148,7 +299,7 @@ bool LLAppViewerLinux::restoreErrorTrap()
}
/////////////////////////////////////////
-#if LL_DBUS_ENABLED
+#if LL_GLIB
typedef struct
{
@@ -158,101 +309,77 @@ typedef struct
static void viewerappapi_init(ViewerAppAPI *server);
static void viewerappapi_class_init(ViewerAppAPIClass *klass);
-///
-
-// regrettable hacks to give us better runtime compatibility with older systems in general
-static GType llg_type_register_static_simple_ONCE(GType parent_type,
- const gchar *type_name,
- guint class_size,
- GClassInitFunc class_init,
- guint instance_size,
- GInstanceInitFunc instance_init,
- GTypeFlags flags)
-{
- static GTypeInfo type_info;
- memset(&type_info, 0, sizeof(type_info));
-
- type_info.class_size = class_size;
- type_info.class_init = class_init;
- type_info.instance_size = instance_size;
- type_info.instance_init = instance_init;
-
- return g_type_register_static(parent_type, type_name, &type_info, flags);
-}
-#define llg_intern_static_string(S) (S)
-#define g_intern_static_string(S) llg_intern_static_string(S)
-#define g_type_register_static_simple(parent_type, type_name, class_size, class_init, instance_size, instance_init, flags) llg_type_register_static_simple_ONCE(parent_type, type_name, class_size, class_init, instance_size, instance_init, flags)
-
G_DEFINE_TYPE(ViewerAppAPI, viewerappapi, G_TYPE_OBJECT);
void viewerappapi_class_init(ViewerAppAPIClass *klass)
{
}
-static bool dbus_server_init = false;
-
-void viewerappapi_init(ViewerAppAPI *server)
+static void dispatchSLURL(gchar const *slurl)
{
- // Connect to the default DBUS, register our service/API.
-
- if (!dbus_server_init)
- {
- GError *error = NULL;
-
- server->connection = lldbus_g_bus_get(DBUS_BUS_SESSION, &error);
- if (server->connection)
- {
- lldbus_g_object_type_install_info(viewerappapi_get_type(), &dbus_glib_viewerapp_object_info);
+ LL_INFOS() << "Was asked to go to slurl: " << slurl << LL_ENDL;
- lldbus_g_connection_register_g_object(server->connection, VIEWERAPI_PATH, G_OBJECT(server));
+ std::string url = slurl;
+ LLMediaCtrl* web = NULL;
+ const bool trusted_browser = false;
+ LLURLDispatcher::dispatch(url, "", web, trusted_browser);
+}
- DBusGProxy *serverproxy = lldbus_g_proxy_new_for_name(server->connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+static void DoMethodeCall (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ LL_INFOS() << "DBUS message " << method_name << " from: " << sender << " interface: " << interface_name << LL_ENDL;
+ const gchar *slurl;
- guint request_name_ret_unused;
- // akin to org_freedesktop_DBus_request_name
- if (lldbus_g_proxy_call(serverproxy, "RequestName", &error, G_TYPE_STRING, VIEWERAPI_SERVICE, G_TYPE_UINT, 0, G_TYPE_INVALID, G_TYPE_UINT, &request_name_ret_unused, G_TYPE_INVALID))
- {
- // total success.
- dbus_server_init = true;
- }
- else
- {
- LL_WARNS() << "Unable to register service name: " << error->message << LL_ENDL;
- }
+ g_variant_get (parameters, "(&s)", &slurl);
+ dispatchSLURL(slurl);
+}
- g_object_unref(serverproxy);
- }
- else
+GDBusNodeInfo *gBusNodeInfo = nullptr;
+static const GDBusInterfaceVTable interface_vtable =
{
- g_warning("Unable to connect to dbus: %s", error->message);
- }
-
- if (error)
- g_error_free(error);
- }
+ DoMethodeCall
+ };
+static void busAcquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
+{
+ auto id = g_dbus_connection_register_object(connection,
+ VIEWERAPI_PATH,
+ gBusNodeInfo->interfaces[0],
+ &interface_vtable,
+ NULL, /* user_data */
+ NULL, /* user_data_free_func */
+ NULL); /* GError** */
+ g_assert (id > 0);
}
-gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error)
+static void nameAcquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
{
- bool success = false;
+}
- LL_INFOS() << "Was asked to go to slurl: " << slurl << LL_ENDL;
+static void nameLost(GDBusConnection *connection, const gchar *name, gpointer user_data)
+{
- std::string url = slurl;
- LLMediaCtrl* web = NULL;
- const bool trusted_browser = false;
- if (LLURLDispatcher::dispatch(url, "", web, trusted_browser))
- {
- // bring window to foreground, as it has just been "launched" from a URL
- // todo: hmm, how to get there from here?
- //xxx->mWindow->bringToFront();
- success = true;
- }
+}
+void viewerappapi_init(ViewerAppAPI *server)
+{
+ gBusNodeInfo = g_dbus_node_info_new_for_xml (DBUS_SERVER, NULL);
+ g_assert (gBusNodeInfo != NULL);
- *success_rtn = g_new (gboolean, 1);
- (*success_rtn)[0] = (gboolean)success;
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ VIEWERAPI_SERVICE,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ busAcquired,
+ nameAcquired,
+ nameLost,
+ NULL,
+ NULL);
- return TRUE; // the invokation succeeded, even if the actual dispatch didn't.
}
///
@@ -260,13 +387,6 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ
//virtual
bool LLAppViewerLinux::initSLURLHandler()
{
- if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME))
- {
- return false; // failed
- }
-
- g_type_init();
-
//ViewerAppAPI *api_server = (ViewerAppAPI*)
g_object_new(viewerappapi_get_type(), NULL);
@@ -276,49 +396,49 @@ bool LLAppViewerLinux::initSLURLHandler()
//virtual
bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url)
{
- if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME))
+ auto *pBus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, nullptr);
+
+ if( !pBus )
{
- return false; // failed
+ LL_WARNS() << "Getting dbus failed." << LL_ENDL;
+ return false;
}
- bool success = false;
- DBusGConnection *bus;
- GError *error = NULL;
+ auto pProxy = g_dbus_proxy_new_sync(pBus, G_DBUS_PROXY_FLAGS_NONE, nullptr,
+ VIEWERAPI_SERVICE, VIEWERAPI_PATH,
+ VIEWERAPI_INTERFACE, nullptr, nullptr);
- g_type_init();
-
- bus = lldbus_g_bus_get (DBUS_BUS_SESSION, &error);
- if (bus)
+ if( !pProxy )
{
- gboolean rtn = FALSE;
- DBusGProxy *remote_object =
- lldbus_g_proxy_new_for_name(bus, VIEWERAPI_SERVICE, VIEWERAPI_PATH, VIEWERAPI_INTERFACE);
-
- if (lldbus_g_proxy_call(remote_object, "GoSLURL", &error,
- G_TYPE_STRING, url.c_str(), G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &rtn, G_TYPE_INVALID))
- {
- success = rtn;
- }
- else
- {
- LL_INFOS() << "Call-out to other instance failed (perhaps not running): " << error->message << LL_ENDL;
- }
-
- g_object_unref(G_OBJECT(remote_object));
+ LL_WARNS() << "Cannot create new dbus proxy." << LL_ENDL;
+ g_object_unref( pBus );
+ return false;
}
- else
+
+ auto *pArgs = g_variant_new( "(s)", url.c_str() );
+ if( !pArgs )
{
- LL_WARNS() << "Couldn't connect to session bus: " << error->message << LL_ENDL;
+ LL_WARNS() << "Cannot create new variant." << LL_ENDL;
+ g_object_unref( pBus );
+ return false;
}
- if (error)
- g_error_free(error);
+ auto pRes = g_dbus_proxy_call_sync(pProxy,
+ "GoSLURL",
+ pArgs,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, nullptr, nullptr);
- return success;
+
+
+ if( pRes )
+ g_variant_unref( pRes );
+ g_object_unref( pProxy );
+ g_object_unref( pBus );
+ return true;
}
-#else // LL_DBUS_ENABLED
+#else // LL_GLIB
bool LLAppViewerLinux::initSLURLHandler()
{
return false; // not implemented without dbus
@@ -327,64 +447,10 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url)
{
return false; // not implemented without dbus
}
-#endif // LL_DBUS_ENABLED
+#endif // LL_GLIB
void LLAppViewerLinux::initCrashReporting(bool reportFreeze)
{
- std::string cmd =gDirUtilp->getExecutableDir();
- cmd += gDirUtilp->getDirDelimiter();
-#if LL_LINUX
- cmd += "linux-crash-logger.bin";
-#else
-# error Unknown platform
-#endif
-
- std::stringstream pid_str;
- pid_str << LLApp::getPid();
- std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
- std::string appname = gDirUtilp->getExecutableFilename();
- // launch the actual crash logger
- const char * cmdargv[] =
- {cmd.c_str(),
- "-user",
- (char*)LLGridManager::getInstance()->getGridId().c_str(),
- "-name",
- LLAppViewer::instance()->getSecondLifeTitle().c_str(),
- "-pid",
- pid_str.str().c_str(),
- "-dumpdir",
- logdir.c_str(),
- "-procname",
- appname.c_str(),
- NULL};
- fflush(NULL);
-
- pid_t pid = fork();
- if (pid == 0)
- { // child
- execv(cmd.c_str(), (char* const*) cmdargv); /* Flawfinder: ignore */
- LL_WARNS() << "execv failure when trying to start " << cmd << LL_ENDL;
- _exit(1); // avoid atexit()
- }
- else
- {
- if (pid > 0)
- {
- // DO NOT wait for child proc to die; we want
- // the logger to outlive us while we quit to
- // free up the screen/keyboard/etc.
- ////int childExitStatus;
- ////waitpid(pid, &childExitStatus, 0);
- }
- else
- {
- LL_WARNS() << "fork failure." << LL_ENDL;
- }
- }
- // Sometimes signals don't seem to quit the viewer. Also, we may
- // have been called explicitly instead of from a signal handler.
- // Make sure we exit so as to not totally confuse the user.
- //_exit(1); // avoid atexit(), else we may re-crash in dtors.
}
bool LLAppViewerLinux::beingDebugged()
@@ -415,7 +481,7 @@ bool LLAppViewerLinux::beingDebugged()
base += 1;
}
- if (strcmp(base, "gdb") == 0)
+ if (strcmp(base, "gdb") == 0 || strcmp(base, "lldb") == 0)
{
debugged = yes;
}
@@ -427,18 +493,6 @@ bool LLAppViewerLinux::beingDebugged()
return debugged == yes;
}
-void LLAppViewerLinux::initLoggingAndGetLastDuration()
-{
- // Remove the last stack trace, if any
- // This file is no longer created, since the move to Google Breakpad
- // The code is left here to clean out any old state in the log dir
- std::string old_stack_file =
- gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
- LLFile::remove(old_stack_file);
-
- LLAppViewer::initLoggingAndGetLastDuration();
-}
-
bool LLAppViewerLinux::initParseCommandLine(LLCommandLineParser& clp)
{
if (!clp.parseCommandLine(gArgC, gArgV))
diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h
index dde223878d..594bb64243 100644
--- a/indra/newview/llappviewerlinux.h
+++ b/indra/newview/llappviewerlinux.h
@@ -27,64 +27,35 @@
#ifndef LL_LLAPPVIEWERLINUX_H
#define LL_LLAPPVIEWERLINUX_H
-extern "C" {
-# include <glib.h>
-}
-
-#if LL_DBUS_ENABLED
-extern "C" {
-# include <glib-object.h>
-# include <dbus/dbus-glib.h>
-}
-#endif
-
#ifndef LL_LLAPPVIEWER_H
#include "llappviewer.h"
#endif
class LLCommandLineParser;
-class LLAppViewerLinux : public LLAppViewer
+class LLAppViewerLinux final : public LLAppViewer
{
public:
- LLAppViewerLinux();
- virtual ~LLAppViewerLinux();
+ LLAppViewerLinux() = default;
+ ~LLAppViewerLinux() override = default;
//
// Main application logic
//
- virtual bool init(); // Override to do application initialization
- std::string generateSerialNumber();
+ bool init() override; // Override to do application initialization
+ std::string generateSerialNumber() override;
bool setupSLURLHandler();
protected:
- virtual bool beingDebugged();
+ bool beingDebugged() override;
- virtual bool restoreErrorTrap();
- virtual void initCrashReporting(bool reportFreeze);
+ bool restoreErrorTrap() override;
+ void initCrashReporting(bool reportFreeze);
- virtual void initLoggingAndGetLastDuration();
- virtual bool initParseCommandLine(LLCommandLineParser& clp);
+ bool initParseCommandLine(LLCommandLineParser& clp) override;
- virtual bool initSLURLHandler();
- virtual bool sendURLToOtherInstance(const std::string& url);
+ bool initSLURLHandler() override;
+ bool sendURLToOtherInstance(const std::string& url) override;
};
-#if LL_DBUS_ENABLED
-typedef struct
-{
- GObject parent;
- DBusGConnection *connection;
-} ViewerAppAPI;
-
-extern "C" {
- gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error);
-}
-
-#define VIEWERAPI_SERVICE "com.secondlife.ViewerAppAPIService"
-#define VIEWERAPI_PATH "/com/secondlife/ViewerAppAPI"
-#define VIEWERAPI_INTERFACE "com.secondlife.ViewerAppAPI"
-
-#endif // LL_DBUS_ENABLED
-
#endif // LL_LLAPPVIEWERLINUX_H
diff --git a/indra/newview/llappviewerlinux_api.h b/indra/newview/llappviewerlinux_api.h
deleted file mode 100644
index 3d1324dd19..0000000000
--- a/indra/newview/llappviewerlinux_api.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/* Generated by dbus-binding-tool; do not edit! */
-/**
- * $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$
- */
-
-#ifndef __dbus_glib_marshal_viewerapp_MARSHAL_H__
-#define __dbus_glib_marshal_viewerapp_MARSHAL_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#ifdef G_ENABLE_DEBUG
-#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
-#define g_marshal_value_peek_char(v) g_value_get_char (v)
-#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
-#define g_marshal_value_peek_int(v) g_value_get_int (v)
-#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
-#define g_marshal_value_peek_long(v) g_value_get_long (v)
-#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
-#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
-#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
-#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
-#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
-#define g_marshal_value_peek_float(v) g_value_get_float (v)
-#define g_marshal_value_peek_double(v) g_value_get_double (v)
-#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
-#define g_marshal_value_peek_param(v) g_value_get_param (v)
-#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
-#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
-#define g_marshal_value_peek_object(v) g_value_get_object (v)
-#else /* !G_ENABLE_DEBUG */
-/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
- * Do not access GValues directly in your code. Instead, use the
- * g_value_get_*() functions
- */
-#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
-#define g_marshal_value_peek_char(v) (v)->data[0].v_int
-#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_int(v) (v)->data[0].v_int
-#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_long(v) (v)->data[0].v_long
-#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
-#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
-#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
-#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
-#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
-#define g_marshal_value_peek_float(v) (v)->data[0].v_float
-#define g_marshal_value_peek_double(v) (v)->data[0].v_double
-#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
-#endif /* !G_ENABLE_DEBUG */
-
-
-/* BOOLEAN:STRING,POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.5XXD8T:1) */
-extern void dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-void
-dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer arg_3,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 4);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_string (param_values + 1),
- g_marshal_value_peek_pointer (param_values + 2),
- g_marshal_value_peek_pointer (param_values + 3),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-G_END_DECLS
-
-#endif /* __dbus_glib_marshal_viewerapp_MARSHAL_H__ */
-
-#include <dbus/dbus-glib.h>
-static const DBusGMethodInfo dbus_glib_viewerapp_methods[] = {
- { (GCallback) viewer_app_api_GoSLURL, dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER, 0 },
-};
-
-const DBusGObjectInfo dbus_glib_viewerapp_object_info = {
- 0,
- dbus_glib_viewerapp_methods,
- 1,
-"com.secondlife.ViewerAppAPI\0GoSLURL\0S\0slurl\0I\0s\0success_ret\0O\0F\0N\0b\0\0\0",
-"\0",
-"\0"
-};
-
diff --git a/indra/newview/llappviewerlinux_api.xml b/indra/newview/llappviewerlinux_api.xml
deleted file mode 100644
index fac35b7adc..0000000000
--- a/indra/newview/llappviewerlinux_api.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<!-- dbus-binding-tool -mode=glib-server llappviewerlinux_api.xml -prefix=viewerapp -output=llappviewerlinux_api.h -->
-
-<node name="/com/secondlife/ViewerAppAPI">
- <interface name="com.secondlife.ViewerAppAPI">
- <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="viewer_app_api"/>
- <method name="GoSLURL">
- <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="viewer_app_api_GoSLURL"/>
- <arg type="s" name="slurl" direction="in" />
- <arg type="b" name="success_ret" direction="out" />
- </method>
- </interface>
-</node>
diff --git a/indra/newview/llappviewerlinux_api_dbus.cpp b/indra/newview/llappviewerlinux_api_dbus.cpp
deleted file mode 100644
index 9aed8a98d4..0000000000
--- a/indra/newview/llappviewerlinux_api_dbus.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * @file llappviewerlinux_api_dbus.cpp
- * @brief dynamic DBus symbol-grabbing code
- *
- * $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$
- */
-
-#if LL_DBUS_ENABLED
-
-#include "linden_common.h"
-
-extern "C" {
-#include <dbus/dbus-glib.h>
-
-#include "apr_pools.h"
-#include "apr_dso.h"
-}
-
-#define DEBUGMSG(...) do { LL_DEBUGS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0)
-#define INFOMSG(...) do { LL_INFOS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0)
-#define WARNMSG(...) do { LL_WARNS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0)
-
-#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) RTN (*ll##DBUSSYM)(__VA_ARGS__) = NULL
-#include "llappviewerlinux_api_dbus_syms_raw.inc"
-#undef LL_DBUS_SYM
-
-static bool sSymsGrabbed = false;
-static apr_pool_t *sSymDBUSDSOMemoryPool = NULL;
-static apr_dso_handle_t *sSymDBUSDSOHandleG = NULL;
-
-bool grab_dbus_syms(std::string dbus_dso_name)
-{
- if (sSymsGrabbed)
- {
- // already have grabbed good syms
- return true;
- }
-
- bool sym_error = false;
- bool rtn = false;
- apr_status_t rv;
- apr_dso_handle_t *sSymDBUSDSOHandle = NULL;
-
-#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##DBUSSYM, sSymDBUSDSOHandle, #DBUSSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #DBUSSYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #DBUSSYM, (void*)ll##DBUSSYM);}while(0)
-
- //attempt to load the shared library
- apr_pool_create(&sSymDBUSDSOMemoryPool, NULL);
-
- if ( APR_SUCCESS == (rv = apr_dso_load(&sSymDBUSDSOHandle,
- dbus_dso_name.c_str(),
- sSymDBUSDSOMemoryPool) ))
- {
- INFOMSG("Found DSO: %s", dbus_dso_name.c_str());
-
-#include "llappviewerlinux_api_dbus_syms_raw.inc"
-
- if ( sSymDBUSDSOHandle )
- {
- sSymDBUSDSOHandleG = sSymDBUSDSOHandle;
- sSymDBUSDSOHandle = NULL;
- }
-
- rtn = !sym_error;
- }
- else
- {
- INFOMSG("Couldn't load DSO: %s", dbus_dso_name.c_str());
- rtn = false; // failure
- }
-
- if (sym_error)
- {
- WARNMSG("Failed to find necessary symbols in DBUS-GLIB libraries.");
- }
-#undef LL_DBUS_SYM
-
- sSymsGrabbed = rtn;
- return rtn;
-}
-
-
-void ungrab_dbus_syms()
-{
- // should be safe to call regardless of whether we've
- // actually grabbed syms.
-
- if ( sSymDBUSDSOHandleG )
- {
- apr_dso_unload(sSymDBUSDSOHandleG);
- sSymDBUSDSOHandleG = NULL;
- }
-
- if ( sSymDBUSDSOMemoryPool )
- {
- apr_pool_destroy(sSymDBUSDSOMemoryPool);
- sSymDBUSDSOMemoryPool = NULL;
- }
-
- // NULL-out all of the symbols we'd grabbed
-#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{ll##DBUSSYM = NULL;}while(0)
-#include "llappviewerlinux_api_dbus_syms_raw.inc"
-#undef LL_DBUS_SYM
-
- sSymsGrabbed = false;
-}
-
-#endif // LL_DBUS_ENABLED
diff --git a/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc b/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc
deleted file mode 100644
index c0548e2fba..0000000000
--- a/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc
+++ /dev/null
@@ -1,9 +0,0 @@
-
-// required symbols to grab
-LL_DBUS_SYM(true, dbus_g_bus_get, DBusGConnection*, DBusBusType, GError**);
-LL_DBUS_SYM(true, dbus_g_proxy_new_for_name, DBusGProxy*, DBusGConnection*, const char *, const char*, const char*);
-LL_DBUS_SYM(true, dbus_g_proxy_call, gboolean, DBusGProxy*, const char*, GError**, GType, ...);
-LL_DBUS_SYM(true, dbus_g_object_type_install_info, void, GType, const DBusGObjectInfo*);
-LL_DBUS_SYM(true, dbus_g_connection_register_g_object, void, DBusGConnection*, const char*, GObject*);
-
-// optional symbols to grab
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 64b506a335..b8b151d627 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -72,6 +72,8 @@
#include <fstream>
#include <exception>
+#include "llversioninfovars.h"
+
// Bugsplat (http://bugsplat.com) crash reporting tool
#ifdef LL_BUGSPLAT
#include "BugSplat.h"
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index e967ff3df2..2dba778e24 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -37,6 +37,10 @@
#include "llviewercontrol.h"
#include "llwin32headers.h"
+#if LL_SDL_WINDOW
+#include "SDL3/SDL.h"
+#endif
+
#if LL_LINUX || LL_DARWIN
# include "llfilepicker.h"
#endif
@@ -65,7 +69,103 @@ bool LLDirPicker::check_local_file_access_enabled()
return true;
}
-#if LL_WINDOWS
+#if LL_SDL_WINDOW
+
+LLDirPicker::LLDirPicker() :
+ mFileName(NULL),
+ mLocked(false)
+{
+ reset();
+}
+
+LLDirPicker::~LLDirPicker()
+{
+}
+
+void LLDirPicker::reset()
+{
+}
+
+bool LLDirPicker::getDir(std::string* filename, bool blocking)
+{
+ return false;
+}
+
+std::string LLDirPicker::getDirName()
+{
+ return {};
+}
+
+bool LLDirPicker::getDirModeless(std::string* filename,
+ void (*callback)(bool, std::string&, void*),
+ void* userdata)
+{
+ if (mLocked)
+ {
+ return false;
+ }
+
+ // if local file browsing is turned off, return without opening dialog
+ if (!check_local_file_access_enabled())
+ {
+ return false;
+ }
+
+ {
+ struct LLSDLFileUserdata
+ {
+ LLSDLFileUserdata(void (*callback_func)(bool, std::string&, void*), void* callback_userdata)
+ : mCallback(callback_func), mUserdata(callback_userdata)
+ {
+ }
+ void (*mCallback)(bool, std::string&, void*);
+ void* mUserdata;
+ };
+
+ auto sdl_callback = [](void* userdata, const char* const* filelist, int filter)
+ {
+ LLSDLFileUserdata* callback_struct = (LLSDLFileUserdata*)userdata;
+
+ auto* callback_func = callback_struct->mCallback;
+ auto* callback_data = callback_struct->mUserdata;
+ delete callback_struct; // delete callback container
+
+ std::string rtn;
+ if (!filelist)
+ {
+ LL_WARNS() << "Error during SDL folder picking: " << SDL_GetError() << LL_ENDL;
+ callback_func(false, rtn, callback_data);
+ return;
+ }
+ else if (!*filelist)
+ {
+ LL_INFOS() << "User did not select any folders. Dialog likely cancelled." << LL_ENDL;
+ callback_func(false, rtn, callback_data);
+ return;
+ }
+
+ while (*filelist) {
+ rtn = std::string(*filelist);
+ break;
+ }
+ callback_func(true, rtn, callback_data);
+
+ };
+
+ LLSDLFileUserdata* llfilecallback = new LLSDLFileUserdata(callback, userdata);
+
+ SDL_PropertiesID props = SDL_CreateProperties();
+ SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_WINDOW_POINTER, SDL_GL_GetCurrentWindow());
+ SDL_ShowFileDialogWithProperties(SDL_FILEDIALOG_OPENFOLDER, sdl_callback, llfilecallback, props);
+
+ SDL_DestroyProperties(props);
+ }
+
+ return true;
+}
+
+
+#elif LL_WINDOWS
LLDirPicker::LLDirPicker() :
mFileName(NULL),
@@ -167,6 +267,13 @@ bool LLDirPicker::getDir(std::string* filename, bool blocking)
return success;
}
+bool LLDirPicker::getDirModeless(std::string* filename,
+ void (*callback)(bool, std::string&, void*),
+ void* userdata)
+{
+ return false;
+}
+
std::string LLDirPicker::getDirName()
{
return mDir;
@@ -195,7 +302,6 @@ void LLDirPicker::reset()
}
-//static
bool LLDirPicker::getDir(std::string* filename, bool blocking)
{
LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY;
@@ -203,6 +309,13 @@ bool LLDirPicker::getDir(std::string* filename, bool blocking)
return mFilePicker->getOpenFile(filter, true);
}
+bool LLDirPicker::getDirModeless(std::string* filename,
+ void (*callback)(bool, std::string&, void*),
+ void* userdata)
+{
+ return false;
+}
+
std::string LLDirPicker::getDirName()
{
return mFilePicker->getFirstFile();
@@ -240,23 +353,13 @@ bool LLDirPicker::getDir(std::string* filename, bool blocking)
return false;
}
-#if !LL_MESA_HEADLESS
-
- if (mFilePicker)
- {
- GtkWindow* picker = mFilePicker->buildFilePicker(false, true,
- "dirpicker");
-
- if (picker)
- {
- gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("choose_the_directory").c_str());
- gtk_widget_show_all(GTK_WIDGET(picker));
- gtk_main();
- return (!mFilePicker->getFirstFile().empty());
- }
- }
-#endif // !LL_MESA_HEADLESS
+ return false;
+}
+bool LLDirPicker::getDirModeless(std::string* filename,
+ void (*callback)(bool, std::string&, void*),
+ void* userdata)
+{
return false;
}
@@ -290,6 +393,13 @@ bool LLDirPicker::getDir(std::string* filename, bool blocking)
return false;
}
+bool LLDirPicker::getDirModeless(std::string* filename,
+ void (*callback)(bool, std::string&, void*),
+ void* userdata)
+{
+ return false;
+}
+
std::string LLDirPicker::getDirName()
{
return "";
@@ -303,7 +413,9 @@ std::queue<LLDirPickerThread*> LLDirPickerThread::sDeadQ;
void LLDirPickerThread::getFile()
{
-#if LL_WINDOWS
+#if LL_SDL_WINDOW
+ runModeless();
+#elif LL_WINDOWS
start();
#else
run();
@@ -333,6 +445,32 @@ void LLDirPickerThread::run()
}
+void LLDirPickerThread::runModeless()
+{
+ LLDirPicker picker;
+ bool result = picker.getDirModeless(&mProposedName, modelessStringCallback, this);
+ if (!result)
+ {
+ LLMutexLock lock(sMutex);
+ sDeadQ.push(this);
+ }
+}
+
+void LLDirPickerThread::modelessStringCallback(bool success,
+ std::string& response,
+ void* user_data)
+{
+ LLDirPickerThread* picker = (LLDirPickerThread*)user_data;
+ {
+ LLMutexLock lock(sMutex);
+ if (success)
+ {
+ picker->mResponses.push_back(response);
+ }
+ sDeadQ.push(picker);
+ }
+}
+
//static
void LLDirPickerThread::initClass()
{
diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h
index dc740caab2..c3619f91f5 100644
--- a/indra/newview/lldirpicker.h
+++ b/indra/newview/lldirpicker.h
@@ -58,6 +58,9 @@ class LLDirPicker
{
public:
bool getDir(std::string* filename, bool blocking = true);
+ bool getDirModeless(std::string* filename,
+ void (*callback)(bool, std::string&, void*),
+ void* userdata);
std::string getDirName();
// clear any lists of buffers or whatever, and make sure the dir
@@ -116,6 +119,11 @@ public:
virtual void run();
+ void runModeless();
+ static void modelessStringCallback(bool success,
+ std::string& response,
+ void* user_data);
+
virtual void notify(const std::vector<std::string>& filenames);
private:
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index a7ac9da618..d05cd0ee2b 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -59,8 +59,7 @@ class LLViewerTexture;
const U32 SILHOUETTE_HIGHLIGHT = 0;
// All data for new renderer goes into this class.
-LL_ALIGN_PREFIX(16)
-class LLDrawable
+class alignas(16) LLDrawable
: public LLViewerOctreeEntryData
{
LL_ALIGN_NEW;
@@ -313,7 +312,7 @@ private:
static U32 sNumZombieDrawables;
static std::vector<LLPointer<LLDrawable> > sDeadList;
-} LL_ALIGN_POSTFIX(16);
+};
inline LLFace* LLDrawable::getFace(const S32 i) const
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index e60b3eb5dc..3eca6059ed 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -369,7 +369,7 @@ void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color)
void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color)
{
- glColor4ubv(color.mV);
+ gGL.diffuseColor4ubv(color.mV);
}
void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a)
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 5e676bc5b3..d75b8d0ac6 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -636,379 +636,6 @@ void LLDrawPoolTerrain::hilightParcelOwners()
}
-void LLDrawPoolTerrain::renderFull4TU()
-{
- // Hack! Get the region that this draw pool is rendering from!
- LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
- LLVLComposition *compp = regionp->getComposition();
- LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
- LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
- LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
- LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
-
- LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
- F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
- F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
-
- LLVector4 tp0, tp1;
-
- tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
- tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
-
- gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA);
-
- //----------------------------------------------------------------------------
- // Pass 1/1
-
- //
- // Stage 0: detail texture 0
- //
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->bind(detail_texture0p);
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- //
- // Stage 1: Generate alpha ramp for detail0/detail1 transition
- //
-
- gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get());
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->activate();
-
- //
- // Stage 2: Interpolate detail1 with existing based on ramp
- //
- gGL.getTexUnit(2)->bind(detail_texture1p);
- gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->activate();
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- //
- // Stage 3: Modulate with primary (vertex) color for lighting
- //
- gGL.getTexUnit(3)->bind(detail_texture1p);
- gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(3)->activate();
-
- gGL.getTexUnit(0)->activate();
-
- // GL_BLEND disabled by default
- drawLoop();
-
- //----------------------------------------------------------------------------
- // Second pass
-
- // Stage 0: Write detail3 into base
- //
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->bind(detail_texture3p);
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- //
- // Stage 1: Generate alpha ramp for detail2/detail3 transition
- //
- gGL.getTexUnit(1)->bind(m2DAlphaRampImagep);
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->activate();
-
- // Set the texture matrix
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-2.f, 0.f, 0.f);
-
- //
- // Stage 2: Interpolate detail2 with existing based on ramp
- //
- gGL.getTexUnit(2)->bind(detail_texture2p);
- gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->activate();
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- //
- // Stage 3: Generate alpha ramp for detail1/detail2 transition
- //
- gGL.getTexUnit(3)->bind(m2DAlphaRampImagep);
- gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(3)->activate();
-
- // Set the texture matrix
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-1.f, 0.f, 0.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- gGL.getTexUnit(0)->activate();
- {
- LLGLEnable blend(GL_BLEND);
- drawLoop();
- }
-
- LLVertexBuffer::unbind();
- // Disable multitexture
- gGL.getTexUnit(3)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(3)->disable();
- gGL.getTexUnit(3)->activate();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->disable();
- gGL.getTexUnit(2)->activate();
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->activate();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- // Restore blend state
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- //----------------------------------------------------------------------------
- // Restore Texture Unit 0 defaults
-
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-}
-
-void LLDrawPoolTerrain::renderFull2TU()
-{
- // Hack! Get the region that this draw pool is rendering from!
- LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
- LLVLComposition *compp = regionp->getComposition();
- LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
- LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
- LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
- LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
-
- LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
- F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
- F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
-
- LLVector4 tp0, tp1;
-
- tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
- tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
-
- gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA);
-
- //----------------------------------------------------------------------------
- // Pass 1/4
-
- //
- // Stage 0: Render detail 0 into base
- //
- gGL.getTexUnit(0)->bind(detail_texture0p);
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- drawLoop();
-
- //----------------------------------------------------------------------------
- // Pass 2/4
-
- //
- // Stage 0: Generate alpha ramp for detail0/detail1 transition
- //
- gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
-
- //
- // Stage 1: Write detail1
- //
- gGL.getTexUnit(1)->bind(detail_texture1p);
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->activate();
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- gGL.getTexUnit(0)->activate();
- {
- LLGLEnable blend(GL_BLEND);
- drawLoop();
- }
- //----------------------------------------------------------------------------
- // Pass 3/4
-
- //
- // Stage 0: Generate alpha ramp for detail1/detail2 transition
- //
- gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
-
- // Set the texture matrix
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-1.f, 0.f, 0.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- //
- // Stage 1: Write detail2
- //
- gGL.getTexUnit(1)->bind(detail_texture2p);
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->activate();
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- {
- LLGLEnable blend(GL_BLEND);
- drawLoop();
- }
-
- //----------------------------------------------------------------------------
- // Pass 4/4
-
- //
- // Stage 0: Generate alpha ramp for detail2/detail3 transition
- //
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
- // Set the texture matrix
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-2.f, 0.f, 0.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- // Stage 1: Write detail3
- gGL.getTexUnit(1)->bind(detail_texture3p);
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->activate();
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- gGL.getTexUnit(0)->activate();
- {
- LLGLEnable blend(GL_BLEND);
- drawLoop();
- }
-
- // Restore blend state
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- // Disable multitexture
-
- gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->activate();
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- //----------------------------------------------------------------------------
- // Restore Texture Unit 0 defaults
-
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-}
-
-
-void LLDrawPoolTerrain::renderSimple()
-{
- LLVector4 tp0, tp1;
-
- //----------------------------------------------------------------------------
- // Pass 1/1
-
- // Stage 0: Base terrain texture pass
- mTexturep->addTextureStats(1024.f*1024.f);
-
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->bind(mTexturep);
-
- LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent();
- F32 tscale = 1.f/256.f;
- tp0.setVec(tscale, 0.f, 0.0f, -1.f*(origin_agent.mV[0]/256.f));
- tp1.setVec(0.f, tscale, 0.0f, -1.f*(origin_agent.mV[1]/256.f));
-
- sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
- sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
-
- drawLoop();
-
- //----------------------------------------------------------------------------
- // Restore Texture Unit 0 defaults
-
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-}
-
//============================================================================
void LLDrawPoolTerrain::renderOwnership()
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 23cf253b6a..49fccc168f 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -73,11 +73,8 @@ public:
protected:
void boostTerrainDetailTextures();
- void renderSimple();
void renderOwnership();
- void renderFull2TU();
- void renderFull4TU();
void renderFullShader();
void renderFullShaderTextures();
void renderFullShaderPBR(bool use_local_materials = false);
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index 375828fefa..cc5e39c5fb 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -33,7 +33,7 @@
#include "llviewertexture.h"
#include "llcamera.h"
-class LLViewerDynamicTexture : public LLViewerTexture
+class alignas(16) LLViewerDynamicTexture : public LLViewerTexture
{
LL_ALIGN_NEW
public:
@@ -90,7 +90,7 @@ protected:
protected:
bool mClamp;
LLCoordGL mOrigin;
- LL_ALIGN_16(LLCamera mCamera);
+ LLCamera mCamera;
LLRenderTarget* mBoundTarget;
diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp
index 25983f4add..66a922e288 100644
--- a/indra/newview/lleventnotifier.cpp
+++ b/indra/newview/lleventnotifier.cpp
@@ -166,6 +166,14 @@ bool LLEventNotifier::handleResponse(U32 eventId, const LLSD& notification, cons
return true;
}
+bool LLEventNotifier::add(LLEventInfo event)
+{
+ if (mEventInfoSignal(event))
+ return false;
+
+ return add(event.mID, event.mUnixTime, event.mTimeStr, event.mName);
+}
+
bool LLEventNotifier::add(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName)
{
LLEventNotification *new_enp = new LLEventNotification(eventId, eventEpoch, eventDateStr, eventName);
@@ -198,20 +206,9 @@ void LLEventNotifier::add(U32 eventId)
//static
void LLEventNotifier::processEventInfoReply(LLMessageSystem *msg, void **)
{
- // extract the agent id
- LLUUID agent_id;
- U32 event_id;
- std::string event_name;
- std::string eventd_date;
- U32 event_time_utc;
-
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
- msg->getU32("EventData", "EventID", event_id);
- msg->getString("EventData", "Name", event_name);
- msg->getString("EventData", "Date", eventd_date);
- msg->getU32("EventData", "DateUTC", event_time_utc);
-
- gEventNotifier.add(event_id, (F64)event_time_utc, eventd_date, event_name);
+ LLEventInfo info;
+ info.unpack(msg);
+ gEventNotifier.add(info);
}
@@ -296,6 +293,52 @@ void LLEventNotifier::serverPushRequest(U32 event_id, bool add)
gAgent.sendReliableMessage();
}
+void LLEventInfo::unpack(LLMessageSystem* msg)
+{
+ U32 event_id;
+ msg->getU32("EventData", "EventID", event_id);
+ mID = event_id;
+
+ msg->getString("EventData", "Name", mName);
+
+ msg->getString("EventData", "Category", mCategoryStr);
+
+ msg->getString("EventData", "Date", mTimeStr);
+
+ U32 duration;
+ msg->getU32("EventData", "Duration", duration);
+ mDuration = duration;
+
+ U32 date;
+ msg->getU32("EventData", "DateUTC", date);
+ mUnixTime = date;
+
+ msg->getString("EventData", "Desc", mDesc);
+
+ std::string buffer;
+ msg->getString("EventData", "Creator", buffer);
+ mRunByID = LLUUID(buffer);
+
+ U32 foo;
+ msg->getU32("EventData", "Cover", foo);
+
+ mHasCover = foo ? true : false;
+ if (mHasCover)
+ {
+ U32 cover;
+ msg->getU32("EventData", "Amount", cover);
+ mCover = cover;
+ }
+
+ msg->getString("EventData", "SimName", mSimName);
+
+ msg->getVector3d("EventData", "GlobalPos", mPosGlobal);
+
+ // Mature content
+ U32 event_flags;
+ msg->getU32("EventData", "EventFlags", event_flags);
+ mEventFlags = event_flags;
+}
LLEventNotification::LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName) :
mEventID(eventId),
diff --git a/indra/newview/lleventnotifier.h b/indra/newview/lleventnotifier.h
index 030c9abb87..2a9295129d 100644
--- a/indra/newview/lleventnotifier.h
+++ b/indra/newview/lleventnotifier.h
@@ -33,6 +33,24 @@
class LLEventNotification;
class LLMessageSystem;
+struct LLEventInfo
+{
+ void unpack(LLMessageSystem* msg);
+
+ std::string mName;
+ U32 mID;
+ std::string mDesc;
+ std::string mCategoryStr;
+ U32 mDuration;
+ std::string mTimeStr;
+ LLUUID mRunByID;
+ std::string mSimName;
+ LLVector3d mPosGlobal;
+ F64 mUnixTime; // seconds from 1970
+ BOOL mHasCover;
+ U32 mCover;
+ U32 mEventFlags;
+};
class LLEventNotifier
{
@@ -42,6 +60,7 @@ public:
void update(); // Notify the user of the event if it's coming up
bool add(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName);
+ bool add(LLEventInfo event);
void add(U32 eventId);
@@ -56,9 +75,13 @@ public:
static void processEventInfoReply(LLMessageSystem *msg, void **);
+ typedef boost::signals2::signal<bool(LLEventInfo event)> info_received_signal_t;
+ boost::signals2::connection setEventInfoCallback(const info_received_signal_t::slot_type& cb) { return mEventInfoSignal.connect(cb); };
+
protected:
en_map mEventNotifications;
- LLFrameTimer mNotificationTimer;
+ LLFrameTimer mNotificationTimer;
+ info_received_signal_t mEventInfoSignal;
};
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index f08ef8d24a..37802fa175 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -58,12 +58,6 @@
#include "llmeshrepository.h"
#include "llskinningutil.h"
-#if LL_LINUX
-// Work-around spurious used before init warning on Vector4a
-//
-#pragma GCC diagnostic ignored "-Wuninitialized"
-#endif
-
#define LL_MAX_INDICES_COUNT 1000000
static LLStaticHashedString sTextureIndexIn("texture_index_in");
@@ -646,7 +640,7 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram
LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
glPolygonOffset(3.f, 3.f);
- glLineWidth(5.f);
+ gGL.setLineWidth(5.f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
renderFace(mDrawablep, this);
}
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 8056983c7c..cce6eeb19d 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -1057,8 +1057,7 @@ void LLFastTimerView::drawLineGraph()
//fatten highlighted timer
if (mHoverID == idp)
{
- gGL.flush();
- glLineWidth(3);
+ gGL.setLineWidth(3);
}
llassert(idp->getIndex() < sTimerColors.size());
@@ -1118,8 +1117,7 @@ void LLFastTimerView::drawLineGraph()
if (mHoverID == idp)
{
- gGL.flush();
- glLineWidth(1);
+ gGL.setLineWidth(1.f);
}
if (idp->getTreeNode().mCollapsed)
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 9f3df54b05..c4d650e636 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -260,7 +260,6 @@ bool LLFeatureManager::loadFeatureTables()
// *TODO - if I or anyone else adds something else to the skipped list
// make this data driven. Put it in the feature table and parse it
// correctly
- mSkippedFeatures.insert("RenderAnisotropic");
mSkippedFeatures.insert("RenderGamma");
mSkippedFeatures.insert("RenderVBOEnable");
mSkippedFeatures.insert("RenderFogRatio");
@@ -509,17 +508,20 @@ bool LLFeatureManager::loadGPUClass()
mGPUClass = GPU_CLASS_5;
}
+ LLMemory::updateMemoryInfo();
#if LL_WINDOWS
const F32Gigabytes MIN_PHYSICAL_MEMORY(8);
-
- LLMemory::updateMemoryInfo();
+ #elif LL_LINUX
+ const F32Gigabytes MIN_PHYSICAL_MEMORY(2);
+ #endif
+ #if LL_WINDOWS || LL_LINUX
F32Gigabytes physical_mem = LLMemory::getMaxMemKB();
if (MIN_PHYSICAL_MEMORY > physical_mem && mGPUClass > GPU_CLASS_1)
{
// reduce quality on systems that don't have enough memory
mGPUClass = (EGPUClass)(mGPUClass - 1);
}
- #endif //LL_WINDOWS
+ #endif //LL_WINDOWS || LL_LINUX
} //end if benchmark
else
{
@@ -755,6 +757,10 @@ void LLFeatureManager::applyBaseMasks()
{
maskFeatures("VRAMLT2GB");
}
+ if (!gGLManager.mHasAnisotropic || 2.f > gGLManager.mMaxAnisotropy)
+ {
+ maskFeatures("AnisotropicMissing");
+ }
if (gGLManager.mGLVersion < 3.99f)
{
maskFeatures("GL3");
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 0e754c9561..2c5c6900d3 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -36,7 +36,7 @@
#include "llviewercontrol.h"
#include "llwindow.h" // beforeDialog()
-#if LL_SDL
+#if LL_SDL_WINDOW
#include "llwindowsdl.h" // for some X/GTK utils to help with filepickers
#endif // LL_SDL
@@ -50,7 +50,7 @@
LLFilePicker LLFilePicker::sInstance;
-#if LL_WINDOWS
+#if LL_WINDOWS && !LL_SDL_WINDOW
#define SOUND_FILTER L"Sounds (*.wav)\0*.wav\0"
#define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
#define ANIM_FILTER L"Animations (*.bvh; *.anim)\0*.bvh;*.anim\0"
@@ -82,7 +82,7 @@ LLFilePicker::LLFilePicker()
{
reset();
-#if LL_WINDOWS
+#if LL_WINDOWS && !LL_SDL_WINDOW
mOFN.lStructSize = sizeof(OPENFILENAMEW);
mOFN.hwndOwner = NULL; // Set later
mOFN.hInstance = NULL;
@@ -102,7 +102,7 @@ LLFilePicker::LLFilePicker()
mOFN.lpfnHook = NULL;
mOFN.lpTemplateName = NULL;
mFilesW[0] = '\0';
-#elif LL_DARWIN
+#elif LL_DARWIN && !LL_SDL_WINDOW
mPickOptions = 0;
#endif
@@ -167,7 +167,452 @@ void LLFilePicker::reset()
mCurrentFile = 0;
}
-#if LL_WINDOWS
+#if LL_SDL_WINDOW
+
+namespace
+{
+ std::vector<SDL_DialogFileFilter> setupLoadFilter(LLFilePicker::ELoadFilter filter)
+ {
+ std::vector<SDL_DialogFileFilter> filter_vec;
+
+ switch (filter)
+ {
+ case LLFilePicker::FFLOAD_ALL:
+ case LLFilePicker::FFLOAD_EXE:
+ filter_vec.push_back({ "All Files (*.*)", "*" });
+ filter_vec.push_back({ "Sounds (*.wav)", "wav" });
+ filter_vec.push_back({ "Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)", "tga;bmp;jpg;jpeg;png" });
+ filter_vec.push_back({ "Animations (*.bvh; *.anim)", "bvh;anim" });
+ filter_vec.push_back({ "GLTF Files (*.gltf; *.glb)", "gltf;glb" });
+ break;
+ case LLFilePicker::FFLOAD_WAV:
+ filter_vec.push_back({ "Sounds (*.wav)", "wav" });
+ break;
+ case LLFilePicker::FFLOAD_IMAGE:
+ filter_vec.push_back({ "Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)", "tga;bmp;jpg;jpeg;png" });
+ break;
+ case LLFilePicker::FFLOAD_ANIM:
+ filter_vec.push_back({ "Animations (*.bvh; *.anim)", "bvh;anim" });
+ break;
+ case LLFilePicker::FFLOAD_GLTF:
+ filter_vec.push_back({ "glTF (*.gltf; *.glb)", "gltf;glb" });
+ break;
+ case LLFilePicker::FFLOAD_COLLADA:
+ filter_vec.push_back({ "Scene (*.dae)", "dae" });
+ break;
+ case LLFilePicker::FFLOAD_XML:
+ filter_vec.push_back({ "XML files (*.xml)", "xml" });
+ break;
+ case LLFilePicker::FFLOAD_SLOBJECT:
+ filter_vec.push_back({ "Objects (*.slobject)", "slobject" });
+ break;
+ case LLFilePicker::FFLOAD_RAW:
+ filter_vec.push_back({ "RAW files (*.raw)", "raw" });
+ break;
+ case LLFilePicker::FFLOAD_MODEL:
+ filter_vec.push_back({ "Model files (*.dae)", "dae" });
+ filter_vec.push_back({ "GLTF Files (*.gltf; *.glb)", "gltf;glb" });
+ break;
+ case LLFilePicker::FFLOAD_MATERIAL:
+ filter_vec.push_back({ "GLTF Files (*.gltf; *.glb)", "gltf;glb" });
+ break;
+ case LLFilePicker::FFLOAD_MATERIAL_TEXTURE:
+ filter_vec.push_back({ "GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)", "gltf;glb;tga;bmp;jpg;jpeg;png" });
+ filter_vec.push_back({ "GLTF Files (*.gltf; *.glb)", "gltf;glb" });
+ filter_vec.push_back({ "Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)", "tga;bmp;jpg;jpeg;png" });
+ break;
+ case LLFilePicker::FFLOAD_HDRI:
+ filter_vec.push_back({ "HDRI Files (*.exr)", "exr" });
+ break;
+ case LLFilePicker::FFLOAD_SCRIPT:
+ filter_vec.push_back({ "Script files (*.lsl)", "lsl" });
+ break;
+ case LLFilePicker::FFLOAD_DICTIONARY:
+ filter_vec.push_back({ "Dictionary files (*.dic; *.xcu)", "dic;xcu" });
+ break;
+ default:
+ break;
+ }
+ return filter_vec;
+ }
+}
+
+bool LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
+{
+ LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL;
+ return false;
+}
+
+bool LLFilePicker::getOpenFileModeless(ELoadFilter filter,
+ void (*callback)(bool, std::vector<std::string>&, void*),
+ void* userdata)
+{
+ if (mLocked)
+ {
+ return false;
+ }
+
+ // if local file browsing is turned off, return without opening dialog
+ if (!check_local_file_access_enabled())
+ {
+ return false;
+ }
+
+ auto file_filters = setupLoadFilter(filter);
+
+ reset();
+
+ {
+ struct LLSDLFileUserdata
+ {
+ LLSDLFileUserdata(void (*callback_func)(bool, std::vector<std::string>&, void*), void* callback_userdata)
+ : mCallback(callback_func), mUserdata(callback_userdata)
+ {
+ }
+ void (*mCallback)(bool, std::vector<std::string>&, void*);
+ void* mUserdata;
+ };
+
+ auto sdl_callback = [](void* userdata, const char* const* filelist, int filter)
+ {
+ LLSDLFileUserdata* callback_struct = (LLSDLFileUserdata*)userdata;
+
+ auto* callback_func = callback_struct->mCallback;
+ auto* callback_data = callback_struct->mUserdata;
+ delete callback_struct; // delete callback container
+
+ std::vector<std::string> rtn;
+
+ if (!filelist)
+ {
+ LL_WARNS() << "Error during SDL file picking: " << SDL_GetError() << LL_ENDL;
+ callback_func(false, rtn, callback_data);
+ return;
+ }
+ else if (!*filelist)
+ {
+ LL_INFOS() << "User did not select any file. Dialog likely cancelled." << LL_ENDL;
+ callback_func(false, rtn, callback_data);
+ return;
+ }
+
+ while (*filelist)
+ {
+ rtn.push_back(std::string(*filelist));
+ filelist++;
+ }
+
+ callback_func(true, rtn, callback_data);
+
+ };
+
+ LLSDLFileUserdata* llfilecallback = new LLSDLFileUserdata(callback, userdata);
+
+ SDL_PropertiesID props = SDL_CreateProperties();
+ SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_FILTERS_POINTER, file_filters.data());
+ SDL_SetNumberProperty(props, SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER, file_filters.size());
+ SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_WINDOW_POINTER, SDL_GL_GetCurrentWindow());
+ SDL_SetBooleanProperty(props, SDL_PROP_FILE_DIALOG_MANY_BOOLEAN, false);
+
+ SDL_ShowFileDialogWithProperties(SDL_FILEDIALOG_OPENFILE, sdl_callback, llfilecallback, props);
+
+ SDL_DestroyProperties(props);
+ }
+ return true;
+}
+
+bool LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)
+{
+ LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL;
+ return false;
+}
+
+bool LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
+ void (*callback)(bool, std::vector<std::string>&, void*),
+ void* userdata)
+{
+ if (mLocked)
+ {
+ return false;
+ }
+
+ // if local file browsing is turned off, return without opening dialog
+ if (!check_local_file_access_enabled())
+ {
+ return false;
+ }
+
+ auto file_filters = setupLoadFilter(filter);
+
+ reset();
+
+ {
+ struct LLSDLFileUserdata
+ {
+ LLSDLFileUserdata(void (*callback_func)(bool, std::vector<std::string>&, void*), void* callback_userdata)
+ : mCallback(callback_func), mUserdata(callback_userdata)
+ {
+ }
+ void (*mCallback)(bool, std::vector<std::string>&, void*);
+ void* mUserdata;
+ };
+
+ auto sdl_callback = [](void* userdata, const char* const* filelist, int filter)
+ {
+ LLSDLFileUserdata* callback_struct = (LLSDLFileUserdata*)userdata;
+
+ auto* callback_func = callback_struct->mCallback;
+ auto* callback_data = callback_struct->mUserdata;
+ delete callback_struct; // delete callback container
+
+ std::vector<std::string> rtn;
+
+ if (!filelist)
+ {
+ LL_WARNS() << "Error during SDL file picking: " << SDL_GetError() << LL_ENDL;
+ callback_func(false, rtn, callback_data);
+ return;
+ }
+ else if (!*filelist)
+ {
+ LL_INFOS() << "User did not select any file. Dialog likely cancelled." << LL_ENDL;
+ callback_func(false, rtn, callback_data);
+ return;
+ }
+
+ while (*filelist)
+ {
+ rtn.push_back(std::string(*filelist));
+ filelist++;
+ }
+
+ callback_func(true, rtn, callback_data);
+
+ };
+
+ LLSDLFileUserdata* llfilecallback = new LLSDLFileUserdata(callback, userdata);
+
+ SDL_PropertiesID props = SDL_CreateProperties();
+ SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_FILTERS_POINTER, file_filters.data());
+ SDL_SetNumberProperty(props, SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER, file_filters.size());
+ SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_WINDOW_POINTER, SDL_GL_GetCurrentWindow());
+ SDL_SetBooleanProperty(props, SDL_PROP_FILE_DIALOG_MANY_BOOLEAN, true);
+
+ SDL_ShowFileDialogWithProperties(SDL_FILEDIALOG_OPENFILE, sdl_callback, llfilecallback, props);
+
+ SDL_DestroyProperties(props);
+ }
+
+ return true;
+}
+
+bool LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking)
+{
+ LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL;
+ return false;
+}
+
+bool LLFilePicker::getSaveFileModeless(ESaveFilter filter,
+ const std::string& filename,
+ void (*callback)(bool, std::string&, void*),
+ void* userdata)
+{
+ if (mLocked)
+ {
+ return false;
+ }
+
+ // if local file browsing is turned off, return without opening dialog
+ if (!check_local_file_access_enabled())
+ {
+ return false;
+ }
+
+ std::string default_filename;
+ if (!filename.empty())
+ {
+ default_filename = filename;
+ }
+
+ std::vector<SDL_DialogFileFilter> file_filters;
+
+ switch (filter)
+ {
+ case FFSAVE_ALL:
+ file_filters.push_back({ "All Files (*.*)", "*" });
+ file_filters.push_back({ "WAV Sounds (*.wav)", "wav" });
+ file_filters.push_back({ "Targa, Bitmap Images (*.tga; *.bmp)", "tga;bmp" });
+ break;
+ case FFSAVE_WAV:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.wav";
+ }
+ file_filters.push_back({ "WAV Sounds (*.wav)", "wav" });
+ break;
+ case FFSAVE_TGA:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.tga";
+ }
+ file_filters.push_back({ "Targa Images (*.tga)", "tga" });
+ break;
+ case FFSAVE_BMP:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.bmp";
+ }
+ file_filters.push_back({ "Bitmap Images (*.bmp)", "bmp" });
+ break;
+ case FFSAVE_PNG:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.png";
+ }
+ file_filters.push_back({ "PNG Images (*.png)", "png" });
+ break;
+ case FFSAVE_TGAPNG:
+ if (default_filename.empty())
+ {
+ //PNG by default
+ default_filename = "untitled.png";
+ }
+ file_filters.push_back({ "PNG Images (*.png)", "png" });
+ file_filters.push_back({ "Targa Images (*.tga)", "tga" });
+ break;
+
+ case FFSAVE_JPEG:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.jpeg";
+ }
+ file_filters.push_back({ "JPEG Images (*.jpg *.jpeg)", "jpg;jpeg" });
+ break;
+ case FFSAVE_AVI:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.avi";
+ }
+ file_filters.push_back({ "AVI Movie File (*.avi)", "avi" });
+ break;
+ case FFSAVE_ANIM:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.xaf";
+ }
+ file_filters.push_back({ "XAF Anim File (*.xaf)", "xaf" });
+ break;
+ case FFSAVE_GLTF:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.gltf";
+ }
+ file_filters.push_back({ "glTF Asset File (*.gltf)", "gltf" });
+ break;
+ case FFSAVE_XML:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.xml";
+ }
+ file_filters.push_back({ "XML File (*.xml)", "xml" });
+ break;
+ case FFSAVE_COLLADA:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.collada";
+ }
+ file_filters.push_back({ "COLLADA File (*.collada)", "collada" });
+ break;
+ case FFSAVE_RAW:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.raw";
+ }
+ file_filters.push_back({ "RAW files (*.raw)", "raw" });
+ break;
+ case FFSAVE_J2C:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.j2c";
+ }
+ file_filters.push_back({ "Compressed Images (*.j2c)", "j2c" });
+ break;
+ case FFSAVE_SCRIPT:
+ if (default_filename.empty())
+ {
+ default_filename = "untitled.lsl";
+ }
+ file_filters.push_back({ "LSL Files (*.lsl)", "lsl" });
+ break;
+ default:
+ return false;
+ }
+
+ reset();
+
+ {
+ struct LLSDLFileUserdata
+ {
+ LLSDLFileUserdata(void (*callback_func)(bool, std::string&, void*), void* callback_userdata)
+ : mCallback(callback_func), mUserdata(callback_userdata)
+ {
+ }
+ void (*mCallback)(bool, std::string&, void*);
+ void* mUserdata;
+ };
+
+ auto sdl_callback = [](void* userdata, const char* const* filelist, int filter)
+ {
+ LLSDLFileUserdata* callback_struct = (LLSDLFileUserdata*)userdata;
+
+ auto* callback_func = callback_struct->mCallback;
+ auto* callback_data = callback_struct->mUserdata;
+ delete callback_struct; // delete callback container
+
+ std::string rtn;
+ if (!filelist)
+ {
+ LL_WARNS() << "Error during SDL file picking: " << SDL_GetError() << LL_ENDL;
+ callback_func(false, rtn, callback_data);
+ return;
+ }
+ else if (!*filelist)
+ {
+ LL_INFOS() << "User did not select any file. Dialog likely cancelled." << LL_ENDL;
+ callback_func(false, rtn, callback_data);
+ return;
+ }
+
+ while (*filelist) {
+ rtn = std::string(*filelist);
+ break;
+ }
+ callback_func(true, rtn, callback_data);
+
+ };
+
+ LLSDLFileUserdata* llfilecallback = new LLSDLFileUserdata(callback, userdata);
+
+ SDL_PropertiesID props = SDL_CreateProperties();
+ SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_FILTERS_POINTER, file_filters.data());
+ SDL_SetNumberProperty(props, SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER, file_filters.size());
+ SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_WINDOW_POINTER, SDL_GL_GetCurrentWindow());
+
+ // Disabled default file name functionality currently due to inconsistency between various SDL3 backends
+ // if(!default_filename.empty())
+ // {
+ // SDL_SetStringProperty(props, SDL_PROP_FILE_DIALOG_LOCATION_STRING, default_filename.c_str());
+ // }
+ SDL_SetBooleanProperty(props, SDL_PROP_FILE_DIALOG_MANY_BOOLEAN, false);
+
+ SDL_ShowFileDialogWithProperties(SDL_FILEDIALOG_SAVEFILE, sdl_callback, llfilecallback, props);
+
+ SDL_DestroyProperties(props);
+ }
+
+ return true;
+}
+#elif LL_WINDOWS
bool LLFilePicker::setupFilter(ELoadFilter filter)
{
@@ -1107,488 +1552,6 @@ bool LLFilePicker::getSaveFileModeless(ESaveFilter filter,
#elif LL_LINUX
-# if LL_GTK
-
-// static
-void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data)
-{
- // We need to run g_filename_to_utf8 in the user's locale
- std::string saved_locale(setlocale(LC_ALL, NULL));
- setlocale(LC_ALL, "");
-
- LLFilePicker* picker = (LLFilePicker*) user_data;
- GError *error = NULL;
- gchar* filename_utf8 = g_filename_to_utf8((gchar*)data,
- -1, NULL, NULL, &error);
- if (error)
- {
- // *FIXME.
- // This condition should really be notified to the user, e.g.
- // through a message box. Just logging it is inappropriate.
-
- // g_filename_display_name is ideal, but >= glib 2.6, so:
- // a hand-rolled hacky makeASCII which disallows control chars
- std::string display_name;
- for (const gchar *str = (const gchar *)data; *str; str++)
- {
- display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?');
- }
- LL_WARNS() << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << LL_ENDL;
- }
-
- if (filename_utf8)
- {
- picker->mFiles.push_back(std::string(filename_utf8));
- LL_DEBUGS() << "ADDED FILE " << filename_utf8 << LL_ENDL;
- g_free(filename_utf8);
- }
-
- setlocale(LC_ALL, saved_locale.c_str());
-}
-
-// static
-void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer user_data)
-{
- LLFilePicker* picker = (LLFilePicker*)user_data;
-
- LL_DEBUGS() << "GTK DIALOG RESPONSE " << response << LL_ENDL;
-
- if (response == GTK_RESPONSE_ACCEPT)
- {
- GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget));
- g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data);
- g_slist_foreach(file_list, (GFunc)g_free, NULL);
- g_slist_free (file_list);
- }
-
- // let's save the extension of the last added file(considering current filter)
- GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget));
- if(gfilter)
- {
- std::string filter = gtk_file_filter_get_name(gfilter);
-
- if(filter == LLTrans::getString("png_image_files"))
- {
- picker->mCurrentExtension = ".png";
- }
- else if(filter == LLTrans::getString("targa_image_files"))
- {
- picker->mCurrentExtension = ".tga";
- }
- }
-
- // set the default path for this usage context.
- const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
- if (cur_folder != NULL)
- {
- picker->mContextToPathMap[picker->mCurContextName] = cur_folder;
- }
-
- gtk_widget_destroy(widget);
- gtk_main_quit();
-}
-
-
-GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context)
-{
-#ifndef LL_MESA_HEADLESS
- if (LLWindowSDL::ll_try_gtk_init())
- {
- GtkWidget *win = NULL;
- GtkFileChooserAction pickertype =
- is_save?
- (is_folder?
- GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER :
- GTK_FILE_CHOOSER_ACTION_SAVE) :
- (is_folder?
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER :
- GTK_FILE_CHOOSER_ACTION_OPEN);
-
- win = gtk_file_chooser_dialog_new(NULL, NULL,
- pickertype,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL,
- is_folder ?
- GTK_STOCK_APPLY :
- (is_save ?
- GTK_STOCK_SAVE :
- GTK_STOCK_OPEN),
- GTK_RESPONSE_ACCEPT,
- (gchar *)NULL);
- mCurContextName = context;
-
- // get the default path for this usage context if it's been
- // seen before.
- std::map<std::string,std::string>::iterator
- this_path = mContextToPathMap.find(context);
- if (this_path != mContextToPathMap.end())
- {
- gtk_file_chooser_set_current_folder
- (GTK_FILE_CHOOSER(win),
- this_path->second.c_str());
- }
-
-# if LL_X11
- // Make GTK tell the window manager to associate this
- // dialog with our non-GTK raw X11 window, which should try
- // to keep it on top etc.
- Window XWindowID = LLWindowSDL::get_SDL_XWindowID();
- if (None != XWindowID)
- {
- gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin
- GdkWindow *gdkwin = gdk_window_foreign_new(XWindowID);
- gdk_window_set_transient_for(GTK_WIDGET(win)->window,
- gdkwin);
- }
- else
- {
- LL_WARNS() << "Hmm, couldn't get xwid to use for transient." << LL_ENDL;
- }
-# endif //LL_X11
-
- g_signal_connect (GTK_FILE_CHOOSER(win),
- "response",
- G_CALLBACK(LLFilePicker::chooser_responder),
- this);
-
- gtk_window_set_modal(GTK_WINDOW(win), TRUE);
-
- /* GTK 2.6: if (is_folder)
- gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win),
- TRUE); */
-
- return GTK_WINDOW(win);
- }
- else
- {
- return NULL;
- }
-#else
- return NULL;
-#endif //LL_MESA_HEADLESS
-}
-
-static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter,
- GtkWindow *picker,
- std::string filtername)
-{
- gtk_file_filter_set_name(gfilter, filtername.c_str());
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
- gfilter);
- GtkFileFilter *allfilter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(allfilter, "*");
- gtk_file_filter_set_name(allfilter, LLTrans::getString("all_files").c_str());
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter);
- gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter);
-}
-
-static std::string add_simple_pattern_filter_to_gtkchooser(GtkWindow *picker,
- std::string pattern,
- std::string filtername)
-{
- GtkFileFilter *gfilter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(gfilter, pattern.c_str());
- add_common_filters_to_gtkchooser(gfilter, picker, filtername);
- return filtername;
-}
-
-static std::string add_simple_mime_filter_to_gtkchooser(GtkWindow *picker,
- std::string mime,
- std::string filtername)
-{
- GtkFileFilter *gfilter = gtk_file_filter_new();
- gtk_file_filter_add_mime_type(gfilter, mime.c_str());
- add_common_filters_to_gtkchooser(gfilter, picker, filtername);
- return filtername;
-}
-
-static std::string add_wav_filter_to_gtkchooser(GtkWindow *picker)
-{
- return add_simple_mime_filter_to_gtkchooser(picker, "audio/x-wav",
- LLTrans::getString("sound_files") + " (*.wav)");
-}
-
-static std::string add_anim_filter_to_gtkchooser(GtkWindow *picker)
-{
- GtkFileFilter *gfilter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(gfilter, "*.bvh");
- gtk_file_filter_add_pattern(gfilter, "*.anim");
- std::string filtername = LLTrans::getString("animation_files") + " (*.bvh; *.anim)";
- add_common_filters_to_gtkchooser(gfilter, picker, filtername);
- return filtername;
-}
-
-static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker)
-{
- return add_simple_pattern_filter_to_gtkchooser(picker, "*.xml",
- LLTrans::getString("xml_files") + " (*.xml)");
-}
-
-static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker)
-{
- return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae",
- LLTrans::getString("scene_files") + " (*.dae)");
-}
-
-static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker)
-{
- GtkFileFilter *gfilter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(gfilter, "*.tga");
- gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_JPEG.c_str());
- gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_PNG.c_str());
- gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_BMP.c_str());
- std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)";
- add_common_filters_to_gtkchooser(gfilter, picker, filtername);
- return filtername;
-}
-
-static std::string add_script_filter_to_gtkchooser(GtkWindow *picker)
-{
- return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN,
- LLTrans::getString("script_files") + " (*.lsl)");
-}
-
-static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker)
-{
- return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN,
- LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)");
-}
-
-static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker)
-{
- GtkFileFilter *gfilter_tga = gtk_file_filter_new();
- GtkFileFilter *gfilter_png = gtk_file_filter_new();
-
- gtk_file_filter_add_pattern(gfilter_tga, "*.tga");
- gtk_file_filter_add_mime_type(gfilter_png, "image/png");
- std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)";
- gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str());
- gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str());
-
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
- gfilter_png);
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
- gfilter_tga);
- return caption;
-}
-
-bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking )
-{
- bool rtn = false;
-
- // if local file browsing is turned off, return without opening dialog
- if (!check_local_file_access_enabled())
- {
- return false;
- }
-
- gViewerWindow->getWindow()->beforeDialog();
-
- reset();
-
- GtkWindow* picker = buildFilePicker(true, false, "savefile");
-
- if (picker)
- {
- std::string suggest_name = "untitled";
- std::string suggest_ext = "";
- std::string caption = LLTrans::getString("save_file_verb") + " ";
- switch (filter)
- {
- case FFSAVE_WAV:
- caption += add_wav_filter_to_gtkchooser(picker);
- suggest_ext = ".wav";
- break;
- case FFSAVE_TGA:
- caption += add_simple_pattern_filter_to_gtkchooser
- (picker, "*.tga", LLTrans::getString("targa_image_files") + " (*.tga)");
- suggest_ext = ".tga";
- break;
- case FFSAVE_BMP:
- caption += add_simple_mime_filter_to_gtkchooser
- (picker, HTTP_CONTENT_IMAGE_BMP, LLTrans::getString("bitmap_image_files") + " (*.bmp)");
- suggest_ext = ".bmp";
- break;
- case FFSAVE_PNG:
- caption += add_simple_mime_filter_to_gtkchooser
- (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)");
- suggest_ext = ".png";
- break;
- case FFSAVE_TGAPNG:
- caption += add_save_texture_filter_to_gtkchooser(picker);
- suggest_ext = ".png";
- break;
- case FFSAVE_AVI:
- caption += add_simple_mime_filter_to_gtkchooser
- (picker, "video/x-msvideo",
- LLTrans::getString("avi_movie_file") + " (*.avi)");
- suggest_ext = ".avi";
- break;
- case FFSAVE_ANIM:
- caption += add_simple_pattern_filter_to_gtkchooser
- (picker, "*.xaf", LLTrans::getString("xaf_animation_file") + " (*.xaf)");
- suggest_ext = ".xaf";
- break;
- case FFSAVE_XML:
- caption += add_simple_pattern_filter_to_gtkchooser
- (picker, "*.xml", LLTrans::getString("xml_file") + " (*.xml)");
- suggest_ext = ".xml";
- break;
- case FFSAVE_RAW:
- caption += add_simple_pattern_filter_to_gtkchooser
- (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)");
- suggest_ext = ".raw";
- break;
- case FFSAVE_J2C:
- // *TODO: Should this be 'image/j2c' ?
- caption += add_simple_mime_filter_to_gtkchooser
- (picker, "images/jp2",
- LLTrans::getString("compressed_image_files") + " (*.j2c)");
- suggest_ext = ".j2c";
- break;
- case FFSAVE_SCRIPT:
- caption += add_script_filter_to_gtkchooser(picker);
- suggest_ext = ".lsl";
- break;
- default:;
- break;
- }
-
- gtk_window_set_title(GTK_WINDOW(picker), caption.c_str());
-
- if (filename.empty())
- {
- suggest_name += suggest_ext;
-
- gtk_file_chooser_set_current_name
- (GTK_FILE_CHOOSER(picker),
- suggest_name.c_str());
- }
- else
- {
- gtk_file_chooser_set_current_name
- (GTK_FILE_CHOOSER(picker), filename.c_str());
- }
-
- gtk_widget_show_all(GTK_WIDGET(picker));
-
- gtk_main();
-
- rtn = (getFileCount() == 1);
-
- if(rtn && filter == FFSAVE_TGAPNG)
- {
- std::string selected_file = mFiles.back();
- mFiles.pop_back();
- mFiles.push_back(selected_file + mCurrentExtension);
- }
- }
-
- gViewerWindow->getWindow()->afterDialog();
-
- return rtn;
-}
-
-bool LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
-{
- bool rtn = false;
-
- // if local file browsing is turned off, return without opening dialog
- if (!check_local_file_access_enabled())
- {
- return false;
- }
-
- gViewerWindow->getWindow()->beforeDialog();
-
- reset();
-
- GtkWindow* picker = buildFilePicker(false, false, "openfile");
-
- if (picker)
- {
- std::string caption = LLTrans::getString("load_file_verb") + " ";
- std::string filtername = "";
- switch (filter)
- {
- case FFLOAD_WAV:
- filtername = add_wav_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_ANIM:
- filtername = add_anim_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_XML:
- filtername = add_xml_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_GLTF:
- filtername = dead_code_should_blow_up_here(picker);
- break;
- case FFLOAD_COLLADA:
- filtername = add_collada_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_IMAGE:
- filtername = add_imageload_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_SCRIPT:
- filtername = add_script_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_DICTIONARY:
- filtername = add_dictionary_filter_to_gtkchooser(picker);
- break;
- default:;
- break;
- }
-
- caption += filtername;
-
- gtk_window_set_title(GTK_WINDOW(picker), caption.c_str());
-
- gtk_widget_show_all(GTK_WIDGET(picker));
- gtk_main();
-
- rtn = (getFileCount() == 1);
- }
-
- gViewerWindow->getWindow()->afterDialog();
-
- return rtn;
-}
-
-bool LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
-{
- bool rtn = false;
-
- // if local file browsing is turned off, return without opening dialog
- if (!check_local_file_access_enabled())
- {
- return false;
- }
-
- gViewerWindow->getWindow()->beforeDialog();
-
- reset();
-
- GtkWindow* picker = buildFilePicker(false, false, "openfile");
-
- if (picker)
- {
- gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker),
- TRUE);
-
- gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("load_files").c_str());
-
- gtk_widget_show_all(GTK_WIDGET(picker));
- gtk_main();
- rtn = !mFiles.empty();
- }
-
- gViewerWindow->getWindow()->afterDialog();
-
- return rtn;
-}
-
-# else // LL_GTK
-
// Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with
// static results, when we don't have a real filepicker.
@@ -1676,8 +1639,6 @@ bool LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
return false;
}
-#endif // LL_GTK
-
#else // not implemented
bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 75ff14f4cf..5a4da61cca 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -35,6 +35,8 @@
#include "stdtypes.h"
+#include <vector>
+
#if LL_DARWIN
#include <Carbon/Carbon.h>
@@ -43,7 +45,6 @@
#undef check
#undef require
-#include <vector>
#include "llstring.h"
#endif
@@ -54,19 +55,8 @@
#include <commdlg.h>
#endif
-extern "C" {
-// mostly for Linux, possible on others
-#if LL_GTK
-# include "gtk/gtk.h"
-#endif // LL_GTK
-}
-
class LLFilePicker
{
-#ifdef LL_GTK
- friend class LLDirPicker;
- friend void chooser_responder(GtkWidget *, gint, gpointer);
-#endif // LL_GTK
public:
// calling this before main() is undefined
static LLFilePicker& instance( void ) { return sInstance; }
@@ -161,14 +151,14 @@ private:
// is enabled and if not, tidy up and indicate we're not allowed to do this.
bool check_local_file_access_enabled();
-#if LL_WINDOWS
+#if LL_WINDOWS && !LL_SDL_WINDOW
OPENFILENAMEW mOFN; // for open and save dialogs
WCHAR mFilesW[FILENAME_BUFFER_SIZE];
bool setupFilter(ELoadFilter filter);
#endif
-#if LL_DARWIN
+#if LL_DARWIN && !LL_SDL_WINDOW
S32 mPickOptions;
std::vector<std::string> mFileVector;
@@ -184,28 +174,12 @@ private:
void *userdata);
#endif
-#if LL_GTK
- static void add_to_selectedfiles(gpointer data, gpointer user_data);
- static void chooser_responder(GtkWidget *widget, gint response, gpointer user_data);
- // we remember the last path that was accessed for a particular usage
- std::map <std::string, std::string> mContextToPathMap;
- std::string mCurContextName;
- // we also remember the extension of the last added file.
- std::string mCurrentExtension;
-#endif
-
std::vector<std::string> mFiles;
S32 mCurrentFile;
bool mLocked;
static LLFilePicker sInstance;
-protected:
-#if LL_GTK
- GtkWindow* buildFilePicker(bool is_save, bool is_folder,
- std::string context = "generic");
-#endif
-
public:
// don't call these directly please.
LLFilePicker();
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 7d098b2676..8897ad55e0 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -151,7 +151,6 @@ void LLVolumeImplFlexible::remapSections(LLFlexibleObjectSection *source, S32 so
{
S32 num_output_sections = 1<<dest_sections;
LLVector3 scale = mVO->mDrawable->getScale();
- F32 source_section_length = scale.mV[VZ] / (F32)(1<<source_sections);
F32 section_length = scale.mV[VZ] / (F32)num_output_sections;
if (source_sections == -1)
{
@@ -183,6 +182,7 @@ void LLVolumeImplFlexible::remapSections(LLFlexibleObjectSection *source, S32 so
// Iterate from right to left since it may be an in-place computation
S32 step_shift = dest_sections-source_sections;
S32 num_steps = 1<<step_shift;
+ F32 source_section_length = scale.mV[VZ] / (F32)(1<<source_sections);
for (S32 section=num_output_sections-num_steps; section>=0; section -= num_steps)
{
LLFlexibleObjectSection *last_source_section = &source[section>>step_shift];
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 08a54b7369..fd9bbf00ae 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -34,6 +34,7 @@
#include "llfloaterreg.h"
#include "llimview.h" // for gIMMgr
#include "lltooldraganddrop.h" // for LLToolDragAndDrop
+#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerregion.h" // getCapability()
#include "llworld.h"
@@ -405,15 +406,50 @@ bool LLFloaterAvatarPicker::visibleItemsSelected() const
}
/*static*/
-void LLFloaterAvatarPicker::findCoro(std::string url, LLUUID queryID, std::string name)
+void LLFloaterAvatarPicker::findByIdCoro(std::string url, LLUUID query_id, LLUUID agent_id, std::string floater_key)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("findByIdCoro", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
+ httpOpts->setTimeout(AVATAR_PICKER_SEARCH_TIMEOUT);
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts);
+
+ LL_DEBUGS("Agent") << result << LL_ENDL;
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status || (status == LLCore::HttpStatus(HTTP_BAD_REQUEST)))
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ }
+ else
+ {
+ result["failure_reason"] = status.toString();
+ }
+
+ LLFloaterAvatarPicker* floater =
+ LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", floater_key);
+ if (floater)
+ {
+ floater->processResponse(query_id, result);
+ }
+}
+
+/*static*/
+void LLFloaterAvatarPicker::findByNameCoro(std::string url, LLUUID queryID, std::string name)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("findByNameCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ LL_INFOS("HttpCoroutineAdapter", "genericPostCoro", "Agent") << "Generic POST for " << url << LL_ENDL;
httpOpts->setTimeout(AVATAR_PICKER_SEARCH_TIMEOUT);
@@ -447,6 +483,7 @@ void LLFloaterAvatarPicker::find()
std::string text = getChild<LLUICtrl>("Edit")->getValue().asString();
+ LLUUID agent_id;
size_t separator_index = text.find_first_of(" ._");
if (separator_index != text.npos)
{
@@ -458,51 +495,92 @@ void LLFloaterAvatarPicker::find()
text = first;
}
}
+ else if (!text.empty())
+ {
+ agent_id.set(text);
+ }
mQueryID.generate();
+ mNumResultsReturned = 0;
- std::string url;
- url.reserve(128); // avoid a memory allocation or two
+ getChild<LLScrollListCtrl>("SearchResults")->deleteAllItems();
+ getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("searching"));
+ getChildView("ok_btn")->setEnabled(false);
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
+ if (agent_id.notNull())
{
- url = region->getCapability("AvatarPickerSearch");
- // Prefer use of capabilities to search on both SLID and display name
- if (!url.empty())
+ // Search by uuid
+ // While cache could have been nicer, it neither has a failure callback, nor
+ // can cleanup in case of an invalid uuid. So we go directly to the capability.
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
{
- // capability urls don't end in '/', but we need one to parse
- // query parameters correctly
- if (url.size() > 0 && url[url.size()-1] != '/')
+ std::string url;
+ url.reserve(128);
+ url = region->getCapability("GetDisplayNames");
+ if (!url.empty())
{
- url += "/";
- }
- url += "?page_size=100&names=";
- std::replace(text.begin(), text.end(), '.', ' ');
- url += LLURI::escape(text);
- LL_INFOS() << "avatar picker " << url << LL_ENDL;
+ // capability urls don't end in '/', but we need one to parse
+ // query parameters correctly
+ if (url[url.size() - 1] != '/')
+ {
+ url += "/";
+ }
+ url += "?ids=";
+ url += agent_id.asString();
+ LL_DEBUGS("Agent") << "avatar picker " << url << LL_ENDL;
- LLCoros::instance().launch("LLFloaterAvatarPicker::findCoro",
- boost::bind(&LLFloaterAvatarPicker::findCoro, url, mQueryID, getKey().asString()));
+ LLCoros::instance().launch("LLFloaterAvatarPicker::findCoro",
+ boost::bind(&LLFloaterAvatarPicker::findByIdCoro, url, mQueryID, agent_id, getKey().asString()));
+ }
+ else
+ {
+ LLSD content;
+ content["failure_reason"] = LLTrans::getString("ServerUnavailable");
+ processResponse(mQueryID, content);
+ }
}
- else
+ }
+ else
+ {
+ std::string url;
+ url.reserve(128); // avoid a memory allocation or two
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
{
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("AvatarPickerRequest");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->addUUID("QueryID", mQueryID); // not used right now
- msg->nextBlock("Data");
- msg->addString("Name", text);
- gAgent.sendReliableMessage();
+ url = region->getCapability("AvatarPickerSearch");
+ // Prefer use of capabilities to search on both SLID and display name
+ if (!url.empty())
+ {
+ // capability urls don't end in '/', but we need one to parse
+ // query parameters correctly
+ if (url.size() > 0 && url[url.size() - 1] != '/')
+ {
+ url += "/";
+ }
+ url += "?page_size=100&names=";
+ std::replace(text.begin(), text.end(), '.', ' ');
+ url += LLURI::escape(text);
+ LL_DEBUGS("Agent") << "avatar picker " << url << LL_ENDL;
+
+ LLCoros::instance().launch("LLFloaterAvatarPicker::findCoro",
+ boost::bind(&LLFloaterAvatarPicker::findByNameCoro, url, mQueryID, getKey().asString()));
+ }
+ else
+ {
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("AvatarPickerRequest");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->addUUID("QueryID", mQueryID); // not used right now
+ msg->nextBlock("Data");
+ msg->addString("Name", text);
+ gAgent.sendReliableMessage();
+ }
}
}
- getChild<LLScrollListCtrl>("SearchResults")->deleteAllItems();
- getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("searching"));
-
- getChildView("ok_btn")->setEnabled(false);
- mNumResultsReturned = 0;
}
void LLFloaterAvatarPicker::setAllowMultiple(bool allow_multiple)
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index 330f1a1226..817427aae6 100644
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -86,7 +86,8 @@ private:
void populateFriend();
bool visibleItemsSelected() const; // Returns true if any items in the current tab are selected.
- static void findCoro(std::string url, LLUUID mQueryID, std::string mName);
+ static void findByIdCoro(std::string url, LLUUID query_id, LLUUID agent_id, std::string floater_key);
+ static void findByNameCoro(std::string url, LLUUID mQueryID, std::string mName);
void find();
void setAllowMultiple(bool allow_multiple);
LLScrollListCtrl* getActiveList();
diff --git a/indra/newview/llfloaterdirectory.cpp b/indra/newview/llfloaterdirectory.cpp
new file mode 100644
index 0000000000..e062ca7ac6
--- /dev/null
+++ b/indra/newview/llfloaterdirectory.cpp
@@ -0,0 +1,100 @@
+/**
+ * @file llfloaterdirectory.cpp
+ * @brief The legacy "Search" floater
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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 "llfloaterdirectory.h"
+
+#include "llpaneldirevents.h"
+#include "llpaneleventinfo.h"
+#include "llpaneldirland.h"
+#include "llpaneldirpeople.h"
+#include "llpaneldirgroups.h"
+#include "llpaneldirplaces.h"
+#include "llpaneldirclassified.h"
+#include "llpaneldirweb.h"
+#include "llscrollbar.h"
+#include "llviewercontrol.h"
+#include "llpanelavatar.h"
+#include "llpanelclassified.h"
+#include "llpanelgroup.h"
+#include "llpanelplaces.h"
+#include "llpanelprofile.h"
+
+LLFloaterDirectory::LLFloaterDirectory(const std::string& name)
+: LLFloater(name),
+ mPanelAvatarp(nullptr),
+ mPanelGroupp(nullptr),
+ mPanelPlacep(nullptr),
+ mPanelClassifiedp(nullptr),
+ mPanelEventp(nullptr)
+{
+}
+
+LLFloaterDirectory::~LLFloaterDirectory()
+{
+}
+
+bool LLFloaterDirectory::postBuild()
+{
+ const std::vector<std::string> panel_names = {
+ "panel_dir_classified",
+ "panel_dir_events",
+ "panel_dir_places",
+ "panel_dir_land",
+ "panel_dir_people",
+ "panel_dir_groups" };
+
+ for (const std::string& panel_name : panel_names)
+ {
+ if (LLPanelDirBrowser* panel_tab = findChild<LLPanelDirBrowser>(panel_name))
+ {
+ panel_tab->setFloaterDirectory(this);
+ }
+ }
+ findChild<LLPanelDirWeb>("panel_dir_web")->setFloaterDirectory(this);
+
+ mPanelAvatarp = findChild<LLPanelProfileSecondLife>("panel_profile_secondlife");
+ mPanelAvatarp->setAllowEdit(false);
+ mPanelGroupp = findChild<LLPanelGroup>("panel_group_info_sidetray");
+ mPanelGroupp->hideBackBtn();
+ mPanelPlacep = findChild<LLPanelPlaces>("panel_places");
+ mPanelPlacep->hideBackBtn();
+ mPanelClassifiedp = findChild<LLPanelClassifiedInfo>("panel_classified_info");
+ mPanelClassifiedp->setBackgroundVisible(false);
+ mPanelEventp = findChild<LLPanelEventInfo>("panel_event_info");
+
+ return true;
+}
+
+void LLFloaterDirectory::hideAllDetailPanels()
+{
+ if (mPanelAvatarp) mPanelAvatarp->setVisible(false);
+ if (mPanelGroupp) mPanelGroupp->setVisible(false);
+ if (mPanelPlacep) mPanelPlacep->setVisible(false);
+ if (mPanelClassifiedp) mPanelClassifiedp->setVisible(false);
+ if (mPanelEventp) mPanelEventp->setVisible(false);
+}
diff --git a/indra/newview/llfloaterdirectory.h b/indra/newview/llfloaterdirectory.h
new file mode 100644
index 0000000000..de788443be
--- /dev/null
+++ b/indra/newview/llfloaterdirectory.h
@@ -0,0 +1,81 @@
+/**
+ * @file llfloaterdirectory.h
+ * @brief The legacy "Search" floater
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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_LLFLOATERDIRECTORY_H
+#define LL_LLFLOATERDIRECTORY_H
+
+#include "llfloater.h"
+#include "lltabcontainer.h"
+
+#include "llpaneldirevents.h"
+#include "llpaneldirland.h"
+#include "llpaneldirpeople.h"
+#include "llpaneldirgroups.h"
+#include "llpaneldirplaces.h"
+#include "llpaneldirclassified.h"
+
+class LLDirectoryCore;
+class LLPanelDirBrowser;
+
+class LLPanelDirAdvanced;
+class LLPanelDirClassified;
+class LLPanelDirEvents;
+class LLPanelDirGroups;
+class LLPanelDirLand;
+class LLPanelDirPeople;
+class LLPanelDirPlaces;
+
+class LLPanelProfileSecondLife;
+class LLPanelEventInfo;
+class LLPanelGroup;
+class LLPanelPlaces;
+class LLPanelClassifiedInfo;
+
+// Floater to find people, places, things
+class LLFloaterDirectory : public LLFloater
+{
+public:
+ LLFloaterDirectory(const std::string& name);
+ /*virtual*/ ~LLFloaterDirectory();
+
+ void hideAllDetailPanels();
+
+ bool postBuild() override;
+
+public:
+ LLPanelProfileSecondLife* mPanelAvatarp;
+ LLPanelEventInfo* mPanelEventp;
+ LLPanelGroup* mPanelGroupp;
+ LLPanelPlaces* mPanelPlacep;
+ LLPanelClassifiedInfo* mPanelClassifiedp;
+
+private:
+ static LLFloaterDirectory *sInstance;
+};
+
+//extern BOOL gDisplayEventHack;
+
+#endif // LL_LLDIRECTORYFLOATER_H
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 936096d8fe..21ae98d380 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -320,15 +320,29 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur
if (gesture)
{
+ element["columns"][0]["column"] = "active";
+ element["columns"][0]["type"] = "icon";
if (gesture->mPlaying)
{
font_style = "BOLD";
+ element["columns"][0]["value"] = "Activate_Checkmark";
}
+
+ // Only add "playing" if we've got the name, less confusing. JC
item_name = gesture->mName;
- element["columns"][0]["column"] = "trigger";
- element["columns"][0]["value"] = gesture->mTrigger;
- element["columns"][0]["font"]["name"] = "SANSSERIF";
- element["columns"][0]["font"]["style"] = font_style;
+ if (item && gesture->mPlaying)
+ {
+ item_name += " " + getString("playing");
+ }
+ element["columns"][1]["column"] = "name";
+ element["columns"][1]["value"] = item_name;
+ element["columns"][1]["font"]["name"] = "SANSSERIF";
+ element["columns"][1]["font"]["style"] = font_style;
+
+ element["columns"][2]["column"] = "trigger";
+ element["columns"][2]["value"] = gesture->mTrigger;
+ element["columns"][2]["font"]["name"] = "SANSSERIF";
+ element["columns"][2]["font"]["style"] = font_style;
std::string key_string;
std::string buffer;
@@ -345,45 +359,38 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur
gesture->mKey);
}
- element["columns"][1]["column"] = "shortcut";
- element["columns"][1]["value"] = buffer;
- element["columns"][1]["font"]["name"] = "SANSSERIF";
- element["columns"][1]["font"]["style"] = font_style;
-
// hidden column for sorting
- element["columns"][2]["column"] = "key";
- element["columns"][2]["value"] = key_string;
- element["columns"][2]["font"]["name"] = "SANSSERIF";
- element["columns"][2]["font"]["style"] = font_style;
-
- // Only add "playing" if we've got the name, less confusing. JC
- if (item && gesture->mPlaying)
- {
- item_name += " " + getString("playing");
- }
- element["columns"][3]["column"] = "name";
- element["columns"][3]["value"] = item_name;
+ element["columns"][3]["column"] = "key";
+ element["columns"][3]["value"] = key_string;
element["columns"][3]["font"]["name"] = "SANSSERIF";
element["columns"][3]["font"]["style"] = font_style;
+
+ element["columns"][4]["column"] = "shortcut";
+ element["columns"][4]["value"] = buffer;
+ element["columns"][4]["font"]["name"] = "SANSSERIF";
+ element["columns"][4]["font"]["style"] = font_style;
}
else
{
- element["columns"][0]["column"] = "trigger";
+ element["columns"][0]["column"] = "active";
+ element["columns"][0]["type"] = "icon";
element["columns"][0]["value"] = "";
- element["columns"][0]["font"]["name"] = "SANSSERIF";
- element["columns"][0]["font"]["style"] = font_style;
- element["columns"][1]["column"] = "shortcut";
- element["columns"][1]["value"] = "---";
+ element["columns"][1]["column"] = "name";
+ element["columns"][1]["value"] = item_name;
element["columns"][1]["font"]["name"] = "SANSSERIF";
element["columns"][1]["font"]["style"] = font_style;
- element["columns"][2]["column"] = "key";
- element["columns"][2]["value"] = "~~~";
+ element["columns"][2]["column"] = "trigger";
+ element["columns"][2]["value"] = "";
element["columns"][2]["font"]["name"] = "SANSSERIF";
element["columns"][2]["font"]["style"] = font_style;
- element["columns"][3]["column"] = "name";
- element["columns"][3]["value"] = item_name;
+ element["columns"][3]["column"] = "key";
+ element["columns"][3]["value"] = "~~~";
element["columns"][3]["font"]["name"] = "SANSSERIF";
element["columns"][3]["font"]["style"] = font_style;
+ element["columns"][4]["column"] = "shortcut";
+ element["columns"][4]["value"] = "---";
+ element["columns"][4]["font"]["name"] = "SANSSERIF";
+ element["columns"][4]["font"]["style"] = font_style;
}
LL_DEBUGS("Gesture") << "Added gesture [" << item_name << "]" << LL_ENDL;
@@ -391,9 +398,18 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur
LLScrollListItem* sl_item = list->addElement(element, ADD_BOTTOM);
if(sl_item)
{
- LLFontGL::StyleFlags style = LLGestureMgr::getInstance()->isGestureActive(item_id) ? LLFontGL::BOLD : LLFontGL::NORMAL;
- // *TODO find out why ["font"]["style"] does not affect font style
- ((LLScrollListText*)sl_item->getColumn(0))->setFontStyle(style);
+ if (LLGestureMgr::getInstance()->isGestureActive(item_id))
+ {
+ // If gesture was not yet loaded, will have to set active state here
+ ((LLScrollListIcon*)sl_item->getColumn(0))->setValue("Activate_Checkmark");
+ ((LLScrollListIcon*)sl_item->getColumn(0))->setIconSize(10);
+ ((LLScrollListText*)sl_item->getColumn(1))->setFontStyle(LLFontGL::BOLD);
+ }
+ else
+ {
+ ((LLScrollListIcon*)sl_item->getColumn(0))->setValue("");
+ ((LLScrollListText*)sl_item->getColumn(1))->setFontStyle(LLFontGL::NORMAL);
+ }
}
}
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 5c5219bcdd..ebc91255d9 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -108,18 +108,6 @@ public:
virtual void changed() { LLFloaterLand::refreshAll(); }
};
-// class needed to get full access to textbox inside checkbox, because LLCheckBoxCtrl::setLabel() has string as its argument.
-// It was introduced while implementing EXT-4706
-class LLCheckBoxWithTBAcess : public LLCheckBoxCtrl
-{
-public:
- LLTextBox* getTextBox()
- {
- return mLabel;
- }
-};
-
-
class LLPanelLandExperiences
: public LLPanel
{
@@ -2176,12 +2164,11 @@ void LLPanelLandOptions::refresh()
mMatureCtrl->setVisible(true);
LLStyle::Params style;
style.image(LLUI::getUIImage(gFloaterView->getParentFloater(this)->getString("maturity_icon_moderate")));
- LLCheckBoxWithTBAcess* fullaccess_mature_ctrl = (LLCheckBoxWithTBAcess*)mMatureCtrl;
- fullaccess_mature_ctrl->getTextBox()->setText(LLStringExplicit(""));
- fullaccess_mature_ctrl->getTextBox()->appendImageSegment(style);
- fullaccess_mature_ctrl->getTextBox()->appendText(getString("mature_check_mature"), false);
- fullaccess_mature_ctrl->setToolTip(getString("mature_check_mature_tooltip"));
- fullaccess_mature_ctrl->reshape(fullaccess_mature_ctrl->getRect().getWidth(), fullaccess_mature_ctrl->getRect().getHeight(), false);
+ mMatureCtrl->getTextBox()->setText(LLStringExplicit(""));
+ mMatureCtrl->getTextBox()->appendImageSegment(style);
+ mMatureCtrl->getTextBox()->appendText(getString("mature_check_mature"), false);
+ mMatureCtrl->setToolTip(getString("mature_check_mature_tooltip"));
+ mMatureCtrl->reshape(mMatureCtrl->getRect().getWidth(), mMatureCtrl->getRect().getHeight(), false);
// they can see the checkbox, but its disposition depends on the
// state of the region
diff --git a/indra/newview/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp
index e571011acf..8eeba095b2 100644
--- a/indra/newview/llfloaternotificationstabbed.cpp
+++ b/indra/newview/llfloaternotificationstabbed.cpp
@@ -45,7 +45,6 @@ LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LL
mGroupNoticeMessageList(NULL),
mTransactionMessageList(NULL),
mSystemMessageList(NULL),
- mNotificationsSeparator(NULL),
mNotificationsTabContainer(NULL),
NOTIFICATION_TABBED_ANCHOR_NAME("notification_well_panel"),
IM_WELL_ANCHOR_NAME("im_well_panel"),
@@ -54,7 +53,7 @@ LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LL
{
setOverlapsScreenChannel(true);
mNotificationUpdates.reset(new NotificationTabbedChannel(this));
- mNotificationsSeparator = new LLNotificationSeparator();
+ mNotificationsSeparator = std::make_unique<LLNotificationSeparator>();
}
//---------------------------------------------------------------------------------
@@ -117,6 +116,7 @@ void LLFloaterNotificationsTabbed::setSysWellChiclet(LLSysWellChiclet* chiclet)
//---------------------------------------------------------------------------------
LLFloaterNotificationsTabbed::~LLFloaterNotificationsTabbed()
{
+ mNotificationsSeparator.reset();
}
//---------------------------------------------------------------------------------
diff --git a/indra/newview/llfloaternotificationstabbed.h b/indra/newview/llfloaternotificationstabbed.h
index 87e880c8d2..49dfe6033f 100644
--- a/indra/newview/llfloaternotificationstabbed.h
+++ b/indra/newview/llfloaternotificationstabbed.h
@@ -162,7 +162,7 @@ private:
LLNotificationListView* mGroupNoticeMessageList;
LLNotificationListView* mTransactionMessageList;
LLNotificationListView* mSystemMessageList;
- LLNotificationSeparator* mNotificationsSeparator;
+ std::unique_ptr<LLNotificationSeparator> mNotificationsSeparator;
LLTabContainer* mNotificationsTabContainer;
LLButton* mDeleteAllBtn;
LLButton* mCollapseAllBtn;
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 f537ae6424..5f061e780a 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1355,7 +1355,7 @@ void LLFloaterPreference::onChangeQuality(const LLSD& data)
if (level >= LVL_HIGH && mLastQualityLevel < level)
{
constexpr U32 LOW_MEM_THRESHOLD = 4097;
- U32 total_mem = (U32Megabytes)LLMemory::getMaxMemKB();
+ U32 total_mem = U32Megabytes(LLMemory::getMaxMemKB());
if (total_mem < LOW_MEM_THRESHOLD)
{
LLSD args;
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index a8a1e507a8..96c2e1e1e4 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -81,7 +81,7 @@ bool LLFloaterPreferenceGraphicsAdvanced::postBuild()
}
}
-#if !LL_DARWIN
+#if !LL_DARWIN && !LL_SDL_WINDOW
LLCheckBoxCtrl *use_HiDPI = getChild<LLCheckBoxCtrl>("use HiDPI");
use_HiDPI->setVisible(false);
#endif
@@ -340,6 +340,12 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
tonemapMix->setEnabled(is_not_vintage);
exposureSlider->setEnabled(is_not_vintage);
cas_slider->setEnabled(is_not_vintage);
+
+ LLComboBox* ctrl_anisotropic = getChild<LLComboBox>("anisotropic_filter");
+ if (!LLFeatureManager::instance().isFeatureAvailable("RenderAnisotropicLevel"))
+ {
+ ctrl_anisotropic->setEnabled(false);
+ }
}
void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
@@ -384,6 +390,20 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"));
+ LLComboBox* af_combo = getChild<LLComboBox>("anisotropic_filter");
+ if (2.f > gGLManager.mMaxAnisotropy) {
+ af_combo->remove("2x");
+ }
+ if (4.f > gGLManager.mMaxAnisotropy) {
+ af_combo->remove("4x");
+ }
+ if (8.f > gGLManager.mMaxAnisotropy) {
+ af_combo->remove("8x");
+ }
+ if (16.f > gGLManager.mMaxAnisotropy) {
+ af_combo->remove("16x");
+ }
+
// now turn off any features that are unavailable
disableUnavailableSettings();
}
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index 0036df9c3d..e0f65315d5 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -515,8 +515,8 @@ private:
void searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string);
void copyListToClipboard(std::string list_name);
- bool mPendingUpdate;
- bool mCtrlsEnabled;
+ bool mPendingUpdate = false;
+ bool mCtrlsEnabled = false;
};
#endif
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 112008172e..cb1068943e 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -728,8 +728,7 @@ void LLViewerObjectList::renderObjectBeacons()
S32 line_width = debug_beacon.mLineWidth;
if (line_width != last_line_width)
{
- gGL.flush();
- glLineWidth( (F32)line_width );
+ gGL.setLineWidth( (F32)line_width );
last_line_width = line_width;
}
@@ -758,8 +757,7 @@ void LLViewerObjectList::renderObjectBeacons()
S32 line_width = debug_beacon.mLineWidth;
if (line_width != last_line_width)
{
- gGL.flush();
- glLineWidth( (F32)line_width );
+ gGL.setLineWidth( (F32)line_width );
last_line_width = line_width;
}
@@ -773,7 +771,7 @@ void LLViewerObjectList::renderObjectBeacons()
}
gGL.flush();
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
{
@@ -808,7 +806,7 @@ void LLSky::renderSunMoonBeacons(const LLVector3& pos_agent, const LLVector3& di
{
pos_end.mV[i] = pos_agent.mV[i] + (50 * direction.mV[i]);
}
- glLineWidth((GLfloat)LLPipeline::DebugBeaconLineWidth);
+ gGL.setLineWidth((GLfloat)LLPipeline::DebugBeaconLineWidth);
gGL.begin(LLRender::LINES);
color.mV[3] *= 0.5f;
gGL.color4fv(color.mV);
@@ -819,7 +817,7 @@ void LLSky::renderSunMoonBeacons(const LLVector3& pos_agent, const LLVector3& di
gGL.end();
gGL.flush();
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
}
diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp
index 5a6e9565ae..e7b988aef5 100644
--- a/indra/newview/llgltfmaterialpreviewmgr.cpp
+++ b/indra/newview/llgltfmaterialpreviewmgr.cpp
@@ -428,7 +428,7 @@ bool LLGLTFPreviewTexture::render()
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- LLGLDepthTest(GL_FALSE);
+ LLGLDepthTest depth(GL_FALSE);
LLGLDisable stencil(GL_STENCIL_TEST);
LLGLDisable scissor(GL_SCISSOR_TEST);
SetTemporarily<bool> no_dof(&LLPipeline::RenderDepthOfField, false);
@@ -462,7 +462,7 @@ bool LLGLTFPreviewTexture::render()
// Set up camera and viewport
const LLVector3 origin(0.0, 0.0, 0.0);
camera.lookAt(origin, object_position);
- camera.setAspect((F32)(mFullHeight / mFullWidth));
+ camera.setAspect((F32)(mFullWidth / mFullHeight));
const LLRect texture_rect(0, mFullHeight, mFullWidth, 0);
camera.setPerspective(NOT_FOR_SELECTION, texture_rect.mLeft, texture_rect.mBottom, texture_rect.getWidth(), texture_rect.getHeight(), false, camera.getNear(), MAX_FAR_CLIP*2.f);
diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp
index eda93e3e79..b63aa0997b 100644
--- a/indra/newview/llinventorygallerymenu.cpp
+++ b/indra/newview/llinventorygallerymenu.cpp
@@ -334,11 +334,11 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata)
}
else if ("copy_slurl" == action)
{
- boost::function<void(LLLandmark*)> copy_slurl_cb = [](LLLandmark* landmark)
+ std::function<void(LLLandmark*)> copy_slurl_cb = [](LLLandmark* landmark)
{
LLVector3d global_pos;
landmark->getGlobalPos(global_pos);
- boost::function<void(std::string& slurl)> copy_slurl_to_clipboard_cb = [](const std::string& slurl)
+ std::function<void(std::string& slurl)> copy_slurl_to_clipboard_cb = [](const std::string& slurl)
{
gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl));
LLSD args;
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 2cf1554957..d538d42972 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -886,31 +886,34 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc
static LLCachedControl<S32> ais_batch(gSavedSettings, "BatchSizeAIS3", 20);
S32 batch_limit = llclamp(ais_batch(), 1, 40);
- for (LLInventoryModel::cat_array_t::iterator it = categories->begin();
- it != categories->end();
- ++it)
+ if (categories)
{
- LLViewerInventoryCategory* child_cat = (*it);
- if (LLViewerInventoryCategory::VERSION_UNKNOWN != child_cat->getVersion()
- || child_cat->getFetching() >= target_state)
+ for (LLInventoryModel::cat_array_t::iterator it = categories->begin();
+ it != categories->end();
+ ++it)
{
- continue;
- }
+ LLViewerInventoryCategory* child_cat = (*it);
+ if (LLViewerInventoryCategory::VERSION_UNKNOWN != child_cat->getVersion()
+ || child_cat->getFetching() >= target_state)
+ {
+ continue;
+ }
- if (child_cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_LISTINGS)
- {
- // special case, marketplace will fetch that as needed
- continue;
- }
+ if (child_cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_LISTINGS)
+ {
+ // special case, marketplace will fetch that as needed
+ continue;
+ }
- children.emplace_back(child_cat->getUUID());
- mExpectedFolderIds.emplace_back(child_cat->getUUID());
- child_cat->setFetching(target_state);
+ children.emplace_back(child_cat->getUUID());
+ mExpectedFolderIds.emplace_back(child_cat->getUUID());
+ child_cat->setFetching(target_state);
- if (children.size() >= batch_limit)
- {
- content_done = false;
- break;
+ if (children.size() >= batch_limit)
+ {
+ content_done = false;
+ break;
+ }
}
}
@@ -940,14 +943,17 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc
// This will have a bit of overlap with onAISContentCalback,
// but something else might have downloaded folders, so verify
// every child that is complete has it's children done as well
- for (LLInventoryModel::cat_array_t::iterator it = categories->begin();
- it != categories->end();
- ++it)
+ if (categories)
{
- LLViewerInventoryCategory* child_cat = (*it);
- if (LLViewerInventoryCategory::VERSION_UNKNOWN != child_cat->getVersion())
+ for (LLInventoryModel::cat_array_t::iterator it = categories->begin();
+ it != categories->end();
+ ++it)
{
- mFetchFolderQueue.emplace_back(child_cat->getUUID(), FT_RECURSIVE);
+ LLViewerInventoryCategory* child_cat = (*it);
+ if (LLViewerInventoryCategory::VERSION_UNKNOWN != child_cat->getVersion())
+ {
+ mFetchFolderQueue.emplace_back(child_cat->getUUID(), FT_RECURSIVE);
+ }
}
}
}
@@ -998,12 +1004,15 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc
LLInventoryModel::cat_array_t* categories(NULL);
LLInventoryModel::item_array_t* items(NULL);
gInventory.getDirectDescendentsOf(cat_id, categories, items);
- for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin();
- it != categories->end();
- ++it)
+ if (categories)
{
- // not emplace_front to not cause an infinite loop
- mFetchFolderQueue.emplace_back((*it)->getUUID(), FT_RECURSIVE);
+ for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin();
+ it != categories->end();
+ ++it)
+ {
+ // not emplace_front to not cause an infinite loop
+ mFetchFolderQueue.emplace_back((*it)->getUUID(), FT_RECURSIVE);
+ }
}
}
}
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index 56e5555ba5..7a62f96064 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -194,7 +194,7 @@ private:
boost::signals2::connection mLocationHistoryConnection;
boost::signals2::connection mRegionCrossingSlot;
LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot;
- bool mIsNavMeshDirty;
+ bool mIsNavMeshDirty = false;
LLUIImage* mLandmarkImageOn;
LLUIImage* mLandmarkImageOff;
LLPointer<LLUIImage> mIconMaturityGeneral;
@@ -206,7 +206,7 @@ private:
std::string mEditLandmarkTooltip;
// this field holds a human-readable form of the location string, it is needed to be able to compare copy-pated value and real location
std::string mHumanReadableLocation;
- bool isHumanReadableLocationVisible;
+ bool isHumanReadableLocationVisible = false;
std::string mMaturityHelpTopic;
};
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 5bdf3f81b5..4bf1b134ef 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -274,7 +274,6 @@ void LLManipRotate::render()
}
LLGLEnable cull_face(GL_CULL_FACE);
- LLGLEnable clip_plane0(GL_CLIP_PLANE0);
LLGLDepthTest gls_depth(GL_FALSE);
//LLGLDisable gls_stencil(GL_STENCIL_TEST);
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 7b8211ded8..53ea345858 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -450,17 +450,14 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()
, mImportInProgress(false)
, mInitialized(false)
, mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
- , mErrorInitSignal(NULL)
- , mStatusChangedSignal(NULL)
- , mStatusReportSignal(NULL)
{
}
boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErrorCallback(const status_report_signal_t::slot_type& cb)
{
- if (mErrorInitSignal == NULL)
+ if (mErrorInitSignal == nullptr)
{
- mErrorInitSignal = new status_report_signal_t();
+ mErrorInitSignal = std::make_unique<status_report_signal_t>();
}
return mErrorInitSignal->connect(cb);
@@ -468,9 +465,9 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErr
boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb)
{
- if (mStatusChangedSignal == NULL)
+ if (mStatusChangedSignal == nullptr)
{
- mStatusChangedSignal = new status_changed_signal_t();
+ mStatusChangedSignal = std::make_unique<status_changed_signal_t>();
}
return mStatusChangedSignal->connect(cb);
@@ -478,9 +475,9 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCall
boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallback(const status_report_signal_t::slot_type& cb)
{
- if (mStatusReportSignal == NULL)
+ if (mStatusReportSignal == nullptr)
{
- mStatusReportSignal = new status_report_signal_t();
+ mStatusReportSignal = std::make_unique<status_report_signal_t>();
}
return mStatusReportSignal->connect(cb);
@@ -717,8 +714,6 @@ LLMarketplaceTuple::LLMarketplaceTuple(const LLUUID& folder_id, S32 listing_id,
LLMarketplaceData::LLMarketplaceData() :
mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED),
mMarketPlaceDataFetched(MarketplaceFetchCodes::MARKET_FETCH_NOT_DONE),
- mStatusUpdatedSignal(NULL),
- mDataFetchedSignal(NULL),
mDirtyCount(false)
{
mInventoryObserver = new LLMarketplaceInventoryObserver;
@@ -752,9 +747,9 @@ LLSD LLMarketplaceData::getMarketplaceStringSubstitutions()
void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type& cb)
{
- if (mStatusUpdatedSignal == NULL)
+ if (mStatusUpdatedSignal == nullptr)
{
- mStatusUpdatedSignal = new status_updated_signal_t();
+ mStatusUpdatedSignal = std::make_unique<status_updated_signal_t>();
}
mStatusUpdatedSignal->connect(cb);
@@ -842,7 +837,7 @@ void LLMarketplaceData::setDataFetchedSignal(const status_updated_signal_t::slot
{
if (mDataFetchedSignal == NULL)
{
- mDataFetchedSignal = new status_updated_signal_t();
+ mDataFetchedSignal = std::make_unique<status_updated_signal_t>();
}
mDataFetchedSignal->connect(cb);
}
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 281743c1d6..4e61b0c7f3 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -113,9 +113,9 @@ private:
bool mInitialized;
U32 mMarketPlaceStatus;
- status_report_signal_t * mErrorInitSignal;
- status_changed_signal_t * mStatusChangedSignal;
- status_report_signal_t * mStatusReportSignal;
+ std::unique_ptr<status_report_signal_t> mErrorInitSignal;
+ std::unique_ptr<status_changed_signal_t> mStatusChangedSignal;
+ std::unique_ptr<status_report_signal_t> mStatusReportSignal;
};
@@ -276,13 +276,13 @@ private:
// Handling Marketplace connection and inventory connection
U32 mMarketPlaceStatus;
std::string mMarketPlaceFailureReason;
- status_updated_signal_t* mStatusUpdatedSignal;
+ std::unique_ptr<status_updated_signal_t> mStatusUpdatedSignal;
LLInventoryObserver* mInventoryObserver;
bool mDirtyCount; // If true, stock count value need to be updated at the next check
// Update data
U32 mMarketPlaceDataFetched;
- status_updated_signal_t* mDataFetchedSignal;
+ std::unique_ptr<status_updated_signal_t> mDataFetchedSignal;
std::set<LLUUID> mPendingUpdateSet;
// Listing folders waiting for validation
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index ee5e5b438e..dbc44ad649 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -234,7 +234,7 @@ boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LL
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
if (itCallback == mGetCallbacks.end())
{
- std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.insert(std::pair<LLMaterialID, get_callback_t*>(material_id, new get_callback_t()));
+ std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.emplace(material_id, std::make_unique<get_callback_t>());
itCallback = ret.first;
}
connection = itCallback->second->connect(cb);;
@@ -279,7 +279,7 @@ boost::signals2::connection LLMaterialMgr::getTE(const LLUUID& region_id, const
get_callback_te_map_t::iterator itCallback = mGetTECallbacks.find(te_mat_pair);
if (itCallback == mGetTECallbacks.end())
{
- std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.insert(std::pair<TEMaterialPair, get_callback_te_t*>(te_mat_pair, new get_callback_te_t()));
+ std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.emplace(te_mat_pair, std::make_unique<get_callback_te_t>());
itCallback = ret.first;
}
connection = itCallback->second->connect(cb);
@@ -317,7 +317,7 @@ boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMat
getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id);
if (mGetAllCallbacks.end() == itCallback)
{
- std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.insert(std::pair<LLUUID, getall_callback_t*>(region_id, new getall_callback_t()));
+ std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.emplace(region_id, std::make_unique<getall_callback_t>());
itCallback = ret.first;
}
return itCallback->second->connect(cb);;
@@ -329,8 +329,8 @@ void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial&
if (mPutQueue.end() == itQueue)
{
LL_DEBUGS("Materials") << "mPutQueue insert object " << object_id << LL_ENDL;
- mPutQueue.insert(std::pair<LLUUID, facematerial_map_t>(object_id, facematerial_map_t()));
- itQueue = mPutQueue.find(object_id);
+ auto ret = mPutQueue.emplace(object_id, facematerial_map_t());
+ itQueue = ret.first;
}
facematerial_map_t::iterator itFace = itQueue->second.find(te);
@@ -361,7 +361,7 @@ void LLMaterialMgr::setLocalMaterial(const LLUUID& region_id, LLMaterialPtr mate
}
LL_DEBUGS("Materials") << "region " << region_id << "new local material id " << material_id << LL_ENDL;
- mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, material_ptr));
+ mMaterials.emplace(material_id, material_ptr);
setMaterialCallbacks(material_id, material_ptr);
@@ -376,7 +376,7 @@ const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LL
{
LL_DEBUGS("Materials") << "new material" << LL_ENDL;
LLMaterialPtr newMaterial(new LLMaterial(material_data));
- std::pair<material_map_t::const_iterator, bool> ret = mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, newMaterial));
+ std::pair<material_map_t::const_iterator, bool> ret = mMaterials.emplace(material_id, newMaterial);
itMaterial = ret.first;
}
@@ -400,7 +400,6 @@ void LLMaterialMgr::setMaterialCallbacks(const LLMaterialID& material_id, const
if (itCallbackTE != mGetTECallbacks.end())
{
(*itCallbackTE->second)(material_id, material_ptr, te_mat_pair.te);
- delete itCallbackTE->second;
mGetTECallbacks.erase(itCallbackTE);
}
}
@@ -410,7 +409,6 @@ void LLMaterialMgr::setMaterialCallbacks(const LLMaterialID& material_id, const
{
(*itCallback->second)(material_id, material_ptr);
- delete itCallback->second;
mGetCallbacks.erase(itCallback);
}
}
@@ -509,7 +507,6 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL
{
(*itCallback->second)(region_id, materials);
- delete itCallback->second;
mGetAllCallbacks.erase(itCallback);
}
@@ -549,11 +546,11 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
{
llassert(response_data.isArray());
LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
+#ifdef SHOW_ASSERT // same condition that controls llassert()
for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter)
{
-# ifdef SHOW_ASSERT // same condition that controls llassert()
const LLSD& face_data = *faceIter; // conditional to avoid unused variable warning
-# endif
+
llassert(face_data.isMap());
llassert(face_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
@@ -570,6 +567,7 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
// *TODO: do we really still need to process this?
}
+#endif
}
}
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index 1279b77ad4..ac4c18d60c 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -110,13 +110,13 @@ private:
typedef std::map<LLUUID, material_queue_t> get_queue_t;
typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
typedef std::map<const pending_material_t, F64> get_pending_map_t;
- typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
+ typedef std::map<LLMaterialID, std::unique_ptr<get_callback_t>> get_callback_map_t;
- typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*> get_callback_te_map_t;
+ typedef boost::unordered_map<TEMaterialPair, std::unique_ptr<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;
+ typedef std::map<LLUUID, std::unique_ptr<getall_callback_t>> getall_callback_map_t;
typedef std::map<U8, LLMaterial> facematerial_map_t;
typedef std::map<LLUUID, facematerial_map_t> put_queue_t;
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index c7b60b2fd5..809628cf6c 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -1030,10 +1030,6 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
case MEDIA_EVENT_NAVIGATE_COMPLETE:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL;
- if(mHidingInitialLoad)
- {
- mHidingInitialLoad = false;
- }
};
break;
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index a644ef3071..d2735a009b 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -202,7 +202,6 @@ public:
mStretchToFill,
mMaintainAspectRatio,
mHideLoading,
- mHidingInitialLoad,
mClearCache,
mHoverTextChanged,
mDecoupleTextureSize,
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 413f02b723..ac4b15c175 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -4503,7 +4503,7 @@ void LLMeshRepository::notifyLoadedMeshes()
// erase from background thread
mThread->mWorkQueue.post([=, this]()
{
- LLMutexLock(mThread->mSkinMapMutex);
+ LLMutexLock skin_lock(mThread->mSkinMapMutex);
mThread->mSkinMap.erase(id);
});
}
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 6b1fbdce4c..ed5ab35439 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -3597,11 +3597,11 @@ bool LLModelPreview::render()
gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV);
if (show_edges)
{
- glLineWidth(PREVIEW_EDGE_WIDTH);
+ gGL.setLineWidth(PREVIEW_EDGE_WIDTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
}
buffer->unmapBuffer();
}
@@ -3649,7 +3649,7 @@ bool LLModelPreview::render()
LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
if (decomp)
{
- LLMutexLock(decomp->mMutex);
+ LLMutexLock decomp_lock(decomp->mMutex);
LLModel::Decomposition& physics = model->mPhysics;
@@ -3724,12 +3724,12 @@ bool LLModelPreview::render()
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
gGL.diffuseColor4fv(PREVIEW_PSYH_EDGE_COL.mV);
- glLineWidth(PREVIEW_PSYH_EDGE_WIDTH);
+ gGL.setLineWidth(PREVIEW_PSYH_EDGE_WIDTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
buffer->unmapBuffer();
}
@@ -3741,7 +3741,7 @@ bool LLModelPreview::render()
// only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks]
if (mHasDegenerate)
{
- glLineWidth(PREVIEW_DEG_EDGE_WIDTH);
+ gGL.setLineWidth(PREVIEW_DEG_EDGE_WIDTH);
glPointSize(PREVIEW_DEG_POINT_SIZE);
gPipeline.enableLightsFullbright();
//show degenerate triangles
@@ -3770,7 +3770,7 @@ bool LLModelPreview::render()
LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
if (decomp)
{
- LLMutexLock(decomp->mMutex);
+ LLMutexLock decomp_lock(decomp->mMutex);
LLModel::Decomposition& physics = model->mPhysics;
@@ -3811,7 +3811,7 @@ bool LLModelPreview::render()
gGL.popMatrix();
}
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
glPointSize(1.f);
gPipeline.enableLightsPreview();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -3933,11 +3933,11 @@ bool LLModelPreview::render()
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV);
- glLineWidth(PREVIEW_EDGE_WIDTH);
+ gGL.setLineWidth(PREVIEW_EDGE_WIDTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
}
}
}
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 8589afae06..8a070babcd 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -988,6 +988,8 @@ LLOutfitGalleryItem::LLOutfitGalleryItem(const Params& p)
mSelected(false),
mWorn(false),
mDefaultImage(true),
+ mHidden(false),
+ mFavorite(false),
mOutfitName(""),
mUUID(LLUUID())
{
diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h
index ebf0ba1a12..431f37f78c 100644
--- a/indra/newview/lloutfitobserver.h
+++ b/indra/newview/lloutfitobserver.h
@@ -75,7 +75,7 @@ protected:
S32 mBaseOutfitLastVersion;
std::string mLastBaseOutfitName;
- bool mLastOutfitDirtiness;
+ bool mLastOutfitDirtiness = false;
LLUUID mItemNameHash;
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 449a670de9..aefda39fb9 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -153,8 +153,10 @@ void LLPanelClassifiedInfo::reshape(S32 width, S32 height, bool called_from_pare
void LLPanelClassifiedInfo::onOpen(const LLSD& key)
{
+ bool from_search = key.has("from_search") ? key["from_search"].asBoolean() : false;
+
LLUUID avatar_id = key["classified_creator_id"];
- if(avatar_id.isNull())
+ if(avatar_id.isNull() && !from_search)
{
return;
}
diff --git a/indra/newview/llpaneldirbrowser.cpp b/indra/newview/llpaneldirbrowser.cpp
new file mode 100644
index 0000000000..8468520c11
--- /dev/null
+++ b/indra/newview/llpaneldirbrowser.cpp
@@ -0,0 +1,1169 @@
+/**
+ * @file llpaneldirbrowser.cpp
+ * @brief Base class for panels in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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$
+ */
+
+// Base class for the various search panels/results browsers
+// in the Find floater. For example, Find > Popular Places
+// is derived from this.
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpaneldirbrowser.h"
+
+// linden library includes
+#include "lldir.h"
+#include "lleventflags.h"
+#include "llqueryflags.h"
+#include "message.h"
+
+// viewer project includes
+#include "llagent.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llpanelgroup.h"
+#include "llpanelclassified.h"
+#include "llpaneldirevents.h"
+#include "llpaneldirland.h"
+#include "llproductinforequest.h"
+#include "llscrolllistctrl.h"
+#include "lltextbox.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llfloaterdirectory.h"
+#include "llpanelprofile.h"
+#include "llpanelplaces.h"
+#include "llpaneleventinfo.h"
+
+
+std::map<LLUUID, LLPanelDirBrowser*> gDirBrowserInstances;
+
+LLPanelDirBrowser::LLPanelDirBrowser()
+: LLPanel(),
+ mSearchID(),
+ mWantSelectID(),
+ mCurrentSortColumn("name"),
+ mCurrentSortAscending(true),
+ mSearchStart(0),
+ mResultsPerPage(RESULTS_PER_PAGE_DEFAULT),
+ mResultsReceived(0),
+ mMinSearchChars(1),
+ mResultsContents(),
+ mHaveSearchResults(false),
+ mDidAutoSelect(true),
+ mLastResultTimer(),
+ mFloaterDirectory(nullptr)
+{
+}
+
+bool LLPanelDirBrowser::postBuild()
+{
+ childSetCommitCallback("results", onCommitList, this);
+
+ mPrevPageBtn = getChild<LLButton>("prev_btn");
+ mNextPageBtn = getChild<LLButton>("next_btn");
+
+ mPrevPageBtn->setClickedCallback([this](LLUICtrl*, const LLSD&){ prevPage(); });
+ mPrevPageBtn->setVisible(false);
+
+ mNextPageBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { nextPage(); });
+ mNextPageBtn->setVisible(false);
+
+ return true;
+}
+
+LLPanelDirBrowser::~LLPanelDirBrowser()
+{
+ // Children all cleaned up by default view destructor.
+ gDirBrowserInstances.erase(mSearchID);
+}
+
+// virtual
+void LLPanelDirBrowser::draw()
+{
+ // HACK: If the results panel has data, we want to select the first
+ // item. Unfortunately, we don't know when the find is actually done,
+ // so only do this if it's been some time since the last packet of
+ // results was received.
+ if (mLastResultTimer.getElapsedTimeF32() > 0.5)
+ {
+ if (!mDidAutoSelect &&
+ !childHasFocus("results"))
+ {
+ LLCtrlListInterface *list = childGetListInterface("results");
+ if (list)
+ {
+ if (list->getCanSelect())
+ {
+ list->selectFirstItem(); // select first item by default
+ childSetFocus("results", true);
+ }
+ // Request specific data from the server
+ onCommitList(NULL, this);
+ }
+ }
+ mDidAutoSelect = true;
+ }
+
+ LLPanel::draw();
+}
+
+
+// virtual
+void LLPanelDirBrowser::nextPage()
+{
+ mSearchStart += mResultsPerPage;
+ mPrevPageBtn->setVisible(true);
+
+ performQuery();
+}
+
+
+// virtual
+void LLPanelDirBrowser::prevPage()
+{
+ mSearchStart -= mResultsPerPage;
+ mPrevPageBtn->setVisible(mSearchStart > 0);
+
+ performQuery();
+}
+
+
+void LLPanelDirBrowser::resetSearchStart()
+{
+ mSearchStart = 0;
+ mNextPageBtn->setVisible(false);
+ mPrevPageBtn->setVisible(false);
+}
+
+// protected
+void LLPanelDirBrowser::updateResultCount()
+{
+ LLScrollListCtrl* list = getChild<LLScrollListCtrl>("results");
+
+ S32 result_count = list->getItemCount();
+ std::string result_text;
+
+ if (!mHaveSearchResults) result_count = 0;
+
+ if (mNextPageBtn && mNextPageBtn->getVisible())
+ {
+ // Item count be off by a few if bogus items sent from database
+ // Just use the number of results per page. JC
+ result_text = llformat(">%d found", mResultsPerPage);
+ }
+ else
+ {
+ result_text = llformat("%d found", result_count);
+ }
+
+ childSetValue("result_text", result_text);
+
+ if (result_count == 0)
+ {
+ // add none found response
+ if (list->getItemCount() == 0)
+ {
+ list->setCommentText(std::string("None found.")); // *TODO: Translate
+ list->operateOnAll(LLCtrlListInterface::OP_DESELECT);
+ }
+ }
+ else
+ {
+ childEnable("results");
+ }
+}
+
+// static
+std::string LLPanelDirBrowser::filterShortWords(const std::string source_string, int shortest_word_length, bool& was_filtered)
+{
+ // degenerate case
+ if ( source_string.length() < 1 )
+ return "";
+
+ std::stringstream codec( source_string );
+ std::string each_word;
+ std::vector< std::string > all_words;
+
+ while( codec >> each_word )
+ all_words.push_back( each_word );
+
+ std::ostringstream dest_string( "" );
+
+ was_filtered = false;
+
+ std::vector< std::string >::iterator iter = all_words.begin();
+ while( iter != all_words.end() )
+ {
+ if ( (int)(*iter).length() >= shortest_word_length )
+ {
+ dest_string << *iter;
+ dest_string << " ";
+ }
+ else
+ {
+ was_filtered = true;
+ }
+
+ ++iter;
+ };
+
+ return dest_string.str();
+}
+
+void LLPanelDirBrowser::selectByUUID(const LLUUID& id)
+{
+ LLCtrlListInterface *list = childGetListInterface("results");
+ if (!list) return;
+ bool found = list->setCurrentByID(id);
+ if (found)
+ {
+ // we got it, don't wait for network
+ // Don't bother looking for this in the draw loop.
+ mWantSelectID.setNull();
+ // Make sure UI updates.
+ onCommitList(NULL, this);
+ }
+ else
+ {
+ // waiting for this item from the network
+ mWantSelectID = id;
+ }
+}
+
+void LLPanelDirBrowser::selectEventByID(S32 event_id)
+{
+ if (mFloaterDirectory)
+ {
+ if (mFloaterDirectory->mPanelEventp)
+ {
+ mFloaterDirectory->mPanelEventp->setVisible(true);
+ mFloaterDirectory->mPanelEventp->setEventID(event_id);
+ }
+ }
+}
+
+void LLPanelDirBrowser::getSelectedInfo(LLUUID* id, S32 *type)
+{
+ LLCtrlListInterface *list = childGetListInterface("results");
+ if (!list) return;
+
+ LLSD id_sd = childGetValue("results");
+
+ *id = id_sd.asUUID();
+
+ std::string id_str = id_sd.asString();
+ *type = mResultsContents[id_str]["type"];
+}
+
+
+// static
+void LLPanelDirBrowser::onCommitList(LLUICtrl* ctrl, void* data)
+{
+ LLPanelDirBrowser* self = (LLPanelDirBrowser*)data;
+ LLCtrlListInterface *list = self->childGetListInterface("results");
+ if (!list) return;
+
+ // Start with everyone invisible
+ if (self->mFloaterDirectory)
+ {
+ self->mFloaterDirectory->hideAllDetailPanels();
+ }
+
+ if (FALSE == list->getCanSelect())
+ {
+ return;
+ }
+
+ std::string id_str = self->childGetValue("results").asString();
+ if (id_str.empty())
+ {
+ return;
+ }
+
+ LLSD item_id = list->getCurrentID();
+ S32 type = self->mResultsContents[id_str]["type"];
+ if (type == EVENT_CODE)
+ {
+ // all but events use the UUID above
+ item_id = self->mResultsContents[id_str]["event_id"];
+ }
+ //std::string name = self->mResultsContents[id_str]["name"].asString();
+ self->showDetailPanel(type, item_id);
+}
+
+void LLPanelDirBrowser::showDetailPanel(S32 type, LLSD id)
+{
+ switch(type)
+ {
+ case AVATAR_CODE:
+ if (mFloaterDirectory && mFloaterDirectory->mPanelAvatarp)
+ {
+ mFloaterDirectory->mPanelAvatarp->setVisible(true);
+ mFloaterDirectory->mPanelAvatarp->onOpen(id);
+ mFloaterDirectory->mPanelAvatarp->updateData();
+ }
+ break;
+ case GROUP_CODE:
+ if (mFloaterDirectory && mFloaterDirectory->mPanelGroupp)
+ {
+ mFloaterDirectory->mPanelGroupp->setVisible(true);
+ mFloaterDirectory->mPanelGroupp->onOpen(LLSD().with("group_id", id));
+ }
+ break;
+ case PLACE_CODE:
+ case FOR_SALE_CODE:
+ case AUCTION_CODE:
+ if (mFloaterDirectory && mFloaterDirectory->mPanelPlacep)
+ {
+ mFloaterDirectory->mPanelPlacep->setVisible(true);
+ LLSD key;
+ key["type"] = "remote_place";
+ key["id"]= id;
+ mFloaterDirectory->mPanelPlacep->onOpen(key);
+ }
+ break;
+ case CLASSIFIED_CODE:
+ if (mFloaterDirectory && mFloaterDirectory->mPanelClassifiedp)
+ {
+ mFloaterDirectory->mPanelClassifiedp->setVisible(true);
+ LLSD key;
+ key["classified_id"] = id;
+ key["from_search"] = true;
+ mFloaterDirectory->mPanelClassifiedp->onOpen(key);
+ }
+ break;
+ case EVENT_CODE:
+ {
+ U32 event_id = (U32)id.asInteger();
+ showEvent(event_id);
+ }
+ break;
+ default:
+ {
+ LL_WARNS() << "Unknown event type!" << LL_ENDL;
+ }
+ break;
+ }
+}
+
+
+void LLPanelDirBrowser::showEvent(const U32 event_id)
+{
+ // Start with everyone invisible
+ if (mFloaterDirectory)
+ {
+ mFloaterDirectory->hideAllDetailPanels();
+ if (mFloaterDirectory->mPanelEventp)
+ {
+ mFloaterDirectory->mPanelEventp->setVisible(true);
+ mFloaterDirectory->mPanelEventp->setEventID(event_id);
+ }
+ }
+}
+
+void LLPanelDirBrowser::processDirPeopleReply(LLMessageSystem *msg, void**)
+{
+ LLUUID query_id;
+ std::string first_name;
+ std::string last_name;
+ LLUUID agent_id;
+
+ msg->getUUIDFast(_PREHASH_QueryData,_PREHASH_QueryID, query_id);
+
+ LLPanelDirBrowser* self = get_if_there(gDirBrowserInstances, query_id, (LLPanelDirBrowser*)NULL);
+ if (!self)
+ {
+ // data from an old query
+ return;
+ }
+
+ self->mHaveSearchResults = TRUE;
+
+ LLCtrlListInterface *list = self->childGetListInterface("results");
+ if (!list) return;
+
+ if (!list->getCanSelect())
+ {
+ list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ self->mResultsContents = LLSD();
+ }
+
+ S32 rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
+ self->mResultsReceived += rows;
+
+ rows = self->showNextButton(rows);
+
+ for (S32 i = 0; i < rows; i++)
+ {
+ msg->getStringFast(_PREHASH_QueryReplies,_PREHASH_FirstName, first_name, i);
+ msg->getStringFast(_PREHASH_QueryReplies,_PREHASH_LastName, last_name, i);
+ msg->getUUIDFast( _PREHASH_QueryReplies,_PREHASH_AgentID, agent_id, i);
+ // msg->getU8Fast( _PREHASH_QueryReplies,_PREHASH_Online, online, i);
+ // unused
+ // msg->getStringFast(_PREHASH_QueryReplies,_PREHASH_Group, group, i);
+ // msg->getS32Fast( _PREHASH_QueryReplies,_PREHASH_Reputation, reputation, i);
+
+ if (agent_id.isNull())
+ {
+ continue;
+ }
+
+ LLSD content;
+
+ LLSD row;
+ row["id"] = agent_id;
+
+ // We don't show online status in the finder anymore,
+ // so just use the 'offline' icon as the generic 'person' icon
+ row["columns"][0]["column"] = "icon";
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = "icon_avatar_offline.tga";
+
+ content["type"] = AVATAR_CODE;
+
+ std::string fullname = first_name + " " + last_name;
+ row["columns"][1]["column"] = "name";
+ row["columns"][1]["value"] = fullname;
+ row["columns"][1]["font"] = "SANSSERIF";
+
+ content["name"] = fullname;
+
+ list->addElement(row);
+ self->mResultsContents[agent_id.asString()] = content;
+ }
+
+ list->sortByColumn(self->mCurrentSortColumn, self->mCurrentSortAscending);
+ self->updateResultCount();
+
+ // Poke the result received timer
+ self->mLastResultTimer.reset();
+ self->mDidAutoSelect = false;
+}
+
+
+void LLPanelDirBrowser::processDirPlacesReply(LLMessageSystem* msg, void**)
+{
+ LLUUID agent_id;
+ LLUUID query_id;
+ LLUUID parcel_id;
+ std::string name;
+ bool is_for_sale = false;
+ bool is_auction = false;
+ F32 dwell;
+
+ msg->getUUID("AgentData", "AgentID", agent_id);
+ msg->getUUID("QueryData", "QueryID", query_id );
+
+ if (msg->getNumberOfBlocks("StatusData"))
+ {
+ U32 status;
+ msg->getU32("StatusData", "Status", status);
+ if (status & STATUS_SEARCH_PLACES_BANNEDWORD)
+ {
+ LLNotificationsUtil::add("SearchWordBanned");
+ }
+ }
+
+ LLPanelDirBrowser* self = get_if_there(gDirBrowserInstances, query_id, (LLPanelDirBrowser*)NULL);
+ if (!self)
+ {
+ // data from an old query
+ return;
+ }
+
+ self->mHaveSearchResults = TRUE;
+
+ LLCtrlListInterface *list = self->childGetListInterface("results");
+ if (!list) return;
+
+ if (!list->getCanSelect())
+ {
+ list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ self->mResultsContents = LLSD();
+ }
+
+ S32 count = msg->getNumberOfBlocks("QueryReplies");
+ self->mResultsReceived += count;
+
+ count = self->showNextButton(count);
+
+ for (S32 i = 0; i < count ; i++)
+ {
+ msg->getUUID("QueryReplies", "ParcelID", parcel_id, i);
+ msg->getString("QueryReplies", "Name", name, i);
+ msg->getBOOL("QueryReplies", "ForSale", is_for_sale, i);
+ msg->getBOOL("QueryReplies", "Auction", is_auction, i);
+ msg->getF32("QueryReplies", "Dwell", dwell, i);
+
+ if (parcel_id.isNull())
+ {
+ continue;
+ }
+
+ LLSD content;
+ S32 type;
+
+ LLSD row = self->createLandSale(parcel_id, is_auction, is_for_sale, name, &type);
+
+ content["type"] = type;
+ content["name"] = name;
+
+ std::string buffer = llformat("%.0f", (F64)dwell);
+ row["columns"][2]["column"] = "dwell";
+ row["columns"][2]["value"] = buffer;
+ row["columns"][2]["font"] = "SansSerifSmall";
+
+ list->addElement(row);
+ self->mResultsContents[parcel_id.asString()] = content;
+ }
+
+ list->sortByColumn(self->mCurrentSortColumn, self->mCurrentSortAscending);
+ self->updateResultCount();
+
+ // Poke the result received timer
+ self->mLastResultTimer.reset();
+ self->mDidAutoSelect = false;
+}
+
+
+void LLPanelDirBrowser::processDirEventsReply(LLMessageSystem* msg, void**)
+{
+ LLUUID agent_id;
+ LLUUID query_id;
+ LLUUID owner_id;
+ std::string name;
+ std::string date;
+ bool show_pg = gSavedSettings.getBOOL("ShowPGEvents");
+ bool show_mature = gSavedSettings.getBOOL("ShowMatureEvents");
+ bool show_adult = gSavedSettings.getBOOL("ShowAdultEvents");
+
+ msg->getUUID("AgentData", "AgentID", agent_id);
+ msg->getUUID("QueryData", "QueryID", query_id );
+
+ LLPanelDirBrowser* self = get_if_there(gDirBrowserInstances, query_id, (LLPanelDirBrowser*)NULL);
+ if (!self)
+ {
+ return;
+ }
+
+ if (msg->getNumberOfBlocks("StatusData"))
+ {
+ U32 status;
+ msg->getU32("StatusData", "Status", status);
+ if (status & STATUS_SEARCH_EVENTS_BANNEDWORD)
+ {
+ LLNotificationsUtil::add("SearchWordBanned");
+ }
+ }
+
+ self->mHaveSearchResults = TRUE;
+
+ LLCtrlListInterface *list = self->childGetListInterface("results");
+ if (!list) return;
+
+ if (!list->getCanSelect())
+ {
+ list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ self->mResultsContents = LLSD();
+ }
+
+ S32 rows = msg->getNumberOfBlocks("QueryReplies");
+ self->mResultsReceived += rows;
+
+ rows = self->showNextButton(rows);
+
+ for (S32 i = 0; i < rows; i++)
+ {
+ U32 event_id;
+ U32 unix_time;
+ U32 event_flags;
+
+ msg->getUUID("QueryReplies", "OwnerID", owner_id, i);
+ msg->getString("QueryReplies", "Name", name, i);
+ msg->getU32("QueryReplies", "EventID", event_id, i);
+ msg->getString("QueryReplies", "Date", date, i);
+ msg->getU32("QueryReplies", "UnixTime", unix_time, i);
+ msg->getU32("QueryReplies", "EventFlags", event_flags, i);
+
+ // Skip empty events
+ if (owner_id.isNull())
+ {
+ //RN: should this check event_id instead?
+ LL_WARNS() << "skipped event due to owner_id null, event_id " << event_id << LL_ENDL;
+ continue;
+ }
+
+ // skip events that don't match the flags
+ // there's no PG flag, so we make sure neither adult nor mature is set
+ if (((event_flags & (EVENT_FLAG_ADULT | EVENT_FLAG_MATURE)) == EVENT_FLAG_NONE) && !show_pg)
+ {
+ //llwarns << "Skipped pg event because we're not showing pg, event_id " << event_id << llendl;
+ continue;
+ }
+
+ if ((event_flags & EVENT_FLAG_MATURE) && !show_mature)
+ {
+ //llwarns << "Skipped mature event because we're not showing mature, event_id " << event_id << llendl;
+ continue;
+ }
+
+ if ((event_flags & EVENT_FLAG_ADULT) && !show_adult)
+ {
+ //llwarns << "Skipped adult event because we're not showing adult, event_id " << event_id << llendl;
+ continue;
+ }
+
+ LLSD content;
+
+ content["type"] = EVENT_CODE;
+ content["name"] = name;
+ content["event_id"] = (S32)event_id;
+
+ LLSD row;
+ row["id"] = llformat("%u", event_id);
+
+ // Column 0 - event icon
+ LLUUID image_id;
+ if (event_flags == EVENT_FLAG_ADULT)
+ {
+ row["columns"][0]["column"] = "icon";
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = "icon_event_adult.tga";
+ }
+ else if (event_flags == EVENT_FLAG_MATURE)
+ {
+ row["columns"][0]["column"] = "icon";
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = "icon_event_mature.tga";
+ }
+ else
+ {
+ row["columns"][0]["column"] = "icon";
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = "icon_event.tga";
+ }
+
+ row["columns"][1]["column"] = "name";
+ row["columns"][1]["value"] = name;
+ row["columns"][1]["font"] = "SANSSERIF";
+
+ row["columns"][2]["column"] = "date";
+ row["columns"][2]["value"] = date;
+ row["columns"][2]["font"] = "SansSerifSmall";
+
+ row["columns"][3]["column"] = "time";
+ row["columns"][3]["value"] = llformat("%u", unix_time);
+ row["columns"][3]["font"] = "SansSerifSmall";
+
+ list->addElement(row, ADD_TOP /*ADD_SORTED*/);
+
+ std::string id_str = llformat("%u", event_id);
+ self->mResultsContents[id_str] = content;
+ }
+
+ list->sortByColumn(self->mCurrentSortColumn, self->mCurrentSortAscending);
+ self->updateResultCount();
+
+ // Poke the result received timer
+ self->mLastResultTimer.reset();
+ self->mDidAutoSelect = false;
+}
+
+
+// static
+void LLPanelDirBrowser::processDirGroupsReply(LLMessageSystem* msg, void**)
+{
+ S32 i;
+
+ LLUUID query_id;
+ LLUUID group_id;
+ std::string group_name;
+ S32 members;
+ F32 search_order;
+
+ msg->getUUIDFast(_PREHASH_QueryData,_PREHASH_QueryID, query_id );
+
+ LLPanelDirBrowser* self = get_if_there(gDirBrowserInstances, query_id, (LLPanelDirBrowser*)NULL);
+ if (!self)
+ {
+ return;
+ }
+
+ self->mHaveSearchResults = TRUE;
+
+ LLCtrlListInterface *list = self->childGetListInterface("results");
+ if (!list) return;
+
+ if (!list->getCanSelect())
+ {
+ list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ self->mResultsContents = LLSD();
+ }
+
+ S32 rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
+ self->mResultsReceived += rows;
+
+ rows = self->showNextButton(rows);
+
+ for (i = 0; i < rows; i++)
+ {
+ msg->getUUIDFast(_PREHASH_QueryReplies, _PREHASH_GroupID, group_id, i );
+ msg->getStringFast(_PREHASH_QueryReplies, _PREHASH_GroupName, group_name, i);
+ msg->getS32Fast(_PREHASH_QueryReplies, _PREHASH_Members, members, i );
+ msg->getF32Fast(_PREHASH_QueryReplies, _PREHASH_SearchOrder, search_order, i );
+
+ if (group_id.isNull())
+ {
+ continue;
+ }
+
+ LLSD content;
+ content["type"] = GROUP_CODE;
+ content["name"] = group_name;
+
+ LLSD row;
+ row["id"] = group_id;
+
+ LLUUID image_id;
+ row["columns"][0]["column"] = "icon";
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = "icon_group.tga";
+
+ row["columns"][1]["column"] = "name";
+ row["columns"][1]["value"] = group_name;
+ row["columns"][1]["font"] = "SANSSERIF";
+
+ row["columns"][2]["column"] = "members";
+ row["columns"][2]["value"] = members;
+ row["columns"][2]["font"] = "SansSerifSmall";
+
+ row["columns"][3]["column"] = "score";
+ row["columns"][3]["value"] = search_order;
+
+ list->addElement(row);
+ self->mResultsContents[group_id.asString()] = content;
+ }
+ list->sortByColumn(self->mCurrentSortColumn, self->mCurrentSortAscending);
+ self->updateResultCount();
+
+ // Poke the result received timer
+ self->mLastResultTimer.reset();
+ self->mDidAutoSelect = false;
+}
+
+
+// static
+void LLPanelDirBrowser::processDirClassifiedReply(LLMessageSystem* msg, void**)
+{
+ S32 i;
+ S32 num_new_rows;
+
+ LLUUID agent_id;
+ LLUUID query_id;
+
+ msg->getUUID("AgentData", "AgentID", agent_id);
+ if (agent_id != gAgent.getID())
+ {
+ LL_WARNS() << "Message for wrong agent " << agent_id
+ << " in processDirClassifiedReply" << LL_ENDL;
+ return;
+ }
+
+ msg->getUUID("QueryData", "QueryID", query_id);
+ LLPanelDirBrowser* self = get_if_there(gDirBrowserInstances, query_id, (LLPanelDirBrowser*)NULL);
+ if (!self)
+ {
+ return;
+ }
+
+ if (msg->getNumberOfBlocks("StatusData"))
+ {
+ U32 status;
+ msg->getU32("StatusData", "Status", status);
+ if (status & STATUS_SEARCH_CLASSIFIEDS_BANNEDWORD)
+ {
+ LLNotificationsUtil::add("SearchWordBanned");
+ }
+ }
+
+ self->mHaveSearchResults = TRUE;
+
+ LLCtrlListInterface *list = self->childGetListInterface("results");
+ if (!list) return;
+
+ if (!list->getCanSelect())
+ {
+ list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ self->mResultsContents = LLSD();
+ }
+
+ num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
+ self->mResultsReceived += num_new_rows;
+
+ num_new_rows = self->showNextButton(num_new_rows);
+ for (i = 0; i < num_new_rows; i++)
+ {
+ LLUUID classified_id;
+ std::string name;
+ U32 creation_date = 0; // unix timestamp
+ U32 expiration_date = 0; // future use
+ S32 price_for_listing = 0;
+ msg->getUUID("QueryReplies", "ClassifiedID", classified_id, i);
+ msg->getString("QueryReplies", "Name", name, i);
+ msg->getU32("QueryReplies","CreationDate",creation_date,i);
+ msg->getU32("QueryReplies","ExpirationDate",expiration_date,i);
+ msg->getS32("QueryReplies","PriceForListing",price_for_listing,i);
+
+ if ( classified_id.notNull() )
+ {
+ self->addClassified(list, classified_id, name, creation_date, price_for_listing);
+
+ LLSD content;
+ content["type"] = CLASSIFIED_CODE;
+ content["name"] = name;
+ self->mResultsContents[classified_id.asString()] = content;
+ }
+ }
+ // The server does the initial sort, by price paid per listing and date. JC
+ self->updateResultCount();
+
+ // Poke the result received timer
+ self->mLastResultTimer.reset();
+ self->mDidAutoSelect = false;
+}
+
+void LLPanelDirBrowser::processDirLandReply(LLMessageSystem *msg, void**)
+{
+ LLUUID agent_id;
+ LLUUID query_id;
+ LLUUID parcel_id;
+ std::string name;
+ std::string land_sku;
+ std::string land_type;
+ bool auction = false;
+ bool for_sale = false;
+ S32 sale_price;
+ S32 actual_area;
+
+ msg->getUUID("AgentData", "AgentID", agent_id);
+ msg->getUUID("QueryData", "QueryID", query_id );
+
+ LLPanelDirBrowser* browser = get_if_there(gDirBrowserInstances, query_id, (LLPanelDirBrowser*)NULL);
+ if (!browser)
+ {
+ // data from an old query
+ return;
+ }
+
+ // Only handled by LLPanelDirLand
+ LLPanelDirLand* self = (LLPanelDirLand*)browser;
+
+ self->mHaveSearchResults = TRUE;
+
+ LLCtrlListInterface *list = self->childGetListInterface("results");
+ if (!list) return;
+
+ if (!list->getCanSelect())
+ {
+ list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ self->mResultsContents = LLSD();
+ }
+
+ bool use_price = gSavedSettings.getBOOL("FindLandPrice");
+ S32 limit_price = self->childGetValue("priceedit").asInteger();
+
+ bool use_area = gSavedSettings.getBOOL("FindLandArea");
+ S32 limit_area = self->childGetValue("areaedit").asInteger();
+
+ S32 i;
+ S32 count = msg->getNumberOfBlocks("QueryReplies");
+ self->mResultsReceived += count;
+
+ S32 non_auction_count = 0;
+ for (i = 0; i < count; i++)
+ {
+ msg->getUUID("QueryReplies", "ParcelID", parcel_id, i);
+ msg->getString("QueryReplies", "Name", name, i);
+ msg->getBOOL("QueryReplies", "Auction", auction, i);
+ msg->getBOOL("QueryReplies", "ForSale", for_sale, i);
+ msg->getS32("QueryReplies", "SalePrice", sale_price, i);
+ msg->getS32("QueryReplies", "ActualArea", actual_area, i);
+
+ if ( msg->getSizeFast(_PREHASH_QueryReplies, i, _PREHASH_ProductSKU) > 0 )
+ {
+ msg->getStringFast(_PREHASH_QueryReplies, _PREHASH_ProductSKU, land_sku, i);
+ land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku);
+ }
+ else
+ {
+ land_sku.clear();
+ land_type = LLTrans::getString("land_type_unknown");
+ }
+
+ if (parcel_id.isNull()) continue;
+
+ if (use_price && (sale_price > limit_price)) continue;
+
+ if (use_area && (actual_area < limit_area)) continue;
+
+ LLSD content;
+ S32 type;
+
+ LLSD row = self->createLandSale(parcel_id, auction, for_sale, name, &type);
+
+ content["type"] = type;
+ content["name"] = name;
+ content["landtype"] = land_type;
+
+ std::string buffer = "Auction";
+ if (!auction)
+ {
+ buffer = llformat("%d", sale_price);
+ non_auction_count++;
+ }
+ row["columns"][2]["column"] = "price";
+ row["columns"][2]["value"] = buffer;
+ row["columns"][2]["font"] = "SansSerifSmall";
+
+ buffer = llformat("%d", actual_area);
+ row["columns"][3]["column"] = "area";
+ row["columns"][3]["value"] = buffer;
+ row["columns"][3]["font"] = "SansSerifSmall";
+
+ if (!auction)
+ {
+ F32 price_per_meter;
+ if (actual_area > 0)
+ {
+ price_per_meter = (F32)sale_price / (F32)actual_area;
+ }
+ else
+ {
+ price_per_meter = 0.f;
+ }
+ // Prices are usually L$1 - L$10 / meter
+ buffer = llformat("%.1f", price_per_meter);
+ row["columns"][4]["column"] = "per_meter";
+ row["columns"][4]["value"] = buffer;
+ row["columns"][4]["font"] = "SansSerifSmall";
+ }
+ else
+ {
+ // Auctions start at L$1 per meter
+ row["columns"][4]["column"] = "per_meter";
+ row["columns"][4]["value"] = "1.0";
+ row["columns"][4]["font"] = "SansSerifSmall";
+ }
+
+ row["columns"][5]["column"] = "landtype";
+ row["columns"][5]["value"] = land_type;
+ row["columns"][5]["font"] = "SansSerifSmall";
+
+ list->addElement(row);
+ self->mResultsContents[parcel_id.asString()] = content;
+ }
+
+ // All auction results are shown on the first page
+ // But they don't count towards the 100 / page limit
+ // So figure out the next button here, when we know how many aren't auctions
+ count = self->showNextButton(non_auction_count);
+
+ self->updateResultCount();
+
+ // Poke the result received timer
+ self->mLastResultTimer.reset();
+ self->mDidAutoSelect = false;
+}
+
+void LLPanelDirBrowser::addClassified(LLCtrlListInterface *list, const LLUUID& pick_id, const std::string& name, const U32 creation_date, const S32 price_for_listing)
+{
+ std::string type = llformat("%d", CLASSIFIED_CODE);
+
+ LLSD row;
+ row["id"] = pick_id;
+
+ row["columns"][0]["column"] = "icon";
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = "icon_top_pick.tga";
+
+ row["columns"][1]["column"] = "name";
+ row["columns"][1]["value"] = name;
+ row["columns"][1]["font"] = "SANSSERIF";
+
+ row["columns"][2]["column"] = "price";
+ row["columns"][2]["value"] = price_for_listing;
+ row["columns"][2]["font"] = "SansSerifSmall";
+
+ list->addElement(row);
+}
+
+LLSD LLPanelDirBrowser::createLandSale(const LLUUID& parcel_id, bool is_auction, bool is_for_sale, const std::string& name, S32 *type)
+{
+ LLSD row;
+ row["id"] = parcel_id;
+ LLUUID image_id;
+
+ // Icon and type
+ if(is_auction)
+ {
+ row["columns"][0]["column"] = "icon";
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = "icon_auction.tga";
+
+ *type = AUCTION_CODE;
+ }
+ else if (is_for_sale)
+ {
+ row["columns"][0]["column"] = "icon";
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = "icon_for_sale.tga";
+
+ *type = FOR_SALE_CODE;
+ }
+ else
+ {
+ row["columns"][0]["column"] = "icon";
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = "icon_place.tga";
+
+ *type = PLACE_CODE;
+ }
+
+ row["columns"][1]["column"] = "name";
+ row["columns"][1]["value"] = name;
+ row["columns"][1]["font"] = "SANSSERIF";
+
+ return row;
+}
+
+void LLPanelDirBrowser::setupNewSearch()
+{
+ LLScrollListCtrl* list = getChild<LLScrollListCtrl>("results");
+
+ gDirBrowserInstances.erase(mSearchID);
+ // Make a new query ID
+ mSearchID.generate();
+
+ gDirBrowserInstances.emplace(mSearchID, this);
+
+ // ready the list for results
+ list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ list->setCommentText(LLTrans::getString("Searching"));
+ list->setEnabled(false);
+
+ mResultsReceived = 0;
+ mHaveSearchResults = FALSE;
+
+ // Set all panels to be invisible
+ mFloaterDirectory->hideAllDetailPanels();
+
+ updateResultCount();
+}
+
+
+// static
+// called from calssifieds, events, groups, land, people, and places
+void LLPanelDirBrowser::onClickSearchCore(void* userdata)
+{
+ LLPanelDirBrowser* self = (LLPanelDirBrowser*)userdata;
+ if (!self) return;
+
+ self->resetSearchStart();
+ self->performQuery();
+}
+
+
+// static
+void LLPanelDirBrowser::sendDirFindQuery(
+ LLMessageSystem* msg,
+ const LLUUID& query_id,
+ const std::string& text,
+ U32 flags,
+ S32 query_start)
+{
+ msg->newMessage("DirFindQuery");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("QueryData");
+ msg->addUUID("QueryID", query_id);
+ msg->addString("QueryText", text);
+ msg->addU32("QueryFlags", flags);
+ msg->addS32("QueryStart", query_start);
+ gAgent.sendReliableMessage();
+}
+
+
+void LLPanelDirBrowser::onKeystrokeName(LLLineEditor* line, void* data)
+{
+ LLPanelDirBrowser *self = (LLPanelDirBrowser*)data;
+ if (line->getLength() >= (S32)self->mMinSearchChars)
+ {
+ self->setDefaultBtn( "Search" );
+ self->childEnable("Search");
+ }
+ else
+ {
+ self->setDefaultBtn();
+ self->childDisable("Search");
+ }
+}
+
+// setup results when shown
+void LLPanelDirBrowser::onVisibilityChange(bool new_visibility)
+{
+ if (new_visibility)
+ {
+ onCommitList(NULL, this);
+ }
+ LLPanel::onVisibilityChange(new_visibility);
+}
+
+S32 LLPanelDirBrowser::showNextButton(S32 rows)
+{
+ // HACK: This hack doesn't work for llpaneldirfind (ALL)
+ // because other data is being returned as well.
+ if ( getName() != "find_all_old_panel")
+ {
+ // HACK: The (mResultsPerPage)+1th entry indicates there are 'more'
+ bool show_next = (mResultsReceived > mResultsPerPage);
+ mNextPageBtn->setVisible(show_next);
+ if (show_next)
+ {
+ rows -= (mResultsReceived - mResultsPerPage);
+ }
+ }
+ else
+ {
+ // Hide page buttons
+ mNextPageBtn->setVisible(false);
+ mPrevPageBtn->setVisible(false);
+ }
+ return rows;
+}
diff --git a/indra/newview/llpaneldirbrowser.h b/indra/newview/llpaneldirbrowser.h
new file mode 100644
index 0000000000..cb947f8507
--- /dev/null
+++ b/indra/newview/llpaneldirbrowser.h
@@ -0,0 +1,167 @@
+/**
+ * @file llpaneldirbrowser.h
+ * @brief Base class for panels in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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_LLPANELDIRBROWSER_H
+#define LL_LLPANELDIRBROWSER_H
+
+#include "llpanel.h"
+
+#include "llframetimer.h"
+
+class LLMessageSystem;
+class LLFloaterDirectory;
+class LLLineEditor;
+
+class LLPanelDirBrowser: public LLPanel
+{
+public:
+ LLPanelDirBrowser();
+ virtual ~LLPanelDirBrowser();
+
+ bool postBuild() override;
+ void setFloaterDirectory(LLFloaterDirectory* floater) { mFloaterDirectory = floater; }
+
+ // Use to get periodic updates.
+ void draw() override;
+
+ void onVisibilityChange(bool curVisibilityIn) override;
+
+ // Redo your search for the prev/next page of results
+ virtual void prevPage();
+ virtual void nextPage();
+ void resetSearchStart();
+ // Do the current query (used by prevPage/nextPage)
+ virtual void performQuery() {};
+
+ const LLUUID& getSearchID() const { return mSearchID; }
+
+ // Select the line in the scroll list control with this ID,
+ // either now or when data arrives from the server.
+ void selectByUUID(const LLUUID& id);
+
+ void selectEventByID(S32 event_id);
+
+ void getSelectedInfo(LLUUID* id, S32 *type);
+
+ void showDetailPanel(S32 type, LLSD item_id);
+ // type is EVENT_CODE, PLACE_CODE, etc. from below.
+ // item_id is integer for events, UUID for all others.
+
+ // from llpaneldirbase
+ void setupNewSearch();
+
+ // default handler for clicking the search button resets the
+ // next/prev state and performs the query.
+ // Expects a pointer to an LLPanelDirBrowser object.
+ static void onClickSearchCore(void* userdata);
+
+ // query_start indicates the first result row to
+ // return, usually 0 or 100 or 200 because the searches
+ // return a max of 100 rows
+ static void sendDirFindQuery(
+ LLMessageSystem* msg,
+ const LLUUID& query_id,
+ const std::string& text,
+ U32 flags,
+ S32 query_start);
+
+ void showEvent(const U32 event_id);
+
+ static void onCommitList(LLUICtrl* ctrl, void* data);
+
+ static void processDirPeopleReply(LLMessageSystem* msg, void**);
+ static void processDirPlacesReply(LLMessageSystem* msg, void**);
+ static void processDirEventsReply(LLMessageSystem* msg, void**);
+ static void processDirGroupsReply(LLMessageSystem* msg, void**);
+ static void processDirClassifiedReply(LLMessageSystem* msg, void**);
+ static void processDirLandReply(LLMessageSystem *msg, void**);
+
+ std::string filterShortWords( const std::string source_string, int shortest_word_length, bool& was_filtered );
+
+protected:
+ void updateResultCount();
+
+ void addClassified(LLCtrlListInterface *list, const LLUUID& classified_id, const std::string& name, const U32 creation_date, const S32 price_for_listing);
+ LLSD createLandSale(const LLUUID& parcel_id, bool is_auction, bool is_for_sale, const std::string& name, S32 *type);
+
+ static void onKeystrokeName(LLLineEditor* line, void* data);
+
+ // If this is a search for a panel like "people_panel" (and not the "all" panel)
+ // optionally show the "Next" button. Return the actual number of
+ // rows to display.
+ S32 showNextButton(S32 rows);
+
+protected:
+ LLUUID mSearchID; // Unique ID for a pending search
+ LLUUID mWantSelectID; // scroll item to select on arrival
+ std::string mCurrentSortColumn;
+ bool mCurrentSortAscending;
+ // Some searches return a max of 100 items per page, so we can
+ // start the search from the 100th item rather than the 0th, etc.
+ S32 mSearchStart;
+ // Places is 100 per page, events is 200 per page
+ S32 mResultsPerPage;
+ S32 mResultsReceived;
+
+ U32 mMinSearchChars;
+
+ LLSD mResultsContents;
+
+ bool mHaveSearchResults;
+ bool mDidAutoSelect;
+ LLFrameTimer mLastResultTimer;
+
+ LLFloaterDirectory* mFloaterDirectory;
+ LLButton* mPrevPageBtn;
+ LLButton* mNextPageBtn;
+};
+
+constexpr S32 RESULTS_PER_PAGE_DEFAULT = 100;
+constexpr S32 RESULTS_PER_PAGE_EVENTS = 200;
+
+// Codes used for sorting by type.
+const S32 INVALID_CODE = -1;
+const S32 EVENT_CODE = 0;
+const S32 PLACE_CODE = 1;
+// We no longer show online vs. offline in search result icons.
+//const S32 ONLINE_CODE = 2;
+//const S32 OFFLINE_CODE = 3;
+const S32 AVATAR_CODE = 3;
+const S32 GROUP_CODE = 4;
+const S32 CLASSIFIED_CODE = 5;
+const S32 FOR_SALE_CODE = 6; // for sale place
+const S32 AUCTION_CODE = 7; // for auction place
+const S32 POPULAR_CODE = 8; // popular by dwell
+
+// mask values for search flags
+const S32 SEARCH_NONE = 0; // should try not to send this to the search engine
+const S32 SEARCH_PG = 1;
+const S32 SEARCH_MATURE = 2;
+const S32 SEARCH_ADULT = 4;
+
+extern std::map<LLUUID, LLPanelDirBrowser*> gDirBrowserInstances;
+
+#endif // LL_LLPANELDIRBROWSER_H
diff --git a/indra/newview/llpaneldirclassified.cpp b/indra/newview/llpaneldirclassified.cpp
new file mode 100644
index 0000000000..ca625b956b
--- /dev/null
+++ b/indra/newview/llpaneldirclassified.cpp
@@ -0,0 +1,109 @@
+/**
+ * @file llpaneldirclassified.cpp
+ * @brief Classified panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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 "llpaneldirclassified.h"
+
+#include "llclassifiedflags.h"
+
+#include "llfontgl.h"
+#include "message.h"
+#include "llqueryflags.h"
+
+#include "llagent.h"
+#include "llbutton.h"
+#include "llcontrol.h"
+#include "llcombobox.h"
+#include "llclassifiedinfo.h"
+#include "lluiconstants.h"
+#include "llpaneldirbrowser.h"
+#include "lltextbox.h"
+
+#include "llcheckboxctrl.h"
+#include "llfloaterdirectory.h"
+#include "lllineeditor.h"
+#include "llsearcheditor.h"
+#include "llviewermenu.h"
+#include "llnotificationsutil.h"
+
+static LLPanelInjector<LLPanelDirClassified> t_panel_dir_classified("panel_dir_classified");
+
+LLPanelDirClassified::LLPanelDirClassified()
+: LLPanelDirBrowser()
+{
+}
+
+bool LLPanelDirClassified::postBuild()
+{
+ LLPanelDirBrowser::postBuild();
+
+ childSetAction("Search", onClickSearchCore, this);
+ setDefaultBtn("Search");
+ return true;
+}
+
+LLPanelDirClassified::~LLPanelDirClassified()
+{
+}
+
+void LLPanelDirClassified::performQuery()
+{
+ static LLUICachedControl<bool> inc_pg("ShowPGClassifieds", true);
+ static LLUICachedControl<bool> inc_mature("ShowMatureClassifieds", false);
+ static LLUICachedControl<bool> inc_adult("ShowAdultClassifieds", false);
+
+ if (!(inc_pg || inc_mature || inc_adult))
+ {
+ LLNotificationsUtil::add("NoContentToSearch");
+ return;
+ }
+
+ // This sets mSearchID and clears the list of results
+ setupNewSearch();
+
+ // send the message
+ LLMessageSystem *msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_DirClassifiedQuery);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+ bool filter_auto_renew = false;
+ U32 query_flags = pack_classified_flags_request(filter_auto_renew, inc_pg,
+ inc_mature && gAgent.canAccessMature(),
+ inc_adult && gAgent.canAccessAdult());
+ U32 category = childGetValue("Category").asInteger();
+
+ msg->nextBlockFast(_PREHASH_QueryData);
+ msg->addUUIDFast(_PREHASH_QueryID, mSearchID );
+ msg->addStringFast(_PREHASH_QueryText, childGetValue("name").asString());
+ msg->addU32Fast(_PREHASH_QueryFlags, query_flags);
+ msg->addU32Fast(_PREHASH_Category, category);
+ msg->addS32Fast(_PREHASH_QueryStart,mSearchStart);
+
+ gAgent.sendReliableMessage();
+}
diff --git a/indra/newview/llpaneldirclassified.h b/indra/newview/llpaneldirclassified.h
new file mode 100644
index 0000000000..6682f73929
--- /dev/null
+++ b/indra/newview/llpaneldirclassified.h
@@ -0,0 +1,55 @@
+/**
+ * @file llpaneldirclassified.h
+ * @brief Classified panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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_LLPANELDIRCLASSIFIED_H
+#define LL_LLPANELDIRCLASSIFIED_H
+
+#include "llpaneldirbrowser.h"
+
+// UI class forward declarations
+class LLButton;
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLLineEditor;
+class LLScrollListCtrl;
+
+class LLPanelDirClassified : public LLPanelDirBrowser
+{
+public:
+ LLPanelDirClassified();
+ /*virtual*/ ~LLPanelDirClassified();
+
+ bool postBuild();
+
+ // Request the classifieds from the database
+ void performQuery();
+
+protected:
+ // onClickNext and onClickPrev are special case searches
+ static void onClickSearch(void *userdata);
+};
+
+#endif
diff --git a/indra/newview/llpaneldirevents.cpp b/indra/newview/llpaneldirevents.cpp
new file mode 100644
index 0000000000..63eba04296
--- /dev/null
+++ b/indra/newview/llpaneldirevents.cpp
@@ -0,0 +1,248 @@
+/**
+ * @file llpaneldirevents.cpp
+ * @brief Events panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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 "llpaneldirevents.h"
+
+#include <sstream>
+
+// linden library includes
+#include "message.h"
+#include "llqueryflags.h"
+
+// viewer project includes
+#include "llagent.h"
+#include "llviewercontrol.h"
+#include "llnotificationsutil.h"
+#include "llpaneldirbrowser.h"
+#include "llresmgr.h"
+#include "lluiconstants.h"
+#include "llappviewer.h"
+
+static LLPanelInjector<LLPanelDirEvents> t_panel_dir_events("panel_dir_events");
+
+constexpr S32 DAY_TO_SEC = 24 * 60 * 60;
+
+LLPanelDirEvents::LLPanelDirEvents()
+ : LLPanelDirBrowser(),
+ mDay(0)
+{
+ // more results per page for this
+ mResultsPerPage = RESULTS_PER_PAGE_EVENTS;
+}
+
+bool LLPanelDirEvents::postBuild()
+{
+ LLPanelDirBrowser::postBuild();
+
+ childSetCommitCallback("date_mode", onDateModeCallback, this);
+
+ childSetAction("back_btn", onBackBtn, this);
+ childSetAction("forward_btn", onForwardBtn, this);
+
+ childSetCommitCallback("mature", onCommitMature, this);
+
+ childSetAction("Search", LLPanelDirBrowser::onClickSearchCore, this);
+ setDefaultBtn("Search");
+
+ onDateModeCallback(NULL, this);
+
+ mCurrentSortColumn = "time";
+
+ setDay(0); // for today
+
+ return TRUE;
+}
+
+LLPanelDirEvents::~LLPanelDirEvents()
+{
+}
+
+void LLPanelDirEvents::setDay(S32 day)
+{
+ mDay = day;
+
+ // Get time UTC
+ time_t utc_time = time_corrected();
+
+ // Correct for offset
+ utc_time += day * DAY_TO_SEC;
+
+ // There's only one internal tm buffer.
+ struct tm* internal_time;
+
+ // Convert to Pacific, based on server's opinion of whether
+ // it's daylight savings time there.
+ internal_time = utc_to_pacific_time(utc_time, is_daylight_savings());
+
+ std::string buffer = llformat("%d/%d",
+ 1 + internal_time->tm_mon, // Jan = 0
+ internal_time->tm_mday); // 2001 = 101
+ childSetValue("date_text", buffer);
+}
+
+// virtual
+void LLPanelDirEvents::performQuery()
+{
+ // event_id 0 will perform no delete action.
+ performQueryOrDelete(0);
+}
+
+void LLPanelDirEvents::performQueryOrDelete(U32 event_id)
+{
+ S32 relative_day = mDay;
+ // Update the date field to show the date IN THE SERVER'S
+ // TIME ZONE, as that is what will be displayed in each event
+
+ // Get time UTC
+ time_t utc_time = time_corrected();
+
+ // Correct for offset
+ utc_time += relative_day * DAY_TO_SEC;
+
+ // There's only one internal tm buffer.
+ struct tm* internal_time;
+
+ // Convert to Pacific, based on server's opinion of whether
+ // it's daylight savings time there.
+ internal_time = utc_to_pacific_time(utc_time, is_daylight_savings());
+
+ std::string buffer = llformat("%d/%d",
+ 1 + internal_time->tm_mon, // Jan = 0
+ internal_time->tm_mday); // 2001 = 101
+ childSetValue("date_text", buffer);
+
+ // Record the relative day so back and forward buttons
+ // offset from this day.
+ mDay = relative_day;
+
+ static LLUICachedControl<bool> incpg("ShowPGEvents", true);
+ static LLUICachedControl<bool> incmature("ShowMatureEvents", false);
+ static LLUICachedControl<bool> incadult("ShowAdultEvents", false);
+
+ U32 scope = DFQ_DATE_EVENTS;
+ if (incpg) scope |= DFQ_INC_PG;
+ if (incmature && gAgent.canAccessMature()) scope |= DFQ_INC_MATURE;
+ if (incadult && gAgent.canAccessAdult()) scope |= DFQ_INC_ADULT;
+
+ if ( !( scope & (DFQ_INC_PG | DFQ_INC_MATURE | DFQ_INC_ADULT )))
+ {
+ LLNotificationsUtil::add("NoContentToSearch");
+ return;
+ }
+
+ setupNewSearch();
+
+ std::ostringstream params;
+
+ // Date mode for the search
+ if ("current" == childGetValue("date_mode").asString())
+ {
+ params << "u|";
+ }
+ else
+ {
+ params << mDay << "|";
+ }
+
+ // Categories are stored in the database in table indra.event_category
+ // XML must match.
+ U32 cat_id = childGetValue("category_combo").asInteger();
+
+ params << cat_id << "|";
+ params << childGetValue("event_search_text").asString();
+
+ // send the message
+ if (0 == event_id)
+ {
+ sendDirFindQuery(gMessageSystem, mSearchID, params.str(), scope, mSearchStart);
+ }
+ else
+ {
+ // This delete will also perform a query.
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_EventGodDelete);
+
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlockFast(_PREHASH_EventData);
+ msg->addU32Fast(_PREHASH_EventID, event_id);
+
+ msg->nextBlockFast(_PREHASH_QueryData);
+ msg->addUUIDFast(_PREHASH_QueryID, mSearchID);
+ msg->addStringFast(_PREHASH_QueryText, params.str());
+ msg->addU32Fast(_PREHASH_QueryFlags, scope);
+ msg->addS32Fast(_PREHASH_QueryStart, mSearchStart);
+ gAgent.sendReliableMessage();
+ }
+}
+
+// static
+void LLPanelDirEvents::onDateModeCallback(LLUICtrl* ctrl, void *data)
+{
+ LLPanelDirEvents* self = (LLPanelDirEvents*)data;
+ if (self->childGetValue("date_mode").asString() == "date")
+ {
+ self->childEnable("forward_btn");
+ self->childEnable("back_btn");
+ }
+ else
+ {
+ self->childDisable("forward_btn");
+ self->childDisable("back_btn");
+ }
+}
+
+// static
+void LLPanelDirEvents::onBackBtn(void* data)
+{
+ LLPanelDirEvents* self = (LLPanelDirEvents*)data;
+ self->resetSearchStart();
+ self->setDay(self->mDay - 1);
+ self->performQuery();
+}
+
+
+// static
+void LLPanelDirEvents::onForwardBtn(void* data)
+{
+ LLPanelDirEvents* self = (LLPanelDirEvents*)data;
+ self->resetSearchStart();
+ self->setDay(self->mDay + 1);
+ self->performQuery();
+}
+
+
+// static
+void LLPanelDirEvents::onCommitMature(LLUICtrl* ctrl, void* data)
+{
+ // just perform another search
+ onClickSearchCore(data);
+}
diff --git a/indra/newview/llpaneldirevents.h b/indra/newview/llpaneldirevents.h
new file mode 100644
index 0000000000..596abc5f0e
--- /dev/null
+++ b/indra/newview/llpaneldirevents.h
@@ -0,0 +1,61 @@
+/**
+ * @file llpaneldirevents.h
+ * @brief Events panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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_LLPANELDIREVENTS_H
+#define LL_LLPANELDIREVENTS_H
+
+#include "llpaneldirbrowser.h"
+
+class LLUICtrl;
+class LLPanelDirBrowser;
+
+class LLPanelDirEvents : public LLPanelDirBrowser
+{
+public:
+ LLPanelDirEvents();
+ virtual ~LLPanelDirEvents();
+
+ bool postBuild() override;
+
+ /*virtual*/ void performQuery() override;
+
+ void performQueryOrDelete(U32 event_id);
+
+ // pass 0 for today, 1 for tomorrow
+ void setDay(S32 day);
+
+protected:
+ static void onDateModeCallback(LLUICtrl* ctrl, void *data);
+ static void onBackBtn(void* data);
+ static void onForwardBtn(void* data);
+ static void onCommitMature(LLUICtrl* ctrl, void* data);
+
+protected:
+ S32 mDay; // 0 = today, 1 = tomorrow
+};
+
+
+#endif
diff --git a/indra/newview/llpaneldirgroups.cpp b/indra/newview/llpaneldirgroups.cpp
new file mode 100644
index 0000000000..992d92091c
--- /dev/null
+++ b/indra/newview/llpaneldirgroups.cpp
@@ -0,0 +1,90 @@
+/**
+ * @file llpaneldirgroups.cpp
+ * @brief Groups panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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 "llpaneldirgroups.h"
+
+#include "llagent.h"
+#include "llqueryflags.h"
+#include "llviewercontrol.h"
+#include "llsearcheditor.h"
+
+static LLPanelInjector<LLPanelDirGroups> t_panel_dir_groups("panel_dir_groups");
+
+LLPanelDirGroups::LLPanelDirGroups()
+ : LLPanelDirBrowser()
+{
+ mMinSearchChars = 3;
+}
+
+
+bool LLPanelDirGroups::postBuild()
+{
+ LLPanelDirBrowser::postBuild();
+
+ //getChild<LLLineEditor>("name")->setKeystrokeCallback(boost::bind(&LLPanelDirBrowser::onKeystrokeName, _1, _2), NULL);
+
+ childSetAction("Search", &LLPanelDirBrowser::onClickSearchCore, this);
+ setDefaultBtn( "Search" );
+
+ return true;
+}
+
+LLPanelDirGroups::~LLPanelDirGroups()
+{
+}
+
+// virtual
+void LLPanelDirGroups::performQuery()
+{
+ if (childGetValue("name").asString().length() < mMinSearchChars)
+ {
+ return;
+ }
+
+ setupNewSearch();
+
+ // groups
+ U32 scope = DFQ_GROUPS;
+
+ // Check group mature filter.
+ if ( !gSavedSettings.getBOOL("ShowMatureGroups") || gAgent.isTeen() )
+ {
+ scope |= DFQ_FILTER_MATURE;
+ }
+
+ mCurrentSortColumn = "score";
+ mCurrentSortAscending = false;
+
+ // send the message
+ sendDirFindQuery(
+ gMessageSystem,
+ mSearchID,
+ childGetValue("name").asString(),
+ scope,
+ mSearchStart);
+}
diff --git a/indra/newview/llpaneldirgroups.h b/indra/newview/llpaneldirgroups.h
new file mode 100644
index 0000000000..1e10353e2a
--- /dev/null
+++ b/indra/newview/llpaneldirgroups.h
@@ -0,0 +1,45 @@
+/**
+ * @file llpaneldirgroups.h
+ * @brief Groups panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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 LLPANELDIRGROUPS_H
+#define LLPANELDIRGROUPS_H
+
+#include "llpaneldirbrowser.h"
+
+class LLPanelDirGroups : public LLPanelDirBrowser
+{
+public:
+ LLPanelDirGroups();
+ virtual ~LLPanelDirGroups();
+
+ /*virtual*/ bool postBuild();
+
+ /*virtual*/ void performQuery();
+
+ static void onClickSearch(void *userdata);
+};
+
+#endif
diff --git a/indra/newview/llpaneldirland.cpp b/indra/newview/llpaneldirland.cpp
new file mode 100644
index 0000000000..c4809fc2a6
--- /dev/null
+++ b/indra/newview/llpaneldirland.cpp
@@ -0,0 +1,247 @@
+/**
+ * @file llpaneldirland.cpp
+ * @brief Land panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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 "llpaneldirland.h"
+
+#include "llagent.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llqueryflags.h"
+#include "llscrolllistctrl.h"
+#include "llstatusbar.h"
+#include "lltextbox.h"
+#include "llviewercontrol.h"
+#include "llviewermessage.h"
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+static const char FIND_ALL[] = "All Types";
+static const char FIND_AUCTION[] = "Auction";
+static const char FIND_MAINLANDSALES[] = "Mainland Sales";
+static const char FIND_ESTATESALES[] = "Estate Sales";
+
+static LLPanelInjector<LLPanelDirLand> t_panel_dir_land("panel_dir_land");
+
+LLPanelDirLand::LLPanelDirLand()
+ : LLPanelDirBrowser()
+{
+}
+
+bool LLPanelDirLand::postBuild()
+{
+ LLPanelDirBrowser::postBuild();
+
+ childSetValue("type", gSavedSettings.getString("FindLandType"));
+
+ bool adult_enabled = gAgent.canAccessAdult();
+ bool mature_enabled = gAgent.canAccessMature();
+ childSetVisible("incpg", true);
+ if (!mature_enabled)
+ {
+ childSetValue("incmature", FALSE);
+ childDisable("incmature");
+ }
+ if (!adult_enabled)
+ {
+ childSetValue("incadult", FALSE);
+ childDisable("incadult");
+ }
+
+ childSetCommitCallback("pricecheck", onCommitPrice, this);
+ childSetCommitCallback("areacheck", onCommitArea, this);
+
+ if (gStatusBar)
+ {
+ childSetValue("priceedit", gStatusBar->getBalance());
+ }
+ childSetEnabled("priceedit", gSavedSettings.getBOOL("FindLandPrice"));
+ LLLineEditor* priceedit = getChild<LLLineEditor>("priceedit");
+ priceedit->setPrevalidateInput(LLTextValidate::validateNonNegativeS32);
+
+ childSetEnabled("areaedit", gSavedSettings.getBOOL("FindLandArea"));
+ LLLineEditor* areaedit = getChild<LLLineEditor>("areaedit");
+ areaedit->setPrevalidateInput(LLTextValidate::validateNonNegativeS32);
+
+ childSetAction("Search", onClickSearchCore, this);
+ setDefaultBtn("Search");
+
+ mCurrentSortColumn = "per_meter";
+
+ LLScrollListCtrl* results = getChild<LLScrollListCtrl>("results");
+ if (results)
+ {
+ results->setSortChangedCallback(boost::bind(&LLPanelDirLand::onClickSort, this));
+ results->sortByColumn(mCurrentSortColumn,mCurrentSortAscending);
+ }
+
+ return TRUE;
+}
+
+LLPanelDirLand::~LLPanelDirLand()
+{
+ // Children all cleaned up by default view destructor.
+}
+
+void LLPanelDirLand::onClickSort()
+{
+ performQuery();
+}
+
+// static
+void LLPanelDirLand::onCommitPrice(LLUICtrl* ctrl, void* data)
+{
+ LLPanelDirLand* self = (LLPanelDirLand*)data;
+ LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl;
+
+ if (!self || !check) return;
+ self->childSetEnabled("priceedit", check->get());
+}
+
+// static
+void LLPanelDirLand::onCommitArea(LLUICtrl* ctrl, void* data)
+{
+ LLPanelDirLand* self = (LLPanelDirLand*)data;
+ LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl;
+
+ if (!self || !check) return;
+ self->childSetEnabled("areaedit", check->get());
+}
+
+void LLPanelDirLand::performQuery()
+{
+ static LLUICachedControl<bool> inc_pg("ShowPGLand", true);
+ static LLUICachedControl<bool> inc_mature("ShowMatureLand", false);
+ static LLUICachedControl<bool> inc_adult("ShowAdultLand", false);
+ if (!(inc_pg || inc_mature || inc_adult))
+ {
+ LLNotificationsUtil::add("NoContentToSearch");
+ return;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+
+ setupNewSearch();
+
+ // We could change the UI to allow arbitrary combinations of these options
+ U32 search_type = ST_ALL;
+ const std::string& type = childGetValue("type").asString();
+ if(!type.empty())
+ {
+ if (FIND_AUCTION == type) search_type = ST_AUCTION;
+ else if(FIND_MAINLANDSALES == type) search_type = ST_MAINLAND;
+ else if(FIND_ESTATESALES == type) search_type = ST_ESTATE;
+ }
+
+ U32 query_flags = 0x0;
+ if (gAgent.wantsPGOnly()) query_flags |= DFQ_PG_SIMS_ONLY;
+
+ bool adult_enabled = gAgent.canAccessAdult();
+ bool mature_enabled = gAgent.canAccessMature();
+
+ if (inc_pg)
+ {
+ query_flags |= DFQ_INC_PG;
+ }
+
+ if (inc_mature && mature_enabled)
+ {
+ query_flags |= DFQ_INC_MATURE;
+ }
+
+ if (inc_adult && adult_enabled)
+ {
+ query_flags |= DFQ_INC_ADULT;
+ }
+
+ // Add old flags in case we are talking to an old dataserver
+ if (inc_pg && !inc_mature)
+ {
+ query_flags |= DFQ_PG_SIMS_ONLY;
+ }
+
+ if (!inc_pg && inc_mature)
+ {
+ query_flags |= DFQ_MATURE_SIMS_ONLY;
+ }
+
+ LLScrollListCtrl* list = getChild<LLScrollListCtrl>("results");
+ if (list)
+ {
+ std::string sort_name = list->getSortColumnName();
+ BOOL sort_asc = list->getSortAscending();
+
+ if (sort_name == "name")
+ {
+ query_flags |= DFQ_NAME_SORT;
+ }
+ else if (sort_name == "price")
+ {
+ query_flags |= DFQ_PRICE_SORT;
+ }
+ else if (sort_name == "per_meter")
+ {
+ query_flags |= DFQ_PER_METER_SORT;
+ }
+ else if (sort_name == "area")
+ {
+ query_flags |= DFQ_AREA_SORT;
+ }
+
+ if (sort_asc)
+ {
+ query_flags |= DFQ_SORT_ASC;
+ }
+ }
+
+ if (childGetValue("pricecheck").asBoolean())
+ {
+ query_flags |= DFQ_LIMIT_BY_PRICE;
+ }
+
+ if (childGetValue("areacheck").asBoolean())
+ {
+ query_flags |= DFQ_LIMIT_BY_AREA;
+ }
+
+ msg->newMessage("DirLandQuery");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("QueryData");
+ msg->addUUID("QueryID", getSearchID());
+ msg->addU32("QueryFlags", query_flags);
+ msg->addU32("SearchType", search_type);
+ msg->addS32("Price", childGetValue("priceedit").asInteger());
+ msg->addS32("Area", childGetValue("areaedit").asInteger());
+ msg->addS32Fast(_PREHASH_QueryStart,mSearchStart);
+ gAgent.sendReliableMessage();
+}
diff --git a/indra/newview/llpaneldirland.h b/indra/newview/llpaneldirland.h
new file mode 100644
index 0000000000..197c4cdc3d
--- /dev/null
+++ b/indra/newview/llpaneldirland.h
@@ -0,0 +1,53 @@
+/**
+ * @file llpaneldirland.h
+ * @brief Land panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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_LLPANELDIRLAND_H
+#define LL_LLPANELDIRLAND_H
+
+#include "llpaneldirbrowser.h"
+
+class LLUICtrl;
+class LLPanelDirBrowser;
+
+class LLPanelDirLand : public LLPanelDirBrowser
+{
+public:
+ LLPanelDirLand();
+ /*virtual*/ ~LLPanelDirLand();
+
+ bool postBuild();
+
+ void performQuery();
+
+protected:
+ void onClickSort();
+ static void onCommitPrice(LLUICtrl* ctrl, void* data);
+ static void onCommitArea(LLUICtrl* ctrl, void* data);
+
+};
+
+
+#endif
diff --git a/indra/newview/llpaneldirpeople.cpp b/indra/newview/llpaneldirpeople.cpp
new file mode 100644
index 0000000000..6a55e3bc7c
--- /dev/null
+++ b/indra/newview/llpaneldirpeople.cpp
@@ -0,0 +1,105 @@
+/**
+ * @file llpaneldirpeople.cpp
+ * @brief People panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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 "llpaneldirpeople.h"
+#include "llviewerwindow.h"
+#include "llsearcheditor.h"
+
+// viewer project includes
+#include "llqueryflags.h"
+#include "llnotificationsutil.h"
+
+static LLPanelInjector<LLPanelDirPeople> t_panel_dir_people("panel_dir_people");
+
+LLPanelDirPeople::LLPanelDirPeople()
+: LLPanelDirBrowser()
+{
+ mMinSearchChars = 3;
+}
+
+bool LLPanelDirPeople::postBuild()
+{
+ LLPanelDirBrowser::postBuild();
+
+ //getChild<LLLineEditor>("name")->setKeystrokeCallback(boost::bind(&LLPanelDirBrowser::onKeystrokeName, _1, _2), NULL);
+
+ childSetAction("Search", &LLPanelDirBrowser::onClickSearchCore, this);
+ setDefaultBtn( "Search" );
+
+ return true;
+}
+
+LLPanelDirPeople::~LLPanelDirPeople()
+{
+}
+
+// virtual
+void LLPanelDirPeople::performQuery()
+{
+ if (childGetValue("name").asString().length() < mMinSearchChars)
+ {
+ return;
+ }
+
+ // filter short words out of the query string
+ // and indidate if we did have to filter it
+ // The shortest username is 2 characters long.
+ const S32 SHORTEST_WORD_LEN = 2;
+ bool query_was_filtered = false;
+ std::string query_string = LLPanelDirBrowser::filterShortWords(
+ childGetValue("name").asString(),
+ SHORTEST_WORD_LEN,
+ query_was_filtered );
+
+ // possible we threw away all the short words in the query so check length
+ if ( query_string.length() < mMinSearchChars )
+ {
+ LLNotificationsUtil::add("SeachFilteredOnShortWordsEmpty");
+ return;
+ };
+
+ // if we filtered something out, display a popup
+ if ( query_was_filtered )
+ {
+ LLSD args;
+ args["FINALQUERY"] = query_string;
+ LLNotificationsUtil::add("SeachFilteredOnShortWords", args);
+ };
+
+ setupNewSearch();
+
+ U32 scope = DFQ_PEOPLE;
+
+ // send the message
+ sendDirFindQuery(
+ gMessageSystem,
+ mSearchID,
+ query_string,
+ scope,
+ mSearchStart);
+}
diff --git a/indra/newview/llpaneldirpeople.h b/indra/newview/llpaneldirpeople.h
new file mode 100644
index 0000000000..a8a7d17cb2
--- /dev/null
+++ b/indra/newview/llpaneldirpeople.h
@@ -0,0 +1,48 @@
+/**
+ * @file llpaneldirpeople.h
+ * @brief People panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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_LLPANELDIRPEOPLE_H
+#define LL_LLPANELDIRPEOPLE_H
+
+#include "llpaneldirbrowser.h"
+class LLLineEditor;
+class LLFloaterDirectory;
+
+class LLPanelDirPeople : public LLPanelDirBrowser
+{
+public:
+ LLPanelDirPeople();
+ virtual ~LLPanelDirPeople();
+
+ /*virtual*/ bool postBuild();
+
+ /*virtual*/ void performQuery();
+
+ static void onClickSearch(void *userdata);
+ static void onKeystrokeName(LLLineEditor* line, void* data);
+};
+
+#endif
diff --git a/indra/newview/llpaneldirplaces.cpp b/indra/newview/llpaneldirplaces.cpp
new file mode 100644
index 0000000000..2d54566038
--- /dev/null
+++ b/indra/newview/llpaneldirplaces.cpp
@@ -0,0 +1,185 @@
+/**
+ * @file llpaneldirplaces.cpp
+ * @brief Places panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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 "llpaneldirplaces.h"
+
+#include "message.h"
+#include "llparcel.h"
+#include "llregionflags.h"
+#include "llqueryflags.h"
+
+#include "llagent.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llfloaterdirectory.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llpaneldirbrowser.h"
+#include "llsearcheditor.h"
+#include "lltextbox.h"
+#include "llviewercontrol.h"
+
+static LLPanelInjector<LLPanelDirPlaces> t_panel_dir_people("panel_dir_places");
+
+LLPanelDirPlaces::LLPanelDirPlaces()
+ : LLPanelDirBrowser()
+{
+ mMinSearchChars = 3;
+}
+
+bool LLPanelDirPlaces::postBuild()
+{
+ LLPanelDirBrowser::postBuild();
+
+ //getChild<LLLineEditor>("name")->setKeystrokeCallback(boost::bind(&LLPanelDirBrowser::onKeystrokeName, _1, _2), NULL);
+
+ childSetAction("Search", &LLPanelDirBrowser::onClickSearchCore, this);
+ setDefaultBtn("Search");
+
+ mCurrentSortColumn = "dwell";
+ mCurrentSortAscending = false;
+
+ return true;
+}
+
+LLPanelDirPlaces::~LLPanelDirPlaces()
+{
+}
+
+// virtual
+void LLPanelDirPlaces::performQuery()
+{
+ std::string place_name = childGetValue("name").asString();
+ if (place_name.length() < mMinSearchChars)
+ {
+ return;
+ }
+
+ // "hi " is three chars but not a long-enough search
+ std::string query_string = place_name;
+ LLStringUtil::trim( query_string );
+ bool query_was_filtered = (query_string != place_name);
+
+ // possible we threw away all the short words in the query so check length
+ if ( query_string.length() < mMinSearchChars )
+ {
+ LLNotificationsUtil::add("SeachFilteredOnShortWordsEmpty");
+ return;
+ };
+
+ // if we filtered something out, display a popup
+ if ( query_was_filtered )
+ {
+ LLSD args;
+ args["FINALQUERY"] = query_string;
+ LLNotificationsUtil::add("SeachFilteredOnShortWords", args);
+ };
+
+ std::string catstring = childGetValue("Category").asString();
+
+ // Because LLParcel::C_ANY is -1, must do special check
+ S32 category = 0;
+ if (catstring == "any")
+ {
+ category = LLParcel::C_ANY;
+ }
+ else
+ {
+ category = LLParcel::getCategoryFromString(catstring);
+ }
+
+ U32 flags = 0x0;
+ bool adult_enabled = gAgent.canAccessAdult();
+ bool mature_enabled = gAgent.canAccessMature();
+
+ static LLUICachedControl<bool> inc_pg("ShowPGSims", true);
+ static LLUICachedControl<bool> inc_mature("ShowMatureSims", false);
+ static LLUICachedControl<bool> inc_adult("ShowAdultSims", false);
+
+ if (inc_pg)
+ {
+ flags |= DFQ_INC_PG;
+ }
+
+ if (inc_mature && mature_enabled)
+ {
+ flags |= DFQ_INC_MATURE;
+ }
+
+ if (inc_adult && adult_enabled)
+ {
+ flags |= DFQ_INC_ADULT;
+ }
+
+ if (0x0 == flags)
+ {
+ LLNotificationsUtil::add("NoContentToSearch");
+ return;
+ }
+
+ queryCore(query_string, category, flags);
+}
+
+void LLPanelDirPlaces::initialQuery()
+{
+ // All Linden locations in PG/Mature sims, any name.
+ U32 flags = DFQ_INC_PG | DFQ_INC_MATURE;
+ queryCore(LLStringUtil::null, LLParcel::C_LINDEN, flags);
+}
+
+void LLPanelDirPlaces::queryCore(const std::string& name, S32 category, U32 flags)
+{
+ setupNewSearch();
+
+// JC: Sorting by dwell severely impacts the performance of the query.
+// Instead of sorting on the dataserver, we sort locally once the results
+// are received.
+// IW: Re-enabled dwell sort based on new 3-character minimum description
+// Hopefully we'll move to next-gen Find before this becomes a big problem
+
+ flags |= DFQ_DWELL_SORT;
+
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage("DirPlacesQuery");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("QueryData");
+ msg->addUUID("QueryID", getSearchID());
+ msg->addString("QueryText", name);
+ msg->addU32("QueryFlags", flags);
+ msg->addS8("Category", (S8)category);
+ // No longer support queries by region name, too many regions
+ // for combobox, no easy way to do autocomplete. JC
+ msg->addString("SimName", "");
+ msg->addS32Fast(_PREHASH_QueryStart,mSearchStart);
+ gAgent.sendReliableMessage();
+}
+
diff --git a/indra/newview/llpaneldirplaces.h b/indra/newview/llpaneldirplaces.h
new file mode 100644
index 0000000000..069414ebf5
--- /dev/null
+++ b/indra/newview/llpaneldirplaces.h
@@ -0,0 +1,51 @@
+/**
+ * @file llpaneldirplaces.h
+ * @brief Places panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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_LLPANELDIRPLACES_H
+#define LL_LLPANELDIRPLACES_H
+
+#include "llpaneldirbrowser.h"
+
+class LLLineEditor;
+
+class LLPanelDirPlaces : public LLPanelDirBrowser
+{
+public:
+ LLPanelDirPlaces();
+ virtual ~LLPanelDirPlaces();
+
+ bool postBuild() override;
+
+ void performQuery() override;
+
+ // Initially fill in some data for the panel.
+ void initialQuery();
+
+private:
+ void queryCore(const std::string& name, S32 category, U32 flags);
+};
+
+#endif
diff --git a/indra/newview/llpaneldirweb.cpp b/indra/newview/llpaneldirweb.cpp
new file mode 100644
index 0000000000..9e76bb81a6
--- /dev/null
+++ b/indra/newview/llpaneldirweb.cpp
@@ -0,0 +1,148 @@
+/**
+ * @file llpaneldirweb.cpp
+ * @brief Web panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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 "llpaneldirweb.h"
+
+#include "llagent.h"
+#include "llbutton.h"
+#include "llfloaterdirectory.h"
+#include "lltextbox.h"
+#include "llviewercontrol.h"
+#include "llweb.h"
+
+static LLPanelInjector<LLPanelDirWeb> t_panel_dir_web("panel_dir_web");
+
+LLPanelDirWeb::LLPanelDirWeb()
+: LLPanel(),
+ mFloaterDirectory(nullptr),
+ mWebBrowser(nullptr)
+{
+}
+
+bool LLPanelDirWeb::postBuild()
+{
+ childSetAction("home_btn", onClickHome, this);
+
+ mBtnBack = getChild<LLButton>("back_btn");
+ mBtnForward = getChild<LLButton>("forward_btn");
+ mStatusBarText = getChild<LLTextBox>("statusbartext");
+
+ mBtnBack->setClickedCallback([this](LLUICtrl*, const LLSD&) { mWebBrowser->navigateBack(); });
+ mBtnForward->setClickedCallback([this](LLUICtrl*, const LLSD&) { mWebBrowser->navigateForward(); });
+
+ mWebBrowser = findChild<LLMediaCtrl>("web_search");
+ navigateToDefaultPage();
+ mWebBrowser->addObserver(this);
+
+ return true;
+}
+
+void LLPanelDirWeb::draw()
+{
+ // Asynchronous so we need to keep checking
+ mBtnBack->setEnabled(mWebBrowser->canNavigateBack());
+ mBtnForward->setEnabled(mWebBrowser->canNavigateForward());
+
+ LLPanel::draw();
+}
+
+LLPanelDirWeb::~LLPanelDirWeb()
+{
+}
+
+// When we show any browser-based view, we want to hide all
+// the right-side XUI detail panels.
+// virtual
+void LLPanelDirWeb::onVisibilityChange(bool new_visibility)
+{
+ if (new_visibility && mFloaterDirectory)
+ {
+ mFloaterDirectory->hideAllDetailPanels();
+ }
+ LLPanel::onVisibilityChange(new_visibility);
+}
+
+void LLPanelDirWeb::navigateToDefaultPage()
+{
+ std::string url = gSavedSettings.getString("SearchURL");
+
+ LLSD subs;
+ subs["QUERY"] = "";
+ subs["TYPE"] = "standard";
+ // Default to PG
+ std::string maturity = "g";
+ if (gAgent.prefersAdult())
+ {
+ // PG,Mature,Adult
+ maturity = "gma";
+ }
+ else if (gAgent.prefersMature())
+ {
+ // PG,Mature
+ maturity = "gm";
+ }
+ subs["MATURITY"] = maturity;
+ url = LLWeb::expandURLSubstitutions(url, subs);
+ mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+}
+
+// static
+void LLPanelDirWeb::onClickHome( void* data )
+{
+ LLPanelDirWeb* self = (LLPanelDirWeb*)data;
+ if (!self)
+ return;
+ self->navigateToDefaultPage();
+}
+
+void LLPanelDirWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ if (event == MEDIA_EVENT_LOCATION_CHANGED)
+ {
+ const std::string url = self->getLocation();
+ if (url.length())
+ mStatusBarText->setText(url);
+ }
+ else if (event == MEDIA_EVENT_NAVIGATE_COMPLETE)
+ {
+ // we populate the status bar with URLs as they change so clear it now we're done
+ const std::string end_str = "";
+ mStatusBarText->setText(end_str);
+ }
+ else if (event == MEDIA_EVENT_STATUS_TEXT_CHANGED)
+ {
+ const std::string text = self->getStatusText();
+ if (text.length())
+ mStatusBarText->setText(text);
+ }
+ else if (event == MEDIA_EVENT_LINK_HOVERED)
+ {
+ const std::string link = self->getHoverLink();
+ mStatusBarText->setText(link);
+ }
+}
diff --git a/indra/newview/llpaneldirweb.h b/indra/newview/llpaneldirweb.h
new file mode 100644
index 0000000000..db7bdc4a6a
--- /dev/null
+++ b/indra/newview/llpaneldirweb.h
@@ -0,0 +1,63 @@
+/**
+ * @file llpaneldirweb.h
+ * @brief Web panel in the legacy Search directory.
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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_LLPANELDIRWEB_H
+#define LL_LLPANELDIRWEB_H
+
+#include "llpanel.h"
+#include "llmediactrl.h"
+
+class LLTextBox;
+class LLFloaterDirectory;
+class LLWebBrowserCtrlObserver;
+
+class LLPanelDirWeb : public LLPanel, public LLViewerMediaObserver
+{
+public:
+ LLPanelDirWeb();
+ ~LLPanelDirWeb();
+
+ bool postBuild() override;
+ void onVisibilityChange(bool new_visibility) override;
+ void draw() override;
+
+ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
+
+ void navigateToDefaultPage();
+
+ void setFloaterDirectory(LLFloaterDirectory* floater) { mFloaterDirectory = floater; }
+
+protected:
+ static void onClickHome( void* data );
+
+ LLButton* mBtnBack;
+ LLButton* mBtnForward;
+ LLTextBox* mStatusBarText;
+ LLFloaterDirectory* mFloaterDirectory;
+ LLMediaCtrl* mWebBrowser;
+};
+
+#endif
diff --git a/indra/newview/llpaneleventinfo.cpp b/indra/newview/llpaneleventinfo.cpp
new file mode 100644
index 0000000000..43b20b3851
--- /dev/null
+++ b/indra/newview/llpaneleventinfo.cpp
@@ -0,0 +1,195 @@
+/**
+ * @file llpaneleventinfo.cpp
+ * @brief Info panel for events in the legacy Search
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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 "llpaneleventinfo.h"
+
+#include "llagent.h"
+#include "llbutton.h"
+#include "lleventflags.h"
+#include "llfloaterreg.h"
+#include "llfloaterworldmap.h"
+#include "lltextbox.h"
+#include "llviewertexteditor.h"
+#include "llworldmap.h"
+
+static LLPanelInjector<LLPanelEventInfo> t_panel_event_info("panel_event_info");
+
+LLPanelEventInfo::LLPanelEventInfo()
+ : LLPanel()
+{
+}
+
+LLPanelEventInfo::~LLPanelEventInfo()
+{
+ if (mEventInfoConnection.connected())
+ {
+ mEventInfoConnection.disconnect();
+ }
+}
+
+bool LLPanelEventInfo::postBuild()
+{
+ mTBName = getChild<LLTextBox>("event_name");
+
+ mTBCategory = getChild<LLTextBox>("event_category");
+ mTBDate = getChild<LLTextBox>("event_date");
+ mTBDuration = getChild<LLTextBox>("event_duration");
+ mTBDesc = getChild<LLTextEditor>("event_desc");
+ mTBDesc->setWordWrap(true);
+
+ mTBRunBy = getChild<LLTextBox>("event_runby");
+ mTBLocation = getChild<LLTextBox>("event_location");
+ mTBCover = getChild<LLTextBox>("event_cover");
+
+ mTeleportBtn = getChild<LLButton>( "teleport_btn");
+ mTeleportBtn->setClickedCallback(boost::bind(&LLPanelEventInfo::onClickTeleport, this));
+
+ mMapBtn = getChild<LLButton>( "map_btn");
+ mMapBtn->setClickedCallback(boost::bind(&LLPanelEventInfo::onClickMap, this));
+
+ mNotifyBtn = getChild<LLButton>( "notify_btn");
+ mNotifyBtn->setClickedCallback(boost::bind(&LLPanelEventInfo::onClickNotify, this));
+
+ mEventInfoConnection = gEventNotifier.setEventInfoCallback(boost::bind(&LLPanelEventInfo::processEventInfoReply, this, _1));
+
+ return true;
+}
+
+void LLPanelEventInfo::setEventID(const U32 event_id)
+{
+ mEventID = event_id;
+
+ if (event_id != 0)
+ {
+ sendEventInfoRequest();
+ }
+}
+
+void LLPanelEventInfo::sendEventInfoRequest()
+{
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_EventInfoRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
+ msg->nextBlockFast(_PREHASH_EventData);
+ msg->addU32Fast(_PREHASH_EventID, mEventID);
+ gAgent.sendReliableMessage();
+}
+
+bool LLPanelEventInfo::processEventInfoReply(LLEventInfo event)
+{
+ if (event.mID != getEventID())
+ return false;
+
+ mTBName->setText(event.mName);
+ mTBName->setToolTip(event.mName);
+ mTBCategory->setText(event.mCategoryStr);
+ mTBDate->setText(event.mTimeStr);
+ mTBDesc->setText(event.mDesc);
+ mTBRunBy->setText(LLSLURL("agent", event.mRunByID, "inspect").getSLURLString());
+
+ mTBDuration->setText(llformat("%d:%.2d", event.mDuration / 60, event.mDuration % 60));
+
+ if (!event.mHasCover)
+ {
+ mTBCover->setText(getString("none"));
+ }
+ else
+ {
+ mTBCover->setText(llformat("%d", event.mCover));
+ }
+
+ mTBLocation->setText(LLSLURL(event.mSimName, event.mPosGlobal).getSLURLString());
+
+ if (event.mEventFlags & EVENT_FLAG_MATURE)
+ {
+ childSetVisible("event_mature_yes", true);
+ childSetVisible("event_mature_no", false);
+ }
+ else
+ {
+ childSetVisible("event_mature_yes", false);
+ childSetVisible("event_mature_no", true);
+ }
+
+ if (event.mUnixTime < time_corrected())
+ {
+ mNotifyBtn->setEnabled(false);
+ }
+ else
+ {
+ mNotifyBtn->setEnabled(true);
+ }
+
+ if (gEventNotifier.hasNotification(event.mID))
+ {
+ mNotifyBtn->setLabel(getString("dont_notify"));
+ }
+ else
+ {
+ mNotifyBtn->setLabel(getString("notify"));
+ }
+ mEventInfo = event;
+ return true;
+}
+
+void LLPanelEventInfo::onClickTeleport()
+{
+ LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance();
+ if (world_map)
+ {
+ world_map->trackLocation(mEventInfo.mPosGlobal);
+ gAgent.teleportViaLocation(mEventInfo.mPosGlobal);
+ }
+}
+
+void LLPanelEventInfo::onClickMap()
+{
+ LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance();
+ if (world_map)
+ {
+ world_map->trackLocation(mEventInfo.mPosGlobal);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+}
+
+void LLPanelEventInfo::onClickNotify()
+{
+ if (!gEventNotifier.hasNotification(mEventID))
+ {
+ gEventNotifier.add(mEventInfo.mID, mEventInfo.mUnixTime, mEventInfo.mTimeStr, mEventInfo.mName);
+ mNotifyBtn->setLabel(getString("dont_notify"));
+ }
+ else
+ {
+ gEventNotifier.remove(mEventInfo.mID);
+ mNotifyBtn->setLabel(getString("notify"));
+ }
+}
diff --git a/indra/newview/llpaneleventinfo.h b/indra/newview/llpaneleventinfo.h
new file mode 100644
index 0000000000..4f0e547493
--- /dev/null
+++ b/indra/newview/llpaneleventinfo.h
@@ -0,0 +1,76 @@
+/**
+ * @file llpaneleventinfo.h
+ * @brief Info panel for events in the legacy Search
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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_LLPANELEVENTINFO_H
+#define LL_LLPANELEVENTINFO_H
+
+#include "lleventnotifier.h"
+
+class LLTextBox;
+class LLTextEditor;
+class LLButton;
+
+class LLPanelEventInfo : public LLPanel
+{
+public:
+ LLPanelEventInfo();
+ /*virtual*/ ~LLPanelEventInfo();
+
+ /*virtual*/ bool postBuild() override;
+
+ void setEventID(const U32 event_id);
+ void sendEventInfoRequest();
+
+ bool processEventInfoReply(LLEventInfo event);
+
+ U32 getEventID() { return mEventID; }
+
+protected:
+ void onClickTeleport();
+ void onClickMap();
+ void onClickNotify();
+
+protected:
+ LLTextBox* mTBName;
+ LLTextBox* mTBCategory;
+ LLTextBox* mTBDate;
+ LLTextBox* mTBDuration;
+ LLTextEditor* mTBDesc;
+
+ LLTextBox* mTBRunBy;
+ LLTextBox* mTBLocation;
+ LLTextBox* mTBCover;
+
+ LLButton* mTeleportBtn;
+ LLButton* mMapBtn;
+ LLButton* mNotifyBtn;
+
+ U32 mEventID;
+ LLEventInfo mEventInfo;
+ boost::signals2::connection mEventInfoConnection;
+};
+
+#endif // LL_LLPANELEVENTINFO_H
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 65aa1876b0..ecb66f9cea 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -231,6 +231,12 @@ void LLPanelGroup::onBackBtnClick()
}
}
+void LLPanelGroup::hideBackBtn()
+{
+ childSetVisible("back", false);
+ setBackgroundVisible(false);
+}
+
void LLPanelGroup::onBtnRefresh(void* user_data)
{
LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index fa0e1d4104..b43a93bc40 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -87,6 +87,7 @@ public:
const std::string& inventory_name,
LLOfferInfo* inventory_offer);
+ void hideBackBtn();
protected:
virtual void update(LLGroupChange gc);
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index a9e860d2ef..2ddc09736f 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -1309,7 +1309,7 @@ void LLPanelOutfitEdit::showFilteredWearablesListView(LLWearableType::EType type
showWearablesListView();
//e_list_view_item_type implicitly contains LLWearableType::EType starting from LVIT_SHAPE
- applyListViewFilter(static_cast<EListViewItemType>(LVIT_SHAPE + type));
+ applyListViewFilter(static_cast<EListViewItemType>(static_cast<U32>(LVIT_SHAPE) + static_cast<U32>(type)));
mWearableItemsList->setMenuWearableType(type);
}
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 7deb1d9fd4..5435a79e16 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -651,7 +651,7 @@ void LLPanelPlaces::onFilterEdit(const std::string& search_string, bool force_fi
void LLPanelPlaces::onTabSelected()
{
mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel());
- if (!mActivePanel)
+ if (!mActivePanel || !mTabsCreated)
return;
onFilterEdit(mActivePanel->getFilterSubString(), true);
@@ -1335,6 +1335,13 @@ LLPanelPlaceInfo* LLPanelPlaces::getCurrentInfoPanel()
return NULL;
}
+void LLPanelPlaces::hideBackBtn()
+{
+ mPlaceProfileBackBtn->setVisible(false);
+ setBackgroundVisible(false);
+ mPlaceProfile->setBackgroundVisible(false);
+}
+
static bool is_agent_in_selected_parcel(LLParcel* parcel)
{
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index fc04d8d45d..8360380b22 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -81,6 +81,8 @@ public:
/*virtual*/ S32 notifyParent(const LLSD& info);
+ void hideBackBtn();
+
private:
void onLandmarkLoaded(LLLandmark* landmark);
void onFilterEdit(const std::string& search_string, bool force_filter);
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 6ea9cd2b92..ee94277ecc 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -693,6 +693,7 @@ LLPanelProfileSecondLife::LLPanelProfileSecondLife()
, mWaitingForImageUpload(false)
, mAllowPublish(false)
, mHideAge(false)
+ , mAllowEdit(true)
{
}
@@ -757,14 +758,15 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key)
LLUUID avatar_id = getAvatarId();
bool own_profile = getSelfProfile();
+ bool allow_edit = own_profile && mAllowEdit;
mGroupList->setShowNone(!own_profile);
- childSetVisible("notes_panel", !own_profile);
- childSetVisible("settings_panel", own_profile);
- childSetVisible("about_buttons_panel", own_profile);
+ childSetVisible("notes_panel", !allow_edit);
+ childSetVisible("settings_panel", allow_edit);
+ childSetVisible("about_buttons_panel", allow_edit);
- if (own_profile)
+ if (allow_edit)
{
// Group list control cannot toggle ForAgent loading
// Less than ideal, but viewing own profile via search is edge case
@@ -789,7 +791,7 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key)
mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT);
}
- mDescriptionEdit->setParseHTML(!own_profile);
+ mDescriptionEdit->setParseHTML(!allow_edit);
if (!own_profile)
{
@@ -1280,7 +1282,7 @@ void LLPanelProfileSecondLife::setLoaded()
{
mHideAgeCombo->setEnabled(true);
}
- mDescriptionEdit->setEnabled(true);
+ mDescriptionEdit->setEnabled(mAllowEdit);
}
}
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index c207a4162a..f2e9c1341f 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -111,6 +111,8 @@ public:
void processProperties(void* data, EAvatarProcessorType type) override;
+ void setAllowEdit(bool allow_edit) { mAllowEdit = allow_edit; }
+
protected:
/**
* Process profile related data received from server.
@@ -207,6 +209,7 @@ private:
bool mWaitingForImageUpload;
bool mAllowPublish;
bool mHideAge;
+ bool mAllowEdit;
std::string mDescriptionText;
boost::signals2::connection mAvatarNameCacheConnection;
};
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 4762fc555d..a624682e11 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6614,7 +6614,7 @@ void LLSelectMgr::renderSilhouettes(bool for_hud)
gGL.popMatrix();
gGL.popMatrix();
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
if (shader)
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 6023f6885d..8329ed86da 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -364,7 +364,7 @@ bool LLSettingsVOBase::exportFile(const LLSettingsBase::ptr_t &settings, const s
{
try
{
- std::ofstream file(filename, std::ios::out | std::ios::trunc);
+ llofstream file(filename, std::ios::out | std::ios::trunc);
file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
if (!file)
@@ -390,7 +390,7 @@ LLSettingsBase::ptr_t LLSettingsVOBase::importFile(const std::string &filename)
try
{
- std::ifstream file(filename, std::ios::in);
+ llifstream file(filename, std::ios::in);
file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
if (!file)
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 9b6a87e68d..58a443ab23 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -238,11 +238,11 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4
{
F32 line_width ;
glGetFloatv(GL_LINE_WIDTH, &line_width) ;
- glLineWidth(2.0f * line_width) ;
+ gGL.setLineWidth(2.0f * line_width) ;
LLColor4 color(0.0f, 0.0f, 0.0f, 1.0f) ;
gl_rect_2d( mPreviewRect.mLeft + offset_x, mPreviewRect.mTop + offset_y,
mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, false ) ;
- glLineWidth(line_width) ;
+ gGL.setLineWidth(line_width) ;
//draw four alpha rectangles to cover areas outside of the snapshot image
if(!mKeepAspectRatio)
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index f3cfbd9565..2dc2810861 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1658,13 +1658,11 @@ void renderOctree(LLSpatialGroup* group)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
gGL.diffuseColor4f(1,0,0,group->mBuilt);
- gGL.flush();
- glLineWidth(5.f);
+ gGL.setLineWidth(5.f);
const LLVector4a* bounds = group->getObjectBounds();
drawBoxOutline(bounds[0], bounds[1]);
- gGL.flush();
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
gGL.flush();
const LLVOAvatar* lastAvatar = nullptr;
@@ -1973,13 +1971,11 @@ void renderBoundingBox(LLDrawable* drawable, bool set_color = true)
LLViewerObject* vobj = drawable->getVObj();
if (vobj && vobj->onActiveList())
{
- gGL.flush();
- glLineWidth(llmax(4.f*sinf(gFrameTimeSeconds*2.f)+1.f, 1.f));
- //glLineWidth(4.f*(sinf(gFrameTimeSeconds*2.f)*0.25f+0.75f));
+ gGL.setLineWidth(llmax(4.f*sinf(gFrameTimeSeconds*2.f)+1.f, 1.f));
+ //gGL.setLineWidth(4.f*(sinf(gFrameTimeSeconds*2.f)*0.25f+0.75f));
stop_glerror();
drawBoxOutline(pos,size);
- gGL.flush();
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
}
else
{
@@ -2491,12 +2487,11 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe
llassert(LLGLSLShader::sCurBoundShader != 0);
LLVertexBuffer::unbind();
- glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints);
gGL.diffuseColor4fv(color.mV);
-
gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
+
+ LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, nullptr, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
}
else
{
@@ -2888,8 +2883,7 @@ public:
if (i == 1)
{
- gGL.flush();
- glLineWidth(3.f);
+ gGL.setLineWidth(3.f);
}
gGL.begin(LLRender::TRIANGLES);
@@ -2907,8 +2901,7 @@ public:
if (i == 1)
{
- gGL.flush();
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
}
}
}
@@ -3625,12 +3618,11 @@ bool LLSpatialPartition::isVisible(const LLVector3& v)
return true;
}
-LL_ALIGN_PREFIX(16)
-class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>>
+class alignas(16) LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>>
{
public:
- LL_ALIGN_16(LLVector4a mStart);
- LL_ALIGN_16(LLVector4a mEnd);
+ LLVector4a mStart;
+ LLVector4a mEnd;
S32 *mFaceHit;
LLVector4a *mIntersection;
@@ -3780,7 +3772,7 @@ public:
return false;
}
-} LL_ALIGN_POSTFIX(16);
+};
LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
bool pick_transparent,
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 3aaa3d60e8..4ca1ef7c7a 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -64,7 +64,7 @@ void pushVerts(LLFace* face);
Make every effort to keep size minimal.
Member ordering is important for cache coherency
*/
-class LLDrawInfo final : public LLRefCount
+class alignas(16) LLDrawInfo final : public LLRefCount
{
LL_ALIGN_NEW;
protected:
@@ -198,12 +198,13 @@ public:
};
};
-LL_ALIGN_PREFIX(16)
-class LLSpatialGroup : public LLOcclusionCullingGroup
+class alignas(16) LLSpatialGroup : public LLOcclusionCullingGroup
{
using super = LLOcclusionCullingGroup;
friend class LLSpatialPartition;
friend class LLOctreeStateCheck;
+
+ LL_ALIGN_NEW
public:
LLSpatialGroup(const LLSpatialGroup& rhs) : LLOcclusionCullingGroup(rhs)
@@ -338,8 +339,8 @@ public:
virtual void rebound();
public:
- LL_ALIGN_16(LLVector4a mViewAngle);
- LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
+ LLVector4a mViewAngle;
+ LLVector4a mLastUpdateViewAngle;
protected:
virtual ~LLSpatialGroup();
@@ -369,7 +370,7 @@ public:
U32 mRenderOrder = 0;
// Reflection Probe associated with this node (if any)
LLPointer<LLReflectionMap> mReflectionProbe = nullptr;
-} LL_ALIGN_POSTFIX(16);
+};
class LLGeometryManager
{
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index ff875c4ddc..bbbe2aad23 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -122,6 +122,7 @@
#include "llpanellogin.h"
#include "llmutelist.h"
#include "llavatarpropertiesprocessor.h"
+#include "llpaneldirbrowser.h"
#include "llpanelgrouplandmoney.h"
#include "llpanelgroupnotices.h"
#include "llparcel.h"
@@ -182,7 +183,6 @@
#include "llnamelistctrl.h"
#include "llnamebox.h"
#include "llnameeditor.h"
-#include "llpostprocess.h"
#include "llagentlanguage.h"
#include "llwearable.h"
#include "llinventorybridge.h"
@@ -1347,10 +1347,6 @@ bool idle_startup()
LLDrawable::initClass();
do_startup_frame();
- // init the shader managers
- LLPostProcess::initClass();
- do_startup_frame();
-
LLAvatarAppearance::initClass("avatar_lad.xml","avatar_skeleton.xml");
do_startup_frame();
@@ -2837,6 +2833,13 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFuncFast(_PREHASH_AvatarPickerReply, LLFloaterAvatarPicker::processAvatarPickerReply);
+ msg->setHandlerFuncFast(_PREHASH_DirPlacesReply, LLPanelDirBrowser::processDirPlacesReply);
+ msg->setHandlerFuncFast(_PREHASH_DirPeopleReply, LLPanelDirBrowser::processDirPeopleReply);
+ msg->setHandlerFuncFast(_PREHASH_DirEventsReply, LLPanelDirBrowser::processDirEventsReply);
+ msg->setHandlerFuncFast(_PREHASH_DirGroupsReply, LLPanelDirBrowser::processDirGroupsReply);
+ msg->setHandlerFuncFast(_PREHASH_DirClassifiedReply, LLPanelDirBrowser::processDirClassifiedReply);
+ msg->setHandlerFuncFast(_PREHASH_DirLandReply, LLPanelDirBrowser::processDirLandReply);
+
msg->setHandlerFuncFast(_PREHASH_MapBlockReply, LLWorldMapMessage::processMapBlockReply);
msg->setHandlerFuncFast(_PREHASH_MapItemReply, LLWorldMapMessage::processMapItemReply);
msg->setHandlerFuncFast(_PREHASH_EventInfoReply, LLEventNotifier::processEventInfoReply);
diff --git a/indra/newview/llterrainpaintmap.cpp b/indra/newview/llterrainpaintmap.cpp
index c7a82013e4..f95f248139 100644
--- a/indra/newview/llterrainpaintmap.cpp
+++ b/indra/newview/llterrainpaintmap.cpp
@@ -107,7 +107,7 @@ bool LLTerrainPaintMap::bakeHeightNoiseIntoPBRPaintMapRGB(const LLViewerRegion&
const LLVector3 region_center = LLVector3(region_half_width, region_half_width, 0.0) + region.getOriginAgent();
const LLVector3 camera_origin = LLVector3(0.0f, 0.0f, region_camera_height) + region_center;
camera.lookAt(camera_origin, region_center, LLVector3::y_axis);
- camera.setAspect(F32(scratch_target.getHeight()) / F32(scratch_target.getWidth()));
+ camera.setAspect(F32(scratch_target.getWidth()) / F32(scratch_target.getHeight()));
const LLRect texture_rect(0, scratch_target.getHeight(), scratch_target.getWidth(), 0);
glViewport(texture_rect.mLeft, texture_rect.mBottom, texture_rect.getWidth(), texture_rect.getHeight());
// Manually get modelview matrix from camera orientation.
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 1a7ce74ccc..612af0d147 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -943,8 +943,6 @@ const char* fast_cache_filename = "FastCache.cache";
void LLTextureCache::setDirNames(ELLPath location)
{
- std::string delem = gDirUtilp->getDirDelimiter();
-
mHeaderEntriesFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, entries_filename);
mHeaderDataFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, cache_filename);
mTexturesDirName = gDirUtilp->getExpandedFilename(location, textures_dirname);
@@ -1345,21 +1343,26 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries)
}
aprfile->seek(APR_SET, (S32)sizeof(EntriesInfo));
}
- for (U32 idx=0; idx<num_entries; idx++)
+
+ U32 idx = 0;
+ try
{
- try
+ entries.resize(num_entries);
+ S32 total_entries_size = sizeof(Entry) * num_entries;
+ S32 bytes_read = aprfile->read((void*)entries.data(), total_entries_size);
+ if (bytes_read != total_entries_size)
{
- Entry entry;
- S32 bytes_read = aprfile->read((void*)(&entry), (S32)sizeof(Entry));
- if (bytes_read < sizeof(Entry))
- {
- LL_WARNS() << "Corrupted header entries, failed at " << idx << " / " << num_entries << LL_ENDL;
- closeHeaderEntriesFile();
- return 0;
- }
- entries.push_back(entry);
- // LL_INFOS() << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << LL_ENDL;
- if (entry.mImageSize > entry.mBodySize)
+ LL_WARNS() << "Corrupted header entries, expected " << total_entries_size << " bytes but got " << bytes_read << " bytes" << LL_ENDL;
+ closeHeaderEntriesFile();
+ purgeAllTextures(false);
+ return 0;
+ }
+
+ for (; idx < num_entries; idx++)
+ {
+ const Entry& entry = entries[idx];
+// LL_INFOS() << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << LL_ENDL;
+ if(entry.mImageSize > entry.mBodySize)
{
mHeaderIDMap[entry.mID] = idx;
mTexturesSizeMap[entry.mID] = entry.mBodySize;
@@ -1370,17 +1373,17 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries)
mFreeList.insert(idx);
}
}
- catch (std::bad_alloc&)
- {
- // Too little ram yet very large cache?
- // Should this actually crash viewer?
- entries.clear();
- LL_WARNS() << "Bad alloc trying to read texture entries from cache, mFreeList: " << (S32)mFreeList.size()
- << ", added entries: " << idx << ", total entries: " << num_entries << LL_ENDL;
- closeHeaderEntriesFile();
- purgeAllTextures(false);
- return 0;
- }
+ }
+ catch (const std::bad_alloc&)
+ {
+ // Too little ram yet very large cache?
+ // Should this actually crash viewer?
+ entries.clear();
+ LL_WARNS() << "Bad alloc trying to read texture entries from cache, mFreeList: " << (S32)mFreeList.size()
+ << ", added entries: " << idx << ", total entries: " << num_entries << LL_ENDL;
+ closeHeaderEntriesFile();
+ purgeAllTextures(false);
+ return 0;
}
closeHeaderEntriesFile();
return num_entries;
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 4e8320b72a..cbd63184e9 100644
--- a/indra/newview/llversioninfo.cpp
+++ b/indra/newview/llversioninfo.cpp
@@ -32,6 +32,8 @@
#include "llversioninfo.h"
#include "stringize.h"
+#include "llversioninfovars.h"
+
#if ! defined(LL_VIEWER_CHANNEL) \
|| ! defined(LL_VIEWER_VERSION_MAJOR) \
|| ! defined(LL_VIEWER_VERSION_MINOR) \
diff --git a/indra/newview/llversioninfovars.h.in b/indra/newview/llversioninfovars.h.in
new file mode 100644
index 0000000000..fe834406e6
--- /dev/null
+++ b/indra/newview/llversioninfovars.h.in
@@ -0,0 +1,31 @@
+/**
+ * @file llversioninfovars.h.in
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, 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$
+ */
+
+#define LL_VIEWER_CHANNEL @VIEWER_CHANNEL@
+#define LL_VIEWER_VERSION_MAJOR @VIEWER_VERSION_MAJOR@
+#define LL_VIEWER_VERSION_MINOR @VIEWER_VERSION_MINOR@
+#define LL_VIEWER_VERSION_PATCH @VIEWER_VERSION_PATCH@
+#define LL_VIEWER_VERSION_BUILD @VIEWER_VERSION_REVISION@
+#define LLBUILD_CONFIG "@CMAKE_BUILD_TYPE@"
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 75cc76fee6..411eb3a47e 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -293,9 +293,14 @@ static bool handleLUTBufferChanged(const LLSD& newvalue)
return true;
}
-static bool handleAnisotropicChanged(const LLSD& newvalue)
+static bool handleAnisotropicFilteringChanged(const LLSD& newval)
{
- LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean();
+ F32 val = static_cast<F32>(newval.asReal());
+ if (val > gGLManager.mMaxAnisotropy)
+ {
+ val = llclamp(val, 0.f, gGLManager.mMaxAnisotropy);
+ }
+ LLRender::sAnisotropicFilteringLevel = val;
LLImageGL::dirtyTexOptions();
return true;
}
@@ -317,6 +322,12 @@ static bool handleVSyncChanged(const LLSD& newvalue)
return true;
}
+static bool validateAnisotropicFiltering(const LLSD& val)
+{
+ S32 filter_level = val.asInteger();
+ return filter_level == 0 || filter_level == 2 || filter_level == 4 || filter_level == 8 || filter_level == 16;
+}
+
static bool handleVolumeLODChanged(const LLSD& newvalue)
{
LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR);
@@ -832,7 +843,8 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAnisotropicLevel", handleAnisotropicFilteringChanged);
+ gSavedSettings.getControl("RenderAnisotropicLevel")->getValidateSignal()->connect(boost::bind(&validateAnisotropicFiltering, _2));
setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized);
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 35ac7919ac..ce59e844ec 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -55,7 +55,6 @@
#include "llmemory.h"
#include "llparcel.h"
#include "llperfstats.h"
-#include "llpostprocess.h"
#include "llrender.h"
#include "llscenemonitor.h"
#include "llsdjson.h"
@@ -1074,7 +1073,7 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot)
LLGLSLShader::finishProfile(stats);
auto report_name = getProfileStatsFilename();
- std::ofstream outf(report_name);
+ llofstream outf(report_name);
if (! outf)
{
LL_WARNS() << "Couldn't write to " << std::quoted(report_name) << LL_ENDL;
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 107b3df831..c1843e7c7e 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -67,6 +67,7 @@
#include "llfloatercreatelandmark.h"
#include "llfloaterdeleteprefpreset.h"
#include "llfloaterdestinations.h"
+#include "llfloaterdirectory.h"
#include "llfloaterdisplayname.h"
#include "llfloatereditextdaycycle.h"
#include "llfloateremojipicker.h"
@@ -119,7 +120,6 @@
#include "llfloaterpay.h"
#include "llfloaterperformance.h"
#include "llfloaterperms.h"
-#include "llfloaterpostprocess.h"
#include "llfloaterpreference.h"
#include "llfloaterpreferencesgraphicsadvanced.h"
#include "llfloaterpreferenceviewadvanced.h"
@@ -232,7 +232,8 @@ public:
"upload_model",
"upload_script",
"upload_sound",
- "bulk_upload"
+ "bulk_upload",
+ "legacy_search"
};
return std::find(blacklist_clicked.begin(), blacklist_clicked.end(), fl_name) == blacklist_clicked.end();
}
@@ -284,7 +285,8 @@ public:
"upload_script",
"upload_sound",
"bulk_upload",
- "slapp_test"
+ "slapp_test",
+ "legacy_search"
};
return std::find(blacklist_untrusted.begin(), blacklist_untrusted.end(), fl_name) == blacklist_untrusted.end();
}
@@ -368,7 +370,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>);
@@ -506,6 +507,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
LLFloaterReg::add("simple_snapshot", "floater_simple_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleSnapshot>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
+ LLFloaterReg::add("legacy_search", "floater_directory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDirectory>);
LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);
LLFloaterReg::add("slapp_test", "floater_test_slapp.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSLappTest>);
diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h
index 7f52ca9623..57959ec2fc 100644
--- a/indra/newview/llviewerjoint.h
+++ b/indra/newview/llviewerjoint.h
@@ -39,9 +39,10 @@ class LLViewerJointMesh;
//-----------------------------------------------------------------------------
// class LLViewerJoint
//-----------------------------------------------------------------------------
-class LLViewerJoint :
+class alignas(16) LLViewerJoint :
public virtual LLAvatarJoint
{
+ LL_ALIGN_NEW
public:
LLViewerJoint();
LLViewerJoint(S32 joint_num);
diff --git a/indra/newview/llviewerjointattachment.h b/indra/newview/llviewerjointattachment.h
index fe66949f73..12075177b3 100644
--- a/indra/newview/llviewerjointattachment.h
+++ b/indra/newview/llviewerjointattachment.h
@@ -40,9 +40,10 @@ class LLViewerObject;
//-----------------------------------------------------------------------------
// class LLViewerJointAttachment
//-----------------------------------------------------------------------------
-class LLViewerJointAttachment :
+class alignas(16) LLViewerJointAttachment :
public LLViewerJoint
{
+ LL_ALIGN_NEW
public:
LLViewerJointAttachment();
virtual ~LLViewerJointAttachment();
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index da7ad71336..7870fe7823 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -56,12 +56,6 @@
#include "llmatrix4a.h"
#include "llperfstats.h"
-#if !LL_DARWIN && !LL_LINUX
-extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
-extern PFNGLWEIGHTFVARBPROC glWeightfvARB;
-extern PFNGLVERTEXBLENDARBPROC glVertexBlendARB;
-#endif
-
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLViewerJointMesh
@@ -242,8 +236,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, bool first_pass, bool is_dummy)
stop_glerror();
- LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), 0.f);
-
//----------------------------------------------------------------
// setup current texture
//----------------------------------------------------------------
diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h
index cfe8ecdb67..a3afd84d06 100644
--- a/indra/newview/llviewerjointmesh.h
+++ b/indra/newview/llviewerjointmesh.h
@@ -41,8 +41,9 @@ class LLViewerTexLayerSet;
//-----------------------------------------------------------------------------
// class LLViewerJointMesh
//-----------------------------------------------------------------------------
-class LLViewerJointMesh : public LLAvatarJointMesh, public LLViewerJoint
+class alignas(16) LLViewerJointMesh : public LLAvatarJointMesh, public LLViewerJoint
{
+ LL_ALIGN_NEW
public:
// Constructor
LLViewerJointMesh();
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 8f229850c0..34aa1b266c 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1819,6 +1819,13 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
}
else
{
+#if LL_LINUX
+ if(plugin_basename == "media_plugin_gstreamer10" && gSavedSettings.getBOOL("MediaPluginForceVLC"))
+ {
+ plugin_basename = "media_plugin_libvlc";
+ }
+#endif
+
std::string launcher_name = gDirUtilp->getLLPluginLauncher();
std::string plugin_name = gDirUtilp->getLLPluginFilename(plugin_basename);
@@ -1833,9 +1840,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
}
else if(LLFile::stat(plugin_name, &s))
{
-#if !LL_LINUX
LL_WARNS_ONCE("Media") << "Couldn't find plugin at " << plugin_name << LL_ENDL;
-#endif
}
else
{
@@ -1867,6 +1872,11 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");
media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled || clean_browser);
+#if LL_LINUX
+ bool media_plugin_pipewire_volume_catcher = gSavedSettings.getBOOL("MediaPluginPipeWireVolumeCatcher");
+ media_source->enablePipeWireVolumeCatcher( media_plugin_pipewire_volume_catcher );
+#endif
+
// need to set agent string here before instance created
media_source->setBrowserUserAgent(LLViewerMedia::getInstance()->getCurrentUserAgent());
@@ -1888,9 +1898,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
}
}
}
-#if !LL_LINUX
LL_WARNS_ONCE("Plugin") << "plugin initialization failed for mime type: " << media_type << LL_ENDL;
-#endif
if(gAgent.isInitialized())
{
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 801ff3c212..10ba93df6d 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -138,11 +138,11 @@ std::queue<LLFilePickerThread*> LLFilePickerThread::sDeadQ;
void LLFilePickerThread::getFile()
{
-#if LL_WINDOWS
+#if LL_DARWIN || LL_SDL_WINDOW
+ runModeless();
+#elif LL_WINDOWS
// Todo: get rid of LLFilePickerThread and make this modeless
start();
-#elif LL_DARWIN
- runModeless();
#else
run();
#endif
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 29f3bc62d5..8cb8d010b8 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3732,9 +3732,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
{
if (!gAudiop)
{
-#if !LL_LINUX
LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
-#endif
return;
}
@@ -3806,9 +3804,7 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data)
{
if (!gAudiop)
{
-#if !LL_LINUX
LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
-#endif
return;
}
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index 60e17a6f58..83b8aa8d03 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -70,8 +70,7 @@ S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVect
S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared);
//defines data needed for octree of an entry
-//LL_ALIGN_PREFIX(16)
-class LLViewerOctreeEntry : public LLRefCount
+class alignas(16) LLViewerOctreeEntry : public LLRefCount
{
LL_ALIGN_NEW
friend class LLViewerOctreeEntryData;
@@ -115,16 +114,15 @@ private:
LLViewerOctreeGroup* mGroup;
//aligned members
- LL_ALIGN_16(LLVector4a mExtents[2]);
- LL_ALIGN_16(LLVector4a mPositionGroup);
+ LLVector4a mExtents[2];
+ LLVector4a mPositionGroup;
F32 mBinRadius;
mutable S32 mBinIndex;
mutable U32 mVisible;
-} ;//LL_ALIGN_POSTFIX(16);
+};
//defines an abstract class for entry data
-//LL_ALIGN_PREFIX(16)
class LLViewerOctreeEntryData : public LLRefCount
{
protected:
@@ -173,11 +171,10 @@ protected:
LLPointer<LLViewerOctreeEntry> mEntry;
LLViewerOctreeEntry::eEntryDataType_t mDataType;
static U32 sCurVisible; // Counter for what value of mVisible means currently visible
-};//LL_ALIGN_POSTFIX(16);
+};
//defines an octree group for an octree node, which contains multiple entries.
-//LL_ALIGN_PREFIX(16)
class LLViewerOctreeGroup
: public OctreeListener
{
@@ -259,18 +256,17 @@ protected:
U32 mState;
OctreeNode* mOctreeNode;
- LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
- LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node
- LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
- LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node
+ LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects)
+ LLVector4a mObjectBounds[2]; // bounding box (center, size) of objects in this node
+ LLVector4a mExtents[2]; // extents (min, max) of this node and all its children
+ LLVector4a mObjectExtents[2]; // extents (min, max) of objects in this node
S32 mAnyVisible; //latest visible to any camera
S32 mVisible[LLViewerCamera::NUM_CAMERAS];
-};//LL_ALIGN_POSTFIX(16);
+};
//octree group which has capability to support occlusion culling
-//LL_ALIGN_PREFIX(16)
class LLOcclusionCullingGroup : public LLViewerOctreeGroup
{
public:
@@ -340,7 +336,7 @@ protected:
public:
static std::set<U32> sPendingQueries;
-};//LL_ALIGN_POSTFIX(16);
+};
class LLViewerOctreePartition
{
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index e36ad0e722..cf92850762 100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -809,7 +809,7 @@ void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_me
const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- glLineWidth(1.0f);
+ gGL.setLineWidth(1.0f);
gGL.color4fv(parcel_outline_color);
for (S32 i = 0; i <= GRIDS_PER_EDGE; i++)
{
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 0c912e8dbc..5bb165051c 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -582,6 +582,7 @@ void LLViewerShaderMgr::setShaders()
unloadShaders();
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
+ LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
if (gViewerWindow)
{
@@ -1001,7 +1002,10 @@ bool LLViewerShaderMgr::loadShadersWater()
return loadShadersWater();
}
- LLWorld::getInstance()->updateWaterObjects();
+ if (LLWorld::instanceExists())
+ {
+ LLWorld::getInstance()->updateWaterObjects();
+ }
return true;
}
@@ -2653,10 +2657,10 @@ bool LLViewerShaderMgr::loadShadersDeferred()
gSMAAEdgeDetectProgram[i].addPermutations(defines);
gSMAAEdgeDetectProgram[i].mShaderFiles.clear();
- gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAAEdgeDetectF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAAEdgeDetectV.glsl", GL_VERTEX_SHADER_ARB));
- gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER_ARB));
- gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER_ARB));
+ gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAAEdgeDetectF.glsl", GL_FRAGMENT_SHADER));
+ gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAAEdgeDetectV.glsl", GL_VERTEX_SHADER));
+ gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER));
+ gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER));
gSMAAEdgeDetectProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gSMAAEdgeDetectProgram[i].createShader();
// llassert(success);
@@ -2679,10 +2683,10 @@ bool LLViewerShaderMgr::loadShadersDeferred()
gSMAABlendWeightsProgram[i].addPermutations(defines);
gSMAABlendWeightsProgram[i].mShaderFiles.clear();
- gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAABlendWeightsF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAABlendWeightsV.glsl", GL_VERTEX_SHADER_ARB));
- gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER_ARB));
- gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER_ARB));
+ gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAABlendWeightsF.glsl", GL_FRAGMENT_SHADER));
+ gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAABlendWeightsV.glsl", GL_VERTEX_SHADER));
+ gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER));
+ gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER));
gSMAABlendWeightsProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gSMAABlendWeightsProgram[i].createShader();
// llassert(success);
@@ -2705,10 +2709,10 @@ bool LLViewerShaderMgr::loadShadersDeferred()
gSMAANeighborhoodBlendProgram[i].addPermutations(defines);
gSMAANeighborhoodBlendProgram[i].mShaderFiles.clear();
- gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendV.glsl", GL_VERTEX_SHADER_ARB));
- gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER_ARB));
- gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER_ARB));
+ gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendF.glsl", GL_FRAGMENT_SHADER));
+ gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendV.glsl", GL_VERTEX_SHADER));
+ gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER));
+ gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER));
gSMAANeighborhoodBlendProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gSMAANeighborhoodBlendProgram[i].createShader();
// llassert(success);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 5fed98dfe4..29fb3cb639 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -188,7 +188,6 @@
#include "llviewerjoystick.h"
#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llviewernetwork.h"
-#include "llpostprocess.h"
#include "llfloaterimnearbychat.h"
#include "llagentui.h"
#include "llwearablelist.h"
@@ -781,14 +780,14 @@ public:
addText(xpos, ypos, "Projection Matrix");
ypos += y_inc;
-#if LL_DARWIN
+#if LL_CLANG
// For sprintf deprecation
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
// View last column is always <0,0,0,1>
MATRIX_ROW_F32_TO_STR(gGLModelView, 12,camera_lines[3]); addText(xpos, ypos, std::string(camera_lines[3])); ypos += y_inc;
-#if LL_DARWIN
+#if LL_CLANG
#pragma clang diagnostic pop
#endif
MATRIX_ROW_N32_TO_STR(gGLModelView, 8,camera_lines[2]); addText(xpos, ypos, std::string(camera_lines[2])); ypos += y_inc;
@@ -1933,13 +1932,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
ms_sleep(5000) ; //wait for 5 seconds.
LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
-#if LL_LINUX
- LL_WARNS() << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt for further information."
- << LL_ENDL;
-#else
LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
<< LL_ENDL;
-#endif
LLAppViewer::instance()->fastQuit(1);
}
else if (!LLViewerShaderMgr::sInitialized)
@@ -3055,7 +3049,7 @@ bool LLViewerWindow::handleKey(KEY key, MASK mask)
{
if ((focusedFloaterName == "nearby_chat") || (focusedFloaterName == "im_container") || (focusedFloaterName == "impanel"))
{
- LLCachedControl<bool> key_move(gSavedSettings, "ArrowKeysAlwaysMove");
+ static LLCachedControl<bool> key_move(gSavedSettings, "ArrowKeysAlwaysMove");
if (key_move())
{
// let Control-Up and Control-Down through for chat line history,
@@ -3328,7 +3322,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())
{
@@ -5634,11 +5628,6 @@ void* LLViewerWindow::getPlatformWindow() const
return mWindow->getPlatformWindow();
}
-void* LLViewerWindow::getMediaWindow() const
-{
- return mWindow->getMediaWindow();
-}
-
void LLViewerWindow::focusClient() const
{
return mWindow->focusClient();
@@ -5860,11 +5849,6 @@ void LLViewerWindow::stopGL()
gBox.cleanupGL();
- if(gPostProcess)
- {
- gPostProcess->invalidate();
- }
-
gTextureList.destroyGL();
stop_glerror();
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 61aa84394c..00413ce141 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -270,7 +270,6 @@ public:
LLWindow* getWindow() const { return mWindow; }
void* getPlatformWindow() const;
- void* getMediaWindow() const;
void focusClient() const;
LLCoordGL getLastMouse() const { return mLastMousePoint; }
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index c6a7a59034..70c64edd7a 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -688,7 +688,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN),
mLoadedCallbacksPaused(false),
mLoadedCallbackTextures(0),
- mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)),
mLastRezzedStatus(-1),
mIsEditingAppearance(false),
mUseLocalAppearance(false),
@@ -3074,7 +3073,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (isImpostor() && !mNeedsImpostorUpdate)
{
- LL_ALIGN_16(LLVector4a ext[2]);
+ LLVector4a ext[2];
F32 distance;
LLVector3 angle;
@@ -5438,7 +5437,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
gGL.begin(LLRender::LINES);
gGL.color4f(1.f,1.f,1.f,1.f);
F32 thickness = llmax(F32(5.0f-5.0f*(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)),1.0f);
- glLineWidth(thickness);
+ gGL.setLineWidth(thickness);
gGL.vertex3fv((pos+left-up).mV);
gGL.vertex3fv((pos-left-up).mV);
gGL.vertex3fv((pos-left-up).mV);
@@ -8580,7 +8579,8 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading)
bool LLVOAvatar::isFullyLoaded() const
{
- return (mRenderUnloadedAvatar || mFullyLoaded);
+ static LLCachedControl<bool> render_unloaded_avatar(gSavedSettings, "RenderUnloadedAvatar", false);
+ return (render_unloaded_avatar || mFullyLoaded);
}
bool LLVOAvatar::hasFirstFullAttachmentData() const
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 1e563c4869..7ccf46d643 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -264,7 +264,7 @@ public:
private: //aligned members
- LL_ALIGN_16(LLVector4a mImpostorExtents[2]);
+ LLVector4a mImpostorExtents[2];
//--------------------------------------------------------------------
// Updates
@@ -671,8 +671,6 @@ private:
LLVector3 mLastAnimExtents[2];
LLVector3 mLastAnimBasePos;
- LLCachedControl<bool> mRenderUnloadedAvatar;
-
//--------------------------------------------------------------------
// Wind rippling in clothes
//--------------------------------------------------------------------
@@ -1017,7 +1015,7 @@ public:
void startTyping() { mTyping = true; mTypingTimer.reset(); }
void stopTyping() { mTyping = false; }
private:
- bool mVisibleChat;
+ bool mVisibleChat = false;
//--------------------------------------------------------------------
// Lip synch morphs
@@ -1199,7 +1197,7 @@ public:
static F32 sGreyUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)
protected:
S32 getUnbakedPixelAreaRank();
- bool mHasGrey;
+ bool mHasGrey = false;
private:
F32 mMinPixelArea;
F32 mMaxPixelArea;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 71a9e71a9f..507154a2a3 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -26,7 +26,9 @@
#include "llvoiceclient.h"
#include "llvoicevivox.h"
+#ifndef DISABLE_WEBRTC
#include "llvoicewebrtc.h"
+#endif
#include "llviewernetwork.h"
#include "llviewercontrol.h"
#include "llcommandhandler.h"
@@ -39,6 +41,7 @@
#include "llagent.h"
#include "lltrans.h"
#include "lluiusage.h"
+#include "llmutelist.h"
const F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f;
@@ -120,10 +123,12 @@ LLVoiceModuleInterface *getVoiceModule(const std::string &voice_server_type)
{
return (LLVoiceModuleInterface *) LLVivoxVoiceClient::getInstance();
}
+#ifndef DISABLE_WEBRTC
else if (voice_server_type == WEBRTC_VOICE_SERVER_TYPE)
{
return (LLVoiceModuleInterface *) LLWebRTCVoiceClient::getInstance();
}
+#endif
else
{
LLNotificationsUtil::add("VoiceVersionMismatch");
@@ -165,7 +170,9 @@ void LLVoiceClient::init(LLPumpIO *pump)
{
// Initialize all of the voice modules
m_servicePump = pump;
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->init(pump);
+#endif
LLVivoxVoiceClient::getInstance()->init(pump);
}
@@ -176,7 +183,9 @@ void LLVoiceClient::userAuthorized(const std::string& user_id, const LLUUID &age
mRegionChangedCallbackSlot.disconnect();
}
mRegionChangedCallbackSlot = gAgent.addRegionChangedCallback(boost::bind(&LLVoiceClient::onRegionChanged, this));
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->userAuthorized(user_id, agentID);
+#endif
LLVivoxVoiceClient::getInstance()->userAuthorized(user_id, agentID);
}
@@ -286,16 +295,20 @@ void LLVoiceClient::setNonSpatialVoiceModule(const std::string &voice_server_typ
void LLVoiceClient::setHidden(bool hidden)
{
LL_INFOS("Voice") << "( " << (hidden ? "true" : "false") << " )" << LL_ENDL;
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setHidden(hidden);
+#endif
LLVivoxVoiceClient::getInstance()->setHidden(hidden);
}
void LLVoiceClient::terminate()
{
- if (LLVivoxVoiceClient::instanceExists())
+#ifndef DISABLE_WEBRTC
+ if (LLWebRTCVoiceClient::instanceExists())
{
LLWebRTCVoiceClient::getInstance()->terminate();
}
+#endif
if (LLVivoxVoiceClient::instanceExists())
{
LLVivoxVoiceClient::getInstance()->terminate();
@@ -334,7 +347,9 @@ void LLVoiceClient::updateSettings()
updateMicMuteLogic();
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->updateSettings();
+#endif
LLVivoxVoiceClient::getInstance()->updateSettings();
}
@@ -343,34 +358,50 @@ void LLVoiceClient::updateSettings()
void LLVoiceClient::tuningStart()
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->tuningStart();
+#endif
LLVivoxVoiceClient::getInstance()->tuningStart();
}
void LLVoiceClient::tuningStop()
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->tuningStop();
+#endif
LLVivoxVoiceClient::getInstance()->tuningStop();
}
bool LLVoiceClient::inTuningMode()
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->inTuningMode();
+#else
+ return false;
+#endif
}
void LLVoiceClient::tuningSetMicVolume(float volume)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->tuningSetMicVolume(volume);
+#endif
}
void LLVoiceClient::tuningSetSpeakerVolume(float volume)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->tuningSetSpeakerVolume(volume);
+#endif
}
float LLVoiceClient::tuningGetEnergy(void)
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->tuningGetEnergy();
+#else
+ return 0.f;
+#endif
}
//------------------------------------------------
@@ -378,40 +409,64 @@ float LLVoiceClient::tuningGetEnergy(void)
bool LLVoiceClient::deviceSettingsAvailable()
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->deviceSettingsAvailable();
+#else
+ return false;
+#endif
}
bool LLVoiceClient::deviceSettingsUpdated()
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->deviceSettingsUpdated();
+#else
+ return false;
+#endif
}
void LLVoiceClient::refreshDeviceLists(bool clearCurrentList)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->refreshDeviceLists(clearCurrentList);
+#endif
}
void LLVoiceClient::setCaptureDevice(const std::string& name)
{
LLVivoxVoiceClient::getInstance()->setCaptureDevice(name);
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setCaptureDevice(name);
+#endif
}
void LLVoiceClient::setRenderDevice(const std::string& name)
{
LLVivoxVoiceClient::getInstance()->setRenderDevice(name);
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setRenderDevice(name);
+#endif
}
const LLVoiceDeviceList& LLVoiceClient::getCaptureDevices()
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->getCaptureDevices();
+#else
+ static LLVoiceDeviceList dummy_device_list;
+ return dummy_device_list;
+#endif
}
const LLVoiceDeviceList& LLVoiceClient::getRenderDevices()
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->getRenderDevices();
+#else
+ static LLVoiceDeviceList dummy_device_list;
+ return dummy_device_list;
+#endif
}
@@ -420,13 +475,18 @@ const LLVoiceDeviceList& LLVoiceClient::getRenderDevices()
void LLVoiceClient::getParticipantList(std::set<LLUUID> &participants) const
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->getParticipantList(participants);
+#endif
LLVivoxVoiceClient::getInstance()->getParticipantList(participants);
}
bool LLVoiceClient::isParticipant(const LLUUID &speaker_id) const
{
- return LLWebRTCVoiceClient::getInstance()->isParticipant(speaker_id) ||
+ return
+#ifndef DISABLE_WEBRTC
+ LLWebRTCVoiceClient::getInstance()->isParticipant(speaker_id) ||
+#endif
LLVivoxVoiceClient::getInstance()->isParticipant(speaker_id);
}
@@ -519,14 +579,22 @@ void LLVoiceClient::activateSpatialChannel(bool activate)
bool LLVoiceClient::isCurrentChannel(const LLSD& channelInfo)
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->isCurrentChannel(channelInfo) ||
LLVivoxVoiceClient::getInstance()->isCurrentChannel(channelInfo);
+#else
+ return LLVivoxVoiceClient::getInstance()->isCurrentChannel(channelInfo);
+#endif
}
bool LLVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2)
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->compareChannels(channelInfo1, channelInfo2) ||
LLVivoxVoiceClient::getInstance()->compareChannels(channelInfo1, channelInfo2);
+#else
+ return LLVivoxVoiceClient::getInstance()->compareChannels(channelInfo1, channelInfo2);
+#endif
}
LLVoiceP2PIncomingCallInterfacePtr LLVoiceClient::getIncomingCallInterface(const LLSD& voice_call_info)
@@ -567,13 +635,17 @@ LLVoiceP2POutgoingCallInterface *LLVoiceClient::getOutgoingCallInterface(const L
void LLVoiceClient::setVoiceVolume(F32 volume)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setVoiceVolume(volume);
+#endif
LLVivoxVoiceClient::getInstance()->setVoiceVolume(volume);
}
void LLVoiceClient::setMicGain(F32 gain)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setMicGain(gain);
+#endif
LLVivoxVoiceClient::getInstance()->setMicGain(gain);
}
@@ -620,10 +692,12 @@ bool LLVoiceClient::voiceEnabled()
void LLVoiceClient::setVoiceEnabled(bool enabled)
{
+#ifndef DISABLE_WEBRTC
if (LLWebRTCVoiceClient::instanceExists())
{
LLWebRTCVoiceClient::getInstance()->setVoiceEnabled(enabled);
}
+#endif
if (LLVivoxVoiceClient::instanceExists())
{
LLVivoxVoiceClient::getInstance()->setVoiceEnabled(enabled);
@@ -646,7 +720,9 @@ void LLVoiceClient::updateMicMuteLogic()
// Either of these always overrides any other PTT setting.
new_mic_mute = true;
}
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setMuteMic(new_mic_mute);
+#endif
LLVivoxVoiceClient::getInstance()->setMuteMic(new_mic_mute);
}
@@ -741,8 +817,11 @@ bool LLVoiceClient::getVoiceEnabled(const LLUUID& id) const
std::string LLVoiceClient::getDisplayName(const LLUUID& id) const
{
- std::string result = LLWebRTCVoiceClient::getInstance()->getDisplayName(id);
+ std::string result;
+#ifndef DISABLE_WEBRTC
+ result = LLWebRTCVoiceClient::getInstance()->getDisplayName(id);
if (result.empty())
+#endif
{
result = LLVivoxVoiceClient::getInstance()->getDisplayName(id);
}
@@ -751,8 +830,12 @@ std::string LLVoiceClient::getDisplayName(const LLUUID& id) const
bool LLVoiceClient::isVoiceWorking() const
{
+#ifndef DISABLE_WEBRTC
return LLVivoxVoiceClient::getInstance()->isVoiceWorking() ||
LLWebRTCVoiceClient::getInstance()->isVoiceWorking();
+#else
+ return LLVivoxVoiceClient::getInstance()->isVoiceWorking();
+#endif
}
bool LLVoiceClient::isParticipantAvatar(const LLUUID& id)
@@ -767,22 +850,34 @@ bool LLVoiceClient::isOnlineSIP(const LLUUID& id)
bool LLVoiceClient::getIsSpeaking(const LLUUID& id)
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->getIsSpeaking(id) ||
LLVivoxVoiceClient::getInstance()->getIsSpeaking(id);
+#else
+ return LLVivoxVoiceClient::getInstance()->getIsSpeaking(id);
+#endif
}
bool LLVoiceClient::getIsModeratorMuted(const LLUUID& id)
{
// don't bother worrying about p2p calls, as
// p2p calls don't have mute.
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->getIsModeratorMuted(id) ||
LLVivoxVoiceClient::getInstance()->getIsModeratorMuted(id);
+#else
+ return LLVivoxVoiceClient::getInstance()->getIsModeratorMuted(id);
+#endif
}
F32 LLVoiceClient::getCurrentPower(const LLUUID& id)
{
+#ifndef DISABLE_WEBRTC
return std::fmax(LLVivoxVoiceClient::getInstance()->getCurrentPower(id),
LLWebRTCVoiceClient::getInstance()->getCurrentPower(id));
+#else
+ return LLVivoxVoiceClient::getInstance()->getCurrentPower(id);
+#endif
}
bool LLVoiceClient::getOnMuteList(const LLUUID& id)
@@ -794,12 +889,18 @@ bool LLVoiceClient::getOnMuteList(const LLUUID& id)
F32 LLVoiceClient::getUserVolume(const LLUUID& id)
{
+#ifndef DISABLE_WEBRTC
return std::fmax(LLVivoxVoiceClient::getInstance()->getUserVolume(id), LLWebRTCVoiceClient::getInstance()->getUserVolume(id));
+#else
+ return LLVivoxVoiceClient::getInstance()->getUserVolume(id);
+#endif
}
void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setUserVolume(id, volume);
+#endif
LLVivoxVoiceClient::getInstance()->setUserVolume(id, volume);
}
@@ -809,7 +910,9 @@ void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer)
{
LLVivoxVoiceClient::getInstance()->addObserver(observer);
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->addObserver(observer);
+#endif
}
void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer)
@@ -818,16 +921,20 @@ void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer)
{
LLVivoxVoiceClient::getInstance()->removeObserver(observer);
}
+#ifndef DISABLE_WEBRTC
if (LLWebRTCVoiceClient::instanceExists())
{
LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
}
+#endif
}
void LLVoiceClient::addObserver(LLFriendObserver* observer)
{
LLVivoxVoiceClient::getInstance()->addObserver(observer);
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->addObserver(observer);
+#endif
}
void LLVoiceClient::removeObserver(LLFriendObserver* observer)
@@ -836,16 +943,20 @@ void LLVoiceClient::removeObserver(LLFriendObserver* observer)
{
LLVivoxVoiceClient::getInstance()->removeObserver(observer);
}
+#ifndef DISABLE_WEBRTC
if (LLWebRTCVoiceClient::instanceExists())
{
LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
}
+#endif
}
void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer)
{
LLVivoxVoiceClient::getInstance()->addObserver(observer);
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->addObserver(observer);
+#endif
}
void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer)
@@ -854,10 +965,12 @@ void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer)
{
LLVivoxVoiceClient::getInstance()->removeObserver(observer);
}
+#ifndef DISABLE_WEBRTC
if (LLWebRTCVoiceClient::instanceExists())
{
LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
}
+#endif
}
std::string LLVoiceClient::sipURIFromID(const LLUUID &id) const
@@ -920,10 +1033,12 @@ class LLViewerRequiredVoiceVersion : public LLHTTPNode
{
voiceModule = (LLVoiceModuleInterface *) LLVivoxVoiceClient::getInstance();
}
+#ifndef DISABLE_WEBRTC
else if (voice_server_type == "webrtc")
{
voiceModule = (LLVoiceModuleInterface *) LLWebRTCVoiceClient::getInstance();
}
+#endif
else
{
LL_WARNS("Voice") << "Unknown voice server type " << voice_server_type << LL_ENDL;
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index fba7098906..3a1aa5f995 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -699,6 +699,7 @@ void LLWebRTCVoiceClient::setCaptureDevice(const std::string& name)
{
if (mWebRTCDeviceInterface)
{
+ LL_DEBUGS("Voice") << "new capture device is " << name << LL_ENDL;
mWebRTCDeviceInterface->setCaptureDevice(name);
}
}
@@ -727,6 +728,9 @@ void LLWebRTCVoiceClient::OnDevicesChangedImpl(const llwebrtc::LLWebRTCVoiceDevi
return;
}
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
+
+ LL_DEBUGS("Voice") << "Reiniting " << LL_ENDL;
+
std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
std::string outputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
@@ -789,6 +793,7 @@ void LLWebRTCVoiceClient::setRenderDevice(const std::string& name)
{
if (mWebRTCDeviceInterface)
{
+ LL_DEBUGS("Voice") << "new render device is " << name << LL_ENDL;
mWebRTCDeviceInterface->setRenderDevice(name);
}
}
@@ -2320,7 +2325,7 @@ LLVoiceWebRTCConnection::LLVoiceWebRTCConnection(const LLUUID &regionID, const s
// retries wait a short period...randomize it so
// all clients don't try to reconnect at once.
- mRetryWaitSecs = (F32)((F32) rand() / (RAND_MAX)) + 0.5f;
+ mRetryWaitSecs = (F32)((F32) rand() / F32(RAND_MAX)) + 0.5f;
mWebRTCPeerConnectionInterface = llwebrtc::newPeerConnection();
mWebRTCPeerConnectionInterface->setSignalingObserver(this);
@@ -2926,7 +2931,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
case VOICE_STATE_SESSION_UP:
{
mRetryWaitPeriod = 0;
- mRetryWaitSecs = (F32)((F32)rand() / (RAND_MAX)) + 0.5f;
+ mRetryWaitSecs = (F32)((F32)rand() / F32(RAND_MAX)) + 0.5f;
// we'll stay here as long as the session remains up.
if (mShutDown)
@@ -2964,7 +2969,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
{
// back off the retry period, and do it by a small random
// bit so all clients don't reconnect at once.
- mRetryWaitSecs += (F32)((F32) rand() / (RAND_MAX)) + 0.5f;
+ mRetryWaitSecs += (F32)((F32) rand() / F32(RAND_MAX)) + 0.5f;
mRetryWaitPeriod = 0;
}
}
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 7fbcb5fc04..5b24d46bb0 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -218,7 +218,7 @@ LLXMLRPCTransaction::Impl::Impl
mCertStore = gSavedSettings.getString("CertStore");
httpOpts->setSSLVerifyPeer(vefifySSLCert);
- httpOpts->setSSLVerifyHost(vefifySSLCert ? 2 : 0);
+ httpOpts->setSSLVerifyHost(vefifySSLCert);
// LLRefCounted starts with a 1 ref, so don't add a ref in the smart pointer
httpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index fc66e9283e..262da507be 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -122,16 +122,27 @@
#include "SMAAAreaTex.h"
#include "SMAASearchTex.h"
#include "llerror.h"
-#ifndef LL_WINDOWS
-#define A_GCC 1
+
+#if LL_CLANG
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+#pragma clang diagnostic ignored "-Wunused-variable"
+#elif LL_GNUC
+#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
-#if LL_LINUX
#pragma GCC diagnostic ignored "-Wrestrict"
#endif
+#ifndef LL_WINDOWS
+#define A_GCC 1
#endif
#define A_CPU 1
#include "app_settings/shaders/class1/deferred/CASF.glsl" // This is also C++
+#if LL_CLANG
+#pragma clang diagnostic pop
+#elif LL_GNUC
+#pragma GCC diagnostic pop
+#endif
extern bool gSnapshot;
bool gShiftFrame = false;
@@ -1006,7 +1017,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
}
}
@@ -1023,7 +1034,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
}
}
@@ -4342,7 +4353,7 @@ void LLPipeline::renderPhysicsDisplay()
LLGLEnable polygon_offset_line(GL_POLYGON_OFFSET_LINE);
glPolygonOffset(3.f, 3.f);
- glLineWidth(3.f);
+ gGL.setLineWidth(3.f);
LLGLEnable blend(GL_BLEND);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -4384,7 +4395,7 @@ void LLPipeline::renderPhysicsDisplay()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
}
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
gDebugProgram.unbind();
}
@@ -4468,8 +4479,7 @@ void LLPipeline::renderDebug()
//NavMesh
if ( pathfindingConsole->isRenderNavMesh() )
{
- gGL.flush();
- glLineWidth(2.0f);
+ gGL.setLineWidth(2.0f);
LLGLEnable cull(GL_CULL_FACE);
LLGLDisable blend(GL_BLEND);
@@ -4493,7 +4503,7 @@ void LLPipeline::renderDebug()
gGL.flush();
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- glLineWidth(1.0f);
+ gGL.setLineWidth(1.0f);
gGL.flush();
}
//User designated path
@@ -4608,11 +4618,11 @@ void LLPipeline::renderDebug()
gPathfindingProgram.uniform1f(sTint, 1.f);
gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
- glLineWidth(gSavedSettings.getF32("PathfindingLineWidth"));
+ gGL.setLineWidth(gSavedSettings.getF32("PathfindingLineWidth"));
LLGLDisable blendOut(GL_BLEND);
llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
gGL.flush();
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
}
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
@@ -4635,7 +4645,7 @@ void LLPipeline::renderDebug()
LLGLEnable blend(GL_BLEND);
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
gGL.flush();
- glLineWidth(2.0f);
+ gGL.setLineWidth(2.0f);
LLGLEnable cull(GL_CULL_FACE);
gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
@@ -4662,7 +4672,7 @@ void LLPipeline::renderDebug()
gPathfindingProgram.bind();
gGL.flush();
- glLineWidth(1.0f);
+ gGL.setLineWidth(1.0f);
}
glPolygonOffset(0.f, 0.f);
@@ -4955,7 +4965,7 @@ void LLPipeline::renderDebug()
}
/*gGL.flush();
- glLineWidth(16-i*2);
+ gGL.setLineWidth(16-i*2);
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
@@ -4973,7 +4983,7 @@ void LLPipeline::renderDebug()
}
}
gGL.flush();
- glLineWidth(1.f);*/
+ gGL.setLineWidth(1.f);*/
}
}
@@ -6989,7 +6999,7 @@ void apply_cube_face_rotation(U32 face)
void validate_framebuffer_object()
{
GLenum status;
- status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE:
@@ -9403,7 +9413,7 @@ void LLPipeline::bindReflectionProbes(LLGLSLShader& shader)
void LLPipeline::unbindReflectionProbes(LLGLSLShader& shader)
{
- S32 channel = shader.disableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP);
+ S32 channel = shader.disableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
if (channel > -1 && mReflectionMapManager.mTexture.notNull())
{
mReflectionMapManager.mTexture->unbind();
diff --git a/indra/newview/skins/default/textures/icon_auction.tga b/indra/newview/skins/default/textures/icon_auction.tga
new file mode 100644
index 0000000000..d121833b47
--- /dev/null
+++ b/indra/newview/skins/default/textures/icon_auction.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icon_event.tga b/indra/newview/skins/default/textures/icon_event.tga
new file mode 100644
index 0000000000..7805dbce60
--- /dev/null
+++ b/indra/newview/skins/default/textures/icon_event.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icon_event_adult.tga b/indra/newview/skins/default/textures/icon_event_adult.tga
new file mode 100644
index 0000000000..c344fb1e78
--- /dev/null
+++ b/indra/newview/skins/default/textures/icon_event_adult.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icon_event_mature.tga b/indra/newview/skins/default/textures/icon_event_mature.tga
new file mode 100644
index 0000000000..61c879bc92
--- /dev/null
+++ b/indra/newview/skins/default/textures/icon_event_mature.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icon_place.tga b/indra/newview/skins/default/textures/icon_place.tga
new file mode 100644
index 0000000000..2170c98499
--- /dev/null
+++ b/indra/newview/skins/default/textures/icon_place.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index d650e7e791..ff5737ab49 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -837,8 +837,14 @@ with the same filename but different name
<texture name="icon_avatar_online.tga" />
<texture name="icon_diurnal.tga" />
<texture name="icon_for_sale.tga" file_name="icons/Icon_For_Sale.png" />
+ <texture name="icon_auction.tga"/>
+ <texture name="icon_place.tga"/>
<texture name="icon_top_pick.tga" />
+ <texture name="icon_event.tga"/>
+ <texture name="icon_event_adult.tga"/>
+ <texture name="icon_event_mature.tga" />
+
<texture name="lag_status_critical.tga" />
<texture name="lag_status_good.tga" />
<texture name="lag_status_warning.tga" />
diff --git a/indra/newview/skins/default/xui/en/floater_directory.xml b/indra/newview/skins/default/xui/en/floater_directory.xml
new file mode 100644
index 0000000000..3274474337
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_directory.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_close="true"
+ can_drag_on_left="false"
+ single_instance="true"
+ can_resize="true"
+ height="570"
+ min_height="570"
+ width="780"
+ min_width="780"
+ name="directory"
+ title="Search">
+ <tab_container
+ top="0"
+ left="0"
+ follows="left|top|right|bottom"
+ height="550"
+ width="780"
+ mouse_opaque="false"
+ name="Directory Tabs"
+ tab_position="top">
+ <panel
+ border="false"
+ label="People"
+ filename="panel_dir_people.xml"
+ class="panel_dir_people"
+ name="panel_dir_people"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ top="0"
+ bottom="-1" />
+ <panel
+ border="false"
+ label="Groups"
+ filename="panel_dir_groups.xml"
+ class="panel_dir_groups"
+ name="panel_dir_groups"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ top="0"
+ bottom="-1" />
+ <panel
+ border="false"
+ label="Places"
+ filename="panel_dir_places.xml"
+ class="panel_dir_places"
+ name="panel_dir_places"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ top="0"
+ bottom="-1" />
+ <panel
+ border="false"
+ label="Land Sales"
+ filename="panel_dir_land.xml"
+ class="panel_dir_land"
+ name="panel_dir_land"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ top="0"
+ bottom="-1" />
+ <panel
+ border="false"
+ label="Events"
+ filename="panel_dir_events.xml"
+ class="panel_dir_events"
+ name="panel_dir_events"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ top="0"
+ bottom="-1" />
+ <panel
+ border="false"
+ label="Classifieds"
+ filename="panel_dir_classified.xml"
+ class="panel_dir_classified"
+ name="panel_dir_classified"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ top="0"
+ bottom="-1" />
+ <panel
+ border="false"
+ label="Web"
+ filename="panel_dir_web.xml"
+ class="panel_dir_web"
+ name="panel_dir_web"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ top="0"
+ bottom="-1" />
+</tab_container>
+ <panel
+ top="65"
+ follows="right|top"
+ height="486"
+ left="345"
+ visible="false"
+ name="panel_profile_secondlife"
+ class="panel_profile_secondlife"
+ filename="panel_profile_secondlife.xml"
+ width="425" />
+ <panel
+ top="70"
+ follows="bottom|right|top"
+ height="482"
+ left="345"
+ visible="false"
+ name="panel_group_info_sidetray"
+ class="panel_group_info_sidetray"
+ filename="panel_group_info_sidetray.xml"
+ width="425" />
+ <panel
+ top="70"
+ follows="bottom|right|top"
+ height="484"
+ left="345"
+ visible="false"
+ name="panel_places"
+ class="panel_places"
+ filename="panel_places.xml"
+ width="425" />
+ <panel
+ top="70"
+ follows="bottom|right|top"
+ height="481"
+ left="345"
+ visible="false"
+ name="panel_classified_info"
+ class="panel_classified_info"
+ filename="panel_classified_info.xml"
+ width="425" />
+ <panel
+ top="70"
+ follows="bottom|right|top"
+ height="480"
+ left="345"
+ visible="false"
+ name="panel_event_info"
+ class="panel_event_info"
+ filename="panel_event_info.xml"
+ width="425" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml
index 832716c600..51e740d687 100644
--- a/indra/newview/skins/default/xui/en/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_gesture.xml
@@ -35,9 +35,13 @@
top="20"
name="gesture_list">
<scroll_list.columns
+ label=""
+ name="active"
+ width="10" />
+ <scroll_list.columns
label="Name"
name="name"
- width="153" />
+ width="143" />
<scroll_list.columns
label="Chat"
name="trigger"
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_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 2a18134491..3ba772e8d7 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -360,17 +360,6 @@
Hardware
</text>
-
- <check_box
- control_name="RenderAnisotropic"
- height="16"
- label="Anisotropic Filtering (slower when enabled)"
- layout="topleft"
- left="30"
- name="ani"
- top_delta="16"
- width="256" />
-
<check_box
control_name="RenderCompressTextures"
height="16"
@@ -401,6 +390,49 @@
height="20"
layout="topleft"
left="30"
+ name="af strength label"
+ top_delta="20"
+ width="130">
+ Anisotropic Filtering:
+ </text>
+ <combo_box
+ control_name="RenderAnisotropicLevel"
+ height="20"
+ label="Anisotropic Filtering"
+ layout="topleft"
+ left_pad="40"
+ name="anisotropic_filter"
+ top_delta="0"
+ width="90">
+ <combo_box.item
+ label="Disabled"
+ name="disabled"
+ value="0" />
+ <combo_box.item
+ label="2x"
+ name="2x"
+ value="2" />
+ <combo_box.item
+ label="4x"
+ name="4x"
+ value="4" />
+ <combo_box.item
+ label="8x"
+ name="8x"
+ value="8" />
+ <combo_box.item
+ label="16x"
+ name="16x"
+ value="16" />
+ </combo_box>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="30"
name="antialiasing label"
top_delta="20"
width="130">
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 081e5be014..08521ebe81 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -125,7 +125,6 @@
</menu_item_call>
<menu_item_separator/>
-
<menu_item_call
label="Preferences..."
name="Preferences"
@@ -688,6 +687,13 @@
<menu_item_check.on_click
function="Avatar.ToggleSearch"/>
</menu_item_check>
+ <menu_item_call
+ label="Legacy Search..."
+ name="LegacySearch">
+ <menu_item_call.on_click
+ function="Floater.Toggle"
+ parameter="legacy_search" />
+ </menu_item_call>
<menu_item_separator/>
<menu_item_call
label="Teleport home"
diff --git a/indra/newview/skins/default/xui/en/mime_types_linux.xml b/indra/newview/skins/default/xui/en/mime_types_linux.xml
index d0ecd0a11c..28e63c82f1 100644
--- a/indra/newview/skins/default/xui/en/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/en/mime_types_linux.xml
@@ -7,7 +7,7 @@
none
</defaultwidget>
<defaultimpl>
- media_plugin_webkit
+ media_plugin_cef
</defaultimpl>
<widgetset name="web">
<label name="web_label">
@@ -130,7 +130,7 @@
movie
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</scheme>
<mimetype name="blank">
@@ -141,7 +141,7 @@
none
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="none/none">
@@ -152,7 +152,7 @@
none
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="audio/*">
@@ -163,7 +163,7 @@
audio
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype name="video/*">
@@ -174,7 +174,7 @@
movie
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype name="image/*">
@@ -185,7 +185,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="video/vnd.secondlife.qt.legacy">
@@ -196,7 +196,7 @@
movie
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype name="application/javascript">
@@ -207,7 +207,7 @@
web
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/ogg">
@@ -218,7 +218,7 @@
audio
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype name="application/pdf">
@@ -229,7 +229,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/postscript">
@@ -240,7 +240,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/rtf">
@@ -251,7 +251,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/smil">
@@ -262,7 +262,7 @@
movie
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/xhtml+xml">
@@ -273,7 +273,7 @@
web
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/x-director">
@@ -284,7 +284,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="audio/mid">
@@ -295,7 +295,7 @@
audio
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype name="audio/mpeg">
@@ -306,7 +306,7 @@
audio
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype name="audio/x-aiff">
@@ -317,7 +317,7 @@
audio
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype name="audio/x-wav">
@@ -328,7 +328,7 @@
audio
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype menu="1" name="image/bmp">
@@ -339,7 +339,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/gif">
@@ -350,7 +350,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/jpeg">
@@ -361,7 +361,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/png">
@@ -372,7 +372,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="image/svg+xml">
@@ -383,7 +383,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/tiff">
@@ -394,7 +394,7 @@
image
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="text/html">
@@ -405,7 +405,7 @@
web
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="text/plain">
@@ -416,7 +416,7 @@
text
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype name="text/xml">
@@ -427,7 +427,7 @@
text
</widgettype>
<impl>
- media_plugin_webkit
+ media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="video/mpeg">
@@ -438,7 +438,7 @@
movie
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype name="video/mp4">
@@ -449,7 +449,7 @@
movie
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype menu="1" name="video/quicktime">
@@ -460,7 +460,7 @@
movie
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype name="video/x-ms-asf">
@@ -471,7 +471,7 @@
movie
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype name="video/x-ms-wmv">
@@ -482,7 +482,7 @@
movie
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
<mimetype menu="1" name="video/x-msvideo">
@@ -493,7 +493,7 @@
movie
</widgettype>
<impl>
- media_plugin_libvlc
+ media_plugin_gstreamer10
</impl>
</mimetype>
</mimetypes>
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index afd3f9410b..b05904cd28 100644
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -344,7 +344,6 @@
width="290"
height="215">
<text
- auto_resize="false"
follows="left|top"
font.style="BOLD"
height="10"
diff --git a/indra/newview/skins/default/xui/en/panel_dir_classified.xml b/indra/newview/skins/default/xui/en/panel_dir_classified.xml
new file mode 100644
index 0000000000..f4d3ccf748
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_dir_classified.xml
@@ -0,0 +1,215 @@
+<panel
+ border="true"
+ top="30"
+ follows="left|top|right|bottom"
+ height="533"
+ label="Classifieds"
+ left="1"
+ left_delta="68"
+ mouse_opaque="false"
+ name="panel_dir_classified"
+ width="778">
+ <string name="searching_text">
+ Searching...
+ </string>
+ <string name="not_found_text">
+ None Found.
+ </string>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ top="8"
+ layout="topleft"
+ follows="left|top"
+ font="SansSerif"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="5"
+ mouse_opaque="true"
+ name="find"
+ v_pad="0"
+ width="150">
+ Enter search terms:
+ </text>
+ <combo_box
+ allow_text_entry="false"
+ top_delta="0"
+ left="525"
+ layout="topleft"
+ follows="right|top"
+ height="18"
+ max_chars="20"
+ mouse_opaque="true"
+ name="Category"
+ width="128">
+ <combo_item name="AnyCategory" value="0" label="Any Category"/>
+ <combo_item name="Shopping" value="1" label="Shopping"/>
+ <combo_item name="LandRental" value="2" label="Land Rental"/>
+ <combo_item name="PropertyRental" value="3" label="Property Rental"/>
+ <combo_item name="SpecialAttraction" value="4" label="Special Attraction"/>
+ <combo_item name="NewProducts" value="5" label="New Products"/>
+ <combo_item name="Employment" value="6" label="Employment"/>
+ <combo_item name="Wanted" value="7" label="Wanted"/>
+ <combo_item name="Service" value="8" label="Service"/>
+ <combo_item name="Personal" value="9" label="Personal"/>
+ </combo_box>
+ <check_box
+ left_pad="5"
+ control_name="ShowPGClassifieds"
+ follows="right|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="true"
+ label=""
+ mouse_opaque="true"
+ name="incpg"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_PG_Dark"
+ tool_tip="General"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_general"
+ width="16"/>
+ <check_box
+ left_pad="4"
+ top_delta="1"
+ layout="topleft"
+ control_name="ShowMatureClassifieds"
+ follows="right|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="true"
+ label=""
+ mouse_opaque="true"
+ name="incmature"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_M_Dark"
+ tool_tip="Moderate"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_moderate"
+ width="16"/>
+ <check_box
+ left_pad="4"
+ top_delta="1"
+ layout="topleft"
+ control_name="ShowAdultClassifieds"
+ follows="right|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="false"
+ label=""
+ mouse_opaque="true"
+ name="incadult"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_R_Dark"
+ tool_tip="Adult"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_adult"
+ width="16"/>
+ <line_editor
+ bevel_style="in"
+ border_style="line"
+ border_thickness="1"
+ top_pad="3"
+ follows="left|right|top"
+ layout="topleft"
+ font="SansSerif"
+ height="18"
+ left="5"
+ max_length="63"
+ mouse_opaque="true"
+ name="name"
+ width="650" />
+ <button
+ follows="right|top"
+ layout="topleft"
+ font="SansSerif"
+ halign="center"
+ height="20"
+ label="Search"
+ top_delta="0"
+ left_pad="5"
+ mouse_opaque="true"
+ name="Search"
+ width="105" />
+ <scroll_list
+ background_visible="true"
+ layout="topleft"
+ top_pad="3"
+ column_padding="0"
+ draw_border="true"
+ draw_heading="true"
+ follows="left|top|right|bottom"
+ height="450"
+ left="5"
+ mouse_opaque="true"
+ multi_select="false"
+ name="results"
+ search_column="2"
+ width="336">
+ <column label="" name="icon" width="24" />
+ <column label="" name="type" width="-1" />
+ <column label="Name" name="name" width="225" />
+ <column label="Price" name="price" width="55" />
+ </scroll_list>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ bottom_delta="-20"
+ follows="left|bottom"
+ font="SansSerifSmall"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="4"
+ mouse_opaque="true"
+ name="result_text"
+ v_pad="0"
+ width="80" />
+ <button
+ image_overlay="Arrow_Left_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ hover_glow_amount="0.15"
+ tool_tip="Previous page"
+ follows="right|bottom"
+ height="22"
+ right="305"
+ bottom="-533"
+ name="prev_btn"
+ width="32" />
+ <button
+ image_overlay="Arrow_Right_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ tool_tip="Next page"
+ follows="right|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="5"
+ name="next_btn"
+ top_delta="0"
+ width="32"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_dir_events.xml b/indra/newview/skins/default/xui/en/panel_dir_events.xml
new file mode 100644
index 0000000000..b194ce5646
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_dir_events.xml
@@ -0,0 +1,300 @@
+<panel
+ border="true"
+ top="30"
+ default_tab_group="1"
+ follows="left|top|right|bottom"
+ height="533"
+ label="Events"
+ left="1"
+ mouse_opaque="false"
+ name="panel_dir_events"
+ width="778">
+ <string name="searching_text">
+ Searching...
+ </string>
+ <string name="not_found_text">
+ None Found.
+ </string>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ top="8"
+ layout="topleft"
+ follows="left|top"
+ font="SansSerif"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="5"
+ mouse_opaque="true"
+ name="find"
+ width="150">
+ Enter search terms:
+ </text>
+ <combo_box
+ allow_text_entry="false"
+ top_delta="0"
+ left="525"
+ layout="topleft"
+ follows="right|top"
+ height="18"
+ max_chars="20"
+ mouse_opaque="true"
+ name="category_combo"
+ width="128">
+ <combo_item name="All" value="0" label="Any Category"/>
+ <combo_item name="Discussion" value="18" label="Discussion"/>
+ <combo_item name="Sports" value="19" label="Sports"/>
+ <combo_item name="LiveMusic" value="20" label="Live Music"/>
+ <combo_item name="LiveDJ" value="30" label="Live DJ"/>
+ <combo_item name="Commercial" value="22" label="Commercial"/>
+ <combo_item name="Nightlife/Entertainment" value="23" label="Nightlife/Entertainment"/>
+ <combo_item name="Games/Contests" value="24" label="Games/Contests"/>
+ <combo_item name="Pageants" value="25" label="Pageants"/>
+ <combo_item name="Education" value="26" label="Education"/>
+ <combo_item name="ArtsandCulture" value="27" label="Arts and Culture"/>
+ <combo_item name="Charity/SupportGroups" value="28" label="Charity/Support Groups"/>
+ <combo_item name="Miscellaneous" value="29" label="Miscellaneous"/>
+ </combo_box>
+ <check_box
+ left_pad="5"
+ control_name="ShowPGEvents"
+ follows="right|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="true"
+ label=""
+ mouse_opaque="true"
+ name="incpg"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_PG_Dark"
+ tool_tip="General"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_general"
+ width="16"/>
+ <check_box
+ left_pad="4"
+ top_delta="1"
+ layout="topleft"
+ control_name="ShowMatureEvents"
+ follows="right|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="true"
+ label=""
+ mouse_opaque="true"
+ name="incmature"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_M_Dark"
+ tool_tip="Moderate"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_moderate"
+ width="16"/>
+ <check_box
+ left_pad="4"
+ top_delta="1"
+ layout="topleft"
+ control_name="ShowAdultEvents"
+ follows="right|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="false"
+ label=""
+ mouse_opaque="true"
+ name="incadult"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_R_Dark"
+ tool_tip="Adult"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_adult"
+ width="16"/>
+ <line_editor
+ bevel_style="in"
+ border_style="line"
+ border_thickness="1"
+ top_pad="3"
+ follows="left|right|top"
+ layout="topleft"
+ font="SansSerif"
+ height="18"
+ left="5"
+ max_length="63"
+ mouse_opaque="true"
+ name="event_search_text"
+ width="650" />
+ <button
+ follows="right|top"
+ layout="topleft"
+ font="SansSerif"
+ halign="center"
+ height="20"
+ label="Search"
+ top_delta="0"
+ left_pad="5"
+ mouse_opaque="true"
+ name="Search"
+ width="105" />
+ <scroll_list
+ background_visible="true"
+ layout="topleft"
+ top_pad="3"
+ column_padding="0"
+ draw_border="true"
+ draw_heading="true"
+ follows="left|top|right|bottom"
+ height="450"
+ left="5"
+ mouse_opaque="true"
+ multi_select="false"
+ name="results"
+ search_column="2"
+ width="336">
+ <column label="" name="icon" width="24" />
+ <column label="" name="type" width="-1" />
+ <column dynamicwidth="true" label="Name" name="name" />
+ <column label="Time (PT)" name="date" sort="time" width="106" />
+ <column label="" name="event_id" width="-1" />
+ <column label="Time" name="time" width="-1" />
+ </scroll_list>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ bottom_delta="-20"
+ drop_shadow_visible="true"
+ follows="left|bottom"
+ font="SansSerifSmall"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="4"
+ mouse_opaque="true"
+ name="result_text"
+ v_pad="0"
+ width="80" />
+ <button
+ image_overlay="Arrow_Left_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ hover_glow_amount="0.15"
+ tool_tip="Previous page"
+ follows="right|bottom"
+ height="22"
+ right="305"
+ bottom="-533"
+ name="prev_btn"
+ width="32" />
+ <button
+ image_overlay="Arrow_Right_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ tool_tip="Next page"
+ follows="right|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="5"
+ name="next_btn"
+ top_delta="0"
+ width="32"/>
+ <radio_group
+ top="5"
+ draw_border="false"
+ follows="top|left"
+ layout="topleft"
+ height="16"
+ left="160"
+ mouse_opaque="true"
+ name="date_mode"
+ initial_value="current"
+ width="200">
+ <radio_item
+ layout="topleft"
+ left="3"
+ top="0"
+ follows="left|top"
+ height="20"
+ mouse_opaque="true"
+ name="current"
+ width="170"
+ label="In-Progress &amp; Upcoming"/>
+ <radio_item
+ layout="topleft"
+ follows="left|top"
+ height="20"
+ top_delta="0"
+ left_delta="151"
+ mouse_opaque="true"
+ name="date"
+ width="56"
+ label="Date"/>
+ </radio_group>
+ <button
+ top="6"
+ left_pad="15"
+ layout="topleft"
+ follows="left|top"
+ font="SansSerif"
+ halign="center"
+ height="20"
+ label="&lt;&lt;"
+ label_selected="&lt;&lt;"
+ left_delta="54"
+ mouse_opaque="true"
+ name="back_btn"
+ tool_tip="Go back a day"
+ width="20" />
+ <text
+ top="8"
+ bg_visible="false"
+ border_visible="false"
+ left_pad="1"
+ layout="topleft"
+ drop_shadow_visible="true"
+ follows="left|top"
+ font="SansSerif"
+ h_pad="0"
+ halign="center"
+ height="14"
+ mouse_opaque="true"
+ name="date_text"
+ v_pad="0"
+ width="48">
+ 6/6
+ </text>
+ <button
+ top="6"
+ left_pad="1"
+ layout="topleft"
+ follows="left|top"
+ font="SansSerif"
+ halign="center"
+ height="20"
+ label="&gt;&gt;"
+ label_selected="&gt;&gt;"
+ left_delta="50"
+ mouse_opaque="true"
+ name="forward_btn"
+ tool_tip="Go forward a day"
+ width="20" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_dir_groups.xml b/indra/newview/skins/default/xui/en/panel_dir_groups.xml
new file mode 100644
index 0000000000..ed3f709005
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_dir_groups.xml
@@ -0,0 +1,129 @@
+<panel
+ border="true"
+ top="30"
+ follows="left|top|right|bottom"
+ height="533"
+ label="Groups"
+ left="1"
+ mouse_opaque="false"
+ name="panel_dir_groups"
+ width="778">
+ <button
+ image_overlay="Arrow_Left_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ hover_glow_amount="0.15"
+ tool_tip="Previous page"
+ follows="right|bottom"
+ height="22"
+ right="305"
+ bottom="-533"
+ name="prev_btn"
+ width="32" />
+ <button
+ image_overlay="Arrow_Right_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ tool_tip="Next page"
+ follows="right|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="5"
+ name="next_btn"
+ top_delta="0"
+ width="32"/>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ top="8"
+ layout="topleft"
+ follows="left|top"
+ font="SansSerif"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="5"
+ mouse_opaque="true"
+ name="find"
+ v_pad="0"
+ width="150">
+ Enter search terms:
+ </text>
+ <check_box
+ top_delta="0"
+ control_name="ShowMatureGroups"
+ follows="right|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="false"
+ label="Include Mature groups"
+ left="510"
+ mouse_opaque="true"
+ name="incmature"
+ width="100" />
+ <line_editor
+ bevel_style="in"
+ border_style="line"
+ border_thickness="1"
+ top_pad="5"
+ follows="left|right|top"
+ font="SansSerif"
+ height="18"
+ left="5"
+ max_length="63"
+ mouse_opaque="true"
+ name="name"
+ width="650" />
+ <button
+ follows="right|top"
+ layout="topleft"
+ font="SansSerif"
+ halign="center"
+ height="20"
+ label="Search"
+ top_delta="0"
+ left_pad="5"
+ mouse_opaque="true"
+ name="Search"
+ width="105" />
+ <scroll_list
+ background_visible="true"
+ layout="topleft"
+ top_pad="3"
+ column_padding="0"
+ draw_border="true"
+ draw_heading="true"
+ follows="left|top|right|bottom"
+ height="450"
+ left="5"
+ mouse_opaque="true"
+ multi_select="false"
+ name="results"
+ search_column="2"
+ width="336">
+ <column label="" name="icon" width="24" sort="score" sort_ascending="false" />
+ <column label="" name="type" width="-1" />
+ <column label="Name" name="name" dynamicwidth="true" />
+ <column label="Members" name="members" width="100" halign="left" sort_ascending="false" />
+ <column label="" name="score" width="-1"/>
+ </scroll_list>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ bottom_delta="-20"
+ follows="left|bottom"
+ font="SansSerifSmall"
+ h_pad="0" halign="left"
+ height="16" left="4"
+ mouse_opaque="true"
+ name="result_text"
+ v_pad="0"
+ width="328" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_dir_land.xml b/indra/newview/skins/default/xui/en/panel_dir_land.xml
new file mode 100644
index 0000000000..61629f3033
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_dir_land.xml
@@ -0,0 +1,268 @@
+<panel border="true" top="30" follows="left|top|right|bottom" height="533"
+ label="Land Sales" left="1" mouse_opaque="false" name="panel_dir_land"
+ width="778">
+ <string name="searching_text">
+ Searching...
+ </string>
+ <string name="not_found_text">
+ None Found.
+ </string>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ top="8"
+ layout="topleft"
+ follows="left|top"
+ font="SansSerif"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="5"
+ mouse_opaque="true"
+ name="find"
+ width="150">
+ Enter search terms:
+ </text>
+ <combo_box
+ allow_text_entry="false"
+ follows="top|right"
+ layout="topleft"
+ height="18"
+ top_delta="0"
+ left="525"
+ max_chars="20"
+ mouse_opaque="true"
+ name="type"
+ width="128">
+ <combo_item name="AllTypes" value="All Types" label="All Types"/>
+ <combo_item name="Auction" value="Auction" label="Auction"/>
+ <combo_item name="MainlandSales" value="Mainland Sales" label="For Sale - Mainland"/>
+ <combo_item name="EstateSales" value="Estate Sales" label="For Sale - Estate"/>
+ </combo_box>
+ <check_box
+ left_pad="5"
+ control_name="ShowPGLand"
+ follows="right|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="true"
+ label=""
+ mouse_opaque="true"
+ name="incpg"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_PG_Dark"
+ tool_tip="General"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_general"
+ width="16"/>
+ <check_box
+ left_pad="4"
+ top_delta="1"
+ layout="topleft"
+ control_name="ShowMatureLand"
+ follows="right|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="true"
+ label=""
+ mouse_opaque="true"
+ name="incmature"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_M_Dark"
+ tool_tip="Moderate"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_moderate"
+ width="16"/>
+ <check_box
+ left_pad="4"
+ top_delta="1"
+ layout="topleft"
+ control_name="ShowAdultLand"
+ follows="right|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="false"
+ label=""
+ mouse_opaque="true"
+ name="incadult"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_R_Dark"
+ tool_tip="Adult"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_adult"
+ width="16"/>
+ <check_box
+ top_pad="3"
+ layout="topleft"
+ control_name="FindLandPrice"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="true"
+ label="Price &#8804; "
+ left="5"
+ mouse_opaque="true"
+ name="pricecheck"
+ width="60" />
+ <line_editor
+ bevel_style="in"
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ height="16"
+ left_pad="1"
+ max_length="10"
+ mouse_opaque="true"
+ name="priceedit"
+ width="50" />
+ <text
+ bg_visible="false"
+ border_visible="false"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ halign="left"
+ height="16"
+ left_pad="3"
+ mouse_opaque="true"
+ name="pricecheck_symbol"
+ width="15">
+ L$
+ </text>
+ <check_box
+ control_name="FindLandArea"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="true"
+ label="Area &#8805; "
+ left_pad="10"
+ mouse_opaque="true"
+ name="areacheck"
+ width="60" />
+ <line_editor
+ bevel_style="in"
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ height="16"
+ left_pad="1"
+ max_length="10"
+ mouse_opaque="true"
+ name="areaedit"
+ width="50" />
+ <text
+ bg_visible="false"
+ border_visible="false"
+ follows="left|top"
+ layout="topleft"
+ left_pad="3"
+ font="SansSerifSmall"
+ halign="left"
+ height="16"
+ mouse_opaque="true"
+ name="areacheck_symbol"
+ width="15">
+ m²
+ </text>
+ <button
+ follows="right|top"
+ layout="topleft"
+ font="SansSerif"
+ halign="center"
+ height="20"
+ label="Search"
+ top_delta="0"
+ left="660"
+ mouse_opaque="true"
+ name="Search"
+ width="105" />
+ <scroll_list
+ background_visible="true"
+ layout="topleft"
+ top_pad="3"
+ column_padding="0"
+ draw_border="true"
+ draw_heading="true"
+ follows="left|top|right|bottom"
+ height="450"
+ left="5"
+ mouse_opaque="true"
+ multi_select="false"
+ name="results"
+ search_column="2"
+ width="336">
+ <column label="" name="icon" width="24" />
+ <column dynamicwidth="true" label="Name" name="name" />
+ <column label="Type" name="landtype" width="50" />
+ <column label="L$ Price" name="price" width="65" />
+ <column label="Area" name="area" width="50" />
+ <column label="L$/m²" name="per_meter" width="65" />
+ </scroll_list>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ bottom_delta="-20"
+ drop_shadow_visible="true"
+ follows="left|bottom"
+ font="SansSerifSmall"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="4"
+ mouse_opaque="true"
+ name="result_text"
+ v_pad="0"
+ width="328" />
+ <button
+ image_overlay="Arrow_Left_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ hover_glow_amount="0.15"
+ tool_tip="Previous page"
+ follows="right|bottom"
+ height="22"
+ right="305"
+ bottom="-533"
+ name="prev_btn"
+ width="32" />
+ <button
+ image_overlay="Arrow_Right_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ tool_tip="Next page"
+ follows="right|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="5"
+ name="next_btn"
+ top_delta="0"
+ width="32"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_dir_people.xml b/indra/newview/skins/default/xui/en/panel_dir_people.xml
new file mode 100644
index 0000000000..fe1a7e9d94
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_dir_people.xml
@@ -0,0 +1,120 @@
+<panel
+ border="true"
+ top="30"
+ follows="left|top|right|bottom"
+ height="533"
+ label="People"
+ left="1"
+ mouse_opaque="false"
+ name="panel_dir_people"
+ width="778">
+ <string name="searching_text">
+ Searching...
+ </string>
+ <string name="not_found_text">
+ None Found.
+ </string>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ top="8"
+ layout="topleft"
+ follows="left|top"
+ font="SansSerif"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="5"
+ mouse_opaque="true"
+ name="find"
+ width="150">
+ Enter search terms:
+ </text>
+ <line_editor
+ bevel_style="in"
+ border_style="line"
+ border_thickness="1"
+ top_pad="5"
+ follows="left|right|top"
+ font="SansSerif"
+ height="18"
+ left="5"
+ max_length="63"
+ mouse_opaque="true"
+ name="name"
+ width="650" />
+ <button
+ follows="right|top"
+ layout="topleft"
+ font="SansSerif"
+ top_delta="0"
+ left_pad="5"
+ height="20"
+ label="Search"
+ mouse_opaque="true"
+ name="Search"
+ width="105" />
+ <scroll_list
+ background_visible="true"
+ layout="topleft"
+ top_pad="3"
+ column_padding="0"
+ draw_border="true"
+ draw_heading="true"
+ follows="left|top|right|bottom"
+ height="450"
+ left="5"
+ mouse_opaque="true"
+ multi_select="false"
+ name="results"
+ search_column="2"
+ width="336">
+ <column label="" name="icon" width="24" />
+ <column label="" name="type" width="-1" />
+ <column label="Name" name="name" width="274" />
+ </scroll_list>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ bottom_delta="-20"
+ follows="left|bottom"
+ font="SansSerifSmall"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="4"
+ mouse_opaque="true"
+ name="result_text"
+ v_pad="0"
+ width="328" />
+ <button
+ image_overlay="Arrow_Left_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ hover_glow_amount="0.15"
+ tool_tip="Previous page"
+ follows="right|bottom"
+ height="22"
+ right="305"
+ bottom="-533"
+ name="prev_btn"
+ width="32" />
+ <button
+ image_overlay="Arrow_Right_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ tool_tip="Next page"
+ follows="right|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="5"
+ name="next_btn"
+ top_delta="0"
+ width="32"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_dir_places.xml b/indra/newview/skins/default/xui/en/panel_dir_places.xml
new file mode 100644
index 0000000000..d337f3addf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_dir_places.xml
@@ -0,0 +1,215 @@
+<panel
+ border="true"
+ top="30"
+ follows="left|top|right|bottom"
+ height="533"
+ label="Places"
+ left="1"
+ mouse_opaque="false"
+ name="panel_dir_places"
+ width="778">
+ <string name="searching_text">
+ Searching...
+ </string>
+ <string name="not_found_text">
+ None Found.
+ </string>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ top="8"
+ layout="topleft"
+ follows="left|top"
+ font="SansSerif"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="5"
+ mouse_opaque="true"
+ name="find"
+ width="150">
+ Enter search terms:
+ </text>
+ <combo_box
+ allow_text_entry="false"
+ follows="right|top"
+ layout="topleft"
+ height="18"
+ top_delta="0"
+ left="525"
+ max_chars="20"
+ mouse_opaque="true"
+ name="Category"
+ width="128">
+ <combo_item name="AnyCategory" value="any" label="Any Category"/>
+ <combo_item name="LindenLocation" value="linden" label="Linden Location"/>
+ <combo_item name="Arts&amp;Culture" value="arts" label="Arts &amp; Culture"/>
+ <combo_item name="Business" value="store" label="Business"/>
+ <combo_item name="Educational" value="educational" label="Educational"/>
+ <combo_item name="Gaming" value="game" label="Gaming"/>
+ <combo_item name="Hangout" value="gather" label="Hangout"/>
+ <combo_item name="NewcomerFriendly" value="newcomer" label="Newcomer Friendly"/>
+ <combo_item name="Parks&amp;Nature" value="park" label="Parks &amp; Nature"/>
+ <combo_item name="Residential" value="home" label="Residential"/>
+ <combo_item name="Shopping" value="shopping" label="Shopping"/>
+ <combo_item name="Adult" value="adult" label="Adult"/>
+ <combo_item name="Other" value="other" label="Other"/>
+ </combo_box>
+ <check_box
+ left_pad="5"
+ control_name="ShowPGSims"
+ follows="right|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="true"
+ label=""
+ mouse_opaque="true"
+ name="incpg"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_PG_Dark"
+ tool_tip="General"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_general"
+ width="16"/>
+ <check_box
+ left_pad="4"
+ top_delta="1"
+ layout="topleft"
+ control_name="ShowMatureSims"
+ follows="right|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="true"
+ label=""
+ mouse_opaque="true"
+ name="incmature"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_M_Dark"
+ tool_tip="Moderate"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_moderate"
+ width="16"/>
+ <check_box
+ left_pad="4"
+ top_delta="1"
+ layout="topleft"
+ control_name="ShowAdultSims"
+ follows="right|top"
+ font="SansSerifSmall"
+ height="16"
+ initial_value="false"
+ label=""
+ mouse_opaque="true"
+ name="incadult"
+ width="15" />
+ <icon
+ follows="right|top"
+ height="16"
+ top_delta="-1"
+ image_name="Parcel_R_Dark"
+ tool_tip="Adult"
+ layout="topleft"
+ left_pad="2"
+ name="rating_icon_adult"
+ width="16"/>
+ <line_editor
+ bevel_style="in"
+ border_style="line"
+ border_thickness="1"
+ top_pad="3"
+ follows="left|right|top"
+ layout="topleft"
+ font="SansSerif"
+ height="18"
+ left="5"
+ max_length="63"
+ mouse_opaque="true"
+ name="name"
+ width="650" />
+ <button
+ follows="right|top"
+ layout="topleft"
+ font="SansSerif"
+ halign="center"
+ height="20"
+ label="Search"
+ top_delta="0"
+ left_pad="5"
+ mouse_opaque="true"
+ name="Search"
+ width="105" />
+ <scroll_list
+ background_visible="true"
+ layout="topleft"
+ top_pad="3"
+ column_padding="0"
+ draw_border="true"
+ draw_heading="true"
+ follows="left|top|right|bottom"
+ height="450"
+ left="5"
+ mouse_opaque="true"
+ multi_select="false"
+ name="results"
+ search_column="2"
+ width="336">
+ <column label="" name="icon" width="24" />
+ <column dynamicwidth="true" label="Name" name="name" />
+ <column label="Traffic" name="dwell" width="75" />
+ </scroll_list>
+ <text
+ bg_visible="false"
+ border_visible="false"
+ bottom_delta="-20"
+ follows="left|bottom"
+ font="SansSerifSmall"
+ h_pad="0"
+ halign="left"
+ height="16"
+ left="4"
+ mouse_opaque="true"
+ name="result_text"
+ v_pad="0"
+ width="328" />
+ <button
+ image_overlay="Arrow_Left_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ hover_glow_amount="0.15"
+ tool_tip="Previous page"
+ follows="right|bottom"
+ height="22"
+ right="305"
+ bottom="-533"
+ name="prev_btn"
+ width="32" />
+ <button
+ image_overlay="Arrow_Right_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ tool_tip="Next page"
+ follows="right|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="5"
+ name="next_btn"
+ top_delta="0"
+ width="32"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_dir_web.xml b/indra/newview/skins/default/xui/en/panel_dir_web.xml
new file mode 100644
index 0000000000..0dde67681a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_dir_web.xml
@@ -0,0 +1,76 @@
+<panel
+ border="true"
+ top="30"
+ follows="all"
+ height="543"
+ label="Web"
+ left="1"
+ mouse_opaque="false"
+ name="panel_dir_web"
+ width="778">
+ <web_browser
+ top="0"
+ left="0"
+ height="515"
+ width="778"
+ follows="all"
+ layout="topleft"
+ name="web_search"
+ trusted_content="true"/>
+ <button
+ image_overlay="Arrow_Left_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ hover_glow_amount="0.15"
+ tool_tip="Navigate back"
+ follows="left|bottom"
+ height="22"
+ layout="topleft"
+ left="5"
+ name="back_btn"
+ top_pad="7"
+ width="22" />
+ <button
+ image_overlay="Arrow_Right_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ chrome="true"
+ tool_tip="Navigate forward"
+ follows="left|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="5"
+ name="forward_btn"
+ top_delta="0"
+ width="22"/>
+ <button
+ name="home_btn"
+ follows="left|bottom"
+ image_overlay="Home_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ layout="topleft"
+ tool_tip="Search page"
+ left_pad="5"
+ height="22"
+ width="22"/>
+ <text
+ type="string"
+ length="200"
+ follows="bottom|left"
+ height="20"
+ layout="topleft"
+ left_pad="20"
+ top_delta="5"
+ name="statusbartext"
+ parse_urls="false"
+ text_color="0.4 0.4 0.4 1"
+ width="495"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_event_info.xml b/indra/newview/skins/default/xui/en/panel_event_info.xml
new file mode 100644
index 0000000000..b31918b919
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_event_info.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="false"
+ follows="all"
+ height="570"
+ left="0"
+ top="0"
+ name="panel_event_info"
+ title="Event"
+ width="330">
+ <string name="none">
+ none
+ </string>
+ <string name="notify">
+ Notify
+ </string>
+ <string name="dont_notify">
+ Don&apos;t Notify
+ </string>
+ <text
+ top="4"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerifBig"
+ left="5"
+ width="417"
+ height="18"
+ use_ellipses="true"
+ name="event_name">
+ (none)
+ </text>
+ <text
+ top_pad="10"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="20"
+ name="event_category_label">
+ Type:
+ </text>
+ <text
+ top_delta="0"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="120"
+ name="event_category">
+ (none)
+ </text>
+ <text
+ top_pad="10"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="20"
+ name="event_mature_label">
+ Mature Content:
+ </text>
+ <text
+ top_delta="0"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="120"
+ name="event_mature_yes"
+ visible="false">
+ Yes
+ </text>
+ <text
+ top_delta="0"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="120"
+ name="event_mature_no"
+ visible="false">
+ No
+ </text>
+ <text
+ top_pad="10"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="20"
+ name="event_date_label">
+ Date:
+ </text>
+ <text
+ top_delta="0"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="120"
+ name="event_date">
+ (none)
+ </text>
+ <text
+ top_pad="10"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="20"
+ name="event_duration_label">
+ Event Duration:
+ </text>
+ <text
+ top_delta="0"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="120"
+ name="event_duration">
+ (none)
+ </text>
+ <text
+ top_pad="10"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="20"
+ name="event_runby_label">
+ Run By:
+ </text>
+ <text
+ top_delta="0"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="116"
+ name="event_runby">
+ (none)
+ </text>
+ <text
+ top_pad="10"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="20"
+ name="event_location_label">
+ Location:
+ </text>
+ <text
+ top_delta="0"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="120"
+ name="event_location">
+ (none)
+ </text>
+ <text
+ top_pad="10"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="20"
+ name="event_cover_label">
+ Cover Charge:
+ </text>
+ <text
+ top_delta="0"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="120"
+ name="event_cover">
+ (none)
+ </text>
+ <text
+ top_pad="20"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerif"
+ left="20"
+ name="event_desc_label">
+ Description:
+ </text>
+ <text_editor
+ top_pad="10"
+ follows="left|top"
+ layout="topleft"
+ height="220"
+ left="20"
+ enabled="false"
+ max_length="1024"
+ name="event_desc"
+ width="400" />
+ <button
+ bottom_delta="-24"
+ follows="left|top"
+ height="20"
+ label="Teleport"
+ left="20"
+ name="teleport_btn"
+ width="130" />
+ <button
+ bottom_delta="0"
+ follows="left|top"
+ height="20"
+ label="Show on Map"
+ left="155"
+ name="map_btn"
+ width="130" />
+ <button
+ bottom_delta="0"
+ follows="left|top"
+ height="20"
+ label="Notify"
+ left="290"
+ name="notify_btn"
+ width="130" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
index 0cac1b410f..90bdea93fa 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
@@ -60,6 +60,10 @@
name="Large(512x512)"
value="[i512,i512]" />
<combo_box.item
+ label="Huge (1024x1024)"
+ name="Huge(1024x1024)"
+ value="[i1024,i1024]" />
+ <combo_box.item
label="Current Window"
name="CurrentWindow"
value="[i0,i0]" />
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 99c7d7b7d4..8e0eea97d1 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -327,6 +327,7 @@ are allowed.
<!-- searching - generic -->
<string name="Searching">Searching...</string>
<string name="NoneFound">None found.</string>
+ <string name="ServerUnavailable">Service not available.</string>
<!-- Indicates that an avatar name or other similar datum is being retrieved. General usage. -->
<string name="RetrievingData">Retrieving...</string>
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index f4ee15319e..acbadbc85a 100644
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -773,7 +773,7 @@ namespace tut
LLMachineID::getUniqueID(unique_id, sizeof(unique_id));
LLXORCipher cipher2(unique_id, sizeof(unique_id));
cipher2.encrypt(&binary_data[0], 16);
- std::ofstream temp_file("sechandler_settings.tmp", std::ofstream::binary);
+ llofstream temp_file("sechandler_settings.tmp", std::ofstream::binary);
temp_file.write((const char *)&binary_data[0], binary_data.size());
temp_file.close();
@@ -846,7 +846,7 @@ namespace tut
// rewrite the initial file to verify reloads
handler = NULL;
- std::ofstream temp_file2("sechandler_settings.tmp", std::ofstream::binary);
+ llofstream temp_file2("sechandler_settings.tmp", std::ofstream::binary);
temp_file2.write((const char *)&binary_data[0], binary_data.size());
temp_file2.close();
diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp
index 8049e67fc5..a78235c5f7 100644
--- a/indra/newview/tests/llversioninfo_test.cpp
+++ b/indra/newview/tests/llversioninfo_test.cpp
@@ -29,6 +29,8 @@
#include "../llversioninfo.h"
+#include "llversioninfovars.h"
+
#include <iostream>
// LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 0e2c9d177e..12705c4295 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1116,33 +1116,33 @@ class LinuxManifest(ViewerManifest):
super(LinuxManifest, self).construct()
pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
+ if "package_dir" in self.args:
+ pkgdir = self.args['package_dir']
+
relpkgdir = os.path.join(pkgdir, "lib", "release")
debpkgdir = os.path.join(pkgdir, "lib", "debug")
self.path("licenses-linux.txt","licenses.txt")
with self.prefix("linux_tools"):
- self.path("client-readme.txt","README-linux.txt")
- self.path("client-readme-voice.txt","README-linux-voice.txt")
- self.path("client-readme-joystick.txt","README-linux-joystick.txt")
self.path("wrapper.sh","secondlife")
with self.prefix(dst="etc"):
self.path("handle_secondlifeprotocol.sh")
self.path("register_secondlifeprotocol.sh")
self.path("refresh_desktop_app_entry.sh")
- self.path("launch_url.sh")
self.path("install.sh")
with self.prefix(dst="bin"):
self.path("secondlife-bin","do-not-directly-run-secondlife-bin")
- self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
self.path2basename("../llplugin/slplugin", "SLPlugin")
#this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323
- with self.prefix(src="../viewer_components/manager", dst=""):
- self.path("*.py")
+ #with self.prefix(src="../viewer_components/manager", dst=""):
+ # self.path("*.py")
# recurses, packaged again
self.path("res-sdl")
+ # We copy ll_icon.BMP in CMakeLists.txt to newview/res-sdl and this will let the above self.path step take care of copying
+ # the correct branded icon
# Get the icons based on the channel type
icon_path = self.icon_path()
print("DEBUG: icon_path '%s'" % icon_path)
@@ -1151,32 +1151,69 @@ class LinuxManifest(ViewerManifest):
with self.prefix(dst="res-sdl") :
self.path("secondlife_256.BMP","ll_icon.BMP")
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir, "llwebrtc" ), dst="lib"):
+ self.path("libllwebrtc.so")
+
# plugins
- with self.prefix(src="../media_plugins", dst="bin/llplugin"):
- self.path("gstreamer010/libmedia_plugin_gstreamer010.so",
- "libmedia_plugin_gstreamer.so")
- self.path2basename("libvlc", "libmedia_plugin_libvlc.so")
+ with self.prefix(dst="bin/llplugin"):
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins')):
+ with self.prefix(src='cef'):
+ self.path("libmedia_plugin_cef.so")
+
+ # Media plugins - LibVLC
+ with self.prefix(src='libvlc'):
+ self.path("libmedia_plugin_libvlc.so")
+
+ # GStreamer 1.0 Media Plugin
+ with self.prefix(src='gstreamer10'):
+ self.path("libmedia_plugin_gstreamer10.so")
+
+ # Media plugins - Example (useful for debugging - not shipped with release viewer)
+ if self.channel_type() != 'release':
+ with self.prefix(src='example'):
+ self.path("libmedia_plugin_example.so")
+
- with self.prefix(src=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
- self.path( "plugins.dat" )
- self.path( "*/*.so" )
+ with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
+ self.path( "libcef.so" )
+ self.path( "libEGL*" )
+ self.path( "libvulkan*" )
+ self.path( "libvk_swiftshader*" )
+ self.path( "libGLESv2*" )
- with self.prefix(src=os.path.join(pkgdir, 'lib' ), dst="lib"):
- self.path( "libvlc*.so*" )
+ with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="bin"):
+ self.path( "chrome-sandbox" )
+ self.path( "dullahan_host" )
- # llcommon
- if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"):
- print("Skipping llcommon.so (assuming llcommon was linked statically)")
+ with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="bin"):
+ self.path( "v8_context_snapshot.bin" )
+ self.path( "vk_swiftshader_icd.json")
+
+ with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
+ self.path( "v8_context_snapshot.bin" )
+ self.path( "vk_swiftshader_icd.json")
+
+ with self.prefix(src=os.path.join(pkgdir, 'resources'), dst="lib"):
+ self.path( "chrome_100_percent.pak" )
+ self.path( "chrome_200_percent.pak" )
+ self.path( "resources.pak" )
+ self.path( "icudtl.dat" )
+
+ with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('lib', 'locales')):
+ self.path("*.pak")
self.path("featuretable_linux.txt")
self.path("cube.dae")
- with self.prefix(src=pkgdir):
+ with self.prefix(src=pkgdir, dst="bin"):
self.path("ca-bundle.crt")
def package_finish(self):
installer_name = self.installer_base_name()
+ # When running as a GitHub Action job, RUNNER_TEMP is defined as the tmp dir
+ RUNNER_TEMP = os.getenv('RUNNER_TEMP')
+
self.strip_binaries()
# Fix access permissions
@@ -1191,8 +1228,18 @@ class LinuxManifest(ViewerManifest):
# temporarily move directory tree so that it has the right
# name in the tarfile
realname = self.get_dst_prefix()
- tempname = self.build_path_of(installer_name)
- self.run_command(["mv", realname, tempname])
+ versionedName = self.build_path_of(installer_name)
+
+ tarName = versionedName + ".tar.xz"
+
+ # If using a github runner we divert packaging a little. Considering this wil be a VM/docker image
+ # we can just pack the final installer into RUNNER_TEMP and not into the usual stop we'd pick when
+ # not building a GHA release
+ if RUNNER_TEMP:
+ tarName = os.path.join(RUNNER_TEMP, self.package_file)
+
+ self.run_command(["mv", realname, versionedName])
+
try:
# only create tarball if it's a release build.
if self.args['buildtype'].lower() == 'release':
@@ -1200,75 +1247,52 @@ class LinuxManifest(ViewerManifest):
# security etc.
self.run_command(['tar', '-C', self.get_build_prefix(),
'--numeric-owner', '-cJf',
- tempname + '.tar.xz', installer_name])
+ tarName, installer_name])
+ self.set_github_output_path('viewer_app', tarName)
else:
print("Skipping %s.tar.xz for non-Release build (%s)" % \
(installer_name, self.args['buildtype']))
finally:
- self.run_command(["mv", tempname, realname])
+ self.run_command(["mv", versionedName, realname])
def strip_binaries(self):
if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer():
- print("* Going strip-crazy on the packaged binaries, since this is a RELEASE build")
+ print("* Going strip-crazy on the packaged binaries, since this is a Release build")
# makes some small assumptions about our packaged dir structure
self.run_command(
["find"] +
[os.path.join(self.get_dst_prefix(), dir) for dir in ('bin', 'lib')] +
['-type', 'f', '!', '-name', '*.py',
+ '!', '-name', '*.pak',
+ '!', '-name', '*.bin',
+ '!', '-name', '*.dat',
+ '!', '-name', '*.crt',
+ '!', '-name', '*.dll',
+ '!', '-name', '*.lib',
+ '!', '-name', '*.json',
'!', '-name', 'update_install', '-exec', 'strip', '-S', '{}', ';'])
-class Linux_i686_Manifest(LinuxManifest):
- address_size = 32
+class Linux_x86_64_Manifest(LinuxManifest):
+ address_size = 64
def construct(self):
- super(Linux_i686_Manifest, self).construct()
+ super(Linux_x86_64_Manifest, self).construct()
pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
+ if "package_dir" in self.args:
+ pkgdir = self.args['package_dir']
+
relpkgdir = os.path.join(pkgdir, "lib", "release")
- debpkgdir = os.path.join(pkgdir, "lib", "debug")
+ #debpkgdir = os.path.join(pkgdir, "lib", "debug")
with self.prefix(src=relpkgdir, dst="lib"):
- self.path("libdb*.so")
- self.path("libuuid.so*")
- self.path("libSDL-1.2.so.*")
- self.path("libdirectfb-1.*.so.*")
- self.path("libfusion-1.*.so.*")
- self.path("libdirect-1.*.so.*")
- self.path("libopenjp2.so*")
- self.path("libdirectfb-1.4.so.5")
- self.path("libfusion-1.4.so.5")
- self.path("libdirect-1.4.so.5*")
+ self.path("libSDL*.so.*")
+
self.path("libalut.so*")
self.path("libopenal.so*")
- self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname
- # KLUDGE: As of 2012-04-11, the 'fontconfig' package installs
- # libfontconfig.so.1.4.4, along with symlinks libfontconfig.so.1
- # and libfontconfig.so. Before we added support for library-file
- # wildcards, though, this self.path() call specifically named
- # libfontconfig.so.1.4.4 WITHOUT also copying the symlinks. When I
- # (nat) changed the call to self.path("libfontconfig.so.*"), we
- # ended up with the libfontconfig.so.1 symlink in the target
- # directory as well. But guess what! At least on Ubuntu 10.04,
- # certain viewer fonts look terrible with libfontconfig.so.1
- # present in the target directory. Removing that symlink suffices
- # to improve them. I suspect that means we actually do better when
- # the viewer fails to find our packaged libfontconfig.so*, falling
- # back on the system one instead -- but diagnosing and fixing that
- # is a bit out of scope for the present project. Meanwhile, this
- # particular wildcard specification gets us exactly what the
- # previous call did, without having to explicitly state the
- # version number.
- self.path("libfontconfig.so.*.*")
-
- # Include libfreetype.so. but have it work as libfontconfig does.
- self.path("libfreetype.so.*.*")
- try:
- self.path("libtcmalloc.so*") #formerly called google perf tools
- pass
- except:
- print("tcmalloc files not found, skipping")
- pass
+ if self.args['discord'] == 'ON':
+ self.path("libdiscord_partner_sdk.so*")
# Vivox runtimes
with self.prefix(src=relpkgdir, dst="bin"):
@@ -1280,17 +1304,6 @@ class Linux_i686_Manifest(LinuxManifest):
self.path("libvivoxsdk.so")
self.strip_binaries()
-
-
-class Linux_x86_64_Manifest(LinuxManifest):
- address_size = 64
-
- def construct(self):
- super(Linux_x86_64_Manifest, self).construct()
-
- # support file for valgrind debug tool
- self.path("secondlife-i686.supp")
-
################################################################
if __name__ == "__main__":
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index f80286a630..a3cf762f90 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -10,6 +10,27 @@ include(Tut)
include(LLAddBuildTest)
include(bugsplat)
+set(test_lib_SOURCE_FILES
+ lltut.cpp
+ test.cpp
+ )
+
+set(test_lib_HEADER_FILES
+ CMakeLists.txt
+ lltut.h
+ )
+
+list(APPEND test_lib_SOURCE_FILES ${test_lib_HEADER_FILES})
+
+add_library(lltut_runner_lib ${test_lib_SOURCE_FILES})
+
+target_link_libraries(lltut_runner_lib PRIVATE llcommon)
+
+set_target_properties(lltut_runner_lib
+ PROPERTIES
+ FOLDER "Tests"
+ )
+
set(test_SOURCE_FILES
io.cpp
llapp_tut.cpp
@@ -31,9 +52,7 @@ set(test_SOURCE_FILES
llservicebuilder_tut.cpp
llstreamtools_tut.cpp
lltemplatemessagebuilder_tut.cpp
- lltut.cpp
message_tut.cpp
- test.cpp
)
set(test_HEADER_FILES
@@ -57,6 +76,7 @@ list(APPEND test_SOURCE_FILES ${test_HEADER_FILES})
add_executable(lltest ${test_SOURCE_FILES})
target_link_libraries(lltest
+ lltut_runner_lib
llinventory
llmessage
llmath
@@ -66,14 +86,27 @@ target_link_libraries(lltest
llcorehttp
)
+set_target_properties(lltest
+ PROPERTIES
+ FOLDER "Tests"
+ )
+
if (WINDOWS)
set_target_properties(lltest
- PROPERTIES
+ PROPERTIES
LINK_FLAGS "/NODEFAULTLIB:LIBCMT"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\""
RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
)
elseif (DARWIN)
+ set_target_properties(lltut_runner_lib
+ PROPERTIES
+ OSX_ARCHITECTURES ${LL_MACOS_TEST_ARCHITECTURE}
+ )
+ set_target_properties(lltest
+ PROPERTIES
+ OSX_ARCHITECTURES ${LL_MACOS_TEST_ARCHITECTURE}
+ )
# Support our "@executable_path/../Resources" load path for our test
# executable. This SHOULD properly be "$<TARGET_FILE_DIR:lltest>/Resources",
# but the CMake $<TARGET_FILE_DIR> generator expression isn't evaluated by
@@ -82,32 +115,24 @@ elseif (DARWIN)
SYMBOLIC)
endif (WINDOWS)
-set(TEST_EXE $<TARGET_FILE:lltest>)
-
-SET_TEST_PATH(LD_LIBRARY_PATH)
+# This should cause the test executable to be built, but not
+# run if LL_TESTS is disabled. This will hopefully keep the
+# tests up to date with any code changes changes even if
+# developers choose to disable LL_TESTS.
+if (LL_TESTS)
+ set(TEST_EXE $<TARGET_FILE:lltest>)
-LL_TEST_COMMAND(command
- "${LD_LIBRARY_PATH}"
- "${TEST_EXE}"
- "--output=${CMAKE_CURRENT_BINARY_DIR}/cpp_test_results.txt"
- "--touch=${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt")
+ SET_TEST_PATH(LD_LIBRARY_PATH)
-ADD_CUSTOM_COMMAND(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt
- COMMAND ${command}
- DEPENDS lltest
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- COMMENT "C++ unit tests"
- )
+ LL_TEST_COMMAND(command
+ "${LD_LIBRARY_PATH}"
+ "${TEST_EXE}"
+ "--output=${CMAKE_CURRENT_BINARY_DIR}/cpp_test_results.txt"
+ "--touch=${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt")
-set(test_results ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt)
+ add_test(NAME "C++ unit tests" COMMAND ${command} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-# This should cause the test executable to be built, but not
-# run if LL_TESTS is disabled. This will hopefully keep the
-# tests up to date with any code changes changes even if
-# developers choose to disable LL_TESTS.
-if (LL_TESTS)
- add_custom_target(tests_ok ALL DEPENDS ${test_results})
+ add_dependencies(BUILD_TESTS lltest)
if(DARWIN)
# Support our "@executable_path/../Resources" load path for our test
# executable. This SHOULD properly be "$<TARGET_FILE_DIR:lltest>/Resources",
diff --git a/indra/test/lltut.h b/indra/test/lltut.h
index 581a08654d..fdc1cd7dfe 100644
--- a/indra/test/lltut.h
+++ b/indra/test/lltut.h
@@ -75,12 +75,12 @@ namespace tut
// overloads declared above.
// turn off warnings about unused functions from clang for tut package
-#if __clang__
+#if LL_CLANG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
#endif
#include <tut/tut.hpp>
-#if __clang__
+#if LL_CLANG
#pragma clang diagnostic pop
#endif
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index 172b6e3542..bf685ef20f 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -108,7 +108,7 @@ public:
void replay(std::ostream& out)
{
mFile.close();
- std::ifstream inf(mTempFile.getName().c_str());
+ llifstream inf(mTempFile.getName().c_str());
std::string line;
while (std::getline(inf, line))
{
@@ -505,6 +505,11 @@ static LLTrace::ThreadRecorder* sMasterThreadRecorder = NULL;
int main(int argc, char **argv)
{
+ // Call Tracy first thing to have it allocate memory
+ // https://github.com/wolfpld/tracy/issues/196
+ LL_PROFILER_FRAME_END;
+ LL_PROFILER_SET_THREAD_NAME("App");
+
ll_init_apr();
apr_getopt_t* os = NULL;
if(APR_SUCCESS != apr_getopt_init(&os, gAPRPoolp, argc, argv))