summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@lindenlab.com>2026-08-14 17:10:28 -0400
committerGitHub <noreply@github.com>2026-08-14 17:10:28 -0400
commit05a5a15c99bd1174736da66c58b7080c75a8acb8 (patch)
treee73b7b75809ab21a1933b7cb9f78f4fc5271b061
parenta3c380acd9256102730574afb261aa6266f9a2a5 (diff)
parent0007f7f99fc37b45ad7f3ad6df4238893c50a5be (diff)
Merge pull request #6132 from secondlife/geenz/linux-to-develop
Geenz/linux (and 26.3) to develop
-rw-r--r--.gitattributes4
-rw-r--r--.github/workflows/build.yaml63
-rwxr-xr-x.gitignore4
-rw-r--r--[-rwxr-xr-x]LICENSE0
-rw-r--r--autobuild.xml533
-rwxr-xr-xbuild.sh48
-rw-r--r--doc/BUILD.LINUX.md87
-rw-r--r--[-rwxr-xr-x]doc/LGPL-license.txt0
-rw-r--r--[-rwxr-xr-x]doc/LICENSE-logos.txt0
-rw-r--r--[-rwxr-xr-x]doc/LICENSE-source.txt0
-rw-r--r--[-rwxr-xr-x]doc/contributions.txt0
-rw-r--r--[-rwxr-xr-x]doc/releasenotes-where.txt0
-rw-r--r--[-rwxr-xr-x]doc/translations.txt0
-rw-r--r--indra/CMakeLists.txt45
-rw-r--r--indra/cmake/00-COMPILE-LINK-RUN.txt4
-rw-r--r--indra/cmake/00-Common.cmake87
-rw-r--r--indra/cmake/Boost.cmake159
-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.cmake24
-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.cmake41
-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.cpp9
-rw-r--r--indra/integration_tests/llui_libtest/CMakeLists.txt14
-rw-r--r--indra/integration_tests/llui_libtest/llui_libtest.cpp2
-rw-r--r--[-rwxr-xr-x]indra/lib/python/indra/__init__.py0
-rw-r--r--[-rwxr-xr-x]indra/lib/python/indra/ipc/__init__.py0
-rw-r--r--[-rwxr-xr-x]indra/lib/python/indra/ipc/compatibility.py0
-rw-r--r--[-rwxr-xr-x]indra/lib/python/indra/ipc/llmessage.py0
-rw-r--r--[-rwxr-xr-x]indra/lib/python/indra/ipc/tokenstream.py0
-rw-r--r--[-rwxr-xr-x]indra/lib/python/indra/util/__init__.py0
-rw-r--r--[-rwxr-xr-x]indra/lib/python/indra/util/llmanifest.py0
-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/llpolymesh.cpp2
-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.cpp683
-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.h (renamed from indra/newview/tests/llwldaycycle_stub.cpp)41
-rw-r--r--indra/llappearanceutility/llbakingjointmesh.cpp (renamed from indra/llcommon/llbase32.h)30
-rw-r--r--indra/llappearanceutility/llbakingjointmesh.h46
-rw-r--r--indra/llappearanceutility/llbakingprocess.cpp (renamed from indra/newview/llappviewerlinux_api_dbus.h)35
-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.h (renamed from indra/media_plugins/gstreamer010/llmediaimplgstreamer.h)50
-rw-r--r--indra/llappearanceutility/llbakingwindow.cpp94
-rw-r--r--indra/llappearanceutility/llbakingwindow.h (renamed from indra/newview/tests/llglslshader_stub.cpp)32
-rw-r--r--indra/llappearanceutility/llprocessparams.cpp281
-rw-r--r--indra/llappearanceutility/llprocessparams.h49
-rw-r--r--indra/llappearanceutility/llprocessskin.cpp118
-rw-r--r--indra/llappearanceutility/llprocessskin.h (renamed from indra/newview/tests/llsky_stub.cpp)26
-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--[-rwxr-xr-x]indra/llaudio/llaudiodecodemgr.cpp2
-rw-r--r--[-rwxr-xr-x]indra/llaudio/llaudioengine.h0
-rw-r--r--indra/llcharacter/CMakeLists.txt16
-rw-r--r--indra/llcharacter/lleditingmotion.h15
-rw-r--r--indra/llcharacter/lljoint.h7
-rw-r--r--indra/llcharacter/llkeyframemotion.cpp2
-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.txt51
-rw-r--r--indra/llcommon/StackWalker.cpp4
-rw-r--r--indra/llcommon/classic_callback.h4
-rw-r--r--indra/llcommon/ctype_workaround.h54
-rw-r--r--indra/llcommon/fix_macros.h21
-rw-r--r--indra/llcommon/fsyspath.h4
-rw-r--r--[-rwxr-xr-x]indra/llcommon/hexdump.h0
-rw-r--r--indra/llcommon/llapp.cpp55
-rw-r--r--indra/llcommon/llapr.cpp222
-rw-r--r--indra/llcommon/llapr.h19
-rw-r--r--indra/llcommon/llatomic.cpp2
-rw-r--r--indra/llcommon/llbase32.cpp238
-rw-r--r--indra/llcommon/llcallbacklist.cpp2
-rw-r--r--indra/llcommon/llcommon.cpp54
-rw-r--r--indra/llcommon/llcond.h2
-rw-r--r--indra/llcommon/llcoros.h2
-rw-r--r--indra/llcommon/llcrc.cpp2
-rw-r--r--indra/llcommon/llcrc.h2
-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.cpp61
-rw-r--r--indra/llcommon/llerror.h7
-rw-r--r--indra/llcommon/llfasttimer.cpp11
-rw-r--r--indra/llcommon/llfile.cpp1117
-rw-r--r--indra/llcommon/llfile.h811
-rw-r--r--indra/llcommon/llfindlocale.cpp4
-rw-r--r--indra/llcommon/llfixedbuffer.h2
-rw-r--r--indra/llcommon/llinstancetracker.h6
-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.cpp122
-rw-r--r--indra/llcommon/llmemory.h63
-rw-r--r--indra/llcommon/llmutex.h2
-rw-r--r--indra/llcommon/llpreprocessor.h50
-rw-r--r--indra/llcommon/llprocessor.cpp69
-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/llprofilercategories.h9
-rw-r--r--indra/llcommon/llrand.cpp25
-rw-r--r--indra/llcommon/llsd.cpp5
-rw-r--r--indra/llcommon/llsdjson.cpp2
-rw-r--r--indra/llcommon/llsdserialize.cpp5
-rw-r--r--indra/llcommon/llsdutil.cpp4
-rw-r--r--indra/llcommon/llsingleton.h2
-rw-r--r--indra/llcommon/llstl.h10
-rw-r--r--indra/llcommon/llstreamqueue.cpp24
-rw-r--r--indra/llcommon/llstreamqueue.h240
-rw-r--r--indra/llcommon/llsys.cpp214
-rw-r--r--indra/llcommon/llsys.h9
-rw-r--r--indra/llcommon/llthread.cpp46
-rw-r--r--indra/llcommon/llthread.h8
-rw-r--r--indra/llcommon/llthreadsafequeue.h2
-rw-r--r--indra/llcommon/lltracerecording.cpp9
-rw-r--r--indra/llcommon/lluuid.cpp46
-rw-r--r--indra/llcommon/lluuid.h2
-rw-r--r--indra/llcommon/llwatchdog.cpp5
-rw-r--r--indra/llcommon/llwatchdog.h2
-rw-r--r--indra/llcommon/lockstatic.h2
-rw-r--r--indra/llcommon/mutex.h22
-rw-r--r--indra/llcommon/stdtypes.h24
-rw-r--r--indra/llcommon/tests/commonmisc_test.cpp4
-rw-r--r--indra/llcommon/tests/llallocator_heap_profile_test.cpp144
-rw-r--r--indra/llcommon/tests/llallocator_test.cpp80
-rw-r--r--indra/llcommon/tests/llapp_test.cpp (renamed from indra/test/llapp_tut.cpp)0
-rw-r--r--indra/llcommon/tests/lldependencies_test.cpp12
-rw-r--r--indra/llcommon/tests/lldoubledispatch_test.cpp (renamed from indra/test/lldoubledispatch_tut.cpp)0
-rw-r--r--indra/llcommon/tests/llerror_test.cpp4
-rw-r--r--indra/llcommon/tests/llevents_test.cpp (renamed from indra/test/llevents_tut.cpp)0
-rw-r--r--indra/llcommon/tests/llfile_test.cpp299
-rw-r--r--indra/llcommon/tests/llhttpdate_test.cpp (renamed from indra/test/llhttpdate_tut.cpp)0
-rw-r--r--indra/llcommon/tests/lllazy_test.cpp239
-rw-r--r--indra/llcommon/tests/llleap_test.cpp20
-rw-r--r--indra/llcommon/tests/llmemtype_test.cpp117
-rw-r--r--indra/llcommon/tests/llprocess_test.cpp66
-rw-r--r--indra/llcommon/tests/llsd_test.cpp (renamed from indra/test/llsd_new_tut.cpp)2
-rw-r--r--indra/llcommon/tests/llsdserialize_test.cpp18
-rw-r--r--indra/llcommon/tests/llsdutil_test.cpp (renamed from indra/test/llsdutil_tut.cpp)0
-rw-r--r--indra/llcommon/tests/llstreamqueue_test.cpp194
-rw-r--r--indra/llcommon/tests/llstreamtools_test.cpp (renamed from indra/test/llstreamtools_tut.cpp)0
-rw-r--r--indra/llcommon/tests/llstring_test.cpp4
-rw-r--r--indra/llcommon/threadpool.cpp1
-rw-r--r--indra/llcorehttp/CMakeLists.txt15
-rw-r--r--indra/llcorehttp/_httpservice.cpp50
-rw-r--r--indra/llcorehttp/_httpservice.h2
-rw-r--r--indra/llcorehttp/_mutex.h11
-rw-r--r--indra/llcorehttp/_refcounted.h10
-rw-r--r--indra/llcorehttp/_thread.h103
-rw-r--r--indra/llcorehttp/httpcommon.cpp4
-rw-r--r--indra/llcorehttp/httpcommon.h6
-rw-r--r--[-rwxr-xr-x]indra/llcorehttp/llhttpconstants.cpp0
-rw-r--r--[-rwxr-xr-x]indra/llcorehttp/llhttpconstants.h2
-rw-r--r--[-rwxr-xr-x]indra/llcorehttp/tests/llcorehttp_test.cpp0
-rw-r--r--indra/llcorehttp/tests/test_httprequest.hpp15
-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.cpp63
-rw-r--r--indra/llfilesystem/lldir.h2
-rw-r--r--indra/llfilesystem/lldir_linux.cpp18
-rw-r--r--indra/llfilesystem/lldir_linux.h1
-rw-r--r--indra/llfilesystem/lldir_mac.cpp24
-rw-r--r--indra/llfilesystem/lldir_mac.h1
-rw-r--r--indra/llfilesystem/lldir_win32.cpp22
-rw-r--r--indra/llfilesystem/lldir_win32.h1
-rw-r--r--indra/llfilesystem/lldiriterator.cpp13
-rw-r--r--indra/llfilesystem/lldiskcache.cpp102
-rw-r--r--indra/llfilesystem/llfilesystem.cpp100
-rw-r--r--indra/llfilesystem/llfilesystem.h7
-rw-r--r--indra/llfilesystem/tests/lldir_test.cpp37
-rw-r--r--indra/llimage/CMakeLists.txt4
-rw-r--r--indra/llimage/llimage.cpp36
-rw-r--r--indra/llimage/llimage.h3
-rw-r--r--indra/llimage/llimagedimensionsinfo.cpp2
-rw-r--r--indra/llimage/llimagetga.cpp2
-rw-r--r--indra/llimagej2coj/CMakeLists.txt3
-rw-r--r--indra/llinventory/CMakeLists.txt7
-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/llinventory/tests/llpermissions_test.cpp (renamed from indra/test/llpermissions_tut.cpp)0
-rw-r--r--indra/llinventory/tests/llsaleinfo_test.cpp (renamed from indra/test/llsaleinfo_tut.cpp)0
-rw-r--r--indra/llinventory/tests/lluserrelations_test.cpp (renamed from indra/test/lluserrelations_tut.cpp)0
-rw-r--r--indra/llkdu/include_kdu_xxxx.h2
-rw-r--r--indra/llkdu/tests/llimagej2ckdu_test.cpp2
-rw-r--r--indra/llmath/CMakeLists.txt12
-rw-r--r--indra/llmath/camera.h27
-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/llsphere.cpp370
-rw-r--r--indra/llmath/llsphere.h77
-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/llmath/tests/mathmisc_test.cpp161
-rw-r--r--indra/llmeshoptimizer/CMakeLists.txt4
-rw-r--r--indra/llmessage/CMakeLists.txt21
-rw-r--r--indra/llmessage/llassetstorage.cpp4
-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/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/llmessage/lltransfersourcefile.cpp2
-rw-r--r--indra/llmessage/lltransfertargetfile.cpp2
-rw-r--r--indra/llmessage/llxfer_file.cpp16
-rw-r--r--indra/llmessage/message.cpp4
-rw-r--r--indra/llmessage/partsyspacket.cpp1297
-rw-r--r--indra/llmessage/partsyspacket.h261
-rw-r--r--indra/llmessage/tests/io_test.cpp (renamed from indra/test/io.cpp)0
-rw-r--r--indra/llmessage/tests/llbuffer_test.cpp (renamed from indra/test/llbuffer_tut.cpp)0
-rw-r--r--indra/llmessage/tests/llcurl_stub.cpp99
-rw-r--r--indra/llmessage/tests/lldatapacker_test.cpp (renamed from indra/test/lldatapacker_tut.cpp)16
-rw-r--r--indra/llmessage/tests/llhttpclient_test.cpp311
-rw-r--r--indra/llmessage/tests/llhttpnode_test.cpp (renamed from indra/test/llhttpnode_tut.cpp)0
-rw-r--r--indra/llmessage/tests/lliohttpserver_test.cpp (renamed from indra/test/lliohttpserver_tut.cpp)0
-rw-r--r--indra/llmessage/tests/llmessageconfig_test.cpp (renamed from indra/test/llmessageconfig_tut.cpp)2
-rw-r--r--indra/llmessage/tests/llmessagetemplateparser_test.cpp (renamed from indra/test/llmessagetemplateparser_tut.cpp)0
-rw-r--r--indra/llmessage/tests/llpipeutil.cpp (renamed from indra/test/llpipeutil.cpp)0
-rw-r--r--indra/llmessage/tests/llpipeutil.h (renamed from indra/test/llpipeutil.h)0
-rw-r--r--indra/llmessage/tests/llsdmessagebuilder_test.cpp (renamed from indra/test/llsdmessagebuilder_tut.cpp)0
-rw-r--r--indra/llmessage/tests/llsdmessagereader_test.cpp (renamed from indra/test/llsdmessagereader_tut.cpp)0
-rw-r--r--indra/llmessage/tests/llservicebuilder_test.cpp (renamed from indra/test/llservicebuilder_tut.cpp)0
-rw-r--r--indra/llmessage/tests/lltemplatemessagebuilder_test.cpp (renamed from indra/test/lltemplatemessagebuilder_tut.cpp)0
-rw-r--r--indra/llmessage/tests/llxorcipher_test.cpp (renamed from indra/test/llxorcipher_tut.cpp)0
-rw-r--r--indra/llmessage/tests/message_test.cpp (renamed from indra/test/message_tut.cpp)2
-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/llcommon/timer.h)6
-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.h14
-rw-r--r--indra/llprimitive/llmodelloader.cpp2
-rw-r--r--indra/llprimitive/llprimlinkinfo.h393
-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.cpp1995
-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.cpp24
-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.cpp154
-rw-r--r--indra/llrender/llrender.h24
-rw-r--r--indra/llrender/llrender2dutils.cpp15
-rw-r--r--indra/llrender/llrendertarget.h2
-rw-r--r--indra/llrender/llshadermgr.cpp24
-rw-r--r--indra/llui/CMakeLists.txt12
-rw-r--r--indra/llui/llcallbackmap.h6
-rw-r--r--indra/llui/llcheckboxctrl.h5
-rw-r--r--indra/llui/llemojihelper.h2
-rw-r--r--indra/llui/llfloater.cpp4
-rw-r--r--indra/llui/llpanel.cpp3
-rw-r--r--indra/llui/llresmgr.cpp40
-rw-r--r--indra/llui/llresmgr.h4
-rw-r--r--indra/llui/lluicolortable.cpp2
-rw-r--r--indra/llui/llviewereventrecorder.h2
-rw-r--r--indra/llui/llxuiparser.cpp6
-rw-r--r--[-rwxr-xr-x]indra/llui/tests/llurlentry_stub.cpp8
-rw-r--r--indra/llwebrtc/CMakeLists.txt9
-rw-r--r--indra/llwebrtc/llwebrtc.cpp565
-rw-r--r--indra/llwebrtc/llwebrtc.h8
-rw-r--r--indra/llwebrtc/llwebrtc_impl.h80
-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/llmath/coordframe.h)15
-rw-r--r--indra/llwindow/llwindow.cpp52
-rw-r--r--indra/llwindow/llwindow.h5
-rw-r--r--indra/llwindow/llwindowcallbacks.cpp2
-rw-r--r--indra/llwindow/llwindowcallbacks.h2
-rw-r--r--indra/llwindow/llwindowheadless.h2
-rw-r--r--indra/llwindow/llwindowmacosx.h5
-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.cpp89
-rw-r--r--indra/llwindow/llwindowwin32.h3
-rw-r--r--indra/llxml/CMakeLists.txt3
-rw-r--r--indra/llxml/llcontrol.cpp47
-rw-r--r--indra/llxml/llcontrol.h8
-rw-r--r--indra/llxml/llxmlparser.cpp4
-rw-r--r--indra/llxml/tests/llcontrol_test.cpp2
-rw-r--r--indra/media_plugins/CMakeLists.txt18
-rw-r--r--indra/media_plugins/base/media_plugin_base.cpp96
-rw-r--r--[-rwxr-xr-x]indra/media_plugins/base/media_plugin_base.exp0
-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
-rw-r--r--indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp333
-rw-r--r--indra/media_plugins/cef/linux/volume_catcher_pipewire_syms.inc26
-rw-r--r--indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp322
-rw-r--r--indra/media_plugins/cef/linux/volume_catcher_pulseaudio_glib_syms.inc10
-rw-r--r--indra/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.txt200
-rw-r--r--indra/newview/Info-SecondLife.plist2
-rw-r--r--indra/newview/Info-SecondLifeVorbis.plist28
-rw-r--r--indra/newview/VertexCache.h105
-rw-r--r--indra/newview/VorbisFramework.h80
-rw-r--r--[-rwxr-xr-x]indra/newview/app_settings/llsd.xsd0
-rw-r--r--[-rwxr-xr-x]indra/newview/app_settings/message.xml0
-rw-r--r--indra/newview/app_settings/settings.xml68
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/CASF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl137
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl126
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl118
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyV.glsl123
-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
-rwxr-xr-xindra/newview/build_win32_appConfig.py68
-rw-r--r--indra/newview/featuretable.txt46
-rw-r--r--indra/newview/featuretable_linux.txt662
-rw-r--r--indra/newview/featuretable_mac.txt44
-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--[-rwxr-xr-x]indra/newview/installers/darwin/dmg-cleanup.applescript0
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/darwin/release-dmg/Applications-alias.r0
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/darwin/release-dmg/_DS_Storebin12292 -> 12292 bytes
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/windows/lang_de.nsi0
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/windows/lang_es.nsibin13790 -> 13790 bytes
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/windows/lang_fr.nsibin14302 -> 14302 bytes
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/windows/lang_it.nsibin13528 -> 13528 bytes
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/windows/lang_ja.nsibin10698 -> 10698 bytes
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/windows/lang_pt-br.nsibin13970 -> 13970 bytes
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/windows/lang_ru.nsibin13264 -> 13264 bytes
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/windows/lang_tr.nsibin13174 -> 13174 bytes
-rw-r--r--[-rwxr-xr-x]indra/newview/installers/windows/lang_zh.nsibin10154 -> 10154 bytes
-rw-r--r--indra/newview/licenses-linux.txt177
-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.mm10
-rw-r--r--indra/newview/llappviewer.cpp100
-rw-r--r--indra/newview/llappviewerlinux.cpp789
-rw-r--r--indra/newview/llappviewerlinux.h47
-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.cpp12
-rw-r--r--indra/newview/llcallbacklist.cpp12
-rw-r--r--indra/newview/llconversationlog.cpp4
-rw-r--r--indra/newview/lldebugview.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/lldrawpoolbump.cpp2
-rw-r--r--indra/newview/lldrawpoolterrain.cpp373
-rw-r--r--indra/newview/lldrawpoolterrain.h3
-rw-r--r--indra/newview/lldrawpoolwater.cpp8
-rw-r--r--indra/newview/lldynamictexture.h4
-rw-r--r--indra/newview/lleventnotifier.h2
-rw-r--r--indra/newview/llface.cpp8
-rw-r--r--indra/newview/llfasttimerview.cpp6
-rw-r--r--indra/newview/llfeaturemanager.cpp10
-rw-r--r--indra/newview/llfilepicker.cpp940
-rw-r--r--indra/newview/llfilepicker.h34
-rw-r--r--indra/newview/llflexibleobject.cpp2
-rw-r--r--indra/newview/llfloaterdirectory.h2
-rw-r--r--indra/newview/llfloaterimcontainer.cpp16
-rw-r--r--indra/newview/llfloaterimcontainer.h2
-rw-r--r--indra/newview/llfloaterimsession.h1
-rw-r--r--indra/newview/llfloaterimsessiontab.h1
-rw-r--r--indra/newview/llfloaterland.cpp23
-rw-r--r--[-rwxr-xr-x]indra/newview/llfloatermap.cpp0
-rw-r--r--indra/newview/llfloaternotificationstabbed.cpp4
-rw-r--r--indra/newview/llfloaternotificationstabbed.h2
-rw-r--r--indra/newview/llfloaterpreference.cpp20
-rw-r--r--indra/newview/llfloaterpreferencesgraphicsadvanced.cpp35
-rw-r--r--indra/newview/llfloaterregioninfo.h4
-rw-r--r--indra/newview/llfloatersettingsdebug.cpp42
-rw-r--r--indra/newview/llfloatersimplesnapshot.cpp197
-rw-r--r--indra/newview/llfloateruipreview.cpp39
-rw-r--r--[-rwxr-xr-x]indra/newview/llfloaterworldmap.cpp0
-rw-r--r--indra/newview/llglsandbox.cpp12
-rw-r--r--indra/newview/llgltfmaterialpreviewmgr.cpp6
-rw-r--r--indra/newview/llinventorygallerymenu.cpp4
-rw-r--r--indra/newview/llinventorymodel.cpp16
-rw-r--r--indra/newview/llinventorymodel.h4
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.cpp35
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.h6
-rw-r--r--indra/newview/llkeyconflict.cpp2
-rw-r--r--indra/newview/lllocalbitmaps.cpp20
-rw-r--r--indra/newview/lllocalbitmaps.h3
-rw-r--r--indra/newview/lllocalgltfmaterials.cpp20
-rw-r--r--indra/newview/lllocalgltfmaterials.h3
-rw-r--r--indra/newview/lllocationinputctrl.h4
-rw-r--r--indra/newview/lllogchat.cpp12
-rw-r--r--indra/newview/lllookshistorypanel.h67
-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/llmutelist.cpp8
-rw-r--r--[-rwxr-xr-x]indra/newview/llnavigationbar.h0
-rw-r--r--indra/newview/lloutfitgallery.cpp2
-rw-r--r--indra/newview/lloutfitobserver.h2
-rw-r--r--indra/newview/llpaneldirland.cpp2
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp44
-rw-r--r--indra/newview/llpanelimcontrolpanel.h84
-rw-r--r--indra/newview/llpaneloutfitedit.cpp2
-rw-r--r--indra/newview/llpanelprofile.cpp158
-rw-r--r--indra/newview/llpanelvoicedevicesettings.cpp7
-rw-r--r--indra/newview/llpathfindingnavmesh.cpp3
-rw-r--r--indra/newview/llpreviewnotecard.cpp7
-rw-r--r--indra/newview/llpreviewscript.cpp7
-rw-r--r--indra/newview/llselectmgr.cpp2
-rw-r--r--indra/newview/llsettingsvo.cpp4
-rw-r--r--indra/newview/llsidepanelinventory.cpp2
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp5
-rw-r--r--indra/newview/llspatialpartition.cpp34
-rw-r--r--indra/newview/llspatialpartition.h13
-rw-r--r--indra/newview/llstartup.cpp11
-rw-r--r--indra/newview/llstatslistener.cpp200
-rw-r--r--indra/newview/llstatslistener.h (renamed from indra/newview/tests/llwlparamset_stub.cpp)30
-rw-r--r--indra/newview/lltexturecache.cpp176
-rw-r--r--indra/newview/lltexturecache.h3
-rw-r--r--indra/newview/lltextureview.cpp2
-rw-r--r--indra/newview/lltoastnotifypanel.cpp2
-rw-r--r--indra/newview/lltoolbarview.cpp2
-rw-r--r--indra/newview/lltoolview.cpp196
-rw-r--r--indra/newview/lltoolview.h84
-rw-r--r--indra/newview/llvelopack.cpp1
-rw-r--r--indra/newview/llversioninfo.cpp13
-rw-r--r--indra/newview/llversioninfo.h1
-rw-r--r--indra/newview/llversioninfovars.h.in (renamed from indra/newview/macutil_Prefix.h)24
-rw-r--r--indra/newview/llviewerassetstorage.cpp4
-rw-r--r--indra/newview/llviewerassetupload.cpp134
-rw-r--r--indra/newview/llviewercontrol.cpp30
-rw-r--r--indra/newview/llviewerdisplay.cpp13
-rw-r--r--indra/newview/llviewerinput.cpp2
-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.cpp29
-rw-r--r--indra/newview/llviewermenufile.cpp8
-rw-r--r--indra/newview/llviewermessage.cpp14
-rw-r--r--indra/newview/llvieweroctree.cpp2
-rw-r--r--indra/newview/llvieweroctree.h26
-rw-r--r--[-rwxr-xr-x]indra/newview/llviewerparceloverlay.cpp2
-rw-r--r--[-rwxr-xr-x]indra/newview/llviewerregion.cpp0
-rw-r--r--indra/newview/llviewershadermgr.cpp30
-rw-r--r--indra/newview/llviewerstats.cpp2
-rw-r--r--indra/newview/llviewerstats.h39
-rw-r--r--indra/newview/llviewerstatsrecorder.cpp2
-rw-r--r--indra/newview/llviewertexture.cpp16
-rw-r--r--indra/newview/llviewertexture.h1
-rw-r--r--indra/newview/llviewertexturelist.cpp32
-rw-r--r--indra/newview/llviewerwindow.cpp49
-rw-r--r--indra/newview/llviewerwindow.h5
-rw-r--r--indra/newview/llvoavatar.cpp18
-rw-r--r--indra/newview/llvoavatar.h8
-rw-r--r--indra/newview/llvocache.cpp12
-rw-r--r--indra/newview/llvoiceclient.cpp121
-rw-r--r--indra/newview/llvoicevisualizer.cpp1
-rw-r--r--indra/newview/llvoicewebrtc.cpp28
-rw-r--r--indra/newview/llvowlsky.cpp7
-rw-r--r--[-rwxr-xr-x]indra/newview/llworldmapview.cpp0
-rw-r--r--indra/newview/llxmlrpctransaction.cpp2
-rw-r--r--indra/newview/macview_Prefix.h229
-rw-r--r--indra/newview/pipeline.cpp61
-rw-r--r--[-rwxr-xr-x]indra/newview/res/have_artwork_bundle.marker0
-rw-r--r--[-rwxr-xr-x]indra/newview/res/viewerRes.rc0
-rw-r--r--[-rwxr-xr-x]indra/newview/secondlife-i686.supp0
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml78
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_script.xml4
-rw-r--r--[-rwxr-xr-x]indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml0
-rw-r--r--indra/newview/skins/default/xui/en/mime_types_linux.xml70
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_local.xml20
-rw-r--r--indra/newview/tests/gpus_results.txt3111
-rw-r--r--indra/newview/tests/gpus_seen.txt4225
-rw-r--r--indra/newview/tests/gpus_unmatched.txt9
-rw-r--r--indra/newview/tests/lldir_stub.cpp2
-rw-r--r--indra/newview/tests/llpipeline_stub.cpp32
-rw-r--r--indra/newview/tests/llremoteparcelrequest_test.cpp12
-rw-r--r--indra/newview/tests/llsechandler_basic_test.cpp4
-rw-r--r--indra/newview/tests/lltextureinfo_test.cpp81
-rw-r--r--indra/newview/tests/lltexturestatsuploader_test.cpp150
-rw-r--r--indra/newview/tests/llversioninfo_test.cpp2
-rw-r--r--indra/newview/tests/llvieweroctree_stub.cpp8
-rw-r--r--indra/newview/tests/llviewershadermgr_stub.cpp50
-rw-r--r--indra/newview/tests/llwlanimator_stub.cpp29
-rw-r--r--indra/newview/tests/llwlparammanager_test.cpp271
-rw-r--r--indra/newview/tests/llxmlrpclistener_test.cpp4
-rwxr-xr-xindra/newview/viewer_manifest.py170
-rw-r--r--indra/test/CMakeLists.txt109
-rw-r--r--indra/test/hexdump.h97
-rw-r--r--indra/test/llassetuploadqueue_tut.cpp195
-rw-r--r--indra/test/lltimestampcache_tut.cpp124
-rw-r--r--indra/test/lltranscode_tut.cpp86
-rw-r--r--indra/test/lltut.h4
-rw-r--r--indra/test/mock_http_client.cpp82
-rw-r--r--indra/test/mock_http_client.h190
-rw-r--r--indra/test/namedtempfile.h45
-rw-r--r--indra/test/prim_linkability_tut.cpp495
-rw-r--r--indra/test/test.cpp148
-rwxr-xr-x[-rw-r--r--]scripts/code_tools/fix_whitespace.py0
-rwxr-xr-x[-rw-r--r--]scripts/code_tools/fix_xml_indentations.py0
-rwxr-xr-x[-rw-r--r--]scripts/code_tools/modified-strings.sh0
-rwxr-xr-x[-rw-r--r--]scripts/code_tools/modified_strings.py0
-rwxr-xr-x[-rw-r--r--]scripts/content_tools/anim_tool.py0
-rwxr-xr-x[-rw-r--r--]scripts/content_tools/arche_tool.py0
-rwxr-xr-x[-rw-r--r--]scripts/content_tools/dae_tool.py0
-rwxr-xr-x[-rw-r--r--]scripts/content_tools/skel_tool.py0
-rw-r--r--[-rwxr-xr-x]scripts/messages/message_template.msg0
-rw-r--r--[-rwxr-xr-x]scripts/messages/message_template.msg.sha10
-rwxr-xr-x[-rw-r--r--]scripts/metrics/slp_conv.py0
-rwxr-xr-x[-rw-r--r--]scripts/metrics/viewer_asset_logs.py0
-rwxr-xr-x[-rw-r--r--]scripts/perf/logsdir.py0
-rwxr-xr-x[-rw-r--r--]scripts/perf/perfbot_run.py0
-rwxr-xr-x[-rw-r--r--]scripts/perf/profile_cmp.py0
-rwxr-xr-x[-rw-r--r--]scripts/perf/profile_csv.py0
-rwxr-xr-x[-rw-r--r--]scripts/perf/profile_pretty.py0
-rw-r--r--[-rwxr-xr-x]scripts/templates/template-cpp.cpp0
-rw-r--r--[-rwxr-xr-x]scripts/templates/template-h.h0
661 files changed, 18537 insertions, 30417 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 bbca953bad..84f58fe5e6 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -51,8 +51,9 @@ 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) }}
+ build_variant: [Viewer, Tests]
runs-on: ${{ matrix.runner }}
outputs:
viewer_channel: ${{ steps.build.outputs.viewer_channel }}
@@ -90,9 +91,9 @@ jobs:
DEVELOPER_DIR: "/Applications/Xcode_16.4.app/Contents/Developer"
# Ensure that Linden viewer builds engage Bugsplat.
BUGSPLAT_DB: ${{ needs.setup.outputs.bugsplat_db }}
- build_coverity: false
build_log_dir: ${{ github.workspace }}/.logs
- build_viewer: true
+ build_viewer: ${{ matrix.build_variant == 'Viewer' }}
+ build_tests: ${{ matrix.build_variant == 'Tests' }}
BUILDSCRIPTS_SHARED: ${{ github.workspace }}/.shared
# extracted and committed to viewer repo
BUILDSCRIPTS_SUPPORT_FUNCTIONS: ${{ github.workspace }}/buildscripts_support_functions
@@ -114,6 +115,20 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
+ - name: Linux Disk Cleanup
+ if: matrix.build_variant == 'Viewer' && runner.os == 'Linux'
+ run: |
+ # Prune various unused files from linux builder for Viewer build to fix 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@v7
with:
@@ -139,11 +154,27 @@ jobs:
uses: actions/cache@v6
with:
path: .autobuild-installables
- key: ${{ runner.os }}-64-${{ matrix.configuration }}-${{ hashFiles('autobuild.xml') }}
+ key: ${{ runner.os }}-64-${{ matrix.configuration }}-${{ matrix.build_variant }}-${{ hashFiles('autobuild.xml') }}
restore-keys: |
+ ${{ runner.os }}-64-${{ matrix.configuration }}-${{ matrix.build_variant }}-
${{ 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
@@ -299,7 +330,7 @@ jobs:
echo "artifact=$RUNNER_OS$cfg_suffix" >> $GITHUB_OUTPUT
- name: Upload executable
- if: steps.build.outputs.viewer_app
+ if: matrix.build_variant == 'Viewer' && steps.build.outputs.viewer_app
uses: actions/upload-artifact@v7
with:
name: "${{ steps.build.outputs.artifact }}-app"
@@ -309,7 +340,7 @@ jobs:
# The other upload of nontrivial size is the symbol file. Use a distinct
# artifact for that too.
- name: Upload symbol file
- if: steps.build.outputs.symbolfile
+ if: matrix.build_variant == 'Viewer' && steps.build.outputs.symbolfile
uses: actions/upload-artifact@v7
with:
name: "${{ steps.build.outputs.artifact }}-symbols"
@@ -317,6 +348,7 @@ jobs:
- name: Upload metadata
uses: actions/upload-artifact@v7
+ if: matrix.build_variant == 'Viewer'
with:
name: "${{ steps.build.outputs.artifact }}-metadata"
# emitted by build.sh, possibly multiple lines
@@ -326,13 +358,23 @@ jobs:
- name: Upload physics package
uses: actions/upload-artifact@v7
# should only be set for viewer-private
- if: matrix.configuration == 'Release' && steps.build.outputs.physicstpv
+ if: matrix.build_variant == 'Viewer' && matrix.configuration == 'Release' && steps.build.outputs.physicstpv
with:
name: "${{ steps.build.outputs.artifact }}-physics"
# emitted by build.sh, zero or one lines
path: |
${{ steps.build.outputs.physicstpv }}
+ - name: Upload appearance utility package
+ uses: actions/upload-artifact@v7
+ if: matrix.build_variant == 'Viewer' && 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 }}
@@ -491,12 +533,18 @@ jobs:
with:
pattern: "*-releases"
+ - uses: actions/download-artifact@v8
+ 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
@@ -520,6 +568,7 @@ jobs:
files: |
macOS-installer/*.dmg
Windows-installer/*.exe
+ *.tar.xz
*-autobuild-package.xml
*-viewer_version.txt
Windows-releases/*
diff --git a/.gitignore b/.gitignore
index 62a6b462f9..b471581456 100755
--- a/.gitignore
+++ b/.gitignore
@@ -20,11 +20,11 @@
/.autobuild-installables/
/.build-variables/
/.logs/
+.venv
CMakeCache.txt
cmake_install.cmake
LICENSES
-build-darwin-*
-build-linux-*
+build-*
debian/files
debian/secondlife-appearance-utility*
debian/secondlife-viewer*
diff --git a/LICENSE b/LICENSE
index 4362b49151..4362b49151 100755..100644
--- a/LICENSE
+++ b/LICENSE
diff --git a/autobuild.xml b/autobuild.xml
index 17d35d82e9..c91395cb65 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>
@@ -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>
@@ -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>
@@ -2516,7 +2319,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>
@@ -2607,11 +2410,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>72ed1f6d469a8ffaffd69be39b7af186d7c3b1d7</string>
+ <string>9622dbeb12d1c9592de3ea3f83c2c1a95b3c0822</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.22/webrtc-m137.7151.04.22.21966754211-darwin64-21966754211.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m144.7559.06.19.hot-mic/webrtc-m144.7559.06.19.hot-mic.29761579711-darwin64-29761579711.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -2621,11 +2424,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>b4d0c836d99491841c3816ff93bb2655a2817bd3</string>
+ <string>9113fdfafca5ca750e415abafaf080540346e068</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.22/webrtc-m137.7151.04.22.21966754211-linux64-21966754211.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m144.7559.06.19.hot-mic/webrtc-m144.7559.06.19.hot-mic.29761579711-linux64-29761579711.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -2635,11 +2438,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>ab2bddd77b1568b22b50ead13c1c33da94f4d59a</string>
+ <string>1d8a82b72887abfb1c5014fcca4337703dfdcd25</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.22/webrtc-m137.7151.04.22.21966754211-windows64-21966754211.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m144.7559.06.19.hot-mic/webrtc-m144.7559.06.19.hot-mic.29761579711-windows64-29761579711.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -2652,7 +2455,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.22.21966754211</string>
+ <string>m144.7559.06.19.hot-mic.29761579711</string>
<key>name</key>
<string>webrtc</string>
<key>vcs_branch</key>
@@ -3163,15 +2966,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>
@@ -3181,14 +2983,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>
@@ -3196,24 +3007,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>default</key>
+ <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>default</string>
+ <string>Release</string>
+ </map>
+ <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>ReleaseOS</string>
</map>
</map>
<key>build_directory</key>
@@ -3244,15 +3113,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>
@@ -3282,19 +3151,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>
@@ -3319,15 +3184,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>
@@ -3356,19 +3221,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..72dc2b96e8 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()
@@ -148,6 +150,7 @@ pre_build()
RELEASE_CRASH_REPORTING=OFF
HAVOK=OFF
+ TESTING=OFF
SIGNING=()
if [[ "$variant" != *OS ]]
then
@@ -163,6 +166,17 @@ 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 $build_tests
+ then
+ TESTING=ON
+ fi
+
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
then
case "$arch" in
@@ -187,7 +201,7 @@ pre_build()
"$autobuild" configure --quiet -c $variant \
${eval_autobuild_configure_parameters:---} \
- -DLL_TESTS:BOOL=ON \
+ -DLL_TESTS:BOOL="$TESTING" \
-DPACKAGE:BOOL=ON \
-DHAVOK:BOOL="$HAVOK" \
-DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
@@ -238,7 +252,18 @@ package_llphysicsextensions_tpv()
build()
{
local variant="$1"
- if $build_viewer
+ if $build_tests
+ then
+ begin_section "autobuild $variant tests"
+ # honor autobuild_build_parameters same as sling-buildscripts
+ export CTEST_OUTPUT_ON_FAILURE=1 # Output log on test failure
+ eval_autobuild_build_parameters=$(eval $(echo echo $autobuild_build_parameters))
+ "$autobuild" build --no-configure -c $variant \
+ $eval_autobuild_build_parameters -- --target BUILD_AND_RUN_TESTS \
+ || fatal "failed building $variant tests"
+ echo true >"$build_dir"/build_ok
+ end_section "autobuild $variant tests"
+ elif $build_viewer
then
begin_section "autobuild $variant"
# honor autobuild_build_parameters same as sling-buildscripts
@@ -394,12 +419,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 +557,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..09acfafaec
--- /dev/null
+++ b/doc/BUILD.LINUX.md
@@ -0,0 +1,87 @@
+# 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
+```
+
+To build with clang instead of gcc, also install:
+```
+sudo dnf install clang lld
+```
+
+### 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 (faster build; less stable)
+```
+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`
+
+### Troubleshooting
+- If you encounter warnings, try adding `-- -DGCC_DISABLE_FATAL_WARNINGS=TRUE` or `-DCLANG_DISABLE_FATAL_WARNINGS=TRUE` to the configure command
diff --git a/doc/LGPL-license.txt b/doc/LGPL-license.txt
index 4362b49151..4362b49151 100755..100644
--- a/doc/LGPL-license.txt
+++ b/doc/LGPL-license.txt
diff --git a/doc/LICENSE-logos.txt b/doc/LICENSE-logos.txt
index 66f8745f4f..66f8745f4f 100755..100644
--- a/doc/LICENSE-logos.txt
+++ b/doc/LICENSE-logos.txt
diff --git a/doc/LICENSE-source.txt b/doc/LICENSE-source.txt
index 3de5123415..3de5123415 100755..100644
--- a/doc/LICENSE-source.txt
+++ b/doc/LICENSE-source.txt
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 1f911a8b39..1f911a8b39 100755..100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
diff --git a/doc/releasenotes-where.txt b/doc/releasenotes-where.txt
index 4af5866905..4af5866905 100755..100644
--- a/doc/releasenotes-where.txt
+++ b/doc/releasenotes-where.txt
diff --git a/doc/translations.txt b/doc/translations.txt
index 9b7f2d6292..9b7f2d6292 100755..100644
--- a/doc/translations.txt
+++ b/doc/translations.txt
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 72347446b9..27d7f9e61f 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -11,10 +11,15 @@
#
# 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}")
@@ -28,6 +33,8 @@ if (DARWIN)
# clamped deployment target.
string(REGEX REPLACE "-mmacosx-version-min=[0-9.]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif (DARWIN)
+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.
@@ -36,7 +43,7 @@ endif (DARWIN)
# 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
@@ -122,7 +129,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}")
@@ -136,9 +143,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
@@ -146,42 +150,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}")
@@ -195,21 +227,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/Boost.cmake b/indra/cmake/Boost.cmake
index bf34d1beae..eba39a4b19 100644
--- a/indra/cmake/Boost.cmake
+++ b/indra/cmake/Boost.cmake
@@ -1,5 +1,6 @@
# -*- cmake -*-
include(Prebuilt)
+include(Linking)
include_guard()
@@ -16,124 +17,76 @@ use_prebuilt_binary(boost)
# with the address size.
set(addrsfx "-x${ADDRESS_SIZE}")
-if (WINDOWS)
-
- find_library(BOOST_CONTEXT_LIBRARY
- NAMES
- libboost_context
- libboost_context-mt
- libboost_context-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_FIBER_LIBRARY
- NAMES
- libboost_fiber
- libboost_fiber-mt
- libboost_fiber-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_FILESYSTEM_LIBRARY
- NAMES
- libboost_filesystem
- libboost_filesystem-mt
- libboost_filesystem-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_PROGRAMOPTIONS_LIBRARY
- NAMES
- libboost_program_options
- libboost_program_options-mt
- libboost_program_options-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_THREAD_LIBRARY
- NAMES
- libboost_thread
- libboost_thread-mt
- libboost_thread-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_URL_LIBRARY
- NAMES
- libboost_url
- libboost_url-mt
- libboost_url-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+find_library(BOOST_CONTEXT_LIBRARY
+ NAMES
+ libboost_context
+ libboost_context-mt
+ libboost_context-mt${addrsfx}
+ boost_context
+ boost_context-mt
+ boost_context-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- # Add Boost.Process library
- find_library(BOOST_PROCESS_LIBRARY
- NAMES
- libboost_process
- libboost_process-mt
- libboost_process-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+find_library(BOOST_FIBER_LIBRARY
+ NAMES
+ libboost_fiber
+ libboost_fiber-mt
+ libboost_fiber-mt${addrsfx}
+ boost_fiber
+ boost_fiber-mt
+ boost_fiber-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-else (WINDOWS)
+find_library(BOOST_FILESYSTEM_LIBRARY
+ NAMES
+ libboost_filesystem
+ libboost_filesystem-mt
+ libboost_filesystem-mt${addrsfx}
+ boost_filesystem
+ boost_filesystem-mt
+ boost_filesystem-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- find_library(BOOST_CONTEXT_LIBRARY
- NAMES
- boost_context
- boost_context-mt
- boost_context-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+find_library(BOOST_PROGRAMOPTIONS_LIBRARY
+ NAMES
+ libboost_program_options
+ libboost_program_options-mt
+ libboost_program_options-mt${addrsfx}
+ boost_program_options
+ boost_program_options-mt
+ boost_program_options-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- find_library(BOOST_FIBER_LIBRARY
- NAMES
- boost_fiber
- boost_fiber-mt
- boost_fiber-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
+find_library(BOOST_URL_LIBRARY
+ NAMES
+ libboost_url
+ libboost_url-mt
+ libboost_url-mt${addrsfx}
+ boost_url
+ boost_url-mt
+ boost_url-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
- find_library(BOOST_FILESYSTEM_LIBRARY
- NAMES
- boost_filesystem
- boost_filesystem-mt
- boost_filesystem-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_PROGRAMOPTIONS_LIBRARY
- NAMES
- boost_program_options
- boost_program_options-mt
- boost_program_options-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_THREAD_LIBRARY
- NAMES
- boost_thread
- boost_thread-mt
- boost_thread-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- find_library(BOOST_URL_LIBRARY
- NAMES
- boost_url
- boost_url-mt
- boost_url-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
- # Add Boost.Process library
- find_library(BOOST_PROCESS_LIBRARY
- NAMES
- boost_process
- boost_process-mt
- boost_process-mt${addrsfx}
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
-
-endif (WINDOWS)
+find_library(BOOST_PROCESS_LIBRARY
+ NAMES
+ libboost_process
+ libboost_process-mt
+ libboost_process-mt${addrsfx}
+ boost_process
+ boost_process-mt
+ boost_process-mt${addrsfx}
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
target_link_libraries(ll::boost INTERFACE
${BOOST_FIBER_LIBRARY}
${BOOST_CONTEXT_LIBRARY}
${BOOST_FILESYSTEM_LIBRARY}
${BOOST_PROGRAMOPTIONS_LIBRARY}
- ${BOOST_THREAD_LIBRARY}
${BOOST_URL_LIBRARY}
${BOOST_PROCESS_LIBRARY})
if (WINDOWS)
- # Boost.Process v2 on Windows requires ntdll for NtSuspendProcess,
- # NtResumeProcess and RtlNtStatusToDosError
+ # Boost.Process v2 needs ntdll (NtSuspendProcess/NtResumeProcess)
target_link_libraries(ll::boost INTERFACE ntdll)
endif (WINDOWS)
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 c10f6ec934..820006bb5a 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 667a04a1c5..def3feaa71 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -75,6 +75,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)
@@ -112,6 +115,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
@@ -173,17 +177,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..03f3fd1619 100644
--- a/indra/cmake/LLKDU.cmake
+++ b/indra/cmake/LLKDU.cmake
@@ -14,19 +14,17 @@ 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
+ kdu.lib
+ libkdu.a
+ PATHS
+ "${ARCH_PREBUILT_DIRS_RELEASE}"
+ "${AUTOBUILD_INSTALL_DIR}/lib"
+ PATH_SUFFIXES 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..77543a653f 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,13 +37,37 @@ macro (use_prebuilt_binary _binary)
--install-dir=${AUTOBUILD_INSTALL_DIR}
${_binary} ")
endif(DEBUG_PREBUILT)
- execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}"
- install
- --install-dir=${AUTOBUILD_INSTALL_DIR}
- ${_binary}
- WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
- RESULT_VARIABLE ${_binary}_installed
- )
+ message(STATUS "Installing ${_binary}...")
+
+ # Retry transient download failures (e.g. remote disconnects) instead
+ # of failing the whole configure on the first attempt.
+ set(_max_retries 4)
+ set(_retry_delay 8)
+ set(${_binary}_installed 1)
+
+ foreach(_attempt RANGE 1 ${_max_retries})
+ if(DEBUG_PREBUILT)
+ message(STATUS "autobuild install ${_binary}: attempt ${_attempt}/${_max_retries}")
+ endif(DEBUG_PREBUILT)
+ execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}"
+ install
+ --skip-source-environment
+ --install-dir=${AUTOBUILD_INSTALL_DIR}
+ ${_binary}
+ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+ RESULT_VARIABLE ${_binary}_installed
+ )
+
+ if(${${_binary}_installed} EQUAL 0)
+ break()
+ endif()
+
+ if(_attempt LESS _max_retries)
+ message(WARNING "autobuild install ${_binary} failed (rc=${${_binary}_installed}); retrying in ${_retry_delay}s")
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep ${_retry_delay})
+ endif()
+ endforeach()
+
file(WRITE ${PREBUILD_TRACKING_DIR}/${_binary}_installed "${${_binary}_installed}")
endif(${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0)
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 baa93bd128..405f2cd742 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")
@@ -203,6 +229,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 5974a5d212..b77993afb1 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 d2a8fcca46..0ba12e68eb 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)
@@ -42,6 +43,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..85c5a8cdd4 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;
@@ -525,7 +530,7 @@ int main(int argc, char** argv)
}
else
{
- LLFastTimer::sMetricLog = TRUE;
+ LLFastTimer::sMetricLog = true;
LLFastTimer::sLogName = test_name;
arg += 1; // Skip that arg now we know it's a valid test name
if ((arg + 1) == argc) // Break out of the loop if we reach the end of the arg list
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/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp
index efb9c47a91..86783049cb 100644
--- a/indra/integration_tests/llui_libtest/llui_libtest.cpp
+++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp
@@ -187,7 +187,7 @@ void export_test_floaters()
LLXMLNodePtr output_node = new LLXMLNode();
LLFloater* floater = new LLFloater(LLSD());
floater->buildFromFile( filename,
- // FALSE, // don't open floater
+ // false, // don't open floater
output_node);
std::string out_filename = gDirUtilp->add(xui_dir, filename);
std::string::size_type extension_pos = out_filename.rfind(".xml");
diff --git a/indra/lib/python/indra/__init__.py b/indra/lib/python/indra/__init__.py
index 0c5053cf49..0c5053cf49 100755..100644
--- a/indra/lib/python/indra/__init__.py
+++ b/indra/lib/python/indra/__init__.py
diff --git a/indra/lib/python/indra/ipc/__init__.py b/indra/lib/python/indra/ipc/__init__.py
index 302bbf4a03..302bbf4a03 100755..100644
--- a/indra/lib/python/indra/ipc/__init__.py
+++ b/indra/lib/python/indra/ipc/__init__.py
diff --git a/indra/lib/python/indra/ipc/compatibility.py b/indra/lib/python/indra/ipc/compatibility.py
index d6ab4f15d5..d6ab4f15d5 100755..100644
--- a/indra/lib/python/indra/ipc/compatibility.py
+++ b/indra/lib/python/indra/ipc/compatibility.py
diff --git a/indra/lib/python/indra/ipc/llmessage.py b/indra/lib/python/indra/ipc/llmessage.py
index 235729944c..235729944c 100755..100644
--- a/indra/lib/python/indra/ipc/llmessage.py
+++ b/indra/lib/python/indra/ipc/llmessage.py
diff --git a/indra/lib/python/indra/ipc/tokenstream.py b/indra/lib/python/indra/ipc/tokenstream.py
index a8e0a17e9c..a8e0a17e9c 100755..100644
--- a/indra/lib/python/indra/ipc/tokenstream.py
+++ b/indra/lib/python/indra/ipc/tokenstream.py
diff --git a/indra/lib/python/indra/util/__init__.py b/indra/lib/python/indra/util/__init__.py
index b004e5804f..b004e5804f 100755..100644
--- a/indra/lib/python/indra/util/__init__.py
+++ b/indra/lib/python/indra/util/__init__.py
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 0ad0b6b1a9..0ad0b6b1a9 100755..100644
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
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/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp
index 1162efb868..b93a232419 100644
--- a/indra/llappearance/llpolymesh.cpp
+++ b/indra/llappearance/llpolymesh.cpp
@@ -280,7 +280,7 @@ bool LLPolyMeshSharedData::loadMesh( const std::string& fileName )
LL_ERRS() << "Filename is Empty!" << LL_ENDL;
return false;
}
- LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/
+ LLFILE* fp = LLFile::fopen(fileName, LLFILE_MODE("rb")); /*Flawfinder: ignore*/
if (!fp)
{
LLError::LLUserWarningMsg::showMissingFiles();
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 19e4e8ed9d..5a02dfe716 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..cdc9cfdf40
--- /dev/null
+++ b/indra/llappearanceutility/llappappearanceutility.cpp
@@ -0,0 +1,683 @@
+/**
+ * @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"
+
+#include "apr_getopt.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/newview/tests/llwldaycycle_stub.cpp b/indra/llappearanceutility/llbakingjoint.h
index cd82e9b200..10201cc7b8 100644
--- a/indra/newview/tests/llwldaycycle_stub.cpp
+++ b/indra/llappearanceutility/llbakingjoint.h
@@ -1,10 +1,10 @@
/**
- * @file llwldaycycle_stub.cpp
- * @brief stub class to allow unit testing
+ * @file llbakingjoint.h
+ * @brief Declaration of LLBakingJoint class
*
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2011, 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,29 +24,22 @@
* $/LicenseInfo$
*/
-LLWLDayCycle::LLWLDayCycle(void)
-{
-}
+#ifndef LL_LLBAKINGJOINT_H
+#define LL_LLBAKINGJOINT_H
-LLWLDayCycle::~LLWLDayCycle(void)
-{
-}
+#include "llavatarjoint.h"
-bool LLWLDayCycle::getKeytime(LLWLParamKey keyFrame, F32& keyTime)
+class alignas(16) LLBakingJoint : public virtual LLAvatarJoint
{
- keyTime = 0.5;
- return true;
-}
+ LL_ALIGN_NEW
+public:
+ LLBakingJoint();
+ LLBakingJoint(S32 joint_num);
+ virtual ~LLBakingJoint();
-bool LLWLDayCycle::removeKeyframe(F32 time)
-{
- return true;
-}
+ // LLViewerJoint interface
+ U32 render( F32 pixelArea, bool first_pass = true, bool is_dummy = false ) override;
+};
-void LLWLDayCycle::loadDayCycleFromFile(const std::string& fileName)
-{
-}
+#endif /* LL_LLBAKINGJOINT_H */
-void LLWLDayCycle::removeReferencesTo(const LLWLParamKey &keyframe)
-{
-}
diff --git a/indra/llcommon/llbase32.h b/indra/llappearanceutility/llbakingjointmesh.cpp
index 8cfbd7ef53..b8e3283df2 100644
--- a/indra/llcommon/llbase32.h
+++ b/indra/llappearanceutility/llbakingjointmesh.cpp
@@ -1,11 +1,10 @@
/**
- * @file llbase32.h
- * @brief base32 encoding that returns a std::string
- * @author James Cook
+ * @file llbakingjointmesh.cpp
+ * @brief Implementation of LLBakingJointMesh class
*
- * $LicenseInfo:firstyear=2007&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
@@ -25,13 +24,20 @@
* $/LicenseInfo$
*/
-#ifndef LLBASE32_H
-#define LLBASE32_H
-class LL_COMMON_API LLBase32
+#include "linden_common.h"
+
+#include "llbakingjointmesh.h"
+
+
+LLBakingJointMesh::LLBakingJointMesh() :
+ LLAvatarJointMesh()
{
-public:
- static std::string encode(const U8* input, size_t input_size);
-};
+}
+
+// virtual
+LLBakingJointMesh::~LLBakingJointMesh()
+{
+}
+
-#endif
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/newview/llappviewerlinux_api_dbus.h b/indra/llappearanceutility/llbakingprocess.cpp
index 2f4492bd7a..85553b0fdb 100644
--- a/indra/newview/llappviewerlinux_api_dbus.h
+++ b/indra/llappearanceutility/llbakingprocess.cpp
@@ -1,10 +1,10 @@
/**
- * @file llappviewerlinux_api_dbus.h
- * @brief DBus-glib symbol handling
+ * @file llbakingprocess.cpp
+ * @brief Implementation of LLBakingProcess class.
*
- * $LicenseInfo:firstyear=2008&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,21 +24,24 @@
* $/LicenseInfo$
*/
+// linden includes
#include "linden_common.h"
-#if LL_DBUS_ENABLED
+#include "llsd.h"
+#include "llsdserialize.h"
-extern "C" {
-#include <dbus/dbus-glib.h>
-}
-
-#define DBUSGLIB_DYLIB_DEFAULT_NAME "libdbus-glib-1.so.2"
+// project includes
+#include "llappappearanceutility.h"
+#include "llbakingprocess.h"
-bool grab_dbus_syms(std::string dbus_dso_name);
-void ungrab_dbus_syms();
+// virtual
+void LLBakingProcess::parseInput(std::istream& input)
+{
+ LLSDSerialize::fromXML( mInputData, input );
+ if (mInputData.isUndefined())
+ {
+ throw LLAppException(RV_UNABLE_TO_PARSE);
+ }
+}
-#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/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/media_plugins/gstreamer010/llmediaimplgstreamer.h b/indra/llappearanceutility/llbakingwearablesdata.h
index cae11a5cb3..1db2ca4bc1 100644
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
+++ b/indra/llappearanceutility/llbakingwearablesdata.h
@@ -1,12 +1,10 @@
/**
- * @file llmediaimplgstreamer.h
- * @author Tofu Linden
- * @brief implementation that supports media playback via GStreamer.
+ * @file llbakingwearablesdata.h
+ * @brief Declaration of LLBakingWearablesData class
*
- * @cond
- * $LicenseInfo:firstyear=2007&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,30 +22,34 @@
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
- * @endcond
*/
-// header guard
-#ifndef llmediaimplgstreamer_h
-#define llmediaimplgstreamer_h
+#ifndef LL_LLBAKINGWEARABLESDATA_H
+#define LL_LLBAKINGWEARABLESDATA_H
-#if LL_GSTREAMER010_ENABLED
+#include "llwearabledata.h"
-extern "C" {
-#include <stdio.h>
-#include <gst/gst.h>
+class LLBakingWearable;
-#include "apr_pools.h"
-#include "apr_dso.h"
-}
+class LLBakingWearablesData : public LLWearableData
+{
+public:
+ LLBakingWearablesData();
+ virtual ~LLBakingWearablesData();
+ void setWearableOutfit(LLSD& sd);
-extern "C" {
-gboolean llmediaimplgstreamer_bus_callback (GstBus *bus,
- GstMessage *message,
- gpointer data);
-}
+ //--------------------------------------------------------------------
+ // I/O methods
+ //--------------------------------------------------------------------
+public:
+ void asLLSD(LLSD& sd) const;
-#endif // LL_GSTREAMER010_ENABLED
+private:
+ typedef std::vector<LLBakingWearable*> wearable_list_t;
+ wearable_list_t mWearables;
+
+};
+
+#endif /* LL_LLBAKINGWEARABLESDATA_H */
-#endif // llmediaimplgstreamer_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/newview/tests/llglslshader_stub.cpp b/indra/llappearanceutility/llbakingwindow.h
index 537434a6d8..a6bf1d8714 100644
--- a/indra/newview/tests/llglslshader_stub.cpp
+++ b/indra/llappearanceutility/llbakingwindow.h
@@ -1,10 +1,10 @@
/**
- * @file llglslshader_stub.cpp
- * @brief stub class to allow unit testing
+ * @file llbakingwindow.h
+ * @brief Declaration of LLBakingWindow class.
*
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2011, 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,16 +24,22 @@
* $/LicenseInfo$
*/
-#include "llglslshader.h"
+#ifndef LL_LLBAKINGWINDOW_H
+#define LL_LLBAKINGWINDOW_H
-void LLGLSLShader::uniform1f(const std::string& uniform, F32 num)
-{
-}
+#include "llwindow.h"
+#include "llwindowcallbacks.h"
-void LLGLSLShader::uniform3fv(const std::string& uniform, U32 count, const GLfloat *v)
+class LLBakingWindow : public LLWindowCallbacks
{
-}
+public:
+ LLBakingWindow(S32 width, S32 height);
+ ~LLBakingWindow();
+
+ void swapBuffers();
+private:
+ LLWindow* mWindow;
+};
+
+#endif /* LL_LLBAKINGWINDOW_H */
-void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
-{
-}
diff --git a/indra/llappearanceutility/llprocessparams.cpp b/indra/llappearanceutility/llprocessparams.cpp
new file mode 100644
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/newview/tests/llsky_stub.cpp b/indra/llappearanceutility/llprocessskin.h
index 8faca2665a..a3cc8c7087 100644
--- a/indra/newview/tests/llsky_stub.cpp
+++ b/indra/llappearanceutility/llprocessskin.h
@@ -1,10 +1,10 @@
/**
- * @file llsky_stub.cpp
- * @brief stub class to allow unit testing
+ * @file llprocessskin.h
+ * @brief Declaration of LLProcessSkin class.
*
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2011, 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,14 +24,20 @@
* $/LicenseInfo$
*/
-class LLSky
+#ifndef LL_LLPROCESSSKIN_H
+#define LL_LLPROCESSSKIN_H
+
+#include "llbakingprocess.h"
+class LLProcessSkin : public LLBakingProcess
{
public:
- void setOverrideSun(BOOL override);
- void setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity);
+ LLProcessSkin(LLAppAppearanceUtility* app) :
+ LLBakingProcess(app) {}
+ void process(std::ostream& output) override;
+
+private:
+
};
-void LLSky::setOverrideSun(BOOL override) {}
-void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity) {}
+#endif /* LL_LLPROCESSSKIN_H */
-LLSky gSky;
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/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index d8a6fffea6..232b429130 100755..100644
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -199,7 +199,7 @@ bool LLVorbisDecodeState::initDecode()
LL_DEBUGS("AudioEngine") << "Initing decode from vfile: " << mUUID << LL_ENDL;
mInFilep = new LLFileSystem(mUUID, LLAssetType::AT_SOUND);
- if (!mInFilep || !mInFilep->getSize())
+ if (!mInFilep || mInFilep->getSize() <= 0)
{
LL_WARNS("AudioEngine") << "unable to open vorbis source vfile for reading" << LL_ENDL;
delete mInFilep;
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index a9a229c0a5..a9a229c0a5 100755..100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt
index c6513cdb66..9dbbddde8a 100644
--- a/indra/llcharacter/CMakeLists.txt
+++ b/indra/llcharacter/CMakeLists.txt
@@ -66,3 +66,19 @@ target_link_libraries(
llfilesystem
llxml
)
+
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llcharacter REUSE_FROM llprecompiled)
+endif ()
+
+
+if (LL_TESTS)
+ include(LLAddBuildTest)
+# SET(llcharacter_TEST_SOURCE_FILES
+# )
+# LL_ADD_PROJECT_UNIT_TESTS(llcharacter "${llcharacter_TEST_SOURCE_FILES}")
+
+ #set(TEST_DEBUG on)
+ set(test_libs llcommon llmath)
+ LL_ADD_INTEGRATION_TEST(lljoint "lljoint.cpp" "${test_libs}")
+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/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index be1c74a908..4e5a920230 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -589,7 +589,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
}
else
{
- LL_WARNS() << "Failed to allocate buffer: " << anim_file_size << mID << LL_ENDL;
+ LL_WARNS() << "Failed to allocate buffer: " << anim_file_size << " " << mID << LL_ENDL;
}
delete anim_file;
anim_file = NULL;
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 0ed47be064..edaecaf96e 100644
--- a/indra/llcharacter/llvisualparam.h
+++ b/indra/llcharacter/llvisualparam.h
@@ -101,8 +101,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 std::function<LLVisualParam*(S32)> visual_param_mapper;
@@ -182,6 +181,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 32226a62e6..bff3c66924 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -22,7 +22,6 @@ set(llcommon_SOURCE_FILES
llapr.cpp
llassettype.cpp
llatomic.cpp
- llbase32.cpp
llbase64.cpp
llbitpack.cpp
llcallbacklist.cpp
@@ -69,7 +68,7 @@ set(llcommon_SOURCE_FILES
llmortician.cpp
llmutex.cpp
llpointer.cpp
- llptrto.cpp
+ llptrto.cpp
llpredicate.cpp
llprocess.cpp
llprocessor.cpp
@@ -86,7 +85,6 @@ set(llcommon_SOURCE_FILES
llsdutil.cpp
llsingleton.cpp
llstacktrace.cpp
- llstreamqueue.cpp
llstreamtools.cpp
llstring.cpp
llstringtable.cpp
@@ -110,7 +108,7 @@ set(llcommon_SOURCE_FILES
workqueue.cpp
StackWalker.cpp
)
-
+
set(llcommon_HEADER_FILES
CMakeLists.txt
@@ -119,8 +117,6 @@ set(llcommon_HEADER_FILES
chrono.h
classic_callback.h
commoncontrol.h
- ctype_workaround.h
- fix_macros.h
fsyspath.h
function_types.h
indra_constants.h
@@ -131,7 +127,6 @@ set(llcommon_HEADER_FILES
llapr.h
llassettype.h
llatomic.h
- llbase32.h
llbase64.h
llbitpack.h
llboost.h
@@ -219,7 +214,6 @@ set(llcommon_HEADER_FILES
llsingleton.h
llstacktrace.h
llstl.h
- llstreamqueue.h
llstreamtools.h
llstrider.h
llstring.h
@@ -252,20 +246,33 @@ set(llcommon_HEADER_FILES
threadpool.h
threadpool_fwd.h
threadsafeschedule.h
- timer.h
tuple.h
u64.h
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})
@@ -283,8 +290,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)
@@ -302,16 +313,21 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(classic_callback "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lazyeventapi "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llapp "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llbase64 "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llcond "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldate "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldeadmantimer "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldependencies "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(lldoubledispatch "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llerror "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventfilter "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llevents "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llfile "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llhttpdate "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llheteromap "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llinstancetracker "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}")
@@ -321,9 +337,11 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocinfo "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llsd "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llsdutil "" "llcommon;llmath")
LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llstreamtools "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltrace "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
@@ -339,4 +357,11 @@ if (LL_TESTS)
## throwing and catching exceptions.
##LL_ADD_INTEGRATION_TEST(llexception "" "${test_libs}")
+ # Skip precompiled header for tests that need special handling
+ set_source_files_properties(
+ tests/llsd_test.cpp
+ PROPERTIES
+ SKIP_PRECOMPILE_HEADERS TRUE
+ )
+
endif (LL_TESTS)
diff --git a/indra/llcommon/StackWalker.cpp b/indra/llcommon/StackWalker.cpp
index e9ae1723fb..a281fe83f6 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;
@@ -902,7 +904,7 @@ bool StackWalker::LoadModules()
SetLastError(ERROR_DLL_INIT_FAILED);
return false;
}
- if (m_modulesLoaded != FALSE)
+ if (m_modulesLoaded)
return true;
// Build the sym-path:
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/ctype_workaround.h b/indra/llcommon/ctype_workaround.h
deleted file mode 100644
index 89a47fe3db..0000000000
--- a/indra/llcommon/ctype_workaround.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * @file ctype_workaround.h
- * @brief The workaround is to create some legacy symbols that point
- * to the correct symbols, which avoids link errors.
- *
- * $LicenseInfo:firstyear=2006&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 _CTYPE_WORKAROUND_H_
-#define _CTYPE_WORKAROUND_H_
-
-/**
- * the CTYPE_WORKAROUND is needed for linux dev stations that don't
- * have the broken libc6 packages needed by our out-of-date static
- * libs (such as libcrypto and libcurl).
- *
- * -- Leviathan 20060113
-*/
-
-#include <cctype>
-
-__const unsigned short int *__ctype_b;
-__const __int32_t *__ctype_tolower;
-__const __int32_t *__ctype_toupper;
-
-// call this function at the beginning of main()
-void ctype_workaround()
-{
- __ctype_b = *(__ctype_b_loc());
- __ctype_toupper = *(__ctype_toupper_loc());
- __ctype_tolower = *(__ctype_tolower_loc());
-}
-
-#endif
-
diff --git a/indra/llcommon/fix_macros.h b/indra/llcommon/fix_macros.h
deleted file mode 100644
index ed6c26a371..0000000000
--- a/indra/llcommon/fix_macros.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * @file fix_macros.h
- * @author Nat Goodspeed
- * @date 2012-11-16
- * @brief The Mac system headers seem to #define macros with obnoxiously
- * generic names, preventing any library from using those names. We've
- * had to fix these in so many places that it's worth making a header
- * file to handle it.
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Copyright (c) 2012, Linden Research, Inc.
- * $/LicenseInfo$
- */
-
-// DON'T use an #include guard: every time we encounter this header, #undef
-// these macros all over again.
-
-// who injects MACROS with such generic names?! Grr.
-#ifdef check
-#undef check
-#endif
diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h
index 2c900c02a7..237d99ae86 100644
--- a/indra/llcommon/fsyspath.h
+++ b/indra/llcommon/fsyspath.h
@@ -57,7 +57,7 @@ class fsyspath: public std::filesystem::path
public:
// default
- fsyspath() {}
+ fsyspath() = default;
// construct from UTF-8 encoded string
fsyspath(const std::string& path): fsyspath(std::string_view(path)) {}
fsyspath(const char* path): fsyspath(std::string_view(path)) {}
@@ -66,8 +66,10 @@ public:
{}
// construct from existing path
fsyspath(const super& path): super(path) {}
+ fsyspath(super&& path) : super(std::move(path)) {}
fsyspath& operator=(const super& p) { super::operator=(p); return *this; }
+ fsyspath& operator=(super&& p) { super::operator=(std::move(p)); return *this; }
fsyspath& operator=(const std::string& p) { return (*this) = std::string_view(p); }
fsyspath& operator=(const char* p) { return (*this) = std::string_view(p); }
fsyspath& operator=(std::string_view p)
diff --git a/indra/llcommon/hexdump.h b/indra/llcommon/hexdump.h
index ab5ba2b16d..ab5ba2b16d 100755..100644
--- a/indra/llcommon/hexdump.h
+++ b/indra/llcommon/hexdump.h
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index f92bb98ba6..02d6da989a 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -37,7 +37,7 @@
#endif
#include "llcommon.h"
-#include "llapr.h"
+
#include "llerrorcontrol.h"
#include "llframetimer.h"
#include "lllivefile.h"
@@ -53,19 +53,13 @@
//
// Signal handling
#ifndef LL_WINDOWS
+#include "apr_signal.h"
+
# include <signal.h>
# include <unistd.h> // for fork()
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;
@@ -721,47 +715,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 06eb4c389f..e1d80c5dea 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -230,7 +230,6 @@ 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];
apr_strerror(status, buf, sizeof(buf));
@@ -260,7 +259,6 @@ bool _ll_apr_warn_status(apr_status_t status, const char* file, int line)
#else
LL_WARNS("APR") << "APR: " << file << ":" << line << " " << buf << " (0x" << std::hex << status << std::dec << ")" << LL_ENDL;
#endif
-#endif
return true;
}
@@ -552,226 +550,6 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
}
}
-//static
-S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
-{
- LL_PROFILE_ZONE_SCOPED;
- //*****************************************
- LLAPRFilePoolScope scope(pool);
- apr_file_t* file_handle = open(filename, scope.getVolatileAPRPool(), APR_READ|APR_BINARY);
- //*****************************************
- if (!file_handle)
- {
- return 0;
- }
-
- llassert(offset >= 0);
-
- if (offset > 0)
- offset = LLAPRFile::seek(file_handle, APR_SET, offset);
-
- apr_size_t bytes_read;
- if (offset < 0)
- {
- bytes_read = 0;
- }
- else
- {
- bytes_read = nbytes ;
- apr_status_t s = apr_file_read(file_handle, buf, &bytes_read);
- if (s != APR_SUCCESS)
- {
- LL_WARNS("APR") << " Attempting to read filename: " << filename << LL_ENDL;
- ll_apr_warn_status(s);
- bytes_read = 0;
- }
- else
- {
- llassert_always(bytes_read <= 0x7fffffff);
- }
- }
-
- //*****************************************
- close(file_handle) ;
- //*****************************************
- return (S32)bytes_read;
-}
-
-//static
-S32 LLAPRFile::writeEx(const std::string& filename, const void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
-{
- LL_PROFILE_ZONE_SCOPED;
- apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
- if (offset < 0)
- {
- flags |= APR_APPEND;
- offset = 0;
- }
-
- //*****************************************
- LLAPRFilePoolScope scope(pool);
- apr_file_t* file_handle = open(filename, scope.getVolatileAPRPool(), flags);
- //*****************************************
- if (!file_handle)
- {
- return 0;
- }
-
- if (offset > 0)
- {
- offset = LLAPRFile::seek(file_handle, APR_SET, offset);
- }
-
- apr_size_t bytes_written;
- if (offset < 0)
- {
- bytes_written = 0;
- }
- else
- {
- bytes_written = nbytes ;
- apr_status_t s = apr_file_write(file_handle, buf, &bytes_written);
- if (s != APR_SUCCESS)
- {
- LL_WARNS("APR") << "Attempting to write filename: " << filename << LL_ENDL;
- if (APR_STATUS_IS_ENOSPC(s))
- {
- LLApp::notifyOutOfDiskSpace();
- }
- ll_apr_warn_status(s);
- bytes_written = 0;
- }
- else
- {
- llassert_always(bytes_written <= 0x7fffffff);
- }
- }
-
- //*****************************************
- LLAPRFile::close(file_handle);
- //*****************************************
-
- return (S32)bytes_written;
-}
-
-//static
-bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)
-{
- apr_status_t s;
-
- LLAPRFilePoolScope scope(pool);
- s = apr_file_remove(filename.c_str(), scope.getVolatileAPRPool());
-
- if (s != APR_SUCCESS)
- {
- ll_apr_warn_status(s);
- LL_WARNS("APR") << " Attempting to remove filename: " << filename << LL_ENDL;
- return false;
- }
- return true;
-}
-
-//static
-bool LLAPRFile::rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool)
-{
- apr_status_t s;
-
- LLAPRFilePoolScope scope(pool);
- s = apr_file_rename(filename.c_str(), newname.c_str(), scope.getVolatileAPRPool());
-
- if (s != APR_SUCCESS)
- {
- ll_apr_warn_status(s);
- LL_WARNS("APR") << " Attempting to rename filename: " << filename << LL_ENDL;
- return false;
- }
- return true;
-}
-
-//static
-bool LLAPRFile::isExist(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
-{
- apr_file_t* apr_file;
- apr_status_t s;
-
- LLAPRFilePoolScope scope(pool);
- s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, scope.getVolatileAPRPool());
-
- if (s != APR_SUCCESS || !apr_file)
- {
- return false;
- }
- else
- {
- apr_file_close(apr_file) ;
- return true;
- }
-}
-
-//static
-S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool)
-{
- apr_file_t* apr_file;
- apr_finfo_t info;
- apr_status_t s;
-
- LLAPRFilePoolScope scope(pool);
- s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, scope.getVolatileAPRPool());
-
- if (s != APR_SUCCESS || !apr_file)
- {
- return 0;
- }
- else
- {
- apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);
-
- apr_file_close(apr_file) ;
-
- if (s == APR_SUCCESS)
- {
- return (S32)info.size;
- }
- else
- {
- return 0;
- }
- }
-}
-
-//static
-bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool)
-{
- apr_status_t s;
-
- LLAPRFilePoolScope scope(pool);
- s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, scope.getVolatileAPRPool());
-
- if (s != APR_SUCCESS)
- {
- ll_apr_warn_status(s);
- LL_WARNS("APR") << " Attempting to make directory: " << dirname << LL_ENDL;
- return false;
- }
- return true;
-}
-
-//static
-bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool)
-{
- apr_status_t s;
-
- LLAPRFilePoolScope scope(pool);
- s = apr_file_remove(dirname.c_str(), scope.getVolatileAPRPool());
-
- if (s != APR_SUCCESS)
- {
- ll_apr_warn_status(s);
- LL_WARNS("APR") << " Attempting to remove directory: " << dirname << LL_ENDL;
- return false;
- }
- return true;
-}
//
//end of static components of LLAPRFile
//*******************************************************************************************************************************
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 11e474b5dd..8795a0f2c4 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -35,12 +35,8 @@
#include "llwin32headers.h"
#include "apr_thread_proc.h"
-#include "apr_getopt.h"
-#include "apr_signal.h"
-#include "llstring.h"
-
-#include "mutex.h"
+#include <mutex>
struct apr_dso_handle_t;
/**
@@ -184,20 +180,7 @@ private:
static apr_file_t* open(const std::string& filename, apr_pool_t* apr_pool, apr_int32_t flags);
static apr_status_t close(apr_file_t* file) ;
static S32 seek(apr_file_t* file, apr_seek_where_t where, S32 offset);
-public:
- // returns false if failure:
- static bool remove(const std::string& filename, LLVolatileAPRPool* pool = NULL);
- static bool rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool = NULL);
- static bool isExist(const std::string& filename, LLVolatileAPRPool* pool = NULL, apr_int32_t flags = APR_READ);
- static S32 size(const std::string& filename, LLVolatileAPRPool* pool = NULL);
- static bool makeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
- static bool removeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
-
- // Returns bytes read/written, 0 if read/write fails:
- static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);
- static S32 writeEx(const std::string& filename, const void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL); // offset<0 means append
//*******************************************************************************************************************************
};
-
#endif // LL_LLAPR_H
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/llbase32.cpp b/indra/llcommon/llbase32.cpp
deleted file mode 100644
index 979114fe86..0000000000
--- a/indra/llcommon/llbase32.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- * @file llbase32.cpp
- * @brief base32 encoding that returns a std::string
- * @author James Cook
- *
- * Based on code from bitter
- * http://ghostwhitecrab.com/bitter/
- *
- * Some parts of this file are:
- * $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$
- */
-
-/**
- * Copyright (c) 2006 Christian Biere <christianbiere@gmx.de>
- * All rights reserved.
- *
- * 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 above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the authors nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- */
-
-#include "linden_common.h"
-
-#include "llbase32.h"
-
-#include <string>
-
-// bitter - base32.c starts here
-
-/*
- * See RFC 3548 for details about Base 32 encoding:
- * http://www.faqs.org/rfcs/rfc3548.html
- */
-
-static const char base32_alphabet[32] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
- 'Y', 'Z', '2', '3', '4', '5', '6', '7'
-};
-
-size_t
-base32_encode(char *dst, size_t size, const void *data, size_t len)
-{
- size_t i = 0;
- const U8 *p = (const U8*)data;
- const char *end = &dst[size];
- char *q = dst;
-
- do {
- size_t j, k;
- U8 x[5];
- char s[8];
-
- switch (len - i) {
- case 4: k = 7; break;
- case 3: k = 5; break;
- case 2: k = 3; break;
- case 1: k = 2; break;
- default:
- k = 8;
- }
-
- for (j = 0; j < 5; j++)
- x[j] = i < len ? p[i++] : 0;
-
-/*
- +-------+-----------+--------+
- | target| source | source |
- | byte | bits | byte |
- +-------+-----------+--------+
- | 0 | 7 6 5 4 3 | 0 |
- | 1 | 2 1 0 7 6 | 0-1 |
- | 2 | 5 4 3 2 1 | 1 |
- | 3 | 0 7 6 5 4 | 1-2 |
- | 4 | 3 2 1 0 7 | 2-3 |
- | 5 | 6 5 4 3 2 | 3 |
- | 6 | 1 0 7 6 5 | 3-4 |
- | 7 | 4 3 2 1 0 | 4 |
- +-------+-----------+--------+
-
-*/
-
- s[0] = (x[0] >> 3);
- s[1] = ((x[0] & 0x07) << 2) | (x[1] >> 6);
- s[2] = (x[1] >> 1) & 0x1f;
- s[3] = ((x[1] & 0x01) << 4) | (x[2] >> 4);
- s[4] = ((x[2] & 0x0f) << 1) | (x[3] >> 7);
- s[5] = (x[3] >> 2) & 0x1f;
- s[6] = ((x[3] & 0x03) << 3) | (x[4] >> 5);
- s[7] = x[4] & 0x1f;
-
- for (j = 0; j < k && q != end; j++)
- *q++ = base32_alphabet[(U8) s[j]];
-
- } while (i < len);
-
- return q - dst;
-}
-
-/* *TODO: Implement base32 encode.
-
-static inline int
-ascii_toupper(int c)
-{
- return c >= 97 && c <= 122 ? c - 32 : c;
-}
-
-static inline int
-ascii_tolower(int c)
-{
- return c >= 65 && c <= 90 ? c + 32 : c;
-}
-
-
-static char base32_map[(unsigned char) -1];
-
-size_t
-base32_decode(char *dst, size_t size, const void *data, size_t len)
-{
- const char *end = &dst[size];
- const unsigned char *p = data;
- char *q = dst;
- size_t i;
- unsigned max_pad = 3;
-
- if (0 == base32_map[0]) {
- for (i = 0; i < LL_ARRAY_SIZE(base32_map); i++) {
- const char *x;
-
- x = memchr(base32_alphabet, ascii_toupper(i), sizeof base32_alphabet);
- base32_map[i] = x ? (x - base32_alphabet) : (unsigned char) -1;
- }
- }
-
- for (i = 0; i < len && max_pad > 0; i++) {
- unsigned char c;
- char s[8];
- size_t j;
-
- c = p[i];
- if ('=' == c) {
- max_pad--;
- c = 0;
- } else {
- c = base32_map[c];
- if ((unsigned char) -1 == c) {
- return -1;
- }
- }
-
- j = i % LL_ARRAY_SIZE(s);
- s[j] = c;
-
- if (7 == j) {
- char b[5];
-
- b[0] = ((s[0] << 3) & 0xf8) | ((s[1] >> 2) & 0x07);
- b[1] = ((s[1] & 0x03) << 6) | ((s[2] & 0x1f) << 1) | ((s[3] >> 4) & 1);
- b[2] = ((s[3] & 0x0f) << 4) | ((s[4] >> 1) & 0x0f);
- b[3] = ((s[4] & 1) << 7) | ((s[5] & 0x1f) << 2) | ((s[6] >> 3) & 0x03);
- b[4] = ((s[6] & 0x07) << 5) | (s[7] & 0x1f);
-
- for (j = 0; j < LL_ARRAY_SIZE(b); j++) {
- if (q != end)
- *q = b[j];
- q++;
- }
- }
- }
-
- return q - dst;
-}
-*/
-
-
-// The following is
-// Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
-// static
-std::string LLBase32::encode(const U8* input, size_t input_size)
-{
- std::string output;
- if (input)
- {
- // Each 5 byte chunk of input is represented by an
- // 8 byte chunk of output.
- size_t input_chunks = (input_size + 4) / 5;
- size_t output_size = input_chunks * 8;
-
- output.resize(output_size);
-
- size_t encoded = base32_encode(&output[0], output_size, input, input_size);
-
- LL_INFOS() << "encoded " << encoded << " into buffer of size "
- << output_size << LL_ENDL;
- }
- return output;
-}
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/llcond.h b/indra/llcommon/llcond.h
index 2df1719941..b72ea33dea 100644
--- a/indra/llcommon/llcond.h
+++ b/indra/llcommon/llcond.h
@@ -17,7 +17,7 @@
#include "llunits.h"
#include "llcoros.h"
#include LLCOROS_MUTEX_HEADER
-#include "mutex.h"
+#include <mutex>
#include <chrono>
/**
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 9df52b6ed5..602c65b9ba 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -34,10 +34,10 @@
#include <boost/fiber/future/future.hpp>
#include <boost/fiber/future/promise.hpp>
#include <boost/fiber/recursive_mutex.hpp>
-#include "mutex.h"
#include "llsingleton.h"
#include "llinstancetracker.h"
#include <functional>
+#include <mutex>
#include <string>
#include <exception>
#include <queue>
diff --git a/indra/llcommon/llcrc.cpp b/indra/llcommon/llcrc.cpp
index d79d06e2a2..33bf01a29b 100644
--- a/indra/llcommon/llcrc.cpp
+++ b/indra/llcommon/llcrc.cpp
@@ -166,7 +166,7 @@ void LLCRC::update(const std::string& filename)
return;
}
- FILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
+ FILE* fp = LLFile::fopen(filename, LLFILE_MODE("rb")); /* Flawfinder: ignore */
if (fp)
{
diff --git a/indra/llcommon/llcrc.h b/indra/llcommon/llcrc.h
index a3bde47780..2ea5fbc3b0 100644
--- a/indra/llcommon/llcrc.h
+++ b/indra/llcommon/llcrc.h
@@ -36,7 +36,7 @@
// example (don't try this at work kids):
//
// LLCRC crc;
-// FILE* fp = LLFile::fopen(filename,"rb");
+// FILE* fp = LLFile::fopen(filename,LLFILE_MODE("rb"));
// while(!feof(fp)) {
// crc.update(fgetc(fp));
// }
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 5545bb71af..7f65c0d715 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -134,11 +134,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 6f5e57c3de..78101e21af 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
}
@@ -435,13 +481,9 @@ namespace
std::string file = user_dir + "/logcontrol-dev.xml";
- llstat stat_info;
- if (LLFile::stat(file, &stat_info)) {
- // NB: stat returns non-zero if it can't read the file, for example
- // if it doesn't exist. LLFile has no better abstraction for
- // testing for file existence.
-
- file = app_dir + "/logcontrol.xml";
+ if (!LLFile::isfile(file))
+ {
+ file = app_dir + "/logcontrol.xml";
}
return * new LogControlFile(file);
// NB: This instance is never freed
@@ -759,6 +801,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 0083865cf7..a06c299c8d 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/llfile.cpp b/indra/llcommon/llfile.cpp
index f752e31563..114df29f6e 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -29,22 +29,17 @@
#include "linden_common.h"
#include "llfile.h"
-#include "llstring.h"
#include "llerror.h"
#include "stringize.h"
#if LL_WINDOWS
-#include "llwin32headers.h"
-#include <vector>
+#include <fcntl.h>
#else
#include <errno.h>
+#include <sys/file.h>
#endif
-using namespace std;
-
-static std::string empty;
-
-// Many of the methods below use OS-level functions that mess with errno. Wrap
+// Some of the methods below use OS-level functions that mess with errno. Wrap
// variants of strerror() to report errors.
#if LL_WINDOWS
@@ -79,6 +74,7 @@ static errentry const errtable[]
{ ERROR_CURRENT_DIRECTORY, EACCES }, // 16
{ ERROR_NOT_SAME_DEVICE, EXDEV }, // 17
{ ERROR_NO_MORE_FILES, ENOENT }, // 18
+ { ERROR_SHARING_VIOLATION, EACCES }, // 32
{ ERROR_LOCK_VIOLATION, EACCES }, // 33
{ ERROR_BAD_NETPATH, ENOENT }, // 53
{ ERROR_NETWORK_ACCESS_DENIED, EACCES }, // 65
@@ -109,22 +105,25 @@ static errentry const errtable[]
{ ERROR_NOT_ENOUGH_QUOTA, ENOMEM } // 1816
};
-static int set_errno_from_oserror(unsigned long oserr)
+static int get_errno_from_oserror(int oserr)
{
if (!oserr)
return 0;
// Check the table for the Windows OS error code
- for (const struct errentry &entry : errtable)
+ for (const struct errentry& entry : errtable)
{
if (oserr == entry.oserr)
{
- _set_errno(entry.errcode);
- return -1;
+ return entry.errcode;
}
}
+ return EINVAL;
+}
- _set_errno(EINVAL);
+static int set_errno_from_oserror(unsigned long oserr)
+{
+ _set_errno(get_errno_from_oserror(oserr));
return -1;
}
@@ -136,90 +135,8 @@ std::string strerr(int errn)
return buffer;
}
-inline bool is_slash(wchar_t const c)
-{
- return c == L'\\' || c == L'/';
-}
-
-static std::wstring utf8path_to_wstring(const std::string& utf8path)
-{
- if (utf8path.size() >= MAX_PATH)
- {
- // By prepending "\\?\" to a path, Windows widechar file APIs will not fail on long path names
- std::wstring utf16path = L"\\\\?\\" + ll_convert<std::wstring>(utf8path);
- // We need to make sure that the path does not contain forward slashes as above
- // prefix does bypass the path normalization that replaces slashes with backslashes
- // before passing the path to kernel mode APIs
- std::replace(utf16path.begin(), utf16path.end(), L'/', L'\\');
- return utf16path;
- }
- return ll_convert<std::wstring>(utf8path);
-}
-
-static unsigned short get_fileattr(const std::wstring& utf16path, bool dontFollowSymLink = false)
-{
- unsigned long flags = FILE_FLAG_BACKUP_SEMANTICS;
- if (dontFollowSymLink)
- {
- flags |= FILE_FLAG_OPEN_REPARSE_POINT;
- }
- HANDLE file_handle = CreateFileW(utf16path.c_str(), FILE_READ_ATTRIBUTES,
- FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- nullptr, OPEN_EXISTING, flags, nullptr);
- if (file_handle != INVALID_HANDLE_VALUE)
- {
- FILE_ATTRIBUTE_TAG_INFO attribute_info;
- if (GetFileInformationByHandleEx(file_handle, FileAttributeTagInfo, &attribute_info, sizeof(attribute_info)))
- {
- // A volume path alone (only drive letter) is not recognized as directory while it technically is
- bool is_directory = (attribute_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
- (iswalpha(utf16path[0]) && utf16path[1] == ':' &&
- (!utf16path[2] || (is_slash(utf16path[2]) && !utf16path[3])));
- unsigned short st_mode = is_directory ? S_IFDIR :
- (attribute_info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ? S_IFLNK : S_IFREG);
- st_mode |= (attribute_info.FileAttributes & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE;
- // we do not try to guess executable flag
-
- // propagate user bits to group/other fields:
- st_mode |= (st_mode & 0700) >> 3;
- st_mode |= (st_mode & 0700) >> 6;
-
- CloseHandle(file_handle);
- return st_mode;
- }
- // Retrieve last error before calling CloseHandle()
- DWORD last_error = GetLastError();
- CloseHandle(file_handle);
- set_errno_from_oserror(last_error);
- }
- else
- {
- set_errno_from_oserror(GetLastError());
- }
-
- // If CreateFileW approach failed (e.g., exFAT), try the simpler GetFileAttributesW()
- // GetFileAttributesW() always follows symlinks, so we skip this fallback when dontFollowSymLink is true.
- if (!dontFollowSymLink)
- {
- DWORD attributes = GetFileAttributesW(utf16path.c_str());
- if (attributes != INVALID_FILE_ATTRIBUTES)
- {
- bool is_directory = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
- unsigned short st_mode = is_directory ? S_IFDIR : S_IFREG;
- st_mode |= (attributes & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE;
-
- // propagate user bits to group/other fields:
- st_mode |= (st_mode & 0700) >> 3;
- st_mode |= (st_mode & 0700) >> 6;
-
- return st_mode;
- }
- set_errno_from_oserror(GetLastError());
- }
- return 0;
-}
-
#else
+
// On Posix we want to call strerror_r(), but alarmingly, there are two
// different variants. The one that returns int always populates the passed
// buffer (except in case of error), whereas the other one always returns a
@@ -266,9 +183,50 @@ std::string strerr(int errn)
return message_from(errn, buffer, sizeof(buffer),
strerror_r(errn, buffer, sizeof(buffer)));
}
+
#endif // ! LL_WINDOWS
-static int warnif(const std::string& desc, const std::string& filename, int rc, int accept = 0)
+#if LL_WINDOWS && 0 // turn on to debug file-locking problems
+#define PROCESS_LOCKING_CHECK 1
+static void find_locking_process(const std::string& filename)
+{
+ // Only do any of this stuff (before LL_ENDL) if it will be logged.
+ LL_DEBUGS("LLFile") << "";
+ // wrong way
+ std::string TEMP = LLFile::tmpdir();
+ if (TEMP.empty())
+ {
+ LL_CONT << "No $TEMP, not running 'handle'";
+ }
+ else
+ {
+ std::string tf(TEMP);
+ tf += "handle.tmp";
+ // http://technet.microsoft.com/en-us/sysinternals/bb896655
+ std::string cmd(STRINGIZE("handle \"" << filename
+ // "openfiles /query /v | fgrep -i \"" << filename
+ << "\" > \"" << tf << '"'));
+ LL_CONT << cmd;
+ if (system(cmd.c_str()) != 0)
+ {
+ LL_CONT << "\nDownload 'handle.exe' from http://technet.microsoft.com/en-us/sysinternals/bb896655";
+ }
+ else
+ {
+ std::ifstream inf(tf);
+ std::string line;
+ while (std::getline(inf, line))
+ {
+ LL_CONT << '\n' << line;
+ }
+ }
+ LLFile::remove(tf);
+ }
+ LL_CONT << LL_ENDL;
+}
+#endif // LL_WINDOWS hack to identify processes holding file open
+
+static int warnif(std::string_view desc, const std::filesystem::path& filename, int rc, int suppress_warning = 0)
{
if (rc < 0)
{
@@ -277,322 +235,840 @@ static int warnif(const std::string& desc, const std::string& filename, int rc,
// For certain operations, a particular errno value might be
// acceptable -- e.g. stat() could permit ENOENT, mkdir() could permit
- // EEXIST. Don't warn if caller explicitly says this errno is okay.
- if (errn != accept)
+ // EEXIST. Don't log a warning if caller explicitly says this errno is okay.
+ if (errn != suppress_warning)
{
- LL_WARNS("LLFile") << "Couldn't " << desc << " '" << filename
- << "' (errno " << errn << "): " << strerr(errn) << LL_ENDL;
+ LL_WARNS("LLFile") << "Couldn't " << desc << " '" << filename << "' (errno " << errn << "): " << strerr(errn) << LL_ENDL;
}
-#if 0 && LL_WINDOWS // turn on to debug file-locking problems
+#if PROCESS_LOCKING_CHECK
// If the problem is "Permission denied," maybe it's because another
// process has the file open. Try to find out.
- if (errn == EACCES) // *not* EPERM
+ if (errn == EACCES) // *not* EPERM
{
- // Only do any of this stuff (before LL_ENDL) if it will be logged.
- LL_DEBUGS("LLFile") << empty;
- // would be nice to use LLDir for this, but dependency goes the
- // wrong way
- const char* TEMP = LLFile::tmpdir();
- if (! (TEMP && *TEMP))
- {
- LL_CONT << "No $TEMP, not running 'handle'";
- }
- else
- {
- std::string tf(TEMP);
- tf += "\\handle.tmp";
- // http://technet.microsoft.com/en-us/sysinternals/bb896655
- std::string cmd(STRINGIZE("handle \"" << filename
- // "openfiles /query /v | fgrep -i \"" << filename
- << "\" > \"" << tf << '"'));
- LL_CONT << cmd;
- if (system(cmd.c_str()) != 0)
- {
- LL_CONT << "\nDownload 'handle.exe' from http://technet.microsoft.com/en-us/sysinternals/bb896655";
- }
- else
- {
- std::ifstream inf(tf);
- std::string line;
- while (std::getline(inf, line))
- {
- LL_CONT << '\n' << line;
- }
- }
- LLFile::remove(tf);
- }
- LL_CONT << LL_ENDL;
+ find_locking_process(filename);
}
-#endif // LL_WINDOWS hack to identify processes holding file open
+#endif
}
return rc;
}
-// static
-int LLFile::mkdir(const std::string& dirname, int perms)
+static int warnif(std::string_view desc, const std::filesystem::path& filename, const std::error_code& ec, int suppress_warning = 0)
{
- // We often use mkdir() to ensure the existence of a directory that might
- // already exist. There is no known case in which we want to call out as
- // an error the requested directory already existing.
+ if (ec)
+ {
+ // get Posix errno from the std::error_code so we can compare it to the suppress_warning parameter
+ // to see when a caller wants us to not generate a warning for a particular error code
+#if LL_WINDOWS
+ int errn = get_errno_from_oserror(ec.value());
+#else
+ int errn = ec.value();
+#endif
+ // For certain operations, a particular errno value might be acceptable
+ // Don't warn if caller explicitly says this errno is okay.
+ if (errn != suppress_warning)
+ {
+ LL_WARNS("LLFile") << "Couldn't " << desc << " '" << filename << "' (errno " << errn << "): " << ec.message() << LL_ENDL;
+ }
+#if PROCESS_LOCKING_CHECK
+ // Try to detect locked files by other processes
+ if (ec.value() == ERROR_SHARING_VIOLATION || ec.value() == ERROR_LOCK_VIOLATION)
+ {
+ find_locking_process(filename);
+ }
+#endif
+ return -1;
+ }
+ return 0;
+}
+
#if LL_WINDOWS
- // permissions are ignored on Windows
- int rc = 0;
- std::wstring utf16dirname = utf8path_to_wstring(dirname);
- if (!CreateDirectoryW(utf16dirname.c_str(), nullptr))
+
+inline int set_ec_from_system_error(std::error_code& ec, DWORD error)
+{
+ ec.assign(error, std::system_category());
+ return -1;
+}
+
+static int set_ec_from_system_error(std::error_code& ec)
+{
+ return set_ec_from_system_error(ec, GetLastError());
+}
+
+inline int set_ec_to_parameter_error(std::error_code& ec)
+{
+ return set_ec_from_system_error(ec, ERROR_INVALID_PARAMETER);
+}
+
+inline int set_ec_to_outofmemory_error(std::error_code& ec)
+{
+ return set_ec_from_system_error(ec, ERROR_NOT_ENOUGH_MEMORY);
+}
+
+inline DWORD decode_access_mode(std::ios_base::openmode omode)
+{
+ switch (omode & (LLFile::in | LLFile::out))
+ {
+ case LLFile::in:
+ return GENERIC_READ;
+ case LLFile::out:
+ return GENERIC_WRITE;
+ case static_cast<std::ios_base::openmode>(LLFile::in | LLFile::out):
+ return GENERIC_READ | GENERIC_WRITE;
+ }
+ if (omode & LLFile::app)
+ {
+ return GENERIC_WRITE;
+ }
+ return 0;
+}
+
+inline DWORD decode_open_create_flags(std::ios_base::openmode omode)
+{
+ if (omode & LLFile::noreplace)
+ {
+ return CREATE_NEW; // create if it does not exist, otherwise fail
+ }
+ if (omode & LLFile::trunc)
{
- // Only treat other errors than an already existing file as a real error
- unsigned long oserr = GetLastError();
- if (oserr != ERROR_ALREADY_EXISTS)
+ if (!(omode & LLFile::out))
{
- rc = set_errno_from_oserror(oserr);
+ return TRUNCATE_EXISTING; // open and truncate if it exists, otherwise fail
}
+ return CREATE_ALWAYS; // open and truncate if it exists, otherwise create it
+ }
+ if (!(omode & LLFile::out))
+ {
+ return OPEN_EXISTING; // open if it exists, otherwise fail
+ }
+ // LLFile::app or (LLFile::out and (!LLFile::trunc or !LLFile::noreplace))
+ return OPEN_ALWAYS; // open if it exists, otherwise create it
+}
+
+inline DWORD decode_share_mode(int omode)
+{
+ if (omode & LLFile::exclusive)
+ {
+ return 0; // allow no other access
+ }
+ if (omode & LLFile::shared)
+ {
+ return FILE_SHARE_READ; // allow read access
+ }
+ return FILE_SHARE_READ | FILE_SHARE_WRITE; // allow read and write access to others
+}
+
+inline DWORD decode_attributes(std::ios_base::openmode omode, int perm)
+{
+ return (perm & S_IWRITE) ? FILE_ATTRIBUTE_NORMAL : FILE_ATTRIBUTE_READONLY;
+}
+
+// Under Windows the values for the std::ios_base::seekdir constants match the according FILE_BEGIN
+// and other constants but we do a programmatic translation for now to be sure
+static DWORD seek_mode_from_dir(std::ios_base::seekdir seekdir)
+{
+ switch (seekdir)
+ {
+ case LLFile::beg:
+ return FILE_BEGIN;
+ case LLFile::cur:
+ return FILE_CURRENT;
+ case LLFile::end:
+ return FILE_END;
}
+ return FILE_BEGIN;
+}
+
#else
- int rc = ::mkdir(dirname.c_str(), (mode_t)perms);
- if (rc < 0 && errno == EEXIST)
+
+inline int set_ec_from_system_error(std::error_code& ec, int error)
+{
+ ec.assign(error, std::system_category());
+ return -1;
+}
+
+static int set_ec_from_system_error(std::error_code& ec)
+{
+ return set_ec_from_system_error(ec, errno);
+}
+
+inline int set_ec_to_parameter_error(std::error_code& ec)
+{
+ return set_ec_from_system_error(ec, EINVAL);
+}
+
+inline int set_ec_to_outofmemory_error(std::error_code& ec)
+{
+ return set_ec_from_system_error(ec, ENOMEM);
+}
+
+inline int decode_access_mode(std::ios_base::openmode omode)
+{
+ if (omode & LLFile::out)
{
- // this is not the error you want, move along
- return 0;
+ if (omode & LLFile::in)
+ {
+ return O_RDWR;
+ }
+ return O_WRONLY;
+ }
+ return O_RDONLY;
+
+ /*switch (omode & (LLFile::in | LLFile::out))
+ {
+ case LLFile::out:
+ return O_WRONLY;
+ case static_cast<std::ios_base::openmode>(LLFile::in | LLFile::out):
+ return O_RDWR;
+ }
+ return O_RDONLY;*/
+}
+
+inline int decode_open_mode(std::ios_base::openmode omode)
+{
+ int flags = O_CREAT | decode_access_mode(omode);
+ if (omode & LLFile::app)
+ {
+ flags |= O_APPEND;
}
+ if (omode & LLFile::trunc)
+ {
+ flags |= O_TRUNC;
+ }
+ if (omode & LLFile::binary)
+ {
+ // Not a thing under *nix
+ }
+ if (omode & LLFile::noreplace)
+ {
+ flags |= O_EXCL;
+ }
+ return flags;
+}
+
+inline int decode_lock_mode(std::ios_base::openmode omode)
+{
+ int lmode = omode & LLFile::noblock ? LOCK_NB : 0;
+ if (omode & LLFile::lock_mask)
+ {
+ if (omode & LLFile::exclusive)
+ {
+ return lmode | LOCK_EX;
+ }
+ return lmode | LOCK_SH;
+ }
+ return lmode | LOCK_UN;
+}
+
+// Under Linux and Mac the values for the std::ios_base::seekdir constants match the according SEEK_SET
+// and other constants but we do a programmatic translation for now to be sure
+inline int seek_mode_from_dir(std::ios_base::seekdir seekdir)
+{
+ switch (seekdir)
+ {
+ case LLFile::beg:
+ return SEEK_SET;
+ case LLFile::cur:
+ return SEEK_CUR;
+ case LLFile::end:
+ return SEEK_END;
+ }
+ return SEEK_SET;
+}
+
#endif
- // anything else might be a problem
- return warnif("mkdir", dirname, rc);
+
+inline int clear_error(std::error_code& ec)
+{
+ ec.clear();
+ return 0;
}
-// static
-int LLFile::rmdir(const std::string& dirname, int suppress_error)
+inline bool are_open_mode_flags_invalid(std::ios_base::openmode omode)
+{
+ // at least one of input or output needs to be specified
+ if (!(omode & (LLFile::in | LLFile::out)))
+ {
+ return true;
+ }
+ // output must be possible for any of the extra options
+ if (!(omode & LLFile::out) && (omode & (LLFile::trunc | LLFile::app | LLFile::noreplace)))
+ {
+ return true;
+ }
+ // invalid combination, mutually exclusive
+ if ((omode & LLFile::app) && (omode & (LLFile::trunc | LLFile::noreplace)))
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------------------
+// class member functions
+//----------------------------------------------------------------------------------------
+int LLFile::open(const std::filesystem::path& file_path, std::ios_base::openmode omode, std::error_code& ec, int perm)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ close(ec);
+ if (are_open_mode_flags_invalid(omode))
+ {
+ return set_ec_to_parameter_error(ec);
+ }
#if LL_WINDOWS
- std::wstring utf16dirname = utf8path_to_wstring(dirname);
- int rc = _wrmdir(utf16dirname.c_str());
+ DWORD access = decode_access_mode(omode),
+ share = decode_share_mode(omode),
+ create = decode_open_create_flags(omode),
+ attributes = decode_attributes(omode, perm);
+
+ mHandle = CreateFileW(file_path.native().c_str(), access, share, nullptr, create, attributes, nullptr);
+ // The dwShareMode = share parameter takes care of locking the file for other processes if indicated,
+ // no need to do anything else for file locking here
#else
- int rc = ::rmdir(dirname.c_str());
+ int oflags = decode_open_mode(omode);
+ int lmode = omode & LLFile::lock_mask;
+ mHandle = ::open(file_path.native().c_str(), oflags, perm);
+ if (mHandle != InvalidHandle && lmode && lock(lmode | LLFile::noblock, ec) != 0)
+ {
+ close();
+ return -1;
+ }
#endif
- return warnif("rmdir", dirname, rc, suppress_error);
+ if (mHandle == InvalidHandle)
+ {
+ return set_ec_from_system_error(ec);
+ }
+
+ if (omode & LLFile::ate && seek(0, LLFile::end, ec) != 0)
+ {
+ close();
+ return -1;
+ }
+ mOpen = omode;
+ return clear_error(ec);
}
-// static
-LLFILE* LLFile::fopen(const std::string& filename, const char* mode)
+S64 LLFile::size(std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
#if LL_WINDOWS
- std::wstring utf16filename = utf8path_to_wstring(filename);
- std::wstring utf16mode = ll_convert<std::wstring>(std::string(mode));
- return _wfopen(utf16filename.c_str(), utf16mode.c_str());
+ LARGE_INTEGER value = { 0 };
+ if (GetFileSizeEx(mHandle, &value))
+ {
+ clear_error(ec);
+ return value.QuadPart;
+ }
#else
- return ::fopen(filename.c_str(),mode);
+ struct stat statval;
+ if (fstat(mHandle, &statval) == 0)
+ {
+ clear_error(ec);
+ return statval.st_size;
+ }
#endif
+ set_ec_from_system_error(ec);
+ return 0;
}
-// static
-int LLFile::close(LLFILE * file)
+S64 LLFile::tell(std::error_code& ec)
{
- int ret_value = 0;
- if (file)
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+#if LL_WINDOWS
+ LARGE_INTEGER value = { 0 };
+ if (SetFilePointerEx(mHandle, value, &value, FILE_CURRENT))
{
- ret_value = fclose(file);
+ clear_error(ec);
+ return value.QuadPart;
}
- return ret_value;
+#else
+ off_t offset = lseek(mHandle, 0, SEEK_CUR);
+ if (offset != -1)
+ {
+ clear_error(ec);
+ return offset;
+ }
+#endif
+ return set_ec_from_system_error(ec);
}
-// static
-std::string LLFile::getContents(const std::string& filename)
+int LLFile::seek(S64 pos, std::error_code& ec)
{
- LLFILE* fp = LLFile::fopen(filename, "rb");
- if (fp)
+ return seek(pos, LLFile::beg, ec);
+}
+
+int LLFile::seek(S64 offset, std::ios_base::seekdir dir, std::error_code& ec)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ S64 newOffset = 0;
+#if LL_WINDOWS
+ DWORD seekdir = seek_mode_from_dir(dir);
+ LARGE_INTEGER value;
+ value.QuadPart = offset;
+ if (SetFilePointerEx(mHandle, value, (PLARGE_INTEGER)&newOffset, seekdir))
+#else
+ newOffset = lseek(mHandle, offset, seek_mode_from_dir(dir));
+ if (newOffset != -1)
+#endif
{
- fseek(fp, 0, SEEK_END);
- U32 length = ftell(fp);
- fseek(fp, 0, SEEK_SET);
+ return clear_error(ec);
+ }
+ return set_ec_from_system_error(ec);
+}
- std::vector<char> buffer(length);
- size_t nread = fread(buffer.data(), 1, length, fp);
- fclose(fp);
+#if LL_WINDOWS
+inline DWORD next_buffer_size(S64 nbytes)
+{
+ return nbytes > 0x80000000 ? 0x80000000 : (DWORD)nbytes;
+}
+#endif
- return std::string(buffer.data(), nread);
+S64 LLFile::read(void* buffer, S64 nbytes, std::error_code& ec)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ if (nbytes == 0)
+ {
+ // Nothing to do
+ return clear_error(ec);
}
+ else if (!buffer || nbytes < 0)
+ {
+ return set_ec_to_parameter_error(ec);
+ }
+#if LL_WINDOWS
+ S64 totalBytes = 0;
+ char *ptr = (char*)buffer;
+ DWORD bytesRead, bytesToRead = next_buffer_size(nbytes);
- return LLStringUtil::null;
+ // Read in chunks to support >4GB which the S64 nbytes value makes possible
+ while (ReadFile(mHandle, ptr, bytesToRead, &bytesRead, nullptr))
+ {
+ totalBytes += bytesRead;
+ if (nbytes <= totalBytes || // requested amount read
+ bytesRead < bytesToRead) // ReadFile encountered eof
+ {
+ clear_error(ec);
+ return totalBytes;
+ }
+ ptr += bytesRead;
+ bytesToRead = next_buffer_size(nbytes - totalBytes);
+ }
+#else
+ ssize_t bytesRead = ::read(mHandle, buffer, nbytes);
+ if (bytesRead != -1)
+ {
+ clear_error(ec);
+ return bytesRead;
+ }
+#endif
+ return set_ec_from_system_error(ec);
}
-// static
-int LLFile::remove(const std::string& filename, int suppress_error)
+S64 LLFile::write(const void* buffer, S64 nbytes, std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ if (nbytes == 0)
+ {
+ // Nothing to do here
+ return clear_error(ec);
+ }
+ else if (!buffer || nbytes < 0)
+ {
+ return set_ec_to_parameter_error(ec);
+ }
#if LL_WINDOWS
- // Posix remove() works on both files and directories although on Windows
- // remove() and its wide char variant _wremove() only removes files just
- // as its siblings unlink() and _wunlink().
- // If we really only want to support files we should instead use
- // unlink() in the non-Windows part below too
- int rc = -1;
- std::wstring utf16filename = utf8path_to_wstring(filename);
- unsigned short st_mode = get_fileattr(utf16filename);
- if (S_ISDIR(st_mode))
+ // If this was opened in append mode, we emulate it on Windows
+ if (mOpen & LLFile::app && seek(0, LLFile::end, ec) != 0)
{
- rc = _wrmdir(utf16filename.c_str());
+ return -1;
}
- else if (S_ISREG(st_mode))
+
+ S64 totalBytes = 0;
+ char* ptr = (char*)buffer;
+ DWORD bytesWritten, bytesToWrite = next_buffer_size(nbytes);
+
+ // Write in chunks to support >4GB which the S64 nbytes value makes possible
+ while (WriteFile(mHandle, ptr, bytesToWrite, &bytesWritten, nullptr))
{
- rc = _wunlink(utf16filename.c_str());
+ totalBytes += bytesWritten;
+ if (nbytes <= totalBytes)
+ {
+ clear_error(ec);
+ return totalBytes;
+ }
+ ptr += bytesWritten;
+ bytesToWrite = next_buffer_size(nbytes - totalBytes);
+ }
+#else
+ ssize_t bytesWritten = ::write(mHandle, buffer, nbytes);
+ if (bytesWritten != -1)
+ {
+ clear_error(ec);
+ return bytesWritten;
+ }
+#endif
+ return set_ec_from_system_error(ec);
+}
+
+S64 LLFile::printf(const char* fmt, ...)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ va_list args1;
+ va_start(args1, fmt);
+ va_list args2;
+ va_copy(args2, args1);
+ int length = vsnprintf(nullptr, 0, fmt, args1);
+ va_end(args1);
+ if (length < 0)
+ {
+ va_end(args2);
+ return -1;
}
- else if (st_mode)
+ void* buffer = malloc(length + 1);
+ if (!buffer)
{
- // it is something else than a file or directory
- // this should not really happen as long as we do not allow for symlink
- // detection in the optional parameter to get_fileattr()
- rc = set_errno_from_oserror(ERROR_INVALID_PARAMETER);
+ va_end(args2);
+ return -1;
+ }
+ length = vsnprintf((char*)buffer, length + 1, fmt, args2);
+ va_end(args2);
+ std::error_code ec;
+ S64 written = write(buffer, length, ec);
+ free(buffer);
+ return written;
+}
+
+int LLFile::lock(int mode, std::error_code& ec)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+#if LL_WINDOWS
+ if (!(mode & LLFile::lock_mask))
+ {
+ if (UnlockFile(mHandle, 0, 0, MAXDWORD, MAXDWORD))
+ {
+ return clear_error(ec);
+ }
}
else
{
- // get_fileattr() failed and already set errno, preserve it for correct error reporting
+ OVERLAPPED overlapped = { 0 };
+ DWORD flags = (mode & LLFile::noblock) ? LOCKFILE_FAIL_IMMEDIATELY : 0;
+ if (mode & LLFile::exclusive)
+ {
+ flags |= LOCKFILE_EXCLUSIVE_LOCK;
+ }
+ // We lock the maximum range, since flock only supports locking the entire file too
+ if (LockFileEx(mHandle, flags, 0, MAXDWORD, MAXDWORD, &overlapped))
+ {
+ return clear_error(ec);
+ }
}
#else
- int rc = ::remove(filename.c_str());
+ if (flock(mHandle, decode_lock_mode(static_cast<std::ios_base::openmode>(mode))) == 0)
+ {
+ return clear_error(ec);
+ }
#endif
- return warnif("remove", filename, rc, suppress_error);
+ return set_ec_from_system_error(ec);
+}
+
+int LLFile::close(std::error_code& ec)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ if (mHandle != InvalidHandle)
+ {
+ llfile_handle_t handle = InvalidHandle;
+ std::swap(handle, mHandle);
+#if LL_WINDOWS
+ if (!CloseHandle(handle))
+#else
+ if (::close(handle))
+#endif
+ {
+ return set_ec_from_system_error(ec);
+ }
+ }
+ return clear_error(ec);
+}
+
+int LLFile::close()
+{
+ std::error_code ec;
+ return close(ec);
}
+//----------------------------------------------------------------------------------------
+// static member functions
+//----------------------------------------------------------------------------------------
+
// static
-int LLFile::rename(const std::string& filename, const std::string& newname, int suppress_error)
+LLFILE* LLFile::fopen(const std::filesystem::path& file_path, const fopen_flags_t* mode, int lmode)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ LLFILE* file;
#if LL_WINDOWS
- // Posix rename() will gladly overwrite a file at newname if it exists, the Windows
- // rename(), respectively _wrename(), will bark on that. Instead call directly the Windows
- // API MoveFileEx() and use its flags to specify that overwrite is allowed.
- std::wstring utf16filename = utf8path_to_wstring(filename);
- std::wstring utf16newname = utf8path_to_wstring(newname);
- int rc = 0;
- if (!MoveFileExW(utf16filename.c_str(), utf16newname.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
+ int shflag = _SH_DENYNO;
+ switch (lmode)
{
- rc = set_errno_from_oserror(GetLastError());
+ case LLFile::exclusive:
+ shflag = _SH_DENYRW;
+ break;
+ case LLFile::shared:
+ shflag = _SH_DENYWR;
+ break;
}
+ file = _wfsopen(file_path.native().c_str(), mode, shflag);
#else
- int rc = ::rename(filename.c_str(),newname.c_str());
+ file = ::fopen(file_path.native().c_str(), mode);
+ if (file && (lmode & (LLFile::lock_mask)))
+ {
+ // Rather fail on a sharing conflict than block
+ if (flock(fileno(file), decode_lock_mode(static_cast<std::ios_base::openmode>(lmode | LLFile::noblock))))
+ {
+ ::fclose(file);
+ file = nullptr;
+ }
+ }
#endif
- return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, suppress_error);
+ return file;
}
-// Make this a define rather than using magic numbers multiple times in the code
-#define LLFILE_COPY_BUFFER_SIZE 16384
+// static
+int LLFile::close(LLFILE* file)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ int ret_value = 0;
+ if (file)
+ {
+ ret_value = ::fclose(file);
+ }
+ return ret_value;
+}
// static
-bool LLFile::copy(const std::string& from, const std::string& to)
+std::string LLFile::getContents(const std::filesystem::path& file_path, std::error_code& ec)
{
- bool copied = false;
- LLFILE* in = LLFile::fopen(from, "rb");
- if (in)
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ std::string buffer;
+ LLFile file(file_path, LLFile::in | LLFile::binary, ec);
+ if (file)
{
- LLFILE* out = LLFile::fopen(to, "wb");
- if (out)
+ S64 length = file.size(ec);
+ if (!ec && length > 0)
{
- char buf[LLFILE_COPY_BUFFER_SIZE];
- size_t readbytes;
- bool write_ok = true;
- while (write_ok && (readbytes = fread(buf, 1, LLFILE_COPY_BUFFER_SIZE, in)))
- {
- if (fwrite(buf, 1, readbytes, out) != readbytes)
- {
- LL_WARNS("LLFile") << "Short write" << LL_ENDL;
- write_ok = false;
- }
- }
- if ( write_ok )
+ buffer = std::string(length, 0);
+ file.read(&buffer[0], length, ec);
+ if (ec)
{
- copied = true;
+ buffer.clear();
}
- fclose(out);
}
- fclose(in);
}
- return copied;
+ return buffer;
}
// static
-int LLFile::stat(const std::string& filename, llstat* filestatus, int suppress_error)
+int LLFile::mkdir(const std::filesystem::path& file_path)
{
-#if LL_WINDOWS
- std::wstring utf16filename = utf8path_to_wstring(filename);
- int rc = _wstat64(utf16filename.c_str(), filestatus);
-#else
- int rc = ::stat(filename.c_str(), filestatus);
-#endif
- return warnif("stat", filename, rc, suppress_error);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ std::error_code ec;
+ // We often use mkdir() to ensure the existence of a directory that might
+ // already exist. There is no known case in which we want to call out as
+ // an error the requested directory already existing.
+ std::filesystem::create_directory(file_path, ec);
+ // The return value is only true if the directory was actually created.
+ // But if it already existed, ec still indicates success.
+ return warnif("mkdir", file_path, ec);
}
// static
-unsigned short LLFile::getattr(const std::string& filename, bool dontFollowSymLink, int suppress_error)
+int LLFile::remove(const std::filesystem::path& file_path, int suppress_warning)
{
-#if LL_WINDOWS
- // _wstat64() is a bit heavyweight on Windows, use a more lightweight API
- // to just get the attributes
- int rc = -1;
- std::wstring utf16filename = utf8path_to_wstring(filename);
- unsigned short st_mode = get_fileattr(utf16filename, dontFollowSymLink);
- if (st_mode)
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ std::error_code ec;
+ std::filesystem::remove(file_path, ec);
+ return warnif("remove", file_path, ec, suppress_warning);
+}
+
+// static
+int LLFile::rename(const std::filesystem::path& file_path, const std::filesystem::path& new_path, int suppress_warning)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ std::error_code ec;
+ std::filesystem::rename(file_path, new_path, ec);
+ return warnif("rename", file_path, ec, suppress_warning);
+}
+
+// static
+S64 LLFile::read(const std::filesystem::path& file_path, void* buf, S64 offset, S64 nbytes, std::error_code& ec)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ // if number of bytes is 0 or less there is nothing to do here
+ if (nbytes <= 0)
{
- return st_mode;
+ clear_error(ec);
+ return 0;
}
-#else
- llstat filestatus;
- int rc = dontFollowSymLink ? ::lstat(filename.c_str(), &filestatus) : ::stat(filename.c_str(), &filestatus);
- if (rc == 0)
+
+ if (!buf || offset < 0)
{
- return filestatus.st_mode;
+ set_ec_to_parameter_error(ec);
}
-#endif
- warnif("getattr", filename, rc, suppress_error);
- return 0;
+ else
+ {
+ std::ios_base::openmode omode = LLFile::in | LLFile::binary;
+
+ LLFile file(file_path, omode, ec);
+ if (!ec && (bool)file)
+ {
+ if (offset > 0)
+ {
+ file.seek(offset, ec);
+ }
+ // else (offset == 0) file was just opened and should already be at 0.
+ if (!ec)
+ {
+ S64 bytes_read = file.read(buf, nbytes, ec);
+ if (!ec)
+ {
+ return bytes_read;
+ }
+ }
+ }
+ }
+ return warnif("read from file failed", file_path, ec);
}
// static
-bool LLFile::isdir(const std::string& filename)
+S64 LLFile::write(const std::filesystem::path& file_path, const void* buf, S64 offset, S64 nbytes, std::error_code& ec)
{
- return S_ISDIR(getattr(filename));
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ // if number of bytes is 0 or less there is nothing to do here
+ if (nbytes <= 0)
+ {
+ clear_error(ec);
+ return 0;
+ }
+
+ if (!buf)
+ {
+ set_ec_to_parameter_error(ec);
+ }
+ else
+ {
+ std::ios_base::openmode omode = LLFile::out | LLFile::binary;
+ if (offset < 0)
+ {
+ omode |= LLFile::app;
+ }
+
+ LLFile file(file_path, omode, ec);
+ if (!ec && (bool)file)
+ {
+ if (offset > 0)
+ {
+ file.seek(offset, ec);
+ }
+ // else (offset == 0) we are not appending, file was just opened and should already be at 0.
+ if (!ec)
+ {
+ S64 bytes_written = file.write(buf, nbytes, ec);
+ if (!ec)
+ {
+ return bytes_written;
+ }
+ }
+ }
+ }
+ return warnif("write to file failed", file_path, ec);
}
// static
-bool LLFile::isfile(const std::string& filename)
+bool LLFile::copy(const std::filesystem::path& source_path, const std::filesystem::path& target_path, std::filesystem::copy_options options, std::error_code& ec)
{
- return S_ISREG(getattr(filename));
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ bool copied = std::filesystem::copy_file(source_path, target_path, options, ec);
+ if (!copied)
+ {
+ warnif(STRINGIZE("copy failed, to '" << target_path << "' from"), source_path, ec);
+ }
+ return copied;
}
// static
-bool LLFile::islink(const std::string& filename)
+int LLFile::stat(const std::filesystem::path& file_path, llstat* filestatus, const char *fname, int suppress_warning)
{
- return S_ISLNK(getattr(filename, true));
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+#if LL_WINDOWS
+ int rc = _wstat64(file_path.native().c_str(), filestatus);
+#else
+ int rc = ::stat(file_path.native().c_str(), filestatus);
+#endif
+ return warnif(fname ? fname : "stat", file_path, rc, suppress_warning);
}
// static
-const char *LLFile::tmpdir()
+S64 LLFile::size(const std::filesystem::path& file_path, int suppress_warning)
{
- static std::string utf8path;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ std::error_code ec;
+ std::intmax_t size = static_cast<std::intmax_t>(std::filesystem::file_size(file_path, ec));
+ if (ec)
+ {
+ warnif("size", file_path, ec, suppress_warning);
+ return 0;
+ }
+ return size;
+}
- if (utf8path.empty())
+// static
+std::filesystem::file_status LLFile::getStatus(const std::filesystem::path& file_path, bool dontFollowSymLink, int suppress_warning)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ std::error_code ec;
+ std::filesystem::file_status status;
+ if (dontFollowSymLink)
{
- char sep;
-#if LL_WINDOWS
- sep = '\\';
+ status = std::filesystem::symlink_status(file_path, ec);
+ }
+ else
+ {
+ status = std::filesystem::status(file_path, ec);
+ }
+ warnif("getStatus()", file_path, ec, suppress_warning);
+ return status;
+}
- std::vector<wchar_t> utf16path(MAX_PATH + 1);
- GetTempPathW(static_cast<DWORD>(utf16path.size()), &utf16path[0]);
- utf8path = ll_convert_wide_to_string(&utf16path[0]);
+// static
+const std::string& LLFile::tmpdir()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
+ static std::string temppath;
+ if (temppath.empty())
+ {
+#if LL_WINDOWS
+ temppath = ll_convert<std::string>(std::filesystem::temp_directory_path().native());
+ char sep = '\\';
#else
- sep = '/';
-
- utf8path = LLStringUtil::getenv("TMPDIR", "/tmp/");
+ temppath = std::filesystem::temp_directory_path().string();
+ char sep = '/';
#endif
- if (utf8path[utf8path.size() - 1] != sep)
+ if (temppath[temppath.size() - 1] != sep)
{
- utf8path += sep;
+ temppath += sep;
}
}
- return utf8path.c_str();
+
+ return temppath;
}
#if LL_WINDOWS
/************** input file stream ********************************/
-llifstream::llifstream() {}
+// explicit
+llifstream::llifstream(const char* _Filename, ios_base::openmode _Mode) :
+ std::ifstream(ll_convert<std::wstring>(_Filename).c_str(), _Mode | ios_base::in)
+{
+}
// explicit
llifstream::llifstream(const std::string& _Filename, ios_base::openmode _Mode):
@@ -601,17 +1077,37 @@ llifstream::llifstream(const std::string& _Filename, ios_base::openmode _Mode):
{
}
+// explicit
+llifstream::llifstream(const std::filesystem::path& _Filepath, ios_base::openmode _Mode) :
+ std::ifstream(_Filepath, _Mode | ios_base::in)
+{
+}
+
+void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
+{
+ std::ifstream::open(ll_convert<std::wstring>(_Filename).c_str(),
+ _Mode | ios_base::in);
+}
+
void llifstream::open(const std::string& _Filename, ios_base::openmode _Mode)
{
std::ifstream::open(ll_convert<std::wstring>(_Filename).c_str(),
_Mode | ios_base::in);
}
+void llifstream::open(const std::filesystem::path& _Filepath, ios_base::openmode _Mode)
+{
+ std::ifstream::open(_Filepath,
+ _Mode | ios_base::in);
+}
/************** output file stream ********************************/
-
-llofstream::llofstream() {}
+// explicit
+llofstream::llofstream(const char* _Filename, ios_base::openmode _Mode) :
+ std::ofstream(ll_convert<std::wstring>(_Filename).c_str(), _Mode | ios_base::out)
+{
+}
// explicit
llofstream::llofstream(const std::string& _Filename, ios_base::openmode _Mode):
@@ -620,36 +1116,27 @@ llofstream::llofstream(const std::string& _Filename, ios_base::openmode _Mode):
{
}
-void llofstream::open(const std::string& _Filename, ios_base::openmode _Mode)
+// explicit
+llofstream::llofstream(const std::filesystem::path& _Filepath, ios_base::openmode _Mode) :
+ std::ofstream(_Filepath, _Mode | ios_base::out)
{
- std::ofstream::open(ll_convert<std::wstring>( _Filename ).c_str(),
- _Mode | ios_base::out);
}
-/************** helper functions ********************************/
+void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
+{
+ std::ofstream::open(ll_convert<std::wstring>(_Filename).c_str(), _Mode | ios_base::out);
+}
-std::streamsize llifstream_size(llifstream& ifstr)
+void llofstream::open(const std::string& _Filename, ios_base::openmode _Mode)
{
- if(!ifstr.is_open()) return 0;
- std::streampos pos_old = ifstr.tellg();
- ifstr.seekg(0, ios_base::beg);
- std::streampos pos_beg = ifstr.tellg();
- ifstr.seekg(0, ios_base::end);
- std::streampos pos_end = ifstr.tellg();
- ifstr.seekg(pos_old, ios_base::beg);
- return pos_end - pos_beg;
+ std::ofstream::open(ll_convert<std::wstring>( _Filename ).c_str(),
+ _Mode | ios_base::out);
}
-std::streamsize llofstream_size(llofstream& ofstr)
+void llofstream::open(const std::filesystem::path& _Filepath, ios_base::openmode _Mode)
{
- if(!ofstr.is_open()) return 0;
- std::streampos pos_old = ofstr.tellp();
- ofstr.seekp(0, ios_base::beg);
- std::streampos pos_beg = ofstr.tellp();
- ofstr.seekp(0, ios_base::end);
- std::streampos pos_end = ofstr.tellp();
- ofstr.seekp(pos_old, ios_base::beg);
- return pos_end - pos_beg;
+ std::ofstream::open(_Filepath,
+ _Mode | ios_base::out);
}
#endif // LL_WINDOWS
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index 04a2946ac4..8de3f5c9b4 100644
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -35,133 +35,712 @@
* Attempts to mostly mirror the POSIX style IO functions.
*/
-typedef FILE LLFILE;
+#include "stdtypes.h"
#include <fstream>
+#include <filesystem>
#include <sys/stat.h>
#if LL_WINDOWS
+#include <windows.h>
// The Windows version of stat function and stat data structure are called _stat64
// We use _stat64 here to support 64-bit st_size and time_t values
-typedef struct _stat64 llstat;
+typedef struct _stat64 llstat;
#else
-typedef struct stat llstat;
#include <sys/types.h>
+typedef struct stat llstat;
#endif
-#ifndef S_ISREG
-# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
-#endif
-
-#ifndef S_ISDIR
-# define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
-#endif
+typedef FILE LLFILE;
-// Windows C runtime library does not define this and does not support symlink detection in the
-// stat functions but we do in our getattr() function
-#ifndef S_IFLNK
-#define S_IFLNK 0xA000 /* symlink */
-#endif
+#include "fsyspath.h"
+#include "llstring.h" // safe char* -> std::string conversion
-#ifndef S_ISLNK
-#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
+#if LL_WINDOWS
+#define LLFILE_MODE(flags) L##flags
+#else
+#define LLFILE_MODE(flags) flags
#endif
-#include "llstring.h" // safe char* -> std::string conversion
-
-/// LLFile is a class of static functions operating on paths
+/// This class provides a selection of functions to operate on files through names and
+/// a class implementation to represent a file for reading and writing to it
/// All the functions with a path string input take UTF8 path/filenames
-class LL_COMMON_API LLFile
+///
+/// @nosubgrouping
+///
+class LLFile
{
public:
+ // ================================================================================
+ /// @name Constants
+ ///
+ ///@{
+ /** These can be passed to the omode parameter of LLFile::open() and its constructor
+
+ This is similar to the openmode flags for std:fstream but not exactly the same
+ std::fstream open() does not allow to open a file for writing without either
+ forcing the file to be truncated on open or all write operations being always
+ appended to the end of the file or failing to open when the file does not exist.
+ But to allow implementing the LLAPRFile::writeEx() functionality we need to be
+ able to write at a random position to the file without truncating it on open.
+
+ any other combinations than listed here are not allowed and will cause an error
+
+ bin in out trunc app noreplace File exists File doesn't exist
+ ----------------------------------------------------------------------------------
+ - + - - - - Open at begin Failure to open
+ + + - - - - " "
+ - - + - - - " Create new
+ + - + - - - " "
+ - + + - - - " "
+ + + + - - - " "
+ ----------------------------------------------------------------------------------
+ - - + + - - Destroy contents Create new
+ + - + + - - " "
+ - + + + - - " "
+ + + + + - - " "
+ ----------------------------------------------------------------------------------
+ - - + x - + Failure to open Create new
+ + - + x - + " "
+ - + + x - + " "
+ + + + x - + " "
+ ----------------------------------------------------------------------------------
+ - - + - + - Write to end Create new
+ + - + - + - " "
+ - + + - + - " "
+ + + + - + - " "
+ ----------------------------------------------------------------------------------
+ */
+ static const std::ios_base::openmode app = static_cast<std::ios_base::openmode>(1 << 1); // append to end
+ static const std::ios_base::openmode ate = static_cast<std::ios_base::openmode>(1 << 2); // initialize to end
+ static const std::ios_base::openmode binary = static_cast<std::ios_base::openmode>(1 << 3); // binary mode
+ static const std::ios_base::openmode in = static_cast<std::ios_base::openmode>(1 << 4); // for reading
+ static const std::ios_base::openmode out = static_cast<std::ios_base::openmode>(1 << 5); // for writing // for writing and reading
+ static const std::ios_base::openmode trunc = static_cast<std::ios_base::openmode>(1 << 6); // truncate on open
+ static const std::ios_base::openmode noreplace = static_cast<std::ios_base::openmode>(1 << 7); // no replace if it exists
+
+ /// Additional optional flags to omode in open() and lmode in fopen() or lock()
+ /// to indicate which sort of lock if any to attempt to get
+ ///
+ /// NOTE: there is a fundamental difference between platforms.
+ /// On Windows this lock is mandatory as it is part of the API to open a file handle and other
+ /// processes can not avoid it. If a file was opened denying other processes read and/or write
+ /// access, trying to open the same file in another process with that access will fail.
+ /// On Mac and Linux it is only an advisory lock implemented through the flock() system call.
+ /// This means that any other application needs to also attempt to at least acquire a shared
+ /// lock on the file in order to notice that the file is actually already locked. It can
+ /// therefore not be used to prevent random other applications from accessing the file, but it
+ /// works for other viewer processes when they use either the LLFile::open() or LLFile::fopen()
+ /// functions with the appropriate lock flags to open a file.
+ static const std::ios_base::openmode exclusive = static_cast<std::ios_base::openmode>(1 << 16);
+ static const std::ios_base::openmode shared = static_cast<std::ios_base::openmode>(1 << 17);
+
+ /// Additional lmode flag to indicate to rather fail instead of blocking when trying
+ /// to acquire a lock with LLFile::lock()
+ static const std::ios_base::openmode noblock = static_cast<std::ios_base::openmode>(1 << 18);
+
+ /// The mask value for the lock mask bits
+ static const std::ios_base::openmode lock_mask = static_cast<std::ios_base::openmode>(exclusive | shared);
+
+ /// One of these can be passed to the dir parameter of LLFile::seek()
+ static const std::ios_base::seekdir beg = std::ios_base::beg;
+ static const std::ios_base::seekdir cur = std::ios_base::cur;
+ static const std::ios_base::seekdir end = std::ios_base::end;
+ ///@}
+
+ // ================================================================================
+ /// @name constructor/deconstructor
+ ///
+ ///@{
+ /// default constructor
+ LLFile() : mHandle(InvalidHandle) {}
+
+ /// no copy constructor
+ LLFile(const LLFile&) = delete;
+
+ /// move constructor
+ LLFile(LLFile&& other) noexcept
+ {
+ mHandle = other.mHandle;
+ other.mHandle = InvalidHandle;
+ }
+
+ /// constructor opening the file
+ explicit LLFile(const char* filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666) :
+ mHandle(InvalidHandle)
+ {
+ open(filename, omode, ec, perm);
+ }
+
+ explicit LLFile(const std::string& filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666) :
+ mHandle(InvalidHandle)
+ {
+ open(filename, omode, ec, perm);
+ }
+
+ explicit LLFile(const std::filesystem::path& file_path, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666) :
+ mHandle(InvalidHandle)
+ {
+ open(file_path, omode, ec, perm);
+ }
+
+ /// destructor always attempts to close the file
+ ~LLFile() { close(); }
+ ///@}
+
+ // ================================================================================
+ /// @name operators
+ ///
+ ///@{
+ /// copy assignment deleted
+ LLFile& operator=(const LLFile&) = delete;
+
+ /// move assignment
+ LLFile& operator=(LLFile&& other) noexcept
+ {
+ close();
+ std::swap(mHandle, other.mHandle);
+ return *this;
+ }
+
+ // detect whether the wrapped file descriptor/handle is open or not
+ explicit operator bool() const { return (mHandle != InvalidHandle); }
+ bool operator!() { return (mHandle == InvalidHandle); }
+ ///@}
+
+ /// ================================================================================
+ /// @name class member methods
+ ///
+ /// These methods provide read and write support as well as additional functionality to query the size of
+ /// the file, change the position of the current file pointer or query it.
+ ///
+ /// Most of these functions take as one of their parameters a std::error_code object which can be used to
+ /// determine in more detail what error occurred if required
+ ///@{
+
+ /// Open a file with the specific open mode flags
+ inline int open(const char* filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return open(file_path, omode, ec, perm);
+ }
+ inline int open(const std::string& filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return open(file_path, omode, ec, perm);
+ }
+ int open(const std::filesystem::path& filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666);
+ ///< @returns 0 on success, -1 on failure
+
+ /// Determine the size of the opened file
+ S64 size(std::error_code& ec);
+ ///< @returns the number of bytes in the file or 0 on failure
+
+ /// Query the position of the current file pointer in the file
+ S64 tell(std::error_code& ec);
+ ///< @returns the absolute offset of the file pointer in bytes relative to the start of the file or -1 on failure
+
+ /// Move the file pointer to the specified absolute position relative to the start of the file
+ int seek(S64 pos, std::error_code& ec);
+ ///< @returns 0 on success, -1 on failure
+
+ /// Move the file pointer to the specified position relative to dir
+ int seek(S64 offset, std::ios_base::seekdir dir, std::error_code& ec);
+ ///< @returns 0 on success, -1 on failure
+
+ /// Read the specified number of bytes into the buffer starting at the current file pointer
+ S64 read(void* buffer, S64 nbytes, std::error_code& ec);
+ ///< If the file ends before the requested amount of bytes could be read, the function succeeds and
+ /// returns the bytes up to the end of the file. The return value indicates the number of actually
+ /// read bytes and can be therefore smaller than the requested amount.
+ /// @returns the number of bytes read from the file or -1 on failure
+
+ /// Write the specified number of bytes to the file starting at the current file pointer
+ S64 write(const void* buffer, S64 nbytes, std::error_code& ec);
+ ///< @returns the number of bytes written to the file or -1 on failure
+
+ /// Write into the file starting at the current file pointer using printf style format and
+ /// additional optional parameters as specified in the fmt string
+ S64 printf(const char* fmt, ...);
+ ///< @returns the number of bytes written to the file or -1 on failure
+
+ /// Attempt to acquire or release a lock on the file
+ int lock(int lmode, std::error_code& ec);
+ ///< lmode can be one of LLFile::exclusive or LLFile::shared to acquire the according lock
+ /// or 0 to give up an earlier acquired lock. Adding LLFile::noblock together with one of
+ /// the lock requests will cause the function to fail if the lock can not be acquired,
+ /// otherwise the function will block until the lock can be acquired.
+ /// @returns 0 on success, -1 on failure
+
+ /// close the file explicitly
+ int close(std::error_code& ec);
+ ///< @returns 0 on success, -1 on failure
+
+ /// Convenience function to close the file without additional parameters
+ int close();
+ ///< @returns 0 on success, -1 on failure
+ ///@}
+
+ /// ================================================================================
+ /// @name static member functions
+ ///
+ /// These functions are static and operate with UTF8 filenames as one of their parameters.
+ ///
+ ///@{
/// open a file with the specified access mode
- static LLFILE* fopen(const std::string& filename, const char* accessmode); /* Flawfinder: ignore */
+ ///
+#if LL_WINDOWS
+ using fopen_flags_t = wchar_t;
+#else
+ using fopen_flags_t = char;
+#endif
+ inline static LLFILE* fopen(const char* filename, const fopen_flags_t* accessmode, int lmode = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return LLFile::fopen(file_path, accessmode, lmode);
+ }
+ inline static LLFILE* fopen(const std::string& filename, const fopen_flags_t* accessmode, int lmode = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return LLFile::fopen(file_path, accessmode, lmode);
+ }
+ static LLFILE* fopen(const std::filesystem::path& file_path, const fopen_flags_t* accessmode, int lmode = 0);
///< 'accessmode' follows the rules of the Posix fopen() mode parameter
- /// "r" open the file for reading only and positions the stream at the beginning
- /// "r+" open the file for reading and writing and positions the stream at the beginning
- /// "w" open the file for reading and writing and truncate it to zero length
- /// "w+" open or create the file for reading and writing and truncate to zero length if it existed
- /// "a" open the file for reading and writing and position the stream at the end of the file
- /// "a+" open or create the file for reading and writing and position the stream at the end of the file
+ /// "r" open the file for reading only and positions the stream at the beginning
+ /// "r+" open the file for reading and writing and positions the stream at the beginning
+ /// "w" open the file for reading and writing and truncate it to zero length
+ /// "w+" open or create the file for reading and writing and truncate to zero length if it existed
+ /// "a" open the file for reading and writing and before every write position the stream at the end of the file
+ /// "a+" open or create the file for reading and writing and before every write position the stream at the end of the file
+ ///
+ /// in addition to these values, "b" can be appended to indicate binary stream access, but on Linux and Mac
+ /// this is strictly for compatibility and has no effect. On Windows this makes the file functions not
+ /// try to translate line endings. Windows also allows to append "t" to indicate text mode. If neither
+ /// "b" or "t" is defined, Windows uses the value set by _fmode which by default is _O_TEXT.
+ /// This means that it is always a good idea to append "b" specifically for binary file access to
+ /// avoid corruption of the binary consistency of the data stream when reading or writing
+ /// Other characters in 'accessmode', while possible on some platforms (Windows), will usually
+ /// cause an error on other platforms as fopen will verify this parameter
///
- /// in addition to these values, "b" can be appended to indicate binary stream access, but on Linux and Mac
- /// this is strictly for compatibility and has no effect. On Windows this makes the file functions not
- /// try to translate line endings. Windows also allows to append "t" to indicate text mode. If neither
- /// "b" or "t" is defined, Windows uses the value set by _fmode which by default is _O_TEXT.
- /// This means that it is always a good idea to append "b" specifically for binary file access to
- /// avoid corruption of the binary consistency of the data stream when reading or writing
- /// Other characters in 'accessmode' will usually cause an error as fopen will verify this parameter
- /// @returns a valid LLFILE* pointer on success or NULL on failure
+ /// lmode is optional and allows to lock the file for other processes either as a shared lock or an
+ /// exclusive lock. If the requested lock conflicts with an already existing lock, the open fails.
+ /// Pass either LLFIle::exclusive or LLFile::shared to this parameter if you want to prevent other
+ /// processes from reading (exclusive lock) or writing (shared lock) to the file. It will always use
+ /// LLFile::noblock, meaning the open will immediately fail if it conflicts with an existing lock on the
+ /// file.
+ ///
+ /// @returns a valid LLFILE* pointer on success that can be passed to the fread() and fwrite() functions
+ /// and some other f<something> functions in the Standard C library that accept a FILE* as parameter
+ /// or NULL on failure
+ /// Close a file handle opened with fopen() above
static int close(LLFILE * file);
-
- /// retrieve the content of a file into a string
- static std::string getContents(const std::string& filename);
- ///< @returns the content of the file or an empty string on failure
+ ///< @returns 0 on success and -1 on failure.
/// create a directory
- static int mkdir(const std::string& filename, int perms = 0700);
- ///< perms is a permissions mask like 0777 or 0700. In most cases it will be
- /// overridden by the user's umask. It is ignored on Windows.
- /// mkdir() considers "directory already exists" to be not an error.
- /// @returns 0 on success and -1 on failure.
-
- //// remove a directory
- static int rmdir(const std::string& filename, int suppress_error = 0);
- ///< pass ENOENT in the optional 'suppress_error' parameter
- /// if you don't want a warning in the log when the directory does not exist
+ inline static int mkdir(const char* dirname)
+ {
+ std::filesystem::path dir_path = fsyspath(dirname);
+ return mkdir(dir_path);
+ }
+ inline static int mkdir(const std::string& dirname)
+ {
+ std::filesystem::path dir_path = fsyspath(dirname);
+ return mkdir(dir_path);
+ }
+ static int mkdir(const std::filesystem::path& dirname);
+ ///< mkdir() considers "directory already exists" to be not an error.
/// @returns 0 on success and -1 on failure.
/// remove a file or directory
- static int remove(const std::string& filename, int suppress_error = 0);
- ///< pass ENOENT in the optional 'suppress_error' parameter
- /// if you don't want a warning in the log when the directory does not exist
+ inline static int remove(const char* filename, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return remove(file_path, suppress_warning);
+ }
+ inline static int remove(const std::string& filename, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return remove(file_path, suppress_warning);
+ }
+ static int remove(const std::filesystem::path& file_path, int suppress_warning = 0);
+ ///< pass an errno value (e.g., ENOENT) in the optional 'suppress_warning' parameter if you want to
+ /// suppress a warning in the log when the failure matches that errno (e.g., suppress warning if
+ /// the file or directory does not exist)
/// @returns 0 on success and -1 on failure.
/// rename a file
- static int rename(const std::string& filename, const std::string& newname, int suppress_error = 0);
+ inline static int rename(const char* filename, const char* newname, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ std::filesystem::path new_path = fsyspath(newname);
+ return rename(file_path, new_path, suppress_warning);
+ }
+ inline static int rename(const std::string& filename, const char* newname, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ std::filesystem::path new_path = fsyspath(newname);
+ return rename(file_path, new_path, suppress_warning);
+ }
+ inline static int rename(const char* filename, const std::string& newname, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ std::filesystem::path new_path = fsyspath(newname);
+ return rename(file_path, new_path, suppress_warning);
+ }
+ inline static int rename(const std::string& filename, const std::string& newname, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ std::filesystem::path new_path = fsyspath(newname);
+ return rename(file_path, new_path, suppress_warning);
+ }
+ static int rename(const std::filesystem::path& file_path, const std::filesystem::path& new_path, int suppress_warning = 0);
///< it will silently overwrite newname if it exists without returning an error
/// Posix guarantees that if newname already exists, then there will be no moment
/// in which for other processes newname does not exist. There is no such guarantee
- /// under Windows at this time. It may do it in the same way but the used Windows API
- /// does not make such guarantees.
+ /// under Windows at this time. It may do it in the same way but the used Windows
+ /// APIs do not make such guarantees.
/// @returns 0 on success and -1 on failure.
+ /// copy the contents of the file from 'source' to 'target'
+ inline static bool copy(const char* source, const char* target)
+ {
+ std::error_code ec;
+ return copy(source, target, std::filesystem::copy_options::overwrite_existing, ec);
+ }
+ inline static bool copy(const char* source, const std::string& target)
+ {
+ std::error_code ec;
+ return copy(source, target, std::filesystem::copy_options::overwrite_existing, ec);
+ }
+ inline static bool copy(const std::string& source, const char* target)
+ {
+ std::error_code ec;
+ return copy(source, target, std::filesystem::copy_options::overwrite_existing, ec);
+ }
+ inline static bool copy(const std::string& source, const std::string& target)
+ {
+ std::error_code ec;
+ return copy(source, target, std::filesystem::copy_options::overwrite_existing, ec);
+ }
+ inline static bool copy(const std::filesystem::path& source_path, const std::filesystem::path& target_path)
+ {
+ std::error_code ec;
+ return copy(source_path, target_path, std::filesystem::copy_options::overwrite_existing, ec);
+ }
+ ///< Copies the contents of the file 'source' to the file 'target', overwriting 'target' if it already
+ /// existed.
+ /// This is a convenience function that implements the previous behavior of silently overwriting an
+ /// already existing target file. Consider using the function below if you desire a different
+ /// behavior when the target file already exists
+ /// @returns true on success and false on failure.
+
+ /// copy the contents of the file from 'from' to 'to'
+ inline static bool copy(const char* source, const char* target, std::filesystem::copy_options options, std::error_code& ec)
+ {
+ std::filesystem::path source_path = fsyspath(source);
+ std::filesystem::path target_path = fsyspath(target);
+ return copy(source_path, target_path, options, ec);
+ }
+ inline static bool copy(const char* source, const std::string& target, std::filesystem::copy_options options, std::error_code& ec)
+ {
+ std::filesystem::path source_path = fsyspath(source);
+ std::filesystem::path target_path = fsyspath(target);
+ return copy(source_path, target_path, options, ec);
+ }
+ inline static bool copy(const std::string& source, const char* target, std::filesystem::copy_options options, std::error_code& ec)
+ {
+ std::filesystem::path source_path = fsyspath(source);
+ std::filesystem::path target_path = fsyspath(target);
+ return copy(source_path, target_path, options, ec);
+ }
+ inline static bool copy(const std::string& source, const std::string& target, std::filesystem::copy_options options, std::error_code& ec)
+ {
+ std::filesystem::path source_path = fsyspath(source);
+ std::filesystem::path target_path = fsyspath(target);
+ return copy(source_path, target_path, options, ec);
+ }
+ static bool copy(const std::filesystem::path& source_path, const std::filesystem::path& target_path, std::filesystem::copy_options options, std::error_code& ec);
+ ///< Copies the contents of the file 'source' to the file 'target'. The options parameter allows to
+ /// specify what should happen if the "target" file already exists:
+ /// std::filesystem::copy_options::none - return an error in ec and fail
+ /// std::filesystem::copy_options::skip_existing - skip the operation and do not overwrite file
+ /// std::filesystem::copy_options::overwrite_existing - overwrite the file
+ /// std::filesystem::copy_options::update_existing - overwrite the file only if it is older than the file being copied
+ /// @returns true on success and false on failure.
+
+ /// retrieve the content of a file into a string
+ inline static std::string getContents(const char* filename)
+ {
+ std::error_code ec;
+ return getContents(filename, ec);
+ }
+ inline static std::string getContents(const std::string& filename)
+ {
+ std::error_code ec;
+ return getContents(filename, ec);
+ }
+ inline static std::string getContents(const std::filesystem::path& file_path)
+ {
+ std::error_code ec;
+ return getContents(file_path, ec);
+ }
+ inline static std::string getContents(const char* filename, std::error_code& ec)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return getContents(file_path, ec);
+ }
+ inline static std::string getContents(const std::string& filename, std::error_code& ec)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return getContents(file_path, ec);
+ }
+ static std::string getContents(const std::filesystem::path& file_path, std::error_code& ec);
+ ///< @returns the entire content of the file as std::string or an empty string on failure
+
+ /// read nBytes from the file into the buffer, starting at offset in the file
+ inline static S64 read(const char* filename, void* buf, S64 offset, S64 nbytes)
+ {
+ std::error_code ec;
+ return read(filename, buf, offset, nbytes, ec);
+ }
+ inline static S64 read(const std::string& filename, void* buf, S64 offset, S64 nbytes)
+ {
+ std::error_code ec;
+ return read(filename, buf, offset, nbytes, ec);
+ }
+ inline static S64 read(const std::filesystem::path& file_path, void* buf, S64 offset, S64 nbytes)
+ {
+ std::error_code ec;
+ return read(file_path, buf, offset, nbytes, ec);
+ }
+ inline static S64 read(const char* filename, void* buf, S64 offset, S64 nbytes, std::error_code& ec)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return read(file_path, buf, offset, nbytes, ec);
+ }
+ inline static S64 read(const std::string& filename, void* buf, S64 offset, S64 nbytes, std::error_code& ec)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return read(file_path, buf, offset, nbytes, ec);
+ }
+ static S64 read(const std::filesystem::path& filename, void* buf, S64 offset, S64 nbytes, std::error_code& ec);
+ ///< @returns bytes read on success, or -1 on failure
- /// copy the contents of file from 'from' to 'to' filename
- static bool copy(const std::string& from, const std::string& to);
- ///< @returns true on success and false on failure.
+ /// write nBytes from the buffer into the file, starting at offset in the file
+ inline static S64 write(const std::string& filename, const void* buf, S64 offset, S64 nbytes)
+ {
+ std::error_code ec;
+ std::filesystem::path file_path = fsyspath(filename);
+ return write(file_path, buf, offset, nbytes, ec);
+ }
+ inline static S64 write(const std::filesystem::path& filename, const void* buf, S64 offset, S64 nbytes)
+ {
+ std::error_code ec;
+ std::filesystem::path file_path = fsyspath(filename);
+ return write(file_path, buf, offset, nbytes, ec);
+ }
+ inline static S64 write(const std::string& filename, const void* buf, S64 offset, S64 nbytes, std::error_code& ec)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return write(file_path, buf, offset, nbytes, ec);
+ }
+ static S64 write(const std::filesystem::path& filename, const void* buf, S64 offset, S64 nbytes, std::error_code& ec);
+ ///< If a negative offset is provided, the file is opened in append mode and the
+ /// write will be appended to the end of the file.
+ /// @returns bytes written on success, or -1 on failure
/// return the file stat structure for filename
- static int stat(const std::string& filename, llstat* file_status, int suppress_error = ENOENT);
+ inline static int stat(const char* filename, llstat* file_status, const char* operation = nullptr, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return stat(file_path, file_status, operation, suppress_warning);
+ }
+ inline static int stat(const std::string& filename, llstat* file_status, const char* operation = nullptr, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return stat(file_path, file_status, operation, suppress_warning);
+ }
+ static int stat(const std::filesystem::path& file_path, llstat* file_status, const char *operation = nullptr, int suppress_warning = ENOENT);
///< for compatibility with existing uses of LL_File::stat() we use ENOENT as default in the
- /// optional 'suppress_error' parameter to avoid spamming the log with warnings when the API
+ /// optional 'suppress_warning' parameter to avoid spamming the log with warnings when the API
/// is used to detect if a file exists
/// @returns 0 on success and -1 on failure.
- /// get the file or directory attributes for filename
- static unsigned short getattr(const std::string& filename, bool dontFollowSymLink = false, int suppress_error = ENOENT);
- ///< a more lightweight function on Windows to stat, that just returns the file attribute flags
- /// dontFollowSymLinks set to true returns the attributes of the symlink if it is one, rather than resolving it
- /// we pass by default ENOENT in the optional 'suppress_error' parameter to not spam the log with
- /// warnings when the file or directory does not exist
- /// @returns 0 on failure and a st_mode value with either S_IFDIR or S_IFREG set otherwise
- /// together with the three access bits which under Windows only the write bit is relevant.
+ /// get the std::filesystem::file_status for filename
+ inline static std::filesystem::file_status getStatus(const char* filename, bool dontFollowSymLink = false, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return getStatus(file_path, dontFollowSymLink, suppress_warning);
+ }
+ inline static std::filesystem::file_status getStatus(const std::string& filename, bool dontFollowSymLink = false, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return getStatus(file_path, dontFollowSymLink, suppress_warning);
+ }
+ static std::filesystem::file_status getStatus(const std::filesystem::path& file_path, bool dontFollowSymLink = false, int suppress_warning = ENOENT);
+ ///< dontFollowSymLinks set to true returns the std::filesystem::file_status of the symlink if it
+ /// is one, rather than resolving it. We pass by default ENOENT in the optional 'suppress_warning'
+ /// parameter to not spam the log with warnings when the file or directory does not exist
+ /// @returns a std::filesystem::file_status value that can be passed to the appropriate std::filesystem::exists()
+ /// and other APIs accepting a file_status.
+
+ /// get the size of a file in bytes
+ inline static S64 size(const char* filename, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return size(file_path, suppress_warning);
+ }
+ inline static S64 size(const std::string& filename, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return size(file_path, suppress_warning);
+ }
+ static S64 size(const std::filesystem::path& file_path, int suppress_warning = ENOENT);
+ ///< we pass by default ENOENT in the optional 'suppress_warning' parameter to not spam
+ /// the log with warnings when the file does not exist
+ /// @returns the file size on success or 0 on failure.
+
+ /// check if filename is an existing file or directory
+ inline static bool exists(const char* filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::exists(status);
+ }
+ inline static bool exists(const std::string& filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::exists(status);
+ }
+ inline static bool exists(const std::filesystem::path& file_path)
+ {
+ std::filesystem::file_status status = getStatus(file_path);
+ return std::filesystem::exists(status);
+ }
+ ///< @returns true if the path is for an existing file or directory
/// check if filename is an existing directory
- static bool isdir(const std::string& filename);
+ inline static bool isdir(const char* filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::is_directory(status);
+ }
+ inline static bool isdir(const std::string& filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::is_directory(status);
+ }
+ inline static bool isdir(const std::filesystem::path& file_path)
+ {
+ std::filesystem::file_status status = getStatus(file_path);
+ return std::filesystem::is_directory(status);
+ }
///< @returns true if the path is for an existing directory
/// check if filename is an existing file
- static bool isfile(const std::string& filename);
+ inline static bool isfile(const char* filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::is_regular_file(status);
+ }
+ inline static bool isfile(const std::string& filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::is_regular_file(status);
+ }
+ inline static bool isfile(const std::filesystem::path& file_path)
+ {
+ std::filesystem::file_status status = getStatus(file_path);
+ return std::filesystem::is_regular_file(status);
+ }
///< @returns true if the path is for an existing file
/// check if filename is a symlink
- static bool islink(const std::string& filename);
+ inline static bool islink(const char* filename)
+ {
+ std::filesystem::file_status status = getStatus(filename, true);
+ return std::filesystem::is_symlink(status);
+ }
+ inline static bool islink(const std::string& filename)
+ {
+ std::filesystem::file_status status = getStatus(filename, true);
+ return std::filesystem::is_symlink(status);
+ }
+ inline static bool islink(const std::filesystem::path& file_path)
+ {
+ std::filesystem::file_status status = getStatus(file_path, true);
+ return std::filesystem::is_symlink(status);
+ }
///< @returns true if the path is pointing at a symlink
/// return a path to the temporary directory on the system
- static const char * tmpdir();
+ static const std::string& tmpdir();
+
+private:
+#if LL_WINDOWS
+ typedef HANDLE llfile_handle_t;
+ const llfile_handle_t InvalidHandle = INVALID_HANDLE_VALUE;
+ llfile_handle_t mHandle = INVALID_HANDLE_VALUE; // The file handle/descriptor
+#else
+ typedef int llfile_handle_t;
+ const llfile_handle_t InvalidHandle = -1;
+ llfile_handle_t mHandle = -1; // The file handle/descriptor
+#endif
+
+ std::ios_base::openmode mOpen{}; // Used to emulate std::ios_base::app under Windows
+};
+
+#if LL_WINDOWS
+/**
+ * @brief Controlling input for files.
+ *
+ * This class supports reading from named files, using the inherited
+ * functions from std::ifstream. The only added value is that our constructor
+ * Does The Right Thing when passed a non-ASCII pathname. Sadly, that isn't
+ * true of Microsoft's std::ifstream.
+ */
+class llifstream : public std::ifstream
+{
+ // input stream associated with a C stream
+ public:
+ // Constructors:
+ /**
+ * @brief Default constructor.
+ *
+ * Initializes @c sb using its default constructor, and passes
+ * @c &sb to the base class initializer. Does not open any files
+ * (you haven't given it a filename to open).
+ */
+ llifstream() = default;
+
+ /**
+ * @brief Create an input file stream.
+ * @param Filename String specifying the filename.
+ * @param Mode Open file in specified mode (see std::ios_base).
+ *
+ * @c ios_base::in is automatically included in @a mode.
+ */
+ explicit llifstream(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::in);
+ explicit llifstream(const std::string& _Filename,
+ ios_base::openmode _Mode = ios_base::in);
+ explicit llifstream(const std::filesystem::path& _Filepath,
+ ios_base::openmode _Mode = ios_base::in);
+
+ /**
+ * @brief Opens an external file.
+ * @param Filename The name of the file.
+ * @param Node The open mode flags.
+ *
+ * Calls @c llstdio_filebuf::open(s,mode|in). If that function
+ * fails, @c failbit is set in the stream's error state.
+ */
+ void open(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::in);
+ void open(const std::string& _Filename,
+ ios_base::openmode _Mode = ios_base::in);
+ void open(const std::filesystem::path& _Filepath,
+ ios_base::openmode _Mode = ios_base::in);
};
/// RAII class
@@ -169,22 +748,19 @@ class LLUniqueFile
{
public:
// empty
- LLUniqueFile(): mFileHandle(nullptr) {}
+ LLUniqueFile() = default;
// wrap (e.g.) result of LLFile::fopen()
- LLUniqueFile(LLFILE* f): mFileHandle(f) {}
+ LLUniqueFile(LLFILE* f) : mFileHandle(f) {}
// no copy
LLUniqueFile(const LLUniqueFile&) = delete;
// move construction
LLUniqueFile(LLUniqueFile&& other) noexcept
{
- mFileHandle = other.mFileHandle;
+ mFileHandle = other.mFileHandle;
other.mFileHandle = nullptr;
}
// The point of LLUniqueFile is to close on destruction.
- ~LLUniqueFile()
- {
- close();
- }
+ ~LLUniqueFile() { close(); }
// simple assignment
LLUniqueFile& operator=(LLFILE* f)
@@ -209,7 +785,7 @@ public:
if (mFileHandle)
{
// in case close() throws, set mFileHandle null FIRST
- LLFILE* h{nullptr};
+ LLFILE* h{ nullptr };
std::swap(h, mFileHandle);
LLFile::close(h);
}
@@ -217,62 +793,16 @@ public:
// detect whether the wrapped LLFILE is open or not
explicit operator bool() const { return bool(mFileHandle); }
- bool operator!() { return ! mFileHandle; }
+ bool operator!() { return !mFileHandle; }
// LLUniqueFile should be usable for any operation that accepts LLFILE*
// (or FILE* for that matter)
operator LLFILE*() const { return mFileHandle; }
private:
- LLFILE* mFileHandle;
-};
-
-#if LL_WINDOWS
-/**
- * @brief Controlling input for files.
- *
- * This class supports reading from named files, using the inherited
- * functions from std::ifstream. The only added value is that our constructor
- * Does The Right Thing when passed a non-ASCII pathname. Sadly, that isn't
- * true of Microsoft's std::ifstream.
- */
-class LL_COMMON_API llifstream : public std::ifstream
-{
- // input stream associated with a C stream
- public:
- // Constructors:
- /**
- * @brief Default constructor.
- *
- * Initializes @c sb using its default constructor, and passes
- * @c &sb to the base class initializer. Does not open any files
- * (you haven't given it a filename to open).
- */
- llifstream();
-
- /**
- * @brief Create an input file stream.
- * @param Filename String specifying the filename.
- * @param Mode Open file in specified mode (see std::ios_base).
- *
- * @c ios_base::in is automatically included in @a mode.
- */
- explicit llifstream(const std::string& _Filename,
- ios_base::openmode _Mode = ios_base::in);
-
- /**
- * @brief Opens an external file.
- * @param Filename The name of the file.
- * @param Node The open mode flags.
- *
- * Calls @c llstdio_filebuf::open(s,mode|in). If that function
- * fails, @c failbit is set in the stream's error state.
- */
- void open(const std::string& _Filename,
- ios_base::openmode _Mode = ios_base::in);
+ LLFILE* mFileHandle = nullptr;
};
-
/**
* @brief Controlling output for files.
*
@@ -281,7 +811,7 @@ class LL_COMMON_API llifstream : public std::ifstream
* Right Thing when passed a non-ASCII pathname. Sadly, that isn't true of
* Microsoft's std::ofstream.
*/
-class LL_COMMON_API llofstream : public std::ofstream
+class llofstream : public std::ofstream
{
public:
// Constructors:
@@ -292,7 +822,7 @@ class LL_COMMON_API llofstream : public std::ofstream
* @c &sb to the base class initializer. Does not open any files
* (you haven't given it a filename to open).
*/
- llofstream();
+ llofstream() = default;
/**
* @brief Create an output file stream.
@@ -301,8 +831,12 @@ class LL_COMMON_API llofstream : public std::ofstream
*
* @c ios_base::out is automatically included in @a mode.
*/
+ explicit llofstream(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
explicit llofstream(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+ explicit llofstream(const std::filesystem::path& _Filepath,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
/**
* @brief Opens an external file.
@@ -311,21 +845,14 @@ class LL_COMMON_API llofstream : public std::ofstream
*
* @c ios_base::out is automatically included in @a mode.
*/
+ void open(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
void open(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+ void open(const std::filesystem::path& _Filepath,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
};
-
-/**
- * @brief filesize helpers.
- *
- * The file size helpers are not considered particularly efficient,
- * and should only be used for config files and the like -- not in a
- * loop.
- */
-std::streamsize LL_COMMON_API llifstream_size(llifstream& fstr);
-std::streamsize LL_COMMON_API llofstream_size(llofstream& fstr);
-
#else // ! LL_WINDOWS
// on non-windows, llifstream and llofstream are just mapped directly to the std:: equivalents
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/llfixedbuffer.h b/indra/llcommon/llfixedbuffer.h
index 1234d2014f..d2cd660c18 100644
--- a/indra/llcommon/llfixedbuffer.h
+++ b/indra/llcommon/llfixedbuffer.h
@@ -27,7 +27,7 @@
#ifndef LL_LLFIXEDBUFFER_H
#define LL_LLFIXEDBUFFER_H
-#include "timer.h"
+#include "lltimer.h"
#include <deque>
#include <string>
#include "llstring.h"
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 92b26354a1..734365767d 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>
@@ -35,7 +37,7 @@
#include <memory>
#include <type_traits>
-#include "mutex.h"
+#include <mutex>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/indirect_iterator.hpp>
@@ -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..6e6597431d 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2026, 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
@@ -52,6 +52,9 @@
//static
+// On windows commit charge information is vital for OOM diagnosis.
+U32Megabytes LLMemory::sAvailCommitMemInMB(U32_MAX);
+
// most important memory metric for texture streaming
// On Windows, this should agree with resource monitor -> performance -> memory -> available
// On OS X, this should be activity monitor -> memory -> (physical memory - memory used)
@@ -70,6 +73,12 @@ U32Kilobytes LLMemory::sAllocatedMemInKB(0);
U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0);
+LLFrameTimer LLMemory::sMemoryCheckTimer;
+F32 LLMemory::sSysMemoryFactor = 1.f;
+U32 LLMemory::sFactorLastFrameCount = 0;
+
+static const S32Megabytes MEM_LOW_THRESHOLD = S32Megabytes(256);
+
static LLTrace::SampleStatHandle<F64Megabytes> sAllocatedMem("allocated_mem", "active memory in use by application");
static LLTrace::SampleStatHandle<F64Megabytes> sVirtualMem("virtual_mem", "virtual memory assigned to application");
@@ -102,23 +111,14 @@ void LLMemory::updateMemoryInfo()
{
LL_PROFILE_ZONE_SCOPED;
+ sMemoryCheckTimer.reset();
sMaxPhysicalMemInKB = gSysMemory.getPhysicalMemoryKB();
- U32Kilobytes avail_mem;
- LLMemoryInfo::getAvailableMemoryKB(avail_mem);
- sAvailPhysicalMemInKB = avail_mem;
+ LLMemoryInfo::updateAvailableMemory();
#if LL_WINDOWS
- PROCESS_MEMORY_COUNTERS counters;
-
- if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
- {
- LL_WARNS() << "GetProcessMemoryInfo failed" << LL_ENDL;
- return ;
- }
-
- sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(counters.WorkingSetSize));
- sAllocatedPageSizeInKB = U32Kilobytes::convert(U64Bytes(counters.PagefileUsage));
+ // On windows updateAvailableMemory fills sAvailPhysicalMemInKB,
+ //sAllocatedMemInKB and sAllocatedPageSizeInKB
sample(sVirtualMem, sAllocatedPageSizeInKB);
#elif defined(LL_DARWIN)
@@ -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.
@@ -201,6 +198,97 @@ void LLMemory::logMemoryInfo(bool update)
LL_INFOS() << llformat("Current max usable memory: %.2f MB", sMaxPhysicalMemInKB / 1024.0) << LL_ENDL;
}
+void LLMemory::updateFreeSystemMemory()
+{
+ if (sMemoryCheckTimer.getElapsedTimeF32() >= 1.f) //once per second.
+ {
+ LLMemory::updateMemoryInfo(); // resets the timer
+ }
+}
+
+F32 LLMemory::getSystemMemoryBudgetFactor()
+{
+ // Only update once per frame
+ U32 current_frame = LLFrameTimer::getFrameCount();
+ if (sFactorLastFrameCount == current_frame)
+ {
+ return sSysMemoryFactor;
+ }
+ sFactorLastFrameCount = current_frame;
+
+ updateFreeSystemMemory();
+#if LL_WINDOWS
+ S32Megabytes free_sys_mem = getAvailableCommitMemMB();
+#else
+ S32Megabytes free_sys_mem = getAvailableMemKB();
+#endif
+ bool is_sys_low = free_sys_mem < MEM_LOW_THRESHOLD;
+ static bool was_low = false;
+
+ // sSysMemoryFactor affects draw distance
+ //
+ // We only decrement when more than 406MB is free, but increment
+ // when below 256MB free. This should provide a stable value
+ // in the 256-406MB range to avoid draw range fluctuations.
+ //
+ // Draw range reduction is a last resort, texture bias is supposed
+ // to free at least some memory before we get here.
+ // Note: textures were mostly moved to vram, we might want to
+ // detach texture bias from system memory.
+ if (is_sys_low)
+ {
+ // debt is a negative value since MIN_FREE_MAIN_MEMORY > free memory.
+ S32Megabytes sys_budget_debt = free_sys_mem - MEM_LOW_THRESHOLD;
+
+ // Leave some padding, otherwise we will crash out of memory before hitting factor 2.
+ const S32Megabytes PAD_BUFFER(32);
+ S32Megabytes budget_target = MEM_LOW_THRESHOLD - PAD_BUFFER;
+ if (!was_low)
+ {
+ // Result should range from 1 at 0 debt to 2 at -224 debt, 2.14 at -256MB
+ F32 new_factor = 1.f - (F32)sys_budget_debt.value() / (F32)budget_target.value();
+ sSysMemoryFactor = llmax(sSysMemoryFactor, new_factor);
+ }
+ else
+ {
+ // Slowly ramp up factor to free memory (increasing factor decreases draw range)
+ constexpr F32 MAX_INCREMENT = 0.05f;
+ F32 increment = MAX_INCREMENT * llmax(-(F32)sys_budget_debt.value() / (F32)budget_target.value(), 0.f);
+ sSysMemoryFactor += increment * LLFrameTimer::getFrameDeltaTimeF32();
+ }
+ sSysMemoryFactor = llclamp(sSysMemoryFactor, 1.f, 2.f);
+ }
+ else
+ {
+ // Only start ramping down when we have breathing room.
+ // This should be under the value of isSystemMemoryLow to not throw texture
+ // bias into 1.5+ territory each time we fluctuate around isSystemMemoryLow's
+ // threshold.
+ const S32Megabytes MEM_THRESHOLD = MEM_LOW_THRESHOLD + S32Megabytes(150);
+ if (free_sys_mem > MEM_THRESHOLD && sSysMemoryFactor > 1.f)
+ {
+ // Ramp down factor over time.
+ constexpr F32 DECREMENT = 0.02f;
+ sSysMemoryFactor -= DECREMENT * LLFrameTimer::getFrameDeltaTimeF32();
+ sSysMemoryFactor = llclamp(sSysMemoryFactor, 1.f, 2.f);
+ }
+ }
+ was_low = is_sys_low;
+
+ return sSysMemoryFactor;
+}
+
+#if LL_WINDOWS
+//static
+U32Megabytes LLMemory::getAvailableCommitMemMB()
+{
+ // Commit charge combines page file and ram,
+ // theoretical limit is 128TB on 64bit windows.
+ // Store as MB instead of KB to prevent overflow.
+ return sAvailCommitMemInMB;
+}
+#endif
+
//static
U32Kilobytes LLMemory::getAvailableMemKB()
{
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index adc556d180..5f9339bbb7 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2026, 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
@@ -27,6 +27,7 @@
#define LLMEMORY_H
#include "linden_common.h"
+#include "llframetimer.h"
#include "llunits.h"
#include "stdtypes.h"
#if !LL_WINDOWS
@@ -48,6 +49,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 +59,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 +93,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 +115,6 @@ public: \
ll_aligned_free_16(ptr); \
}
-
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// for enable buffer overrun detection predefine LL_DEBUG_BUFFER_OVERRUN in current library
@@ -143,6 +130,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 +156,8 @@ public: \
LL_PROFILE_FREE(ptr);
#if defined(LL_WINDOWS)
_aligned_free(ptr);
+ #elif defined(LL_LINUX)
+ free(ptr);
#else
if (ptr)
{
@@ -179,10 +172,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 +189,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 +202,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);
@@ -428,17 +421,31 @@ public:
static void initMaxHeapSizeGB(F32Gigabytes max_heap_size);
static void updateMemoryInfo() ;
static void logMemoryInfo(bool update = false);
+ static F32 getSystemMemoryBudgetFactor();
+#if LL_WINDOWS
+ // Commit charge is a Windows-only concept, combines page file and ram
+ static U32Megabytes getAvailableCommitMemMB();
+#endif
static U32Kilobytes getAvailableMemKB() ;
static U32Kilobytes getMaxMemKB() ;
static U32Kilobytes getAllocatedMemKB() ;
private:
+ static void updateFreeSystemMemory();
+ // LLMemoryInfo directly updates memory stats
+ friend class LLMemoryInfo;
+
+ static U32Megabytes sAvailCommitMemInMB;
static U32Kilobytes sAvailPhysicalMemInKB ;
static U32Kilobytes sMaxPhysicalMemInKB ;
static U32Kilobytes sAllocatedMemInKB;
static U32Kilobytes sAllocatedPageSizeInKB ;
static U32Kilobytes sMaxHeapSizeInKB;
+
+ static LLFrameTimer sMemoryCheckTimer;
+ static F32 sSysMemoryFactor;
+ static U32 sFactorLastFrameCount;
};
// LLRefCount moved to llrefcount.h
diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h
index f3615a1270..bc3d8fed06 100644
--- a/indra/llcommon/llmutex.h
+++ b/indra/llcommon/llmutex.h
@@ -30,7 +30,7 @@
#include "stdtypes.h"
#include "llthread.h"
-#include "mutex.h"
+#include <mutex>
#include <shared_mutex>
#include <unordered_map>
#include <condition_variable>
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/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 180538eeb9..456f2b02d4 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -854,6 +854,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
@@ -865,12 +879,36 @@ 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;
- LLFILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, "rb");
+ LLFILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, LLFILE_MODE("rb"));
if(cpuinfo_fp)
{
char line[MAX_STRING];
@@ -901,24 +939,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");
@@ -928,7 +959,7 @@ private:
LLPI_SET_INFO_INT(eModel, "model");
- S32 family;
+ S32 family{};
if (!cpuinfo["cpu family"].empty()
&& LLStringUtil::convertToS32(cpuinfo["cpu family"], family))
{
@@ -1009,7 +1040,7 @@ private:
std::ostringstream s;
// *NOTE:Mani - This is for linux only.
- LLFILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "rb");
+ LLFILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, LLFILE_MODE("rb"));
if(cpuinfo)
{
char line[MAX_STRING];
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/llprofilercategories.h b/indra/llcommon/llprofilercategories.h
index 1c4f0f5624..261fdf14b7 100644
--- a/indra/llcommon/llprofilercategories.h
+++ b/indra/llcommon/llprofilercategories.h
@@ -48,6 +48,7 @@
#define LL_PROFILER_CATEGORY_ENABLE_DRAWPOOL 1
#define LL_PROFILER_CATEGORY_ENABLE_ENVIRONMENT 1
#define LL_PROFILER_CATEGORY_ENABLE_FACE 1
+//#define LL_PROFILER_CATEGORY_ENABLE_FILE 1
#define LL_PROFILER_CATEGORY_ENABLE_LLSD 1
#define LL_PROFILER_CATEGORY_ENABLE_LOGGING 1
#define LL_PROFILER_CATEGORY_ENABLE_MATERIAL 1
@@ -126,6 +127,14 @@
#define LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
#endif
+#if LL_PROFILER_CATEGORY_ENABLE_FILE
+#define LL_PROFILE_ZONE_NAMED_CATEGORY_FILE LL_PROFILE_ZONE_NAMED
+#define LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE LL_PROFILE_ZONE_SCOPED
+#else
+#define LL_PROFILE_ZONE_NAMED_CATEGORY_FILE(name)
+#define LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE
+#endif
+
#if LL_PROFILER_CATEGORY_ENABLE_LLSD
#define LL_PROFILE_ZONE_NAMED_CATEGORY_LLSD LL_PROFILE_ZONE_NAMED
#define LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD LL_PROFILE_ZONE_SCOPED
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 ce39bc7af3..ad2ce231fa 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"
@@ -297,10 +296,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 bb806f32eb..acd4bafb85 100644
--- a/indra/llcommon/llsdjson.cpp
+++ b/indra/llcommon/llsdjson.cpp
@@ -26,14 +26,12 @@
// Must turn on conditional declarations in header file so definitions end up
// with proper linkage.
-#define LLSD_DEBUG_INFO
#include "linden_common.h"
#include "llsdjson.h"
#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 ee7f0b01cc..7fe1f9cdd4 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -1421,11 +1421,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()
@@ -2391,6 +2387,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/llsingleton.h b/indra/llcommon/llsingleton.h
index e6989211ae..ebef2489ce 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -30,7 +30,7 @@
#include <typeinfo>
#include <unordered_set>
#include <vector>
-#include "mutex.h"
+#include <mutex>
#include "lockstatic.h"
#include "llthread.h" // on_main_thread()
#include "llmainthreadtask.h"
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index 7a1c7caf82..550725cbc8 100644
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -519,18 +519,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/llstreamqueue.cpp b/indra/llcommon/llstreamqueue.cpp
deleted file mode 100644
index 981d913749..0000000000
--- a/indra/llcommon/llstreamqueue.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * @file llstreamqueue.cpp
- * @author Nat Goodspeed
- * @date 2012-01-05
- * @brief Implementation for llstreamqueue.
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Copyright (c) 2012, Linden Research, Inc.
- * $/LicenseInfo$
- */
-
-// Precompiled header
-#include "linden_common.h"
-// associated header
-#include "llstreamqueue.h"
-// STL headers
-// std headers
-// external library headers
-// other Linden headers
-
-// As of this writing, llstreamqueue.h is entirely template-based, therefore
-// we don't strictly need a corresponding .cpp file. However, our CMake test
-// macro assumes one. Here it is.
-bool llstreamqueue_cpp_ignored = true;
diff --git a/indra/llcommon/llstreamqueue.h b/indra/llcommon/llstreamqueue.h
deleted file mode 100644
index 01689457dd..0000000000
--- a/indra/llcommon/llstreamqueue.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/**
- * @file llstreamqueue.h
- * @author Nat Goodspeed
- * @date 2012-01-04
- * @brief Definition of LLStreamQueue
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Copyright (c) 2012, Linden Research, Inc.
- * $/LicenseInfo$
- */
-
-#if ! defined(LL_LLSTREAMQUEUE_H)
-#define LL_LLSTREAMQUEUE_H
-
-#include <string>
-#include <list>
-#include <iosfwd> // std::streamsize
-#include <boost/iostreams/categories.hpp>
-
-/**
- * This class is a growable buffer between a producer and consumer. It serves
- * as a queue usable with Boost.Iostreams -- hence, a "stream queue."
- *
- * This is especially useful for buffering nonblocking I/O. For instance, we
- * want application logic to be able to serialize LLSD to a std::ostream. We
- * may write more data than the destination pipe can handle all at once, but
- * it's imperative NOT to block the application-level serialization call. So
- * we buffer it instead. Successive frames can try nonblocking writes to the
- * destination pipe until all buffered data has been sent.
- *
- * Similarly, we want application logic be able to deserialize LLSD from a
- * std::istream. Again, we must not block that deserialize call waiting for
- * more data to arrive from the input pipe! Instead we build up a buffer over
- * a number of frames, using successive nonblocking reads, until we have
- * "enough" data to be able to present it through a std::istream.
- *
- * @note The use cases for this class overlap somewhat with those for the
- * LLIOPipe/LLPumpIO hierarchies, and indeed we considered using those. This
- * class has two virtues over the older machinery:
- *
- * # It's vastly simpler -- way fewer concepts. It's not clear to me whether
- * there were ever LLIOPipe/etc. use cases that demanded all the fanciness
- * rolled in, or whether they were simply overdesigned. In any case, no
- * remaining Lindens will admit to familiarity with those classes -- and
- * they're sufficiently obtuse that it would take considerable learning
- * curve to figure out how to use them properly. The bottom line is that
- * current management is not keen on any more engineers climbing that curve.
- * # This class is designed around available components such as std::string,
- * std::list, Boost.Iostreams. There's less proprietary code.
- */
-template <typename Ch>
-class LLGenericStreamQueue
-{
-public:
- LLGenericStreamQueue():
- mSize(0),
- mClosed(false)
- {}
-
- /**
- * Boost.Iostreams Source Device facade for use with other Boost.Iostreams
- * functionality. LLGenericStreamQueue doesn't quite fit any of the Boost
- * 1.48 Iostreams concepts; instead it behaves as both a Sink and a
- * Source. This is its Source facade.
- */
- struct Source
- {
- typedef Ch char_type;
- typedef boost::iostreams::source_tag category;
-
- /// Bind the underlying LLGenericStreamQueue
- Source(LLGenericStreamQueue& sq):
- mStreamQueue(sq)
- {}
-
- // Read up to n characters from the underlying data source into the
- // buffer s, returning the number of characters read; return -1 to
- // indicate EOF
- std::streamsize read(Ch* s, std::streamsize n)
- {
- return mStreamQueue.read(s, n);
- }
-
- LLGenericStreamQueue& mStreamQueue;
- };
-
- /**
- * Boost.Iostreams Sink Device facade for use with other Boost.Iostreams
- * functionality. LLGenericStreamQueue doesn't quite fit any of the Boost
- * 1.48 Iostreams concepts; instead it behaves as both a Sink and a
- * Source. This is its Sink facade.
- */
- struct Sink
- {
- typedef Ch char_type;
- typedef boost::iostreams::sink_tag category;
-
- /// Bind the underlying LLGenericStreamQueue
- Sink(LLGenericStreamQueue& sq):
- mStreamQueue(sq)
- {}
-
- /// Write up to n characters from the buffer s to the output sequence,
- /// returning the number of characters written
- std::streamsize write(const Ch* s, std::streamsize n)
- {
- return mStreamQueue.write(s, n);
- }
-
- /// Send EOF to consumer
- void close()
- {
- mStreamQueue.close();
- }
-
- LLGenericStreamQueue& mStreamQueue;
- };
-
- /// Present Boost.Iostreams Source facade
- Source asSource() { return Source(*this); }
- /// Present Boost.Iostreams Sink facade
- Sink asSink() { return Sink(*this); }
-
- /// append data to buffer
- std::streamsize write(const Ch* s, std::streamsize n)
- {
- // Unclear how often we might be asked to write 0 bytes -- perhaps a
- // naive caller responding to an unready nonblocking read. But if we
- // do get such a call, don't add a completely empty BufferList entry.
- if (n == 0)
- return n;
- // We could implement this using a single std::string object, a la
- // ostringstream. But the trouble with appending to a string is that
- // you might have to recopy all previous contents to grow its size. If
- // we want this to scale to large data volumes, better to allocate
- // individual pieces.
- mBuffer.push_back(string(s, n));
- mSize += n;
- return n;
- }
-
- /**
- * Inform this LLGenericStreamQueue that no further data are forthcoming.
- * For our purposes, close() is strictly a producer-side operation;
- * there's little point in closing the consumer side.
- */
- void close()
- {
- mClosed = true;
- }
-
- /// consume data from buffer
- std::streamsize read(Ch* s, std::streamsize n)
- {
- // read() is actually a convenience method for peek() followed by
- // skip().
- std::streamsize got(peek(s, n));
- // We can only skip() as many characters as we can peek(); ignore
- // skip() return here.
- skip(n);
- return got;
- }
-
- /// Retrieve data from buffer without consuming. Like read(), return -1 on
- /// EOF.
- std::streamsize peek(Ch* s, std::streamsize n) const;
-
- /// Consume data from buffer without retrieving. Unlike read() and peek(),
- /// at EOF we simply skip 0 characters.
- std::streamsize skip(std::streamsize n);
-
- /// How many characters do we currently have buffered?
- std::streamsize size() const
- {
- return mSize;
- }
-
-private:
- typedef std::basic_string<Ch> string;
- typedef std::list<string> BufferList;
- BufferList mBuffer;
- std::streamsize mSize;
- bool mClosed;
-};
-
-template <typename Ch>
-std::streamsize LLGenericStreamQueue<Ch>::peek(Ch* s, std::streamsize n) const
-{
- // Here we may have to build up 'n' characters from an arbitrary
- // number of individual BufferList entries.
- typename BufferList::const_iterator bli(mBuffer.begin()), blend(mBuffer.end());
- // Indicate EOF if producer has closed the pipe AND we've exhausted
- // all previously-buffered data.
- if (mClosed && bli == blend)
- {
- return -1;
- }
- // Here either producer hasn't yet closed, or we haven't yet exhausted
- // remaining data.
- std::streamsize needed(n), got(0);
- // Loop until either we run out of BufferList entries or we've
- // completely satisfied the request.
- for ( ; bli != blend && needed; ++bli)
- {
- std::streamsize chunk(std::min(needed, std::streamsize(bli->length())));
- std::copy(bli->begin(), bli->begin() + chunk, s);
- needed -= chunk;
- s += chunk;
- got += chunk;
- }
- return got;
-}
-
-template <typename Ch>
-std::streamsize LLGenericStreamQueue<Ch>::skip(std::streamsize n)
-{
- typename BufferList::iterator bli(mBuffer.begin()), blend(mBuffer.end());
- std::streamsize toskip(n), skipped(0);
- while (bli != blend && (size_t)toskip >= bli->length())
- {
- std::streamsize chunk(bli->length());
- typename BufferList::iterator zap(bli++);
- mBuffer.erase(zap);
- mSize -= chunk;
- toskip -= chunk;
- skipped += chunk;
- }
- if (bli != blend && toskip)
- {
- bli->erase(bli->begin(), bli->begin() + toskip);
- mSize -= toskip;
- skipped += toskip;
- }
- return skipped;
-}
-
-typedef LLGenericStreamQueue<char> LLStreamQueue;
-typedef LLGenericStreamQueue<wchar_t> LLWStreamQueue;
-
-#endif /* ! defined(LL_LLSTREAMQUEUE_H) */
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 051f24fcb5..bc38b72004 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2026, 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
@@ -43,6 +43,7 @@
#include "llerrorcontrol.h"
#include "llevents.h"
#include "llformat.h"
+#include "llmemory.h"
#include "llregex.h"
#include "lltimer.h"
#include "llsdserialize.h"
@@ -506,57 +507,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", LLFILE_MODE("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
@@ -756,7 +746,7 @@ public:
void add(const LLSD::String& name, const T& value,
typename std::enable_if_t<std::is_integral_v<T> >* = 0)
{
- mStats[name] = LLSD::Integer(value);
+ mStats[name] = LLSD::Integer(llmin<T>(value, S32_MAX));
}
// Store every floating-point type as LLSD::Real.
@@ -837,15 +827,13 @@ U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
}
//static
-void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb)
+void LLMemoryInfo::updateAvailableMemory()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
#if LL_WINDOWS
- // Sigh, this shouldn't be a static method, then we wouldn't have to
- // reload this data separately from refresh()
- LLSD statsMap(loadStatsMap());
-
- avail_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger();
+ // On windows loadStatsMap will fill sAvailPhysicalMemInKB,
+ // sAvailCommitMemInMB, sAllocatedMemInKB and sAllocatedPageSizeInKB
+ loadStatsMap();
#elif LL_DARWIN
// use host_statistics64 to get memory info
@@ -857,70 +845,21 @@ void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb)
kern_return_t result = host_statistics64(host, HOST_VM_INFO64, reinterpret_cast<host_info_t>(&vmstat), &count);
if (result == KERN_SUCCESS)
{
- avail_mem_kb = U64Bytes((vmstat.free_count + vmstat.inactive_count) * page_size);
+ LLMemory::sAvailPhysicalMemInKB = U64Bytes((vmstat.free_count + vmstat.inactive_count) * page_size);
}
else
{
- avail_mem_kb = (U32Kilobytes)-1;
+ LLMemory::sAvailPhysicalMemInKB = (U32Kilobytes)-1;
}
#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());
+ LLMemory::sAvailPhysicalMemInKB = U64Bytes(phys);
#else
//do not know how to collect available memory info for other systems.
//leave it blank here for now.
- avail_mem_kb = (U32Kilobytes)-1 ;
+ LLMemory::sAvailPhysicalMemInKB = (U32Kilobytes)-1 ;
#endif
}
@@ -991,15 +930,24 @@ LLSD LLMemoryInfo::loadStatsMap()
state.dwLength = sizeof(state);
GlobalMemoryStatusEx(&state);
- DWORDLONG div = 1024;
+ static constexpr DWORDLONG div = 1024;
- stats.add("Percent Memory use", state.dwMemoryLoad/div);
+ stats.add("Percent Memory use", state.dwMemoryLoad);
stats.add("Total Physical KB", state.ullTotalPhys/div);
stats.add("Avail Physical KB", state.ullAvailPhys/div);
+
+ // Despite the confusing naming "PageFile" , these values
+ // actually represent the committed memory limit for
+ // the system or the current process, whichever is smaller.
stats.add("Total page KB", state.ullTotalPageFile/div);
stats.add("Avail page KB", state.ullAvailPageFile/div);
- stats.add("Total Virtual KB", state.ullTotalVirtual/div);
- stats.add("Avail Virtual KB", state.ullAvailVirtual/div);
+
+ static constexpr DWORDLONG mb_div = 1024 * 1024;
+ stats.add("Total Virtual MB", state.ullTotalVirtual/mb_div); // ~134 million MB
+ stats.add("Avail Virtual MB", state.ullAvailVirtual/mb_div);
+
+ LLMemory::sAvailPhysicalMemInKB = U32Kilobytes::convert(U64Bytes(state.ullAvailPhys));
+ LLMemory::sAvailCommitMemInMB = U32Megabytes::convert(U64Bytes(state.ullAvailPageFile));
// SL-12122 - Call to GetPerformanceInfo() was removed here. Took
// on order of 10 ms, causing unacceptable frame time spike every
@@ -1015,18 +963,38 @@ LLSD LLMemoryInfo::loadStatsMap()
// specifically accepts PROCESS_MEMORY_COUNTERS*, and since this is a
// classic-C API, PROCESS_MEMORY_COUNTERS_EX isn't a subclass. Cast the
// pointer.
- GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmem, sizeof(pmem));
+ if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmem, sizeof(pmem)))
+ {
+ LLMemory::sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(pmem.WorkingSetSize));
+ LLMemory::sAllocatedPageSizeInKB = U32Kilobytes::convert(U64Bytes(pmem.PagefileUsage));
- stats.add("Page Fault Count", pmem.PageFaultCount);
- stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize/div);
- stats.add("WorkingSetSize KB", pmem.WorkingSetSize/div);
- stats.add("QutaPeakPagedPoolUsage KB", pmem.QuotaPeakPagedPoolUsage/div);
- stats.add("QuotaPagedPoolUsage KB", pmem.QuotaPagedPoolUsage/div);
- stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage/div);
- stats.add("QuotaNonPagedPoolUsage KB", pmem.QuotaNonPagedPoolUsage/div);
- stats.add("PagefileUsage KB", pmem.PagefileUsage/div);
- stats.add("PeakPagefileUsage KB", pmem.PeakPagefileUsage/div);
- stats.add("PrivateUsage KB", pmem.PrivateUsage/div);
+ stats.add("Page Fault Count", pmem.PageFaultCount);
+ stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize / div);
+ stats.add("WorkingSetSize KB", pmem.WorkingSetSize / div);
+ stats.add("QuotaPeakPagedPoolUsage KB", pmem.QuotaPeakPagedPoolUsage / div);
+ stats.add("QuotaPagedPoolUsage KB", pmem.QuotaPagedPoolUsage / div);
+ stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage / div);
+ stats.add("QuotaNonPagedPoolUsage KB", pmem.QuotaNonPagedPoolUsage / div);
+ stats.add("PagefileUsage KB", pmem.PagefileUsage / div);
+ stats.add("PeakPagefileUsage KB", pmem.PeakPagefileUsage / div);
+ stats.add("PrivateUsage KB", pmem.PrivateUsage / div);
+ }
+ else
+ {
+ LLMemory::sAllocatedMemInKB = U32Kilobytes(0);
+ LLMemory::sAllocatedPageSizeInKB = U32Kilobytes(0);
+
+ stats.add("Page Fault Count", 0);
+ stats.add("PeakWorkingSetSize KB", 0);
+ stats.add("WorkingSetSize KB", 0);
+ stats.add("QuotaPeakPagedPoolUsage KB", 0);
+ stats.add("QuotaPagedPoolUsage KB", 0);
+ stats.add("QuotaPeakNonPagedPoolUsage KB", 0);
+ stats.add("QuotaNonPagedPoolUsage KB", 0);
+ stats.add("PagefileUsage KB", 0);
+ stats.add("PeakPagefileUsage KB", 0);
+ stats.add("PrivateUsage KB", 0);
+ }
#elif LL_DARWIN
@@ -1115,7 +1083,7 @@ LLSD LLMemoryInfo::loadStatsMap()
}
#elif LL_LINUX
- std::ifstream meminfo(MEMINFO_FILE);
+ llifstream meminfo(MEMINFO_FILE);
if (meminfo.is_open())
{
// MemTotal: 4108424 kB
@@ -1155,9 +1123,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&)
{
@@ -1166,6 +1135,7 @@ LLSD LLMemoryInfo::loadStatsMap()
<< line << LL_ENDL;
continue;
}
+ value = LLSD::Integer(intval);
// Store this statistic.
stats.add(key, value);
}
@@ -1366,7 +1336,7 @@ bool gunzip_file(const std::string& srcfile, const std::string& dstfile)
src = gzopen(srcfile.c_str(), "rb");
#endif
if (! src) goto err;
- dst = LLFile::fopen(tmpfile, "wb"); /* Flawfinder: ignore */
+ dst = LLFile::fopen(tmpfile, LLFILE_MODE("wb")); /* Flawfinder: ignore */
if (! dst) goto err;
do
{
@@ -1407,7 +1377,7 @@ bool gzip_file(const std::string& srcfile, const std::string& dstfile)
#endif
if (! dst) goto err;
- src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */
+ src = LLFile::fopen(srcfile, LLFILE_MODE("rb")); /* Flawfinder: ignore */
if (! src) goto err;
while ((bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE, src)) > 0)
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index e19f6922f3..aeba5563ba 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2026, 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
@@ -142,11 +142,12 @@ public:
static U32Kilobytes getHardwareMemSize(); // Because some Mac linkers won't let us reference extern gSysMemory from a different lib.
#endif
- //get the available memory in KiloBytes.
- static void getAvailableMemoryKB(U32Kilobytes& avail_mem_kb);
+ // Updates LLMemory's values.
+ static void updateAvailableMemory();
// Retrieve a map of memory statistics. The keys of the map are platform-
- // dependent. The values are in kilobytes to try to avoid integer overflow.
+ // dependent.
+ // On Windows updates LLMemory values.
LLSD getStatsMap() const;
// Re-fetch memory data (as reported by stream() and getStatsMap()) from the
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 4f15626108..277edcb6a2 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/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 1a1d06a6fd..2a18b4a438 100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -32,7 +32,7 @@
#include <boost/fiber/timed_mutex.hpp>
#include LLCOROS_CONDVAR_HEADER
#include "llexception.h"
-#include "mutex.h"
+#include <mutex>
#include <chrono>
#include <queue>
#include <string>
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/lluuid.cpp b/indra/llcommon/lluuid.cpp
index 4aae90626e..867744a29d 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -151,6 +151,48 @@ U32 janky_fast_random_seeded_bytes(U32 seed, U32 val)
}
#endif
+void LLUUID::to_chars(char* out) const
+{
+ snprintf(out, UUID_STR_LENGTH, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (U8)(mData[0]),
+ (U8)(mData[1]),
+ (U8)(mData[2]),
+ (U8)(mData[3]),
+ (U8)(mData[4]),
+ (U8)(mData[5]),
+ (U8)(mData[6]),
+ (U8)(mData[7]),
+ (U8)(mData[8]),
+ (U8)(mData[9]),
+ (U8)(mData[10]),
+ (U8)(mData[11]),
+ (U8)(mData[12]),
+ (U8)(mData[13]),
+ (U8)(mData[14]),
+ (U8)(mData[15]));
+}
+
+void LLUUID::to_wchars(wchar_t* out) const
+{
+ swprintf(out, UUID_STR_LENGTH, L"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (U8)(mData[0]),
+ (U8)(mData[1]),
+ (U8)(mData[2]),
+ (U8)(mData[3]),
+ (U8)(mData[4]),
+ (U8)(mData[5]),
+ (U8)(mData[6]),
+ (U8)(mData[7]),
+ (U8)(mData[8]),
+ (U8)(mData[9]),
+ (U8)(mData[10]),
+ (U8)(mData[11]),
+ (U8)(mData[12]),
+ (U8)(mData[13]),
+ (U8)(mData[14]),
+ (U8)(mData[15]));
+}
+
// Common to all UUID implementations
void LLUUID::toString(std::string& out) const
{
@@ -405,8 +447,8 @@ LLUUID LLUUID::combine(const LLUUID& other) const
std::ostream& operator<<(std::ostream& s, const LLUUID& uuid)
{
- std::string uuid_str;
- uuid.toString(uuid_str);
+ char uuid_str[UUID_STR_LENGTH];
+ uuid.to_chars(uuid_str);
s << uuid_str;
return s;
}
diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h
index f91aadccc0..122cf414ca 100644
--- a/indra/llcommon/lluuid.h
+++ b/indra/llcommon/lluuid.h
@@ -104,6 +104,8 @@ public:
friend LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLUUID &uuid);
friend LL_COMMON_API std::istream& operator>>(std::istream& s, LLUUID &uuid);
+ void to_chars(char* out) const;
+ void to_wchars(wchar_t* out) const;
void toString(std::string& out) const;
void toCompressedString(std::string& out) const;
diff --git a/indra/llcommon/llwatchdog.cpp b/indra/llcommon/llwatchdog.cpp
index b17b68dbe7..ad7c2db62e 100644
--- a/indra/llcommon/llwatchdog.cpp
+++ b/indra/llcommon/llwatchdog.cpp
@@ -122,6 +122,11 @@ bool LLWatchdogTimeout::hasExpired() const
return mTimer.hasExpired();
}
+bool LLWatchdogTimeout::started() const
+{
+ return mTimer.getStarted();
+}
+
void LLWatchdogTimeout::reset()
{
mTimer.setTimerExpirySec(mTimeout);
diff --git a/indra/llcommon/llwatchdog.h b/indra/llcommon/llwatchdog.h
index ea567197c5..9386bd6bb3 100644
--- a/indra/llcommon/llwatchdog.h
+++ b/indra/llcommon/llwatchdog.h
@@ -48,6 +48,7 @@ public:
// isAlive and other method may need synchronization.
virtual bool isAlive() const = 0;
virtual bool hasExpired() const = 0;
+ virtual bool started() const = 0;
virtual void reset() = 0;
virtual void start();
virtual void stop();
@@ -68,6 +69,7 @@ public:
bool isAlive() const override;
bool hasExpired() const override;
+ bool started() const override;
void reset() override;
void start() override { start(""); }
void stop() override;
diff --git a/indra/llcommon/lockstatic.h b/indra/llcommon/lockstatic.h
index 7cc9b7eec0..db4c7af0ec 100644
--- a/indra/llcommon/lockstatic.h
+++ b/indra/llcommon/lockstatic.h
@@ -13,7 +13,7 @@
#if ! defined(LL_LOCKSTATIC_H)
#define LL_LOCKSTATIC_H
-#include "mutex.h" // std::unique_lock
+#include <mutex> // std::unique_lock
namespace llthread
{
diff --git a/indra/llcommon/mutex.h b/indra/llcommon/mutex.h
deleted file mode 100644
index 82e46315e2..0000000000
--- a/indra/llcommon/mutex.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * @file mutex.h
- * @author Nat Goodspeed
- * @date 2019-12-03
- * @brief Wrap <mutex> in odious boilerplate
- *
- * $LicenseInfo:firstyear=2019&license=viewerlgpl$
- * Copyright (c) 2019, Linden Research, Inc.
- * $/LicenseInfo$
- */
-
-#if LL_WINDOWS
-#pragma warning (push)
-#pragma warning (disable:4265)
-#endif
-// warning C4265: 'std::_Pad' : class has virtual functions, but destructor is not virtual
-
-#include <mutex>
-
-#if LL_WINDOWS
-#pragma warning (pop)
-#endif
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/llallocator_heap_profile_test.cpp b/indra/llcommon/tests/llallocator_heap_profile_test.cpp
deleted file mode 100644
index da8b54ffc0..0000000000
--- a/indra/llcommon/tests/llallocator_heap_profile_test.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * @file llallocator_heap_profile_test.cpp
- * @author Brad Kittenbrink
- * @date 2008-02-
- * @brief Test for llallocator_heap_profile.cpp.
- *
- * $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$
- */
-
-#include "../llallocator_heap_profile.h"
-#include "../test/lltut.h"
-
-namespace tut
-{
- struct llallocator_heap_profile_data
- {
- LLAllocatorHeapProfile prof;
-
- static char const * const sample_win_profile;
- // *TODO - get test output from mac/linux tcmalloc
- static char const * const sample_mac_profile;
- static char const * const sample_lin_profile;
-
- static char const * const crash_testcase;
- };
- typedef test_group<llallocator_heap_profile_data> factory;
- typedef factory::object object;
-}
-namespace
-{
- tut::factory llallocator_heap_profile_test_factory("LLAllocatorHeapProfile");
-}
-
-namespace tut
-{
- template<> template<>
- void object::test<1>()
- {
- prof.parse(sample_win_profile);
-
- ensure_equals("count lines", prof.mLines.size() , 5);
- ensure_equals("alloc counts", prof.mLines[0].mLiveCount, 2131854U);
- ensure_equals("alloc counts", prof.mLines[0].mLiveSize, 2245710106ULL);
- ensure_equals("alloc counts", prof.mLines[0].mTotalCount, 14069198U);
- ensure_equals("alloc counts", prof.mLines[0].mTotalSize, 4295177308ULL);
- ensure_equals("count markers", prof.mLines[0].mTrace.size(), 0);
- ensure_equals("count markers", prof.mLines[1].mTrace.size(), 0);
- ensure_equals("count markers", prof.mLines[2].mTrace.size(), 4);
- ensure_equals("count markers", prof.mLines[3].mTrace.size(), 6);
- ensure_equals("count markers", prof.mLines[4].mTrace.size(), 7);
-
- //prof.dump(std::cout);
- }
-
- template<> template<>
- void object::test<2>()
- {
- prof.parse(crash_testcase);
-
- ensure_equals("count lines", prof.mLines.size(), 2);
- ensure_equals("alloc counts", prof.mLines[0].mLiveCount, 3U);
- ensure_equals("alloc counts", prof.mLines[0].mLiveSize, 1049652ULL);
- ensure_equals("alloc counts", prof.mLines[0].mTotalCount, 8U);
- ensure_equals("alloc counts", prof.mLines[0].mTotalSize, 1049748ULL);
- ensure_equals("count markers", prof.mLines[0].mTrace.size(), 0);
- ensure_equals("count markers", prof.mLines[1].mTrace.size(), 0);
-
- //prof.dump(std::cout);
- }
-
- template<> template<>
- void object::test<3>()
- {
- // test that we don't crash on edge case data
- prof.parse("");
- ensure("emtpy on error", prof.mLines.empty());
-
- prof.parse("heap profile:");
- ensure("emtpy on error", prof.mLines.empty());
- }
-
-char const * const llallocator_heap_profile_data::sample_win_profile =
-"heap profile: 2131854: 2245710106 [14069198: 4295177308] @\n"
-"308592: 1073398388 [966564: 1280998739] @\n"
-"462651: 375969538 [1177377: 753561247] @ 2 3 6 1\n"
-"314744: 206611283 [2008722: 570934755] @ 2 3 3 7 21 32\n"
-"277152: 82862770 [621961: 168503640] @ 2 3 3 7 21 32 87\n"
-"\n"
-"MAPPED_LIBRARIES:\n"
-"00400000-02681000 r-xp 00000000 00:00 0 c:\\proj\\tcmalloc-eval-9\\indra\\build-vc80\\newview\\RelWithDebInfo\\secondlife-bin.exe\n"
-"77280000-773a7000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\ntdll.dll\n"
-"76df0000-76ecb000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\kernel32.dll\n"
-"76000000-76073000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\comdlg32.dll\n"
-"75ee0000-75f8a000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\msvcrt.dll\n"
-"76c30000-76c88000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\SHLWAPI.dll\n"
-"75f90000-75fdb000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\GDI32.dll\n"
-"77420000-774bd000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\USER32.dll\n"
-"75e10000-75ed6000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\ADVAPI32.dll\n"
-"75b00000-75bc2000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\RPCRT4.dll\n"
-"72ca0000-72d25000 r-xp 00000000 00:00 0 C:\\Windows\\WinSxS\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.6001.18000_none_886786f450a74a05\\COMCTL32.dll\n"
-"76120000-76c30000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\SHELL32.dll\n"
-"71ce0000-71d13000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\DINPUT8.dll\n";
-
-
-char const * const llallocator_heap_profile_data::crash_testcase =
-"heap profile: 3: 1049652 [ 8: 1049748] @\n"
-" 3: 1049652 [ 8: 1049748] @\n"
-"\n"
-"MAPPED_LIBRARIES:\n"
-"00400000-004d5000 r-xp 00000000 00:00 0 c:\\code\\linden\\tcmalloc\\indra\\build-vc80\\llcommon\\RelWithDebInfo\\llallocator_test.exe\n"
-"7c900000-7c9af000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\ntdll.dll\n"
-"7c800000-7c8f6000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\kernel32.dll\n"
-"77dd0000-77e6b000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\ADVAPI32.dll\n"
-"77e70000-77f02000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\RPCRT4.dll\n"
-"77fe0000-77ff1000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\Secur32.dll\n"
-"71ab0000-71ac7000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\WS2_32.dll\n"
-"77c10000-77c68000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\msvcrt.dll\n"
-"71aa0000-71aa8000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\WS2HELP.dll\n"
-"76bf0000-76bfb000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\PSAPI.DLL\n"
-"5b860000-5b8b5000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\NETAPI32.dll\n"
-"10000000-10041000 r-xp 00000000 00:00 0 c:\\code\\linden\\tcmalloc\\indra\\build-vc80\\llcommon\\RelWithDebInfo\\libtcmalloc_minimal.dll\n"
-"7c420000-7c4a7000 r-xp 00000000 00:00 0 C:\\WINDOWS\\WinSxS\\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.1433_x-ww_5cf844d2\\MSVCP80.dll\n"
-"78130000-781cb000 r-xp 00000000 00:00 0 C:\\WINDOWS\\WinSxS\\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.1433_x-ww_5cf844d2\\MSVCR80.dll\n";
-
-}
diff --git a/indra/llcommon/tests/llallocator_test.cpp b/indra/llcommon/tests/llallocator_test.cpp
deleted file mode 100644
index a7573641c7..0000000000
--- a/indra/llcommon/tests/llallocator_test.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * @file llallocator_test.cpp
- * @author Brad Kittenbrink
- * @date 2008-02-
- * @brief Test for llallocator.cpp.
- *
- * $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$
- */
-
-#include "../llallocator.h"
-#include "../test/lltut.h"
-
-namespace tut
-{
- struct llallocator_data
- {
- LLAllocator llallocator;
- };
- typedef test_group<llallocator_data> factory;
- typedef factory::object object;
-}
-namespace
-{
- tut::factory llallocator_test_factory("LLAllocator");
-}
-
-namespace tut
-{
- template<> template<>
- void object::test<1>()
- {
- llallocator.setProfilingEnabled(false);
- ensure("Profiler disable", !llallocator.isProfiling());
- }
-
-#if LL_USE_TCMALLOC
- template<> template<>
- void object::test<2>()
- {
- llallocator.setProfilingEnabled(true);
- ensure("Profiler enable", llallocator.isProfiling());
- }
-
- template <> template <>
- void object::test<3>()
- {
- llallocator.setProfilingEnabled(true);
-
- char * test_alloc = new char[1024];
-
- llallocator.getProfile();
-
- delete [] test_alloc;
-
- llallocator.getProfile();
-
- // *NOTE - this test isn't ensuring anything right now other than no
- // exceptions are thrown.
- }
-#endif // LL_USE_TCMALLOC
-};
diff --git a/indra/test/llapp_tut.cpp b/indra/llcommon/tests/llapp_test.cpp
index 114af6edbf..114af6edbf 100644
--- a/indra/test/llapp_tut.cpp
+++ b/indra/llcommon/tests/llapp_test.cpp
diff --git a/indra/llcommon/tests/lldependencies_test.cpp b/indra/llcommon/tests/lldependencies_test.cpp
index 2fea92e3b7..fd554005a3 100644
--- a/indra/llcommon/tests/lldependencies_test.cpp
+++ b/indra/llcommon/tests/lldependencies_test.cpp
@@ -228,19 +228,7 @@ namespace tut
StringList keys(StringList{ "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/test/lldoubledispatch_tut.cpp b/indra/llcommon/tests/lldoubledispatch_test.cpp
index 79c4edc058..79c4edc058 100644
--- a/indra/test/lldoubledispatch_tut.cpp
+++ b/indra/llcommon/tests/lldoubledispatch_test.cpp
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/test/llevents_tut.cpp b/indra/llcommon/tests/llevents_test.cpp
index c5d5dcb9d4..c5d5dcb9d4 100644
--- a/indra/test/llevents_tut.cpp
+++ b/indra/llcommon/tests/llevents_test.cpp
diff --git a/indra/llcommon/tests/llfile_test.cpp b/indra/llcommon/tests/llfile_test.cpp
new file mode 100644
index 0000000000..ab4616cfb2
--- /dev/null
+++ b/indra/llcommon/tests/llfile_test.cpp
@@ -0,0 +1,299 @@
+/**
+ * @file llfile_test.cpp
+ * @author Frederick Martian
+ * @date 2025-11
+ * @brief LLFile test cases.
+ *
+ * $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 <tut/tut.hpp>
+#include "lltut.h"
+#include "linden_common.h"
+#include "llfile.h"
+
+namespace tut
+{
+ static void clear_entire_dir(const std::filesystem::path& dir_path)
+ {
+ std::error_code ec;
+ std::filesystem::remove_all(dir_path, ec);
+ }
+
+ static std::filesystem::path append_filename(const std::filesystem::path& dir, const std::u8string& element)
+ {
+ std::filesystem::path path = dir;
+ return path.append(element);
+ }
+
+ static std::filesystem::path get_testdir(const std::filesystem::path& tempdir)
+ {
+ return append_filename(tempdir, std::u8string(u8"test_dir"));
+ }
+
+ static std::filesystem::path get_testdir_unicode(const std::filesystem::path& tempdir)
+ {
+ // Example Unicode directory name: "test_ユニコード_dir"
+ return append_filename(tempdir, std::u8string(u8"test_\xE3\x83\xA6\xE3\x83\x8B\xE3\x82\xB3\xE3\x83\xBC\xE3\x83\x89_dir"));
+ }
+
+ struct llfile_test
+ {
+ std::filesystem::path tempdir = LLFile::tmpdir();
+ std::filesystem::path testdir = get_testdir(tempdir);
+ };
+ typedef test_group<llfile_test> llfile_test_t;
+ typedef llfile_test_t::object llfile_test_object_t;
+ tut::llfile_test_t tut_llfile_test("llfile_test");
+
+ template<> template<>
+ void llfile_test_object_t::test<1>()
+ {
+ // Test creating directories and files and deleting them and checking if the
+ // relevant status functions work as expected
+ ensure("LLFile::tmpdir() empty", !tempdir.empty());
+ ensure("LLFile::tmpdir() doesn't exist", LLFile::exists(tempdir));
+ ensure("LLFile::tmpdir() is not a directory", LLFile::isdir(tempdir));
+ ensure("LLFile::tmpdir() should not be a file", !LLFile::isfile(tempdir));
+
+ // Make sure there is nothing left from a previous test run
+ clear_entire_dir(testdir);
+ ensure("llfile_test should not exist anymore", !LLFile::exists(testdir));
+
+ int rc = LLFile::mkdir(testdir);
+ ensure("LLFile::mkdir() failed", rc == 0);
+ ensure("llfile_test should be a directory", LLFile::isdir(testdir));
+ rc = LLFile::mkdir(testdir);
+ ensure("LLFile::mkdir() should not fail when the directory already exists", rc == 0);
+
+ std::filesystem::path testfile1 = testdir;
+ testfile1.append("llfile_test.dat");
+ ensure("llfile_test1.dat should not yet exist", !LLFile::exists(testfile1));
+
+ const char* testdata = "testdata";
+ S64 bytes = LLFile::write(testfile1, testdata, 0, sizeof(testdata));
+ ensure("LLFile::write() did not write correctly", bytes == sizeof(testdata));
+
+ rc = LLFile::remove(testfile1);
+ ensure("LLFile::remove() for file test_file.dat", rc == 0);
+ ensure("llfile_test.dat should not exist anymore", !LLFile::exists(testfile1));
+ ensure("llfile_test.dat should not be a file", !LLFile::isfile(testfile1));
+ ensure("llfile_test.dat should not be a directory", !LLFile::isdir(testfile1));
+ ensure("llfile_test.dat should not be a symlink", !LLFile::islink(testfile1));
+
+ rc = LLFile::remove(testdir);
+ ensure("LLFile::remove() for directory llfile_test failed", rc == 0);
+ ensure("llfile_test should not exist anymore", !LLFile::exists(testdir));
+ }
+
+ template<> template<>
+ void llfile_test_object_t::test<2>()
+ {
+ // High level static file IO functions to read and write data files
+ LLFile::mkdir(testdir);
+ ensure("llfile_test should exist", LLFile::isdir(testdir));
+
+ std::filesystem::path testfile1 = testdir;
+ testfile1.append("llfile_test.dat");
+
+ std::string testdata1("testdata");
+ std::string testdata2("datateststuff");
+ std::time_t current = time(nullptr);
+ S64 bytes = LLFile::write(testfile1, testdata1.c_str(), 0, testdata1.length());
+ ensure("LLFile::write() did not write correctly", bytes == testdata1.length());
+ ensure("llfile_test.dat should exist", LLFile::exists(testfile1));
+ ensure("llfile_test.dat should be a file", LLFile::isfile(testfile1));
+ ensure("llfile_test.dat should not be a directory", !LLFile::isdir(testfile1));
+
+ bytes = LLFile::size(testfile1);
+ ensure("LLFile::size() did not return the correct size", bytes == testdata1.length());
+
+ std::string data = LLFile::getContents(testfile1);
+ ensure("LLFile::getContents() did not return the correct size data", data.length() == testdata1.length());
+ ensure_memory_matches("LLFile::getContents() did not read correct data", testdata1.c_str(), (U32)testdata1.length(), data.c_str(), (U32)data.length());
+
+ char buffer[1024];
+ bytes = LLFile::read(testfile1, buffer, 0, testdata1.length());
+ ensure("LLFile:read() did not return the correct size", bytes == testdata1.length());
+ ensure_memory_matches("LLFile::read() did not read correct data", testdata1.c_str(), (U32)bytes, buffer, (U32)bytes);
+
+ // What if we try to read more data than there is in the file?
+ bytes = LLFile::read(testfile1, buffer, 0, bytes + 10);
+ ensure("LLFile:read() did not correctly stop on eof", bytes == testdata1.length());
+ ensure_memory_matches("LLFile::read() did not read correct data", testdata1.c_str(), (U32)bytes, buffer, (U32)bytes);
+
+ // Let's append more data
+ bytes = LLFile::write(testfile1, testdata2.c_str(), -1, testdata2.length());
+ ensure("LLFile::write() did not write correctly", bytes == testdata2.length());
+
+ bytes = LLFile::size(testfile1);
+ ensure("LLFile::size() did not return the correct size", bytes == testdata1.length() + testdata2.length());
+ bytes = LLFile::read(testfile1, buffer, 0, bytes);
+ ensure("LLFile:read() did not read correct number of bytes", bytes == testdata1.length() + testdata2.length());
+ ensure_memory_matches("LLFile:read() did not read correct testdata1", testdata1.c_str(), (U32)testdata1.length(), buffer, (U32)testdata1.length());
+ ensure_memory_matches("LLFile:read() did not read correct testdata2", testdata2.c_str(), (U32)testdata2.length(), buffer + testdata1.length(), (U32)testdata2.length());
+ }
+
+ template<> template<>
+ void llfile_test_object_t::test<3>()
+ {
+ const size_t numints = 1024;
+
+ // Testing the LLFile class implementation
+ std::filesystem::path testfile = testdir;
+ testfile.append("llfile_test.bin");
+
+ int data[numints];
+ for (int &t : data)
+ {
+ t = rand();
+ }
+
+ std::error_code ec;
+ LLFile fileout(testfile, LLFile::out, ec);
+ ensure("LLFile constructor did not open correctly", (bool)fileout);
+ ensure("error_code from LLFile constructor should not indicate an error", !ec);
+ if (fileout)
+ {
+ S64 length = fileout.size(ec);
+ ensure("freshly created file should be empty", length == 0);
+ ensure("error_code from LLFile::size() should not indicate an error", !ec);
+ S64 bytes = fileout.write(data, sizeof(data), ec);
+ ensure("LLFile::write() did not write correctly", bytes == sizeof(data));
+ ensure("error_code from LLFile::write() should not indicate an error", !ec);
+ bytes = fileout.write(data, sizeof(data), ec);
+ ensure("LLFile::write() did not write correctly", bytes == sizeof(data));
+ ensure("error_code from LLFile::write() should not indicate an error", !ec);
+ bytes = fileout.size(ec);
+ ensure("LLFile::size() returned wrong size", bytes == 2 * sizeof(data));
+ ensure("error_code from LLFile::size() should not indicate an error", !ec);
+ fileout.close();
+ }
+
+ LLFile filein(testfile, LLFile::in, ec);
+ ensure("LLFile constructor did not open correctly", (bool)filein);
+ ensure("error_code from LLFile constructor should not indicate an error", !ec);
+ if (filein)
+ {
+ S64 length = filein.size(ec);
+ ensure("LLFile::size() returned wrong size", length == 2 * sizeof(data));
+ ensure("error_code from LLFile::size() should not indicate an error", !ec);
+ char* buffer = (char*)malloc(length);
+ S64 bytes = filein.read(buffer, length, ec);
+ ensure("LLFile::read() did not read correctly", bytes == length);
+ ensure("error_code from LLFile::read() should not indicate an error", !ec);
+ ensure_memory_matches("LLFile:read() did not read correct data1", data, (U32)sizeof(data), buffer, (U32)sizeof(data));
+ ensure_memory_matches("LLFile:read() did not read correct data2", data, (U32)sizeof(data), buffer + sizeof(data), (U32)sizeof(data));
+ S64 offset = filein.tell(ec);
+ ensure("LLFile::tell() returned a bad offset", offset == length);
+ ensure("error_code from LLFile::read() should not indicate an error", !ec);
+ offset = sizeof(data) / 2;
+ int rc = filein.seek(offset, ec);
+ ensure("LLFile::seek() indicated an error", rc == 0);
+ ensure("error_code from LLFile::seek() should not indicate an error", !ec);
+ bytes = filein.read(buffer, 2 * sizeof(data), ec);
+ ensure("LLFile::read() did not read correctly", bytes == sizeof(data) + offset);
+ ensure("error_code from LLFile::read() should not indicate an error", !ec);
+ ensure_memory_matches("LLFile:read() did not read correct data3", (char*)data + offset, (U32)offset, buffer, (U32)offset);
+ ensure_memory_matches("LLFile:read() did not read correct data4", (char*)data, (U32)sizeof(data), buffer + offset, (U32)sizeof(data));
+ filein.close();
+
+ free(buffer);
+ }
+ }
+
+ template<> template<>
+ void llfile_test_object_t::test<4>()
+ {
+ // Testing the LLFile class implementation with wrong paths and parameters
+ std::filesystem::path testfile = testdir;
+ testfile.append("llfile_test.bin");
+
+ std::error_code ec;
+ LLFile file(testfile, LLFile::out | LLFile::noreplace, ec);
+ ensure("LLFile constructor should not have opened the already existing file", !file);
+ ensure("error_code from LLFile constructor should indicate an error", (bool)ec);
+
+ LLFile::remove(testfile);
+ file = LLFile(testfile, LLFile::out | LLFile::app | LLFile::trunc, ec);
+ ensure("LLFile constructor should not have opened the file with conflicting flags", !file);
+ ensure("error_code from LLFile constructor should indicate an error", (bool)ec);
+
+ file = LLFile(testfile, LLFile::out | LLFile::app | LLFile::noreplace, ec);
+ ensure("LLFile constructor should not have opened the file with conflicting flags", !file);
+ ensure("error_code from LLFile constructor should indicate an error", (bool)ec);
+
+ testfile = testdir;
+ testfile.append("llfile_test");
+ testfile.append("llfile_test.bin");
+
+ file = LLFile(testfile, LLFile::in, ec);
+ ensure("LLFile constructor should not have been able to open the file in the non-existing directory", !file);
+ ensure("error_code from LLFile constructor should indicate an error", (bool)ec);
+ }
+
+ template<> template<>
+ void llfile_test_object_t::test<5>()
+ {
+ // Test file and directory operations with Unicode paths and filenames
+ std::filesystem::path testdir_unicode = get_testdir_unicode(tempdir);
+
+ // Unicode filename: "ファイル_テスト.bin" (means "file_test.bin" in Japanese)
+ std::string unicode_filename = "\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB_\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88.bin";
+ std::filesystem::path testfile_unicode = testdir_unicode;
+ testfile_unicode.append(unicode_filename);
+
+ // Clean up any previous test artifacts
+ clear_entire_dir(testdir_unicode);
+ ensure("Unicode test directory should not exist", !LLFile::exists(testdir_unicode));
+
+ // Create the Unicode directory
+ int rc = LLFile::mkdir(testdir_unicode);
+ ensure("LLFile::mkdir() failed for Unicode directory", rc == 0);
+ ensure("Unicode test directory should exist", LLFile::isdir(testdir_unicode));
+
+
+ ensure("Unicode test file should not exist", !LLFile::exists(testfile_unicode));
+
+ // Write to the Unicode file
+ const char* testdata = "unicode_testdata";
+ S64 bytes = LLFile::write(testfile_unicode, testdata, 0, strlen(testdata));
+ ensure("Unicode test file should exist", LLFile::exists(testfile_unicode));
+ ensure("Unicode test file should be a file", LLFile::isfile(testfile_unicode));
+ ensure("LLFile::write() did not write correctly to Unicode file", bytes == (S64)strlen(testdata));
+
+ // Read back the data
+ char buffer[64] = {};
+ bytes = LLFile::read(testfile_unicode, buffer, 0, sizeof(buffer));
+ ensure("LLFile::read() did not read correctly from Unicode file", bytes == (S64)strlen(testdata));
+ ensure_memory_matches("LLFile::read() did not read correct Unicode data", testdata, (U32)bytes, buffer, (U32)bytes);
+
+ // Remove the file and directory
+ rc = LLFile::remove(testfile_unicode);
+ ensure("LLFile::remove() failed for Unicode file", rc == 0);
+ ensure("Unicode test file should not exist after removal", !LLFile::exists(testfile_unicode));
+
+ rc = LLFile::remove(testdir_unicode);
+ ensure("LLFile::remove() failed for Unicode directory", rc == 0);
+ ensure("Unicode test directory should not exist after removal", !LLFile::exists(testdir_unicode));
+ }
+} // namespace tut
diff --git a/indra/test/llhttpdate_tut.cpp b/indra/llcommon/tests/llhttpdate_test.cpp
index b580b09a9f..b580b09a9f 100644
--- a/indra/test/llhttpdate_tut.cpp
+++ b/indra/llcommon/tests/llhttpdate_test.cpp
diff --git a/indra/llcommon/tests/lllazy_test.cpp b/indra/llcommon/tests/lllazy_test.cpp
deleted file mode 100644
index 923fe952a9..0000000000
--- a/indra/llcommon/tests/lllazy_test.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/**
- * @file lllazy_test.cpp
- * @author Nat Goodspeed
- * @date 2009-01-28
- * @brief Tests of lllazy.h.
- *
- * $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$
- */
-
-// Precompiled header
-#include "linden_common.h"
-// associated header
-#include "lllazy.h"
-// STL headers
-#include <iostream>
-// std headers
-// external library headers
-#include <boost/lambda/construct.hpp>
-#include <boost/lambda/bind.hpp>
-// other Linden headers
-#include "../test/lltut.h"
-#include "../test/catch_and_store_what_in.h"
-
-namespace bll = boost::lambda;
-
-/*****************************************************************************
-* Test classes
-*****************************************************************************/
-
-// Let's say that because of its many external dependencies, YuckyFoo is very
-// hard to instantiate in a test harness.
-class YuckyFoo
-{
-public:
- virtual ~YuckyFoo() {}
- virtual std::string whoami() const { return "YuckyFoo"; }
-};
-
-// Let's further suppose that YuckyBar is another hard-to-instantiate class.
-class YuckyBar
-{
-public:
- YuckyBar(const std::string& which):
- mWhich(which)
- {}
- virtual ~YuckyBar() {}
-
- virtual std::string identity() const { return std::string("YuckyBar(") + mWhich + ")"; }
-
-private:
- const std::string mWhich;
-};
-
-// Pretend that this class would be tough to test because, up until we started
-// trying to test it, it contained instances of both YuckyFoo and YuckyBar.
-// Now we've refactored so it contains LLLazy<YuckyFoo> and LLLazy<YuckyBar>.
-// More than that, it contains them by virtue of deriving from
-// LLLazyBase<YuckyFoo> and LLLazyBase<YuckyBar>.
-// We postulate two different LLLazyBases because, with only one, you need not
-// specify *which* get()/set() method you're talking about. That's a simpler
-// case.
-class NeedsTesting: public LLLazyBase<YuckyFoo>, public LLLazyBase<YuckyBar>
-{
-public:
- NeedsTesting():
- // mYuckyBar("RealYuckyBar")
- LLLazyBase<YuckyBar>(bll::bind(bll::new_ptr<YuckyBar>(), "RealYuckyBar"))
- {}
- virtual ~NeedsTesting() {}
-
- virtual std::string describe() const
- {
- return std::string("NeedsTesting(") + getLazy<YuckyFoo>(this).whoami() + ", " +
- getLazy<YuckyBar>(this).identity() + ")";
- }
-
-private:
- // These instance members were moved to LLLazyBases:
- // YuckyFoo mYuckyFoo;
- // YuckyBar mYuckyBar;
-};
-
-// Fake up a test YuckyFoo class
-class TestFoo: public YuckyFoo
-{
-public:
- virtual std::string whoami() const { return "TestFoo"; }
-};
-
-// and a test YuckyBar
-class TestBar: public YuckyBar
-{
-public:
- TestBar(const std::string& which): YuckyBar(which) {}
- virtual std::string identity() const
- {
- return std::string("TestBar(") + YuckyBar::identity() + ")";
- }
-};
-
-// So here's a test subclass of NeedsTesting that uses TestFoo and TestBar
-// instead of YuckyFoo and YuckyBar.
-class TestNeedsTesting: public NeedsTesting
-{
-public:
- TestNeedsTesting()
- {
- // Exercise setLazy(T*)
- setLazy<YuckyFoo>(this, new TestFoo());
- // Exercise setLazy(Factory)
- setLazy<YuckyBar>(this, bll::bind(bll::new_ptr<TestBar>(), "TestYuckyBar"));
- }
-
- virtual std::string describe() const
- {
- return std::string("TestNeedsTesting(") + NeedsTesting::describe() + ")";
- }
-
- void toolate()
- {
- setLazy<YuckyFoo>(this, new TestFoo());
- }
-};
-
-// This class tests having an explicit LLLazy<T> instance as a named member,
-// rather than deriving from LLLazyBase<T>.
-class LazyMember
-{
-public:
- YuckyFoo& getYuckyFoo() { return *mYuckyFoo; }
- std::string whoisit() const { return mYuckyFoo->whoami(); }
-
-protected:
- LLLazy<YuckyFoo> mYuckyFoo;
-};
-
-// This is a test subclass of the above, dynamically replacing the
-// LLLazy<YuckyFoo> member.
-class TestLazyMember: public LazyMember
-{
-public:
- // use factory setter
- TestLazyMember()
- {
- mYuckyFoo.set(bll::new_ptr<TestFoo>());
- }
-
- // use instance setter
- TestLazyMember(YuckyFoo* instance)
- {
- mYuckyFoo.set(instance);
- }
-};
-
-/*****************************************************************************
-* TUT
-*****************************************************************************/
-namespace tut
-{
- struct lllazy_data
- {
- };
- typedef test_group<lllazy_data> lllazy_group;
- typedef lllazy_group::object lllazy_object;
- lllazy_group lllazygrp("lllazy");
-
- template<> template<>
- void lllazy_object::test<1>()
- {
- // Instantiate an official one, just because we can
- NeedsTesting nt;
- // and a test one
- TestNeedsTesting tnt;
-// std::cout << nt.describe() << '\n';
- ensure_equals(nt.describe(), "NeedsTesting(YuckyFoo, YuckyBar(RealYuckyBar))");
-// std::cout << tnt.describe() << '\n';
- ensure_equals(tnt.describe(),
- "TestNeedsTesting(NeedsTesting(TestFoo, TestBar(YuckyBar(TestYuckyBar))))");
- }
-
- template<> template<>
- void lllazy_object::test<2>()
- {
- TestNeedsTesting tnt;
- std::string threw = catch_what<LLLazyCommon::InstanceChange>([&tnt](){
- tnt.toolate();
- });
- ensure_contains("InstanceChange exception", threw, "replace LLLazy instance");
- }
-
- template<> template<>
- void lllazy_object::test<3>()
- {
- {
- LazyMember lm;
- // operator*() on-demand instantiation
- ensure_equals(lm.getYuckyFoo().whoami(), "YuckyFoo");
- }
- {
- LazyMember lm;
- // operator->() on-demand instantiation
- ensure_equals(lm.whoisit(), "YuckyFoo");
- }
- }
-
- template<> template<>
- void lllazy_object::test<4>()
- {
- {
- // factory setter
- TestLazyMember tlm;
- ensure_equals(tlm.whoisit(), "TestFoo");
- }
- {
- // instance setter
- TestLazyMember tlm(new TestFoo());
- ensure_equals(tlm.whoisit(), "TestFoo");
- }
- }
-} // namespace tut
diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp
index fa48bcdefd..ae20e7ed27 100644
--- a/indra/llcommon/tests/llleap_test.cpp
+++ b/indra/llcommon/tests/llleap_test.cpp
@@ -190,7 +190,7 @@ namespace tut
// computation, so I don't mind calling it twice.) Then take the
// basename.
reader_module(LLProcess::basename(
- reader.getName().substr(0, reader.getName().length()-3))),
+ reader.getPath().string().substr(0, reader.getPath().string().length()-3))),
PYTHON(LLStringUtil::getenv("PYTHON"))
{
ensure("Set PYTHON to interpreter pathname", !PYTHON.empty());
@@ -212,9 +212,9 @@ namespace tut
"time.sleep(1)\n");
LLLeapVector instances;
instances.push_back(LLLeap::create(get_test_name(),
- StringVec{PYTHON, script.getName()})->getWeak());
+ StringVec{PYTHON, script.getPath().string()})->getWeak());
instances.push_back(LLLeap::create(get_test_name(),
- StringVec{PYTHON, script.getName()})->getWeak());
+ StringVec{PYTHON, script.getPath().string()})->getWeak());
// In this case we're simply establishing that two LLLeap instances
// can coexist without throwing exceptions or bombing in any other
// way. Wait for them to terminate.
@@ -229,7 +229,7 @@ namespace tut
"import sys\n"
"sys.stderr.write('''Hello from Python!\n"
"note partial line''')\n");
- StringVec vcommand{ PYTHON, script.getName() };
+ StringVec vcommand{ PYTHON, script.getPath().string() };
CaptureLog log(LLError::LEVEL_INFO);
waitfor(LLLeap::create(get_test_name(), vcommand));
log.messageWith("Hello from Python!");
@@ -244,7 +244,7 @@ namespace tut
"print('Hello from Python!')\n");
CaptureLog log(LLError::LEVEL_WARN);
waitfor(LLLeap::create(get_test_name(),
- StringVec{PYTHON, script.getName()}));
+ StringVec{PYTHON, script.getPath().string()}));
ensure_contains("error log line",
log.messageWith("invalid protocol"), "Hello from Python!");
}
@@ -259,7 +259,7 @@ namespace tut
"sys.stdout.write('Hello from Python!')\n");
CaptureLog log(LLError::LEVEL_WARN);
waitfor(LLLeap::create(get_test_name(),
- StringVec{PYTHON, script.getName()}));
+ StringVec{PYTHON, script.getPath().string()}));
ensure_contains("error log line",
log.messageWith("Discarding"), "Hello from Python!");
}
@@ -273,7 +273,7 @@ namespace tut
"sys.stdout.write('5a2:something')\n");
CaptureLog log(LLError::LEVEL_WARN);
waitfor(LLLeap::create(get_test_name(),
- StringVec{PYTHON, script.getName()}));
+ StringVec{PYTHON, script.getPath().string()}));
ensure_contains("error log line",
log.messageWith("invalid protocol"), "5a2:");
}
@@ -386,7 +386,7 @@ namespace tut
" else 'bad: ' + str(resp)\n"
"send(pump='" << result.getName() << "', data=result)\n";});
waitfor(LLLeap::create(get_test_name(),
- StringVec{PYTHON, script.getName()}));
+ StringVec{PYTHON, script.getPath().string()}));
result.ensure();
}
@@ -445,7 +445,7 @@ namespace tut
" result = 'expected reqid=%s in %s' % (i, resp)\n"
" break\n"
"send(pump='" << result.getName() << "', data=result)\n";});
- waitfor(LLLeap::create(get_test_name(), StringVec{PYTHON, script.getName()}),
+ waitfor(LLLeap::create(get_test_name(), StringVec{PYTHON, script.getPath().string()}),
300); // needs more realtime than most tests
result.ensure();
}
@@ -512,7 +512,7 @@ namespace tut
" (start, large[start:end], echoed[start:end]))\n"
"sys.exit(1)\n";});
waitfor(LLLeap::create(test_name,
- StringVec{PYTHON, script.getName(), stringize(size)}),
+ StringVec{PYTHON, script.getPath().string(), stringize(size)}),
180); // try a longer timeout
result.ensure();
}
diff --git a/indra/llcommon/tests/llmemtype_test.cpp b/indra/llcommon/tests/llmemtype_test.cpp
deleted file mode 100644
index 2d64d342ae..0000000000
--- a/indra/llcommon/tests/llmemtype_test.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * @file llmemtype_test.cpp
- * @author Palmer Truelson
- * @date 2008-03-
- * @brief Test for llmemtype.cpp.
- *
- * $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$
- */
-
-#include "../llmemtype.h"
-#include "../test/lltut.h"
-#include "../llallocator.h"
-
-
-#include <stack>
-
-std::stack<S32> memTypeStack;
-
-void LLAllocator::pushMemType(S32 i)
-{
- memTypeStack.push(i);
-}
-
-S32 LLAllocator::popMemType(void)
-{
- S32 ret = memTypeStack.top();
- memTypeStack.pop();
- return ret;
-}
-
-namespace tut
-{
- struct llmemtype_data
- {
- };
-
- typedef test_group<llmemtype_data> factory;
- typedef factory::object object;
-}
-namespace
-{
- tut::factory llmemtype_test_factory("LLMemType");
-}
-
-namespace tut
-{
- template<> template<>
- void object::test<1>()
- {
- ensure("Simplest test ever", true);
- }
-
- // test with no scripts
- template<> template<>
- void object::test<2>()
- {
- {
- LLMemType m1(LLMemType::MTYPE_INIT);
- }
- ensure("Test that you can construct and destruct the mem type");
- }
-
- // test creation and stack testing
- template<> template<>
- void object::test<3>()
- {
- {
- ensure("Test that creation and destruction properly inc/dec the stack");
- ensure_equals(memTypeStack.size(), 0);
- {
- LLMemType m1(LLMemType::MTYPE_INIT);
- ensure_equals(memTypeStack.size(), 1);
- LLMemType m2(LLMemType::MTYPE_STARTUP);
- ensure_equals(memTypeStack.size(), 2);
- }
- ensure_equals(memTypeStack.size(), 0);
- }
- }
-
- // test with no scripts
- template<> template<>
- void object::test<4>()
- {
- // catch the begining and end
- std::string test_name = LLMemType::getNameFromID(LLMemType::MTYPE_INIT.mID);
- ensure_equals("Init name", test_name, "Init");
-
- std::string test_name2 = LLMemType::getNameFromID(LLMemType::MTYPE_VOLUME.mID);
- ensure_equals("Volume name", test_name2, "Volume");
-
- std::string test_name3 = LLMemType::getNameFromID(LLMemType::MTYPE_OTHER.mID);
- ensure_equals("Other name", test_name3, "Other");
-
- std::string test_name4 = LLMemType::getNameFromID(-1);
- ensure_equals("Invalid name", test_name4, "INVALID");
- }
-
-};
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index 00dcd52d5d..dfc34373da 100644
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -89,14 +89,14 @@ static void aprchk_(const char* call, apr_status_t rv, apr_status_t expected=APR
* @param desc Optional description of the file for error message;
* defaults to "in <pathname>"
*/
-static std::string readfile(const std::string& pathname, const std::string& desc="")
+static std::string readfile(const std::filesystem::path& pathname, const std::string& desc="")
{
std::string use_desc(desc);
if (use_desc.empty())
{
- use_desc = "in " + pathname;
+ use_desc = "in " + pathname.string();
}
- std::ifstream inf(pathname.c_str());
+ llifstream inf(pathname.c_str());
std::string output;
if (!std::getline(inf, output))
{
@@ -183,7 +183,7 @@ struct PythonProcessLauncher
mParams.desc = desc + " script";
mParams.executable = PYTHON;
- mParams.args.add(mScript.getName());
+ mParams.args.add(mScript.getPath().string());
}
/// Launch Python script; verify that it launched
@@ -203,7 +203,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;
@@ -251,11 +251,11 @@ struct PythonProcessLauncher
{
NamedTempFile out("out", ""); // placeholder
// pass name of this temporary file to the script
- mParams.args.add(out.getName());
+ mParams.args.add(out.getPath().string());
run();
// assuming the script wrote to that file, read it
std::string desc = "from " + mDesc + " script";
- return readfile(out.getName(), desc);
+ return readfile(out.getPath(), desc);
}
LLProcess::Params mParams;
@@ -431,9 +431,9 @@ namespace
NamedTempFile pidfile("pid", "");
NamedTempFile releasefile("release", "");
- ScopedEnvironmentVariable helper_script(AUTOKILL_HELPER_SCRIPT_ENV, child_script.getName());
- ScopedEnvironmentVariable helper_pidfile(AUTOKILL_HELPER_PIDFILE_ENV, pidfile.getName());
- ScopedEnvironmentVariable helper_release(AUTOKILL_HELPER_RELEASE_ENV, releasefile.getName());
+ ScopedEnvironmentVariable helper_script(AUTOKILL_HELPER_SCRIPT_ENV, child_script.getPath().string());
+ ScopedEnvironmentVariable helper_pidfile(AUTOKILL_HELPER_PIDFILE_ENV, pidfile.getPath().string());
+ ScopedEnvironmentVariable helper_release(AUTOKILL_HELPER_RELEASE_ENV, releasefile.getPath().string());
ScopedEnvironmentVariable helper_count(AUTOKILL_HELPER_COUNT_ENV, std::to_string(child_count));
LLProcess::Params params;
@@ -442,7 +442,7 @@ namespace
LLProcessPtr helper = LLProcess::create(params);
tut::ensure("helper launched", bool(helper));
- std::vector<DWORD> pids = wait_for_helper_pids(pidfile.getName(), child_count);
+ std::vector<DWORD> pids = wait_for_helper_pids(pidfile.getPath().string(), child_count);
std::vector<HANDLE> handles;
handles.reserve(pids.size());
for (DWORD pid : pids)
@@ -455,7 +455,7 @@ namespace
}
{
- std::ofstream out(releasefile.getName().c_str(), std::ios::trunc);
+ std::ofstream out(releasefile.getPath(), std::ios::trunc);
out << "exit";
}
@@ -498,23 +498,23 @@ public:
NamedTempDir():
mPath(NamedTempFile::temp_path()),
- mCreated(boost::filesystem::create_directories(mPath))
+ mCreated(std::filesystem::create_directories(mPath))
{
- mPath = boost::filesystem::canonical(mPath);
+ mPath = std::filesystem::canonical(mPath);
}
~NamedTempDir()
{
if (mCreated)
{
- boost::filesystem::remove_all(mPath);
+ std::filesystem::remove_all(mPath);
}
}
std::string getName() const { return mPath.string(); }
private:
- boost::filesystem::path mPath;
+ std::filesystem::path mPath;
bool mCreated;
};
@@ -674,7 +674,7 @@ namespace tut
#endif
// Have to have a named copy of this std::string so its c_str() value
// will persist.
- std::string scriptname(script.getName());
+ std::string scriptname(script.getPath().string());
argv.push_back(scriptname.c_str());
argv.push_back(NULL);
@@ -953,14 +953,14 @@ namespace tut
"with open(sys.argv[1], 'w') as f:\n"
" f.write('bad')\n");
NamedTempFile out("out", "not started");
- py.mParams.args.add(out.getName());
+ py.mParams.args.add(out.getPath().string());
py.launch();
// Wait for the script to wake up and do its first write
int i = 0, timeout = 60;
for ( ; i < timeout; ++i)
{
yield();
- if (readfile(out.getName(), "from kill() script") == "ok")
+ if (readfile(out.getPath(), "from kill() script") == "ok")
break;
}
// If we broke this loop because of the counter, something's wrong
@@ -979,7 +979,7 @@ namespace tut
// If kill() failed, the script would have woken up on its own and
// overwritten the file with 'bad'. But if kill() succeeded, it should
// not have had that chance.
- ensure_equals(get_test_name() + " script output", readfile(out.getName()), "ok");
+ ensure_equals(get_test_name() + " script output", readfile(out.getPath()), "ok");
}
template<> template<>
@@ -999,7 +999,7 @@ namespace tut
"# if caller hasn't managed to kill by now, bad\n"
"with open(sys.argv[1], 'w') as f:\n"
" f.write('bad')\n");
- py.mParams.args.add(out.getName());
+ py.mParams.args.add(out.getPath().string());
py.launch();
// Capture handle for later
phandle = py.mPy->getProcessHandle();
@@ -1008,7 +1008,7 @@ namespace tut
for ( ; i < timeout; ++i)
{
yield();
- if (readfile(out.getName(), "from kill() script") == "ok")
+ if (readfile(out.getPath(), "from kill() script") == "ok")
break;
}
// If we broke this loop because of the counter, something's wrong
@@ -1021,7 +1021,7 @@ namespace tut
// If kill() failed, the script would have woken up on its own and
// overwritten the file with 'bad'. But if kill() succeeded, it should
// not have had that chance.
- ensure_equals(get_test_name() + " script output", readfile(out.getName()), "ok");
+ ensure_equals(get_test_name() + " script output", readfile(out.getPath()), "ok");
}
template<> template<>
@@ -1051,8 +1051,8 @@ namespace tut
"# okay, saw 'go', write 'ack'\n"
"with open(sys.argv[1], 'w') as f:\n"
" f.write('ack')\n");
- py.mParams.args.add(from.getName());
- py.mParams.args.add(to.getName());
+ py.mParams.args.add(from.getPath().string());
+ py.mParams.args.add(to.getPath().string());
py.mParams.autokill = false;
py.launch();
// Capture handle for later
@@ -1062,7 +1062,7 @@ namespace tut
for ( ; i < timeout; ++i)
{
yield();
- if (readfile(from.getName(), "from autokill script") == "ok")
+ if (readfile(from.getPath(), "from autokill script") == "ok")
break;
}
// If we broke this loop because of the counter, something's wrong
@@ -1074,14 +1074,14 @@ 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.getPath());
outf << "go";
} // flush and close.
// now wait for the script to terminate... one way or another.
waitfor(phandle, "autokill script");
// If the LLProcess destructor implicitly called kill(), the
// script could not have written 'ack' as we expect.
- ensure_equals(get_test_name() + " script output", readfile(from.getName()), "ack");
+ ensure_equals(get_test_name() + " script output", readfile(from.getPath()), "ack");
}
template<> template<>
@@ -1113,8 +1113,8 @@ namespace tut
"# okay, saw 'go', write 'ack'\n"
"with open(sys.argv[1], 'w') as f:\n"
" f.write('ack')\n");
- py.mParams.args.add(from.getName());
- py.mParams.args.add(to.getName());
+ py.mParams.args.add(from.getPath().string());
+ py.mParams.args.add(to.getPath().string());
py.mParams.autokill = true;
py.mParams.attached = false;
py.launch();
@@ -1125,7 +1125,7 @@ namespace tut
for ( ; i < timeout; ++i)
{
yield();
- if (readfile(from.getName(), "from autokill script") == "ok")
+ if (readfile(from.getPath(), "from autokill script") == "ok")
break;
}
// If we broke this loop because of the counter, something's wrong
@@ -1137,14 +1137,14 @@ 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.getPath());
outf << "go";
} // flush and close.
// now wait for the script to terminate... one way or another.
waitfor(phandle, "autokill script");
// If the LLProcess destructor implicitly called kill(), the
// script could not have written 'ack' as we expect.
- ensure_equals(get_test_name() + " script output", readfile(from.getName()), "ack");
+ ensure_equals(get_test_name() + " script output", readfile(from.getPath()), "ack");
}
template<> template<>
diff --git a/indra/test/llsd_new_tut.cpp b/indra/llcommon/tests/llsd_test.cpp
index cc084df045..9cc93bcd14 100644
--- a/indra/test/llsd_new_tut.cpp
+++ b/indra/llcommon/tests/llsd_test.cpp
@@ -26,9 +26,9 @@
*/
#define LLSD_DEBUG_INFO
-#include <tut/tut.hpp>
#include "linden_common.h"
#include "lltut.h"
+#include "llsd.h"
#include "llsdtraits.h"
#include "llstring.h"
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index f52b3fec71..71096523a9 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -52,7 +52,7 @@ typedef U32 uint32_t;
#include "llformat.h"
#include "llmemorystream.h"
-#include "../test/hexdump.h"
+#include "hexdump.h"
#include "../test/lltut.h"
#include "../test/namedtempfile.h"
#include "stringize.h"
@@ -1860,7 +1860,7 @@ namespace tut
#if LL_WINDOWS
std::string q("\"");
std::string qPYTHON(q + PYTHON + q);
- std::string qscript(q + scriptfile.getName() + q);
+ std::string qscript(q + scriptfile.getPath().string() + q);
int rc = (int)_spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(),
std::forward<ARGS>(args)..., NULL);
if (rc == -1)
@@ -1877,7 +1877,7 @@ namespace tut
#else // LL_DARWIN, LL_LINUX
LLProcess::Params params;
params.executable = PYTHON;
- params.args.add(scriptfile.getName());
+ params.args.add(scriptfile.getPath().string());
for (const std::string& arg : StringVec{ std::forward<ARGS>(args)... })
{
params.args.add(arg);
@@ -1973,12 +1973,12 @@ namespace tut
int bufflen{ static_cast<int>(buffstr.length()) };
out.write(reinterpret_cast<const char*>(&bufflen), sizeof(bufflen));
LL_DEBUGS() << "Wrote length: "
- << hexdump(reinterpret_cast<const char*>(&bufflen),
+ << LL::hexdump(reinterpret_cast<const char*>(&bufflen),
sizeof(bufflen))
<< LL_ENDL;
out.write(buffstr.c_str(), buffstr.length());
LL_DEBUGS() << "Wrote data: "
- << hexmix(buffstr.c_str(), buffstr.length())
+ << LL::hexmix(buffstr.c_str(), buffstr.length())
<< LL_ENDL;
}
}
@@ -2054,8 +2054,8 @@ namespace tut
" yield frombytes\n"
<< pydata <<
// Don't forget raw-string syntax for Windows pathnames.
- "debug = open(r'" << debug.getName() << "', 'w')\n"
- "verify(parse_each(open(r'" << file.getName() << "', 'rb')))\n";});
+ "debug = open(r'" << debug.getPath().string() << "', 'w')\n"
+ "verify(parse_each(open(r'" << file.getPath().string() << "', 'rb')))\n";});
}
catch (const failure&)
{
@@ -2163,13 +2163,13 @@ namespace tut
"]\n"
// Don't forget raw-string syntax for Windows pathnames.
// N.B. Using 'print' implicitly adds newlines.
- "with open(r'" << file.getName() << "', 'wb') as f:\n"
+ "with open(r'" << (const char*)file.getPath().u8string().c_str() << "', 'wb') as f:\n"
" for item in DATA:\n"
" serialized = llsd." << pyformatter << "(item)\n"
" f.write(lenformat.pack(len(serialized)))\n"
" f.write(serialized)\n";});
- std::ifstream inf(file.getName().c_str());
+ llifstream inf(file.getPath());
LLSD item;
try
{
diff --git a/indra/test/llsdutil_tut.cpp b/indra/llcommon/tests/llsdutil_test.cpp
index 4b25a02f30..4b25a02f30 100644
--- a/indra/test/llsdutil_tut.cpp
+++ b/indra/llcommon/tests/llsdutil_test.cpp
diff --git a/indra/llcommon/tests/llstreamqueue_test.cpp b/indra/llcommon/tests/llstreamqueue_test.cpp
deleted file mode 100644
index 82b451119e..0000000000
--- a/indra/llcommon/tests/llstreamqueue_test.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * @file llstreamqueue_test.cpp
- * @author Nat Goodspeed
- * @date 2012-01-05
- * @brief Test for llstreamqueue.
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Copyright (c) 2012, Linden Research, Inc.
- * $/LicenseInfo$
- */
-
-// Precompiled header
-#include "linden_common.h"
-// associated header
-#include "llstreamqueue.h"
-// STL headers
-#include <vector>
-// other Linden headers
-#include "../test/lltut.h"
-#include "stringize.h"
-
-/*****************************************************************************
-* TUT
-*****************************************************************************/
-namespace tut
-{
- struct llstreamqueue_data
- {
- llstreamqueue_data():
- // we want a buffer with actual bytes in it, not an empty vector
- buffer(10)
- {}
- // As LLStreamQueue is merely a typedef for
- // LLGenericStreamQueue<char>, and no logic in LLGenericStreamQueue is
- // specific to the <char> instantiation, we're comfortable for now
- // testing only the narrow-char version.
- LLStreamQueue strq;
- // buffer for use in multiple tests
- std::vector<char> buffer;
- };
- typedef test_group<llstreamqueue_data> llstreamqueue_group;
- typedef llstreamqueue_group::object object;
- llstreamqueue_group llstreamqueuegrp("llstreamqueue");
-
- template<> template<>
- void object::test<1>()
- {
- set_test_name("empty LLStreamQueue");
- ensure_equals("brand-new LLStreamQueue isn't empty",
- strq.size(), 0);
- ensure_equals("brand-new LLStreamQueue returns data",
- strq.asSource().read(&buffer[0], buffer.size()), 0);
- strq.asSink().close();
- ensure_equals("closed empty LLStreamQueue not at EOF",
- strq.asSource().read(&buffer[0], buffer.size()), -1);
- }
-
- template<> template<>
- void object::test<2>()
- {
- set_test_name("one internal block, one buffer");
- LLStreamQueue::Sink sink(strq.asSink());
- ensure_equals("write(\"\")", sink.write("", 0), 0);
- ensure_equals("0 write should leave LLStreamQueue empty (size())",
- strq.size(), 0);
- ensure_equals("0 write should leave LLStreamQueue empty (peek())",
- strq.peek(&buffer[0], buffer.size()), 0);
- // The meaning of "atomic" is that it must be smaller than our buffer.
- std::string atomic("atomic");
- ensure("test data exceeds buffer", atomic.length() < buffer.size());
- ensure_equals(STRINGIZE("write(\"" << atomic << "\")"),
- sink.write(&atomic[0], atomic.length()), atomic.length());
- ensure_equals("size() after write()", strq.size(), atomic.length());
- size_t peeklen(strq.peek(&buffer[0], buffer.size()));
- ensure_equals(STRINGIZE("peek(\"" << atomic << "\")"),
- peeklen, atomic.length());
- ensure_equals(STRINGIZE("peek(\"" << atomic << "\") result"),
- std::string(buffer.begin(), buffer.begin() + peeklen), atomic);
- ensure_equals("size() after peek()", strq.size(), atomic.length());
- // peek() should not consume. Use a different buffer to prove it isn't
- // just leftover data from the first peek().
- std::vector<char> again(buffer.size());
- peeklen = size_t(strq.peek(&again[0], again.size()));
- ensure_equals(STRINGIZE("peek(\"" << atomic << "\") again"),
- peeklen, atomic.length());
- ensure_equals(STRINGIZE("peek(\"" << atomic << "\") again result"),
- std::string(again.begin(), again.begin() + peeklen), atomic);
- // now consume.
- std::vector<char> third(buffer.size());
- size_t readlen(strq.read(&third[0], third.size()));
- ensure_equals(STRINGIZE("read(\"" << atomic << "\")"),
- readlen, atomic.length());
- ensure_equals(STRINGIZE("read(\"" << atomic << "\") result"),
- std::string(third.begin(), third.begin() + readlen), atomic);
- ensure_equals("peek() after read()", strq.peek(&buffer[0], buffer.size()), 0);
- ensure_equals("size() after read()", strq.size(), 0);
- }
-
- template<> template<>
- void object::test<3>()
- {
- set_test_name("basic skip()");
- std::string lovecraft("lovecraft");
- ensure("test data exceeds buffer", lovecraft.length() < buffer.size());
- ensure_equals(STRINGIZE("write(\"" << lovecraft << "\")"),
- strq.write(&lovecraft[0], lovecraft.length()), lovecraft.length());
- size_t peeklen(strq.peek(&buffer[0], buffer.size()));
- ensure_equals(STRINGIZE("peek(\"" << lovecraft << "\")"),
- peeklen, lovecraft.length());
- ensure_equals(STRINGIZE("peek(\"" << lovecraft << "\") result"),
- std::string(buffer.begin(), buffer.begin() + peeklen), lovecraft);
- std::streamsize skip1(4);
- ensure_equals(STRINGIZE("skip(" << skip1 << ")"), strq.skip(skip1), skip1);
- ensure_equals("size() after skip()", strq.size(), lovecraft.length() - skip1);
- size_t readlen(strq.read(&buffer[0], buffer.size()));
- ensure_equals(STRINGIZE("read(\"" << lovecraft.substr(skip1) << "\")"),
- readlen, lovecraft.length() - skip1);
- ensure_equals(STRINGIZE("read(\"" << lovecraft.substr(skip1) << "\") result"),
- std::string(buffer.begin(), buffer.begin() + readlen),
- lovecraft.substr(skip1));
- ensure_equals("unconsumed", strq.read(&buffer[0], buffer.size()), 0);
- }
-
- template<> template<>
- void object::test<4>()
- {
- set_test_name("skip() multiple blocks");
- std::string blocks[] = { "books of ", "H.P. ", "Lovecraft" };
- std::streamsize total(blocks[0].length() + blocks[1].length() + blocks[2].length());
- std::streamsize leave(5); // len("craft") above
- std::streamsize skip(total - leave);
- std::streamsize written(0);
- for (const std::string& block : blocks)
- {
- written += strq.write(&block[0], block.length());
- ensure_equals("size() after write()", strq.size(), written);
- }
- std::streamsize skiplen(strq.skip(skip));
- ensure_equals(STRINGIZE("skip(" << skip << ")"), skiplen, skip);
- ensure_equals("size() after skip()", strq.size(), leave);
- size_t readlen(strq.read(&buffer[0], buffer.size()));
- ensure_equals("read(\"craft\")", readlen, leave);
- ensure_equals("read(\"craft\") result",
- std::string(buffer.begin(), buffer.begin() + readlen), "craft");
- }
-
- template<> template<>
- void object::test<5>()
- {
- set_test_name("concatenate blocks");
- std::string blocks[] = { "abcd", "efghij", "klmnopqrs" };
- for (const std::string& block : blocks)
- {
- strq.write(&block[0], block.length());
- }
- std::vector<char> longbuffer(30);
- std::streamsize readlen(strq.read(&longbuffer[0], longbuffer.size()));
- ensure_equals("read() multiple blocks",
- readlen, blocks[0].length() + blocks[1].length() + blocks[2].length());
- ensure_equals("read() multiple blocks result",
- std::string(longbuffer.begin(), longbuffer.begin() + readlen),
- blocks[0] + blocks[1] + blocks[2]);
- }
-
- template<> template<>
- void object::test<6>()
- {
- set_test_name("split blocks");
- std::string blocks[] = { "abcdefghijklm", "nopqrstuvwxyz" };
- for (const std::string& block : blocks)
- {
- strq.write(&block[0], block.length());
- }
- strq.close();
- // We've already verified what strq.size() should be at this point;
- // see above test named "skip() multiple blocks"
- std::streamsize chksize(strq.size());
- std::streamsize readlen(strq.read(&buffer[0], buffer.size()));
- ensure_equals("read() 0", readlen, buffer.size());
- ensure_equals("read() 0 result", std::string(buffer.begin(), buffer.end()), "abcdefghij");
- chksize -= readlen;
- ensure_equals("size() after read() 0", strq.size(), chksize);
- readlen = strq.read(&buffer[0], buffer.size());
- ensure_equals("read() 1", readlen, buffer.size());
- ensure_equals("read() 1 result", std::string(buffer.begin(), buffer.end()), "klmnopqrst");
- chksize -= readlen;
- ensure_equals("size() after read() 1", strq.size(), chksize);
- readlen = strq.read(&buffer[0], buffer.size());
- ensure_equals("read() 2", readlen, chksize);
- ensure_equals("read() 2 result",
- std::string(buffer.begin(), buffer.begin() + readlen), "uvwxyz");
- ensure_equals("read() 3", strq.read(&buffer[0], buffer.size()), -1);
- }
-} // namespace tut
diff --git a/indra/test/llstreamtools_tut.cpp b/indra/llcommon/tests/llstreamtools_test.cpp
index 970afb3b02..970afb3b02 100644
--- a/indra/test/llstreamtools_tut.cpp
+++ b/indra/llcommon/tests/llstreamtools_test.cpp
diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp
index 7393e0087c..3c9d8071ac 100644
--- a/indra/llcommon/tests/llstring_test.cpp
+++ b/indra/llcommon/tests/llstring_test.cpp
@@ -374,7 +374,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);
@@ -396,7 +396,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 05b788a433..58bbdb2d9a 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -81,6 +81,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
@@ -92,6 +93,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")
@@ -131,7 +136,7 @@ if (LL_TESTS AND LLCOREHTTP_TESTS)
${PYTHON_EXECUTABLE}
"${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llcorehttp_peer.py"
)
-
+
#
# Example Programs
#
@@ -151,6 +156,7 @@ if (LL_TESTS AND LLCOREHTTP_TESTS)
set_target_properties(http_texture_load
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
+ FOLDER "Tests"
)
if (WINDOWS)
@@ -163,6 +169,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 a8660decc3..e14a533479 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -70,7 +70,6 @@ volatile HttpService::EState HttpService::sState(NOT_INITIALIZED);
HttpService::HttpService()
: mRequestQueue(NULL),
mExitRequested(0U),
- mThread(NULL),
mPolicy(NULL),
mTransport(NULL),
mLastPolicy(0)
@@ -89,23 +88,30 @@ HttpService::~HttpService()
{
if (mRequestQueue->stopQueue())
{
- // Give mRequestQueue a chance to finish
- ms_sleep(10);
+ // Now wait a bit for the thread to exit
+ S32 counter = 0;
+ const S32 MAX_WAIT = 600;
+ while (counter < MAX_WAIT)
+ {
+ if (STOPPED == sState)
+ {
+ break;
+ }
+ // Sleep for a tenth of a second
+ ms_sleep(100);
+ std::this_thread::yield();
+ counter++;
+ }
}
}
- if (mThread)
+ if (mThread && RUNNING == sState)
{
- if (! mThread->timedJoin(250))
- {
- // Failed to join, expect problems ahead so do a hard termination.
- LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems." << LL_NEWLINE
- << "State: " << S32(sState)
- << " Last policy: " << U32(mLastPolicy)
- << LL_ENDL;
+ // Failed to shutdown, expect problems ahead so do a hard termination.
+ LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems." << LL_NEWLINE << "State: " << S32(sState)
+ << " Last policy: " << U32(mLastPolicy) << LL_ENDL;
- mThread->cancel();
- }
+ mThread->cancel();
}
}
@@ -121,11 +127,7 @@ HttpService::~HttpService()
delete mPolicy;
mPolicy = NULL;
- if (mThread)
- {
- mThread->release();
- mThread = NULL;
- }
+ mThread.reset();
}
@@ -204,14 +206,15 @@ void HttpService::startThread()
if (mThread)
{
- mThread->release();
+ mThread.reset();
}
// Push current policy definitions, enable policy & transport components
mPolicy->start();
mTransport->start(mLastPolicy + 1);
- mThread = new LLCoreInt::HttpThread(boost::bind(&HttpService::threadRun, this, _1));
+ mThread = std::make_unique<LLCoreInt::HttpThread>(boost::bind(&HttpService::threadRun, this, _1));
+ mThread->detach(); // Detach thread to let it clean its self up
sState = RUNNING;
}
@@ -282,12 +285,9 @@ 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)
{
@@ -314,7 +314,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
{
LOG_UNHANDLED_EXCEPTION("");
}
- catch (std::bad_alloc&)
+ catch (const std::bad_alloc&)
{
LLMemory::logMemoryInfo(true);
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
index 7202b496fc..4540fb9383 100644
--- a/indra/llcorehttp/_httpservice.h
+++ b/indra/llcorehttp/_httpservice.h
@@ -218,7 +218,7 @@ protected:
static volatile EState sState;
HttpRequestQueue * mRequestQueue; // Refcounted
LLAtomicU32 mExitRequested;
- LLCoreInt::HttpThread * mThread;
+ std::unique_ptr<LLCoreInt::HttpThread> mThread;
// === working-thread-only data ===
HttpPolicy * mPolicy; // Simple pointer, has ownership
diff --git a/indra/llcorehttp/_mutex.h b/indra/llcorehttp/_mutex.h
index 5e0164eb51..43782d3a37 100644
--- a/indra/llcorehttp/_mutex.h
+++ b/indra/llcorehttp/_mutex.h
@@ -27,9 +27,8 @@
#ifndef LLCOREINT_MUTEX_H_
#define LLCOREINT_MUTEX_H_
-
-#include <boost/thread.hpp>
-
+#include <condition_variable>
+#include <mutex>
namespace LLCoreInt
{
@@ -37,17 +36,17 @@ namespace LLCoreInt
// MUTEX TYPES
// unique mutex type
-typedef boost::mutex HttpMutex;
+typedef std::mutex HttpMutex;
// CONDITION VARIABLES
// standard condition variable
-typedef boost::condition_variable HttpConditionVariable;
+typedef std::condition_variable HttpConditionVariable;
// LOCKS AND FENCES
// scoped unique lock
-typedef boost::unique_lock<HttpMutex> HttpScopedLock;
+typedef std::unique_lock<HttpMutex> HttpScopedLock;
}
diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h
index 63684b5e2c..bc90f8274d 100644
--- a/indra/llcorehttp/_refcounted.h
+++ b/indra/llcorehttp/_refcounted.h
@@ -30,7 +30,6 @@
#include "linden_common.h"
-#include "fix_macros.h"
#include <boost/intrusive_ptr.hpp>
#include "llatomic.h"
@@ -40,12 +39,11 @@ namespace LLCoreInt
class RefCounted
{
-private:
- RefCounted() = delete; // may not be default constructed
- RefCounted(const RefCounted&) = delete;
- RefCounted& operator=(const RefCounted&) = delete;
-
public:
+ RefCounted() = delete; // Not defined - may not be default constructed
+ RefCounted(const RefCounted&) = delete; // Not defined - may not be copy constructed
+ void operator=(const RefCounted&) = delete; // Not defined
+
explicit RefCounted(bool const implicit)
: mRefCount(implicit)
{}
diff --git a/indra/llcorehttp/_thread.h b/indra/llcorehttp/_thread.h
index 93efbbedbc..66b9689c5a 100644
--- a/indra/llcorehttp/_thread.h
+++ b/indra/llcorehttp/_thread.h
@@ -29,94 +29,75 @@
#include "linden_common.h"
-#include <boost/thread.hpp>
-#include <boost/function.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <functional>
+#include <thread>
-#include "apr.h" // thread-related functions
#include "_refcounted.h"
namespace LLCoreInt
{
-class HttpThread : public RefCounted
+class HttpThread
{
-private:
- // May not be default constructed or copied
- HttpThread() = delete;
- HttpThread(const HttpThread&) = delete;
- void operator=(const HttpThread &) = delete;
-
- void at_exit()
- {
- // the thread function has exited so we need to release our reference
- // to ourself so that we will be automagically cleaned up.
- release();
- }
+public:
+ HttpThread() = delete; // Not defined
+ HttpThread(const HttpThread&) = delete; // Not defined
+ void operator=(const HttpThread &) = delete; // Not defined
+private:
void run()
- { // THREAD CONTEXT
-
- // Take out additional reference for the at_exit handler
- addRef();
- boost::this_thread::at_thread_exit(boost::bind(&HttpThread::at_exit, this));
-
- // run the thread function
- mThreadFunc(this);
-
- } // THREAD CONTEXT
-
-protected:
- virtual ~HttpThread()
- {
- delete mThread;
- }
+ { // THREAD CONTEXT
+ // run the thread function
+ mThreadFunc(this);
+ } // THREAD CONTEXT
public:
/// Constructs a thread object for concurrent execution but does
/// not start running. Caller receives on refcount on the thread
/// instance. If the thread is started, another will be taken
/// out for the exit handler.
- explicit HttpThread(boost::function<void (HttpThread *)> threadFunc)
- : RefCounted(true), // implicit reference
- mThreadFunc(threadFunc)
- {
- // this creates a boost thread that will call HttpThread::run on this instance
- // and pass it the threadfunc callable...
- boost::function<void()> f = boost::bind(&HttpThread::run, this);
+ explicit HttpThread(std::function<void (HttpThread *)> threadFunc)
+ : mThreadFunc(threadFunc)
+ {
+ // this creates a std thread that will call HttpThread::run on this instance
+ // and pass it the threadfunc callable...
+ std::function<void()> f = std::bind(&HttpThread::run, this);
- mThread = new boost::thread(f);
- }
+ mThread = std::make_unique<std::thread>(f);
+ mNativeHandle = mThread->native_handle();
+ }
- inline void join()
- {
- mThread->join();
- }
+ ~HttpThread() = default;
- inline bool timedJoin(S32 millis)
- {
- return mThread->timed_join(boost::posix_time::milliseconds(millis));
- }
+ inline void join()
+ {
+ mThread->join();
+ }
inline bool joinable() const
- {
- return mThread->joinable();
- }
+ {
+ return mThread->joinable();
+ }
+
+ inline void detach()
+ {
+ mThread->detach();
+ }
// A very hostile method to force a thread to quit
inline void cancel()
- {
- boost::thread::native_handle_type thread(mThread->native_handle());
-#if LL_WINDOWS
- TerminateThread(thread, 0);
+ {
+#if LL_WINDOWS
+ TerminateThread(mNativeHandle, 0);
#else
- pthread_cancel(thread);
+ pthread_cancel(mNativeHandle);
#endif
- }
+ }
private:
- boost::function<void(HttpThread *)> mThreadFunc;
- boost::thread * mThread;
+ std::function<void(HttpThread *)> mThreadFunc;
+ std::unique_ptr<std::thread> mThread;
+ std::thread::native_handle_type mNativeHandle;
}; // end class HttpThread
} // end namespace LLCoreInt
diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index a1b5f55e8d..dabc61975d 100644
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -36,10 +36,6 @@
namespace LLCore
{
-const HttpStatus::type_enum_t HttpStatus::EXT_CURL_EASY;
-const HttpStatus::type_enum_t HttpStatus::EXT_CURL_MULTI;
-const HttpStatus::type_enum_t HttpStatus::LLCORE;
-
HttpStatus::operator U32() const
{
// Effectively, concatenate mType (high) with mStatus (low).
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index 1c003a0966..001fd08f93 100644
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -340,9 +340,9 @@ struct HttpStatus
return *this;
}
- static const type_enum_t EXT_CURL_EASY = 0; ///< mStatus is an error from a curl_easy_*() call
- static const type_enum_t EXT_CURL_MULTI = 1; ///< mStatus is an error from a curl_multi_*() call
- static const type_enum_t LLCORE = 2; ///< mStatus is an HE_* error code
+ static constexpr type_enum_t EXT_CURL_EASY = 0; ///< mStatus is an error from a curl_easy_*() call
+ static constexpr type_enum_t EXT_CURL_MULTI = 1; ///< mStatus is an error from a curl_multi_*() call
+ static constexpr type_enum_t LLCORE = 2; ///< mStatus is an HE_* error code
///< 100-999 directly represent HTTP status codes
/// Test for successful status in the code regardless
/// of error source (internal, libcurl).
diff --git a/indra/llcorehttp/llhttpconstants.cpp b/indra/llcorehttp/llhttpconstants.cpp
index 7a671543d9..7a671543d9 100755..100644
--- a/indra/llcorehttp/llhttpconstants.cpp
+++ b/indra/llcorehttp/llhttpconstants.cpp
diff --git a/indra/llcorehttp/llhttpconstants.h b/indra/llcorehttp/llhttpconstants.h
index 71c1dfa173..d05d0f1af1 100755..100644
--- 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/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp
index c7c50e6166..c7c50e6166 100755..100644
--- a/indra/llcorehttp/tests/llcorehttp_test.cpp
+++ b/indra/llcorehttp/tests/llcorehttp_test.cpp
diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp
index 77ed8df066..68f8c4f71f 100644
--- a/indra/llcorehttp/tests/test_httprequest.hpp
+++ b/indra/llcorehttp/tests/test_httprequest.hpp
@@ -2744,13 +2744,6 @@ void HttpRequestTestObjectType::test<22>()
set_test_name("BUG-2295");
-#if LL_WINDOWS && ADDRESS_SIZE == 64
- // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it
- if (getenv("TEAMCITY_PROJECT_NAME"))
- {
- skip("BUG-2295 - partial load on W64 causes freeze");
- }
-#endif
// Handler can be stack-allocated *if* there are no dangling
// references to it after completion of this method.
// Create before memory record as the string copy will bump numbers.
@@ -2924,14 +2917,6 @@ void HttpRequestTestObjectType::test<23>()
set_test_name("HttpRequest GET 503s with 'Retry-After'");
-#if LL_WINDOWS && ADDRESS_SIZE == 64
- // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it
- if (getenv("TEAMCITY_PROJECT_NAME"))
- {
- skip("llcorehttp 503-with-retry test hangs on Windows 64");
- }
-#endif
-
// This tests mainly that the code doesn't fall over if
// various well- and mis-formed Retry-After headers are
// sent along with the response. Direct inspection of
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.cpp b/indra/llfilesystem/lldir.cpp
index 22bb50074a..756d09e69a 100644
--- a/indra/llfilesystem/lldir.cpp
+++ b/indra/llfilesystem/lldir.cpp
@@ -30,8 +30,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
-#else
-#include <direct.h>
#endif
#include "lldir.h"
@@ -43,7 +41,6 @@
#include "lldiriterator.h"
#include "stringize.h"
#include "llstring.h"
-#include <boost/filesystem.hpp>
#include "llprocess.h"
#include <boost/bind.hpp>
#include <algorithm>
@@ -94,30 +91,20 @@ LLDir::~LLDir()
std::vector<std::string> LLDir::getFilesInDir(const std::string &dirname)
{
- //Returns a vector of fullpath filenames.
-
-#ifdef LL_WINDOWS // or BOOST_WINDOWS_API
- boost::filesystem::path p(ll_convert<std::wstring>(dirname));
-#else
- boost::filesystem::path p(dirname);
-#endif
-
+ // Returns a vector of filenames in the directory.
+ fsyspath dir_path(dirname);
std::vector<std::string> v;
-
- boost::system::error_code ec;
- if (exists(p, ec) && !ec.failed())
+ std::error_code ec;
+ if (std::filesystem::is_directory(dir_path, ec))
{
- if (is_directory(p, ec) && !ec.failed())
+ std::filesystem::directory_iterator end_iter;
+ for (std::filesystem::directory_iterator dir_itr(dir_path);
+ dir_itr != end_iter;
+ ++dir_itr)
{
- boost::filesystem::directory_iterator end_iter;
- for (boost::filesystem::directory_iterator dir_itr(p);
- dir_itr != end_iter;
- ++dir_itr)
+ if (std::filesystem::is_regular_file(dir_itr->status()))
{
- if (boost::filesystem::is_regular_file(dir_itr->status()))
- {
- v.push_back(dir_itr->path().filename().string());
- }
+ v.push_back(dir_itr->path().filename().string());
}
}
}
@@ -190,31 +177,31 @@ U32 LLDir::deleteDirAndContents(const std::string& dir_name)
try
{
-#ifdef LL_WINDOWS // or BOOST_WINDOWS_API
- boost::filesystem::path dir_path(ll_convert<std::wstring>(dir_name));
-#else
- boost::filesystem::path dir_path(dir_name);
-#endif
-
- if (boost::filesystem::exists(dir_path))
+ fsyspath dir_path(dir_name);
+ if (std::filesystem::is_directory(dir_path))
{
- if (!boost::filesystem::is_empty(dir_path))
+ if (!std::filesystem::is_empty(dir_path))
{ // Directory has content
- num_deleted = (U32)boost::filesystem::remove_all(dir_path);
+ num_deleted = (U32)std::filesystem::remove_all(dir_path);
}
else
{ // Directory is empty
- boost::filesystem::remove(dir_path);
+ std::filesystem::remove(dir_path);
}
}
}
- catch (boost::filesystem::filesystem_error &er)
+ catch (std::filesystem::filesystem_error &er)
{
LL_WARNS() << "Failed to delete " << dir_name << " with error " << er.code().message() << LL_ENDL;
}
return num_deleted;
}
+bool LLDir::fileExists(const std::string& filename) const
+{
+ return LLFile::exists(filename);
+}
+
const std::string LLDir::findFile(const std::string &filename,
const std::string& searchPath1,
const std::string& searchPath2,
@@ -1024,7 +1011,7 @@ bool LLDir::setCacheDir(const std::string &path)
{
LLFile::mkdir(path);
std::string tempname = add(path, "temp");
- LLFILE* file = LLFile::fopen(tempname,"wt");
+ LLFILE* file = LLFile::fopen(tempname, LLFILE_MODE("wt"));
if (file)
{
fclose(file);
@@ -1161,15 +1148,15 @@ void dir_exists_or_crash(const std::string &dir_name)
#if LL_WINDOWS
// *FIX: lame - it doesn't do the same thing on windows. not so
// important since we don't deploy simulator to windows boxes.
- LLFile::mkdir(dir_name, 0700);
+ LLFile::mkdir(dir_name);
#else
- struct stat dir_stat;
+ llstat dir_stat;
if(0 != LLFile::stat(dir_name, &dir_stat))
{
S32 stat_rv = errno;
if(ENOENT == stat_rv)
{
- if(0 != LLFile::mkdir(dir_name, 0700)) // octal
+ if(0 != LLFile::mkdir(dir_name))
{
LL_ERRS() << "Unable to create directory: " << dir_name << LL_ENDL;
}
diff --git a/indra/llfilesystem/lldir.h b/indra/llfilesystem/lldir.h
index 3c8e2e2da6..8742b7f937 100644
--- a/indra/llfilesystem/lldir.h
+++ b/indra/llfilesystem/lldir.h
@@ -71,7 +71,7 @@ class LLDir
std::vector<std::string> getFilesInDir(const std::string &dirname);
// pure virtual functions
virtual std::string getCurPath() = 0;
- virtual bool fileExists(const std::string &filename) const = 0;
+ virtual bool fileExists(const std::string &filename) const;
const std::string findFile(const std::string& filename, const std::vector<std::string> filenames) const;
const std::string findFile(const std::string& filename, const std::string& searchPath1 = "", const std::string& searchPath2 = "", const std::string& searchPath3 = "") const;
diff --git a/indra/llfilesystem/lldir_linux.cpp b/indra/llfilesystem/lldir_linux.cpp
index b13b42c954..0ebaab1114 100644
--- a/indra/llfilesystem/lldir_linux.cpp
+++ b/indra/llfilesystem/lldir_linux.cpp
@@ -238,24 +238,6 @@ std::string LLDir_Linux::getCurPath()
return tmp_str;
}
-
-bool LLDir_Linux::fileExists(const std::string &filename) const
-{
- struct stat stat_data;
- // Check the age of the file
- // Now, we see if the files we've gathered are recent...
- int res = stat(filename.c_str(), &stat_data);
- if (!res)
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-
/*virtual*/ std::string LLDir_Linux::getLLPluginLauncher()
{
return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
diff --git a/indra/llfilesystem/lldir_linux.h b/indra/llfilesystem/lldir_linux.h
index bd031bd7bb..ad9cd76554 100644
--- a/indra/llfilesystem/lldir_linux.h
+++ b/indra/llfilesystem/lldir_linux.h
@@ -47,7 +47,6 @@ public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
- /*virtual*/ bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);
diff --git a/indra/llfilesystem/lldir_mac.cpp b/indra/llfilesystem/lldir_mac.cpp
index 2db1b6ec5d..b13e72ff15 100644
--- a/indra/llfilesystem/lldir_mac.cpp
+++ b/indra/llfilesystem/lldir_mac.cpp
@@ -35,7 +35,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <glob.h>
-#include <boost/filesystem.hpp>
+#include <filesystem>
#include "lldir_utils_objc.h"
// --------------------------------------------------------------------------------
@@ -45,15 +45,15 @@ static bool CreateDirectory(const std::string &parent,
std::string *fullname)
{
- boost::filesystem::path p(parent);
+ std::filesystem::path p(parent);
p /= child;
if (fullname)
*fullname = std::string(p.string());
- if (! boost::filesystem::create_directory(p))
+ if (! std::filesystem::create_directory(p))
{
- return (boost::filesystem::is_directory(p));
+ return (std::filesystem::is_directory(p));
}
return true;
}
@@ -75,10 +75,8 @@ LLDir_Mac::LLDir_Mac()
// mExecutablePathAndName
mExecutablePathAndName = executablepathstr;
- boost::filesystem::path executablepath(executablepathstr);
+ std::filesystem::path executablepath(executablepathstr);
-# ifndef BOOST_SYSTEM_NO_DEPRECATED
-#endif
mExecutableFilename = executablepath.filename().string();
mExecutableDir = executablepath.parent_path().string();
@@ -140,7 +138,7 @@ LLDir_Mac::LLDir_Mac()
mOSUserAppDir = mOSUserDir;
// mTempDir
- //Aura 120920 boost::filesystem::temp_directory_path() not yet implemented on mac. :(
+ //Aura 120920 std::filesystem::temp_directory_path() not yet implemented on mac. :(
std::string tmpdir = getSystemTempFolder();
if (!tmpdir.empty())
{
@@ -174,17 +172,9 @@ void LLDir_Mac::initAppDirs(const std::string &app_name,
std::string LLDir_Mac::getCurPath()
{
- return boost::filesystem::path( boost::filesystem::current_path() ).string();
+ return std::filesystem::path( std::filesystem::current_path() ).string();
}
-
-
-bool LLDir_Mac::fileExists(const std::string &filename) const
-{
- return boost::filesystem::exists(filename);
-}
-
-
/*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
{
return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() +
diff --git a/indra/llfilesystem/lldir_mac.h b/indra/llfilesystem/lldir_mac.h
index f812ee810b..54dc2eb237 100644
--- a/indra/llfilesystem/lldir_mac.h
+++ b/indra/llfilesystem/lldir_mac.h
@@ -45,7 +45,6 @@ public:
const std::string& app_read_only_data_dir);
virtual std::string getCurPath();
- virtual bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);
diff --git a/indra/llfilesystem/lldir_win32.cpp b/indra/llfilesystem/lldir_win32.cpp
index 58c080c982..912a2963c6 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);
@@ -373,24 +373,6 @@ std::string LLDir_Win32::getCurPath()
return ll_convert<std::string>(std::wstring(w_str));
}
-
-bool LLDir_Win32::fileExists(const std::string &filename) const
-{
- llstat stat_data;
- // Check the age of the file
- // Now, we see if the files we've gathered are recent...
- int res = LLFile::stat(filename, &stat_data);
- if (!res)
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-
/*virtual*/ std::string LLDir_Win32::getLLPluginLauncher()
{
return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
diff --git a/indra/llfilesystem/lldir_win32.h b/indra/llfilesystem/lldir_win32.h
index 21a3f1213b..c3a41d3e33 100644
--- a/indra/llfilesystem/lldir_win32.h
+++ b/indra/llfilesystem/lldir_win32.h
@@ -44,7 +44,6 @@ public:
/*virtual*/ std::string getCurPath();
/*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask);
- /*virtual*/ bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);
diff --git a/indra/llfilesystem/lldiriterator.cpp b/indra/llfilesystem/lldiriterator.cpp
index e8c37389d2..60b55c7bf3 100644
--- a/indra/llfilesystem/lldiriterator.cpp
+++ b/indra/llfilesystem/lldiriterator.cpp
@@ -24,13 +24,14 @@
* $/LicenseInfo$
*/
+#include "linden_common.h"
+
#include "lldiriterator.h"
-#include "fix_macros.h"
#include "llregex.h"
-#include <boost/filesystem.hpp>
+#include <filesystem>
-namespace fs = boost::filesystem;
+namespace fs = std::filesystem;
static std::string glob_to_regex(const std::string& glob);
@@ -51,11 +52,7 @@ private:
LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
: mIsValid(false)
{
-#ifdef LL_WINDOWS // or BOOST_WINDOWS_API
- fs::path dir_path(ll_convert<std::wstring>(dirname));
-#else
- fs::path dir_path(dirname);
-#endif
+ fs::path dir_path = fsyspath(dirname);
bool is_dir = false;
diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp
index ea33178a1e..e7b43e15e2 100644
--- a/indra/llfilesystem/lldiskcache.cpp
+++ b/indra/llfilesystem/lldiskcache.cpp
@@ -34,8 +34,8 @@
#include "llapp.h"
#include "llassettype.h"
#include "lldir.h"
-#include <boost/filesystem.hpp>
#include <chrono>
+#include <filesystem>
#include "lldiskcache.h"
@@ -67,7 +67,7 @@ LLDiskCache::LLDiskCache(const std::string& cache_dir,
// Interaction through the filesystem itself should be safe. Let's say thread
// A is accessing the cache file for reading/writing and thread B is trimming
// the cache. Let's also assume using llifstream to open a file and
-// boost::filesystem::remove are not atomic (which will be pretty much the
+// std::filesystem::remove are not atomic (which will be pretty much the
// case).
// Now, A is trying to open the file using llifstream ctor. It does some
@@ -83,7 +83,7 @@ LLDiskCache::LLDiskCache(const std::string& cache_dir,
// garbage.)
// Other situation: B is trimming the cache and A wants to read a file that is
-// about to get deleted. boost::filesystem::remove does whatever it is doing
+// about to get deleted. std::filesystem::remove does whatever it is doing
// before actually deleting the file. If A opens the file before the file is
// actually gone, the OS call from B to delete the file will fail since the OS
// will prevent this. B continues with the next file. If the file is already
@@ -98,38 +98,34 @@ void LLDiskCache::purge()
LL_INFOS() << "Total dir size before purge is " << dirFileSize(sCacheDir) << LL_ENDL;
}
- boost::system::error_code ec;
+ std::error_code ec;
auto start_time = std::chrono::high_resolution_clock::now();
- typedef std::pair<std::time_t, std::pair<uintmax_t, std::string>> file_info_t;
+ typedef std::pair<std::filesystem::file_time_type, std::pair<uintmax_t, std::string>> file_info_t;
std::vector<file_info_t> file_info;
-#if LL_WINDOWS
- std::wstring cache_path(ll_convert<std::wstring>(sCacheDir));
-#else
- std::string cache_path(sCacheDir);
-#endif
- if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
+ std::filesystem::path cache_path = fsyspath(sCacheDir);
+ if (std::filesystem::is_directory(cache_path, ec) && !ec)
{
- boost::filesystem::directory_iterator iter(cache_path, ec);
- while (iter != boost::filesystem::directory_iterator() && !ec.failed())
+ std::filesystem::directory_iterator iter(cache_path, ec);
+ while (iter != std::filesystem::directory_iterator() && !ec)
{
if(!LLApp::isRunning())
{
return;
}
- if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
+ if (std::filesystem::is_regular_file(*iter, ec) && !ec)
{
if ((*iter).path().string().find(CACHE_FILENAME_PREFIX) != std::string::npos)
{
- uintmax_t file_size = boost::filesystem::file_size(*iter, ec);
- if (ec.failed())
+ uintmax_t file_size = std::filesystem::file_size(*iter, ec);
+ if (ec)
{
continue;
}
const std::string file_path = (*iter).path().string();
- const std::time_t file_time = boost::filesystem::last_write_time(*iter, ec);
- if (ec.failed())
+ const std::filesystem::file_time_type file_time = std::filesystem::last_write_time(*iter, ec);
+ if (ec)
{
continue;
}
@@ -169,8 +165,8 @@ void LLDiskCache::purge()
}
if (should_remove)
{
- boost::filesystem::remove(entry.second.second, ec);
- if (ec.failed())
+ std::filesystem::remove(entry.second.second, ec);
+ if (ec)
{
LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL;
}
@@ -198,7 +194,7 @@ void LLDiskCache::purge()
std::ostringstream line;
line << action << " ";
- line << entry.first << " ";
+ line << S64(entry.first.time_since_epoch().count()) << " ";
line << entry.second.first << " ";
line << entry.second.second;
line << " (" << file_size_total << "/" << mMaxSizeBytes << ")";
@@ -212,7 +208,9 @@ void LLDiskCache::purge()
const std::string LLDiskCache::metaDataToFilepath(const LLUUID& id, LLAssetType::EType at)
{
- return llformat("%s%s%s_%s_0.asset", sCacheDir.c_str(), gDirUtilp->getDirDelimiter().c_str(), CACHE_FILENAME_PREFIX.c_str(), id.asString().c_str());
+ char uuid_str[UUID_STR_LENGTH]{};
+ id.to_chars(uuid_str);
+ return llformat("%s%s%s_%s_0.asset", sCacheDir.c_str(), gDirUtilp->getDirDelimiter().c_str(), CACHE_FILENAME_PREFIX.c_str(), uuid_str);
}
const std::string LLDiskCache::getCacheInfo()
@@ -238,23 +236,19 @@ void LLDiskCache::clearCache()
* the component files but it's called infrequently so it's
* likely just fine
*/
- boost::system::error_code ec;
-#if LL_WINDOWS
- std::wstring cache_path(ll_convert<std::wstring>(sCacheDir));
-#else
- std::string cache_path(sCacheDir);
-#endif
- if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
+ std::error_code ec;
+ std::filesystem::path cache_path = fsyspath(sCacheDir);
+ if (std::filesystem::is_directory(cache_path, ec) && !ec)
{
- boost::filesystem::directory_iterator iter(cache_path, ec);
- while (iter != boost::filesystem::directory_iterator() && !ec.failed())
+ std::filesystem::directory_iterator iter(cache_path, ec);
+ while (iter != std::filesystem::directory_iterator() && !ec)
{
- if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
+ if (std::filesystem::is_regular_file(*iter, ec) && !ec)
{
if ((*iter).path().string().find(CACHE_FILENAME_PREFIX) != std::string::npos)
{
- boost::filesystem::remove(*iter, ec);
- if (ec.failed())
+ std::filesystem::remove(*iter, ec);
+ if (ec)
{
LL_WARNS() << "Failed to delete cache file " << *iter << ": " << ec.message() << LL_ENDL;
}
@@ -271,24 +265,20 @@ void LLDiskCache::removeOldVFSFiles()
static const char CACHE_FORMAT[] = "inv.llsd";
static const char DB_FORMAT[] = "db2.x";
- boost::system::error_code ec;
-#if LL_WINDOWS
- std::wstring cache_path(ll_convert<std::wstring>(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "")));
-#else
- std::string cache_path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""));
-#endif
- if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
+ std::error_code ec;
+ std::filesystem::path cache_path = fsyspath(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""));
+ if (std::filesystem::is_directory(cache_path, ec) && !ec)
{
- boost::filesystem::directory_iterator iter(cache_path, ec);
- while (iter != boost::filesystem::directory_iterator() && !ec.failed())
+ std::filesystem::directory_iterator iter(cache_path, ec);
+ while (iter != std::filesystem::directory_iterator() && !ec)
{
- if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
+ if (std::filesystem::is_regular_file(*iter, ec) && !ec)
{
if (((*iter).path().string().find(CACHE_FORMAT) != std::string::npos) ||
((*iter).path().string().find(DB_FORMAT) != std::string::npos))
{
- boost::filesystem::remove(*iter, ec);
- if (ec.failed())
+ std::filesystem::remove(*iter, ec);
+ if (ec)
{
LL_WARNS() << "Failed to delete cache file " << *iter << ": " << ec.message() << LL_ENDL;
}
@@ -312,23 +302,19 @@ uintmax_t LLDiskCache::dirFileSize(const std::string& dir)
* so if performance is ever an issue, optimizing this or removing it altogether,
* is an easy win.
*/
- boost::system::error_code ec;
-#if LL_WINDOWS
- std::wstring dir_path(ll_convert<std::wstring>(dir));
-#else
- std::string dir_path(dir);
-#endif
- if (boost::filesystem::is_directory(dir_path, ec) && !ec.failed())
+ std::error_code ec;
+ std::filesystem::path dir_path = fsyspath(dir);
+ if (std::filesystem::is_directory(dir_path, ec) && !ec)
{
- boost::filesystem::directory_iterator iter(dir_path, ec);
- while (iter != boost::filesystem::directory_iterator() && !ec.failed())
+ std::filesystem::directory_iterator iter(dir_path, ec);
+ while (iter != std::filesystem::directory_iterator() && !ec)
{
- if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
+ if (std::filesystem::is_regular_file(*iter, ec) && !ec)
{
if ((*iter).path().string().find(CACHE_FILENAME_PREFIX) != std::string::npos)
{
- uintmax_t file_size = boost::filesystem::file_size(*iter, ec);
- if (!ec.failed())
+ uintmax_t file_size = std::filesystem::file_size(*iter, ec);
+ if (!ec)
{
total_file_size += file_size;
}
diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp
index 728ff396ef..388cbc280f 100644
--- a/indra/llfilesystem/llfilesystem.cpp
+++ b/indra/llfilesystem/llfilesystem.cpp
@@ -34,8 +34,6 @@
#include "llfasttimer.h"
#include "lldiskcache.h"
-#include "boost/filesystem.hpp"
-
constexpr S32 LLFileSystem::READ = 0x00000001;
constexpr S32 LLFileSystem::WRITE = 0x00000002;
constexpr S32 LLFileSystem::READ_WRITE = 0x00000003; // LLFileSystem::READ & LLFileSystem::WRITE
@@ -51,22 +49,21 @@ LLFileSystem::LLFileSystem(const LLUUID& file_id, const LLAssetType::EType file_
mBytesRead = 0;
mMode = mode;
+ // build the filepath
+ mPath = fsyspath(LLDiskCache::metaDataToFilepath(mFileID, mFileType));
+
// This block of code was originally called in the read() method but after comments here:
// https://bitbucket.org/lindenlab/viewer/commits/e28c1b46e9944f0215a13cab8ee7dded88d7fc90#comment-10537114
// we decided to follow Henri's suggestion and move the code to update the last access time here.
if (mode == LLFileSystem::READ)
{
- // build the filename (TODO: we do this in a few places - perhaps we should factor into a single function)
- const std::string filename = LLDiskCache::metaDataToFilepath(mFileID, mFileType);
-
// update the last access time for the file if it exists - this is required
// even though we are reading and not writing because this is the
// way the cache works - it relies on a valid "last accessed time" for
// each file so it knows how to remove the oldest, unused files
- bool exists = gDirUtilp->fileExists(filename);
- if (exists)
+ if (LLFile::exists(mPath))
{
- updateFileAccessTime(filename);
+ updateFileAccessTime();
}
}
}
@@ -77,20 +74,17 @@ bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType fil
LL_PROFILE_ZONE_SCOPED;
const std::string filename = LLDiskCache::metaDataToFilepath(file_id, file_type);
- boost::system::error_code ec;
- if (boost::filesystem::exists(filename, ec) && boost::filesystem::is_regular_file(filename, ec))
- {
- return boost::filesystem::file_size(filename, ec) > 0;
- }
- return false;
+ // not only test for existence but for the file to be not empty
+ S64 size = LLFile::size(filename);
+ return size > 0;
}
// static
-bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type, int suppress_error /*= 0*/)
+bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type, int suppress_warning /*= 0*/)
{
const std::string filename = LLDiskCache::metaDataToFilepath(file_id, file_type);
- LLFile::remove(filename.c_str(), suppress_error);
+ LLFile::remove(filename.c_str(), suppress_warning);
return true;
}
@@ -114,26 +108,11 @@ bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::ETyp
return true;
}
-// static
-S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type)
-{
- const std::string filename = LLDiskCache::metaDataToFilepath(file_id, file_type);
-
- boost::system::error_code ec;
- if (boost::filesystem::exists(filename, ec) && boost::filesystem::is_regular_file(filename, ec))
- {
- return static_cast<S32>(boost::filesystem::file_size(filename, ec));
- }
- return 0;
-}
-
bool LLFileSystem::read(U8* buffer, S32 bytes)
{
bool success = false;
- const std::string filename = LLDiskCache::metaDataToFilepath(mFileID, mFileType);
-
- llifstream file(filename, std::ios::binary);
+ llifstream file(mPath, std::ios::binary);
if (file.is_open())
{
file.seekg(mPosition, std::ios::beg);
@@ -173,13 +152,11 @@ bool LLFileSystem::eof() const
bool LLFileSystem::write(const U8* buffer, S32 bytes)
{
- const std::string filename = LLDiskCache::metaDataToFilepath(mFileID, mFileType);
-
bool success = false;
if (mMode == APPEND)
{
- llofstream ofs(filename, std::ios::app | std::ios::binary);
+ llofstream ofs(mPath, std::ios::app | std::ios::binary);
if (ofs)
{
ofs.write((const char*)buffer, bytes);
@@ -192,7 +169,7 @@ bool LLFileSystem::write(const U8* buffer, S32 bytes)
else if (mMode == READ_WRITE)
{
// Don't truncate if file already exists
- llofstream ofs(filename, std::ios::in | std::ios::binary);
+ llofstream ofs(mPath, std::ios::in | std::ios::binary);
if (ofs)
{
ofs.seekp(mPosition, std::ios::beg);
@@ -203,7 +180,7 @@ bool LLFileSystem::write(const U8* buffer, S32 bytes)
else
{
// File doesn't exist - open in write mode
- ofs.open(filename, std::ios::binary);
+ ofs.open(mPath, std::ios::binary);
if (ofs.is_open())
{
ofs.write((const char*)buffer, bytes);
@@ -214,7 +191,7 @@ bool LLFileSystem::write(const U8* buffer, S32 bytes)
}
else
{
- llofstream ofs(filename, std::ios::binary);
+ llofstream ofs(mPath, std::ios::binary);
if (ofs)
{
ofs.write((const char*)buffer, bytes);
@@ -265,7 +242,7 @@ S32 LLFileSystem::tell() const
S32 LLFileSystem::getSize() const
{
- return LLFileSystem::getFileSize(mFileID, mFileType);
+ return narrow(LLFile::size(mPath));
}
S32 LLFileSystem::getMaxSize() const
@@ -280,17 +257,18 @@ bool LLFileSystem::rename(const LLUUID& new_id, const LLAssetType::EType new_typ
mFileID = new_id;
mFileType = new_type;
+ mPath = fsyspath(LLDiskCache::metaDataToFilepath(mFileID, mFileType));
return true;
}
bool LLFileSystem::remove() const
{
- LLFileSystem::removeFile(mFileID, mFileType);
+ LLFile::remove(mPath);
return true;
}
-void LLFileSystem::updateFileAccessTime(const std::string& file_path)
+void LLFileSystem::updateFileAccessTime()
{
/**
* Threshold in time_t units that is used to decide if the last access time
@@ -301,52 +279,32 @@ void LLFileSystem::updateFileAccessTime(const std::string& file_path)
*
* Let's start with 1 hour in time_t units and see how that unfolds
*/
- constexpr std::time_t time_threshold = 1 * 60 * 60;
+ constexpr std::chrono::hours time_threshold(1);
// current time
- const std::time_t cur_time = std::time(nullptr);
+ const std::filesystem::file_time_type cur_time = std::chrono::file_clock::now();
- boost::system::error_code ec;
-#if LL_WINDOWS
- // file last write time
- const std::time_t last_write_time = boost::filesystem::last_write_time(ll_convert<std::wstring>(file_path), ec);
- if (ec.failed())
- {
- LL_WARNS() << "Failed to read last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
- return;
- }
-
- // delta between cur time and last time the file was written
- const std::time_t delta_time = cur_time - last_write_time;
-
- // we only write the new value if the time in time_threshold has elapsed
- // before the last one
- if (delta_time > time_threshold)
- {
- boost::filesystem::last_write_time(ll_convert<std::wstring>(file_path), cur_time, ec);
- }
-#else
+ std::error_code ec;
// file last write time
- const std::time_t last_write_time = boost::filesystem::last_write_time(file_path, ec);
- if (ec.failed())
+ const std::filesystem::file_time_type last_write_time = std::filesystem::last_write_time(mPath, ec);
+ if (ec)
{
- LL_WARNS() << "Failed to read last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
+ LL_WARNS() << "Failed to read last write time for cache file " << mPath << ": " << ec.message() << LL_ENDL;
return;
}
// delta between cur time and last time the file was written
- const std::time_t delta_time = cur_time - last_write_time;
+ const auto delta_time = cur_time - last_write_time;
// we only write the new value if the time in time_threshold has elapsed
// before the last one
if (delta_time > time_threshold)
{
- boost::filesystem::last_write_time(file_path, cur_time, ec);
+ std::filesystem::last_write_time(mPath, cur_time, ec);
}
-#endif
- if (ec.failed())
+ if (ec)
{
- LL_WARNS() << "Failed to update last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
+ LL_WARNS() << "Failed to update last write time for cache file " << mPath << ": " << ec.message() << LL_ENDL;
}
}
diff --git a/indra/llfilesystem/llfilesystem.h b/indra/llfilesystem/llfilesystem.h
index 10649b6920..bc8b9216bd 100644
--- a/indra/llfilesystem/llfilesystem.h
+++ b/indra/llfilesystem/llfilesystem.h
@@ -33,6 +33,7 @@
#include "lluuid.h"
#include "llassettype.h"
#include "lldiskcache.h"
+#include <filesystem>
class LLFileSystem
{
@@ -58,13 +59,12 @@ class LLFileSystem
* file in the cache is read (not written) so that the last time the file was
* accessed is up to date (This is used in the mechanism for purging the cache)
*/
- void updateFileAccessTime(const std::string& file_path);
+ void updateFileAccessTime();
static bool getExists(const LLUUID& file_id, const LLAssetType::EType file_type);
- static bool removeFile(const LLUUID& file_id, const LLAssetType::EType file_type, int suppress_error = 0);
+ static bool removeFile(const LLUUID& file_id, const LLAssetType::EType file_type, int suppress_warning = 0);
static bool renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type,
const LLUUID& new_file_id, const LLAssetType::EType new_file_type);
- static S32 getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type);
public:
static const S32 READ;
@@ -73,6 +73,7 @@ class LLFileSystem
static const S32 APPEND;
protected:
+ std::filesystem::path mPath;
LLAssetType::EType mFileType;
LLUUID mFileID;
S32 mPosition;
diff --git a/indra/llfilesystem/tests/lldir_test.cpp b/indra/llfilesystem/tests/lldir_test.cpp
index 13db6fad80..412feb147b 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"
// For some tests, use a dummy LLDir that uses memory data instead of touching
@@ -403,7 +405,7 @@ namespace tut
std::string makeTestFile( const std::string& dir, const std::string& file )
{
std::string path = dir + file;
- LLFILE* handle = LLFile::fopen( path, "w" );
+ LLFILE* handle = LLFile::fopen(path, LLFILE_MODE("w"));
ensure("failed to open test file '"+path+"'", handle != NULL );
// Harbison & Steele, 4th ed., p. 366: "If an error occurs, fputs
// returns EOF; otherwise, it returns some other, nonnegative value."
@@ -412,23 +414,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" };
@@ -484,8 +482,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++)
@@ -558,8 +557,8 @@ namespace tut
LLFile::remove(dir1files[i]);
LLFile::remove(dir2files[i]);
}
- LLFile::rmdir(dir1);
- LLFile::rmdir(dir2);
+ LLFile::remove(dir1);
+ LLFile::remove(dir2);
}
template<> template<>
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/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 35bc7065b1..b4d34f536c 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -2048,6 +2048,25 @@ file_extensions[] =
{ "dxt", IMG_CODEC_DXT },
{ "png", IMG_CODEC_PNG }
};
+
+static struct
+{
+ const wchar_t* exten;
+ EImageCodec codec;
+}
+wide_file_extensions[] =
+{
+ { L"bmp", IMG_CODEC_BMP },
+ { L"tga", IMG_CODEC_TGA },
+ { L"j2c", IMG_CODEC_J2C },
+ { L"jp2", IMG_CODEC_J2C },
+ { L"texture", IMG_CODEC_J2C },
+ { L"jpg", IMG_CODEC_JPEG },
+ { L"jpeg", IMG_CODEC_JPEG },
+ { L"mip", IMG_CODEC_DXT },
+ { L"dxt", IMG_CODEC_DXT },
+ { L"png", IMG_CODEC_PNG }
+};
#define NUM_FILE_EXTENSIONS LL_ARRAY_SIZE(file_extensions)
#if 0
static std::string find_file(std::string &name, S8 *codec)
@@ -2068,7 +2087,8 @@ static std::string find_file(std::string &name, S8 *codec)
return std::string("");
}
#endif
-EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten)
+
+EImageCodec LLImageBase::getCodecFromExtension(std::string_view exten)
{
if (!exten.empty())
{
@@ -2080,6 +2100,20 @@ EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten)
}
return IMG_CODEC_INVALID;
}
+
+EImageCodec LLImageBase::getCodecFromExtension(std::wstring_view exten)
+{
+ if (!exten.empty())
+ {
+ for (int i = 0; i < (int)(NUM_FILE_EXTENSIONS); i++)
+ {
+ if (exten == wide_file_extensions[i].exten)
+ return wide_file_extensions[i].codec;
+ }
+ }
+ return IMG_CODEC_INVALID;
+}
+
#if 0
bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip_only)
{
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 1fb61673bd..8569c28528 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -159,7 +159,8 @@ public:
// <= 0 priority means that there's no need for more data.
static F32 calc_download_priority(F32 virtual_size, F32 visible_area, S32 bytes_sent);
- static EImageCodec getCodecFromExtension(const std::string& exten);
+ static EImageCodec getCodecFromExtension(std::string_view exten);
+ static EImageCodec getCodecFromExtension(std::wstring_view exten);
//static LLTrace::MemStatHandle sMemStat;
diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp
index c896d60c85..2ae7760d4c 100644
--- a/indra/llimage/llimagedimensionsinfo.cpp
+++ b/indra/llimage/llimagedimensionsinfo.cpp
@@ -166,7 +166,7 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
{
sJpegErrorEncountered = false;
clean();
- FILE* fp = LLFile::fopen(mSrcFilename, "rb");
+ FILE* fp = LLFile::fopen(mSrcFilename, LLFILE_MODE("rb"));
if (!fp)
{
setLastError("Unable to open file for reading", mSrcFilename);
diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp
index 25232b77aa..7b09553974 100644
--- a/indra/llimage/llimagetga.cpp
+++ b/indra/llimage/llimagetga.cpp
@@ -1191,7 +1191,7 @@ bool LLImageTGA::loadFile( const std::string& path )
return false;
}
- LLFILE* file = LLFile::fopen(path, "rb"); /* Flawfinder: ignore */
+ LLFILE* file = LLFile::fopen(path, LLFILE_MODE("rb")); /* Flawfinder: ignore */
if( !file )
{
LL_WARNS() << "Couldn't open file " << path << LL_ENDL;
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..e8f76eaa7d 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)
@@ -71,4 +75,7 @@ if (LL_TESTS)
set(test_libs llinventory llmath llcorehttp llfilesystem )
LL_ADD_INTEGRATION_TEST(inventorymisc "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llparcel "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llpermissions "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llsaleinfo "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(lluserrelations "" "${test_libs}")
endif (LL_TESTS)
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp
index 031029531c..944f38bd3e 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/test/llpermissions_tut.cpp b/indra/llinventory/tests/llpermissions_test.cpp
index 1328939004..1328939004 100644
--- a/indra/test/llpermissions_tut.cpp
+++ b/indra/llinventory/tests/llpermissions_test.cpp
diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/llinventory/tests/llsaleinfo_test.cpp
index 1da7101aa3..1da7101aa3 100644
--- a/indra/test/llsaleinfo_tut.cpp
+++ b/indra/llinventory/tests/llsaleinfo_test.cpp
diff --git a/indra/test/lluserrelations_tut.cpp b/indra/llinventory/tests/lluserrelations_test.cpp
index 80a659da65..80a659da65 100644
--- a/indra/test/lluserrelations_tut.cpp
+++ b/indra/llinventory/tests/lluserrelations_test.cpp
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..f97e4a5bb6 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -24,7 +24,6 @@ set(llmath_SOURCE_FILES
llquaternion.cpp
llrigginginfo.cpp
llrect.cpp
- llsphere.cpp
llvector4a.cpp
llvolume.cpp
llvolumemgr.cpp
@@ -46,8 +45,6 @@ set(llmath_SOURCE_FILES
set(llmath_HEADER_FILES
CMakeLists.txt
- camera.h
- coordframe.h
llbbox.h
llbboxlocal.h
llcalc.h
@@ -74,7 +71,6 @@ set(llmath_HEADER_FILES
llsimdmath.h
llsimdtypes.h
llsimdtypes.inl
- llsphere.h
lltreenode.h
llvector4a.h
llvector4a.inl
@@ -99,10 +95,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/camera.h b/indra/llmath/camera.h
deleted file mode 100644
index 14a08c5985..0000000000
--- a/indra/llmath/camera.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * @file camera.h
- * @brief Legacy wrapper header.
- *
- * $LicenseInfo:firstyear=2000&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 "llcamera.h"
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/llsphere.cpp b/indra/llmath/llsphere.cpp
deleted file mode 100644
index 5f48764455..0000000000
--- a/indra/llmath/llsphere.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-/**
- * @file llsphere.cpp
- * @author Andrew Meadows
- * @brief Simple line class that can compute nearest approach between two lines
- *
- * $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 "llsphere.h"
-
-LLSphere::LLSphere()
-: mCenter(0.f, 0.f, 0.f),
- mRadius(0.f)
-{ }
-
-LLSphere::LLSphere( const LLVector3& center, F32 radius)
-{
- set(center, radius);
-}
-
-void LLSphere::set( const LLVector3& center, F32 radius )
-{
- mCenter = center;
- setRadius(radius);
-}
-
-void LLSphere::setCenter( const LLVector3& center)
-{
- mCenter = center;
-}
-
-void LLSphere::setRadius( F32 radius)
-{
- if (radius < 0.f)
- {
- radius = -radius;
- }
- mRadius = radius;
-}
-
-const LLVector3& LLSphere::getCenter() const
-{
- return mCenter;
-}
-
-F32 LLSphere::getRadius() const
-{
- return mRadius;
-}
-
-// returns 'true' if this sphere completely contains other_sphere
-bool LLSphere::contains(const LLSphere& other_sphere) const
-{
- F32 separation = (mCenter - other_sphere.mCenter).length();
- return mRadius >= separation + other_sphere.mRadius;
-}
-
-// returns 'true' if this sphere completely contains other_sphere
-bool LLSphere::overlaps(const LLSphere& other_sphere) const
-{
- F32 separation = (mCenter - other_sphere.mCenter).length();
- return mRadius >= separation - other_sphere.mRadius;
-}
-
-// returns overlap
-// negative overlap is closest approach
-F32 LLSphere::getOverlap(const LLSphere& other_sphere) const
-{
- // separation is distance from other_sphere's edge and this center
- return (mCenter - other_sphere.mCenter).length() - mRadius - other_sphere.mRadius;
-}
-
-bool LLSphere::operator==(const LLSphere& rhs) const
-{
- return fabs(mRadius - rhs.mRadius) <= FLT_EPSILON &&
- (mCenter - rhs.mCenter).length() <= FLT_EPSILON;
-}
-
-std::ostream& operator<<( std::ostream& output_stream, const LLSphere& sphere)
-{
- output_stream << "{center=" << sphere.mCenter << "," << "radius=" << sphere.mRadius << "}";
- return output_stream;
-}
-
-// static
-// removes any spheres that are contained in others
-void LLSphere::collapse(std::vector<LLSphere>& sphere_list)
-{
- std::vector<LLSphere>::iterator first_itr = sphere_list.begin();
- while (first_itr != sphere_list.end())
- {
- bool delete_from_front = false;
-
- std::vector<LLSphere>::iterator second_itr = first_itr;
- ++second_itr;
- while (second_itr != sphere_list.end())
- {
- if (second_itr->contains(*first_itr))
- {
- delete_from_front = true;
- break;
- }
- else if (first_itr->contains(*second_itr))
- {
- sphere_list.erase(second_itr++);
- }
- else
- {
- ++second_itr;
- }
- }
-
- if (delete_from_front)
- {
- sphere_list.erase(first_itr++);
- }
- else
- {
- ++first_itr;
- }
- }
-}
-
-// static
-// returns the bounding sphere that contains both spheres
-LLSphere LLSphere::getBoundingSphere(const LLSphere& first_sphere, const LLSphere& second_sphere)
-{
- LLVector3 direction = second_sphere.mCenter - first_sphere.mCenter;
-
- // HACK -- it is possible to get enough floating point error in the
- // other getBoundingSphere() method that we have to add some slop
- // at the end. Unfortunately, this breaks the link-order invarience
- // for the linkability tests... unless we also apply the same slop
- // here.
- F32 half_milimeter = 0.0005f;
-
- F32 distance = direction.length();
- if (0.f == distance)
- {
- direction.setVec(1.f, 0.f, 0.f);
- }
- else
- {
- direction.normVec();
- }
- // the 'edge' is measured from the first_sphere's center
- F32 max_edge = 0.f;
- F32 min_edge = 0.f;
-
- max_edge = llmax(max_edge + first_sphere.getRadius(), max_edge + distance + second_sphere.getRadius() + half_milimeter);
- min_edge = llmin(min_edge - first_sphere.getRadius(), min_edge + distance - second_sphere.getRadius() - half_milimeter);
- F32 radius = 0.5f * (max_edge - min_edge);
- LLVector3 center = first_sphere.mCenter + (0.5f * (max_edge + min_edge)) * direction;
- return LLSphere(center, radius);
-}
-
-// static
-// returns the bounding sphere that contains an arbitrary set of spheres
-LLSphere LLSphere::getBoundingSphere(const std::vector<LLSphere>& sphere_list)
-{
- // this algorithm can get relatively inaccurate when the sphere
- // collection is 'small' (contained within a bounding sphere of about
- // 2 meters or less)
- // TODO -- improve the accuracy for small collections of spheres
-
- LLSphere bounding_sphere( LLVector3(0.f, 0.f, 0.f), 0.f );
- auto sphere_count = sphere_list.size();
- if (1 == sphere_count)
- {
- // trivial case -- single sphere
- std::vector<LLSphere>::const_iterator sphere_itr = sphere_list.begin();
- bounding_sphere = *sphere_itr;
- }
- else if (2 == sphere_count)
- {
- // trivial case -- two spheres
- std::vector<LLSphere>::const_iterator first_sphere = sphere_list.begin();
- std::vector<LLSphere>::const_iterator second_sphere = first_sphere;
- ++second_sphere;
- bounding_sphere = LLSphere::getBoundingSphere(*first_sphere, *second_sphere);
- }
- else if (sphere_count > 0)
- {
- // non-trivial case -- we will approximate the solution
- //
- // NOTE -- there is a fancy/fast way to do this for large
- // numbers of arbirary N-dimensional spheres -- you can look it
- // up on the net. We're dealing with 3D spheres at collection
- // sizes of 256 spheres or smaller, so we just use this
- // brute force method.
-
- // TODO -- perhaps would be worthwile to test for the solution where
- // the largest spanning radius just happens to work. That is, where
- // there are really two spheres that determine the bounding sphere,
- // and all others are contained therein.
-
- // compute the AABB
- std::vector<LLSphere>::const_iterator first_itr = sphere_list.begin();
- LLVector3 max_corner = first_itr->getCenter() + first_itr->getRadius() * LLVector3(1.f, 1.f, 1.f);
- LLVector3 min_corner = first_itr->getCenter() - first_itr->getRadius() * LLVector3(1.f, 1.f, 1.f);
- {
- std::vector<LLSphere>::const_iterator sphere_itr = sphere_list.begin();
- for (++sphere_itr; sphere_itr != sphere_list.end(); ++sphere_itr)
- {
- LLVector3 center = sphere_itr->getCenter();
- F32 radius = sphere_itr->getRadius();
- for (S32 i=0; i<3; ++i)
- {
- if (center.mV[i] + radius > max_corner.mV[i])
- {
- max_corner.mV[i] = center.mV[i] + radius;
- }
- if (center.mV[i] - radius < min_corner.mV[i])
- {
- min_corner.mV[i] = center.mV[i] - radius;
- }
- }
- }
- }
-
- // get the starting center and radius from the AABB
- LLVector3 diagonal = max_corner - min_corner;
- F32 bounding_radius = 0.5f * diagonal.length();
- LLVector3 bounding_center = 0.5f * (max_corner + min_corner);
-
- // compute the starting step-size
- F32 minimum_radius = 0.5f * llmin(diagonal.mV[VX], llmin(diagonal.mV[VY], diagonal.mV[VZ]));
- F32 step_length = bounding_radius - minimum_radius;
- //S32 step_count = 0;
- //S32 max_step_count = 12;
- F32 half_milimeter = 0.0005f;
-
- // wander the center around in search of tighter solutions
- S32 last_dx = 2; // 2 is out of bounds --> no match
- S32 last_dy = 2;
- S32 last_dz = 2;
-
- while (step_length > half_milimeter
- /*&& step_count < max_step_count*/)
- {
- // the algorithm for testing the maximum radius could be expensive enough
- // that it makes sense to NOT duplicate testing when possible, so we keep
- // track of where we last tested, and only test the new points
-
- S32 best_dx = 0;
- S32 best_dy = 0;
- S32 best_dz = 0;
-
- // sample near the center of the box
- bool found_better_center = false;
- for (S32 dx = -1; dx < 2; ++dx)
- {
- for (S32 dy = -1; dy < 2; ++dy)
- {
- for (S32 dz = -1; dz < 2; ++dz)
- {
- if (dx == 0 && dy == 0 && dz == 0)
- {
- continue;
- }
-
- // count the number of indecies that match the last_*'s
- S32 match_count = 0;
- if (last_dx == dx) ++match_count;
- if (last_dy == dy) ++match_count;
- if (last_dz == dz) ++match_count;
- if (match_count == 2)
- {
- // we've already tested this point
- continue;
- }
-
- LLVector3 center = bounding_center;
- center.mV[VX] += (F32) dx * step_length;
- center.mV[VY] += (F32) dy * step_length;
- center.mV[VZ] += (F32) dz * step_length;
-
- // compute the radius of the bounding sphere
- F32 max_radius = 0.f;
- std::vector<LLSphere>::const_iterator sphere_itr;
- for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr)
- {
- F32 radius = (sphere_itr->getCenter() - center).length() + sphere_itr->getRadius();
- if (radius > max_radius)
- {
- max_radius = radius;
- }
- }
- if (max_radius < bounding_radius)
- {
- best_dx = dx;
- best_dy = dy;
- best_dz = dz;
- bounding_center = center;
- bounding_radius = max_radius;
- found_better_center = true;
- }
- }
- }
- }
- if (found_better_center)
- {
- // remember where we came from so we can avoid retesting
- last_dx = -best_dx;
- last_dy = -best_dy;
- last_dz = -best_dz;
- }
- else
- {
- // reduce the step size
- step_length *= 0.5f;
- //++step_count;
- // reset the last_*'s
- last_dx = 2; // 2 is out of bounds --> no match
- last_dy = 2;
- last_dz = 2;
- }
- }
-
- // HACK -- it is possible to get enough floating point error for the
- // bounding sphere to too small on the order of 10e-6, but we only need
- // it to be accurate to within about half a millimeter
- bounding_radius += half_milimeter;
-
- // this algorithm can get relatively inaccurate when the sphere
- // collection is 'small' (contained within a bounding sphere of about
- // 2 meters or less)
- // TODO -- fix this
- /* debug code
- {
- std::vector<LLSphere>::const_iterator sphere_itr;
- for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr)
- {
- F32 radius = (sphere_itr->getCenter() - bounding_center).length() + sphere_itr->getRadius();
- if (radius + 0.1f > bounding_radius)
- {
- std::cout << " rad = " << radius << " bounding - rad = " << (bounding_radius - radius) << std::endl;
- }
- }
- std::cout << "\n" << std::endl;
- }
- */
-
- bounding_sphere.set(bounding_center, bounding_radius);
- }
- return bounding_sphere;
-}
-
-
diff --git a/indra/llmath/llsphere.h b/indra/llmath/llsphere.h
deleted file mode 100644
index cb923dcd3c..0000000000
--- a/indra/llmath/llsphere.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// llsphere.h
-/**
- * @file llsphere.cpp
- * @author Andrew Meadows
- * @brief Simple sphere implementation for basic geometric operations
- *
- * $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_SPHERE_H
-#define LL_SPHERE_H
-
-#include "stdtypes.h"
-#include "v3math.h"
-#include <iostream>
-#include <vector>
-
-class LLSphere
-{
-public:
- LLSphere();
- LLSphere( const LLVector3& center, F32 radius );
-
- void set( const LLVector3& center, F32 radius );
- void setCenter( const LLVector3& center );
- void setRadius( F32 radius );
-
- const LLVector3& getCenter() const;
- F32 getRadius() const;
-
- // returns true if this sphere completely contains other_sphere
- bool contains(const LLSphere& other_sphere) const;
-
- // returns true if this sphere overlaps other_sphere
- bool overlaps(const LLSphere& other_sphere) const;
-
- // returns overlap distance
- // negative overlap is closest approach
- F32 getOverlap(const LLSphere& other_sphere) const;
-
- // removes any spheres that are contained in others
- static void collapse(std::vector<LLSphere>& sphere_list);
-
- // returns minimum sphere bounding sphere for a set of spheres
- static LLSphere getBoundingSphere(const LLSphere& first_sphere, const LLSphere& second_sphere);
- static LLSphere getBoundingSphere(const std::vector<LLSphere>& sphere_list);
-
- bool operator==(const LLSphere& rhs) const;
-
- friend std::ostream& operator<<( std::ostream& output_stream, const LLSphere& line );
-
-protected:
- LLVector3 mCenter;
- F32 mRadius;
-};
-
-
-#endif
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 1bbc559763..ece52db1b1 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2477,7 +2477,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 b6b7e22517..0250bf8bfb 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];
@@ -91,8 +91,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/llmath/tests/mathmisc_test.cpp b/indra/llmath/tests/mathmisc_test.cpp
index ff0899e975..810b0d80da 100644
--- a/indra/llmath/tests/mathmisc_test.cpp
+++ b/indra/llmath/tests/mathmisc_test.cpp
@@ -35,7 +35,6 @@
#include "../llline.h"
#include "../llmath.h"
-#include "../llsphere.h"
#include "../v3math.h"
namespace tut
@@ -280,166 +279,6 @@ namespace tut
namespace tut
{
- struct sphere_data
- {
- };
- typedef test_group<sphere_data> sphere_test;
- typedef sphere_test::object sphere_object;
- tut::sphere_test tsphere("LLSphere");
-
- template<> template<>
- void sphere_object::test<1>()
- {
- // test LLSphere::contains() and ::overlaps()
- S32 number_of_tests = 10;
- for (S32 test = 0; test < number_of_tests; ++test)
- {
- LLVector3 first_center(1.f, 1.f, 1.f);
- F32 first_radius = 3.f;
- LLSphere first_sphere( first_center, first_radius );
-
- F32 half_millimeter = 0.0005f;
- LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
- direction.normalize();
-
- F32 distance = ll_frand(first_radius - 2.f * half_millimeter);
- LLVector3 second_center = first_center + distance * direction;
- F32 second_radius = first_radius - distance - half_millimeter;
- LLSphere second_sphere( second_center, second_radius );
- ensure("first sphere should contain the second", first_sphere.contains(second_sphere));
- ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere));
-
- distance = first_radius + ll_frand(first_radius);
- second_center = first_center + distance * direction;
- second_radius = distance - first_radius + half_millimeter;
- second_sphere.set( second_center, second_radius );
- ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere));
- ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere));
-
- distance = first_radius + ll_frand(first_radius) + half_millimeter;
- second_center = first_center + distance * direction;
- second_radius = distance - first_radius - half_millimeter;
- second_sphere.set( second_center, second_radius );
- ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere));
- ensure("first sphere should NOT overlap the second", !first_sphere.overlaps(second_sphere));
- }
- }
-
- template<> template<>
- void sphere_object::test<2>()
- {
- skip("See SNOW-620. Neither the test nor the code being tested seem good. Also sim-only.");
-
- // test LLSphere::getBoundingSphere()
- S32 number_of_tests = 100;
- S32 number_of_spheres = 10;
- F32 sphere_center_range = 32.f;
- F32 sphere_radius_range = 5.f;
-
- for (S32 test = 0; test < number_of_tests; ++test)
- {
- // gegnerate a bunch of random sphere
- std::vector< LLSphere > sphere_list;
- for (S32 sphere_count=0; sphere_count < number_of_spheres; ++sphere_count)
- {
- LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
- direction.normalize();
- F32 distance = ll_frand(sphere_center_range);
- LLVector3 center = distance * direction;
- F32 radius = ll_frand(sphere_radius_range);
- LLSphere sphere( center, radius );
- sphere_list.push_back(sphere);
- }
-
- // compute the bounding sphere
- LLSphere bounding_sphere = LLSphere::getBoundingSphere(sphere_list);
-
- // make sure all spheres are inside the bounding sphere
- {
- std::vector< LLSphere >::const_iterator sphere_itr;
- for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr)
- {
- ensure("sphere should be contained by the bounding sphere", bounding_sphere.contains(*sphere_itr));
- }
- }
-
- // TODO -- improve LLSphere::getBoundingSphere() to the point where
- // we can reduce the 'expansion' in the two tests below to about
- // 2 mm or less
-
- F32 expansion = 0.005f;
- // move all spheres out a little bit
- // and count how many are NOT contained
- {
- std::vector< LLVector3 > uncontained_directions;
- std::vector< LLSphere >::iterator sphere_itr;
- for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr)
- {
- LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter();
- direction.normalize();
-
- sphere_itr->setCenter( sphere_itr->getCenter() + expansion * direction );
- if (! bounding_sphere.contains( *sphere_itr ) )
- {
- uncontained_directions.push_back(direction);
- }
- }
- ensure("when moving spheres out there should be at least two uncontained spheres",
- uncontained_directions.size() > 1);
-
- /* TODO -- when the bounding sphere algorithm is improved we can open up this test
- * at the moment it occasionally fails when the sphere collection is tight and small
- * (2 meters or less)
- if (2 == uncontained_directions.size() )
- {
- // if there were only two uncontained spheres then
- // the two directions should be nearly opposite
- F32 dir_dot = uncontained_directions[0] * uncontained_directions[1];
- ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f);
- }
- */
- }
-
- // compute the new bounding sphere
- bounding_sphere = LLSphere::getBoundingSphere(sphere_list);
-
- // increase the size of all spheres a little bit
- // and count how many are NOT contained
- {
- std::vector< LLVector3 > uncontained_directions;
- std::vector< LLSphere >::iterator sphere_itr;
- for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr)
- {
- LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter();
- direction.normalize();
-
- sphere_itr->setRadius( sphere_itr->getRadius() + expansion );
- if (! bounding_sphere.contains( *sphere_itr ) )
- {
- uncontained_directions.push_back(direction);
- }
- }
- ensure("when boosting sphere radii there should be at least two uncontained spheres",
- uncontained_directions.size() > 1);
-
- /* TODO -- when the bounding sphere algorithm is improved we can open up this test
- * at the moment it occasionally fails when the sphere collection is tight and small
- * (2 meters or less)
- if (2 == uncontained_directions.size() )
- {
- // if there were only two uncontained spheres then
- // the two directions should be nearly opposite
- F32 dir_dot = uncontained_directions[0] * uncontained_directions[1];
- ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f);
- }
- */
- }
- }
- }
-}
-
-namespace tut
-{
F32 SMALL_RADIUS = 1.0f;
F32 MEDIUM_RADIUS = 5.0f;
F32 LARGE_RADIUS = 10.0f;
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 48f613c124..f143ee18cf 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -79,7 +79,6 @@ set(llmessage_SOURCE_FILES
message_prehash.cpp
message_string_table.cpp
net.cpp
- partsyspacket.cpp
patch_code.cpp
patch_dct.cpp
patch_idct.cpp
@@ -171,7 +170,6 @@ set(llmessage_HEADER_FILES
message.h
message_prehash.h
net.h
- partsyspacket.h
patch_code.h
patch_dct.h
sound_ids.h
@@ -190,6 +188,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
@@ -211,9 +213,22 @@ if (LL_TESTS)
llcommon
)
- #LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(io "tests/llpipeutil.cpp" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llbuffer "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(lldatapacker "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llhost "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llhttpnode "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(lliohttpserver "tests/llpipeutil.cpp" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llsdmessagebuilder "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llsdmessagereader "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llmessageconfig "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llmessagetemplateparser "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llpartdata "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llservicebuilder "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(lltemplatemessagebuilder "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llxfer_file "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llxorcipher "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(message "" "${test_libs}")
endif (LL_TESTS)
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index b6a98575f9..321b2e04b7 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -468,7 +468,7 @@ bool LLAssetStorage::findInCacheAndInvokeCallback(const LLUUID& uuid, LLAssetTyp
else
{
LL_WARNS("AssetStorage") << "Asset vfile " << uuid << ":" << type
- << " found in static cache with bad size " << file.getSize() << ", ignoring" << LL_ENDL;
+ << " found in static cache with bad size " << size << ", ignoring" << LL_ENDL;
}
}
return false;
@@ -1406,7 +1406,7 @@ void LLAssetStorage::legacyGetDataCallback(const LLUUID &uuid,
uuid.toString(uuid_str);
filename = llformat("%s.%s",gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str(),LLAssetType::lookup(type));
- LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("wb")); /* Flawfinder: ignore */
if (fp)
{
const S32 buf_size = 65536;
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/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index e4c7deb1c5..07d11932bc 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/llmessage/lltransfersourcefile.cpp b/indra/llmessage/lltransfersourcefile.cpp
index 77a6c466c7..d2d264c520 100644
--- a/indra/llmessage/lltransfersourcefile.cpp
+++ b/indra/llmessage/lltransfersourcefile.cpp
@@ -62,7 +62,7 @@ void LLTransferSourceFile::initTransfer()
return;
}
// Look for the file.
- mFP = LLFile::fopen(mParams.getFilename(), "rb"); /* Flawfinder: ignore */
+ mFP = LLFile::fopen(mParams.getFilename(), LLFILE_MODE("rb")); /* Flawfinder: ignore */
if (!mFP)
{
sendTransferStatus(LLTS_ERROR);
diff --git a/indra/llmessage/lltransfertargetfile.cpp b/indra/llmessage/lltransfertargetfile.cpp
index 6d8b69fa6f..05dba219ed 100644
--- a/indra/llmessage/lltransfertargetfile.cpp
+++ b/indra/llmessage/lltransfertargetfile.cpp
@@ -75,7 +75,7 @@ LLTSCode LLTransferTargetFile::dataCallback(const S32 packet_id, U8 *in_datap, c
if (!mFP)
{
- mFP = LLFile::fopen(mParams.mFilename, "wb"); /* Flawfinder: ignore */
+ mFP = LLFile::fopen(mParams.mFilename, LLFILE_MODE("wb")); /* Flawfinder: ignore */
if (!mFP)
{
diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp
index 71b910297b..5f27cc4827 100644
--- a/indra/llmessage/llxfer_file.cpp
+++ b/indra/llmessage/llxfer_file.cpp
@@ -161,7 +161,7 @@ S32 LLXfer_File::initializeRequest(U64 xfer_id,
S32 LLXfer_File::startDownload()
{
S32 retval = 0; // presume success
- mFp = LLFile::fopen(mTempFilename,"w+b"); /* Flawfinder : ignore */
+ mFp = LLFile::fopen(mTempFilename,LLFILE_MODE("w+b")); /* Flawfinder : ignore */
if (mFp)
{
fclose(mFp);
@@ -209,7 +209,7 @@ S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host)
mBufferStartOffset = 0;
// We leave the file open, assuming we'll start reading and sending soon
- mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */
+ mFp = LLFile::fopen(mLocalFilename, LLFILE_MODE("rb")); /* Flawfinder : ignore */
if (mFp)
{
fseek(mFp,0,SEEK_END);
@@ -252,7 +252,7 @@ S32 LLXfer_File::reopenFileHandle()
if (mFp == NULL)
{
- mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */
+ mFp = LLFile::fopen(mLocalFilename, LLFILE_MODE("rb")); /* Flawfinder : ignore */
if (mFp == NULL)
{
LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found when re-opening file" << LL_ENDL;
@@ -313,7 +313,7 @@ S32 LLXfer_File::flush()
{
LL_ERRS("Xfer") << "Overwriting open file pointer!" << LL_ENDL;
}
- mFp = LLFile::fopen(mTempFilename,"a+b"); /* Flawfinder : ignore */
+ mFp = LLFile::fopen(mTempFilename, LLFILE_MODE("a+b")); /* Flawfinder : ignore */
if (mFp)
{
@@ -381,11 +381,11 @@ S32 LLXfer_File::processEOF()
}
else
{
- //LLFILE* fp = LLFile::fopen(mTempFilename, "r");
+ //LLFILE* fp = LLFile::fopen(mTempFilename, LLFILE_MODE("r"));
//LL_WARNS() << "File " << mTempFilename << " does "
// << (!fp ? "not" : "" ) << " exit." << LL_ENDL;
//if(fp) fclose(fp);
- //fp = LLFile::fopen(mLocalFilename, "r");
+ //fp = LLFile::fopen(mLocalFilename, LLFILE_MODE("r"));
//LL_WARNS() << "File " << mLocalFilename << " does "
// << (!fp ? "not" : "" ) << " exit." << LL_ENDL;
//if(fp) fclose(fp);
@@ -452,8 +452,8 @@ U32 LLXfer_File::getXferTypeTag()
S32 copy_file(const std::string& from, const std::string& to)
{
S32 rv = 0;
- LLFILE* in = LLFile::fopen(from, "rb"); /*Flawfinder: ignore*/
- LLFILE* out = LLFile::fopen(to, "wb"); /*Flawfinder: ignore*/
+ LLFILE* in = LLFile::fopen(from, LLFILE_MODE("rb")); /*Flawfinder: ignore*/
+ LLFILE* out = LLFile::fopen(to, LLFILE_MODE("wb")); /*Flawfinder: ignore*/
if(in && out)
{
S32 read = 0;
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 8d86856706..db7405f93f 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -2691,7 +2691,7 @@ void dump_prehash_files()
{
U32 i;
std::string filename("../../indra/llmessage/message_prehash.h");
- LLFILE* fp = LLFile::fopen(filename, "w"); /* Flawfinder: ignore */
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("w")); /* Flawfinder: ignore */
if (fp)
{
fprintf(
@@ -2722,7 +2722,7 @@ void dump_prehash_files()
fclose(fp);
}
filename = std::string("../../indra/llmessage/message_prehash.cpp");
- fp = LLFile::fopen(filename, "w"); /* Flawfinder: ignore */
+ fp = LLFile::fopen(filename, LLFILE_MODE("w")); /* Flawfinder: ignore */
if (fp)
{
fprintf(
diff --git a/indra/llmessage/partsyspacket.cpp b/indra/llmessage/partsyspacket.cpp
deleted file mode 100644
index 6113adbfcf..0000000000
--- a/indra/llmessage/partsyspacket.cpp
+++ /dev/null
@@ -1,1297 +0,0 @@
-/**
- * @file partsyspacket.cpp
- * @brief Object for packing particle system initialization parameters
- * before sending them over the network.
- *
- * $LicenseInfo:firstyear=2000&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 "partsyspacket.h"
-#include "indra_constants.h"
-
-// this function is global
-void gSetInitDataDefaults(LLPartInitData *setMe)
-{
- U32 i;
-
- //for(i = 0; i < 18; i++)
- //{
- // setMe->k[i] = 0.0f;
- //}
-
- //setMe->kill_p[0] = setMe->kill_p[1] = setMe->kill_p[2] = 0.0f;
- //setMe->kill_p[3] = -0.2f; // time parameter, die when t= 5.0f
- //setMe->kill_p[4] = 1.0f;
- //setMe->kill_p[5] = -0.5f; // or radius == 2 (contracting)
-
- //setMe->bounce_p[0] = setMe->bounce_p[1] =
- // setMe->bounce_p[2] = setMe->bounce_p[3] = 0.0f;
- //setMe->bounce_p[4] = 1.0f;
-
- setMe->bounce_b = 1.0f;
- // i just changed the meaning of bounce_b
- // its now the attenuation from revlecting your velocity across the normal
- // set by bounce_p
-
- //setMe->pos_ranges[0] = setMe->pos_ranges[2] = setMe->pos_ranges[4] = -1.0f;
- //setMe->pos_ranges[1] = setMe->pos_ranges[3] = setMe->pos_ranges[5] = 1.0f;
-
- //setMe->vel_ranges[0] = setMe->vel_ranges[2] = setMe->vel_ranges[4] = -1.0f;
- //setMe->vel_ranges[1] = setMe->vel_ranges[3] = setMe->vel_ranges[5] = 1.0f;
-
- for(i = 0; i < 3; i++)
- {
- setMe->diffEqAlpha[i] = 0.0f;
- setMe->diffEqScale[i] = 0.0f;
- }
-
- setMe->scale_range[0] = 1.00f;
- setMe->scale_range[1] = 5.00f;
- setMe->scale_range[2] = setMe->scale_range[3] = 0.0f;
-
- setMe->alpha_range[0] = setMe->alpha_range[1] = 1.0f;
- setMe->alpha_range[2] = setMe->alpha_range[3] = 0.0f;
-
- setMe->vel_offset[0] = 0.0f;
- setMe->vel_offset[1] = 0.0f;
- setMe->vel_offset[2] = 0.0f;
-
- // start dropping particles when I'm more then one sim away
- setMe->mDistBeginFadeout = 256.0f;
- setMe->mDistEndFadeout = 1.414f * 512.0f;
- // stop displaying particles when I'm more then two sim diagonals away
-
- setMe->mImageUuid = IMG_SHOT;
-
- for(i = 0; i < 8; i++)
- {
- setMe->mFlags[i] = 0x00;
- }
-
- setMe->createMe = true;
-
- setMe->maxParticles = 25;
- setMe->initialParticles = 25;
-
- //These defaults are for an explosion - a short lived set of debris affected by gravity.
- //Action flags default to PART_SYS_AFFECTED_BY_WIND + PART_SYS_AFFECTED_BY_GRAVITY + PART_SYS_DISTANCE_DEATH
- setMe->mFlags[PART_SYS_ACTION_BYTE] = PART_SYS_AFFECTED_BY_WIND | PART_SYS_AFFECTED_BY_GRAVITY | PART_SYS_DISTANCE_DEATH;
- setMe->mFlags[PART_SYS_KILL_BYTE] = PART_SYS_DISTANCE_DEATH + PART_SYS_TIME_DEATH;
-
- setMe->killPlaneNormal[0] = 0.0f;setMe->killPlaneNormal[1] = 0.0f;setMe->killPlaneNormal[2] = 1.0f; //Straight up
- setMe->killPlaneZ = 0.0f; //get local ground z as an approximation if turn on PART_SYS_KILL_PLANE
- setMe->bouncePlaneNormal[0] = 0.0f;setMe->bouncePlaneNormal[1] = 0.0f;setMe->bouncePlaneNormal[2] = 1.0f; //Straight up
- setMe->bouncePlaneZ = 0.0f; //get local ground z as an approximation if turn on PART_SYS_BOUNCE
- setMe->spawnRange = 1.0f;
- setMe->spawnFrequency = 0.0f; //Create the instant one dies
- setMe->spawnFreqencyRange = 0.0f;
- setMe->spawnDirection[0] = 0.0f;setMe->spawnDirection[1] = 0.0f;setMe->spawnDirection[2] = 1.0f; //Straight up
- setMe->spawnDirectionRange = 1.0f; //global scattering
- setMe->spawnVelocity = 0.75f;
- setMe->spawnVelocityRange = 0.25f; //velocity +/- 0.25
- setMe->speedLimit = 1.0f;
-
- setMe->windWeight = 0.5f; //0.0f means looks like a heavy object (if gravity is on), 1.0f means light and fluffy
- setMe->currentGravity[0] = 0.0f;setMe->currentGravity[1] = 0.0f;setMe->currentGravity[2] = -9.81f;
- //This has to be constant to allow for compression
-
- setMe->gravityWeight = 0.5f; //0.0f means boyed by air, 1.0f means it's a lead weight
- setMe->globalLifetime = 0.0f; //Arbitrary, but default is no global die, so doesn't matter
- setMe->individualLifetime = 5.0f;
- setMe->individualLifetimeRange = 1.0f; //Particles last 5 secs +/- 1
- setMe->alphaDecay = 1.0f; //normal alpha fadeout
- setMe->scaleDecay = 0.0f; //no scale decay
- setMe->distanceDeath = 10.0f; //die if hit unit radius
- setMe->dampMotionFactor = 0.0f;
-
- setMe->windDiffusionFactor[0] = 0.0f;
- setMe->windDiffusionFactor[1] = 0.0f;
- setMe->windDiffusionFactor[2] = 0.0f;
-}
-
-LLPartSysCompressedPacket::LLPartSysCompressedPacket()
-{
- // default constructor for mDefaults called implicitly/automatically here
- for(int i = 0; i < MAX_PART_SYS_PACKET_SIZE; i++)
- {
- mData[i] = '\0';
- }
-
- mNumBytes = 0;
-
- gSetInitDataDefaults(&mDefaults);
-}
-
-LLPartSysCompressedPacket::~LLPartSysCompressedPacket()
-{
- // no dynamic data is stored by this class, do nothing.
-}
-
-void LLPartSysCompressedPacket::writeFlagByte(LLPartInitData *in)
-{
- mData[0] = mData[1] = mData[2] = '\0';
-
- U32 i;
- //for(i = 1; i < 18; i++) {
- // if(in->k[i] != mDefaults.k[i])
- // {
- // mData[0] |= PART_SYS_K_MASK;
- // break;
- // }
- //}
-
- if(in->killPlaneZ != mDefaults.killPlaneZ ||
- in->killPlaneNormal[0] != mDefaults.killPlaneNormal[0] ||
- in->killPlaneNormal[1] != mDefaults.killPlaneNormal[1] ||
- in->killPlaneNormal[2] != mDefaults.killPlaneNormal[2] ||
- in->distanceDeath != mDefaults.distanceDeath)
- {
- mData[0] |= PART_SYS_KILL_P_MASK;
- }
-
-
-
- if(in->bouncePlaneZ != mDefaults.bouncePlaneZ ||
- in->bouncePlaneNormal[0] != mDefaults.bouncePlaneNormal[0] ||
- in->bouncePlaneNormal[1] != mDefaults.bouncePlaneNormal[1] ||
- in->bouncePlaneNormal[2] != mDefaults.bouncePlaneNormal[2])
- {
- mData[0] |= PART_SYS_BOUNCE_P_MASK;
- }
-
- if(in->bounce_b != mDefaults.bounce_b)
- {
- mData[0] |= PART_SYS_BOUNCE_B_MASK;
- }
-
-
- //if(in->pos_ranges[0] != mDefaults.pos_ranges[0] || in->pos_ranges[1] != mDefaults.pos_ranges[1] ||
- // in->pos_ranges[2] != mDefaults.pos_ranges[2] || in->pos_ranges[3] != mDefaults.pos_ranges[3] ||
- // in->pos_ranges[4] != mDefaults.pos_ranges[4] || in->pos_ranges[5] != mDefaults.pos_ranges[5])
- //{
- // mData[0] |= PART_SYS_POS_RANGES_MASK;
- //}
-
- //if(in->vel_ranges[0] != mDefaults.vel_ranges[0] || in->vel_ranges[1] != mDefaults.vel_ranges[1] ||
- // in->vel_ranges[2] != mDefaults.vel_ranges[2] || in->vel_ranges[3] != mDefaults.vel_ranges[3] ||
- // in->vel_ranges[4] != mDefaults.vel_ranges[4] || in->vel_ranges[5] != mDefaults.vel_ranges[5])
- //{
-// mData[0] |= PART_SYS_VEL_RANGES_MASK;
- //}
-
-
- if(in->diffEqAlpha[0] != mDefaults.diffEqAlpha[0] ||
- in->diffEqAlpha[1] != mDefaults.diffEqAlpha[1] ||
- in->diffEqAlpha[2] != mDefaults.diffEqAlpha[2] ||
- in->diffEqScale[0] != mDefaults.diffEqScale[0] ||
- in->diffEqScale[1] != mDefaults.diffEqScale[1] ||
- in->diffEqScale[2] != mDefaults.diffEqScale[2])
- {
- mData[0] |= PART_SYS_ALPHA_SCALE_DIFF_MASK;
- }
-
-
- if(in->scale_range[0] != mDefaults.scale_range[0] ||
- in->scale_range[1] != mDefaults.scale_range[1] ||
- in->scale_range[2] != mDefaults.scale_range[2] ||
- in->scale_range[3] != mDefaults.scale_range[3])
- {
- mData[0] |= PART_SYS_SCALE_RANGE_MASK;
- }
-
-
- if(in->alpha_range[0] != mDefaults.alpha_range[0] ||
- in->alpha_range[1] != mDefaults.alpha_range[1] ||
- in->alpha_range[2] != mDefaults.alpha_range[2] ||
- in->alpha_range[3] != mDefaults.alpha_range[3])
- {
- mData[2] |= PART_SYS_BYTE_3_ALPHA_MASK;
- }
-
- if(in->vel_offset[0] != mDefaults.vel_offset[0] ||
- in->vel_offset[1] != mDefaults.vel_offset[1] ||
- in->vel_offset[2] != mDefaults.vel_offset[2])
- {
- mData[0] |= PART_SYS_VEL_OFFSET_MASK;
- }
-
-
- if(in->mImageUuid != mDefaults.mImageUuid)
- {
- mData[0] |= PART_SYS_M_IMAGE_UUID_MASK;
- }
-
- for( i = 0; i < 8; i++)
- {
- if(in->mFlags[i])
- {
- mData[1] |= 1<<i;
-// llprintline("Flag \"%x\" gets byte \"%x\"\n", i<<i, in->mFlags[i]);
- }
- }
-
-
- if(in->spawnRange != mDefaults.spawnRange ||
- in->spawnFrequency != mDefaults.spawnFrequency ||
- in->spawnFreqencyRange != mDefaults.spawnFreqencyRange ||
- in->spawnDirection[0] != mDefaults.spawnDirection[0] ||
- in->spawnDirection[1] != mDefaults.spawnDirection[1] ||
- in->spawnDirection[2] != mDefaults.spawnDirection[2] ||
- in->spawnDirectionRange != mDefaults.spawnDirectionRange ||
- in->spawnVelocity != mDefaults.spawnVelocity ||
- in->spawnVelocityRange != mDefaults.spawnVelocityRange)
- {
- mData[3] |= PART_SYS_BYTE_SPAWN_MASK;
- }
-
-
- if(in->windWeight != mDefaults.windWeight ||
- in->currentGravity[0] != mDefaults.currentGravity[0] ||
- in->currentGravity[1] != mDefaults.currentGravity[1] ||
- in->currentGravity[2] != mDefaults.currentGravity[2] ||
- in->gravityWeight != mDefaults.gravityWeight)
- {
- mData[3] |= PART_SYS_BYTE_ENVIRONMENT_MASK;
- }
-
-
- if(in->globalLifetime != mDefaults.globalLifetime ||
- in->individualLifetime != mDefaults.individualLifetime ||
- in->individualLifetimeRange != mDefaults.individualLifetimeRange)
- {
- mData[3] |= PART_SYS_BYTE_LIFESPAN_MASK;
- }
-
-
- if(in->speedLimit != mDefaults.speedLimit ||
- in->alphaDecay != mDefaults.alphaDecay ||
- in->scaleDecay != mDefaults.scaleDecay ||
- in->dampMotionFactor != mDefaults.dampMotionFactor)
- {
- mData[3] |= PART_SYS_BYTE_DECAY_DAMP_MASK;
- }
-
- if(in->windDiffusionFactor[0] != mDefaults.windDiffusionFactor[0] ||
- in->windDiffusionFactor[1] != mDefaults.windDiffusionFactor[1] ||
- in->windDiffusionFactor[2] != mDefaults.windDiffusionFactor[2])
- {
- mData[3] |= PART_SYS_BYTE_WIND_DIFF_MASK;
- }
-}
-
-F32 floatFromTwoBytes(S8 bMant, S8 bExp)
-{
- F32 result = bMant;
- while(bExp > 0)
- {
- result *= 2.0f;
- bExp--;
- }
- while(bExp < 0)
- {
- result *= 0.5f;
- bExp++;
- }
- return result;
-}
-
-void twoBytesFromFloat(F32 fIn, S8 &bMant, S8 &bExp)
-{
- bExp = 0;
- if(fIn > 127.0f)
- {
- fIn = 127.0f;
- }
- if(fIn < -127.0f)
- {
- fIn = -127.0f;
- }
- while(fIn < 64 && fIn > -64 && bExp > -127)
- {
- fIn *= 2.0f;
- bExp--;
- }
- while((fIn > 128 || fIn < -128) && bExp < 127)
- {
- fIn *= 0.5f;
- bExp++;
- }
- bMant = (S8)fIn;
-}
-
-
-
-/*
-U32 LLPartSysCompressedPacket::writeK(LLPartInitData *in, U32 startByte)
-{
- U32 i, kFlag, i_mod_eight;
- S8 bMant, bExp;
-
- kFlag = startByte;
-
- startByte += 3; // 3 bytes contain enough room for 18 flag bits
- mData[kFlag] = 0x00;
-// llprintline("In the writeK\n");
-
- i_mod_eight = 0;
- for(i = 0; i < 18; i++)
- {
- if(in->k[i] != mDefaults.k[i])
- {
-
- mData[kFlag] |= 1<<i_mod_eight;
- twoBytesFromFloat(in->k[i], bMant, bExp);
-
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- }
- i_mod_eight++;
- while(i_mod_eight >= 8)
- {
- kFlag++;
- i_mod_eight -= 8;
- }
- }
-
- return startByte;
-}*/
-
-U32 LLPartSysCompressedPacket::writeKill_p(LLPartInitData *in, U32 startByte)
-{
- S8 bMant, bExp;
-
- twoBytesFromFloat(in->killPlaneNormal[0], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- twoBytesFromFloat(in->killPlaneNormal[1], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- twoBytesFromFloat(in->killPlaneNormal[2], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- twoBytesFromFloat(in->killPlaneZ, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- twoBytesFromFloat(in->distanceDeath, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::writeBounce_p(LLPartInitData *in, U32 startByte)
-{
- S8 bMant, bExp;
-
- twoBytesFromFloat(in->bouncePlaneNormal[0], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- twoBytesFromFloat(in->bouncePlaneNormal[1], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- twoBytesFromFloat(in->bouncePlaneNormal[2], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
-
- twoBytesFromFloat(in->bouncePlaneZ, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::writeBounce_b(LLPartInitData *in, U32 startByte)
-{
- S8 bMant, bExp;
- twoBytesFromFloat(in->bounce_b, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- return startByte;
-}
-
-//U32 LLPartSysCompressedPacket::writePos_ranges(LLPartInitData *in, U32 startByte)
-//{
-// S8 tmp;
-// int i;
-// for(i = 0; i < 6; i++)
-// {
-// tmp = (S8) in->pos_ranges[i]; // float to int conversion (keep the sign)
-// mData[startByte++] = (U8)tmp; // signed to unsigned typecast
-// }
-// return startByte;
-//}
-
-//U32 LLPartSysCompressedPacket::writeVel_ranges(LLPartInitData *in, U32 startByte)
-//{
-// S8 tmp;
-// int i;
-// for(i = 0; i < 6; i++)
-// {
-// tmp = (S8) in->vel_ranges[i]; // float to int conversion (keep the sign)
-// mData[startByte++] = (U8)tmp; // signed to unsigned typecast
-// }
-// return startByte;
-//}
-
-U32 LLPartSysCompressedPacket::writeAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte)
-{
- S8 bExp, bMant;
- int i;
- for(i = 0; i < 3; i++)
- {
- twoBytesFromFloat(in->diffEqAlpha[i], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- }
- for(i = 0; i < 3; i++)
- {
- twoBytesFromFloat(in->diffEqScale[i], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- }
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::writeScale_range(LLPartInitData *in, U32 startByte)
-{
- S8 bExp, bMant;
- int i;
- for(i = 0; i < 4; i++)
- {
- twoBytesFromFloat(in->scale_range[i], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- }
- return startByte;
-}
-
-
-U32 LLPartSysCompressedPacket::writeAlpha_range(LLPartInitData *in, U32 startByte)
-{
- S8 bExp, bMant;
- int i;
- for(i = 0; i < 4; i++)
- {
- twoBytesFromFloat(in->alpha_range[i], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- }
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::writeVelocityOffset(LLPartInitData *in, U32 startByte)
-{
- S8 bExp, bMant;
- int i;
- for(i = 0; i < 3; i++)
- {
- twoBytesFromFloat(in->vel_offset[i], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- }
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::writeUUID(LLPartInitData *in, U32 startByte)
-{
- U8 * bufPtr = mData + startByte;
- if(in->mImageUuid == IMG_SHOT) {
- mData[startByte++] = 0x01;
- return startByte;
- }
-
- if(in->mImageUuid == IMG_SPARK) {
- mData[startByte++] = 0x02;
- return startByte;
- }
-
-
- if(in->mImageUuid == IMG_BIG_EXPLOSION_1) {
- mData[startByte++] = 0x03;
- return startByte;
- }
-
- if(in->mImageUuid == IMG_BIG_EXPLOSION_2) {
- mData[startByte++] = 0x04;
- return startByte;
- }
-
-
- if(in->mImageUuid == IMG_SMOKE_POOF) {
- mData[startByte++] = 0x05;
- return startByte;
- }
-
- if(in->mImageUuid == IMG_FIRE) {
- mData[startByte++] = 0x06;
- return startByte;
- }
-
-
- if(in->mImageUuid == IMG_EXPLOSION) {
- mData[startByte++] = 0x07;
- return startByte;
- }
-
- if(in->mImageUuid == IMG_EXPLOSION_2) {
- mData[startByte++] = 0x08;
- return startByte;
- }
-
-
- if(in->mImageUuid == IMG_EXPLOSION_3) {
- mData[startByte++] = 0x09;
- return startByte;
- }
-
- if(in->mImageUuid == IMG_EXPLOSION_4) {
- mData[startByte++] = 0x0A;
- return startByte;
- }
-
- mData[startByte++] = 0x00; // flag for "read whole UUID"
-
- memcpy(bufPtr, in->mImageUuid.mData, 16); /* Flawfinder: ignore */
- return (startByte+16);
-}
-
-U32 LLPartSysCompressedPacket::writeSpawn(LLPartInitData *in, U32 startByte)
-{
- S8 bExp, bMant;
- int i;
-
- twoBytesFromFloat(in->spawnRange, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- twoBytesFromFloat(in->spawnFrequency, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- twoBytesFromFloat(in->spawnFreqencyRange, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
-
-
- for(i = 0; i < 3; i++)
- {
- twoBytesFromFloat(in->spawnDirection[i], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- }
-
- twoBytesFromFloat(in->spawnDirectionRange, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- twoBytesFromFloat(in->spawnVelocity, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- twoBytesFromFloat(in->spawnVelocityRange, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::writeEnvironment(LLPartInitData *in, U32 startByte)
-{
- S8 bExp, bMant;
- int i;
-
- twoBytesFromFloat(in->windWeight, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- for(i = 0; i < 3; i++)
- {
- twoBytesFromFloat(in->currentGravity[i], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- }
-
- twoBytesFromFloat(in->gravityWeight, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::writeLifespan(LLPartInitData *in, U32 startByte)
-{
- S8 bExp, bMant;
-
- twoBytesFromFloat(in->globalLifetime, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- twoBytesFromFloat(in->individualLifetime, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- twoBytesFromFloat(in->individualLifetimeRange, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- return startByte;
-}
-
-
-U32 LLPartSysCompressedPacket::writeDecayDamp(LLPartInitData *in, U32 startByte)
-{
- S8 bExp, bMant;
-
- twoBytesFromFloat(in->speedLimit, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- twoBytesFromFloat(in->alphaDecay, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- twoBytesFromFloat(in->scaleDecay, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- twoBytesFromFloat(in->dampMotionFactor, bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::writeWindDiffusionFactor(LLPartInitData *in, U32 startByte)
-{
- S8 bExp, bMant;
-
- twoBytesFromFloat(in->windDiffusionFactor[0], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- twoBytesFromFloat(in->windDiffusionFactor[1], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- twoBytesFromFloat(in->windDiffusionFactor[2], bMant, bExp);
- mData[startByte++] = bMant;
- mData[startByte++] = bExp;
-
- return startByte;
-}
-
-
-
-
-
-
-/*
-U32 LLPartSysCompressedPacket::readK(LLPartInitData *in, U32 startByte)
-{
- U32 i, i_mod_eight, kFlag;
- S8 bMant, bExp; // 1 bytes mantissa and exponent for a float
- kFlag = startByte;
- startByte += 3; // 3 bytes has enough room for 18 bits
-
- i_mod_eight = 0;
- for(i = 0; i < 18; i++)
- {
- if(mData[kFlag]&(1<<i_mod_eight))
- {
-
-
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
-
-
- in->k[i] = floatFromTwoBytes(bMant, bExp); // much tighter platform-independent
- // way to ship floats
-
- }
- i_mod_eight++;
- if(i_mod_eight >= 8)
- {
- i_mod_eight -= 8;
- kFlag++;
- }
- }
-
- return startByte;
-}
-*/
-
-U32 LLPartSysCompressedPacket::readKill_p(LLPartInitData *in, U32 startByte)
-{
- S8 bMant, bExp;
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->killPlaneNormal[0] = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->killPlaneNormal[1] = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->killPlaneNormal[2] = floatFromTwoBytes(bMant, bExp);
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->killPlaneZ = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->distanceDeath = floatFromTwoBytes(bMant, bExp);
-
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::readBounce_p(LLPartInitData *in, U32 startByte)
-{
-
- S8 bMant, bExp;
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->bouncePlaneNormal[0] = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->bouncePlaneNormal[1] = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->bouncePlaneNormal[2] = floatFromTwoBytes(bMant, bExp);
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->bouncePlaneZ = floatFromTwoBytes(bMant, bExp);
-
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::readBounce_b(LLPartInitData *in, U32 startByte)
-{
- S8 bMant, bExp;
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->bounce_b = floatFromTwoBytes(bMant, bExp);
- return startByte;
-}
-
-
-//U32 LLPartSysCompressedPacket::readPos_ranges(LLPartInitData *in, U32 startByte)
-//{
-// S8 tmp;
-// int i;
-// for(i = 0; i < 6; i++)
-// {
-// tmp = (S8)mData[startByte++];
-// in->pos_ranges[i] = tmp;
-// }
-// return startByte;
-//}
-
-//U32 LLPartSysCompressedPacket::readVel_ranges(LLPartInitData *in, U32 startByte)
-//{
-// S8 tmp;
-// int i;
-// for(i = 0; i < 6; i++)
-// {
-// tmp = (S8)mData[startByte++];
-// in->vel_ranges[i] = tmp;
-// }
-// return startByte;
-//}
-
-
-
-U32 LLPartSysCompressedPacket::readAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte)
-{
- int i;
- S8 bMant, bExp;
- for(i = 0; i < 3; i++)
- {
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->diffEqAlpha[i] = floatFromTwoBytes(bMant, bExp);
- }
- for(i = 0; i < 3; i++)
- {
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->diffEqScale[i] = floatFromTwoBytes(bMant, bExp);
- }
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::readAlpha_range(LLPartInitData *in, U32 startByte)
-{
- int i;
- S8 bMant, bExp;
- for(i = 0; i < 4; i++)
- {
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->alpha_range[i] = floatFromTwoBytes(bMant, bExp);
- }
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::readScale_range(LLPartInitData *in, U32 startByte)
-{
- int i;
- S8 bMant, bExp;
- for(i = 0; i < 4; i++)
- {
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->scale_range[i] = floatFromTwoBytes(bMant, bExp);
- }
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::readVelocityOffset(LLPartInitData *in, U32 startByte)
-{
- int i;
- S8 bMant, bExp;
- for(i = 0; i < 3; i++)
- {
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->vel_offset[i] = floatFromTwoBytes(bMant, bExp);
- }
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::readUUID(LLPartInitData *in, U32 startByte)
-{
- U8 * bufPtr = mData + startByte;
-
- if(mData[startByte] == 0x01)
- {
- in->mImageUuid = IMG_SHOT;
- return startByte+1;
- }
- if(mData[startByte] == 0x02)
- {
- in->mImageUuid = IMG_SPARK;
- return startByte+1;
- }
- if(mData[startByte] == 0x03)
- {
- in->mImageUuid = IMG_BIG_EXPLOSION_1;
- return startByte+1;
- }
- if(mData[startByte] == 0x04)
- {
- in->mImageUuid = IMG_BIG_EXPLOSION_2;
- return startByte+1;
- }
- if(mData[startByte] == 0x05)
- {
- in->mImageUuid = IMG_SMOKE_POOF;
- return startByte+1;
- }
- if(mData[startByte] == 0x06)
- {
- in->mImageUuid = IMG_FIRE;
- return startByte+1;
- }
- if(mData[startByte] == 0x07)
- {
- in->mImageUuid = IMG_EXPLOSION;
- return startByte+1;
- }
- if(mData[startByte] == 0x08)
- {
- in->mImageUuid = IMG_EXPLOSION_2;
- return startByte+1;
- }
- if(mData[startByte] == 0x09)
- {
- in->mImageUuid = IMG_EXPLOSION_3;
- return startByte+1;
- }
- if(mData[startByte] == 0x0A)
- {
- in->mImageUuid = IMG_EXPLOSION_4;
- return startByte+1;
- }
-
- startByte++; // cause we actually have to read the UUID now.
- memcpy(in->mImageUuid.mData, bufPtr, 16); /* Flawfinder: ignore */
- return (startByte+16);
-}
-
-
-
-
-U32 LLPartSysCompressedPacket::readSpawn(LLPartInitData *in, U32 startByte)
-{
- S8 bMant, bExp;
- U32 i;
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->spawnRange = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->spawnFrequency = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->spawnFreqencyRange = floatFromTwoBytes(bMant, bExp);
-
- for(i = 0; i < 3; i++)
- {
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->spawnDirection[i] = floatFromTwoBytes(bMant, bExp);
- }
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->spawnDirectionRange = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->spawnVelocity = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->spawnVelocityRange = floatFromTwoBytes(bMant, bExp);
-
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::readEnvironment(LLPartInitData *in, U32 startByte)
-{
- S8 bMant, bExp;
- U32 i;
-
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->windWeight = floatFromTwoBytes(bMant, bExp);
-
- for(i = 0; i < 3; i++)
- {
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->currentGravity[i] = floatFromTwoBytes(bMant, bExp);
- }
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->gravityWeight = floatFromTwoBytes(bMant, bExp);
-
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::readLifespan(LLPartInitData *in, U32 startByte)
-{
- S8 bMant, bExp;
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->globalLifetime = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->individualLifetime = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->individualLifetimeRange = floatFromTwoBytes(bMant, bExp);
-
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::readDecayDamp(LLPartInitData *in, U32 startByte)
-{
- S8 bMant, bExp;
-
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->speedLimit = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->alphaDecay = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->scaleDecay = floatFromTwoBytes(bMant, bExp);
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->dampMotionFactor = floatFromTwoBytes(bMant, bExp);
-
- return startByte;
-}
-
-U32 LLPartSysCompressedPacket::readWindDiffusionFactor(LLPartInitData *in, U32 startByte)
-{
- int i;
- S8 bMant, bExp;
- for(i = 0; i < 3; i++)
- {
- bMant = mData[startByte++];
- bExp = mData[startByte++];
- in->windDiffusionFactor[i] = floatFromTwoBytes(bMant, bExp);
- }
- return startByte;
-}
-
-bool LLPartSysCompressedPacket::fromLLPartInitData(LLPartInitData *in, U32 &bytesUsed)
-{
-
- writeFlagByte(in);
- U32 currByte = 4;
-
-// llprintline("calling \"fromLLPartInitData\"\n");
-
- //if(mData[0] & PART_SYS_K_MASK)
- //{
- // currByte = writeK(in, 3); // first 3 bytes are reserved for header data
- //}
-
-
-
- if(mData[0] & PART_SYS_KILL_P_MASK)
- {
- currByte = writeKill_p(in, currByte);
- }
-
- if(mData[0] & PART_SYS_BOUNCE_P_MASK)
- {
- currByte = writeBounce_p(in, currByte);
- }
-
- if(mData[0] & PART_SYS_BOUNCE_B_MASK)
- {
- currByte = writeBounce_b(in, currByte);
- }
-
- //if(mData[0] & PART_SYS_POS_RANGES_MASK)
- //{
- // currByte = writePos_ranges(in, currByte);
- //}
-
- //if(mData[0] & PART_SYS_VEL_RANGES_MASK)
- //{
- // currByte = writeVel_ranges(in, currByte);
- //}
-
- if(mData[0] & PART_SYS_ALPHA_SCALE_DIFF_MASK)
- {
- currByte = writeAlphaScaleDiffEqn_range(in, currByte);
- }
-
- if(mData[0] & PART_SYS_SCALE_RANGE_MASK)
- {
- currByte = writeScale_range(in, currByte);
- }
-
- if(mData[0] & PART_SYS_VEL_OFFSET_MASK)
- {
- currByte = writeVelocityOffset(in, currByte);
- }
-
- if(mData[0] & PART_SYS_M_IMAGE_UUID_MASK)
- {
- currByte = writeUUID(in, currByte);
- }
-
-
- if(mData[3] & PART_SYS_BYTE_SPAWN_MASK)
- {
- currByte = writeSpawn(in, currByte);
- }
-
- if(mData[3] & PART_SYS_BYTE_ENVIRONMENT_MASK)
- {
- currByte = writeEnvironment(in, currByte);
- }
-
- if(mData[3] & PART_SYS_BYTE_LIFESPAN_MASK)
- {
- currByte = writeLifespan(in, currByte);
- }
-
- if(mData[3] & PART_SYS_BYTE_DECAY_DAMP_MASK)
- {
- currByte = writeDecayDamp(in, currByte);
- }
-
- if(mData[3] & PART_SYS_BYTE_WIND_DIFF_MASK)
- {
- currByte = writeWindDiffusionFactor(in, currByte);
- }
-
-
- if(mData[2] & PART_SYS_BYTE_3_ALPHA_MASK)
- {
- currByte = writeAlpha_range(in, currByte);
- }
-
- mData[currByte++] = (U8)in->maxParticles;
- mData[currByte++] = (U8)in->initialParticles;
-
-
- U32 flagFlag = 1; // flag indicating which flag bytes are non-zero
- // yeah, I know, the name sounds funny
- for(U32 i = 0; i < 8; i++)
- {
-
-// llprintline("Flag \"%x\" gets byte \"%x\"\n", flagFlag, in->mFlags[i]);
- if(mData[1] & flagFlag)
- {
- mData[currByte++] = in->mFlags[i];
-// llprintline("and is valid...\n");
- }
- flagFlag <<= 1;
- }
-
- bytesUsed = mNumBytes = currByte;
-
-
-
-// llprintline("returning from \"fromLLPartInitData\" with %d bytes\n", bytesUsed);
-
- return true;
-}
-
-bool LLPartSysCompressedPacket::toLLPartInitData(LLPartInitData *out, U32 *bytesUsed)
-{
- U32 currByte = 4;
-
- gSetInitDataDefaults(out);
-
- if(mData[0] & PART_SYS_KILL_P_MASK)
- {
- currByte = readKill_p(out, currByte);
- }
-
- if(mData[0] & PART_SYS_BOUNCE_P_MASK)
- {
- currByte = readBounce_p(out, currByte);
- }
-
- if(mData[0] & PART_SYS_BOUNCE_B_MASK)
- {
- currByte = readBounce_b(out, currByte);
- }
-
- if(mData[0] & PART_SYS_ALPHA_SCALE_DIFF_MASK)
- {
- currByte = readAlphaScaleDiffEqn_range(out, currByte);
- }
-
- if(mData[0] & PART_SYS_SCALE_RANGE_MASK)
- {
- currByte = readScale_range(out, currByte);
- }
-
- if(mData[0] & PART_SYS_VEL_OFFSET_MASK)
- {
- currByte = readVelocityOffset(out, currByte);
- }
-
- if(mData[0] & PART_SYS_M_IMAGE_UUID_MASK)
- {
- currByte = readUUID(out, currByte);
- }
-
-
- if(mData[3] & PART_SYS_BYTE_SPAWN_MASK)
- {
- currByte = readSpawn(out, currByte);
- }
-
- if(mData[3] & PART_SYS_BYTE_ENVIRONMENT_MASK)
- {
- currByte = readEnvironment(out, currByte);
- }
-
- if(mData[3] & PART_SYS_BYTE_LIFESPAN_MASK)
- {
- currByte = readLifespan(out, currByte);
- }
-
- if(mData[3] & PART_SYS_BYTE_DECAY_DAMP_MASK)
- {
- currByte = readDecayDamp(out, currByte);
- }
-
- if(mData[3] & PART_SYS_BYTE_WIND_DIFF_MASK)
- {
- currByte = readWindDiffusionFactor(out, currByte);
- }
-
- if(mData[2] & PART_SYS_BYTE_3_ALPHA_MASK)
- {
- currByte = readAlpha_range(out, currByte);
- }
-
- out->maxParticles = mData[currByte++];
- out->initialParticles = mData[currByte++];
-
- U32 flagFlag = 1; // flag indicating which flag bytes are non-zero
- // yeah, I know, the name sounds funny
- for(U32 i = 0; i < 8; i++)
- {
- flagFlag = 1<<i;
-
- if((mData[1] & flagFlag))
- {
- out->mFlags[i] = mData[currByte++];
- }
- }
-
- *bytesUsed = currByte;
- return true;
-}
-
-bool LLPartSysCompressedPacket::fromUnsignedBytes(U8 *in, U32 bytesUsed)
-{
- if ((in != NULL) && (bytesUsed <= sizeof(mData)))
- {
- memcpy(mData, in, bytesUsed); /* Flawfinder: ignore */
- mNumBytes = bytesUsed;
- return true;
- }
- else
- {
- LL_ERRS() << "NULL input data or number of bytes exceed mData size" << LL_ENDL;
- return false;
- }
-}
-
-
-U32 LLPartSysCompressedPacket::bufferSize()
-{
- return mNumBytes;
-}
-
-bool LLPartSysCompressedPacket::toUnsignedBytes(U8 *out)
-{
- memcpy(out, mData, mNumBytes); /* Flawfinder: ignore */
- return true;
-}
-
-U8 * LLPartSysCompressedPacket::getBytePtr()
-{
- return mData;
-}
-
-
diff --git a/indra/llmessage/partsyspacket.h b/indra/llmessage/partsyspacket.h
deleted file mode 100644
index 23307f3409..0000000000
--- a/indra/llmessage/partsyspacket.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/**
- * @file partsyspacket.h
- * @brief Object for packing particle system initialization parameters
- * before sending them over the network
- *
- * $LicenseInfo:firstyear=2000&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_PARTSYSPACKET_H
-#define LL_PARTSYSPACKET_H
-
-#include "lluuid.h"
-
-// Particle system stuff
-
-const U64 PART_SYS_MAX_TIME_IN_USEC = 1000000; // 1 second, die not quite near instantaneously
-
-
-// this struct is for particle system initialization parameters
-// I'm breaking some rules here, but I need a storage structure to hold initialization data
-// for these things. Sorry guys, they're not simple enough (yet) to avoid this cleanly
-struct LLPartInitData {
- // please do not add functions to this class -- data only!
- //F32 k[18]; // first 9 --> x,y,z last 9 --> scale, alpha, rot
- //F32 kill_p[6]; // last one is for particles that die when they reach a spherical bounding radius
- //F32 kill_plane[3];
- //F32 bounce_p[5];
- F32 bounce_b; // recently changed
- // no need to store orientation and position here, as they're sent over seperately
- //F32 pos_ranges[6];
- //F32 vel_ranges[6];
- F32 scale_range[4];
- F32 alpha_range[4];
- F32 vel_offset[3]; //new - more understandable!
-
- F32 mDistBeginFadeout; // for fadeout LOD optimization
- F32 mDistEndFadeout;
-
- LLUUID mImageUuid;
- //U8 n; // number of particles
- U8 mFlags[8]; // for miscellaneous data --> its interpretation can change at my whim!
- U8 createMe; // do I need to be created? or has the work allready been done?
- //ActionFlag is now mFlags[PART_SYS_ACTION_BYTE]
- //Spawn point is initially object creation center
-
- F32 diffEqAlpha[3];
- F32 diffEqScale[3];
-
- U8 maxParticles;
- //How many particles exist at any time within the system?
- U8 initialParticles;
- //How many particles exist when the system is created?
- F32 killPlaneZ;
- //For simplicity assume the XY plane, so this sets an altitude at which to die
- F32 killPlaneNormal[3];
- //Normal if not planar XY
- F32 bouncePlaneZ;
- //For simplicity assume the XY plane, so this sets an altitude at which to bounce
- F32 bouncePlaneNormal[3];
- //Normal if not planar XY
- F32 spawnRange;
- //Range of emission points about the mSpawnPoint
- F32 spawnFrequency;
- //Required if the system is to spawn new particles.
- //This variable determines the time after a particle dies when it is respawned.
- F32 spawnFreqencyRange;
- //Determines the random range of time until a new particle is spawned.
- F32 spawnDirection[3];
- //Direction vector giving the mean direction in which particles are spawned
- F32 spawnDirectionRange;
- //Direction limiting the angular range of emissions about the mean direction. 1.0f means everywhere, 0.0f means uni-directional
- F32 spawnVelocity;
- //The mean speed at which particles are emitted
- F32 spawnVelocityRange;
- //The range of speeds about the mean at which particles are emitted.
- F32 speedLimit;
- //Used to constrain particle maximum velocity
- F32 windWeight;
- //How much of an effect does wind have
- F32 currentGravity[3];
- //Gravity direction used in update calculations
- F32 gravityWeight;
- //How much of an effect does gravity have
- F32 globalLifetime;
- //If particles re-spawn, a system can exist forever.
- //If (ActionFlags & PART_SYS_GLOBAL_DIE) is true this variable is used to determine how long the system lasts.
- F32 individualLifetime;
- //How long does each particle last if nothing else happens to it
- F32 individualLifetimeRange;
- //Range of variation in individual lifetimes
- F32 alphaDecay;
- //By what factor does alpha decrease as the lifetime of a particle is approached.
- F32 scaleDecay;
- //By what factor does scale decrease as the lifetime of a particle is approached.
- F32 distanceDeath;
- //With the increased functionality, particle systems can expand to indefinite size
- //(e.g. wind can chaotically move particles into a wide spread).
- //To avoid particles exceeding normal object size constraints,
- //set the PART_SYS_DISTANCE_DEATH flag, and set a distance value here, representing a radius around the spawn point.
- F32 dampMotionFactor;
- //How much to damp motion
- F32 windDiffusionFactor[3];
- //Change the size and alpha of particles as wind speed increases (scale gets bigger, alpha smaller)
-};
-
-// constants for setting flag values
-// BYTES are in range 0-8, bits are in range 2^0 - 2^8 and can only be powers of two
-const int PART_SYS_NO_Z_BUFFER_BYTE = 0; // option to turn off z-buffer when rendering
-const int PART_SYS_NO_Z_BUFFER_BIT = 2; // particle systems --
-// I advise against using this, as it looks bad in every case I've tried
-
-const int PART_SYS_SLOW_ANIM_BYTE = 0; // slow animation down by a factor of 10
-const int PART_SYS_SLOW_ANIM_BIT = 1; // useful for tweaking anims during debugging
-
-const int PART_SYS_FOLLOW_VEL_BYTE = 0; // indicates whether to orient sprites towards
-const int PART_SYS_FOLLOW_VEL_BIT = 4; // their velocity vector -- default is false
-
-const int PART_SYS_IS_LIGHT_BYTE = 0; // indicates whether a particular particle system
-const int PART_SYS_IS_LIGHT_BIT = 8; // is also a light object -- for andrew
-// should deprecate this once there is a general method for setting light properties of objects
-
-const int PART_SYS_SPAWN_COPY_BYTE = 0; // indicates whether to spawn baby particle systems on
-const int PART_SYS_SPAWN_COPY_BIT = 0x10; // particle death -- intended for smoke trails
-
-const int PART_SYS_COPY_VEL_BYTE = 0; // indicates whether baby particle systems inherit parents vel
-const int PART_SYS_COPY_VEL_BIT = 0x20; // (by default they don't)
-
-const int PART_SYS_INVISIBLE_BYTE = 0; // optional -- turn off display, just simulate
-const int PART_SYS_INVISIBLE_BIT = 0x40; // useful for smoke trails
-
-const int PART_SYS_ADAPT_TO_FRAMERATE_BYTE = 0; // drop sprites from render call proportionally
-const int PART_SYS_ADAPT_TO_FRAMERATE_BIT = 0x80; // to how far we are below 60 fps
-
-
-// 26 September 2001 - not even big enough to hold all changes, so should enlarge anyway
-//const U16 MAX_PART_SYS_PACKET_SIZE = 180;
-const U16 MAX_PART_SYS_PACKET_SIZE = 256;
-
-//const U8 PART_SYS_K_MASK = 0x01;
-const U8 PART_SYS_KILL_P_MASK = 0x02;
-const U8 PART_SYS_BOUNCE_P_MASK = 0x04;
-const U8 PART_SYS_BOUNCE_B_MASK = 0x08;
-//const U8 PART_SYS_POS_RANGES_MASK = 0x10;
-//const U8 PART_SYS_VEL_RANGES_MASK = 0x20;
-const U8 PART_SYS_VEL_OFFSET_MASK = 0x10; //re-use one of the original slots now commented out
-const U8 PART_SYS_ALPHA_SCALE_DIFF_MASK = 0x20; //re-use one of the original slots now commented out
-const U8 PART_SYS_SCALE_RANGE_MASK = 0x40;
-const U8 PART_SYS_M_IMAGE_UUID_MASK = 0x80;
-const U8 PART_SYS_BYTE_3_ALPHA_MASK = 0x01; // wrapped around, didn't we?
-
-const U8 PART_SYS_BYTE_SPAWN_MASK = 0x01;
-const U8 PART_SYS_BYTE_ENVIRONMENT_MASK = 0x02;
-const U8 PART_SYS_BYTE_LIFESPAN_MASK = 0x04;
-const U8 PART_SYS_BYTE_DECAY_DAMP_MASK = 0x08;
-const U8 PART_SYS_BYTE_WIND_DIFF_MASK = 0x10;
-
-
-// 26 September 2001 - new constants for mActionFlags
-const int PART_SYS_ACTION_BYTE = 1;
-const U8 PART_SYS_SPAWN = 0x01;
-const U8 PART_SYS_BOUNCE = 0x02;
-const U8 PART_SYS_AFFECTED_BY_WIND = 0x04;
-const U8 PART_SYS_AFFECTED_BY_GRAVITY = 0x08;
-const U8 PART_SYS_EVALUATE_WIND_PER_PARTICLE = 0x10;
-const U8 PART_SYS_DAMP_MOTION = 0x20;
-const U8 PART_SYS_WIND_DIFFUSION = 0x40;
-
-// 26 September 2001 - new constants for mKillFlags
-const int PART_SYS_KILL_BYTE = 2;
-const U8 PART_SYS_KILL_PLANE = 0x01;
-const U8 PART_SYS_GLOBAL_DIE = 0x02;
-const U8 PART_SYS_DISTANCE_DEATH = 0x04;
-const U8 PART_SYS_TIME_DEATH = 0x08;
-
-
-// global, because the sim-side also calls it in the LLPartInitDataFactory
-
-
-void gSetInitDataDefaults(LLPartInitData *setMe);
-
-class LLPartSysCompressedPacket
-{
-public:
- LLPartSysCompressedPacket();
- ~LLPartSysCompressedPacket();
- bool fromLLPartInitData(LLPartInitData *in, U32 &bytesUsed);
- bool toLLPartInitData(LLPartInitData *out, U32 *bytesUsed);
- bool fromUnsignedBytes(U8 *in, U32 bytesUsed);
- bool toUnsignedBytes(U8 *out);
- U32 bufferSize();
- U8 *getBytePtr();
-
-protected:
- U8 mData[MAX_PART_SYS_PACKET_SIZE];
- U32 mNumBytes;
- LLPartInitData mDefaults; // this is intended to hold default LLPartInitData values
- // please do not modify it
- LLPartInitData mWorkingCopy; // uncompressed data I'm working with
-
-protected:
- // private functions (used only to break up code)
- void writeFlagByte(LLPartInitData *in);
- //U32 writeK(LLPartInitData *in, U32 startByte);
- U32 writeKill_p(LLPartInitData *in, U32 startByte);
- U32 writeBounce_p(LLPartInitData *in, U32 startByte);
- U32 writeBounce_b(LLPartInitData *in, U32 startByte);
- //U32 writePos_ranges(LLPartInitData *in, U32 startByte);
- //U32 writeVel_ranges(LLPartInitData *in, U32 startByte);
- U32 writeAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte);
- U32 writeScale_range(LLPartInitData *in, U32 startByte);
- U32 writeAlpha_range(LLPartInitData *in, U32 startByte);
- U32 writeUUID(LLPartInitData *in, U32 startByte);
-
- U32 writeVelocityOffset(LLPartInitData *in, U32 startByte);
- U32 writeSpawn(LLPartInitData *in, U32 startByte); //all spawn data
- U32 writeEnvironment(LLPartInitData *in, U32 startByte); //wind and gravity
- U32 writeLifespan(LLPartInitData *in, U32 startByte); //lifespan data - individual and global
- U32 writeDecayDamp(LLPartInitData *in, U32 startByte); //alpha and scale, and motion damp
- U32 writeWindDiffusionFactor(LLPartInitData *in, U32 startByte);
-
-
- //U32 readK(LLPartInitData *in, U32 startByte);
- U32 readKill_p(LLPartInitData *in, U32 startByte);
- U32 readBounce_p(LLPartInitData *in, U32 startByte);
- U32 readBounce_b(LLPartInitData *in, U32 startByte);
- //U32 readPos_ranges(LLPartInitData *in, U32 startByte);
- //U32 readVel_ranges(LLPartInitData *in, U32 startByte);
- U32 readAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte);
- U32 readScale_range(LLPartInitData *in, U32 startByte);
- U32 readAlpha_range(LLPartInitData *in, U32 startByte);
- U32 readUUID(LLPartInitData *in, U32 startByte);
-
- U32 readVelocityOffset(LLPartInitData *in, U32 startByte);
- U32 readSpawn(LLPartInitData *in, U32 startByte); //all spawn data
- U32 readEnvironment(LLPartInitData *in, U32 startByte); //wind and gravity
- U32 readLifespan(LLPartInitData *in, U32 startByte); //lifespan data - individual and global
- U32 readDecayDamp(LLPartInitData *in, U32 startByte); //alpha and scale, and motion damp
- U32 readWindDiffusionFactor(LLPartInitData *in, U32 startByte);
-};
-
-#endif
-
diff --git a/indra/test/io.cpp b/indra/llmessage/tests/io_test.cpp
index f77402065a..f77402065a 100644
--- a/indra/test/io.cpp
+++ b/indra/llmessage/tests/io_test.cpp
diff --git a/indra/test/llbuffer_tut.cpp b/indra/llmessage/tests/llbuffer_test.cpp
index 330a4f288f..330a4f288f 100644
--- a/indra/test/llbuffer_tut.cpp
+++ b/indra/llmessage/tests/llbuffer_test.cpp
diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp
deleted file mode 100644
index 78c195580c..0000000000
--- a/indra/llmessage/tests/llcurl_stub.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * @file llcurl_stub.cpp
- * @brief stub class to allow unit testing
- *
- * $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 LL_CURL_STUB_CPP
-#define LL_CURL_STUB_CPP
-
-
-#include "linden_common.h"
-#include "llcurl.h"
-#include "llhttpconstants.cpp"
-
-LLCurl::Responder::Responder()
-{
-}
-
-void LLCurl::Responder::httpCompleted()
-{
- if (isGoodStatus())
- {
- httpSuccess();
- }
- else
- {
- httpFailure();
- }
-}
-
-void LLCurl::Responder::completedRaw(LLChannelDescriptors const&,
- std::shared_ptr<LLBufferArray> const&)
-{
-}
-
-void LLCurl::Responder::httpFailure()
-{
-}
-
-LLCurl::Responder::~Responder ()
-{
-}
-
-void LLCurl::Responder::httpSuccess()
-{
-}
-
-std::string LLCurl::Responder::dumpResponse() const
-{
- return "dumpResponse()";
-}
-
-void LLCurl::Responder::successResult(const LLSD& content)
-{
- setResult(HTTP_OK, "", content);
- httpSuccess();
-}
-
-void LLCurl::Responder::failureResult(S32 status, const std::string& reason, const LLSD& content)
-{
- setResult(status, reason, content);
- httpFailure();
-}
-
-
-void LLCurl::Responder::completeResult(S32 status, const std::string& reason, const LLSD& content)
-{
- setResult(status, reason, content);
- httpCompleted();
-}
-
-void LLCurl::Responder::setResult(S32 status, const std::string& reason, const LLSD& content /* = LLSD() */)
-{
- mStatus = status;
- mReason = reason;
- mContent = content;
-}
-
-#endif
diff --git a/indra/test/lldatapacker_tut.cpp b/indra/llmessage/tests/lldatapacker_test.cpp
index 5aa5233806..e4253ab140 100644
--- a/indra/test/lldatapacker_tut.cpp
+++ b/indra/llmessage/tests/lldatapacker_test.cpp
@@ -26,9 +26,10 @@
* $/LicenseInfo$
*/
-#include <tut/tut.hpp>
-#include "lltut.h"
#include "linden_common.h"
+
+#include "lltut.h"
+
#include "lldatapacker.h"
#include "v4color.h"
#include "v4coloru.h"
@@ -38,6 +39,7 @@
#include "llsdserialize.h"
#define TEST_FILE_NAME "datapacker_test.txt"
+
namespace tut
{
struct datapacker_test
@@ -188,11 +190,11 @@ namespace tut
template<> template<>
void datapacker_test_object_t::test<5>()
{
- U8 buf[] = "SecondLife is virtual World";
+ U8* buf = new U8[]("SecondLife is virtual World");
S32 size = sizeof(buf);
LLDataPackerBinaryBuffer lldp(buf, size);
- U8 new_buf[] = "Its Amazing";
- size = sizeof(new_buf);
+ U8* new_buf = new U8[]("Its Amazing");
+ size = sizeof(new_buf)-1;
lldp.assignBuffer(new_buf, size);
ensure("LLDataPackerBinaryBuffer::assignBuffer failed" , ((lldp.getBufferSize() == size) && (0 == lldp.getCurrentSize()))) ;
}
@@ -346,7 +348,7 @@ namespace tut
{
F32 f_val = 44.44f, f_unpkval;
- LLFILE* fp = LLFile::fopen(TEST_FILE_NAME, "w+");
+ LLFILE* fp = LLFile::fopen(TEST_FILE_NAME, LLFILE_MODE("w+"));
if(!fp)
{
LL_ERRS() << "File couldnt be open" << LL_ENDL;
@@ -401,7 +403,7 @@ namespace tut
LLVector4 unpkllvec4;
LLUUID unpkuuid;
- LLFILE* fp = LLFile::fopen(TEST_FILE_NAME,"w+");
+ LLFILE* fp = LLFile::fopen(TEST_FILE_NAME, LLFILE_MODE("w+"));
if(!fp)
{
LL_ERRS() << "File couldnt be open" << LL_ENDL;
diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
deleted file mode 100644
index 1881144d3e..0000000000
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/**
- * @file llhttpclient_test.cpp
- * @brief Testing the HTTP client classes.
- *
- * $LicenseInfo:firstyear=2006&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$
- */
-
-/**
- *
- * These classes test the HTTP client framework.
- *
- */
-
-#include <tut/tut.hpp>
-#include "linden_common.h"
-
-#include "lltut.h"
-#include "llhttpclient.h"
-#include "llformat.h"
-#include "llpipeutil.h"
-#include "llproxy.h"
-#include "llpumpio.h"
-
-#include "lliosocket.h"
-#include "llstring.h"
-#include "stringize.h"
-#include "llcleanup.h"
-
-namespace tut
-{
- struct HTTPClientTestData
- {
- public:
- HTTPClientTestData():
- PORT(LLStringUtil::getenv("PORT")),
- // Turning NULL PORT into empty string doesn't make things work;
- // that's just to keep this initializer from blowing up. We test
- // PORT separately in the constructor body.
- local_server(STRINGIZE("http://127.0.0.1:" << PORT << "/"))
- {
- ensure("Set environment variable PORT to local test server port", !PORT.empty());
- apr_pool_create(&mPool, NULL);
- LLCurl::initClass(false);
- mClientPump = new LLPumpIO(mPool);
-
- LLHTTPClient::setPump(*mClientPump);
- }
-
- ~HTTPClientTestData()
- {
- delete mClientPump;
- SUBSYSTEM_CLEANUP(LLProxy);
- apr_pool_destroy(mPool);
- }
-
- void runThePump(float timeout = 100.0f)
- {
- LLTimer timer;
- timer.setTimerExpirySec(timeout);
-
- while(!mSawCompleted && !mSawCompletedHeader && !timer.hasExpired())
- {
- LLFrameTimer::updateFrameTime();
- if (mClientPump)
- {
- mClientPump->pump();
- mClientPump->callback();
- }
- }
- }
-
- const std::string PORT;
- const std::string local_server;
-
- private:
- apr_pool_t* mPool;
- LLPumpIO* mClientPump;
-
- protected:
- void ensureStatusOK()
- {
- if (mSawError)
- {
- std::string msg =
- llformat("httpFailure() called when not expected, status %d",
- mStatus);
- fail(msg);
- }
- }
-
- void ensureStatusError()
- {
- if (!mSawError)
- {
- fail("httpFailure() wasn't called");
- }
- }
-
- LLSD getResult()
- {
- return mResult;
- }
- LLSD getHeader()
- {
- return mHeader;
- }
-
- protected:
- bool mSawError;
- U32 mStatus;
- std::string mReason;
- bool mSawCompleted;
- bool mSawCompletedHeader;
- LLSD mResult;
- LLSD mHeader;
- bool mResultDeleted;
-
- class Result : public LLHTTPClient::Responder
- {
- protected:
- Result(HTTPClientTestData& client)
- : mClient(client)
- {
- }
-
- public:
- static Result* build(HTTPClientTestData& client)
- {
- return new Result(client);
- }
-
- ~Result()
- {
- mClient.mResultDeleted = true;
- }
-
- protected:
- virtual void httpFailure()
- {
- mClient.mSawError = true;
- mClient.mStatus = getStatus();
- mClient.mReason = getReason();
- }
-
- virtual void httpSuccess()
- {
- mClient.mResult = getContent();
- }
-
- virtual void httpCompleted()
- {
- LLHTTPClient::Responder::httpCompleted();
-
- mClient.mSawCompleted = true;
- mClient.mSawCompletedHeader = true;
- mClient.mHeader = getResponseHeaders();
- }
-
- private:
- HTTPClientTestData& mClient;
- };
-
- friend class Result;
-
- protected:
- LLHTTPClient::ResponderPtr newResult()
- {
- mSawError = false;
- mStatus = 0;
- mSawCompleted = false;
- mSawCompletedHeader = false;
- mResult.clear();
- mHeader.clear();
- mResultDeleted = false;
-
- return Result::build(*this);
- }
- };
-
-
- typedef test_group<HTTPClientTestData> HTTPClientTestGroup;
- typedef HTTPClientTestGroup::object HTTPClientTestObject;
- HTTPClientTestGroup httpClientTestGroup("http_client");
-
- template<> template<>
- void HTTPClientTestObject::test<1>()
- {
- LLHTTPClient::get(local_server, newResult());
- runThePump();
- ensureStatusOK();
- ensure("result object wasn't destroyed", mResultDeleted);
- }
-
- template<> template<>
- void HTTPClientTestObject::test<2>()
- {
- // Please nobody listen on this particular port...
- LLHTTPClient::get("http://127.0.0.1:7950", newResult());
- runThePump();
- ensureStatusError();
- }
-
- template<> template<>
- void HTTPClientTestObject::test<3>()
- {
- LLSD sd;
-
- sd["list"][0]["one"] = 1;
- sd["list"][0]["two"] = 2;
- sd["list"][1]["three"] = 3;
- sd["list"][1]["four"] = 4;
-
- LLHTTPClient::post(local_server + "web/echo", sd, newResult());
- runThePump();
- ensureStatusOK();
- ensure_equals("echoed result matches", getResult(), sd);
- }
-
- template<> template<>
- void HTTPClientTestObject::test<4>()
- {
- LLSD sd;
-
- sd["message"] = "This is my test message.";
-
- LLHTTPClient::put(local_server + "test/storage", sd, newResult());
- runThePump();
- ensureStatusOK();
-
- LLHTTPClient::get(local_server + "test/storage", newResult());
- runThePump();
- ensureStatusOK();
- ensure_equals("echoed result matches", getResult(), sd);
-
- }
-
- template<> template<>
- void HTTPClientTestObject::test<5>()
- {
- LLSD sd;
- sd["status"] = 543;
- sd["reason"] = "error for testing";
-
- LLHTTPClient::post(local_server + "test/error", sd, newResult());
- runThePump();
- ensureStatusError();
- ensure_contains("reason", mReason, sd["reason"]);
- }
-
- template<> template<>
- void HTTPClientTestObject::test<6>()
- {
- const F32 timeout = 1.0f;
- LLHTTPClient::get(local_server + "test/timeout", newResult(), LLSD(), timeout);
- runThePump(timeout * 5.0f);
- ensureStatusError();
- ensure_equals("reason", mReason, "STATUS_EXPIRED");
- }
-
- template<> template<>
- void HTTPClientTestObject::test<7>()
- {
- LLHTTPClient::get(local_server, newResult());
- runThePump();
- ensureStatusOK();
- LLSD expected = getResult();
-
- LLSD result;
- result = LLHTTPClient::blockingGet(local_server);
- LLSD body = result["body"];
- ensure_equals("echoed result matches", body.size(), expected.size());
- }
- template<> template<>
- void HTTPClientTestObject::test<8>()
- {
- // This is testing for the presence of the Header in the returned results
- // from an HTTP::get call.
- LLHTTPClient::get(local_server, newResult());
- runThePump();
- ensureStatusOK();
- LLSD header = getHeader();
- ensure("got a header", ! header.emptyMap().asBoolean());
- }
- template<> template<>
- void HTTPClientTestObject::test<9>()
- {
- LLHTTPClient::head(local_server, newResult());
- runThePump();
- ensureStatusOK();
- ensure("result object wasn't destroyed", mResultDeleted);
- }
-}
diff --git a/indra/test/llhttpnode_tut.cpp b/indra/llmessage/tests/llhttpnode_test.cpp
index c38dee120b..c38dee120b 100644
--- a/indra/test/llhttpnode_tut.cpp
+++ b/indra/llmessage/tests/llhttpnode_test.cpp
diff --git a/indra/test/lliohttpserver_tut.cpp b/indra/llmessage/tests/lliohttpserver_test.cpp
index 7034f4a063..7034f4a063 100644
--- a/indra/test/lliohttpserver_tut.cpp
+++ b/indra/llmessage/tests/lliohttpserver_test.cpp
diff --git a/indra/test/llmessageconfig_tut.cpp b/indra/llmessage/tests/llmessageconfig_test.cpp
index 93443467a2..b8942e99b3 100644
--- a/indra/test/llmessageconfig_tut.cpp
+++ b/indra/llmessage/tests/llmessageconfig_test.cpp
@@ -62,7 +62,7 @@ namespace tut
int rmfile = LLFile::remove((mTestConfigDir + "/message.xml"));
ensure_equals("rmfile value", rmfile, 0);
// rm temp dir
- int rmdir = LLFile::rmdir(mTestConfigDir);
+ int rmdir = LLFile::remove(mTestConfigDir);
ensure_equals("rmdir value", rmdir, 0);
}
diff --git a/indra/test/llmessagetemplateparser_tut.cpp b/indra/llmessage/tests/llmessagetemplateparser_test.cpp
index f665fdde4d..f665fdde4d 100644
--- a/indra/test/llmessagetemplateparser_tut.cpp
+++ b/indra/llmessage/tests/llmessagetemplateparser_test.cpp
diff --git a/indra/test/llpipeutil.cpp b/indra/llmessage/tests/llpipeutil.cpp
index 1dd4bdfa3c..1dd4bdfa3c 100644
--- a/indra/test/llpipeutil.cpp
+++ b/indra/llmessage/tests/llpipeutil.cpp
diff --git a/indra/test/llpipeutil.h b/indra/llmessage/tests/llpipeutil.h
index 97d9e1c85c..97d9e1c85c 100644
--- a/indra/test/llpipeutil.h
+++ b/indra/llmessage/tests/llpipeutil.h
diff --git a/indra/test/llsdmessagebuilder_tut.cpp b/indra/llmessage/tests/llsdmessagebuilder_test.cpp
index 6804c3e29e..6804c3e29e 100644
--- a/indra/test/llsdmessagebuilder_tut.cpp
+++ b/indra/llmessage/tests/llsdmessagebuilder_test.cpp
diff --git a/indra/test/llsdmessagereader_tut.cpp b/indra/llmessage/tests/llsdmessagereader_test.cpp
index dd6520ea33..dd6520ea33 100644
--- a/indra/test/llsdmessagereader_tut.cpp
+++ b/indra/llmessage/tests/llsdmessagereader_test.cpp
diff --git a/indra/test/llservicebuilder_tut.cpp b/indra/llmessage/tests/llservicebuilder_test.cpp
index 0bc17865d6..0bc17865d6 100644
--- a/indra/test/llservicebuilder_tut.cpp
+++ b/indra/llmessage/tests/llservicebuilder_test.cpp
diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/llmessage/tests/lltemplatemessagebuilder_test.cpp
index ddf1c3dbcc..ddf1c3dbcc 100644
--- a/indra/test/lltemplatemessagebuilder_tut.cpp
+++ b/indra/llmessage/tests/lltemplatemessagebuilder_test.cpp
diff --git a/indra/test/llxorcipher_tut.cpp b/indra/llmessage/tests/llxorcipher_test.cpp
index 9acac53604..9acac53604 100644
--- a/indra/test/llxorcipher_tut.cpp
+++ b/indra/llmessage/tests/llxorcipher_test.cpp
diff --git a/indra/test/message_tut.cpp b/indra/llmessage/tests/message_test.cpp
index 11cd710ef6..6fb2b92803 100644
--- a/indra/test/message_tut.cpp
+++ b/indra/llmessage/tests/message_test.cpp
@@ -113,7 +113,7 @@ namespace tut
ensure_equals("rmfile value", rmfile, 0);
// rm temp dir
- int rmdir = LLFile::rmdir(mTestConfigDir);
+ int rmdir = LLFile::remove(mTestConfigDir);
ensure_equals("rmdir value", rmdir, 0);
}
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 da5fe08b13..2269d7adc8 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -36,7 +36,7 @@
#include <cmath>
extern LLControlGroup gSavedSettings;
-#if LL_DARWIN
+#if LL_DARWIN || LL_LINUX
extern bool gHiDPISupport;
#endif
@@ -378,7 +378,7 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
}
-#if LL_DARWIN
+#if LL_DARWIN || LL_LINUX
if (!gHiDPISupport)
#endif
{
@@ -1053,6 +1053,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 1125d530f4..153a7eb823 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/llcommon/timer.h b/indra/llprecompiled/cmake_dummy.cpp
index aaa0cf0775..21a47a9b14 100644
--- a/indra/llcommon/timer.h
+++ b/indra/llprecompiled/cmake_dummy.cpp
@@ -1,8 +1,7 @@
/**
- * @file timer.h
- * @brief Legacy wrapper header.
+ * @file cmake_dummy.cpp
*
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
@@ -23,4 +22,3 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-#include "lltimer.h"
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 41dd5a8710..3ed80eaab9 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;
@@ -73,7 +69,6 @@ private:
friend size_t hash_value(const LLMaterialID&) noexcept;
void parseFromBinary(const LLSD::Binary& pMaterialID);
- void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID);
int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const;
U8 mID[MATERIAL_ID_SIZE];
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index ac88af18f0..d624b6dc7a 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -33,15 +33,12 @@
#include "m4math.h"
#include <queue>
-#include <boost/align/aligned_allocator.hpp>
-
class daeElement;
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 +62,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 +319,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/llprimlinkinfo.h b/indra/llprimitive/llprimlinkinfo.h
deleted file mode 100644
index 67e40fd5be..0000000000
--- a/indra/llprimitive/llprimlinkinfo.h
+++ /dev/null
@@ -1,393 +0,0 @@
-/**
- * @file llprimlinkinfo.h
- * @author andrew@lindenlab.com
- * @brief A template for determining which prims in a set are linkable
- *
- * $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_PRIM_LINK_INFO_H
-#define LL_PRIM_LINK_INFO_H
-
-// system includes
-#include <iostream>
-#include <map>
-#include <list>
-#include <vector>
-
-// common includes
-#include "stdtypes.h"
-#include "v3math.h"
-#include "llquaternion.h"
-#include "llsphere.h"
-
-
-const F32 MAX_OBJECT_SPAN = 54.f; // max distance from outside edge of an object to the farthest edge
-const F32 OBJECT_SPAN_BONUS = 2.f; // infinitesimally small prims can always link up to this distance
-const S32 MAX_PRIMS_PER_OBJECT = 256;
-
-
-template < typename DATA_TYPE >
-class LLPrimLinkInfo
-{
-public:
- LLPrimLinkInfo();
- LLPrimLinkInfo( DATA_TYPE data, const LLSphere& sphere );
- ~LLPrimLinkInfo();
-
- void set( DATA_TYPE data, const LLSphere& sphere );
- void append( DATA_TYPE data, const LLSphere& sphere );
- void getData( std::list< DATA_TYPE >& data_list ) const;
- F32 getDiameter() const;
- LLVector3 getCenter() const;
-
- // returns 'true' if this info can link with other_info
- bool canLink( const LLPrimLinkInfo< DATA_TYPE >& other_info );
-
- S32 getPrimCount() const { return mDataMap.size(); }
-
- void mergeLinkableSet( typename std::list< LLPrimLinkInfo < DATA_TYPE > >& unlinked );
-
- void transform(const LLVector3& position, const LLQuaternion& rotation);
-
-private:
- // returns number of merges made
- S32 merge(LLPrimLinkInfo< DATA_TYPE >& other_info);
-
- // returns number of collapses made
- static S32 collapse(typename std::list< LLPrimLinkInfo < DATA_TYPE > >& unlinked );
-
- void computeBoundingSphere();
-
- // Internal utility to encapsulate the link rules
- F32 get_max_linkable_span(const LLSphere& first, const LLSphere& second);
- F32 get_span(const LLSphere& first, const LLSphere& second);
-
-private:
- std::map< DATA_TYPE, LLSphere > mDataMap;
- LLSphere mBoundingSphere;
-};
-
-
-
-template < typename DATA_TYPE >
-LLPrimLinkInfo< DATA_TYPE >::LLPrimLinkInfo()
-: mBoundingSphere( LLVector3(0.f, 0.f, 0.f), 0.f )
-{
-}
-
-template < typename DATA_TYPE >
-LLPrimLinkInfo< DATA_TYPE >::LLPrimLinkInfo( DATA_TYPE data, const LLSphere& sphere)
-: mBoundingSphere(sphere)
-{
- mDataMap[data] = sphere;
-}
-
-template < typename DATA_TYPE >
-LLPrimLinkInfo< DATA_TYPE >::~LLPrimLinkInfo()
-{
- mDataMap.clear();
-}
-
-template < typename DATA_TYPE >
-void LLPrimLinkInfo< DATA_TYPE>::set( DATA_TYPE data, const LLSphere& sphere )
-{
- if (!mDataMap.empty())
- {
- mDataMap.clear();
- }
- mDataMap[data] = sphere;
- mBoundingSphere = sphere;
-}
-
-template < typename DATA_TYPE >
-void LLPrimLinkInfo< DATA_TYPE>::append( DATA_TYPE data, const LLSphere& sphere )
-{
- mDataMap[data] = sphere;
- if (!mBoundingSphere.contains(sphere))
- {
- computeBoundingSphere();
- }
-}
-
-template < typename DATA_TYPE >
-void LLPrimLinkInfo< DATA_TYPE >::getData( std::list< DATA_TYPE >& data_list) const
-{
- typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr;
- for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr)
- {
- data_list.push_back(map_itr->first);
- }
-}
-
-template < typename DATA_TYPE >
-F32 LLPrimLinkInfo< DATA_TYPE >::getDiameter() const
-{
- return 2.f * mBoundingSphere.getRadius();
-}
-
-template < typename DATA_TYPE >
-LLVector3 LLPrimLinkInfo< DATA_TYPE >::getCenter() const
-{
- return mBoundingSphere.getCenter();
-}
-
-template < typename DATA_TYPE >
-F32 LLPrimLinkInfo< DATA_TYPE >::get_max_linkable_span(const LLSphere& first, const LLSphere& second)
-{
- F32 max_span = 3.f * (first.getRadius() + second.getRadius()) + OBJECT_SPAN_BONUS;
- if (max_span > MAX_OBJECT_SPAN)
- {
- max_span = MAX_OBJECT_SPAN;
- }
-
- return max_span;
-}
-
-template < typename DATA_TYPE >
-F32 LLPrimLinkInfo< DATA_TYPE >::get_span(const LLSphere& first, const LLSphere& second)
-{
- F32 span = (first.getCenter() - second.getCenter()).length()
- + first.getRadius() + second.getRadius();
- return span;
-}
-
-// static
-// returns 'true' if this info can link with any part of other_info
-template < typename DATA_TYPE >
-bool LLPrimLinkInfo< DATA_TYPE >::canLink(const LLPrimLinkInfo& other_info)
-{
- F32 max_span = get_max_linkable_span(mBoundingSphere, other_info.mBoundingSphere);
-
- F32 span = get_span(mBoundingSphere, other_info.mBoundingSphere);
-
- if (span <= max_span)
- {
- // The entire other_info fits inside the max span.
- return TRUE;
- }
- else if (span > max_span + 2.f * other_info.mBoundingSphere.getRadius())
- {
- // there is no way any piece of other_info could link with this one
- return FALSE;
- }
-
- // there may be a piece of other_info that is linkable
- typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr;
- for (map_itr = other_info.mDataMap.begin(); map_itr != other_info.mDataMap.end(); ++map_itr)
- {
- const LLSphere& other_sphere = (*map_itr).second;
- max_span = get_max_linkable_span(mBoundingSphere, other_sphere);
-
- span = get_span(mBoundingSphere, other_sphere);
-
- if (span <= max_span)
- {
- // found one piece that is linkable
- return TRUE;
- }
- }
- return FALSE;
-}
-
-// merges elements of 'unlinked'
-// returns number of links made (NOT final prim count, NOR linked prim count)
-// and removes any linkable infos from 'unlinked'
-template < typename DATA_TYPE >
-void LLPrimLinkInfo< DATA_TYPE >::mergeLinkableSet(std::list< LLPrimLinkInfo< DATA_TYPE > > & unlinked)
-{
- bool linked_something = true;
- while (linked_something)
- {
- linked_something = false;
-
- typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator other_itr = unlinked.begin();
- while ( other_itr != unlinked.end()
- && getPrimCount() < MAX_PRIMS_PER_OBJECT )
- {
- S32 merge_count = merge(*other_itr);
- if (merge_count > 0)
- {
- linked_something = true;
- }
- if (0 == (*other_itr).getPrimCount())
- {
- unlinked.erase(other_itr++);
- }
- else
- {
- ++other_itr;
- }
- }
- if (!linked_something
- && unlinked.size() > 1)
- {
- S32 collapse_count = collapse(unlinked);
- if (collapse_count > 0)
- {
- linked_something = true;
- }
- }
- }
-}
-
-// transforms all of the spheres into a new reference frame
-template < typename DATA_TYPE >
-void LLPrimLinkInfo< DATA_TYPE >::transform(const LLVector3& position, const LLQuaternion& rotation)
-{
- typename std::map< DATA_TYPE, LLSphere >::iterator map_itr;
- for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr)
- {
- (*map_itr).second.setCenter((*map_itr).second.getCenter() * rotation + position);
- }
- mBoundingSphere.setCenter(mBoundingSphere.getCenter() * rotation + position);
-}
-
-// private
-// returns number of links made
-template < typename DATA_TYPE >
-S32 LLPrimLinkInfo< DATA_TYPE >::merge(LLPrimLinkInfo& other_info)
-{
- S32 link_count = 0;
-
-// F32 other_radius = other_info.mBoundingSphere.getRadius();
-// other_info.computeBoundingSphere();
-// if ( other_radius != other_info.mBoundingSphere.getRadius() )
-// {
-// LL_INFOS() << "Other bounding sphere changed!!" << LL_ENDL;
-// }
-
-// F32 this_radius = mBoundingSphere.getRadius();
-// computeBoundingSphere();
-// if ( this_radius != mBoundingSphere.getRadius() )
-// {
-// LL_INFOS() << "This bounding sphere changed!!" << LL_ENDL;
-// }
-
-
- F32 max_span = get_max_linkable_span(mBoundingSphere, other_info.mBoundingSphere);
-
- // F32 center_dist = (mBoundingSphere.getCenter() - other_info.mBoundingSphere.getCenter()).length();
- // LL_INFOS() << "objects are " << center_dist << "m apart" << LL_ENDL;
- F32 span = get_span(mBoundingSphere, other_info.mBoundingSphere);
-
- F32 span_limit = max_span + (2.f * other_info.mBoundingSphere.getRadius());
- if (span > span_limit)
- {
- // there is no way any piece of other_info could link with this one
- // LL_INFOS() << "span too large: " << span << " vs. " << span_limit << LL_ENDL;
- return 0;
- }
-
- bool completely_linkable = (span <= max_span) ? true : false;
-
- typename std::map< DATA_TYPE, LLSphere >::iterator map_itr = other_info.mDataMap.begin();
- while (map_itr != other_info.mDataMap.end()
- && getPrimCount() < MAX_PRIMS_PER_OBJECT )
- {
- DATA_TYPE other_data = (*map_itr).first;
- LLSphere& other_sphere = (*map_itr).second;
-
- if (!completely_linkable)
- {
- max_span = get_max_linkable_span(mBoundingSphere, other_sphere);
-
- F32 span = get_span(mBoundingSphere, other_sphere);
-
- if (span > max_span)
- {
- ++map_itr;
- continue;
- }
- }
-
- mDataMap[other_data] = other_sphere;
- ++link_count;
-
- if (!mBoundingSphere.contains(other_sphere) )
- {
- computeBoundingSphere();
- }
-
- // remove from the other info
- other_info.mDataMap.erase(map_itr++);
- }
-
- if (link_count > 0 && other_info.getPrimCount() > 0)
- {
- other_info.computeBoundingSphere();
- }
- return link_count;
-}
-
-// links any linkable elements of unlinked
-template < typename DATA_TYPE >
-S32 LLPrimLinkInfo< DATA_TYPE >::collapse(std::list< LLPrimLinkInfo< DATA_TYPE > > & unlinked)
-{
- S32 link_count = 0;
- bool linked_something = true;
- while (linked_something)
- {
- linked_something = false;
-
- typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator this_itr = unlinked.begin();
- typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator other_itr = this_itr;
- ++other_itr;
- while ( other_itr != unlinked.end() )
-
- {
- S32 merge_count = (*this_itr).merge(*other_itr);
- if (merge_count > 0)
- {
- linked_something = true;
- link_count += merge_count;
- }
- if (0 == (*other_itr).getPrimCount())
- {
- unlinked.erase(other_itr++);
- }
- else
- {
- ++other_itr;
- }
- }
- }
- return link_count;
-}
-
-
-template < typename DATA_TYPE >
-void LLPrimLinkInfo< DATA_TYPE >::computeBoundingSphere()
-{
- std::vector< LLSphere > sphere_list;
- typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr;
- for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr)
- {
- sphere_list.push_back(map_itr->second);
- }
- mBoundingSphere = LLSphere::getBoundingSphere(sphere_list);
-}
-
-
-#endif
-
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 fcd287bbb3..82ffa5dde4 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -22,7 +22,6 @@ set(llrender_SOURCE_FILES
llglslshader.cpp
llgltexture.cpp
llimagegl.cpp
- llpostprocess.cpp
llrender.cpp
llrender2dutils.cpp
llrendernavprim.cpp
@@ -54,7 +53,6 @@ set(llrender_HEADER_FILES
llgltexture.h
llgltypes.h
llimagegl.h
- llpostprocess.h
llrender.h
llrender2dutils.h
llrendernavprim.h
@@ -74,23 +72,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
@@ -102,7 +103,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 a577a729b0..8545f634a3 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,67 +1016,146 @@ 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;
}
#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
@@ -1132,7 +1191,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?
@@ -1198,16 +1261,46 @@ bool LLGLManager::initGL()
{
LL_INFOS("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_INFOS("RenderInit") << "VRAM Detected (GLXMesaQueryRenderer):" << mVRAM << LL_ENDL;
+ }
+ }
+ }
+#endif
+
+#if LL_WINDOWS || LL_LINUX
+ {
+ if (mHasNVXGpuMemoryInfo && mVRAM == 0)
{
- LL_INFOS("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_INFOS("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
@@ -1227,6 +1320,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);
@@ -1258,12 +1354,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
}
@@ -1286,8 +1379,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
@@ -1310,9 +1407,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
}
@@ -1371,24 +1472,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
@@ -1396,11 +1577,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);
@@ -1408,846 +1592,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)
@@ -2262,6 +2306,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()
{
@@ -2274,17 +2351,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();
}
}
@@ -2298,27 +2366,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;
}
}
@@ -2402,11 +2455,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();
}
}
@@ -2561,6 +2613,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 e1ab2a49e6..469802657a 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -34,6 +34,8 @@
#include <unordered_map>
#include <list>
+#include "llglheaders.h"
+
#include "llerror.h"
#include "v4color.h"
#include "llstring.h"
@@ -43,7 +45,6 @@
#include "llgltypes.h"
#include "llinstancetracker.h"
-#include "llglheaders.h"
#include "glm/mat4x4.hpp"
extern bool gDebugGL;
@@ -70,7 +71,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
@@ -90,6 +93,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;
@@ -100,6 +104,8 @@ public:
// Vendor-specific extensions
bool mHasAMDAssociations = false;
bool mHasNVXGpuMemoryInfo = false;
+ bool mHasATIMemInfo = false;
+ bool mHasGLXMESAQueryRenderer = false;
bool mIsAMD;
bool mIsNVIDIA;
@@ -141,7 +147,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();
};
@@ -261,19 +276,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
{
@@ -418,67 +420,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 8057149d73..fafc92b5d0 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;
@@ -838,14 +837,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,
@@ -861,7 +852,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);
@@ -1054,7 +1044,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
@@ -1859,7 +1853,7 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
LLGLint is_compressed = 0;
if (compressed_ok)
{
- glGetTexLevelParameteriv(mTarget, is_compressed, GL_TEXTURE_COMPRESSED, (GLint*)&is_compressed);
+ glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED, (GLint*)&is_compressed);
}
//-----------------------------------------------------------------------------------------------
@@ -2010,7 +2004,7 @@ bool LLImageGL::getIsResident(bool test_now)
{
if (mTexName != 0)
{
- glAreTexturesResident(1, (GLuint*)&mTexName, &mIsResident);
+ mIsResident = true;
}
else
{
@@ -2148,7 +2142,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
case GL_SRGB_ALPHA:
mAlphaStride = 4;
break;
- case GL_BGRA_EXT:
+ case GL_BGRA:
mAlphaStride = 4;
break;
default:
@@ -2185,7 +2179,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 a98094de29..0e186ca833 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -287,7 +287,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 0a9aa462d1..6a39a34c4e 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,
@@ -197,6 +193,7 @@ void LLTexUnit::bindFast(LLTexture* texture)
glActiveTexture(GL_TEXTURE0 + mIndex);
gGL.mCurrTextureUnitIndex = mIndex;
mCurrTexture = gl_tex->getTexName();
+ mCurrTexType = gl_tex->getTarget();
if (!mCurrTexture)
{
LL_PROFILE_ZONE_NAMED("MISSING TEXTURE");
@@ -529,9 +526,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 +539,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 +768,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 +822,9 @@ void LLRender::initVertexBuffer()
void LLRender::resetVertexBuffer()
{
- mBuffer = NULL;
+ mBuffer = nullptr;
+ mBufferDataList = nullptr;
+ mVBCache.clear();
}
void LLRender::shutdown()
@@ -1096,7 +1021,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 +1431,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 +1533,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 +1596,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 +1610,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 +1622,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
{
@@ -1718,7 +1643,16 @@ LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count)
LLVertexBuffer * vb = new LLVertexBuffer(attribute_mask);
vb->allocateBuffer(count, 0);
- vb->setBuffer();
+ // Non-Apple path uses glBufferSubData inside setXxxData, so the VBO
+ // must already be bound. On Apple, the VBO is lazily created in
+ // _unmapBuffer (LLAppleVBOPool); calling setBuffer() here would bind
+ // mGLBuffer == 0 and then setupVertexBuffer would issue
+ // glVertexAttribIPointer with a non-null offset against no bound
+ // GL_ARRAY_BUFFER -> GL_INVALID_OPERATION in core profile.
+ if (!gGLManager.mIsApple)
+ {
+ vb->setBuffer();
+ }
vb->setPositionData(mVerticesp.get());
@@ -1733,6 +1667,9 @@ LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count)
}
#if LL_DARWIN
+ // unmapBuffer creates the GL buffer, uploads, and leaves it bound,
+ // drawBuffer's later setBuffer() then runs setupVertexBuffer against
+ // a valid VBO.
vb->unmapBuffer();
#endif
vb->unbind();
@@ -2002,6 +1939,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..9c17cf3470 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -43,10 +43,11 @@
#include "llglheaders.h"
#include "llmatrix4a.h"
#include "glm/mat4x4.hpp"
-#include <boost/align/aligned_allocator.hpp>
#include <array>
+#include <chrono>
#include <list>
+#include <vector>
class LLVertexBuffer;
class LLCubeMap;
@@ -235,8 +236,6 @@ protected:
bool mHasMipMaps;
void debugTextureUnit(void);
- GLint getTextureSource(eTextureBlendSrc src);
- GLint getTextureSourceType(eTextureBlendSrc src, bool isAlpha = false);
};
class LLLightState
@@ -467,6 +466,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 +488,7 @@ public:
public:
static U32 sUICalls;
static U32 sUIVerts;
+ static F32 sAnisotropicFilteringLevel;
static bool sGLCoreProfile;
static bool sNsightDebugSupport;
static LLVector2 sUIGLScaleFactor;
@@ -512,7 +514,8 @@ private:
U32 mCount;
U32 mMode;
U32 mCurrTextureUnitIndex;
- bool mCurrColorMask[4];
+ bool mCurrColorMask[4];
+ F32 mLineWidth = 1.f;
LLPointer<LLVertexBuffer> mBuffer;
LLStrider<LLVector4a> mVerticesp;
@@ -527,8 +530,17 @@ private:
eBlendFactor mCurrBlendAlphaSFactor;
eBlendFactor mCurrBlendAlphaDFactor;
- std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 16> > mUIOffset;
- std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 16> > mUIScale;
+ std::vector<LLVector4a> mUIOffset;
+ std::vector<LLVector4a> 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/llrendertarget.h b/indra/llrender/llrendertarget.h
index cd3290cf66..ea4c38d483 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -42,7 +42,7 @@
...
//allocate a 256x256 RGBA render target with depth buffer
- target.allocate(256,256,GL_RGBA,TRUE);
+ target.allocate(256,256,GL_RGBA,true);
//render to contents of offscreen buffer
target.bindTarget();
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 1a0fb1aeb9..9f7c244fe9 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -501,7 +501,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
open_file_name = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/errorF.glsl");
}
- file = LLFile::fopen(open_file_name, "r");
+ file = LLFile::fopen(open_file_name, LLFILE_MODE("r"));
}
else
#endif
@@ -529,7 +529,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
*/
LL_DEBUGS("ShaderLoading") << "Looking in " << open_file_name << LL_ENDL;
- file = LLFile::fopen(open_file_name, "r"); /* Flawfinder: ignore */
+ file = LLFile::fopen(open_file_name, LLFILE_MODE("r")); /* Flawfinder: ignore */
if (file)
{
LL_DEBUGS("ShaderLoading") << "Loading file: " << open_file_name << " (Want class " << gpu_class << ")" << LL_ENDL;
@@ -1014,7 +1014,6 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version,
mShaderCacheDir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache");
LLFile::mkdir(mShaderCacheDir);
-
{
std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd");
if (gDirUtilp->fileExists(meta_out_path))
@@ -1074,7 +1073,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();
}
@@ -1100,7 +1098,7 @@ void LLShaderMgr::persistShaderCacheMetadata()
// Settings and shader cache get saved at different time, thus making
// RenderShaderCacheVersion unreliable when running multiple viewer
// instances, or for cases where viewer crashes before saving settings.
- // Dupplicate version to the cache itself.
+ // Duplicate version to the cache itself.
out["version"] = mShaderCacheVersion;
out["shaders"] = LLSD::emptyMap();
LLSD &shaders = out["shaders"];
@@ -1179,10 +1177,11 @@ bool LLShaderMgr::loadCachedProgramBinary(LLGLSLShader* shader)
std::vector<U8> in_data;
in_data.resize(shader_info.mBinaryLength);
- LLUniqueFile filep = LLFile::fopen(in_path, "rb");
- if (filep)
+ std::error_code ec;
+ LLFile filep = LLFile(in_path, LLFile::in | LLFile::binary, ec);
+ if (!ec && (bool)filep)
{
- size_t result = fread(in_data.data(), sizeof(U8), in_data.size(), filep);
+ size_t result = filep.read(in_data.data(), in_data.size(), ec);
filep.close();
if (result == in_data.size())
@@ -1244,11 +1243,12 @@ bool LLShaderMgr::saveCachedProgramBinary(LLGLSLShader* shader)
if (error == GL_NO_ERROR)
{
std::string out_path = gDirUtilp->add(mShaderCacheDir, shader->mShaderHash.asString() + ".shaderbin");
- LLUniqueFile outfile = LLFile::fopen(out_path, "wb");
- if (outfile)
+ std::error_code ec;
+ LLFile filep = LLFile(out_path, LLFile::out | LLFile::binary, ec);
+ if (filep)
{
- fwrite(program_binary.data(), sizeof(U8), program_binary.size(), outfile);
- outfile.close();
+ filep.write(program_binary.data(), program_binary.size(), ec);
+ filep.close();
binary_info.mLastUsedTime = (F32)LLTimer::getTotalSeconds();
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 1c9a16ba41..82cbc4bb5e 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -274,6 +274,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)
@@ -284,10 +288,8 @@ if(LL_TESTS)
)
set_property( SOURCE ${llui_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_LIBRARIES ${test_libs})
LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}")
- # INTEGRATION TESTS
- if(NOT LINUX)
- set(test_libs llui llmessage llcorehttp llxml llrender llcommon ll::hunspell )
- LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}")
- endif(NOT LINUX)
+ # INTEGRATION TESTS
+ set(test_libs llui llmessage llcorehttp llxml llrender llcommon ll::hunspell )
+ LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}")
endif(LL_TESTS)
diff --git a/indra/llui/llcallbackmap.h b/indra/llui/llcallbackmap.h
index 69b80db1e8..3115606d91 100644
--- a/indra/llui/llcallbackmap.h
+++ b/indra/llui/llcallbackmap.h
@@ -27,11 +27,9 @@
#ifndef LLCALLBACKMAP_H
#define LLCALLBACKMAP_H
-#include "llstl.h"
-
+#include <map>
#include <string>
#include <functional>
-#include <unordered_map>
class LLCallbackMap
{
@@ -39,7 +37,7 @@ public:
// callback definition.
typedef std::function<void* (void* data)> callback_t;
- typedef std::unordered_map<std::string, LLCallbackMap> map_t;
+ typedef std::map<std::string, LLCallbackMap> map_t;
typedef map_t::iterator map_iter_t;
typedef map_t::const_iterator map_const_iter_t;
diff --git a/indra/llui/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 9361358ced..b5e26db1b5 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -250,6 +250,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),
@@ -569,6 +570,8 @@ void LLFloater::storeRectControl()
void LLFloater::storeVisibilityControl()
{
+ // Todo: this is a bit pricey, gets called each frame
+ // on LLAppViewer::idle(), optimize!
if( !sQuitting && mVisibilityControl.size() > 1 )
{
getControlGroup()->setBOOL( mVisibilityControl, getVisible() );
@@ -3357,6 +3360,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/llpanel.cpp b/indra/llui/llpanel.cpp
index d09fc3e22d..ff5a28b250 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -489,10 +489,9 @@ bool LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
LL_RECORD_BLOCK_TIME(FTM_PANEL_SETUP);
LLXMLNodePtr referenced_xml;
- const std::string& xml_filename = mXMLFilename;
// if the panel didn't provide a filename, check the node
- if (xml_filename.empty())
+ if (mXMLFilename.empty())
{
std::string temp_filename;
node->getAttributeString("filename", temp_filename);
diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp
index 111c732548..f00d876b2b 100644
--- a/indra/llui/llresmgr.cpp
+++ b/indra/llui/llresmgr.cpp
@@ -54,11 +54,9 @@ char LLResMgr::getDecimalPoint() const
return decimal;
}
-char LLResMgr::getThousandsSeparator() const
+std::string LLResMgr::getThousandsSeparator() const
{
- char separator = localeconv()->thousands_sep[0];
-
- return separator;
+ return localeconv()->thousands_sep;
}
char LLResMgr::getMonetaryDecimalPoint() const
@@ -68,11 +66,9 @@ char LLResMgr::getMonetaryDecimalPoint() const
return decimal;
}
-char LLResMgr::getMonetaryThousandsSeparator() const
+std::string LLResMgr::getMonetaryThousandsSeparator() const
{
- char separator = localeconv()->mon_thousands_sep[0];
-
- return separator;
+ return localeconv()->mon_thousands_sep;
}
@@ -85,7 +81,7 @@ std::string LLResMgr::getMonetaryString( S32 input ) const
struct lconv *conv = localeconv();
char* negative_sign = conv->negative_sign;
- char separator = getMonetaryThousandsSeparator();
+ std::string separator = getMonetaryThousandsSeparator();
char* grouping = conv->mon_grouping;
// Note on mon_grouping:
@@ -135,10 +131,7 @@ std::string LLResMgr::getMonetaryString( S32 input ) const
}
S32 group_count = cur_group;
- char reversed_output[20] = ""; /* Flawfinder: ignore */
- char forward_output[20] = ""; /* Flawfinder: ignore */
- S32 output_pos = 0;
-
+ std::string formatted;
cur_group = 0;
S32 pos = static_cast<S32>(digits.size()) - 1;
S32 count_within_group = 0;
@@ -148,7 +141,7 @@ std::string LLResMgr::getMonetaryString( S32 input ) const
if( count_within_group > groupings[cur_group] )
{
count_within_group = 1;
- reversed_output[ output_pos++ ] = separator;
+ formatted = separator + formatted;
if( (cur_group + 1) >= group_count )
{
@@ -160,28 +153,19 @@ std::string LLResMgr::getMonetaryString( S32 input ) const
cur_group++;
}
}
- reversed_output[ output_pos++ ] = digits[pos--];
+ formatted = std::string(1, digits[pos--]) + formatted;
}
while( pos >= 0 )
{
- reversed_output[ output_pos++ ] = digits[pos--];
- }
-
-
- reversed_output[ output_pos ] = '\0';
- forward_output[ output_pos ] = '\0';
-
- for( S32 i = 0; i < output_pos; i++ )
- {
- forward_output[ output_pos - 1 - i ] = reversed_output[ i ];
+ formatted = std::string(1, digits[pos--]) + formatted;
}
if( negative_before )
{
output.append( negative_sign );
}
- output.append( forward_output );
+ output.append( formatted );
if( negative_after )
{
output.append( negative_sign );
@@ -210,11 +194,11 @@ void LLResMgr::getIntegerString( std::string& output, S32 input ) const
{
if (fraction == remaining_count)
{
- fraction_string = llformat_to_utf8("%d%c", fraction, getThousandsSeparator());
+ fraction_string = llformat_to_utf8("%d", fraction) + getThousandsSeparator();
}
else
{
- fraction_string = llformat_to_utf8("%3.3d%c", fraction, getThousandsSeparator());
+ fraction_string = llformat_to_utf8("%3.3d", fraction) + getThousandsSeparator();
}
output = fraction_string + output;
}
diff --git a/indra/llui/llresmgr.h b/indra/llui/llresmgr.h
index 7ad6659a44..8ceb584ec5 100644
--- a/indra/llui/llresmgr.h
+++ b/indra/llui/llresmgr.h
@@ -49,10 +49,10 @@ public:
LLLOCALE_ID getLocale() const { return mLocale; }
char getDecimalPoint() const;
- char getThousandsSeparator() const;
+ std::string getThousandsSeparator() const;
char getMonetaryDecimalPoint() const;
- char getMonetaryThousandsSeparator() const;
+ std::string getMonetaryThousandsSeparator() const;
std::string getMonetaryString( S32 input ) const;
void getIntegerString( std::string& output, S32 input ) const;
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp
index 7a4f72fe4f..90ba6f1ecc 100644
--- a/indra/llui/lluicolortable.cpp
+++ b/indra/llui/lluicolortable.cpp
@@ -298,7 +298,7 @@ void LLUIColorTable::saveUserSettings() const
if(!output_node->isNull())
{
const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "colors.xml");
- LLFILE *fp = LLFile::fopen(filename, "w");
+ LLFILE *fp = LLFile::fopen(filename, LLFILE_MODE("w"));
if(fp != NULL)
{
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/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index 71ce2afdbd..f4ef6f79f1 100644
--- a/indra/llui/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
@@ -637,7 +637,7 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p
}
}
- LLFILE* xsd_file = LLFile::fopen(file_name.c_str(), "w");
+ LLFILE* xsd_file = LLFile::fopen(file_name.c_str(), LLFILE_MODE("w"));
LLXMLNode::writeHeaderToFile(xsd_file);
root_nodep->writeToFile(xsd_file);
fclose(xsd_file);
@@ -1326,7 +1326,7 @@ void LLXUIParser::parserError(const std::string& message)
struct ScopedFile
{
- ScopedFile( const std::string& filename, const char* accessmode )
+ ScopedFile( const std::string& filename, const LLFile::fopen_flags_t* accessmode )
{
mFile = LLFile::fopen(filename, accessmode);
}
@@ -1397,7 +1397,7 @@ bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBl
mCurReadDepth = 0;
setParseSilently(silent);
- ScopedFile file(filename, "rb");
+ ScopedFile file(filename, LLFILE_MODE("rb"));
if( !file.isOpen() )
{
LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL;
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index 95d1586495..8277c23691 100755..100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -50,16 +50,16 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
//
// Stub implementation for LLCacheName
//
-BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname)
+bool LLCacheName::getFullName(const LLUUID& id, std::string& fullname)
{
fullname = "Lynx Linden";
- return TRUE;
+ return true;
}
-BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
+bool LLCacheName::getGroupName(const LLUUID& id, std::string& group)
{
group = "My Group";
- return TRUE;
+ return true;
}
boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback)
diff --git a/indra/llwebrtc/CMakeLists.txt b/indra/llwebrtc/CMakeLists.txt
index eb10f4eee4..9d5cde0e6a 100644
--- a/indra/llwebrtc/CMakeLists.txt
+++ b/indra/llwebrtc/CMakeLists.txt
@@ -47,7 +47,14 @@ if (WINDOWS)
set_target_properties(llwebrtc PROPERTIES PDB_OUTPUT_DIRECTORY "${SYMBOLS_STAGING_DIR}")
endif (USE_BUGSPLAT)
elseif (DARWIN)
- target_link_libraries(llwebrtc PRIVATE ll::webrtc)
+ target_link_libraries(llwebrtc PRIVATE ll::webrtc
+ "-framework AVFoundation"
+ "-framework AudioToolbox"
+ "-framework CoreAudio"
+ "-framework CoreMedia"
+ "-framework CoreVideo"
+ "-framework Foundation"
+ )
if (USE_BUGSPLAT)
set_target_properties(llwebrtc PROPERTIES XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym"
XCODE_ATTRIBUTE_DWARF_DSYM_FOLDER_PATH "${SYMBOLS_STAGING_DIR}/dSYMs")
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index f4ecce63a6..bdb629172d 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -26,8 +26,11 @@
#include "llwebrtc_impl.h"
#include <algorithm>
+#include <chrono>
+#include <future>
+#include <thread>
#include <string.h>
-
+#include "api/audio/create_audio_device_module.h"
#include "api/audio_codecs/audio_decoder_factory.h"
#include "api/audio_codecs/audio_encoder_factory.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
@@ -42,8 +45,8 @@
namespace llwebrtc
{
#if WEBRTC_WIN
-static int16_t PLAYOUT_DEVICE_DEFAULT = webrtc::AudioDeviceModule::kDefaultDevice;
-static int16_t RECORD_DEVICE_DEFAULT = webrtc::AudioDeviceModule::kDefaultDevice;
+static int16_t PLAYOUT_DEVICE_DEFAULT = webrtc::AudioDeviceModule::kDefaultCommunicationDevice;
+static int16_t RECORD_DEVICE_DEFAULT = webrtc::AudioDeviceModule::kDefaultCommunicationDevice;
#else
static int16_t PLAYOUT_DEVICE_DEFAULT = 0;
static int16_t RECORD_DEVICE_DEFAULT = 0;
@@ -134,7 +137,9 @@ int32_t LLWebRTCAudioTransport::NeedMorePlayData(size_t number_of_frames,
if (!engine)
{
// No engine sink; output silence to be safe.
- const size_t bytes = number_of_frames * bytes_per_frame * number_of_channels;
+ // bytes_per_frame already accounts for all channels, so do not multiply
+ // by number_of_channels again (that would overrun the playout buffer).
+ const size_t bytes = number_of_frames * bytes_per_frame;
memset(audio_data, 0, bytes);
number_of_samples_out = bytes_per_frame;
return 0;
@@ -250,17 +255,47 @@ void LLCustomProcessor::Process(webrtc::AudioBuffer *audio)
mState->setMicrophoneEnergy(std::sqrt(totalSum / (audio->num_channels() * audio->num_frames() * buffer_size)));
}
+
+//
+// LLWebRTCImpl implementation
+//
+
+void LLWebRTCAudioDeviceModule::SetTuning(bool tuning, bool mute)
+{
+ tuning_ = tuning;
+ if (tuning)
+ {
+ // Ensure capture is running (it's normally already running -- capture is
+ // session-long) so the mic-level meter works, and stop rendering the
+ // call while tuning. The recording calls are no-ops if capture is
+ // already active, so this won't cold-start it.
+ inner_->InitMicrophone();
+ inner_->InitRecording();
+ inner_->StartRecording();
+ inner_->StopPlayout();
+ }
+ // On exit, capture is deliberately left running (mute is handled by gain,
+ // not by stopping the device, so there's no AEC cold-start hiss). Playout
+ // is restored by the caller via workerOpenPlayout(), keeping it gated on
+ // there being a connection to render.
+}
+
//
// LLWebRTCImpl implementation
//
LLWebRTCImpl::LLWebRTCImpl(LLWebRTCLogCallback* logCallback) :
+ mEnv(webrtc::CreateEnvironment(webrtc::CreateDefaultTaskQueueFactory())),
mLogSink(new LLWebRTCLogSink(logCallback)),
mPeerCustomProcessor(nullptr),
mMute(true),
+ mVoiceEnabled(false),
mTuningMode(false),
mDevicesDeploying(0),
- mGain(0.0f)
+ mGain(0.0f),
+ mBuiltinNS(false),
+ mBuiltinAGC(false),
+ mBuiltinAEC(false)
{
}
@@ -273,8 +308,6 @@ void LLWebRTCImpl::init()
webrtc::LogMessage::SetLogToStderr(true);
webrtc::LogMessage::AddLogToStream(mLogSink, webrtc::LS_VERBOSE);
- mTaskQueueFactory = webrtc::CreateDefaultTaskQueueFactory();
-
// Create the native threads.
mNetworkThread = webrtc::Thread::CreateWithSocketServer();
mNetworkThread->SetName("WebRTCNetworkThread", nullptr);
@@ -290,9 +323,17 @@ void LLWebRTCImpl::init()
[this]()
{
webrtc::scoped_refptr<webrtc::AudioDeviceModule> realADM =
- webrtc::AudioDeviceModule::Create(webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, mTaskQueueFactory.get());
+ webrtc::CreateAudioDeviceModule(mEnv, webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio);
mDeviceModule = webrtc::make_ref_counted<LLWebRTCAudioDeviceModule>(realADM);
mDeviceModule->SetObserver(this);
+ mDeviceModule->Init();
+
+ mBuiltinNS = mDeviceModule->BuiltInNSIsAvailable();
+ mBuiltinAEC = mDeviceModule->BuiltInAECIsAvailable();
+ mBuiltinAGC = mDeviceModule->BuiltInAGCIsAvailable();
+ // All audio processing is done by WebRTC's software APM (configured
+ // below); make sure the hardware processors stay off.
+ workerDisableBuiltInAudioProcessing();
});
// The custom processor allows us to retrieve audio data (and levels)
@@ -302,17 +343,22 @@ void LLWebRTCImpl::init()
apb.SetCapturePostProcessing(std::make_unique<LLCustomProcessor>(mPeerCustomProcessor));
mAudioProcessingModule = apb.Build(webrtc::CreateEnvironment());
+ // Initial software-APM state, matching setAudioConfig() so there's no
+ // window where processing differs before the viewer's first config call.
+ // All processing is done here in software (the hardware AEC/AGC/NS is kept
+ // disabled), so enable echo cancellation from the very first frame.
webrtc::AudioProcessing::Config apm_config;
- apm_config.echo_canceller.enabled = false;
- apm_config.echo_canceller.mobile_mode = false;
- apm_config.gain_controller1.enabled = false;
- apm_config.gain_controller2.enabled = true;
- apm_config.high_pass_filter.enabled = true;
- apm_config.noise_suppression.enabled = true;
- apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kVeryHigh;
- apm_config.transient_suppression.enabled = true;
- apm_config.pipeline.multi_channel_render = true;
- apm_config.pipeline.multi_channel_capture = false;
+ apm_config.echo_canceller.enabled = true;
+ apm_config.echo_canceller.mobile_mode = false;
+ apm_config.gain_controller1.enabled = false;
+ apm_config.gain_controller2.enabled = true;
+ apm_config.gain_controller2.adaptive_digital.enabled = true; // auto-level speech
+ apm_config.high_pass_filter.enabled = true;
+ apm_config.noise_suppression.enabled = true;
+ apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kVeryHigh;
+ apm_config.transient_suppression.enabled = true;
+ apm_config.pipeline.multi_channel_render = true;
+ apm_config.pipeline.multi_channel_capture = true;
mAudioProcessingModule->ApplyConfig(apm_config);
@@ -344,7 +390,6 @@ void LLWebRTCImpl::init()
{
if (mDeviceModule)
{
- mDeviceModule->EnableBuiltInAEC(false);
updateDevices();
}
});
@@ -353,8 +398,23 @@ void LLWebRTCImpl::init()
void LLWebRTCImpl::terminate()
{
- mWorkerThread->BlockingCall(
- [this]()
+ // Run all blocking WebRTC shutdown calls on a separate thread so that a
+ // hung BlockingCall cannot block the viewer shutdown indefinitely.
+ // Webrtc is not mission critical, we need to save personal data.
+ auto done_promise = std::make_shared<std::promise<void> >();
+ std::future<void> done_future = done_promise->get_future();
+
+ // Hand ownership of the connections to the shutdown thread. Nothing on
+ // this thread may touch them afterwards -- in the timeout case below the
+ // shutdown thread is detached and may still be working through them.
+ std::vector<webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl>> connections;
+ connections.swap(mPeerConnections);
+
+ std::thread shutdown_thread(
+ [this, connections = std::move(connections), done_promise]() mutable
+ {
+ mWorkerThread->BlockingCall(
+ [this]()
{
if (mDeviceModule)
{
@@ -363,79 +423,155 @@ void LLWebRTCImpl::terminate()
}
});
- for (auto &connection : mPeerConnections)
- {
- connection->terminate();
- }
+ // Close the connections inline on the signaling thread. This can't be
+ // connection->terminate(), which only *posts* the close: that queues the
+ // real work behind everything below, so the connections would be closed
+ // after the factory and the device module are gone -- or not at all, if
+ // the thread is destroyed with the task still queued.
+ //
+ // It matters that the close completes here because closing a peer
+ // connection flushes any in-flight GetStats request and runs its
+ // callback inline, and that callback calls back into the viewer's
+ // signaling observers. Those observers are only valid until
+ // llwebrtc::terminate() returns.
+ mSignalingThread->BlockingCall(
+ [&connections]()
+ {
+ for (auto& connection : connections)
+ {
+ connection->closeOnSignalingThread();
+ }
+ // Destroy the connections here, on the signaling thread, while
+ // it's still running.
+ connections.clear();
+ });
- // connection->terminate() above spawns a number of Signaling thread calls to
- // shut down the connection. The following Blocking Call will wait
- // until they're done before it's executed, allowing time to clean up.
+ // Drain anything the closes posted before dropping the factory.
+ mSignalingThread->BlockingCall([]() {});
- mSignalingThread->BlockingCall([this]() { mPeerConnectionFactory = nullptr; });
+ mSignalingThread->BlockingCall([this]() {
+ mPeerConnectionFactory = nullptr;
+ });
- mWorkerThread->BlockingCall(
- [this]()
+ mWorkerThread->BlockingCall(
+ [this]()
{
if (mDeviceModule)
{
- mDeviceModule->Terminate();
+ mDeviceModule->ForceTerminate();
}
- mDeviceModule = nullptr;
- mTaskQueueFactory = nullptr;
+ mDeviceModule = nullptr;
});
- // In case peer connections still somehow have jobs in workers,
- // only clear connections up after clearing workers.
+ done_promise->set_value();
+ });
+
+ constexpr auto WEBRTC_TERMINATE_TIMEOUT = std::chrono::seconds(10);
+ if (done_future.wait_for(WEBRTC_TERMINATE_TIMEOUT) == std::future_status::timeout)
+ {
+ RTC_LOG(LS_WARNING) << __FUNCTION__
+ << ": timed out waiting for WebRTC thread shutdown."
+ " Detaching — some WebRTC resources will be leaked.";
+ shutdown_thread.detach();
+
+ // Release the unique_ptrs WITHOUT joining/deleting: the detached thread
+ // may still be using these thread objects.
+ // The raw pointers are intentionally leaked — the process is exiting anyway
+ // and our priority is saving cache and personal data.
+ (void)mNetworkThread.release();
+ (void)mWorkerThread.release();
+ (void)mSignalingThread.release();
+
+ // mPeerConnections is already empty -- the detached thread owns the
+ // connections now and must be left to finish with them.
+ webrtc::LogMessage::RemoveLogToStream(mLogSink);
+ return;
+ }
+
+ shutdown_thread.join();
+
+ // The connections were closed and destroyed on the signaling thread before
+ // the shutdown thread finished, so it's safe to drop the threads now.
mNetworkThread = nullptr;
mWorkerThread = nullptr;
mSignalingThread = nullptr;
- mPeerConnections.clear();
webrtc::LogMessage::RemoveLogToStream(mLogSink);
}
+
void LLWebRTCImpl::setAudioConfig(LLWebRTCDeviceInterface::AudioConfig config)
{
+ // All audio processing is handled by WebRTC's software APM here. The
+ // platform/hardware AEC/AGC/NS is always disabled (see
+ // workerDisableBuiltInAudioProcessing), so these are enabled purely on the
+ // requested config without deferring to any built-in processor.
webrtc::AudioProcessing::Config apm_config;
- apm_config.echo_canceller.enabled = config.mEchoCancellation;
- apm_config.echo_canceller.mobile_mode = false;
- apm_config.gain_controller1.enabled = false;
- apm_config.gain_controller2.enabled = config.mAGC;
+ apm_config.echo_canceller.enabled = config.mEchoCancellation;
+ apm_config.echo_canceller.mobile_mode = false;
+ apm_config.gain_controller1.enabled = false;
+ apm_config.gain_controller2.enabled = config.mAGC;
apm_config.gain_controller2.adaptive_digital.enabled = true; // auto-level speech
- apm_config.high_pass_filter.enabled = true;
- apm_config.transient_suppression.enabled = true;
- apm_config.pipeline.multi_channel_render = true;
- apm_config.pipeline.multi_channel_capture = true;
- apm_config.pipeline.multi_channel_capture = true;
+ apm_config.high_pass_filter.enabled = true;
+ apm_config.transient_suppression.enabled = true;
+ apm_config.pipeline.multi_channel_render = true;
+ apm_config.pipeline.multi_channel_capture = true;
switch (config.mNoiseSuppressionLevel)
{
case LLWebRTCDeviceInterface::AudioConfig::NOISE_SUPPRESSION_LEVEL_NONE:
apm_config.noise_suppression.enabled = false;
- apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kLow;
+ apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kLow;
break;
case LLWebRTCDeviceInterface::AudioConfig::NOISE_SUPPRESSION_LEVEL_LOW:
apm_config.noise_suppression.enabled = true;
- apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kLow;
+ apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kLow;
break;
case LLWebRTCDeviceInterface::AudioConfig::NOISE_SUPPRESSION_LEVEL_MODERATE:
apm_config.noise_suppression.enabled = true;
- apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kModerate;
+ apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kModerate;
break;
case LLWebRTCDeviceInterface::AudioConfig::NOISE_SUPPRESSION_LEVEL_HIGH:
apm_config.noise_suppression.enabled = true;
- apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kHigh;
+ apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kHigh;
break;
case LLWebRTCDeviceInterface::AudioConfig::NOISE_SUPPRESSION_LEVEL_VERY_HIGH:
apm_config.noise_suppression.enabled = true;
- apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kVeryHigh;
+ apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kVeryHigh;
break;
default:
apm_config.noise_suppression.enabled = false;
- apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kLow;
+ apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kLow;
}
mAudioProcessingModule->ApplyConfig(apm_config);
+
+ // Keep the hardware processors off; the APM above is the only processing.
+ PostWorkerTask([this]() { workerDisableBuiltInAudioProcessing(); });
+}
+
+void LLWebRTCImpl::workerDisableBuiltInAudioProcessing()
+{
+ if (!mDeviceModule)
+ {
+ return;
+ }
+
+ // We always use WebRTC's internal (software APM) audio processing. Running
+ // the platform/hardware AEC, AGC, or NS alongside it causes the two to
+ // fight -- pumping levels, double noise suppression, and mismatched AEC
+ // references -- so disable any that the device exposes.
+ if (mBuiltinNS)
+ {
+ mDeviceModule->EnableBuiltInNS(false);
+ }
+ if (mBuiltinAGC)
+ {
+ mDeviceModule->EnableBuiltInAGC(false);
+ }
+ if (mBuiltinAEC)
+ {
+ mDeviceModule->EnableBuiltInAEC(false);
+ }
}
void LLWebRTCImpl::refreshDevices()
@@ -455,20 +591,25 @@ void LLWebRTCImpl::unsetDevicesObserver(LLWebRTCDevicesObserver *observer)
}
}
-// must be run in the worker thread.
-void LLWebRTCImpl::workerDeployDevices()
+// must be run in the worker thread. Selects the configured capture device and
+// starts recording. Capture runs the whole time voice is enabled (it's never
+// stopped for mute or between calls, so the AEC never cold-starts -- there's no
+// hiss on unmute), so this is a no-op when already recording. Device changes
+// go through workerDeployDevices(), which stops recording first to force a
+// clean re-select; voice off goes through setVoiceEnabled(false).
+void LLWebRTCImpl::workerStartRecording()
{
- if (!mDeviceModule)
+ // Only run capture while voice is enabled, and never cold-start it when
+ // it's already running (that would cause the unmute hiss).
+ if (!mDeviceModule || !mVoiceEnabled || mDeviceModule->Recording())
{
return;
}
int16_t recordingDevice = RECORD_DEVICE_DEFAULT;
- int16_t recording_device_start = 0;
-
if (mRecordingDevice != "Default")
{
- for (int16_t i = recording_device_start; i < mRecordingDeviceList.size(); i++)
+ for (int16_t i = 0; i < mRecordingDeviceList.size(); i++)
{
if (mRecordingDeviceList[i].mID == mRecordingDevice)
{
@@ -484,8 +625,6 @@ void LLWebRTCImpl::workerDeployDevices()
}
}
- mDeviceModule->StopPlayout();
- mDeviceModule->ForceStopRecording();
#if WEBRTC_WIN
if (recordingDevice < 0)
{
@@ -500,13 +639,32 @@ void LLWebRTCImpl::workerDeployDevices()
#endif
mDeviceModule->InitMicrophone();
mDeviceModule->SetStereoRecording(false);
+ // A newly-selected capture device may default its hardware AEC/AGC/NS on;
+ // disable before InitRecording so the recording stream is configured to
+ // use only WebRTC's software APM.
+ workerDisableBuiltInAudioProcessing();
mDeviceModule->InitRecording();
+ mDeviceModule->ForceStartRecording();
+}
+
+// must be run in the worker thread. Selects the configured playout device and
+// starts playout. Playout only runs while there's a connection to render
+// (running the output device with no engine data is heard as a buzz), so this
+// is a no-op when there are no connections or when already playing. Device
+// changes go through workerDeployDevices(), which stops playout first.
+void LLWebRTCImpl::workerStartPlayout()
+{
+ // Only run playout while voice is enabled and there's a connection to
+ // render (running the output device otherwise is heard as a buzz).
+ if (!mDeviceModule || !mVoiceEnabled || mTuningMode || mDeviceModule->Playing() || mPeerConnections.empty())
+ {
+ return;
+ }
int16_t playoutDevice = PLAYOUT_DEVICE_DEFAULT;
- int16_t playout_device_start = 0;
if (mPlayoutDevice != "Default")
{
- for (int16_t i = playout_device_start; i < mPlayoutDeviceList.size(); i++)
+ for (int16_t i = 0; i < mPlayoutDeviceList.size(); i++)
{
if (mPlayoutDeviceList[i].mID == mPlayoutDevice)
{
@@ -537,16 +695,29 @@ void LLWebRTCImpl::workerDeployDevices()
mDeviceModule->InitSpeaker();
mDeviceModule->SetStereoPlayout(true);
mDeviceModule->InitPlayout();
+ mDeviceModule->StartPlayout();
+}
- if ((!mMute && mPeerConnections.size()) || mTuningMode)
+// must be run in the worker thread. Used for device changes and tuning: forces
+// a clean re-select of both devices, then re-applies per-connection mute/track
+// state. To merely bring playout up when a connection is established (without
+// disturbing the connection's own mute/track management) call
+// workerOpenPlayout() directly -- see startPlayout().
+void LLWebRTCImpl::workerDeployDevices()
+{
+ if (!mDeviceModule)
{
- mDeviceModule->ForceStartRecording();
+ return;
}
- if (!mTuningMode)
- {
- mDeviceModule->StartPlayout();
- }
+ // Stop first so the start helpers (which no-op when already running) will
+ // re-select the now-current device.
+ mDeviceModule->StopPlayout();
+ mDeviceModule->ForceStopRecording();
+
+ workerStartRecording();
+ workerStartPlayout();
+
mSignalingThread->PostTask(
[this]
{
@@ -588,6 +759,35 @@ void LLWebRTCImpl::setRenderDevice(const std::string &id)
}
}
+void LLWebRTCImpl::setVoiceEnabled(bool enable)
+{
+ mVoiceEnabled = enable;
+ mWorkerThread->PostTask(
+ [this, enable]()
+ {
+ if (!mDeviceModule)
+ {
+ return;
+ }
+ if (enable)
+ {
+ // Voice on: start the capture device (it then stays running
+ // across calls and mute/unmute), and start playout if there's
+ // already a connection to render.
+ mDeviceModule->Init();
+ workerDeployDevices();
+ }
+ else
+ {
+ // Voice off: release both devices so the OS mic/speaker aren't
+ // held open.
+ mDeviceModule->ForceStopRecording();
+ mDeviceModule->StopPlayout();
+ mDeviceModule->ForceTerminate();
+ }
+ });
+}
+
// updateDevices needs to happen on the worker thread.
void LLWebRTCImpl::updateDevices()
{
@@ -611,6 +811,7 @@ void LLWebRTCImpl::updateDevices()
char name[webrtc::kAdmMaxDeviceNameSize];
char guid[webrtc::kAdmMaxGuidSize];
mDeviceModule->PlayoutDeviceName(index, name, guid);
+ RTC_LOG(LS_VERBOSE) << "updateDevices: playout device [" << index << "] name='" << name << "' guid='" << guid << "'";
mPlayoutDeviceList.emplace_back(name, guid);
}
@@ -629,13 +830,18 @@ void LLWebRTCImpl::updateDevices()
char name[webrtc::kAdmMaxDeviceNameSize];
char guid[webrtc::kAdmMaxGuidSize];
mDeviceModule->RecordingDeviceName(index, name, guid);
+ RTC_LOG(LS_VERBOSE) << "updateDevices: recording device [" << index << "] name='" << name << "' guid='" << guid << "'";
mRecordingDeviceList.emplace_back(name, guid);
}
+ RTC_LOG(LS_INFO) << "updateDevices, playout count: " << renderDeviceCount << "; capture count: " << captureDeviceCount;
+
for (auto &observer : mVoiceDevicesObserverList)
{
observer->OnDevicesChanged(mPlayoutDeviceList, mRecordingDeviceList);
}
+
+ deployDevices();
}
void LLWebRTCImpl::OnDevicesUpdated()
@@ -658,6 +864,13 @@ void LLWebRTCImpl::setTuningMode(bool enable)
[this]
{
mDeviceModule->SetTuning(mTuningMode, mMute);
+ if (!mTuningMode)
+ {
+ // Restore playout after tuning, gated on there being a
+ // connection to render (so the output device isn't left
+ // spinning with no engine data).
+ workerStartPlayout();
+ }
mSignalingThread->PostTask(
[this]
{
@@ -729,39 +942,16 @@ void LLWebRTCImpl::setMute(bool mute, int delay_ms)
void LLWebRTCImpl::intSetMute(bool mute, int delay_ms)
{
+ // Mute by zeroing the captured (post-APM) gain; the sender track is also
+ // disabled per connection (see LLWebRTCPeerConnectionImpl::setMute). The
+ // capture device deliberately stays running for the whole session, so
+ // muting/unmuting never stops or starts it -- that's what avoids the AEC
+ // cold-start hiss on unmute. Capture start/stop is tied to device
+ // selection (workerStartRecording) and shutdown, not to mute.
if (mPeerCustomProcessor)
{
mPeerCustomProcessor->setGain(mMute ? 0.0f : mGain);
}
-
- // Sequence counter to prevent race conditions from rapid requests to mute/unmute
- static std::atomic<uint32_t> mute_sequence(0);
- uint32_t current_sequence = ++mute_sequence;
-
- if (mMute)
- {
- mWorkerThread->PostDelayedTask(
- [this, current_sequence]
- {
- if (mDeviceModule && (current_sequence == mute_sequence.load()))
- {
- mDeviceModule->ForceStopRecording();
- }
- },
- webrtc::TimeDelta::Millis(delay_ms));
- }
- else
- {
- mWorkerThread->PostTask(
- [this, current_sequence]
- {
- if (mDeviceModule && (current_sequence == mute_sequence.load()))
- {
- mDeviceModule->InitRecording();
- mDeviceModule->ForceStartRecording();
- }
- });
- }
}
//
@@ -770,8 +960,7 @@ void LLWebRTCImpl::intSetMute(bool mute, int delay_ms)
LLWebRTCPeerConnectionInterface *LLWebRTCImpl::newPeerConnection()
{
- bool empty = mPeerConnections.empty();
- webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl> peerConnection = webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl>(new webrtc::RefCountedObject<LLWebRTCPeerConnectionImpl>());
+ webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl> peerConnection = webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl>(new webrtc::RefCountedObject<LLWebRTCPeerConnectionImpl>(mEnv));
peerConnection->init(this);
if (mPeerConnections.empty())
{
@@ -779,6 +968,13 @@ LLWebRTCPeerConnectionInterface *LLWebRTCImpl::newPeerConnection()
}
mPeerConnections.emplace_back(peerConnection);
+ // Playout is intentionally NOT started here. This runs when the connection
+ // is created/connecting; starting the output device now leaves it spinning
+ // with no decoded audio during the handshake, which is heard as a buzz.
+ // Playout is started from OnConnectionChange(kConnected) instead, once audio
+ // is actually established (see startPlayout()). Capture follows
+ // voice-enabled state, so it's not touched here either.
+
peerConnection->enableSenderTracks(false);
peerConnection->resetMute();
return peerConnection.get();
@@ -795,10 +991,45 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn
if (mPeerConnections.empty())
{
intSetMute(true);
+ // Last connection gone: stop playout (there's nothing to render).
+ // Capture stays running while voice is enabled so it's ready -- with
+ // no cold-start hiss -- when the next call comes up. But if voice
+ // has been disabled, stop capture now: setVoiceEnabled(false) tried
+ // to, but the engine's send stream was still active then (and the
+ // engine's own StopRecording is intentionally a no-op), so the stop
+ // only sticks once the connection -- and its stream -- is gone.
+ mWorkerThread->PostTask(
+ [this]()
+ {
+ if (mDeviceModule)
+ {
+ mDeviceModule->StopPlayout();
+ if (!mVoiceEnabled)
+ {
+ mDeviceModule->ForceStopRecording();
+ }
+ }
+ });
}
}
}
+void LLWebRTCImpl::startPlayout()
+{
+ // Called when a connection's audio is established. Only playout is started
+ // here: it's gated on there being a connection to render, because running
+ // the output device with no engine data is heard as a buzz. Capture is
+ // NOT touched here -- it follows voice-enabled state (setVoiceEnabled), so
+ // it's already running if voice is on and must stay off if voice is off.
+ // Starting it here would also let a stray kConnected during voice-disable
+ // teardown re-open the mic.
+ mWorkerThread->PostTask(
+ [this]()
+ {
+ workerStartPlayout();
+ });
+}
+
//
// LLWebRTCPeerConnectionImpl implementation.
@@ -806,13 +1037,16 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn
// Most peer connection (signaling) happens on
// the signaling thread.
-LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() :
+LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl(const webrtc::Environment& env) :
+ mEnv(env),
mWebRTCImpl(nullptr),
mPeerConnection(nullptr),
mMute(MUTE_INITIAL),
mAnswerReceived(false),
mPeerConnectionState(webrtc::PeerConnectionInterface::PeerConnectionState::kNew),
mDisconnectCount(0),
+ mStatsRequestPending(false),
+ mShuttingDown(false),
mPendingJobs(0)
{
}
@@ -845,47 +1079,64 @@ void LLWebRTCPeerConnectionImpl::terminate()
mWebRTCImpl->PostSignalingTask(
[self]()
{
- if (self->mPeerConnection)
- {
- if (self->mDataChannel)
- {
- {
- self->mDataChannel->Close();
- self->mDataChannel = nullptr;
- }
- }
+ self->closeOnSignalingThread();
+ self->mPendingJobs--;
+ });
+}
- // to remove 'Secondlife is recording' icon from taskbar
- // if user was speaking
- auto senders = self->mPeerConnection->GetSenders();
- for (auto& sender : senders)
- {
- auto track = sender->track();
- if (track)
- {
- track->set_enabled(false);
- }
- }
+// Signaling thread only.
+void LLWebRTCPeerConnectionImpl::closeOnSignalingThread()
+{
+ // Stop issuing stats requests; one may already be in flight, and
+ // Close() below will flush it.
+ mShuttingDown = true;
- self->mPeerConnection->Close();
- if (self->mLocalStream)
- {
- auto tracks = self->mLocalStream->GetAudioTracks();
- for (auto& track : tracks)
- {
- self->mLocalStream->RemoveTrack(track);
- }
- self->mLocalStream = nullptr;
- }
- self->mPeerConnection = nullptr;
+ if (mPeerConnection)
+ {
+ if (mDataChannel)
+ {
+ mDataChannel->Close();
+ mDataChannel = nullptr;
+ }
- for (auto &observer : self->mSignalingObserverList)
- {
- observer->OnPeerConnectionClosed();
- }
+ // to remove 'Secondlife is recording' icon from taskbar
+ // if user was speaking
+ auto senders = mPeerConnection->GetSenders();
+ for (auto& sender : senders)
+ {
+ auto track = sender->track();
+ if (track)
+ {
+ track->set_enabled(false);
}
- self->mPendingJobs--;
- });
+ }
+
+ // NOTE: Close() delivers any pending GetStats report inline, before it
+ // returns, so the observer list below must still be valid here.
+ mPeerConnection->Close();
+ if (mLocalStream)
+ {
+ auto tracks = mLocalStream->GetAudioTracks();
+ for (auto& track : tracks)
+ {
+ mLocalStream->RemoveTrack(track);
+ }
+ mLocalStream = nullptr;
+ }
+ mPeerConnection = nullptr;
+
+ for (auto &observer : mSignalingObserverList)
+ {
+ observer->OnPeerConnectionClosed();
+ }
+ }
+
+ // Nothing may call back into the viewer past this point. On shutdown the
+ // viewer's connection objects are torn down as soon as llwebrtc::terminate()
+ // returns and they deliberately don't unset themselves as observers, so any
+ // late callback would be reaching into freed memory.
+ mSignalingObserverList.clear();
+ mDataObserverList.clear();
}
void LLWebRTCPeerConnectionImpl::setSignalingObserver(LLWebRTCSignalingObserver *observer) { mSignalingObserverList.emplace_back(observer); }
@@ -1255,6 +1506,12 @@ void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterf
{
case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
{
+ // Audio is established now -- start playout for this connection.
+ // (Capture follows voice-enabled state, so it's already running and
+ // isn't touched here.) Doing playout here rather than at connection
+ // creation avoids running the output device with no decoded audio
+ // during the handshake (heard as a buzz).
+ mWebRTCImpl->startPlayout();
mPendingJobs++;
webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl> self(this);
mWebRTCImpl->PostWorkerTask([self]()
@@ -1267,6 +1524,7 @@ void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterf
});
break;
}
+
case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed:
{
for (auto &observer : mSignalingObserverList)
@@ -1605,16 +1863,41 @@ void LLWebRTCPeerConnectionImpl::gatherConnectionStats()
return;
}
- auto stats_callback = webrtc::make_ref_counted<LLStatsCollectorCallback>(
- [this](const LLWebRTCStatsMap& generic_stats)
+ webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl> self(this);
+ mWebRTCImpl->PostSignalingTask(
+ [self]()
+ {
+ if (!self->mPeerConnection
+ || self->mShuttingDown
+ || self->mPeerConnectionState != webrtc::PeerConnectionInterface::PeerConnectionState::kConnected
+ || self->mStatsRequestPending) // signaling thread only
+ {
+ return;
+ }
+
+ self->mStatsRequestPending = true;
+
+ auto stats_callback = webrtc::make_ref_counted<LLStatsCollectorCallback>(
+ [self](const LLWebRTCStatsMap& generic_stats)
{
- for (auto& observer : mSignalingObserverList)
+ self->mStatsRequestPending = false;
+
+ // This can be delivered inline from PeerConnection::Close(), which
+ // flushes pending stats requests as it tears down. Don't call out
+ // to the observers in that case -- we're on our way out.
+ if (!self->mPeerConnection || self->mShuttingDown)
+ {
+ return;
+ }
+
+ for (auto& observer : self->mSignalingObserverList)
{
observer->OnStatsDelivered(generic_stats);
}
});
- mPeerConnection->GetStats(stats_callback.get());
+ self->mPeerConnection->GetStats(stats_callback.get());
+ });
}
LLWebRTCImpl * gWebRTCImpl = nullptr;
diff --git a/indra/llwebrtc/llwebrtc.h b/indra/llwebrtc/llwebrtc.h
index e76e708f0c..821400cfe8 100644
--- a/indra/llwebrtc/llwebrtc.h
+++ b/indra/llwebrtc/llwebrtc.h
@@ -153,6 +153,14 @@ class LLWebRTCDeviceInterface
virtual void setCaptureDevice(const std::string& id) = 0;
virtual void setRenderDevice(const std::string& id) = 0;
+ // Enable/disable the audio devices, set when voice is enabled/disabled.
+ // The capture (microphone) and playout (speaker) devices only run while this
+ // is enabled, so neither is held open when the user has voice off. While
+ // enabled, capture stays running across calls and mute/unmute so the AEC
+ // never cold-starts (no unmute hiss); playout still only runs when there's a
+ // connection to render.
+ virtual void setVoiceEnabled(bool enable) = 0;
+
// Device observers for device change callbacks.
virtual void setDevicesObserver(LLWebRTCDevicesObserver *observer) = 0;
virtual void unsetDevicesObserver(LLWebRTCDevicesObserver *observer) = 0;
diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h
index bd7a2e0bcf..cee42cf19a 100644
--- a/indra/llwebrtc/llwebrtc_impl.h
+++ b/indra/llwebrtc/llwebrtc_impl.h
@@ -180,7 +180,7 @@ private:
class LLWebRTCAudioDeviceModule : public webrtc::AudioDeviceModule
{
public:
- explicit LLWebRTCAudioDeviceModule(webrtc::scoped_refptr<webrtc::AudioDeviceModule> inner) : inner_(std::move(inner)), tuning_(false)
+ explicit LLWebRTCAudioDeviceModule(webrtc::scoped_refptr<webrtc::AudioDeviceModule> inner) : inner_(inner), tuning_(false)
{
RTC_CHECK(inner_);
}
@@ -197,9 +197,15 @@ public:
}
int32_t Init() override { return inner_->Init(); }
- int32_t Terminate() override { return inner_->Terminate(); }
+ int32_t Terminate() override {
+ // libwebrtc attempts to terminate the adm when peer connections go to zero, but we don't want that,
+ // now that we're keeping the adm active throughout the session.
+ return 0;
+ }
bool Initialized() const override { return inner_->Initialized(); }
+ int32_t ForceTerminate() { return inner_->Terminate(); }
+
// --- Device enumeration/selection (forward) ---
int16_t PlayoutDevices() override { return inner_->PlayoutDevices(); }
int16_t RecordingDevices() override { return inner_->RecordingDevices(); }
@@ -323,30 +329,8 @@ public:
// tuning microphone energy calculations
float GetMicrophoneEnergy() { return audio_transport_.GetMicrophoneEnergy(); }
void SetTuningMicGain(float gain) { audio_transport_.SetGain(gain); }
- void SetTuning(bool tuning, bool mute)
- {
- tuning_ = tuning;
- if (tuning)
- {
- inner_->InitRecording();
- inner_->StartRecording();
- inner_->StopPlayout();
- }
- else
- {
- if (mute)
- {
- inner_->StopRecording();
- }
- else
- {
- inner_->InitRecording();
- inner_->StartRecording();
- }
- inner_->InitPlayout();
- inner_->StartPlayout();
- }
- }
+
+ void SetTuning(bool tuning, bool mute);
protected:
~LLWebRTCAudioDeviceModule() override = default;
@@ -436,7 +420,6 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceO
//
void setAudioConfig(LLWebRTCDeviceInterface::AudioConfig config = LLWebRTCDeviceInterface::AudioConfig()) override;
-
void refreshDevices() override;
void setDevicesObserver(LLWebRTCDevicesObserver *observer) override;
@@ -445,6 +428,8 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceO
void setCaptureDevice(const std::string& id) override;
void setRenderDevice(const std::string& id) override;
+ void setVoiceEnabled(bool enable) override;
+
void setTuningMode(bool enable) override;
float getTuningAudioLevel() override;
float getPeerConnectionAudioLevel() override;
@@ -522,9 +507,23 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceO
LLWebRTCPeerConnectionInterface* newPeerConnection();
void freePeerConnection(LLWebRTCPeerConnectionInterface* peer_connection);
+ // Start playout once a connection's audio is established (playout is gated
+ // on there being a connection to render). Capture is not touched here --
+ // it follows voice-enabled state, not connection state. Safe to call from
+ // any thread (work is posted to the worker thread).
+ void startPlayout();
+
protected:
+ const webrtc::Environment mEnv;
+ void workerStartRecording();
+ void workerStartPlayout();
void workerDeployDevices();
+ // We always rely on WebRTC's internal (software APM) audio processing, so
+ // any platform/hardware AEC/AGC/NS must be kept disabled.
+ void workerDisableBuiltInAudioProcessing();
+
+
LLWebRTCLogSink* mLogSink;
// The native webrtc threads
@@ -537,10 +536,6 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceO
webrtc::scoped_refptr<webrtc::AudioProcessing> mAudioProcessingModule;
- // more native webrtc stuff
- std::unique_ptr<webrtc::TaskQueueFactory> mTaskQueueFactory;
-
-
// Devices
void updateDevices();
void deployDevices();
@@ -548,6 +543,10 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceO
webrtc::scoped_refptr<LLWebRTCAudioDeviceModule> mDeviceModule;
std::vector<LLWebRTCDevicesObserver *> mVoiceDevicesObserverList;
+ bool mBuiltinNS;
+ bool mBuiltinAGC;
+ bool mBuiltinAEC;
+
// accessors in native webrtc for devices aren't apparently implemented yet.
bool mTuningMode;
std::string mRecordingDevice;
@@ -557,6 +556,8 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceO
LLWebRTCVoiceDeviceList mPlayoutDeviceList;
bool mMute;
+ // Whether voice is enabled; gates whether the capture/playout devices run.
+ bool mVoiceEnabled;
float mGain;
LLCustomProcessorStatePtr mPeerCustomProcessor;
@@ -580,11 +581,16 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
{
public:
- LLWebRTCPeerConnectionImpl();
+ LLWebRTCPeerConnectionImpl(const webrtc::Environment& env);
~LLWebRTCPeerConnectionImpl();
void init(LLWebRTCImpl * webrtc_impl);
+ // Posts closeOnSignalingThread() and returns immediately.
void terminate();
+ // The actual close. Signaling thread only. Callable directly (via a
+ // BlockingCall) when the caller needs the connection to be fully closed
+ // before it continues -- see LLWebRTCImpl::terminate().
+ void closeOnSignalingThread();
virtual void AddRef() const override = 0;
virtual webrtc::RefCountReleaseStatus Release() const override = 0;
@@ -659,7 +665,7 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
void gatherConnectionStats() override;
protected:
-
+ const webrtc::Environment mEnv;
LLWebRTCImpl * mWebRTCImpl;
webrtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory;
@@ -687,6 +693,14 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
webrtc::PeerConnectionInterface::PeerConnectionState mPeerConnectionState;
uint32_t mDisconnectCount;
+ // Accessed only on the WebRTC signaling thread.
+ bool mStatsRequestPending;
+
+ // Set by closeOnSignalingThread() so that no new stats request (or other
+ // callback into the viewer) is issued while we're tearing down.
+ // Accessed only on the WebRTC signaling thread.
+ bool mShuttingDown;
+
std::atomic<int> mPendingJobs;
};
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 3dae2d1067..5f8a9a64eb 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
@@ -66,11 +68,13 @@ set(macosx_HEADER_FILES
)
set(linux_SOURCE_FILES
+ llsdl.cpp
llkeyboardsdl.cpp
llwindowsdl.cpp
)
set(linux_HEADER_FILES
+ llsdl.h
llkeyboardsdl.h
llwindowsdl.h
)
@@ -99,28 +103,16 @@ 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 ${linux_SOURCE_FILES})
list(APPEND viewer_HEADER_FILES ${linux_HEADER_FILES})
- 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 ${macosx_SOURCE_FILES})
@@ -133,6 +125,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)
@@ -147,32 +146,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)
@@ -224,14 +246,16 @@ elseif (LINUX)
)
endif()
-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 b642736d8e..df69b1390c 100644
--- a/indra/llwindow/llkeyboard.cpp
+++ b/indra/llwindow/llkeyboard.cpp
@@ -43,7 +43,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
//
@@ -164,6 +163,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
@@ -197,12 +197,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;
@@ -216,11 +214,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;
@@ -232,7 +228,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;
@@ -260,7 +256,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 067445d24c..a092787cef 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -54,6 +54,13 @@ class LLWindowCallbacks;
class LLKeyboard
{
public:
+#ifdef LL_SDL_WINDOW
+ // linux relies on SDL 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();
@@ -66,16 +73,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
@@ -110,8 +116,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..e4d096e2e9 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 > mSDL_to_Win;
+
+U32 LLKeyboardSDL::mapSDLtoWin( 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( mSDL_to_Win.empty() )
+ {
+
+ mSDL_to_Win[ SDLK_BACKSPACE ] = (U32)WindowsVK::LL_VK_BACK;
+ mSDL_to_Win[ SDLK_TAB ] = (U32)WindowsVK::LL_VK_TAB;
+ mSDL_to_Win[ 12 ] = (U32)WindowsVK::LL_VK_CLEAR;
+ mSDL_to_Win[ SDLK_RETURN ] = (U32)WindowsVK::LL_VK_RETURN;
+ mSDL_to_Win[ 19 ] = (U32)WindowsVK::LL_VK_PAUSE;
+ mSDL_to_Win[ SDLK_ESCAPE ] = (U32)WindowsVK::LL_VK_ESCAPE;
+ mSDL_to_Win[ SDLK_SPACE ] = (U32)WindowsVK::LL_VK_SPACE;
+ mSDL_to_Win[ SDLK_APOSTROPHE ] = (U32)WindowsVK::LL_VK_OEM_7;
+ mSDL_to_Win[ SDLK_COMMA ] = (U32)WindowsVK::LL_VK_OEM_COMMA;
+ mSDL_to_Win[ SDLK_MINUS ] = (U32)WindowsVK::LL_VK_OEM_MINUS;
+ mSDL_to_Win[ SDLK_PERIOD ] = (U32)WindowsVK::LL_VK_OEM_PERIOD;
+ mSDL_to_Win[ SDLK_SLASH ] = (U32)WindowsVK::LL_VK_OEM_2;
+
+ mSDL_to_Win[ SDLK_0 ] = (U32)WindowsVK::LL_VK_0;
+ mSDL_to_Win[ SDLK_1 ] = (U32)WindowsVK::LL_VK_1;
+ mSDL_to_Win[ SDLK_2 ] = (U32)WindowsVK::LL_VK_2;
+ mSDL_to_Win[ SDLK_3 ] = (U32)WindowsVK::LL_VK_3;
+ mSDL_to_Win[ SDLK_4 ] = (U32)WindowsVK::LL_VK_4;
+ mSDL_to_Win[ SDLK_5 ] = (U32)WindowsVK::LL_VK_5;
+ mSDL_to_Win[ SDLK_6 ] = (U32)WindowsVK::LL_VK_6;
+ mSDL_to_Win[ SDLK_7 ] = (U32)WindowsVK::LL_VK_7;
+ mSDL_to_Win[ SDLK_8 ] = (U32)WindowsVK::LL_VK_8;
+ mSDL_to_Win[ SDLK_9 ] = (U32)WindowsVK::LL_VK_9;
+
+ mSDL_to_Win[ SDLK_SEMICOLON ] = (U32)WindowsVK::LL_VK_OEM_1;
+ mSDL_to_Win[ SDLK_LESS ] = (U32)WindowsVK::LL_VK_OEM_102;
+ mSDL_to_Win[ SDLK_EQUALS ] = (U32)WindowsVK::LL_VK_OEM_PLUS;
+ mSDL_to_Win[ SDLK_KP_EQUALS ] = (U32)WindowsVK::LL_VK_OEM_PLUS;
+
+ mSDL_to_Win[ SDLK_LEFTBRACKET ] = (U32)WindowsVK::LL_VK_OEM_4;
+ mSDL_to_Win[ SDLK_BACKSLASH ] = (U32)WindowsVK::LL_VK_OEM_5;
+ mSDL_to_Win[ SDLK_RIGHTBRACKET ] = (U32)WindowsVK::LL_VK_OEM_6;
+ mSDL_to_Win[ SDLK_GRAVE ] = (U32)WindowsVK::LL_VK_OEM_8;
+
+ mSDL_to_Win[ SDLK_A ] = (U32)WindowsVK::LL_VK_A;
+ mSDL_to_Win[ SDLK_B ] = (U32)WindowsVK::LL_VK_B;
+ mSDL_to_Win[ SDLK_C ] = (U32)WindowsVK::LL_VK_C;
+ mSDL_to_Win[ SDLK_D ] = (U32)WindowsVK::LL_VK_D;
+ mSDL_to_Win[ SDLK_E ] = (U32)WindowsVK::LL_VK_E;
+ mSDL_to_Win[ SDLK_F ] = (U32)WindowsVK::LL_VK_F;
+ mSDL_to_Win[ SDLK_G ] = (U32)WindowsVK::LL_VK_G;
+ mSDL_to_Win[ SDLK_H ] = (U32)WindowsVK::LL_VK_H;
+ mSDL_to_Win[ SDLK_I ] = (U32)WindowsVK::LL_VK_I;
+ mSDL_to_Win[ SDLK_J ] = (U32)WindowsVK::LL_VK_J;
+ mSDL_to_Win[ SDLK_K ] = (U32)WindowsVK::LL_VK_K;
+ mSDL_to_Win[ SDLK_L ] = (U32)WindowsVK::LL_VK_L;
+ mSDL_to_Win[ SDLK_M ] = (U32)WindowsVK::LL_VK_M;
+ mSDL_to_Win[ SDLK_N ] = (U32)WindowsVK::LL_VK_N;
+ mSDL_to_Win[ SDLK_O ] = (U32)WindowsVK::LL_VK_O;
+ mSDL_to_Win[ SDLK_P ] = (U32)WindowsVK::LL_VK_P;
+ mSDL_to_Win[ SDLK_Q ] = (U32)WindowsVK::LL_VK_Q;
+ mSDL_to_Win[ SDLK_R ] = (U32)WindowsVK::LL_VK_R;
+ mSDL_to_Win[ SDLK_S ] = (U32)WindowsVK::LL_VK_S;
+ mSDL_to_Win[ SDLK_T ] = (U32)WindowsVK::LL_VK_T;
+ mSDL_to_Win[ SDLK_Y ] = (U32)WindowsVK::LL_VK_U;
+ mSDL_to_Win[ SDLK_V ] = (U32)WindowsVK::LL_VK_V;
+ mSDL_to_Win[ SDLK_W ] = (U32)WindowsVK::LL_VK_W;
+ mSDL_to_Win[ SDLK_X ] = (U32)WindowsVK::LL_VK_X;
+ mSDL_to_Win[ SDLK_Y ] = (U32)WindowsVK::LL_VK_Y;
+ mSDL_to_Win[ SDLK_Z ] = (U32)WindowsVK::LL_VK_Z;
+ mSDL_to_Win[ SDLK_DELETE ] = (U32)WindowsVK::LL_VK_DELETE;
+
+
+ mSDL_to_Win[ SDLK_NUMLOCKCLEAR ] = (U32)WindowsVK::LL_VK_NUMLOCK;
+ mSDL_to_Win[ SDLK_SCROLLLOCK ] = (U32)WindowsVK::LL_VK_SCROLL;
+
+ mSDL_to_Win[ SDLK_HELP ] = (U32)WindowsVK::LL_VK_HELP;
+ mSDL_to_Win[ SDLK_PRINTSCREEN ] = (U32)WindowsVK::LL_VK_SNAPSHOT;
+ mSDL_to_Win[ SDLK_CANCEL ] = (U32)WindowsVK::LL_VK_CANCEL;
+ mSDL_to_Win[ SDLK_APPLICATION ] = (U32)WindowsVK::LL_VK_APPS;
+
+ mSDL_to_Win[ SDLK_UNKNOWN ] = (U32)WindowsVK::LL_VK_UNKNOWN;
+ mSDL_to_Win[ SDLK_BACKSPACE ] = (U32)WindowsVK::LL_VK_BACK;
+ mSDL_to_Win[ SDLK_TAB ] = (U32)WindowsVK::LL_VK_TAB;
+ mSDL_to_Win[ SDLK_CLEAR ] = (U32)WindowsVK::LL_VK_CLEAR;
+ mSDL_to_Win[ SDLK_RETURN ] = (U32)WindowsVK::LL_VK_RETURN;
+ mSDL_to_Win[ SDLK_PAUSE ] = (U32)WindowsVK::LL_VK_PAUSE;
+ mSDL_to_Win[ SDLK_ESCAPE ] = (U32)WindowsVK::LL_VK_ESCAPE;
+ mSDL_to_Win[ SDLK_DELETE ] = (U32)WindowsVK::LL_VK_DELETE;
+
+ mSDL_to_Win[ SDLK_KP_PERIOD ] = (U32)WindowsVK::LL_VK_DELETE; // LL_VK_DECIMAL?
+ mSDL_to_Win[ SDLK_KP_DIVIDE ] = (U32)WindowsVK::LL_VK_DIVIDE;
+ mSDL_to_Win[ SDLK_KP_MULTIPLY] = (U32)WindowsVK::LL_VK_MULTIPLY;
+ mSDL_to_Win[ SDLK_KP_MINUS ] = (U32)WindowsVK::LL_VK_OEM_MINUS; // LL_VK_SUBSTRACT?
+ mSDL_to_Win[ SDLK_KP_PLUS ] = (U32)WindowsVK::LL_VK_OEM_PLUS; // LL_VK_ADD?
+ mSDL_to_Win[ SDLK_KP_ENTER ] = (U32)WindowsVK::LL_VK_RETURN;
+ mSDL_to_Win[ SDLK_KP_0 ] = (U32)WindowsVK::LL_VK_INSERT;
+ mSDL_to_Win[ SDLK_KP_1 ] = (U32)WindowsVK::LL_VK_END;
+ mSDL_to_Win[ SDLK_KP_2 ] = (U32)WindowsVK::LL_VK_DOWN;
+ mSDL_to_Win[ SDLK_KP_3 ] = (U32)WindowsVK::LL_VK_NEXT;
+ mSDL_to_Win[ SDLK_KP_4 ] = (U32)WindowsVK::LL_VK_LEFT;
+ mSDL_to_Win[ SDLK_KP_5 ] = (U32)WindowsVK::LL_VK_NUMPAD5;
+ mSDL_to_Win[ SDLK_KP_6 ] = (U32)WindowsVK::LL_VK_RIGHT;
+ mSDL_to_Win[ SDLK_KP_7 ] = (U32)WindowsVK::LL_VK_HOME;
+ mSDL_to_Win[ SDLK_KP_8 ] = (U32)WindowsVK::LL_VK_UP;
+ mSDL_to_Win[ SDLK_KP_9 ] = (U32)WindowsVK::LL_VK_PRIOR;
+
+ // ?
+
+ mSDL_to_Win[ SDLK_UP ] = (U32)WindowsVK::LL_VK_UP;
+ mSDL_to_Win[ SDLK_DOWN ] = (U32)WindowsVK::LL_VK_DOWN;
+ mSDL_to_Win[ SDLK_RIGHT ] = (U32)WindowsVK::LL_VK_RIGHT;
+ mSDL_to_Win[ SDLK_LEFT ] = (U32)WindowsVK::LL_VK_LEFT;
+ mSDL_to_Win[ SDLK_INSERT ] = (U32)WindowsVK::LL_VK_INSERT;
+ mSDL_to_Win[ SDLK_HOME ] = (U32)WindowsVK::LL_VK_HOME;
+ mSDL_to_Win[ SDLK_END ] = (U32)WindowsVK::LL_VK_END;
+ mSDL_to_Win[ SDLK_PAGEUP ] = (U32)WindowsVK::LL_VK_PRIOR;
+ mSDL_to_Win[ SDLK_PAGEDOWN ] = (U32)WindowsVK::LL_VK_NEXT;
+ mSDL_to_Win[ SDLK_F1 ] = (U32)WindowsVK::LL_VK_F1;
+ mSDL_to_Win[ SDLK_F2 ] = (U32)WindowsVK::LL_VK_F2;
+ mSDL_to_Win[ SDLK_F3 ] = (U32)WindowsVK::LL_VK_F3;
+ mSDL_to_Win[ SDLK_F4 ] = (U32)WindowsVK::LL_VK_F4;
+ mSDL_to_Win[ SDLK_F5 ] = (U32)WindowsVK::LL_VK_F5;
+ mSDL_to_Win[ SDLK_F6 ] = (U32)WindowsVK::LL_VK_F6;
+ mSDL_to_Win[ SDLK_F7 ] = (U32)WindowsVK::LL_VK_F7;
+ mSDL_to_Win[ SDLK_F8 ] = (U32)WindowsVK::LL_VK_F8;
+ mSDL_to_Win[ SDLK_F9 ] = (U32)WindowsVK::LL_VK_F9;
+ mSDL_to_Win[ SDLK_F10 ] = (U32)WindowsVK::LL_VK_F10;
+ mSDL_to_Win[ SDLK_F11 ] = (U32)WindowsVK::LL_VK_F11;
+ mSDL_to_Win[ SDLK_F12 ] = (U32)WindowsVK::LL_VK_F12;
+ mSDL_to_Win[ SDLK_F13 ] = (U32)WindowsVK::LL_VK_F13;
+ mSDL_to_Win[ SDLK_F14 ] = (U32)WindowsVK::LL_VK_F14;
+ mSDL_to_Win[ SDLK_F15 ] = (U32)WindowsVK::LL_VK_F15;
+ mSDL_to_Win[ SDLK_CAPSLOCK ] = (U32)WindowsVK::LL_VK_CAPITAL;
+ mSDL_to_Win[ SDLK_RSHIFT ] = (U32)WindowsVK::LL_VK_SHIFT;
+ mSDL_to_Win[ SDLK_LSHIFT ] = (U32)WindowsVK::LL_VK_SHIFT;
+ mSDL_to_Win[ SDLK_RCTRL ] = (U32)WindowsVK::LL_VK_CONTROL;
+ mSDL_to_Win[ SDLK_LCTRL ] = (U32)WindowsVK::LL_VK_CONTROL;
+ mSDL_to_Win[ SDLK_RALT ] = (U32)WindowsVK::LL_VK_MENU;
+ mSDL_to_Win[ SDLK_LALT ] = (U32)WindowsVK::LL_VK_MENU;
+
+ mSDL_to_Win[ SDLK_MENU ] = (U32)WindowsVK::LL_VK_MENU;
+
+ // LL_VK_MODECHANGE ?
+ // mSDL_to_Win[ SDLK_MODE ] = (U32)WindowsVK::LL_VK_MODE;
+
+ // ?
+ // mSDL_to_Win[ SDLK_SYSREQ ] = (U32)WindowsVK::LL_VK_SYSREQ;
+ // mSDL_to_Win[ SDLK_POWER ] = (U32)WindowsVK::LL_VK_POWER;
+ // mSDL_to_Win[ SDLK_UNDO ] = (U32)WindowsVK::LL_VK_UNDO;
+ // mSDL_to_Win[ SDLK_KP_EQUALS ] = (U32)WindowsVK::LL_VK_EQUALS;
+ // mSDL_to_Win[ 311 ] = (U32)WindowsVK::LL_VK_LWIN;
+ // mSDL_to_Win[ 312 ] = (U32)WindowsVK::LL_VK_RWIN;
+ // mSDL_to_Win[ SDLK_COLON ] = ?
+ }
+
+ auto itr = mSDL_to_Win.find( aSymbol );
+ if( itr != mSDL_to_Win.end() )
+ return itr->second;
+
+ return aSymbol;
+}
diff --git a/indra/llwindow/llkeyboardsdl.h b/indra/llwindow/llkeyboardsdl.h
index fd348b28f2..2ebe647561 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 mapSDLtoWin( 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..bc38120386
--- /dev/null
+++ b/indra/llwindow/llsdl.cpp
@@ -0,0 +1,149 @@
+/**
+ * @file llsdl.cpp
+ * @brief SDL 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/llmath/coordframe.h b/indra/llwindow/llsdl.h
index e7395b1212..6c9c9eb07c 100644
--- a/indra/llmath/coordframe.h
+++ b/indra/llwindow/llsdl.h
@@ -1,8 +1,8 @@
/**
- * @file coordframe.h
- * @brief Legacy wrapper header.
+ * @file llsdl.h
+ * @brief SDL initialization
*
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
@@ -24,4 +24,11 @@
* $/LicenseInfo$
*/
-#include "llcoordframe.h"
+#pragma once
+
+#include "llpreprocessor.h"
+
+extern bool gSDLMainHandled;
+
+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 185940e32d..e9dfa3aba4 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/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
index 8d1eebe33d..f997aebb9d 100644
--- a/indra/llwindow/llwindowcallbacks.cpp
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -202,7 +202,7 @@ bool LLWindowCallbacks::handleTimerEvent(LLWindow *window)
return false;
}
-bool LLWindowCallbacks::handleDeviceChange(LLWindow *window)
+bool LLWindowCallbacks::handleDeviceChange(LLWindow *window, const std::string& change_type)
{
return false;
}
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
index 390e3ff93a..cd54ccd7c9 100644
--- a/indra/llwindow/llwindowcallbacks.h
+++ b/indra/llwindow/llwindowcallbacks.h
@@ -72,7 +72,7 @@ public:
virtual void handleWindowUnblock(LLWindow *window); // window coming back after taking over CPU for a while
virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data);
virtual bool handleTimerEvent(LLWindow *window);
- virtual bool handleDeviceChange(LLWindow *window);
+ virtual bool handleDeviceChange(LLWindow *window, const std::string& change_type);
virtual bool handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
virtual bool handleDisplayChanged();
virtual bool handleWindowDidChangeScreen(LLWindow *window);
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/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index d703a84d02..dc8b7504c9 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -36,11 +36,6 @@
#include <ApplicationServices/ApplicationServices.h>
#include <OpenGL/OpenGL.h>
-// AssertMacros.h does bad things.
-#include "fix_macros.h"
-#undef verify
-#undef require
-
class LLWindowMacOSX : public LLWindow
{
public:
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..2d8a74c782 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::mapSDLtoWin( 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 3c7b83bde4..3fccc1fbff 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -227,6 +227,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;
@@ -465,6 +466,16 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
}
});
}
+
+ // For mainWindowProc, it should not unpause watchdog if it was paused
+ void pingWindowTimeout(std::string_view state)
+ {
+ if (mWindowTimeout && mWindowTimeout->started())
+ {
+ mWindowTimeout->setTimeout(WINDOW_TIMEOUT_SEC);
+ mWindowTimeout->ping(state);
+ }
+ }
private:
// These timeout related functions are strictly for the thread.
void resumeTimeout(std::string_view state)
@@ -529,7 +540,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");
// Request high-performance GPU before creating OpenGL context
// This increases probability of discrete GPU being used when
@@ -1779,6 +1790,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"), LLError::LLUserWarningMsg::ERROR_INIT_FAILED);
@@ -2427,18 +2440,45 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_DEVICECHANGE:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_DEVICECHANGE");
+ window_imp->mWindowThread->pingWindowTimeout("WM_DEVICECHANGE");
+
+ // Log detailed device change information
+ std::string change_type = "UNKNOWN";
+ switch (w_param)
+ {
+ case DBT_DEVICEARRIVAL: change_type = "DBT_DEVICEARRIVAL"; break;
+ case DBT_DEVICEREMOVECOMPLETE: change_type = "DBT_DEVICEREMOVECOMPLETE"; break;
+ case DBT_DEVNODES_CHANGED: change_type = "DBT_DEVNODES_CHANGED"; break;
+ case DBT_DEVICEQUERYREMOVE: change_type = "DBT_DEVICEQUERYREMOVE"; break;
+ case DBT_DEVICEQUERYREMOVEFAILED: change_type = "DBT_DEVICEQUERYREMOVEFAILED"; break;
+ case DBT_DEVICEREMOVEPENDING: change_type = "DBT_DEVICEREMOVEPENDING"; break;
+ case DBT_CONFIGCHANGED: change_type = "DBT_CONFIGCHANGED"; break;
+ }
+
if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL)
{
- WINDOW_IMP_POST(window_imp->mCallbacks->handleDeviceChange(window_imp));
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleDeviceChange(window_imp, change_type));
return 1;
}
+ else if (l_param)
+ {
+ const auto* hdr = reinterpret_cast<const DEV_BROADCAST_HDR*>(l_param);
+ if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
+ {
+ // Might need to register for monitor device notifications
+ // to get this message when monitor is suspended or resumed.
+ // TODO: log monitor suspending and resuming.
+ LL_INFOS("Window") << "DEVICEINTERFACE: " << change_type << LL_ENDL;
+ }
+ }
break;
}
case WM_PAINT:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_PAINT");
+ window_imp->mWindowThread->pingWindowTimeout("WM_PAINT");
GetUpdateRect(window_imp->mWindowHandle, &update_rect, FALSE);
update_width = update_rect.right - update_rect.left + 1;
update_height = update_rect.bottom - update_rect.top + 1;
@@ -2583,6 +2623,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_CLOSE:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_CLOSE");
+ window_imp->mWindowThread->pingWindowTimeout("WM_CLOSE");
window_imp->mCallbacks->handlePreCloseRequest(); // mark app as potentially closing
if (!window_imp->mReceivedSCClose)
@@ -2651,6 +2692,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// Comes after WM_QUERYENDSESSION
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_ENDSESSION");
LL_INFOS("Window") << "Received WM_ENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL;
+ window_imp->mWindowThread->pingWindowTimeout("WM_ENDSESSION");
unsigned int end_session_flags = (U32)l_param;
if (w_param == TRUE // if true, session is ending
@@ -2719,6 +2761,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
return TRUE;
default:
+ LL_INFOS("Window") << "Received WM_POWERBROADCAST with wParam: 0x" << std::hex << (uintptr_t)w_param << " lParam: 0x" << (uintptr_t)l_param << std::dec << LL_ENDL;
break;
}
break;
@@ -3374,6 +3417,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_DPICHANGED:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_DPICHANGED");
+ window_imp->mWindowThread->pingWindowTimeout("WM_DPICHANGED");
LPRECT lprc_new_scale;
F32 new_scale = F32(LOWORD(w_param)) / F32(USER_DEFAULT_SCREEN_DPI);
lprc_new_scale = (LPRECT)l_param;
@@ -3395,6 +3439,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_DISPLAYCHANGE:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_DISPLAYCHANGE");
+ window_imp->mWindowThread->pingWindowTimeout("WM_DISPLAYCHANGE");
window_imp->post([=]() {
window_imp->mCallbacks->handleDisplayChanged();
// Note: WM_DISPLAYCHANGE was passing to WM_SETFOCUS
@@ -3443,6 +3488,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_SETTINGCHANGE:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SETTINGCHANGE");
+ // Can be called on OS user switching
+ LL_INFOS("Window") << "WM_SETTINGCHANGE, with wParam: 0x" << std::hex << (uintptr_t)w_param << " lParam: 0x" << (uintptr_t)l_param << std::dec << LL_ENDL;
+ window_imp->mWindowThread->pingWindowTimeout("WM_SETTINGCHANGE");
if (w_param == SPI_SETMOUSEVANISH)
{
if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &window_imp->mMouseVanish, 0))
@@ -4977,6 +5025,16 @@ void LLWindowWin32::requestHighPerformanceGPU() const
<< ", Vendor: 0x" << std::hex << desc.VendorId << std::dec
<< ", Flags: " << desc.Flags << LL_ENDL;
}
+ // Skip Microsoft Basic Render Driver, it's a placeholder for missing drivers
+ else if (description.find("Microsoft Basic Render Driver") != std::string::npos)
+ {
+ // User is likely missing drivers, so log a warning.
+ // Don't consider this adapter as a valid selection.
+ LL_WARNS("Window") << "Adapter " << adapterIndex << ": " << description
+ << ", Dedicated VRAM: " << (desc.DedicatedVideoMemory / 1024 / 1024) << " MB"
+ << ", Vendor: 0x" << std::hex << desc.VendorId << std::dec
+ << ", Flags: " << desc.Flags << LL_ENDL;
+ }
else
{
LL_INFOS("Window") << "Adapter " << adapterIndex << ": " << description
@@ -5260,6 +5318,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();
@@ -5277,6 +5347,13 @@ inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread()
: LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE, false)
{
LL::ThreadPool::start();
+
+ // Set thread name for the window thread
+ // This will make it distinguishable in Visual Studio debugger
+ post([this]()
+ {
+ SetThreadDescription(GetCurrentThread(), L"LLWindowWin32 Thread");
+ });
}
/**
@@ -5458,7 +5535,7 @@ void LLWindowWin32::LLWindowWin32Thread::run()
}
// Normally won't exist yet, but in case of re-init, make sure it's cleaned up
- resumeTimeout("WindowThread");
+ resumeTimeout("Window:WindowThread");
while (! getQueue().done())
{
@@ -5469,23 +5546,25 @@ void LLWindowWin32::LLWindowWin32Thread::run()
if (mWindowHandleThrd != 0)
{
- pingTimeout("messages");
MSG msg;
BOOL status;
if (mhDCThrd == 0)
{
+ pingTimeout("Window:PeekMessage");
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - PeekMessage");
logger.onChange("PeekMessage(", std::hex, mWindowHandleThrd, ")");
status = PeekMessage(&msg, mWindowHandleThrd, 0, 0, PM_REMOVE);
}
else
{
+ pingTimeout("Window:GetMessage");
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - GetMessage");
logger.always("GetMessage(", std::hex, mWindowHandleThrd, ")");
status = GetMessage(&msg, NULL, 0, 0);
}
if (status > 0)
{
+ pingTimeout("Window:TranslateMessage");
logger.always("got MSG (", std::hex, msg.hwnd, ", ", msg.message,
", ", msg.wParam, ")");
TranslateMessage(&msg);
@@ -5497,7 +5576,7 @@ void LLWindowWin32::LLWindowWin32Thread::run()
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - Function Queue");
- pingTimeout("queue");
+ pingTimeout("Window:Queue");
logger.onChange("runPending()");
//process any pending functions
getQueue().runPending();
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index defa90d1a3..956dd510dd 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -130,6 +130,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();
@@ -265,6 +266,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/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index be53a93a2d..84d03a6d0c 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -37,7 +37,6 @@
#include "llstring.h"
#include "v3math.h"
#include "v3dmath.h"
-#include "v4math.h"
#include "v4coloru.h"
#include "v4color.h"
#include "v3color.h"
@@ -64,7 +63,6 @@ template <> eControlType get_control_type<std::string>();
template <> eControlType get_control_type<LLVector3>();
template <> eControlType get_control_type<LLVector3d>();
-template <> eControlType get_control_type<LLVector4>();
template <> eControlType get_control_type<LLRect>();
template <> eControlType get_control_type<LLColor4>();
template <> eControlType get_control_type<LLColor3>();
@@ -74,7 +72,6 @@ template <> eControlType get_control_type<LLSD>();
template <> LLSD convert_to_llsd<U32>(const U32& in);
template <> LLSD convert_to_llsd<LLVector3>(const LLVector3& in);
template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in);
-template <> LLSD convert_to_llsd<LLVector4>(const LLVector4& in);
template <> LLSD convert_to_llsd<LLRect>(const LLRect& in);
template <> LLSD convert_to_llsd<LLColor4>(const LLColor4& in);
template <> LLSD convert_to_llsd<LLColor3>(const LLColor3& in);
@@ -88,7 +85,6 @@ template <> std::string convert_from_llsd<std::string>(const LLSD& sd, eControlT
template <> LLWString convert_from_llsd<LLWString>(const LLSD& sd, eControlType type, std::string_view control_name);
template <> LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd, eControlType type, std::string_view control_name);
template <> LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, std::string_view control_name);
-template <> LLVector4 convert_from_llsd<LLVector4>(const LLSD& sd, eControlType type, std::string_view control_name);
template <> LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, std::string_view control_name);
template <> LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, std::string_view control_name);
template <> LLColor4U convert_from_llsd<LLColor4U>(const LLSD& sd, eControlType type, std::string_view control_name);
@@ -128,9 +124,6 @@ bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)
case TYPE_VEC3D:
result = LLVector3d(a) == LLVector3d(b);
break;
- case TYPE_VEC4:
- result = LLVector4(a) == LLVector4(b);
- break;
case TYPE_QUAT:
result = LLQuaternion(a) == LLQuaternion(b);
break;
@@ -380,7 +373,6 @@ const std::string LLControlGroup::mTypeString[TYPE_COUNT] = { "U32"
,"Rect"
,"Color4"
,"Color3"
- ,"Vector4"
,"LLSD"
};
@@ -411,7 +403,7 @@ void LLControlGroup::cleanup()
if(mSettingsProfile && getCount.size() != 0)
{
std::string file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, SETTINGS_PROFILE);
- LLFILE* out = LLFile::fopen(file, "w"); /* Flawfinder: ignore */
+ LLFILE* out = LLFile::fopen(file, LLFILE_MODE("w")); /* Flawfinder: ignore */
if(!out)
{
LL_WARNS("SettingsProfile") << "Error opening " << SETTINGS_PROFILE << LL_ENDL;
@@ -541,11 +533,6 @@ LLControlVariable* LLControlGroup::declareVec3d(const std::string& name, const L
return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist);
}
-LLControlVariable* LLControlGroup::declareVec4(const std::string& name, const LLVector4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
-{
- return declareControl(name, TYPE_VEC4, initial_val.getValue(), comment, persist);
-}
-
LLControlVariable* LLControlGroup::declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
return declareControl(name, TYPE_QUAT, initial_val.getValue(), comment, persist);
@@ -628,11 +615,6 @@ LLVector3d LLControlGroup::getVector3d(std::string_view name)
return get<LLVector3d>(name);
}
-LLVector4 LLControlGroup::getVector4(std::string_view name)
-{
- return get<LLVector4>(name);
-}
-
LLQuaternion LLControlGroup::getQuaternion(std::string_view name)
{
return get<LLQuaternion>(name);
@@ -733,11 +715,6 @@ void LLControlGroup::setVector3d(std::string_view name, const LLVector3d &val)
set(name, val);
}
-void LLControlGroup::setVector4(std::string_view name, const LLVector4 &val)
-{
- set(name, val);
-}
-
void LLControlGroup::setQuaternion(std::string_view name, const LLQuaternion &val)
{
set(name, val);
@@ -1287,11 +1264,6 @@ template <> eControlType get_control_type<LLVector3d>()
return TYPE_VEC3D;
}
-template <> eControlType get_control_type<LLVector4>()
-{
- return TYPE_VEC4;
-}
-
template <> eControlType get_control_type<LLQuaternion>()
{
return TYPE_QUAT;
@@ -1332,11 +1304,6 @@ template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in)
{
return in.getValue();
}
-template <> LLSD convert_to_llsd<LLVector4>(const LLVector4& in)
-{
- return in.getValue();
-}
-
template <> LLSD convert_to_llsd<LLQuaternion>(const LLQuaternion& in)
{
return in.getValue();
@@ -1454,18 +1421,6 @@ LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, std:
}
template<>
-LLVector4 convert_from_llsd<LLVector4>(const LLSD& sd, eControlType type, std::string_view control_name)
-{
- if (type == TYPE_VEC4)
- return LLVector4(sd);
- else
- {
- CONTROL_ERRS << "Invalid LLVector4 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL;
- return LLVector4();
- }
-}
-
-template<>
LLQuaternion convert_from_llsd<LLQuaternion>(const LLSD& sd, eControlType type, std::string_view control_name)
{
if (type == TYPE_QUAT)
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index c2a7c22bbc..ad283c89b1 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -43,7 +43,6 @@
class LLVector3;
class LLVector3d;
-class LLVector4;
class LLQuaternion;
class LLColor4;
class LLColor3;
@@ -62,7 +61,6 @@ typedef enum e_control_type
TYPE_RECT,
TYPE_COL4,
TYPE_COL3,
- TYPE_VEC4,
TYPE_LLSD,
TYPE_COUNT
} eControlType;
@@ -198,7 +196,6 @@ public:
LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
- LLControlVariable* declareVec4(const std::string& name, const LLVector4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
LLControlVariable* declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
LLControlVariable* declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
LLControlVariable* declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
@@ -215,7 +212,6 @@ public:
LLWString getWString(std::string_view name);
LLVector3 getVector3(std::string_view name);
LLVector3d getVector3d(std::string_view name);
- LLVector4 getVector4(std::string_view name);
LLRect getRect(std::string_view name);
LLSD getLLSD(std::string_view name);
LLQuaternion getQuaternion(std::string_view name);
@@ -254,7 +250,6 @@ public:
void setString(std::string_view name, const std::string& val);
void setVector3(std::string_view name, const LLVector3 &val);
void setVector3d(std::string_view name, const LLVector3d &val);
- void setVector4(std::string_view name, const LLVector4 &val);
void setQuaternion(std::string_view name, const LLQuaternion &val);
void setRect(std::string_view name, const LLRect &val);
void setColor4(std::string_view name, const LLColor4 &val);
@@ -421,7 +416,6 @@ template <> eControlType get_control_type<bool>();
template <> eControlType get_control_type<std::string>();
template <> eControlType get_control_type<LLVector3>();
template <> eControlType get_control_type<LLVector3d>();
-template <> eControlType get_control_type<LLVector4>();
template <> eControlType get_control_type<LLQuaternion>();
template <> eControlType get_control_type<LLRect>();
template <> eControlType get_control_type<LLColor4>();
@@ -431,7 +425,6 @@ template <> eControlType get_control_type<LLSD>();
template <> LLSD convert_to_llsd<U32>(const U32& in);
template <> LLSD convert_to_llsd<LLVector3>(const LLVector3& in);
template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in);
-template <> LLSD convert_to_llsd<LLVector4>(const LLVector4& in);
template <> LLSD convert_to_llsd<LLQuaternion>(const LLQuaternion& in);
template <> LLSD convert_to_llsd<LLRect>(const LLRect& in);
template <> LLSD convert_to_llsd<LLColor4>(const LLColor4& in);
@@ -441,7 +434,6 @@ template<> std::string convert_from_llsd<std::string>(const LLSD& sd, eControlTy
template<> LLWString convert_from_llsd<LLWString>(const LLSD& sd, eControlType type, std::string_view control_name);
template<> LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd, eControlType type, std::string_view control_name);
template<> LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, std::string_view control_name);
-template<> LLVector4 convert_from_llsd<LLVector4>(const LLSD& sd, eControlType type, std::string_view control_name);
template<> LLQuaternion convert_from_llsd<LLQuaternion>(const LLSD& sd, eControlType type, std::string_view control_name);
template<> LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, std::string_view control_name);
template<> bool convert_from_llsd<bool>(const LLSD& sd, eControlType type, std::string_view control_name);
diff --git a/indra/llxml/llxmlparser.cpp b/indra/llxml/llxmlparser.cpp
index e2c7d17e2a..8afd412cda 100644
--- a/indra/llxml/llxmlparser.cpp
+++ b/indra/llxml/llxmlparser.cpp
@@ -72,7 +72,7 @@ bool LLXmlParser::parseFile(const std::string &path)
bool success = true;
- LLFILE* file = LLFile::fopen(path, "rb"); /* Flawfinder: ignore */
+ LLFILE* file = LLFile::fopen(path, LLFILE_MODE("rb")); /* Flawfinder: ignore */
if( !file )
{
mAuxErrorString = llformat( "Couldn't open file %s", path.c_str());
@@ -388,7 +388,7 @@ int main()
{
char buf[1024];
- LLFILE* file = LLFile::fopen("test.xml", "rb");
+ LLFILE* file = LLFile::fopen("test.xml", LLFILE_MODE("rb"));
if( !file )
{
return 1;
diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp
index 4192e029c5..e15117fc29 100644
--- a/indra/llxml/tests/llcontrol_test.cpp
+++ b/indra/llxml/tests/llcontrol_test.cpp
@@ -69,7 +69,7 @@ namespace tut
LLFile::remove(filename);
}
LLFile::remove(mTestConfigFile);
- LLFile::rmdir(mTestConfigDir);
+ LLFile::remove(mTestConfigDir);
}
void writeSettingsFile(const LLSD& config)
{
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.exp b/indra/media_plugins/base/media_plugin_base.exp
index d8c7bb712a..d8c7bb712a 100755..100644
--- a/indra/media_plugins/base/media_plugin_base.exp
+++ b/indra/media_plugins/base/media_plugin_base.exp
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 100644
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 100644
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 100644
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 100644
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 96fcc38979..3f143cb9ac 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -916,7 +916,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");
@@ -938,6 +938,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");
@@ -1100,6 +1107,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())
@@ -1130,6 +1159,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..e3b959f2b6
--- /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..5fdea56920
--- /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 3e0c343913..7e771de0f7 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)
@@ -47,7 +46,6 @@ include(Velopack)
include(ViewerMiscLibs)
include(ViewerManager)
include(VisualLeakDetector)
-include(VulkanGltf)
include(ZLIBNG)
include(LLPrimitive)
@@ -79,6 +77,8 @@ if (HAVOK)
endif()
endif ()
+configure_file(llversioninfovars.h.in llversioninfovars.h @ONLY)
+
set(viewer_SOURCE_FILES
gltfscenemanager.cpp
gltf/asset.cpp
@@ -532,6 +532,7 @@ set(viewer_SOURCE_FILES
llpathfindingobjectlist.cpp
llpathfindingpathtool.cpp
llpbrterrainfeatures.cpp
+ llperfstats.cpp
llpersistentnotificationstorage.cpp
llphysicsmotion.cpp
llphysicsshapebuilderutil.cpp
@@ -588,6 +589,7 @@ set(viewer_SOURCE_FILES
llslurl.cpp
llsnapshotlivepreview.cpp
llspatialpartition.cpp
+ llstatslistener.cpp
llspeakers.cpp
llspeakingindicatormanager.cpp
llsplitbutton.cpp
@@ -724,7 +726,6 @@ set(viewer_SOURCE_FILES
llvoicechannel.cpp
llvoiceclient.cpp
llvoicevisualizer.cpp
- llvoicewebrtc.cpp
llvoinventorylistener.cpp
llvopartgroup.cpp
llvosky.cpp
@@ -1199,6 +1200,7 @@ set(viewer_HEADER_FILES
llpathfindingobject.h
llpathfindingobjectlist.h
llpathfindingpathtool.h
+ llperfstats.h
llpbrterrainfeatures.h
llpersistentnotificationstorage.h
llphysicsmotion.h
@@ -1259,6 +1261,7 @@ set(viewer_HEADER_FILES
llsnapshotlivepreview.h
llsnapshotmodel.h
llspatialpartition.h
+ llstatslistener.h
llspeakers.h
llspeakingindicatormanager.h
llsplitbutton.h
@@ -1397,7 +1400,6 @@ set(viewer_HEADER_FILES
llvoicechannel.h
llvoiceclient.h
llvoicevisualizer.h
- llvoicewebrtc.h
llvoinventorylistener.h
llvopartgroup.h
llvosky.h
@@ -1423,13 +1425,8 @@ set(viewer_HEADER_FILES
noise.h
pipeline.h
roles_constants.h
- VertexCache.h
- 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
@@ -1437,11 +1434,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)
@@ -1470,7 +1466,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
@@ -1513,7 +1508,6 @@ set(macosx_viewer_HEADER_FILES
set(linux_viewer_SOURCE_FILES
llappviewerlinux.cpp
- llappviewerlinux_api_dbus.cpp
)
set(linux_viewer_HEADER_FILES
@@ -1531,14 +1525,6 @@ set(windows_viewer_HEADER_FILES
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)
@@ -1548,12 +1534,6 @@ if (WINDOWS)
llvelopack.cpp
llwindebug.cpp
)
- set_source_files_properties(
- llappviewerwin32.cpp
- llvelopack.cpp
- PROPERTIES
- COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
- )
list(APPEND viewer_HEADER_FILES
llappviewerwin32.h
@@ -1767,6 +1747,7 @@ set(viewer_APPSETTINGS_FILES
packages-info.txt
featuretable.txt
featuretable_mac.txt
+ featuretable_linux.txt
)
source_group("App Settings" FILES ${viewer_APPSETTINGS_FILES})
@@ -1790,6 +1771,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)
@@ -1801,13 +1791,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}
@@ -1816,6 +1799,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)
@@ -2053,11 +2038,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
@@ -2105,7 +2092,6 @@ target_link_libraries(${VIEWER_BINARY_NAME}
llcorehttp
llcommon
llmeshoptimizer
- llwebrtc
lllogin
llprimitive
llappearance
@@ -2116,8 +2102,12 @@ 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::velopack)
@@ -2125,11 +2115,11 @@ if (TARGET ll::velopack)
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 )
@@ -2168,14 +2158,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}
@@ -2407,7 +2396,7 @@ if (LL_TESTS)
lldateutil.cpp
# llmediadataclient.cpp
lllogininstance.cpp
-# llremoteparcelrequest.cpp
+ llremoteparcelrequest.cpp
llviewerhelputil.cpp
llversioninfo.cpp
# llvocache.cpp
@@ -2432,21 +2421,24 @@ if (LL_TESTS)
# )
set(test_libs
- llcommon
- llfilesystem
- llxml
- llmessage
- llcharacter
- llui
- lllogin
- llplugin
- llappearance
- )
+ llfilesystem
+ llmath
+ llcommon
+ llmessage
+ llcorehttp
+ llxml
+ llui
+ llplugin
+ llappearance
+ llprimitive
+ lllogin
+ )
- set_source_files_properties(
- llmediadataclient.cpp
- PROPERTIES
- LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}"
+ set_property(SOURCE
+ ${viewer_TEST_SOURCE_FILES}
+ PROPERTY
+ LL_TEST_ADDITIONAL_LIBRARIES
+ ${test_libs}
)
set_source_files_properties(
@@ -2458,66 +2450,39 @@ if (LL_TESTS)
)
set_source_files_properties(
- llmediadataclient.cpp
- PROPERTIES
- LL_TEST_ADDITIONAL_LIBRARIES llprimitive
- )
-
- set_source_files_properties(
lllogininstance.cpp
PROPERTIES
- LL_TEST_ADDITIONAL_SOURCE_FILES llversioninfo.cpp
- )
-
- set_property( SOURCE
- ${viewer_TEST_SOURCE_FILES}
- PROPERTY
- LL_TEST_ADDITIONAL_LIBRARIES ${test_libs}
+ LL_TEST_ADDITIONAL_SOURCE_FILES
+ llversioninfo.cpp
)
LL_ADD_PROJECT_UNIT_TESTS(${VIEWER_BINARY_NAME} "${viewer_TEST_SOURCE_FILES}")
#set(TEST_DEBUG on)
-
- set(test_libs
- llfilesystem
- llmath
- llcommon
- llmessage
- llcorehttp
- llxml
- llui
- llplugin
- llappearance
- lllogin
- llprimitive
- lllogin
- )
-
LL_ADD_INTEGRATION_TEST(cppfeatures
""
"${test_libs}"
- )
+ )
LL_ADD_INTEGRATION_TEST(llsechandler_basic
llsechandler_basic.cpp
"${test_libs}"
- )
+ )
LL_ADD_INTEGRATION_TEST(llsecapi
- llsecapi.cpp
+ llsecapi.cpp
"${test_libs}"
- )
+ )
set(llslurl_test_sources
- llslurl.cpp
- llviewernetwork.cpp
+ llslurl.cpp
+ llviewernetwork.cpp
)
LL_ADD_INTEGRATION_TEST(llslurl
- "${llslurl_test_sources}"
+ "${llslurl_test_sources}"
"${test_libs}"
- )
+ )
set(llviewercontrollistener_test_sources
llviewercontrollistener.cpp
@@ -2525,31 +2490,34 @@ if (LL_TESTS)
../llxml/llxmltree.cpp
../llxml/llxmlparser.cpp
../llcommon/commoncontrol.cpp
- )
+ )
LL_ADD_INTEGRATION_TEST(llviewercontrollistener
"${llviewercontrollistener_test_sources}"
"${test_libs}"
- )
+ )
LL_ADD_INTEGRATION_TEST(llviewernetwork
- llviewernetwork.cpp
+ llviewernetwork.cpp
"${test_libs}"
- )
+ )
LL_ADD_INTEGRATION_TEST(llviewerassetstats
llviewerassetstats.cpp
"${test_libs}"
- )
-
-# LL_ADD_INTEGRATION_TEST(llhttpretrypolicy "llhttpretrypolicy.cpp" "${test_libs}")
-
- #ADD_VIEWER_BUILD_TEST(llmemoryview viewer)
- #ADD_VIEWER_BUILD_TEST(llagentaccess viewer)
- #ADD_VIEWER_BUILD_TEST(lltextureinfo viewer)
- #ADD_VIEWER_BUILD_TEST(lltextureinfodetails viewer)
+ )
+ LL_ADD_INTEGRATION_TEST(llhttpretrypolicy "llhttpretrypolicy.cpp" "${test_libs}")
+ set(lltextureinfo_test_sources
+ lltextureinfo.cpp
+ ../llxml/llcontrol.cpp
+ ../llxml/llxmltree.cpp
+ ../llxml/llxmlparser.cpp
+ ../llcommon/commoncontrol.cpp
+ )
+ LL_ADD_INTEGRATION_TEST(lltextureinfo "${lltextureinfo_test_sources}" "${test_libs}")
+ #LL_ADD_INTEGRATION_TEST(lltextureinfodetails "" "${test_libs}") test cases currently empty
endif (LL_TESTS)
check_message_template(${VIEWER_BINARY_NAME})
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index 09b0e1ec1b..506b2b8a60 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -34,6 +34,8 @@
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>NSMicrophoneUsageDescription</key>
<string>For voice chat, you must grant permission for Second Life to use the microphone.</string>
+ <key>NSLocalNetworkUsageDescription</key>
+ <string>Second Life uses WebRTC for voice chat, which may require local network access while establishing the voice connection.</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
diff --git a/indra/newview/Info-SecondLifeVorbis.plist b/indra/newview/Info-SecondLifeVorbis.plist
deleted file mode 100644
index 9cb367eec1..0000000000
--- a/indra/newview/Info-SecondLifeVorbis.plist
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>English</string>
- <key>CFBundleExecutable</key>
- <string>SecondLifeVorbis</string>
- <key>CFBundleGetInfoString</key>
- <string></string>
- <key>CFBundleIconFile</key>
- <string></string>
- <key>CFBundleIdentifier</key>
- <string>com.secondlife.indra.vorbis</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>SecondLifeVorbis</string>
- <key>CFBundlePackageType</key>
- <string>FMWK</string>
- <key>CFBundleShortVersionString</key>
- <string></string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>0.0.1d1</string>
-</dict>
-</plist>
diff --git a/indra/newview/VertexCache.h b/indra/newview/VertexCache.h
deleted file mode 100644
index edb231feb1..0000000000
--- a/indra/newview/VertexCache.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * @file VertexCache.h
- * @brief VertexCache class definition
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-#ifndef VERTEX_CACHE_H
-
-#define VERTEX_CACHE_H
-
-class VertexCache
-{
-
-public:
-
- VertexCache(int size)
- {
- numEntries = size;
-
- entries = new int[numEntries];
-
- for(int i = 0; i < numEntries; i++)
- entries[i] = -1;
- }
-
- VertexCache() { VertexCache(16); }
- ~VertexCache() { delete[] entries; entries = 0; }
-
- bool InCache(int entry)
- {
- bool returnVal = false;
- for(int i = 0; i < numEntries; i++)
- {
- if(entries[i] == entry)
- {
- returnVal = true;
- break;
- }
- }
-
- return returnVal;
- }
-
- int AddEntry(int entry)
- {
- int removed;
-
- removed = entries[numEntries - 1];
-
- //push everything right one
- for(int i = numEntries - 2; i >= 0; i--)
- {
- entries[i + 1] = entries[i];
- }
-
- entries[0] = entry;
-
- return removed;
- }
-
- void Clear()
- {
- memset(entries, -1, sizeof(int) * numEntries);
- }
-
- void Copy(VertexCache* inVcache)
- {
- for(int i = 0; i < numEntries; i++)
- {
- inVcache->Set(i, entries[i]);
- }
- }
-
- int At(int index) { return entries[index]; }
- void Set(int index, int value) { entries[index] = value; }
-
-private:
-
- int *entries;
- int numEntries;
-
-};
-
-#endif
diff --git a/indra/newview/VorbisFramework.h b/indra/newview/VorbisFramework.h
deleted file mode 100644
index 7ee9a8c411..0000000000
--- a/indra/newview/VorbisFramework.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * @file VorbisFramework.h
- * @author Dave Camp
- * @date Fri Oct 10 2003
- * @brief For the Macview project
- *
- * $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$
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "ogg/ogg.h"
-#include "vorbis/codec.h"
-#include "vorbis/vorbisenc.h"
-
-extern int mac_vorbis_analysis(vorbis_block *vb,ogg_packet *op);
-
-extern int mac_vorbis_analysis_headerout(vorbis_dsp_state *v,
- vorbis_comment *vc,
- ogg_packet *op,
- ogg_packet *op_comm,
- ogg_packet *op_code);
-
-extern int mac_vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi);
-
-extern int mac_vorbis_encode_ctl(vorbis_info *vi,int number,void *arg);
-
-extern int mac_vorbis_encode_setup_init(vorbis_info *vi);
-
-extern int mac_vorbis_encode_setup_managed(vorbis_info *vi,
- long channels,
- long rate,
-
- long max_bitrate,
- long nominal_bitrate,
- long min_bitrate);
-
-extern void mac_vorbis_info_init(vorbis_info *vi);
-extern void mac_vorbis_info_clear(vorbis_info *vi);
-extern void mac_vorbis_comment_init(vorbis_comment *vc);
-extern void mac_vorbis_comment_clear(vorbis_comment *vc);
-extern int mac_vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
-extern int mac_vorbis_block_clear(vorbis_block *vb);
-extern void mac_vorbis_dsp_clear(vorbis_dsp_state *v);
-extern float **mac_vorbis_analysis_buffer(vorbis_dsp_state *v,int vals);
-extern int mac_vorbis_analysis_wrote(vorbis_dsp_state *v,int vals);
-extern int mac_vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb);
-
-extern int mac_ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
-extern int mac_ogg_stream_init(ogg_stream_state *os,int serialno);
-extern int mac_ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
-extern int mac_ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
-extern int mac_ogg_page_eos(ogg_page *og);
-extern int mac_ogg_stream_clear(ogg_stream_state *os);
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/indra/newview/app_settings/llsd.xsd b/indra/newview/app_settings/llsd.xsd
index 34612d9faa..34612d9faa 100755..100644
--- a/indra/newview/app_settings/llsd.xsd
+++ b/indra/newview/app_settings/llsd.xsd
diff --git a/indra/newview/app_settings/message.xml b/indra/newview/app_settings/message.xml
index dee3fd72dd..dee3fd72dd 100755..100644
--- a/indra/newview/app_settings/message.xml
+++ b/indra/newview/app_settings/message.xml
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d34a5b3eab..e50234d26a 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5096,6 +5096,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>
@@ -5881,7 +5903,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>110</integer>
+ <integer>127</integer>
</map>
<key>NotificationChannelRightMargin</key>
<map>
@@ -7306,7 +7328,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>
@@ -7314,6 +7336,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>
@@ -7530,7 +7563,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>
@@ -10205,6 +10238,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderHighPrecisionPostProcess</key>
+ <map>
+ <key>Comment</key>
+ <string>Use 16-bit floating point buffers for post process rendering</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>ReplaySession</key>
<map>
<key>Comment</key>
@@ -11860,22 +11904,6 @@
<key>Value</key>
<real>20.0</real>
</map>
- <key>TextureChannelPriority</key>
- <map>
- <key>Comment</key>
- <string>Per-channel texture streaming aggressiveness. X=normals, Y=diffuse, Z=specular/metallic, W=emissive. 1.0=baseline, higher=more aggressive downrez.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector4</string>
- <key>Value</key>
- <array>
- <real>5</real>
- <real>7.5</real>
- <real>20</real>
- <real>7.5</real>
- </array>
- </map>
<key>TextureCameraBoost</key>
<map>
<key>Comment</key>
@@ -13810,7 +13838,7 @@
<key>WLSkyDetail</key>
<map>
<key>Comment</key>
- <string>Controls vertex detail on the WindLight sky. Lower numbers will give better performance and uglier skies.</string>
+ <string>[OBSOLETE]</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl b/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl
index 8e12d09443..df58f68556 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl
@@ -1171,12 +1171,12 @@ vec3 linear_to_srgb(vec3 cl);
// - Float zero is mapped to center of integers (so clear to integer zero is a nice default for atomic max usage).
// Burns 3 ops for conversion {shift,or,xor}.
//==============================================================================================================================
- AU1 AFisToU1(AU1 x){return x^(( AShrSU1(x,AU1_(31)))|AU1_(0x80000000));}
- AU1 AFisFromU1(AU1 x){return x^((~AShrSU1(x,AU1_(31)))|AU1_(0x80000000));}
+ AU1 AFisToU1(AU1 x){return x^(( AShrSU1(x,AU1_(31)))|AU1_(0x80000000u));}
+ AU1 AFisFromU1(AU1 x){return x^((~AShrSU1(x,AU1_(31)))|AU1_(0x80000000u));}
//------------------------------------------------------------------------------------------------------------------------------
// Just adjust high 16-bit value (useful when upper part of 32-bit word is a 16-bit float value).
- AU1 AFisToHiU1(AU1 x){return x^(( AShrSU1(x,AU1_(15)))|AU1_(0x80000000));}
- AU1 AFisFromHiU1(AU1 x){return x^((~AShrSU1(x,AU1_(15)))|AU1_(0x80000000));}
+ AU1 AFisToHiU1(AU1 x){return x^(( AShrSU1(x,AU1_(15)))|AU1_(0x80000000u));}
+ AU1 AFisFromHiU1(AU1 x){return x^((~AShrSU1(x,AU1_(15)))|AU1_(0x80000000u));}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//_____________________________________________________________/\_______________________________________________________________
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/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index 8c51b4a36b..f5200719ae 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -30,9 +30,13 @@ out vec4 frag_data[4];
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-in vec3 vary_CloudColorSun;
-in vec3 vary_CloudColorAmbient;
-in float vary_CloudDensity;
+// In
+in vec3 pos;
+
+in vec2 vary_texcoord0;
+in vec2 vary_texcoord1;
+in vec2 vary_texcoord2;
+in vec2 vary_texcoord3;
uniform sampler2D cloud_noise_texture;
uniform sampler2D cloud_noise_texture_next;
@@ -42,11 +46,26 @@ uniform vec3 cloud_pos_density2;
uniform float cloud_scale;
uniform float cloud_variance;
-in vec2 vary_texcoord0;
-in vec2 vary_texcoord1;
-in vec2 vary_texcoord2;
-in vec2 vary_texcoord3;
-in float altitude_blend_factor;
+uniform vec3 camPosLocal;
+
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
+uniform int sun_up_factor;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
+uniform float haze_horizon;
+uniform float haze_density;
+
+uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float max_y;
+
+uniform vec3 glow;
+uniform float sun_moon_glow_factor;
+
+uniform vec3 cloud_color;
vec4 cloudNoise(vec2 uv)
{
@@ -58,21 +77,111 @@ vec4 cloudNoise(vec2 uv)
void main()
{
+ if (cloud_scale < 0.001)
+ {
+ discard;
+ }
+
// Set variables
vec2 uv1 = vary_texcoord0.xy;
vec2 uv2 = vary_texcoord1.xy;
-
- vec3 cloudColorSun = vary_CloudColorSun;
- vec3 cloudColorAmbient = vary_CloudColorAmbient;
- float cloudDensity = vary_CloudDensity;
vec2 uv3 = vary_texcoord2.xy;
vec2 uv4 = vary_texcoord3.xy;
- if (cloud_scale < 0.001)
+ // Get relative position
+ vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+
+ float altitude_blend_factor = clamp((rel_pos.y + 512.0) / max_y, 0.0, 1.0);
+
+ // Set altitude
+ if (rel_pos.y > 0)
{
- discard;
+ rel_pos *= (max_y / rel_pos.y);
+ }
+ if (rel_pos.y < 0)
+ {
+ altitude_blend_factor = 0; // SL-11589 Fix clouds drooping below horizon
+ rel_pos *= (-32000. / rel_pos.y);
}
+ // Can normalize then
+ vec3 rel_pos_norm = normalize(rel_pos);
+ float rel_pos_len = length(rel_pos);
+
+ // Initialize temp variables
+ vec3 sunlight = sunlight_color;
+ vec3 light_atten;
+
+ // Sunlight attenuation effect (hue and brightness) due to atmosphere
+ // this is used later for sunlight modulation at various altitudes
+ light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
+
+ // Calculate relative weights
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
+
+ // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
+ float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
+ sunlight *= exp(-light_atten * off_axis);
+
+ // Distance
+ float density_dist = rel_pos_len * density_multiplier;
+
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
+ // compiler gets confused.
+ combined_haze = exp(-combined_haze * density_dist);
+
+ // Compute haze glow
+ float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
+ // haze_glow is 0 at the sun and increases away from sun
+ haze_glow = max(haze_glow, .001);
+ // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+ haze_glow *= glow.x;
+ // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ haze_glow = pow(haze_glow, glow.z);
+ // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ haze_glow *= sun_moon_glow_factor;
+
+ // Add "minimum anti-solar illumination"
+ // For sun, add to glow. For moon, remove glow entirely. SL-13768
+ haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
+
+ // Increase ambient when there are more clouds
+ vec3 tmpAmbient = ambient_color;
+ tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
+
+ // Dim sunlight by cloud shadow percentage
+ sunlight *= (1. - cloud_shadow);
+
+ // Haze color below cloud
+ vec3 additiveColorBelowCloud =
+ (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
+
+ // CLOUDS
+ sunlight = sunlight_color;
+ off_axis = 1.0 / max(1e-6, lightnorm.y * 2.);
+ sunlight *= exp(-light_atten * off_axis);
+
+ // Cloud color out
+ vec3 cloudColorSun = (sunlight * haze_glow) * cloud_color;
+ vec3 cloudColorAmbient = tmpAmbient * cloud_color;
+
+ // Attenuate cloud color by atmosphere
+ combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
+ cloudColorSun *= combined_haze;
+ cloudColorAmbient *= combined_haze;
+ vec3 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
+
+ // Make a nice cloud density based on the cloud_shadow value that was passed in.
+ float cloudDensity = 2. * (cloud_shadow - 0.25);
+
+ // Combine these to minimize register use
+ cloudColorAmbient += oHazeColorBelowCloud;
+
+ // Cloud Fragment
vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
index c019b5606a..89fbe38af0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLCloudsV.glsl
+ * @file class1/deferred/cloudsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -33,38 +33,15 @@ in vec2 texcoord0;
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-out vec3 vary_CloudColorSun;
-out vec3 vary_CloudColorAmbient;
-out float vary_CloudDensity;
+out vec3 pos;
out vec2 vary_texcoord0;
out vec2 vary_texcoord1;
out vec2 vary_texcoord2;
out vec2 vary_texcoord3;
-out float altitude_blend_factor;
// Inputs
-uniform vec3 camPosLocal;
-
uniform vec3 lightnorm;
-uniform vec3 sunlight_color;
-uniform vec3 moonlight_color;
-uniform int sun_up_factor;
-uniform vec3 ambient_color;
-uniform vec3 blue_horizon;
-uniform vec3 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float max_y;
-
-uniform vec3 glow;
-uniform float sun_moon_glow_factor;
-
-uniform vec3 cloud_color;
-
uniform float cloud_scale;
// NOTE: Keep these in sync!
@@ -76,6 +53,7 @@ uniform float cloud_scale;
void main()
{
// World / view / projection
+ pos = position.xyz;
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
// Texture coords
@@ -92,102 +70,4 @@ void main()
vary_texcoord2 = vary_texcoord0 * 16.;
vary_texcoord3 = vary_texcoord1 * 16.;
-
- // Get relative position
- vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
-
- altitude_blend_factor = clamp((rel_pos.y + 512.0) / max_y, 0.0, 1.0);
-
- // Set altitude
- if (rel_pos.y > 0)
- {
- rel_pos *= (max_y / rel_pos.y);
- }
- if (rel_pos.y < 0)
- {
- altitude_blend_factor = 0; // SL-11589 Fix clouds drooping below horizon
- rel_pos *= (-32000. / rel_pos.y);
- }
-
- // Can normalize then
- vec3 rel_pos_norm = normalize(rel_pos);
- float rel_pos_len = length(rel_pos);
-
- // Initialize temp variables
- vec3 sunlight = sunlight_color;
- vec3 light_atten;
-
- // Sunlight attenuation effect (hue and brightness) due to atmosphere
- // this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
-
- // Calculate relative weights
- vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
- vec3 blue_weight = blue_density / combined_haze;
- vec3 haze_weight = haze_density / combined_haze;
-
- // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
- float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
- sunlight *= exp(-light_atten * off_axis);
-
- // Distance
- float density_dist = rel_pos_len * density_multiplier;
-
- // Transparency (-> combined_haze)
- // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
- // compiler gets confused.
- combined_haze = exp(-combined_haze * density_dist);
-
- // Compute haze glow
- float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
- // haze_glow is 0 at the sun and increases away from sun
- haze_glow = max(haze_glow, .001);
- // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- haze_glow *= glow.x;
- // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- haze_glow = pow(haze_glow, glow.z);
- // glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- haze_glow *= sun_moon_glow_factor;
-
- // Add "minimum anti-solar illumination"
- // For sun, add to glow. For moon, remove glow entirely. SL-13768
- haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
-
- // Increase ambient when there are more clouds
- vec3 tmpAmbient = ambient_color;
- tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
-
- // Dim sunlight by cloud shadow percentage
- sunlight *= (1. - cloud_shadow);
-
- // Haze color below cloud
- vec3 additiveColorBelowCloud =
- (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
-
- // CLOUDS
- sunlight = sunlight_color;
- off_axis = 1.0 / max(1e-6, lightnorm.y * 2.);
- sunlight *= exp(-light_atten * off_axis);
-
- // Cloud color out
- vary_CloudColorSun = (sunlight * haze_glow) * cloud_color;
- vary_CloudColorAmbient = tmpAmbient * cloud_color;
-
- // Attenuate cloud color by atmosphere
- combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
- vary_CloudColorSun *= combined_haze;
- vary_CloudColorAmbient *= combined_haze;
- vec3 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
-
- // Make a nice cloud density based on the cloud_shadow value that was passed in.
- vary_CloudDensity = 2. * (cloud_shadow - 0.25);
-
- // Combine these to minimize register use
- vary_CloudColorAmbient += oHazeColorBelowCloud;
-
- // needs this to compile on mac
- //vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
-
- // END CLOUDS
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index 7639a5e6fc..b70d1db499 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -23,13 +23,14 @@
* $/LicenseInfo$
*/
+// Outputs
+out vec4 frag_data[4];
+
// Inputs
-in vec3 vary_HazeColor;
-in float vary_LightNormPosDot;
+in vec3 pos;
#ifdef HAS_HDRI
in vec4 vary_position;
-in vec3 vary_rel_pos;
uniform float sky_hdr_scale;
uniform float hdri_split_screen;
uniform mat3 env_mat;
@@ -43,7 +44,27 @@ uniform float moisture_level;
uniform float droplet_radius;
uniform float ice_level;
-out vec4 frag_data[4];
+uniform vec3 camPosLocal;
+
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
+uniform int sun_up_factor;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
+uniform float haze_horizon;
+uniform float haze_density;
+
+uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float distance_multiplier;
+uniform float max_y;
+
+uniform vec3 glow;
+uniform float sun_moon_glow_factor;
+
+uniform int cube_snapshot;
vec3 srgb_to_linear(vec3 c);
vec3 linear_to_srgb(vec3 c);
@@ -83,12 +104,25 @@ vec3 halo22(float d)
void main()
{
+ // Get relative position
+ vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+
+ // Adj position vector to clamp altitude
+ if (rel_pos.y > 0.)
+ {
+ rel_pos *= (max_y / rel_pos.y);
+ }
+ if (rel_pos.y < 0.)
+ {
+ rel_pos *= (-32000. / rel_pos.y);
+ }
+
vec3 color;
#ifdef HAS_HDRI
vec3 frag_coord = vary_position.xyz/vary_position.w;
if (-frag_coord.x > ((1.0-hdri_split_screen)*2.0-1.0))
{
- vec3 pos = normalize(vary_rel_pos);
+ vec3 pos = normalize(rel_pos);
pos = env_mat * pos;
vec2 texCoord = vec2(atan(pos.z, pos.x) + PI, acos(pos.y)) / vec2(2.0 * PI, PI);
color = textureLod(environmentMap, texCoord.xy, 0).rgb * sky_hdr_scale;
@@ -99,15 +133,75 @@ void main()
else
#endif
{
- // Potential Fill-rate optimization. Add cloud calculation
- // back in and output alpha of 0 (so that alpha culling kills
- // the fragment) if the sky wouldn't show up because the clouds
- // are fully opaque.
+ // Normalized
+ vec3 rel_pos_norm = normalize(rel_pos);
+ float rel_pos_len = length(rel_pos);
+
+ // Grab this value and pass to frag shader for rainbows
+ float rel_pos_lightnorm_dot = dot(rel_pos_norm, lightnorm.xyz);
+
+ // Initialize temp variables
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color * 0.7; //magic 0.7 to match legacy color
+
+ // Sunlight attenuation effect (hue and brightness) due to atmosphere
+ // this is used later for sunlight modulation at various altitudes
+ vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
+
+ // Calculate relative weights
+ vec3 combined_haze = max(abs(blue_density) + vec3(abs(haze_density)), vec3(1e-6));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
+
+ // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
+ float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
+ sunlight *= exp(-light_atten * off_axis);
+
+ // Distance
+ float density_dist = rel_pos_len * density_multiplier;
+
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
+ // compiler gets confused.
+ combined_haze = exp(-combined_haze * density_dist);
+
+ // Compute haze glow
+ float haze_glow = 1.0 - rel_pos_lightnorm_dot;
+ // haze_glow is 0 at the sun and increases away from sun
+ haze_glow = max(haze_glow, .001);
+ // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+ haze_glow *= glow.x;
+ // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ haze_glow = pow(haze_glow, glow.z);
+ // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ // Add "minimum anti-solar illumination"
+ // For sun, add to glow. For moon, remove glow entirely. SL-13768
+ haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
+
+ // Haze color above cloud
+ color = (blue_horizon * blue_weight * (sunlight + ambient_color)
+ + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
+
+ // Final atmosphere additive
+ color *= (1. - combined_haze);
+
+ // Increase ambient when there are more clouds
+ vec3 ambient = ambient_color + max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
+
+ // Dim sunlight by cloud shadow percentage
+ sunlight *= max(0.0, (1. - cloud_shadow));
+
+ // Haze color below cloud
+ vec3 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
+ + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient));
+
+ // Attenuate cloud color by atmosphere
+ combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
- color = vary_HazeColor;
+ // At horizon, blend high altitude sky color towards the darker color below the clouds
+ color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
- float rel_pos_lightnorm = vary_LightNormPosDot;
- float optic_d = rel_pos_lightnorm;
+ float optic_d = rel_pos_lightnorm_dot;
vec3 halo_22 = halo22(optic_d);
color.rgb += rainbow(optic_d);
color.rgb += halo_22;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index ea00d240df..836ad66098 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLSkyV.glsl
+ * @file class1/deferred/skyV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -32,36 +32,13 @@ in vec3 position;
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-out vec3 vary_HazeColor;
-out float vary_LightNormPosDot;
+out vec3 pos;
#ifdef HAS_HDRI
out vec4 vary_position;
-out vec3 vary_rel_pos;
#endif
// Inputs
-uniform vec3 camPosLocal;
-
-uniform vec3 lightnorm;
-uniform vec3 sunlight_color;
-uniform vec3 moonlight_color;
-uniform int sun_up_factor;
-uniform vec3 ambient_color;
-uniform vec3 blue_horizon;
-uniform vec3 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float distance_multiplier;
-uniform float max_y;
-
-uniform vec3 glow;
-uniform float sun_moon_glow_factor;
-
-uniform int cube_snapshot;
// NOTE: Keep these in sync!
// indra\newview\app_settings\shaders\class1\deferred\skyV.glsl
@@ -70,97 +47,13 @@ uniform int cube_snapshot;
void main()
{
// World / view / projection
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- gl_Position = pos;
-
- // Get relative position
- vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
-
-#ifdef HAS_HDRI
- vary_rel_pos = rel_pos;
- vary_position = pos;
-#endif
-
- // Adj position vector to clamp altitude
- if (rel_pos.y > 0.)
- {
- rel_pos *= (max_y / rel_pos.y);
- }
- if (rel_pos.y < 0.)
- {
- rel_pos *= (-32000. / rel_pos.y);
- }
-
- // Normalized
- vec3 rel_pos_norm = normalize(rel_pos);
- float rel_pos_len = length(rel_pos);
-
- // Grab this value and pass to frag shader for rainbows
- float rel_pos_lightnorm_dot = dot(rel_pos_norm, lightnorm.xyz);
- vary_LightNormPosDot = rel_pos_lightnorm_dot;
-
- // Initialize temp variables
- vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color * 0.7; //magic 0.7 to match legacy color
-
- // Sunlight attenuation effect (hue and brightness) due to atmosphere
- // this is used later for sunlight modulation at various altitudes
- vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
-
- // Calculate relative weights
- vec3 combined_haze = max(abs(blue_density) + vec3(abs(haze_density)), vec3(1e-6));
- vec3 blue_weight = blue_density / combined_haze;
- vec3 haze_weight = haze_density / combined_haze;
-
- // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
- float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
- sunlight *= exp(-light_atten * off_axis);
-
- // Distance
- float density_dist = rel_pos_len * density_multiplier;
-
- // Transparency (-> combined_haze)
- // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
- // compiler gets confused.
- combined_haze = exp(-combined_haze * density_dist);
-
- // Compute haze glow
- float haze_glow = 1.0 - rel_pos_lightnorm_dot;
- // haze_glow is 0 at the sun and increases away from sun
- haze_glow = max(haze_glow, .001);
- // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- haze_glow *= glow.x;
- // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- haze_glow = pow(haze_glow, glow.z);
- // glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- // Add "minimum anti-solar illumination"
- // For sun, add to glow. For moon, remove glow entirely. SL-13768
- haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
-
- // Haze color above cloud
- vec3 color = (blue_horizon * blue_weight * (sunlight + ambient_color)
- + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
-
- // Final atmosphere additive
- color *= (1. - combined_haze);
-
- // Increase ambient when there are more clouds
- vec3 ambient = ambient_color + max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
-
- // Dim sunlight by cloud shadow percentage
- sunlight *= max(0.0, (1. - cloud_shadow));
-
- // Haze color below cloud
- vec3 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
- + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient));
+ pos = position.xyz;
- // Attenuate cloud color by atmosphere
- combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
+ vec4 transformed_pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- // At horizon, blend high altitude sky color towards the darker color below the clouds
- color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
+ gl_Position = transformed_pos;
- // Haze color above cloud
- vary_HazeColor = color;
+ #ifdef HAS_HDRI
+ vary_position = transformed_pos;
+ #endif
}
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 53bd0c741f..69c9e9ff84 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -255,8 +255,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 65616e7835..1738cbf9a2 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/build_win32_appConfig.py b/indra/newview/build_win32_appConfig.py
deleted file mode 100755
index 1bfcc7a9bc..0000000000
--- a/indra/newview/build_win32_appConfig.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# @file build_win32_appConfig.py
-# @brief Create the windows app.config file to redirect crt linkage.
-#
-# $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$
-
-import sys, os, re
-from xml.dom.minidom import parse
-
-def munge_binding_redirect_version(src_manifest_name, src_config_name, dst_config_name):
- manifest_dom = parse(src_manifest_name)
- node = manifest_dom.getElementsByTagName('assemblyIdentity')[0]
- manifest_assm_ver = node.getAttribute('version')
-
- config_dom = parse(src_config_name)
- node = config_dom.getElementsByTagName('bindingRedirect')[0]
- node.setAttribute('newVersion', manifest_assm_ver)
- src_old_ver = re.match('([^-]*-).*', node.getAttribute('oldVersion')).group(1)
- node.setAttribute('oldVersion', src_old_ver + manifest_assm_ver)
- comment = config_dom.createComment("This file is automatically generated by the build. see indra/newview/build_win32_appConfig.py")
- config_dom.insertBefore(comment, config_dom.childNodes[0])
-
- print("Writing: " + dst_config_name)
- f = open(dst_config_name, 'w')
- config_dom.writexml(f)
- f.close()
-
-
-
-def main():
- config = sys.argv[1]
- src_dir = sys.argv[2]
- dst_dir = sys.argv[3]
- dst_name = sys.argv[4]
-
- if config.lower() == 'debug':
- src_manifest_name = dst_dir + '/Microsoft.VC80.DebugCRT.manifest'
- src_config_name = src_dir + '/SecondLifeDebug.exe.config'
- else:
- src_manifest_name = dst_dir + '/Microsoft.VC80.CRT.manifest'
- src_config_name = src_dir + '/SecondLife.exe.config'
-
- dst_config_name = dst_dir + '/' + dst_name
-
- munge_binding_redirect_version(src_manifest_name, src_config_name, dst_config_name)
-
- return 0
-
-if __name__ == "__main__":
- main()
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 1090dd8ffb..21cbf259df 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 74
+version 76
// 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
@@ -56,7 +56,6 @@ RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
UseOcclusion 1 1
WindLightUseAtmosShaders 1 1
-WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderCompressTextures 1 1
@@ -87,12 +86,13 @@ RenderTonemapMix 1 1
RenderDisableVintageMode 1 1
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 256
+RenderHighPrecisionPostProcess 1 1
//
// Low Graphics Settings
//
list Low
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -113,7 +113,6 @@ RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 96
RenderFSAAType 1 0
RenderFSAASamples 1 0
RenderScreenSpaceReflections 1 0
@@ -130,12 +129,13 @@ RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
RenderMaxTextureResolution 1 512
RenderReflectionProbeCount 1 1
+RenderHighPrecisionPostProcess 1 0
//
// Medium Low Graphics Settings
//
list LowMid
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
@@ -156,7 +156,6 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 96
RenderFSAAType 1 0
RenderFSAASamples 1 0
RenderScreenSpaceReflections 1 0
@@ -173,12 +172,13 @@ RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
RenderMaxTextureResolution 1 1024
RenderReflectionProbeCount 1 32
+RenderHighPrecisionPostProcess 1 0
//
// Medium Graphics Settings (standard)
//
list Mid
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -197,7 +197,6 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.25
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 96
RenderFSAAType 1 1
RenderFSAASamples 1 1
RenderReflectionsEnabled 1 1
@@ -215,12 +214,13 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 64
+RenderHighPrecisionPostProcess 1 0
//
// Medium High Graphics Settings
//
list MidHigh
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 4
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -239,7 +239,6 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.375
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 96
RenderFSAAType 1 1
RenderFSAASamples 1 1
RenderReflectionsEnabled 1 1
@@ -257,12 +256,13 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 64
+RenderHighPrecisionPostProcess 1 0
//
// 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
@@ -281,7 +281,6 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.5
RenderDeferredSSAO 1 1
RenderShadowDetail 1 1
-WLSkyDetail 1 96
RenderFSAAType 1 2
RenderFSAASamples 1 2
RenderReflectionsEnabled 1 1
@@ -299,12 +298,13 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 128
+RenderHighPrecisionPostProcess 1 0
//
-// 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
@@ -323,7 +323,6 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.75
RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
-WLSkyDetail 1 96
RenderFSAAType 1 2
RenderFSAASamples 1 2
RenderReflectionsEnabled 1 1
@@ -341,12 +340,13 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 256
+RenderHighPrecisionPostProcess 1 1
//
// Ultra graphics (REALLY PURTY!)
//
list Ultra
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 8
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarPhysicsLODFactor 1 1.0
@@ -363,7 +363,6 @@ RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
WindLightUseAtmosShaders 1 1
-WLSkyDetail 1 128
RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
RenderFSAAType 1 2
@@ -383,6 +382,7 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 256
+RenderHighPrecisionPostProcess 1 1
//
// Class Unknown Hardware (unknown)
@@ -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..5d2819169e 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -1,10 +1,10 @@
-version 30
+version 35
// 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
@@ -56,63 +56,43 @@ RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
UseOcclusion 1 1
WindLightUseAtmosShaders 1 1
-WLSkyDetail 1 128
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
+RenderHighPrecisionPostProcess 1 1
//
// 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
+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
+RenderHighPrecisionPostProcess 1 0
//
// 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
+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
+RenderHighPrecisionPostProcess 1 0
//
// 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
+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
+RenderHighPrecisionPostProcess 1 0
//
-// 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
+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
+RenderHighPrecisionPostProcess 1 0
//
-// 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
+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
+RenderHighPrecisionPostProcess 1 0
//
-// 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
+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
+RenderHighPrecisionPostProcess 1 1
//
// 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
+RenderHighPrecisionPostProcess 1 1
//
// 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..7bb4fb6dd0 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 73
+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 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
@@ -54,7 +54,6 @@ RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
UseOcclusion 1 1
WindLightUseAtmosShaders 1 1
-WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderCompressTextures 1 1
@@ -87,12 +86,13 @@ RenderDisableVintageMode 1 1
RenderDownScaleMethod 1 0
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 256
+RenderHighPrecisionPostProcess 1 1
//
// Low Graphics Settings
//
list Low
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -111,7 +111,6 @@ RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 96
RenderFSAAType 1 0
RenderFSAASamples 1 0
RenderReflectionsEnabled 1 0
@@ -130,12 +129,13 @@ RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
RenderMaxTextureResolution 1 512
RenderReflectionProbeCount 1 1
+RenderHighPrecisionPostProcess 1 0
//
// Medium Low Graphics Settings
//
list LowMid
-RenderAnisotropic 1 0
+RenderAnisotropicLevel 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
@@ -154,7 +154,6 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 96
RenderFSAAType 1 0
RenderFSAASamples 1 0
RenderReflectionsEnabled 1 1
@@ -173,12 +172,13 @@ RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
RenderMaxTextureResolution 1 1024
RenderReflectionProbeCount 1 32
+RenderHighPrecisionPostProcess 1 0
//
// Medium Graphics Settings (standard)
//
list Mid
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -197,7 +197,6 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.25
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 96
RenderFSAAType 1 1
RenderFSAASamples 1 0
RenderReflectionsEnabled 1 1
@@ -215,12 +214,13 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 64
+RenderHighPrecisionPostProcess 1 0
//
// Medium High Graphics Settings
//
list MidHigh
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 2
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -239,7 +239,6 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.375
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 96
RenderFSAAType 1 1
RenderFSAASamples 1 1
RenderReflectionsEnabled 1 1
@@ -257,12 +256,13 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 64
+RenderHighPrecisionPostProcess 1 0
//
// 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
@@ -281,7 +281,6 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.5
RenderDeferredSSAO 1 1
RenderShadowDetail 1 1
-WLSkyDetail 1 96
RenderFSAAType 1 1
RenderFSAASamples 1 2
RenderReflectionsEnabled 1 1
@@ -299,12 +298,13 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 128
+RenderHighPrecisionPostProcess 1 0
//
// 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
@@ -323,7 +323,6 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.75
RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
-WLSkyDetail 1 96
RenderFSAAType 1 2
RenderFSAASamples 1 2
RenderReflectionsEnabled 1 1
@@ -341,12 +340,13 @@ RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderMaxTextureResolution 1 2048
RenderReflectionProbeCount 1 256
+RenderHighPrecisionPostProcess 1 1
//
// Ultra graphics (REALLY PURTY!)
//
list Ultra
-RenderAnisotropic 1 1
+RenderAnisotropicLevel 1 4
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
@@ -363,7 +363,6 @@ RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
WindLightUseAtmosShaders 1 1
-WLSkyDetail 1 128
RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
RenderFSAAType 1 2
@@ -401,10 +400,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 +440,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 bb8adf236a..c170672859 100644
--- a/indra/newview/gltf/asset.cpp
+++ b/indra/newview/gltf/asset.cpp
@@ -929,7 +929,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;
@@ -1129,7 +1129,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 54ad8c894b..1bdc915bd5 100644
--- a/indra/newview/gltf/llgltfloader.cpp
+++ b/indra/newview/gltf/llgltfloader.cpp
@@ -507,7 +507,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;
}
@@ -1930,7 +1930,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/installers/darwin/dmg-cleanup.applescript b/indra/newview/installers/darwin/dmg-cleanup.applescript
index 8a71b392f9..8a71b392f9 100755..100644
--- a/indra/newview/installers/darwin/dmg-cleanup.applescript
+++ b/indra/newview/installers/darwin/dmg-cleanup.applescript
diff --git a/indra/newview/installers/darwin/release-dmg/Applications-alias.r b/indra/newview/installers/darwin/release-dmg/Applications-alias.r
index f9be0536c6..f9be0536c6 100755..100644
--- a/indra/newview/installers/darwin/release-dmg/Applications-alias.r
+++ b/indra/newview/installers/darwin/release-dmg/Applications-alias.r
diff --git a/indra/newview/installers/darwin/release-dmg/_DS_Store b/indra/newview/installers/darwin/release-dmg/_DS_Store
index 747ca961d8..747ca961d8 100755..100644
--- a/indra/newview/installers/darwin/release-dmg/_DS_Store
+++ b/indra/newview/installers/darwin/release-dmg/_DS_Store
Binary files differ
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index 7cc70e4c76..7cc70e4c76 100755..100644
--- a/indra/newview/installers/windows/lang_de.nsi
+++ b/indra/newview/installers/windows/lang_de.nsi
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index 364cc9f67e..364cc9f67e 100755..100644
--- a/indra/newview/installers/windows/lang_es.nsi
+++ b/indra/newview/installers/windows/lang_es.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index 2f34c0c87a..2f34c0c87a 100755..100644
--- a/indra/newview/installers/windows/lang_fr.nsi
+++ b/indra/newview/installers/windows/lang_fr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index 51214d3a9c..51214d3a9c 100755..100644
--- a/indra/newview/installers/windows/lang_it.nsi
+++ b/indra/newview/installers/windows/lang_it.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index 296703d1a3..296703d1a3 100755..100644
--- a/indra/newview/installers/windows/lang_ja.nsi
+++ b/indra/newview/installers/windows/lang_ja.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
index 542c8654b5..542c8654b5 100755..100644
--- a/indra/newview/installers/windows/lang_pt-br.nsi
+++ b/indra/newview/installers/windows/lang_pt-br.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index 4e53a4957d..4e53a4957d 100755..100644
--- a/indra/newview/installers/windows/lang_ru.nsi
+++ b/indra/newview/installers/windows/lang_ru.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index bae5029ad1..bae5029ad1 100755..100644
--- a/indra/newview/installers/windows/lang_tr.nsi
+++ b/indra/newview/installers/windows/lang_tr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index 0985663041..0985663041 100755..100644
--- a/indra/newview/installers/windows/lang_zh.nsi
+++ b/indra/newview/installers/windows/lang_zh.nsi
Binary files differ
diff --git a/indra/newview/licenses-linux.txt b/indra/newview/licenses-linux.txt
index 8a410d22a3..167341fc19 100644
--- a/indra/newview/licenses-linux.txt
+++ b/indra/newview/licenses-linux.txt
@@ -632,183 +632,6 @@ supporting the PNG file format in commercial products. If you use this
source code in a product, acknowledgment is not required but would be
appreciated.
-=================
-Vivox SDK License
-=================
-
-RSA Data Security, Inc. MD5 Message-Digest Algorithm
-
-Audio coding: Polycom(R) Siren14TM (ITU-T Rec. G.722.1 Annex C)
-
-Open Source Software Licensing
-Each open source software component utilized by this product is subject to its own copyright and licensing terms, as listed below.
-
-*************************************************************
-*************************************************************
-
-/**
- * OpenAL cross platform audio library
- * Copyright (C) 1999-2000 by authors.
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- * Or go to http://www.gnu.org/copyleft/lgpl.html
- */
-
-*************************************************************
-*************************************************************
-RTP code under Lesser General Public License
-
-/*
- The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack.
- Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
-
- 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; either
- version 2.1 of the License, or (at your option) any later version.
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-************************************************************
-*************************************************************
-
-/*
- * The Vovida Software License, Version 1.0
- *
- * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
- *
- * 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 above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The names "VOCAL", "Vovida Open Communication Application Library",
- * and "Vovida Open Communication Application Library (VOCAL)" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact vocal@vovida.org.
- *
- * 4. Products derived from this software may not be called "VOCAL", nor
- * may "VOCAL" appear in their name, without prior written
- * permission of Vovida Networks, Inc.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
- * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
- * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
- * IN EXCESS OF $1,000, NOR FOR ANY 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.
- *
- *
- * This software consists of voluntary contributions made by Vovida
- * Networks, Inc. and many individuals on behalf of Vovida Networks,
- * Inc. For more information on Vovida Networks, Inc., please see
- *
- *
- */
-*************************************************************
-*************************************************************
-
-Internet Software Consortium code
-
-/* This is from the BIND 4.9.4 release, modified to compile by itself */
-/* Copyright (c) 1996 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-*************************************************************
-
-*************************************************************
-
-************************************************************
-
-http://tinyxpath.sourceforge.net/
-
-TinyXPath is covered by the zlib license :
-
- www.sourceforge.net/projects/tinyxpath
- Copyright (c) 2002-2006 Yves Berquin (yvesb@users.sourceforge.net)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product documentation
- would be appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
-
- 3. This notice may not be removed or altered from any source distribution.
-
-
-************************************************************
-************************************************************
-
-THE FREE SOFTWARE FOUNDATION
-
-Any customer may request the source code for all open source portions of this product which are covered by the Free Software Foundation's General Public License (GPL), for a period of three years from purchase. Please contact the vendor from whom you obtained this product for instructions. A fee equivalent to the cost of making the code available may be charged. Alternatively, customers may choose to download desired GPL components directly from their original vendors. Specifically, this product contains the following GPL-licensed components:
-
-
-From Vivox:
- - Assorted software components. To request source, contact Vivox at:
- Vivox, Inc.
- Attn: customer support
- 40 Speen Street Suite 402
- Framingham, MA 01701
-
DejaVu Fonts
MIT License
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 d3aac5a43e..017d5c80f3 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -26,7 +26,7 @@
#import "llappdelegate-objc.h"
#if defined(LL_BUGSPLAT)
-#include <boost/filesystem.hpp>
+#include <filesystem>
#include <vector>
@import CrashReporter;
@import HockeySDK;
@@ -39,6 +39,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;
@@ -250,7 +252,7 @@
if(!secondLogPath.empty())
{
- boost::filesystem::remove(secondLogPath);
+ std::filesystem::remove(secondLogPath);
}
clearDumpLogsDir();
}
@@ -324,7 +326,7 @@ struct AttachmentInfo
{
AttachmentInfo(const std::string& path, const std::string& type):
pathname(path),
- basename(boost::filesystem::path(path).filename().string()),
+ basename(std::filesystem::path(path).filename().string()),
mimetype(type)
{}
@@ -359,7 +361,7 @@ struct AttachmentInfo
// the log data to a browser, so take this opportunity to rename the file
// from <base>.crash to <base>_log.txt
info[0].basename =
- boost::filesystem::path(info[0].pathname).stem().string() + "_log.txt";
+ std::filesystem::path(info[0].pathname).stem().string() + "_log.txt";
infos("attachmentsForBugsplatStartupManager attaching log " + info[0].basename);
NSMutableArray *attachments = [[NSMutableArray alloc] init];
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 67b84c324c..35a2cc1852 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -137,20 +137,23 @@
#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>
#include <boost/regex.hpp>
#include <boost/throw_exception.hpp>
+#include <chrono>
#if LL_WINDOWS
# include <share.h> // For _SH_DENYWR in processMarkerFiles
@@ -186,7 +189,6 @@
#include "lltracker.h"
#include "llviewerparcelmgr.h"
#include "llworldmapview.h"
-#include "llpostprocess.h"
#include "lldebugview.h"
#include "llconsole.h"
@@ -269,10 +271,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>
@@ -298,7 +296,7 @@ extern bool gRandomizeFramerate;
extern bool gPeriodicSlowFrame;
extern bool gDebugGL;
-#if LL_DARWIN
+#if LL_DARWIN || LL_SDL_WINDOW
extern bool gHiDPISupport;
#endif
@@ -552,7 +550,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;
@@ -578,6 +576,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
}
@@ -1145,17 +1146,17 @@ bool LLAppViewer::init()
gGLActive = false;
-//#if LL_RELEASE_FOR_DOWNLOAD
- // Launch VVM update check
+#if !LL_LINUX
+ // Launch VVM update check (Linux updater is future work: Velopack port)
if (!gSavedSettings.getBOOL("CmdLineSkipUpdater") && !gNonInteractive)
{
initVVMUpdateCheck();
}
else
+#endif
{
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
@@ -1315,7 +1316,11 @@ bool LLAppViewer::frame()
{
try
{
+ const auto start = std::chrono::steady_clock::now();
ret = doFrame();
+ const auto end = std::chrono::steady_clock::now();
+ const U64 doframe_time_us = (U64)std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
+ LLTrace::sample(LLStatViewer::DOFRAME_TIME_US, doframe_time_us);
}
catch (const LLContinueError&)
{
@@ -1888,8 +1893,6 @@ bool LLAppViewer::cleanup()
SUBSYSTEM_CLEANUP(LLAvatarAppearance);
- SUBSYSTEM_CLEANUP(LLPostProcess);
-
LLTracker::cleanupInstance();
// *FIX: This is handled in LLAppViewerWin32::cleanup().
@@ -2293,7 +2296,7 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)
LLAppViewer::instance()->writeDebugInfo();
std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
- if (!LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
+ if (!LLFile::isfile(error_marker_file))
{
// If marker doesn't exist, create a marker with llerror code for next launch
// otherwise don't override existing file
@@ -3129,13 +3132,20 @@ bool LLAppViewer::initConfiguration()
if (mSecondInstance)
{
- // This is the second instance of SL. Mute voice,
- // but make sure the setting is *not* persisted.
+ // This is the second concurrent instance of SL.
+ // Disable voice for this session only, user should
+ // be able to enable voice manually, after that it
+ // works the same way as on primary instance.
LLControlVariable* enable_voice = gSavedSettings.getControl("EnableVoiceChat");
- if (enable_voice)
+ if (enable_voice && enable_voice->getValue().asBoolean())
{
+ LL_DEBUGS("AppInit") << "Disabling voice for this session only" << LL_ENDL;
+ // Will be saved as mValues[2] which does not get written to the file.
+ // This feels like a hack, but otherwise way too many controls have to
+ // be tracked manually instead of using xmls' control_name.
const bool DO_NOT_PERSIST = false;
- enable_voice->setValue(LLSD(false), DO_NOT_PERSIST);
+ LLSD::Boolean new_value = false;
+ enable_voice->setValue(new_value, DO_NOT_PERSIST);
}
}
@@ -3227,13 +3237,11 @@ void LLAppViewer::initStrings()
}
else
{
- llstat st;
- int rc = LLFile::stat(strings_path_full, &st);
- if (rc != 0)
+ if (!LLFile::exists(strings_path_full))
{
- crash_reason = "The file '" + strings_path_full + "' failed to get status. Error code: " + std::to_string(rc);
+ crash_reason = "The file '" + strings_path_full + "' doesn't seem to exist";
}
- else if (S_ISDIR(st.st_mode))
+ else if (LLFile::isdir(strings_path_full))
{
crash_reason = "The filename '" + strings_path_full + "' is a directory name";
}
@@ -3622,7 +3630,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
@@ -3652,7 +3660,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;
@@ -3678,11 +3685,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 << ".";
@@ -3690,9 +3693,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
LLTrace::Recording& recording = LLViewerStats::instance().getRecording();
S32 packets_in = (S32)recording.getSum(LLStatViewer::PACKETS_IN);
@@ -4155,7 +4155,7 @@ void LLAppViewer::processMarkerFiles()
bool marker_is_same_version = true;
// first, look for the marker created at startup and deleted on a clean exit
mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME);
- if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB))
+ if (LLFile::isfile(mMarkerFileName))
{
// File exists...
// first, read it to see if it was created by the same version (we need this later)
@@ -4242,7 +4242,7 @@ void LLAppViewer::processMarkerFiles()
// check for any last exec event report based on whether or not it happened during logout
// (the logout marker is created when logout begins)
std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);
- if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))
+ if(LLFile::isfile(logout_marker_file))
{
if (markerIsSameVersion(logout_marker_file))
{
@@ -4254,7 +4254,7 @@ void LLAppViewer::processMarkerFiles()
{
LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "' found, but versions did not match" << LL_ENDL;
}
- LLAPRFile::remove(logout_marker_file);
+ LLFile::remove(logout_marker_file);
}
// Refine based on whether or not a marker created during
// a crash is found or if wathdog caught a freeze.
@@ -4263,7 +4263,7 @@ void LLAppViewer::processMarkerFiles()
std::string watchdog_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, WATCHDOG_MARKER_FILE_NAME);
std::string inited_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, INITED_MARKER_FILE_NAME);
std::string close_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, CLOSE_EVENT_MARKER_FILE_NAME);
- if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
+ if(LLFile::isfile(error_marker_file))
{
S32 marker_code = getMarkerErrorCode(error_marker_file);
if (marker_code >= 0)
@@ -4291,8 +4291,8 @@ void LLAppViewer::processMarkerFiles()
{
LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;
}
- LLAPRFile::remove(error_marker_file);
- if (LLAPRFile::isExist(watchdog_marker_file, NULL, LL_APR_RB))
+ LLFile::remove(error_marker_file);
+ if (LLFile::isfile(watchdog_marker_file))
{
// If viewer crashed after a freeze was detected,
// crash still takes precendence. Just clear watchdog.
@@ -4307,7 +4307,7 @@ void LLAppViewer::processMarkerFiles()
// If viewer crashed after a freeze was detected,
// crash still takes precendence.
// So only check watchdog marker if there is no error marker.
- if (LLAPRFile::isExist(watchdog_marker_file, NULL, LL_APR_RB))
+ if (LLFile::isfile(watchdog_marker_file))
{
// watchdog marker gets created if we detect a freeze,
// so if viwer did not stop gracefully, and we know it wasn't a crash,
@@ -4324,7 +4324,7 @@ void LLAppViewer::processMarkerFiles()
// killed by task manager.
// Marker does not indicate that viewer was closed or is closing,
// just that 'close' was requested before viewer died.
- else if (LLAPRFile::isExist(close_marker_file, NULL, LL_APR_RB))
+ else if (LLFile::isfile(close_marker_file))
{
// Unfortunately we can't reliably distinguish
// task manager's case from genuine shutdown, so we
@@ -4339,7 +4339,7 @@ void LLAppViewer::processMarkerFiles()
}
}
else if ((LAST_EXEC_UNKNOWN == gLastExecEvent)
- && !LLAPRFile::isExist(inited_marker_file, NULL, LL_APR_RB))
+ && !LLFile::isfile(inited_marker_file))
{
// Viewer didn't get to a login screen.
gLastExecEvent = LAST_EXEC_INIT;
@@ -4350,15 +4350,15 @@ void LLAppViewer::processMarkerFiles()
}
}
}
- if (LLAPRFile::isExist(watchdog_marker_file, NULL, LL_APR_RB))
+ if (LLFile::isfile(watchdog_marker_file))
{
removeWatchdogMarker();
}
- if (LLAPRFile::isExist(inited_marker_file, NULL, LL_APR_RB))
+ if (LLFile::isfile(inited_marker_file))
{
removeInitedMarker();
}
- if (LLAPRFile::isExist(close_marker_file, NULL, LL_APR_RB))
+ if (LLFile::isfile(close_marker_file))
{
removeCloseRequestMarker();
}
@@ -4387,7 +4387,7 @@ void LLAppViewer::removeMarkerFiles()
if (mMarkerFile.getFileHandle())
{
mMarkerFile.close() ;
- LLAPRFile::remove( mMarkerFileName );
+ LLFile::remove( mMarkerFileName );
LL_DEBUGS("MarkerFile") << "removed exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
}
else
@@ -4398,7 +4398,7 @@ void LLAppViewer::removeMarkerFiles()
if (mLogoutMarkerFile.getFileHandle())
{
mLogoutMarkerFile.close();
- LLAPRFile::remove( mLogoutMarkerFileName );
+ LLFile::remove( mLogoutMarkerFileName );
LL_DEBUGS("MarkerFile") << "removed logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
}
else
@@ -4641,7 +4641,7 @@ void LLAppViewer::migrateCacheDirectory()
LLFile::remove(ds_store);
}
#endif
- if (LLFile::rmdir(old_cache_dir) != 0)
+ if (LLFile::remove(old_cache_dir) != 0)
{
LL_WARNS() << "could not delete old cache directory " << old_cache_dir << LL_ENDL;
}
@@ -4927,7 +4927,7 @@ void LLAppViewer::purgeCacheImmediate()
std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "objectcache");
LL_INFOS() << "Removing cache at " << cache_dir << LL_ENDL;
gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files
- LLFile::rmdir(cache_dir);
+ LLFile::remove(cache_dir);
}
}
@@ -5860,7 +5860,7 @@ void LLAppViewer::createErrorMarker(eLastExecEvent error_code) const
bool LLAppViewer::errorMarkerExists() const
{
std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
- return LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB);
+ return LLFile::isfile(error_marker_file);
}
void LLAppViewer::createCloseRequestMarker() const
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index fe0d6f6e7d..2fd0eebd44 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -34,27 +34,48 @@
#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"
+
+#include "llsdl.h"
+#include "llwindowsdl.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"
+#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;
}
@@ -62,6 +83,97 @@ namespace
guint32 LLAppViewerLinux::sPowerInhibitCookie = 0;
bool LLAppViewerLinux::sPowerInhibitActive = false;
+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()
{
@@ -75,32 +187,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())
{
//
@@ -108,11 +273,11 @@ 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;
+
+ delete gViewerAppPtr;
+ gViewerAppPtr = nullptr;
}
LLAppViewerLinux::LLAppViewerLinux()
@@ -130,12 +295,6 @@ LLAppViewerLinux::~LLAppViewerLinux()
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
@@ -157,7 +316,7 @@ bool LLAppViewerLinux::restoreErrorTrap()
}
/////////////////////////////////////////
-#if LL_DBUS_ENABLED
+#if LL_GLIB
typedef struct
{
@@ -167,101 +326,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.
}
///
@@ -269,13 +404,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);
@@ -285,49 +413,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;
-
- g_type_init();
+ auto pProxy = g_dbus_proxy_new_sync(pBus, G_DBUS_PROXY_FLAGS_NONE, nullptr,
+ VIEWERAPI_SERVICE, VIEWERAPI_PATH,
+ VIEWERAPI_INTERFACE, nullptr, nullptr);
- 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
@@ -336,8 +464,68 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url)
{
return false; // not implemented without dbus
}
-#endif // LL_DBUS_ENABLED
+#endif // LL_GLIB
+
+#if LL_GLIB
+
+namespace
+{
+ // Session-bus sleep inhibitors, tried in order; both hand back a uint cookie.
+ struct PowerInhibitor
+ {
+ const char* service;
+ const char* path;
+ const char* iface;
+ const char* uninhibit;
+ bool gnome_args;
+ };
+
+ const PowerInhibitor POWER_INHIBITORS[] =
+ {
+ { "org.freedesktop.PowerManagement", "/org/freedesktop/PowerManagement/Inhibit",
+ "org.freedesktop.PowerManagement.Inhibit", "UnInhibit", false },
+ { "org.gnome.SessionManager", "/org/gnome/SessionManager",
+ "org.gnome.SessionManager", "Uninhibit", true }
+ };
+
+ const PowerInhibitor* sActiveInhibitor = nullptr;
+
+ // Returns the reply, or null on failure. Takes ownership of args.
+ GVariant* call_power_manager(const PowerInhibitor& inhibitor, const char* method, GVariant* args,
+ const GVariantType* reply_type)
+ {
+ g_variant_ref_sink(args);
+
+ GDBusConnection* bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
+ if (!bus)
+ {
+ LL_WARNS("OS") << "Getting dbus failed." << LL_ENDL;
+ g_variant_unref(args);
+ return nullptr;
+ }
+
+ GError* error = nullptr;
+ GVariant* result = g_dbus_connection_call_sync(bus, inhibitor.service, inhibitor.path,
+ inhibitor.iface, method, args, reply_type,
+ G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error);
+ if (!result)
+ {
+ LL_DEBUGS("OS") << inhibitor.service << "." << method << " failed: "
+ << (error ? error->message : "unknown error") << LL_ENDL;
+ }
+ if (error)
+ {
+ g_error_free(error);
+ }
+
+ g_variant_unref(args);
+ g_object_unref(bus);
+ return result;
+ }
+}
+
+#endif // LL_GLIB
void LLAppViewerLinux::setOSHibernationMode(eHibernationMode mode)
{
@@ -391,302 +579,67 @@ void LLAppViewerLinux::setOSHibernationMode(eHibernationMode mode)
// TODO: This is AI Generated!!!, needs review and testing.
bool LLAppViewerLinux::inhibitPowerManagement(bool inhibit_display)
{
-#if LL_DBUS_ENABLED
- // Try to use D-Bus to inhibit power management via various desktop environment APIs
- // This works with GNOME, KDE, XFCE, and most modern Linux desktop environments
-
- if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME))
- {
- LL_WARNS("OS") << "Failed to load D-Bus symbols for power management" << LL_ENDL;
- return false;
- }
-
- GError* error = nullptr;
- DBusGConnection* bus = lldbus_g_bus_get(DBUS_BUS_SESSION, &error);
-
- if (!bus)
- {
- LL_WARNS("OS") << "Failed to connect to D-Bus session bus: "
- << (error ? error->message : "unknown error") << LL_ENDL;
- if (error)
- g_error_free(error);
- return false;
- }
-
- // Try multiple power management services in order of preference
- // 1. org.freedesktop.PowerManagement (older standard)
- // 2. org.gnome.SessionManager (GNOME)
- // 3. org.kde.Solid.PowerManagement (KDE)
-
- const char* services[] = {
- "org.freedesktop.PowerManagement",
- "org.gnome.SessionManager",
- "org.kde.Solid.PowerManagement"
- };
-
- const char* paths[] = {
- "/org/freedesktop/PowerManagement/Inhibit",
- "/org/gnome/SessionManager",
- "/org/kde/Solid/PowerManagement"
- };
+#if LL_GLIB
+ const char* reason = inhibit_display ?
+ "Viewer active - preventing system and display sleep" :
+ "Viewer active - preventing system sleep";
- const char* interfaces[] = {
- "org.freedesktop.PowerManagement.Inhibit",
- "org.gnome.SessionManager",
- "org.kde.Solid.PowerManagement"
- };
-
- const char* methods[] = {
- "Inhibit",
- "Inhibit",
- "inhibit"
- };
-
- bool success = false;
-
- for (int i = 0; i < 3 && !success; ++i)
+ for (const PowerInhibitor& inhibitor : POWER_INHIBITORS)
{
- DBusGProxy* proxy = lldbus_g_proxy_new_for_name(
- bus,
- services[i],
- paths[i],
- interfaces[i]
- );
-
- if (!proxy)
- continue;
-
- error = nullptr;
- guint32 cookie = 0;
+ // Inhibit(app: s, reason: s) -> u, or GNOME's Inhibit(app: s, xid: u, reason: s, flags: u) -> u
+ // GNOME flags: 4 = suspend, 8 = idle (display), 12 = both
+ GVariant* args = inhibitor.gnome_args ?
+ g_variant_new("(susu)", "SecondLifeViewer", (guint32)0, reason,
+ (guint32)(inhibit_display ? 12 : 4)) :
+ g_variant_new("(ss)", "Second Life Viewer", reason);
- if (i == 0) // freedesktop.PowerManagement
- {
- // Inhibit(application_name: s, reason: s) -> cookie: u
- success = lldbus_g_proxy_call(
- proxy,
- methods[i],
- &error,
- G_TYPE_STRING, "Second Life Viewer",
- G_TYPE_STRING, inhibit_display ?
- "Viewer active - preventing system and display sleep" :
- "Viewer active - preventing system sleep",
- G_TYPE_INVALID,
- G_TYPE_UINT, &cookie,
- G_TYPE_INVALID
- );
- }
- else if (i == 1) // GNOME SessionManager
- {
- // Inhibit(app_id: s, toplevel_xid: u, reason: s, flags: u) -> cookie: u
- // flags: 4 = suspend, 8 = idle (display), 12 = both
- guint32 flags = inhibit_display ? 12 : 4;
- success = lldbus_g_proxy_call(
- proxy,
- methods[i],
- &error,
- G_TYPE_STRING, "SecondLifeViewer",
- G_TYPE_UINT, 0, // toplevel_xid (0 = none)
- G_TYPE_STRING, inhibit_display ?
- "Viewer active - preventing system and display sleep" :
- "Viewer active - preventing system sleep",
- G_TYPE_UINT, flags,
- G_TYPE_INVALID,
- G_TYPE_UINT, &cookie,
- G_TYPE_INVALID
- );
- }
- else if (i == 2) // KDE Solid
+ GVariant* result = call_power_manager(inhibitor, "Inhibit", args, G_VARIANT_TYPE("(u)"));
+ if (!result)
{
- // Different method signature for KDE
- success = lldbus_g_proxy_call(
- proxy,
- methods[i],
- &error,
- G_TYPE_INVALID,
- G_TYPE_INT, &cookie,
- G_TYPE_INVALID
- );
+ continue;
}
- if (success)
- {
- sPowerInhibitCookie = cookie;
- sPowerInhibitActive = true;
- LL_INFOS("OS") << "Successfully inhibited power management using "
- << services[i] << LL_ENDL;
- }
- else if (error)
- {
- LL_DEBUGS("OS") << "Failed to inhibit via " << services[i]
- << ": " << error->message << LL_ENDL;
- g_error_free(error);
- error = nullptr;
- }
+ guint32 cookie = 0;
+ g_variant_get(result, "(u)", &cookie);
+ g_variant_unref(result);
- g_object_unref(proxy);
+ sPowerInhibitCookie = cookie;
+ sPowerInhibitActive = true;
+ sActiveInhibitor = &inhibitor;
+ LL_INFOS("OS") << "Successfully inhibited power management using "
+ << inhibitor.service << LL_ENDL;
+ return true;
}
+#endif // LL_GLIB
- return success;
-
-#else // !LL_DBUS_ENABLED
- LL_WARNS("OS") << "Power management control not available - D-Bus support not enabled" << LL_ENDL;
return false;
-#endif
}
void LLAppViewerLinux::uninhibitPowerManagement()
{
-#if LL_DBUS_ENABLED
- if (!sPowerInhibitActive || sPowerInhibitCookie == 0)
+#if LL_GLIB
+ if (sPowerInhibitActive && sActiveInhibitor)
{
- return;
- }
-
- if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME))
- {
- LL_WARNS("OS") << "Failed to load D-Bus symbols for power management uninhibit" << LL_ENDL;
- return;
- }
-
- GError* error = nullptr;
- DBusGConnection* bus = lldbus_g_bus_get(DBUS_BUS_SESSION, &error);
-
- if (!bus)
- {
- if (error)
- g_error_free(error);
- return;
- }
-
- // Try to uninhibit using all services that might have been used
- const char* services[] = {
- "org.freedesktop.PowerManagement",
- "org.gnome.SessionManager",
- "org.kde.Solid.PowerManagement"
- };
-
- const char* paths[] = {
- "/org/freedesktop/PowerManagement/Inhibit",
- "/org/gnome/SessionManager",
- "/org/kde/Solid/PowerManagement"
- };
-
- const char* interfaces[] = {
- "org.freedesktop.PowerManagement.Inhibit",
- "org.gnome.SessionManager",
- "org.kde.Solid.PowerManagement"
- };
-
- const char* methods[] = {
- "UnInhibit",
- "Uninhibit",
- "uninhibit"
- };
-
- bool success = false;
-
- for (int i = 0; i < 3; ++i)
- {
- DBusGProxy* proxy = lldbus_g_proxy_new_for_name(
- bus,
- services[i],
- paths[i],
- interfaces[i]
- );
-
- if (!proxy)
- continue;
-
- error = nullptr;
-
- if (lldbus_g_proxy_call(
- proxy,
- methods[i],
- &error,
- G_TYPE_UINT, sPowerInhibitCookie,
- G_TYPE_INVALID,
- G_TYPE_INVALID))
+ GVariant* result = call_power_manager(*sActiveInhibitor, sActiveInhibitor->uninhibit,
+ g_variant_new("(u)", (guint32)sPowerInhibitCookie),
+ nullptr);
+ if (result)
{
- success = true;
+ g_variant_unref(result);
LL_INFOS("OS") << "Successfully uninhibited power management using "
- << services[i] << LL_ENDL;
- }
- else if (error)
- {
- LL_DEBUGS("OS") << "Failed to uninhibit via " << services[i]
- << ": " << error->message << LL_ENDL;
- g_error_free(error);
- error = nullptr;
+ << sActiveInhibitor->service << LL_ENDL;
}
- g_object_unref(proxy);
-
- if (success)
- break;
+ sActiveInhibitor = nullptr;
}
+#endif // LL_GLIB
sPowerInhibitCookie = 0;
sPowerInhibitActive = false;
-
-#endif // LL_DBUS_ENABLED
}
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()
@@ -717,7 +670,7 @@ bool LLAppViewerLinux::beingDebugged()
base += 1;
}
- if (strcmp(base, "gdb") == 0)
+ if (strcmp(base, "gdb") == 0 || strcmp(base, "lldb") == 0)
{
debugged = yes;
}
@@ -729,18 +682,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 6ab3682515..faac3c0a05 100644
--- a/indra/newview/llappviewerlinux.h
+++ b/indra/newview/llappviewerlinux.h
@@ -31,44 +31,36 @@ 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() override;
//
// 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);
- virtual void setOSHibernationMode(eHibernationMode mode);
+ bool initSLURLHandler() override;
+ bool sendURLToOtherInstance(const std::string& url) override;
+ void setOSHibernationMode(eHibernationMode mode) override;
private:
// Power management state tracking
@@ -80,21 +72,4 @@ private:
void uninhibitPowerManagement();
};
-#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 416efa9354..159c3af8a0 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -76,12 +76,14 @@
#if LL_VELOPACK
#include "llvelopack.h"
#endif
+#include "llversioninfovars.h"
// Bugsplat (http://bugsplat.com) crash reporting tool
#ifdef LL_BUGSPLAT
#include "BugSplat.h"
#include "boost/json.hpp" // Boost.Json
#include "llagent.h" // for agent location
+#include "llmemory.h"
#include "llstartup.h"
#include "llviewerregion.h"
#include "llvoavatarself.h" // for agent name
@@ -181,6 +183,16 @@ namespace
sBugSplatSender->setAttribute(WCSTR(L"VRAM"), WCSTR(STRINGIZE(gGLManager.mVRAM)));
sBugSplatSender->setAttribute(WCSTR(L"RAM"), WCSTR(STRINGIZE(gSysMemory.getPhysicalMemoryKB().value())));
+ const U32 avail_kb = LLMemory::getAvailableMemKB().value();
+ if (avail_kb != U32_MAX) // filter out initial values, if one is not set, all are not set
+ {
+ // Memory usage at crash time (can be 1s obsolete)
+ sBugSplatSender->setAttribute(WCSTR(L"MemAllocatedKB"), WCSTR(std::to_string(LLMemory::getAllocatedMemKB().value())));
+ sBugSplatSender->setAttribute(WCSTR(L"MemAvailableKB"), WCSTR(std::to_string(LLMemory::getAvailableMemKB().value())));
+ sBugSplatSender->setAttribute(WCSTR(L"MemMaxPhysicalKB"), WCSTR(std::to_string(LLMemory::getMaxMemKB().value())));
+ sBugSplatSender->setAttribute(WCSTR(L"MemAvailCommitMB"), WCSTR(std::to_string(LLMemory::getAvailableCommitMemMB().value())));
+ }
+
if (gAgent.getRegion())
{
// region location, when we have it
diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp
index c474f2885b..1e596624b9 100644
--- a/indra/newview/llcallbacklist.cpp
+++ b/indra/newview/llcallbacklist.cpp
@@ -70,33 +70,33 @@ void LLCallbackList::addFunction( callback_t func, void *data)
}
-BOOL LLCallbackList::containsFunction( callback_t func, void *data)
+bool LLCallbackList::containsFunction( callback_t func, void *data)
{
callback_pair_t t(func, data);
callback_list_t::iterator iter = std::find(mCallbackList.begin(), mCallbackList.end(), t);
if (iter != mCallbackList.end())
{
- return TRUE;
+ return true;
}
else
{
- return FALSE;
+ return false;
}
}
-BOOL LLCallbackList::deleteFunction( callback_t func, void *data)
+bool LLCallbackList::deleteFunction( callback_t func, void *data)
{
callback_pair_t t(func, data);
callback_list_t::iterator iter = std::find(mCallbackList.begin(), mCallbackList.end(), t);
if (iter != mCallbackList.end())
{
mCallbackList.erase(iter);
- return TRUE;
+ return true;
}
else
{
- return FALSE;
+ return false;
}
}
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 4a4985d8ac..bfcc2e4182 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -512,7 +512,7 @@ bool LLConversationLog::saveToFile(const std::string& filename)
return false;
}
- LLFILE* fp = LLFile::fopen(filename, "wb");
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("wb"));
if (!fp)
{
LL_WARNS() << "Couldn't open call log list" << filename << LL_ENDL;
@@ -556,7 +556,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
return false;
}
- LLFILE* fp = LLFile::fopen(filename, "rb");
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("rb"));
if (!fp)
{
LL_WARNS() << "Couldn't open call log list" << filename << LL_ENDL;
diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp
index 3941b82e75..246a9d28e4 100644
--- a/indra/newview/lldebugview.cpp
+++ b/indra/newview/lldebugview.cpp
@@ -101,7 +101,7 @@ void LLDebugView::init()
addChild(gSceneMonitorView);
gSceneMonitorView->setRect(rect);
- r.set(150, rect.getHeight() - 60, 820, 110);
+ r.set(150, rect.getHeight() - 60, 835, 110);
LLTextureView::Params tvp;
tvp.name("gTextureView");
tvp.rect(r);
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 6f6faf9909..8af044990f 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;
@@ -304,7 +303,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 cc702e8f56..f5a93a4804 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/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 6c151351ff..a42972205a 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -114,7 +114,7 @@ void LLStandardBumpmap::addstandard()
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness"); // BE_DARKNESS
std::string file_name = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "std_bump.ini" );
- LLFILE* file = LLFile::fopen( file_name, "rt" ); /*Flawfinder: ignore*/
+ LLFILE* file = LLFile::fopen( file_name, LLFILE_MODE("rt") ); /*Flawfinder: ignore*/
if( !file )
{
LL_WARNS() << "Could not open std_bump <" << file_name << ">" << LL_ENDL;
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/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index cdf3244389..fbecaa1583 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -204,22 +204,22 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
if (tex_a && (!tex_b || (tex_a == tex_b)))
{
- shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a);
tex_a->setFilteringOption(filter_mode);
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a);
blend_factor = 0; // only one tex provided, no blending
}
else if (tex_b && !tex_a)
{
- shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_b);
tex_b->setFilteringOption(filter_mode);
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_b);
blend_factor = 0; // only one tex provided, no blending
}
else if (tex_b != tex_a)
{
- shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a);
tex_a->setFilteringOption(filter_mode);
- shader->bindTexture(LLViewerShaderMgr::BUMP_MAP2, tex_b);
tex_b->setFilteringOption(filter_mode);
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a);
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP2, tex_b);
}
shader->bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &gPipeline.mWaterExclusionMask);
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.h b/indra/newview/lleventnotifier.h
index 2a9295129d..be96b7680f 100644
--- a/indra/newview/lleventnotifier.h
+++ b/indra/newview/lleventnotifier.h
@@ -47,7 +47,7 @@ struct LLEventInfo
std::string mSimName;
LLVector3d mPosGlobal;
F64 mUnixTime; // seconds from 1970
- BOOL mHasCover;
+ bool mHasCover;
U32 mCover;
U32 mEventFlags;
};
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 018d4c4bba..ec7ea398f0 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 c8692224f1..8140aaab22 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -259,7 +259,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");
@@ -510,10 +509,9 @@ bool LLFeatureManager::loadGPUClass()
mGPUClass = GPU_CLASS_5;
}
- #if LL_WINDOWS
- const F32Gigabytes MIN_PHYSICAL_MEMORY(8);
-
LLMemory::updateMemoryInfo();
+ #if LL_WINDOWS || LL_LINUX
+ const F32Gigabytes MIN_PHYSICAL_MEMORY(8);
F32Gigabytes physical_mem = LLMemory::getMaxMemKB();
if (MIN_PHYSICAL_MEMORY > physical_mem && mGPUClass > GPU_CLASS_1)
{
@@ -756,6 +754,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..f540ca549a 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,453 @@ 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; *.gltf; *.glb)", "dae;gltf;glb" });
+ filter_vec.push_back({ "Collada 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 +1553,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 +1640,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/llfloaterdirectory.h b/indra/newview/llfloaterdirectory.h
index de788443be..fb3b9975ed 100644
--- a/indra/newview/llfloaterdirectory.h
+++ b/indra/newview/llfloaterdirectory.h
@@ -76,6 +76,6 @@ private:
static LLFloaterDirectory *sInstance;
};
-//extern BOOL gDisplayEventHack;
+//extern bool gDisplayEventHack;
#endif // LL_LLDIRECTORYFLOATER_H
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c2a9008420..c2a1a306fe 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -155,6 +155,11 @@ void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const
{
// The general strategy when a session id is modified is to delete all related objects and create them anew.
+ // The conversation floater can be active while participant widgets are selected.
+ // Preserve that state separately so the new conversation widget can be selected
+ // after the server replaces an outgoing ad-hoc session id.
+ const bool was_active = old_session_id == getSelectedSession();
+
// Note however that the LLFloaterIMSession has its session id updated through a call to sessionInitReplyReceived()
// and do not need to be deleted and recreated (trying this creates loads of problems). We do need however to suppress
// its related mSessions record as it's indexed with the wrong id.
@@ -175,6 +180,11 @@ void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const
{
mSessions[new_session_id] = conversp;
}
+
+ if (was_active)
+ {
+ selectConversationPair(new_session_id, true, false, true);
+ }
}
@@ -1734,7 +1744,7 @@ bool LLFloaterIMContainer::visibleContextMenuItem(const LLSD& userdata)
void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
{
setVisibleAndFrontmost(false);
- selectConversationPair(session_id, true);
+ selectConversationPair(session_id, true, true, true);
LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
if (session_floater)
@@ -1780,13 +1790,13 @@ void LLFloaterIMContainer::selectNextConversationByID(const LLUUID& uuid)
}
// Synchronous select the conversation item and the conversation floater
-bool LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater/*=true*/)
+bool LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater/*=true*/, bool force_select_widget/*=false*/)
{
bool handled = true;
LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
/* widget processing */
- if (select_widget && mConversationsRoot->getSelectedCount() <= 1)
+ if (select_widget && (force_select_widget || mConversationsRoot->getSelectedCount() <= 1))
{
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
if (widget && widget->getParentFolder())
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 9f1690a9b9..4cb243aa64 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -74,7 +74,7 @@ public:
void showConversation(const LLUUID& session_id);
void selectConversation(const LLUUID& session_id);
void selectNextConversationByID(const LLUUID& session_id);
- bool selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater = true);
+ bool selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater = true, bool force_select_widget = false);
void clearAllFlashStates();
bool selectAdjacentConversation(bool focus_selected);
bool selectNextorPreviousConversation(bool select_next, bool focus_selected = true);
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index a442099ad1..aa03fc4e62 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -39,7 +39,6 @@ class LLAvatarName;
class LLButton;
class LLChatEntry;
class LLTextEditor;
-class LLPanelChatControlPanel;
class LLChatHistory;
class LLInventoryItem;
class LLInventoryCategory;
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 3ca1187ec9..d97b0eaa33 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -38,7 +38,6 @@
#include "llconversationview.h"
#include "lltexteditor.h"
-class LLPanelChatControlPanel;
class LLChatEntry;
class LLChatHistory;
class LLPanelEmojiComplete;
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 750d218f52..3dc4e53250 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
{
@@ -2146,12 +2134,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/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index 83abbb0357..83abbb0357 100755..100644
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
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/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 537dca99da..d58a5a76ca 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1359,7 +1359,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;
@@ -1505,7 +1505,7 @@ bool LLFloaterPreference::moveTranscriptsAndLog()
//Couldn't move the log and created a new directory so remove the new directory
if(madeDirectory)
{
- LLFile::rmdir(chatLogPath);
+ LLFile::remove(chatLogPath);
}
return false;
}
@@ -1531,7 +1531,7 @@ bool LLFloaterPreference::moveTranscriptsAndLog()
if(madeDirectory)
{
- LLFile::rmdir(chatLogPath);
+ LLFile::remove(chatLogPath);
}
return false;
@@ -2052,17 +2052,19 @@ void LLFloaterPreference::changed()
{
if (LLConversationLog::instance().getIsLoggingEnabled())
{
- getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0);
+ getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0);
}
else
{
// onClearLog clears list, then notifies changed() and only then clears file,
// so check presence of conversations before checking file, file will cleared later.
- llstat st;
- bool has_logs = LLConversationLog::instance().getConversations().size() > 0
- && LLFile::stat(LLConversationLog::instance().getFileName(), &st) == 0
- && S_ISREG(st.st_mode)
- && st.st_size > 0;
+ bool has_logs = false;
+ if (LLConversationLog::instance().getConversations().size() > 0)
+ {
+ std::filesystem::path file_path = fsyspath(LLConversationLog::instance().getFileName());
+ has_logs = LLFile::isfile(file_path)
+ && LLFile::size(file_path) > 0;
+ }
getChild<LLButton>("clear_log")->setEnabled(has_logs);
}
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index a8a1e507a8..8999a84c7e 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
@@ -158,7 +158,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refresh()
updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail", true), getChild<LLTextBox>("AvatarPhysicsDetailText", true));
updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail", true), getChild<LLTextBox>("TerrainMeshDetailText", true));
updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess", true), getChild<LLTextBox>("PostProcessText", true));
- updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail", true), getChild<LLTextBox>("SkyMeshDetailText", true));
+ updateSliderText(getChild<LLSliderCtrl>("GlowResolution", true), getChild<LLTextBox>("GlowResolutionText", true));
LLAvatarComplexityControls::setIndirectControls();
setMaxNonImpostorsText(
gSavedSettings.getU32("RenderAvatarMaxNonImpostors"),
@@ -277,16 +277,11 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText");
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
- LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
- LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
LLSliderCtrl* cas_slider = getChild<LLSliderCtrl>("RenderSharpness");
// disabled windlight
if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
{
- sky->setEnabled(false);
- sky_text->setEnabled(false);
-
//deferred needs windlight, disable deferred
ctrl_shadows->setEnabled(false);
ctrl_shadows->setValue(0);
@@ -340,16 +335,16 @@ 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()
{
- // WindLight
- LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
- LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
- sky->setEnabled(true);
- sky_text->setEnabled(true);
-
bool enabled = true;
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
@@ -384,6 +379,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/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp
index 92b3c92165..01108b5cfa 100644
--- a/indra/newview/llfloatersettingsdebug.cpp
+++ b/indra/newview/llfloatersettingsdebug.cpp
@@ -106,7 +106,6 @@ void LLFloaterSettingsDebug::onCommitSettings()
LLVector3 vector;
LLVector3d vectord;
- LLVector4 vector4;
LLQuaternion quat;
LLRect rect;
LLColor4 col4;
@@ -143,13 +142,6 @@ void LLFloaterSettingsDebug::onCommitSettings()
vectord.mdV[VZ] = mValSpinner3->getValue().asReal();
controlp->set(vectord.getValue());
break;
- case TYPE_VEC4:
- vector4.mV[VX] = (F32)mValSpinner1->getValue().asReal();
- vector4.mV[VY] = (F32)mValSpinner2->getValue().asReal();
- vector4.mV[VZ] = (F32)mValSpinner3->getValue().asReal();
- vector4.mV[VW] = (F32)mValSpinner4->getValue().asReal();
- controlp->set(vector4.getValue());
- break;
case TYPE_QUAT:
quat.mQ[VX] = mValSpinner1->getValueF32();
quat.mQ[VY] = mValSpinner2->getValueF32();
@@ -360,40 +352,6 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)
}
break;
}
- case TYPE_VEC4:
- {
- LLVector4 v;
- v.setValue(sd);
- mValSpinner1->setVisible(true);
- mValSpinner1->setLabel(std::string("X"));
- mValSpinner2->setVisible(true);
- mValSpinner2->setLabel(std::string("Y"));
- mValSpinner3->setVisible(true);
- mValSpinner3->setLabel(std::string("Z"));
- mValSpinner4->setVisible(true);
- mValSpinner4->setLabel(std::string("W"));
- if (!mValSpinner1->hasFocus())
- {
- mValSpinner1->setPrecision(3);
- mValSpinner1->setValue(v[VX]);
- }
- if (!mValSpinner2->hasFocus())
- {
- mValSpinner2->setPrecision(3);
- mValSpinner2->setValue(v[VY]);
- }
- if (!mValSpinner3->hasFocus())
- {
- mValSpinner3->setPrecision(3);
- mValSpinner3->setValue(v[VZ]);
- }
- if (!mValSpinner4->hasFocus())
- {
- mValSpinner4->setPrecision(3);
- mValSpinner4->setValue(v[VW]);
- }
- break;
- }
case TYPE_QUAT:
{
LLQuaternion q;
diff --git a/indra/newview/llfloatersimplesnapshot.cpp b/indra/newview/llfloatersimplesnapshot.cpp
index 55b39d9193..4671f74d6d 100644
--- a/indra/newview/llfloatersimplesnapshot.cpp
+++ b/indra/newview/llfloatersimplesnapshot.cpp
@@ -54,87 +54,162 @@ void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, L
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter = std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("post_profile_image_coro", httpPolicy);
+ httpAdapter = std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("post_thumbnail_image_coro", httpPolicy);
LLCore::HttpRequest::ptr_t httpRequest = std::make_shared<LLCore::HttpRequest>();
LLCore::HttpHeaders::ptr_t httpHeaders;
LLCore::HttpOptions::ptr_t httpOpts = std::make_shared<LLCore::HttpOptions>();
httpOpts->setFollowRedirects(true);
- LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
+ // Retry stage-2 upload by re-requesting a fresh one-time uploader capability (up to 3 attempts total)
+ const S32 MAX_UPLOAD_RETRIES = 2;
+ S32 upload_retry_count = 0;
+ LLUUID result_uuid;
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- // todo: notification?
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
- return;
- }
- if (!result.has("uploader"))
+ while (upload_retry_count <= MAX_UPLOAD_RETRIES)
{
- // todo: notification?
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
- return;
- }
- std::string uploader_cap = result["uploader"].asString();
- if (uploader_cap.empty())
- {
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
- return;
- }
+ // Stage 1: Request uploader URL
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
- // Upload the image
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- LLCore::HttpRequest::ptr_t uploaderhttpRequest = std::make_shared<LLCore::HttpRequest>();
- LLCore::HttpHeaders::ptr_t uploaderhttpHeaders = std::make_shared<LLCore::HttpHeaders>();
- LLCore::HttpOptions::ptr_t uploaderhttpOpts = std::make_shared<LLCore::HttpOptions>();
- S64 length;
+ if (!status)
+ {
+ LL_WARNS("Thumbnail") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
+ return;
+ }
- {
- llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
- if (!instream.is_open())
+ if (!result.has("uploader"))
{
- LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+ LL_WARNS("Thumbnail") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
return;
}
- length = instream.tellg();
- }
- uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional
- uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required!
- uploaderhttpOpts->setFollowRedirects(true);
+ std::string uploader_cap = result["uploader"].asString();
+ if (uploader_cap.empty())
+ {
+ LL_WARNS("Thumbnail") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
+ return;
+ }
- result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
+ // Stage 2: Upload the image
+ LLCore::HttpRequest::ptr_t uploaderhttpRequest = std::make_shared<LLCore::HttpRequest>();
+ LLCore::HttpHeaders::ptr_t uploaderhttpHeaders = std::make_shared<LLCore::HttpHeaders>();
+ LLCore::HttpOptions::ptr_t uploaderhttpOpts = std::make_shared<LLCore::HttpOptions>();
+ S64 length;
- httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ {
+ llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
+ if (!instream.is_open())
+ {
+ LL_WARNS("Thumbnail") << "Failed to open file " << path_to_image << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
+ return;
+ }
+ length = instream.tellg();
+ }
- LL_DEBUGS("Thumbnail") << result << LL_ENDL;
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2");
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, std::to_string(length));
+ uploaderhttpOpts->setFollowRedirects(true);
- if (!status)
- {
- LL_WARNS("Thumbnail") << "Failed to upload image " << status.toString() << LL_ENDL;
- return;
- }
+ result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
- if (result["state"].asString() != "complete")
- {
- if (result.has("message"))
- {
- LL_WARNS("Thumbnail") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
- }
- else
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LL_DEBUGS("Thumbnail") << result << LL_ENDL;
+
+ if (!status)
{
- LL_WARNS("Thumbnail") << "Failed to upload image " << result << LL_ENDL;
+ if (upload_retry_count < MAX_UPLOAD_RETRIES)
+ {
+ upload_retry_count++;
+ LL_WARNS("Thumbnail") << "Failed to upload image (attempt " << upload_retry_count
+ << " of " << (MAX_UPLOAD_RETRIES + 1) << "): " << status.toString()
+ << ", re-requesting uploader..." << LL_ENDL;
+ llcoro::suspendUntilTimeout(1.0f);
+ continue;
+ }
+ else
+ {
+ LL_WARNS("Thumbnail") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts: " << status.toString() << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
+ return;
+ }
}
- if (callback)
+ if (result["state"].asString() != "complete")
{
- callback(LLUUID());
+ if (upload_retry_count < MAX_UPLOAD_RETRIES)
+ {
+ upload_retry_count++;
+ if (result.has("message"))
+ {
+ LL_WARNS("Thumbnail") << "Failed to upload image, state " << result["state"]
+ << " message: " << result["message"] << " (attempt "
+ << upload_retry_count << " of " << (MAX_UPLOAD_RETRIES + 1)
+ << "), re-requesting uploader..." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("Thumbnail") << "Failed to upload image (attempt " << upload_retry_count
+ << " of " << (MAX_UPLOAD_RETRIES + 1)
+ << "), re-requesting uploader..." << LL_ENDL;
+ }
+ llcoro::suspendUntilTimeout(1.0f);
+ continue;
+ }
+ else
+ {
+ if (result.has("message"))
+ {
+ LL_WARNS("Thumbnail") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts, state " << result["state"]
+ << " message: " << result["message"] << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("Thumbnail") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts" << LL_ENDL;
+ }
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
+ return;
+ }
}
- return;
+
+ // Success!
+ result_uuid = result["new_asset"].asUUID();
+ break;
}
if (first_data.has("category_id"))
@@ -143,7 +218,7 @@ void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, L
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
if (cat)
{
- cat->setThumbnailUUID(result["new_asset"].asUUID());
+ cat->setThumbnailUUID(result_uuid);
}
gInventory.addChangedMask(LLInventoryObserver::INTERNAL, cat_id);
}
@@ -153,16 +228,18 @@ void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, L
LLViewerInventoryItem* item = gInventory.getItem(item_id);
if (item)
{
- item->setThumbnailUUID(result["new_asset"].asUUID());
+ item->setThumbnailUUID(result_uuid);
}
- // Are we supposed to get BulkUpdateInventory?
gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
}
if (callback)
{
- callback(result["new_asset"].asUUID());
+ callback(result_uuid);
}
+
+ // Cleanup
+ LLFile::remove(path_to_image);
}
///----------------------------------------------------------------------------
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index c3bc24c6b9..637871da0d 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -484,47 +484,47 @@ bool LLFloaterUIPreview::postBuild()
bool found_en_us = false;
std::string language_directory;
std::string xui_dir = get_xui_dir(); // directory containing localizations -- don't forget trailing delim
- mLanguageSelection->removeall(); // clear out anything temporarily in list from XML
+ mLanguageSelection->removeall(); // clear out anything temporarily in list from XML
LLDirIterator iter(xui_dir, "*");
- while(found) // for every directory
+ while (found) // for every directory
{
- if((found = iter.next(language_directory))) // get next directory
+ if ((found = iter.next(language_directory))) // get next directory
{
std::string full_path = gDirUtilp->add(xui_dir, language_directory);
- if(LLFile::isfile(full_path.c_str())) // if it's not a directory, skip it
+ if (!LLFile::isdir(full_path.c_str())) // if it's not a directory, skip it
{
continue;
}
- if(strncmp("template",language_directory.c_str(),8) && -1 == language_directory.find(".")) // if it's not the template directory or a hidden directory
+ if (strncmp("template",language_directory.c_str(), 8) && -1 == language_directory.find(".")) // if it's not the template directory or a hidden directory
{
- if(!strncmp("en",language_directory.c_str(),5)) // remember if we've seen en, so we can make it default
+ if (!strncmp("en",language_directory.c_str(), 5)) // remember if we've seen en, so we can make it default
{
found_en_us = true;
}
else
{
- mLanguageSelection->add(std::string(language_directory)); // add it to the language selection dropdown menu
+ mLanguageSelection->add(std::string(language_directory)); // add it to the language selection dropdown menu
mLanguageSelection_2->add(std::string(language_directory));
}
}
}
}
- if(found_en_us)
+ if (found_en_us)
{
- mLanguageSelection->add(std::string("en"),ADD_TOP); // make en first item if we found it
- mLanguageSelection_2->add(std::string("en"),ADD_TOP);
+ mLanguageSelection->add(std::string("en"), ADD_TOP); // make en first item if we found it
+ mLanguageSelection_2->add(std::string("en"), ADD_TOP);
}
else
{
std::string warning = std::string("No EN localization found; check your XUI directories!");
popupAndPrintWarning(warning);
}
- mLanguageSelection->selectFirstItem(); // select the first item
+ mLanguageSelection->selectFirstItem(); // select the first item
mLanguageSelection_2->selectFirstItem();
- refreshList(); // refresh the list of available floaters
+ refreshList(); // refresh the list of available floaters
return true;
}
@@ -574,7 +574,7 @@ void LLFloaterUIPreview::onClickExportSchema()
// std::string file_name(template_path + gDirUtilp->getDirDelimiter() + widget_name + ".rng");
- // LLFILE* rng_file = LLFile::fopen(file_name.c_str(), "w");
+ // LLFILE* rng_file = LLFile::fopen(file_name.c_str(), LLFILE_MODE("w"));
// {
// LLXMLNode::writeHeaderToFile(rng_file);
// const bool use_type_decorations = false;
@@ -892,8 +892,7 @@ void LLFloaterUIPreview::displayFloater(bool click, S32 ID)
// Add localization to title so user knows whether it's localized or defaulted to en
std::string full_path = getLocalizedDirectory() + path;
std::string floater_lang = "EN";
- llstat dummy;
- if(!LLFile::stat(full_path.c_str(), &dummy)) // if the file does not exist
+ if (LLFile::isfile(full_path.c_str())) // use localized language if the file exists
{
floater_lang = getLocStr(ID);
}
@@ -966,9 +965,8 @@ void LLFloaterUIPreview::onClickEditFloater()
}
file_path = getLocalizedDirectory() + file_name;
- // stat file to see if it exists (some localized versions may not have it there are no diffs, and then we try to open an nonexistent file)
- llstat dummy;
- if(LLFile::stat(file_path.c_str(), &dummy)) // if the file does not exist
+ // Does it exist? (Some localized versions may not have it when there are no diffs, and then we try to open a nonexistent file)
+ if (!LLFile::isfile(file_path.c_str())) // if the file does not exist
{
popupAndPrintWarning("No file for this floater exists in the selected localization. Opening the EN version instead.");
file_path = get_xui_dir() + mDelim + "en" + mDelim + file_name; // open the en version instead, by default
@@ -1117,15 +1115,14 @@ void LLFloaterUIPreview::onClickToggleDiffHighlighting()
std::string path_in_textfield = mDiffPathTextBox->getText(); // get file path
bool error = false;
- if(std::string("") == path_in_textfield) // check for blank file
+ if(std::string("") == path_in_textfield) // check for blank file
{
std::string warning = "Unable to highlight differences because no file was provided; fill in the relevant text field";
popupAndPrintWarning(warning);
error = true;
}
- llstat dummy;
- if(LLFile::stat(path_in_textfield.c_str(), &dummy) && !error) // check if the file exists (empty check is reduntant but useful for the informative error message)
+ if (!LLFile::isfile(path_in_textfield.c_str()) && !error) // check if the file exists (empty check is redundant but useful for the informative error message)
{
std::string warning = std::string("Unable to highlight differences because an invalid path to a difference file was provided:\"") + path_in_textfield + "\"";
popupAndPrintWarning(warning);
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 87a9b91015..87a9b91015 100755..100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 5484ce6276..41d7d93528 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 ebb9dc3e3c..446742f316 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);
@@ -520,21 +520,17 @@ bool LLGLTFPreviewTexture::render()
// *HACK: Hide mExposureMap from generateExposure
gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure);
- gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap);
gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap);
gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap, /*use_history = */ false);
gPipeline.gammaCorrect(&screen, &gPipeline.mPostPingMap);
LLVertexBuffer::unbind();
gPipeline.generateGlow(&gPipeline.mPostPingMap);
gPipeline.combineGlow(&gPipeline.mPostPingMap, &screen);
- gPipeline.renderDoF(&screen, &gPipeline.mPostPingMap);
- gPipeline.applyFXAA(&gPipeline.mPostPingMap, &screen);
// *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame)
gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure);
// Final render
-
gDeferredPostNoDoFProgram.bind();
// From LLPipeline::renderFinalize: "Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems."
diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp
index 1fe2965784..6c72b0b7ee 100644
--- a/indra/newview/llinventorygallerymenu.cpp
+++ b/indra/newview/llinventorygallerymenu.cpp
@@ -334,13 +334,13 @@ 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);
if (!global_pos.isExactlyZero())
{
- 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/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 7a80c46c73..d0d4d85993 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -396,6 +396,8 @@ LLInventoryModel::LLInventoryModel()
: // These are now ordered, keep them that way.
mBacklinkMMap(),
mIsAgentInvUsable(false),
+ mLibrarySkeletonLoadTime(0.f),
+ mAgentSkeletonLoadTime(0.f),
mRootFolderID(),
mLibraryRootFolderID(),
mLibraryOwnerID(),
@@ -2865,7 +2867,7 @@ bool LLInventoryModel::loadSkeleton(
const S32 NO_VERSION = LLViewerInventoryCategory::VERSION_UNKNOWN;
std::string gzip_filename(inventory_filename);
gzip_filename.append(".gz");
- LLFILE* fp = LLFile::fopen(gzip_filename, "rb");
+ LLFILE* fp = LLFile::fopen(gzip_filename, LLFILE_MODE("rb"));
bool remove_inventory_file = false;
if (LLAppViewer::instance()->isSecondInstance())
{
@@ -3100,6 +3102,16 @@ bool LLInventoryModel::loadSkeleton(
<< " after " << timer.getElapsedTimeF32() << " seconds."
<< LL_ENDL;
+ const F32 elapsed = timer.getElapsedTimeF32();
+ if (owner_id == mLibraryOwnerID)
+ {
+ mLibrarySkeletonLoadTime = elapsed;
+ }
+ else
+ {
+ mAgentSkeletonLoadTime = elapsed;
+ }
+
return rv;
}
@@ -5054,7 +5066,7 @@ bool decompress_file(const char* src_filename, const char* dst_filename)
// open the files
src = gzopen(src_filename, "rb");
if(!src) goto err_decompress;
- dst = LLFile::fopen(dst_filename, "wb");
+ dst = LLFile::fopen(dst_filename, LLFILE_MODE("wb"));
if(!dst) goto err_decompress;
// decompress.
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 2c516f6a86..6ac307dd68 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -158,8 +158,12 @@ protected:
public:
// The inventory model usage is sensitive to the initial construction of the model
bool isInventoryUsable() const;
+ F32 getLibrarySkeletonLoadTime() const { return mLibrarySkeletonLoadTime; }
+ F32 getAgentSkeletonLoadTime() const { return mAgentSkeletonLoadTime; }
private:
bool mIsAgentInvUsable; // used to handle an invalid inventory state
+ F32 mLibrarySkeletonLoadTime;
+ F32 mAgentSkeletonLoadTime;
// One-time initialization of HTTP system.
void initHttpRequest();
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 82eefb50ac..b02b2e2eb9 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -192,6 +192,8 @@ LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch():
mFetchCount(0),
mLastFetchCount(0),
mFetchFolderCount(0),
+ mInitialFetchDuration(0.f),
+ mInitialFetchDurationCaptured(false),
mAllRecursiveFoldersFetched(false),
mRecursiveInventoryFetchStarted(false),
mRecursiveLibraryFetchStarted(false),
@@ -199,6 +201,15 @@ LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch():
mMinTimeBetweenFetches(0.3f)
{}
+void LLInventoryModelBackgroundFetch::markFetchStarted()
+{
+ if (!mBackgroundFetchActive)
+ {
+ mFetchStartTimer.reset();
+ }
+ mBackgroundFetchActive = true;
+}
+
LLInventoryModelBackgroundFetch::~LLInventoryModelBackgroundFetch()
{
gIdleCallbacks.deleteFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, nullptr);
@@ -289,7 +300,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive)
// it's a folder, do a bulk fetch
LL_DEBUGS(LOG_INV) << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL;
- mBackgroundFetchActive = true;
+ markFetchStarted();
mFolderFetchActive = true;
EFetchType recursion_type = recursive ? FT_RECURSIVE : FT_DEFAULT;
if (id.isNull())
@@ -376,7 +387,7 @@ void LLInventoryModelBackgroundFetch::scheduleFolderFetch(const LLUUID& cat_id,
{
if (mFetchFolderQueue.empty() || mFetchFolderQueue.front().mUUID != cat_id)
{
- mBackgroundFetchActive = true;
+ markFetchStarted();
mFolderFetchActive = true;
if (forced)
@@ -403,7 +414,7 @@ void LLInventoryModelBackgroundFetch::scheduleItemFetch(const LLUUID& item_id, b
{
if (mFetchItemQueue.empty() || mFetchItemQueue.front().mUUID != item_id)
{
- mBackgroundFetchActive = true;
+ markFetchStarted();
if (forced)
{
// check if already requested
@@ -447,7 +458,7 @@ void LLInventoryModelBackgroundFetch::fetchFolderAndLinks(const LLUUID& cat_id,
});
// start idle loop to track completion
- mBackgroundFetchActive = true;
+ markFetchStarted();
mFolderFetchActive = true;
gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, nullptr);
}
@@ -489,14 +500,14 @@ void LLInventoryModelBackgroundFetch::fetchCOF(nullary_func_t callback)
});
// start idle loop to track completion
- mBackgroundFetchActive = true;
+ markFetchStarted();
mFolderFetchActive = true;
gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, nullptr);
}
void LLInventoryModelBackgroundFetch::findLostItems()
{
- mBackgroundFetchActive = true;
+ markFetchStarted();
mFolderFetchActive = true;
mFetchFolderQueue.emplace_back(LLUUID::null, FT_RECURSIVE);
gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, nullptr);
@@ -515,13 +526,18 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched()
mFolderFetchActive = false;
if (isBulkFetchProcessingComplete())
{
+ if (mAllRecursiveFoldersFetched && !mInitialFetchDurationCaptured)
+ {
+ mInitialFetchDuration = mFetchStartTimer.getElapsedTimeF32();
+ mInitialFetchDurationCaptured = true;
+ }
mBackgroundFetchActive = false;
}
// For now only informs about initial fetch being done
mFoldersFetchedSignal();
- LL_INFOS(LOG_INV) << "Inventory background fetch completed" << LL_ENDL;
+ LL_INFOS(LOG_INV) << "Inventory background fetch completed after: " << mFetchStartTimer.getElapsedTimeF32() << LL_ENDL;
}
boost::signals2::connection LLInventoryModelBackgroundFetch::setFetchCompletionCallback(folders_fetched_callback_t cb)
@@ -843,6 +859,11 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis()
if (isBulkFetchProcessingComplete())
{
+ if (mAllRecursiveFoldersFetched && !mInitialFetchDurationCaptured)
+ {
+ mInitialFetchDuration = mFetchStartTimer.getElapsedTimeF32();
+ mInitialFetchDurationCaptured = true;
+ }
mBackgroundFetchActive = false;
}
}
diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h
index ef6fa06e9f..6a5e0f66ff 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.h
+++ b/indra/newview/llinventorymodelbackgroundfetch.h
@@ -70,6 +70,7 @@ public:
bool inventoryFetchStarted() const;
bool inventoryFetchCompleted() const;
bool inventoryFetchInProgress() const;
+ F32 getInitialFetchDuration() const { return mInitialFetchDuration; }
void findLostItems();
void incrFetchCount(S32 fetching);
@@ -120,6 +121,8 @@ protected:
bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const;
private:
+ void markFetchStarted();
+
bool mRecursiveInventoryFetchStarted;
bool mRecursiveLibraryFetchStarted;
bool mRecursiveMarketplaceFetchStarted; // AIS3 specific
@@ -133,6 +136,9 @@ private:
S32 mLastFetchCount; // for debug
S32 mFetchFolderCount;
+ LLFrameTimer mFetchStartTimer;
+ F32 mInitialFetchDuration;
+ bool mInitialFetchDurationCaptured;
LLFrameTimer mFetchTimer;
F32 mMinTimeBetweenFetches;
fetch_queue_t mFetchFolderQueue;
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
index 666ab4f5d0..c082c632f1 100644
--- a/indra/newview/llkeyconflict.cpp
+++ b/indra/newview/llkeyconflict.cpp
@@ -575,7 +575,7 @@ void LLKeyConflictHandler::saveToSettings(bool temporary)
// Write the resulting XML to file
if (!output_node->isNull())
{
- LLFILE *fp = LLFile::fopen(filename, "w");
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("w"));
if (fp != NULL)
{
LLXMLNode::writeHeaderToFile(fp);
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 1329b1308d..3567ca8e4a 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -31,10 +31,6 @@
/* own header */
#include "lllocalbitmaps.h"
-/* boost: will not compile unless equivalent is undef'd, beware. */
-#include "fix_macros.h"
-#include <boost/filesystem.hpp>
-
/* image compression headers. */
#include "llimagebmp.h"
#include "llimagetga.h"
@@ -42,11 +38,8 @@
#include "llimagejpeg.h"
#include "llimagepng.h"
-/* time headers */
-#include <time.h>
-#include <ctime>
-
/* misc headers */
+#include "fsyspath.h"
#include "llgltfmaterial.h"
#include "llscrolllistctrl.h"
#include "lllocaltextureobject.h"
@@ -192,15 +185,8 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
if (gDirUtilp->fileExists(mFilename))
{
// verifying that the file has indeed been modified
-
-#ifndef LL_WINDOWS
- const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename));
-#else
- const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(ll_convert<std::wstring>(mFilename)));
-#endif
- LLSD new_last_modified = asctime(localtime(&temp_time));
-
- if (mLastModified.asString() != new_last_modified.asString())
+ const std::filesystem::file_time_type new_last_modified = std::filesystem::last_write_time(fsyspath(mFilename));
+ if (mLastModified != new_last_modified)
{
/* loading the image file and decoding it, here is a critical point which,
if fails, invalidates the whole update (or unit creation) process. */
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index 6c9d65e3b6..c4aaeae719 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -32,6 +32,7 @@
#include "lleventtimer.h"
#include "llpointer.h"
#include "llwearabletype.h"
+#include <filesystem>
class LLScrollListCtrl;
class LLImageRaw;
@@ -99,7 +100,7 @@ class LLLocalBitmap
LLUUID mTrackingID;
LLUUID mWorldID;
bool mValid;
- LLSD mLastModified;
+ std::filesystem::file_time_type mLastModified;
EExtension mExtension;
ELinkStatus mLinkStatus;
S32 mUpdateRetries;
diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp
index d6facad23d..e9f2299be7 100644
--- a/indra/newview/lllocalgltfmaterials.cpp
+++ b/indra/newview/lllocalgltfmaterials.cpp
@@ -30,15 +30,8 @@
/* own header */
#include "lllocalgltfmaterials.h"
-/* boost: will not compile unless equivalent is undef'd, beware. */
-#include "fix_macros.h"
-#include <boost/filesystem.hpp>
-
-/* time headers */
-#include <time.h>
-#include <ctime>
-
/* misc headers */
+#include "fsyspath.h"
#include "llgltfmateriallist.h"
#include "llimage.h"
#include "llinventoryicon.h"
@@ -130,15 +123,8 @@ bool LLLocalGLTFMaterial::updateSelf()
if (gDirUtilp->fileExists(mFilename))
{
// verifying that the file has indeed been modified
-
-#ifndef LL_WINDOWS
- const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename));
-#else
- const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(ll_convert<std::wstring>(mFilename)));
-#endif
- LLSD new_last_modified = asctime(localtime(&temp_time));
-
- if (mLastModified.asString() != new_last_modified.asString())
+ const std::filesystem::file_time_type new_last_modified = std::filesystem::last_write_time(fsyspath(mFilename));
+ if (mLastModified != new_last_modified)
{
if (loadMaterial())
{
diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h
index b806b54508..bf9a8c68ae 100644
--- a/indra/newview/lllocalgltfmaterials.h
+++ b/indra/newview/lllocalgltfmaterials.h
@@ -30,6 +30,7 @@
#include "lleventtimer.h"
#include "llpointer.h"
#include "llgltfmateriallist.h"
+#include <filesystem>
class LLScrollListCtrl;
class LLGLTFMaterial;
@@ -73,7 +74,7 @@ private: /* members */
std::string mShortName;
LLUUID mTrackingID;
LLUUID mWorldID;
- LLSD mLastModified;
+ std::filesystem::file_time_type mLastModified;
EExtension mExtension;
ELinkStatus mLinkStatus;
S32 mUpdateRetries;
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/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 30ea255e24..59f6993a0b 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -453,7 +453,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
// If we got here, we managed to stat the file.
// Open the file to read in binary mode to prevent interpreting other characters as EOF
- LLFILE* fptr = LLFile::fopen(log_file_name, "rb"); /*Flawfinder: ignore*/
+ LLFILE* fptr = LLFile::fopen(log_file_name, LLFILE_MODE("rb")); /*Flawfinder: ignore*/
if (!fptr)
{ // Ok, this is strange but not really tragic in the big picture of things
LL_WARNS("ChatHistory") << "Unable to read file " << log_file_name << " after stat was successful" << LL_ENDL;
@@ -890,7 +890,7 @@ bool LLLogChat::isAdHocTranscriptExist(std::string file_name)
bool LLLogChat::isTranscriptFileFound(std::string fullname)
{
bool result = false;
- LLFILE * filep = LLFile::fopen(fullname, "rb");
+ LLFILE * filep = LLFile::fopen(fullname, LLFILE_MODE("rb"));
if (NULL != filep)
{
if (makeLogFileName("chat") == fullname)
@@ -1183,7 +1183,7 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL
}
bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
- LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "rb");/*Flawfinder: ignore*/
+ LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), LLFILE_MODE("rb"));/*Flawfinder: ignore*/
if (!fptr)
{
@@ -1192,17 +1192,17 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL
{
std::string old_name(file_name);
old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());
- fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "rb");
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), LLFILE_MODE("rb"));
if (fptr)
{
fclose(fptr);
LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name));
}
- fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "rb");
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), LLFILE_MODE("rb"));
}
if (!fptr)
{
- fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "rb");/*Flawfinder: ignore*/
+ fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), LLFILE_MODE("rb")); /*Flawfinder: ignore*/
if (!fptr)
{
mNewLoad = false;
diff --git a/indra/newview/lllookshistorypanel.h b/indra/newview/lllookshistorypanel.h
deleted file mode 100644
index 6293de7170..0000000000
--- a/indra/newview/lllookshistorypanel.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file llpanelteleporthistory.h
- * @brief Teleport history represented by a scrolling list
- * class definition
- *
- * $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$
- */
-
-#ifndef LL_LLPANELLOOKSHISTORY_H
-#define LL_LLPANELLOOKSHISTORY_H
-
-#include "lluictrlfactory.h"
-#include "llscrolllistctrl.h"
-
-#include "llpanelappearancetab.h"
-#include "lllookshistory.h"
-
-class LLLooksHistoryPanel : public LLPanelAppearanceTab
-{
-public:
- LLLooksHistoryPanel();
- virtual ~LLLooksHistoryPanel();
-
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onSearchEdit(const std::string& string);
- /*virtual*/ void onShowOnMap();
- /*virtual*/ void onLooks();
- ///*virtual*/ void onCopySLURL();
-
- void showLooksHistory();
- void handleItemSelect(const LLSD& data);
-
- static void onDoubleClickItem(void* user_data);
-
-private:
- enum LOOKS_HISTORY_COLUMN_ORDER
- {
- LIST_ICON,
- LIST_ITEM_TITLE,
- LIST_INDEX
- };
-
- LLLooksHistory* mLooksHistory;
- LLScrollListCtrl* mHistoryItems;
- std::string mFilterSubString;
-};
-
-#endif //LL_LLPANELLOOKSHISTORY_H
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 30f634f6d4..dad04f4eab 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 07ed667b0a..59c7dddc33 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -109,9 +109,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;
};
@@ -272,13 +272,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 723f834d6f..4dc3f958aa 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 c04f874923..5fc0b1b290 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -120,13 +120,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 std::unordered_map<TEMaterialPair, get_callback_te_t*> get_callback_te_map_t;
+ typedef std::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 26422d7d47..9b61529b5d 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -1038,10 +1038,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;
- }
mLoadingState = LOADING_STATE_LOADED;
};
break;
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index e407bfbbcb..0a092f21d2 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -215,7 +215,6 @@ public:
mStretchToFill,
mMaintainAspectRatio,
mHideLoading,
- mHidingInitialLoad,
mClearCache,
mHoverTextChanged,
mDecoupleTextureSize,
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index fb6ecedcbf..933a6d530f 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -4580,7 +4580,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 b2e21bea1c..bc9ca46672 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/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 36bcba2c5c..880e675c6b 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -684,7 +684,7 @@ bool LLMuteList::loadFromFile(const std::string& filename, EMuteListSource sourc
return false;
}
- LLFILE* fp = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("rb")); /*Flawfinder: ignore*/
if (!fp)
{
LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL;
@@ -751,7 +751,7 @@ bool LLMuteList::saveToFile(const std::string& filename)
return false;
}
- LLFILE* fp = LLFile::fopen(filename, "wb"); /*Flawfinder: ignore*/
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("wb")); /*Flawfinder: ignore*/
if (!fp)
{
LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL;
@@ -1084,7 +1084,7 @@ LLRenderMuteList::LLRenderMuteList()
bool LLRenderMuteList::saveToFile()
{
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt");
- LLFILE* fp = LLFile::fopen(filename, "wb");
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("wb"));
if (!fp)
{
LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL;
@@ -1109,7 +1109,7 @@ bool LLRenderMuteList::loadFromFile()
LL_PROFILE_ZONE_SCOPED;
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt");
- LLFILE* fp = LLFile::fopen(filename, "rb");
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("rb"));
if (!fp)
{
LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL;
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 2bb6af24bc..2bb6af24bc 100755..100644
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 852f2dab21..9b21a217db 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1005,6 +1005,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/llpaneldirland.cpp b/indra/newview/llpaneldirland.cpp
index f85a8b948e..11ca7a0af0 100644
--- a/indra/newview/llpaneldirland.cpp
+++ b/indra/newview/llpaneldirland.cpp
@@ -183,7 +183,7 @@ void LLPanelDirLand::performQuery()
if (list)
{
std::string sort_name = list->getSortColumnName();
- BOOL sort_asc = list->getSortAscending();
+ bool sort_asc = list->getSortAscending();
if (sort_name == "name")
{
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
deleted file mode 100644
index 07a8641a92..0000000000
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file llpanelimcontrolpanel.cpp
- * @brief LLPanelIMControlPanel and related class implementations
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-#include "llfloaterreg.h"
-
-#include "llpanelimcontrolpanel.h"
-
-#include "llagent.h"
-#include "llappviewer.h" // for gDisconnected
-#include "llavataractions.h"
-#include "llavatariconctrl.h"
-#include "llbutton.h"
-#include "llgroupactions.h"
-#include "llavatarlist.h"
-#include "llparticipantlist.h"
-#include "llimview.h"
-#include "llspeakers.h"
-#include "lltrans.h"
-
-
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
deleted file mode 100644
index c7f5263bec..0000000000
--- a/indra/newview/llpanelimcontrolpanel.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * @file llpanelimcontrolpanel.h
- * @brief LLPanelIMControlPanel and related class definitions
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLPANELIMCONTROLPANEL_H
-#define LL_LLPANELIMCONTROLPANEL_H
-
-#include "llpanel.h"
-#include "llcallingcard.h"
-
-class LLParticipantList;
-
-class LLPanelChatControlPanel
- : public LLPanel
-{
-public:
- LLPanelChatControlPanel() :
- mSessionId(LLUUID()) {};
- ~LLPanelChatControlPanel();
-
- virtual BOOL postBuild();
-
- virtual void setSessionId(const LLUUID& session_id);
- const LLUUID& getSessionId() { return mSessionId; }
-
-private:
- LLUUID mSessionId;
-
- // connection to voice channel state change signal
- boost::signals2::connection mVoiceChannelStateChangeConnection;
-};
-
-class LLPanelGroupControlPanel : public LLPanelChatControlPanel
-{
-public:
- LLPanelGroupControlPanel(const LLUUID& session_id);
- ~LLPanelGroupControlPanel();
-
- BOOL postBuild();
-
- void setSessionId(const LLUUID& session_id);
- /*virtual*/ void draw();
-
-protected:
- LLUUID mGroupID;
-
- LLParticipantList* mParticipantList;
-
-private:
- void onSortMenuItemClicked(const LLSD& userdata);
-};
-
-class LLPanelAdHocControlPanel : public LLPanelGroupControlPanel
-{
-public:
- LLPanelAdHocControlPanel(const LLUUID& session_id);
-
- BOOL postBuild();
-
-};
-
-#endif // LL_LLPANELIMCONTROLPANEL_H
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/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 34d2d4d6a5..b33696244d 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -113,77 +113,131 @@ LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::stri
LLCore::HttpOptions::ptr_t httpOpts = std::make_shared<LLCore::HttpOptions>();
httpOpts->setFollowRedirects(true);
- LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
+ // Retry stage-2 upload by re-requesting a fresh one-time uploader capability (up to 3 attempts total)
+ const S32 MAX_UPLOAD_RETRIES = 2;
+ S32 upload_retry_count = 0;
+ LLUUID result_uuid;
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- // todo: notification?
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
- return LLUUID::null;
- }
- if (!result.has("uploader"))
+ while (upload_retry_count <= MAX_UPLOAD_RETRIES)
{
- // todo: notification?
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
- return LLUUID::null;
- }
- std::string uploader_cap = result["uploader"].asString();
- if (uploader_cap.empty())
- {
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
- return LLUUID::null;
- }
+ // Stage 1: Request uploader URL
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
- // Upload the image
- LLCore::HttpRequest::ptr_t uploaderhttpRequest = std::make_shared<LLCore::HttpRequest>();
- LLCore::HttpHeaders::ptr_t uploaderhttpHeaders = std::make_shared<LLCore::HttpHeaders>();
- LLCore::HttpOptions::ptr_t uploaderhttpOpts = std::make_shared<LLCore::HttpOptions>();
- S64 length;
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- {
- llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
- if (!instream.is_open())
+ if (!status)
{
- LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ if (!result.has("uploader"))
+ {
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
return LLUUID::null;
}
- length = instream.tellg();
- }
- uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional
- uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required!
- uploaderhttpOpts->setFollowRedirects(true);
+ std::string uploader_cap = result["uploader"].asString();
+ if (uploader_cap.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ // Stage 2: Upload the image
+ LLCore::HttpRequest::ptr_t uploaderhttpRequest = std::make_shared<LLCore::HttpRequest>();
+ LLCore::HttpHeaders::ptr_t uploaderhttpHeaders = std::make_shared<LLCore::HttpHeaders>();
+ LLCore::HttpOptions::ptr_t uploaderhttpOpts = std::make_shared<LLCore::HttpOptions>();
+ S64 length;
+
+ {
+ llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
+ if (!instream.is_open())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+ return LLUUID::null;
+ }
+ length = instream.tellg();
+ }
- result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2");
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, std::to_string(length));
+ uploaderhttpOpts->setFollowRedirects(true);
- httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
- LL_DEBUGS("AvatarProperties") << result << LL_ENDL;
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- if (!status)
- {
- LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL;
- return LLUUID::null;
- }
+ LL_DEBUGS("AvatarProperties") << result << LL_ENDL;
- if (result["state"].asString() != "complete")
- {
- if (result.has("message"))
+ if (!status)
{
- LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
+ if (upload_retry_count < MAX_UPLOAD_RETRIES)
+ {
+ upload_retry_count++;
+ LL_WARNS("AvatarProperties") << "Failed to upload image (attempt " << upload_retry_count
+ << " of " << (MAX_UPLOAD_RETRIES + 1) << "): " << status.toString()
+ << ", re-requesting uploader..." << LL_ENDL;
+ llcoro::suspendUntilTimeout(1.0f);
+ continue;
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts: " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
}
- else
+
+ // Todo: should we really repeat if 'complete' not set?
+ if (result["state"].asString() != "complete")
{
- LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL;
+ if (upload_retry_count < MAX_UPLOAD_RETRIES)
+ {
+ upload_retry_count++;
+ if (result.has("message"))
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"]
+ << " message: " << result["message"] << " (attempt "
+ << upload_retry_count << " of " << (MAX_UPLOAD_RETRIES + 1)
+ << "), re-requesting uploader..." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image (attempt " << upload_retry_count
+ << " of " << (MAX_UPLOAD_RETRIES + 1)
+ << "), re-requesting uploader..." << LL_ENDL;
+ }
+ llcoro::suspendUntilTimeout(1.0f);
+ continue;
+ }
+ else
+ {
+ if (result.has("message"))
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts, state " << result["state"]
+ << " message: " << result["message"] << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts" << LL_ENDL;
+ }
+ return LLUUID::null;
+ }
}
- return LLUUID::null;
+
+ // Success!
+ result_uuid = result["new_asset"].asUUID();
+ break;
}
- return result["new_asset"].asUUID();
+ return result_uuid;
}
enum EProfileImageType
diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp
index 0e6b61f316..609177046e 100644
--- a/indra/newview/llpanelvoicedevicesettings.cpp
+++ b/indra/newview/llpanelvoicedevicesettings.cpp
@@ -338,8 +338,12 @@ void LLPanelVoiceDeviceSettings::initialize()
// put voice client in "tuning" mode
if (mUseTuningMode)
{
+ // WebRTC tuning only affects the local audio device (mic-level
+ // monitoring and device selection); the peer connection stays up and
+ // its send/receive tracks are disabled for the duration. Unlike Vivox,
+ // there's no need to suspend (and tear down) the voice channel, which
+ // previously dropped the call and failed to reconnect on resume.
LLVoiceClient::getInstance()->tuningStart();
- LLVoiceChannel::suspend();
}
}
@@ -348,7 +352,6 @@ void LLPanelVoiceDeviceSettings::cleanup()
if (mUseTuningMode)
{
LLVoiceClient::getInstance()->tuningStop();
- LLVoiceChannel::resume();
}
}
diff --git a/indra/newview/llpathfindingnavmesh.cpp b/indra/newview/llpathfindingnavmesh.cpp
index c9fbeba2f3..5bb33a65f2 100644
--- a/indra/newview/llpathfindingnavmesh.cpp
+++ b/indra/newview/llpathfindingnavmesh.cpp
@@ -139,7 +139,8 @@ void LLPathfindingNavMesh::handleNavMeshResult(const LLSD &pContent, U32 pNavMes
ENavMeshRequestStatus status;
if ( pContent.has(NAVMESH_DATA_FIELD) )
{
- const LLSD::Binary &value = pContent.get(NAVMESH_DATA_FIELD).asBinary();
+ LLSD nav_data = pContent.get(NAVMESH_DATA_FIELD);
+ const LLSD::Binary& value = nav_data.asBinary();
auto binSize = value.size();
std::string newStr(reinterpret_cast<const char *>(&value[0]), binSize);
std::istringstream streamdecomp( newStr );
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index eefd19e153..85de487aae 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -576,8 +576,7 @@ void LLPreviewNotecard::syncExternal()
{
// Sync with external editor.
std::string tmp_file = getTmpFileName();
- llstat s;
- if (LLFile::stat(tmp_file, &s) == 0) // file exists
+ if (LLFile::isfile(tmp_file)) // file exists
{
if (mLiveFile) mLiveFile->ignoreNextUpdate();
writeToFile(tmp_file);
@@ -803,7 +802,7 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
return false;
}
- LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ LLFILE* file = LLFile::fopen(filename, LLFILE_MODE("rb")); /*Flawfinder: ignore*/
if (!file)
{
LL_WARNS() << "Error opening " << filename << LL_ENDL;
@@ -834,7 +833,7 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
bool LLPreviewNotecard::writeToFile(const std::string& filename)
{
- LLFILE* fp = LLFile::fopen(filename, "wb");
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("wb"));
if (!fp)
{
LL_WARNS() << "Unable to write to " << filename << LL_ENDL;
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index c2aa4925bd..53d0a712a8 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -632,7 +632,7 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename)
return false;
}
- LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ LLFILE* file = LLFile::fopen(filename, LLFILE_MODE("rb")); /*Flawfinder: ignore*/
if (!file)
{
LL_WARNS() << "Error opening " << filename << LL_ENDL;
@@ -663,7 +663,7 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename)
bool LLScriptEdCore::writeToFile(const std::string& filename)
{
- LLFILE* fp = LLFile::fopen(filename, "wb");
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("wb"));
if (!fp)
{
LL_WARNS() << "Unable to write to " << filename << LL_ENDL;
@@ -694,8 +694,7 @@ void LLScriptEdCore::sync()
if (mLiveFile)
{
std::string tmp_file = mLiveFile->filename();
- llstat s;
- if (LLFile::stat(tmp_file, &s) == 0) // file exists
+ if (LLFile::isfile(tmp_file)) // file exists
{
mLiveFile->ignoreNextUpdate();
writeToFile(tmp_file);
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 72f92785fc..aebc4d5ac0 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6621,7 +6621,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/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index b48417bd71..623db82939 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -402,8 +402,6 @@ void LLSidepanelInventory::onOpen(const LLSD& key)
gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", (U32)time_corrected());
}
#endif
-
- gAgent.showLatestFeatureNotification("inventory");
}
void LLSidepanelInventory::performActionOnSelection(const std::string &action)
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index e696c2dcb5..7d2828a872 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -54,7 +54,6 @@
#include "llviewertexturelist.h"
#include "llwindow.h"
#include "llworld.h"
-#include <boost/filesystem.hpp>
constexpr F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
@@ -238,11 +237,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 6e18bb979a..c2ac07af88 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1662,13 +1662,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;
@@ -1977,13 +1975,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
{
@@ -2495,12 +2491,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
{
@@ -2892,8 +2887,7 @@ public:
if (i == 1)
{
- gGL.flush();
- glLineWidth(3.f);
+ gGL.setLineWidth(3.f);
}
gGL.begin(LLRender::TRIANGLES);
@@ -2911,8 +2905,7 @@ public:
if (i == 1)
{
- gGL.flush();
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
}
}
}
@@ -3629,12 +3622,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;
@@ -3784,7 +3776,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 4b312b1597..2e918df910 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:
@@ -190,12 +190,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) = delete;
@@ -322,8 +323,8 @@ public:
virtual void rebound();
public:
- LL_ALIGN_16(LLVector4a mViewAngle);
- LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
+ LLVector4a mViewAngle;
+ LLVector4a mLastUpdateViewAngle;
protected:
virtual ~LLSpatialGroup();
@@ -353,7 +354,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 cd4c9d40b1..6458811e2c 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -254,7 +254,6 @@
#include "llnamelistctrl.h"
#include "llnamebox.h"
#include "llnameeditor.h"
-#include "llpostprocess.h"
#include "llagentlanguage.h"
#include "llwearable.h"
#include "llinventorybridge.h"
@@ -659,7 +658,7 @@ bool idle_startup()
std::string message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message_template.msg");
LLFILE* found_template = NULL;
- found_template = LLFile::fopen(message_template_path, "r"); /* Flawfinder: ignore */
+ found_template = LLFile::fopen(message_template_path, LLFILE_MODE("r")); /* Flawfinder: ignore */
#if LL_WINDOWS
// On the windows dev builds, unpackaged, the message_template.msg
@@ -668,7 +667,7 @@ bool idle_startup()
if (!found_template)
{
message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", "message_template.msg");
- found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
+ found_template = LLFile::fopen(message_template_path.c_str(), LLFILE_MODE("r")); /* Flawfinder: ignore */
}
#elif LL_DARWIN
// On Mac dev builds, message_template.msg lives in:
@@ -678,7 +677,7 @@ bool idle_startup()
message_template_path =
gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
"message_template.msg");
- found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
+ found_template = LLFile::fopen(message_template_path.c_str(), LLFILE_MODE("r")); /* Flawfinder: ignore */
}
#endif
@@ -1451,10 +1450,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();
diff --git a/indra/newview/llstatslistener.cpp b/indra/newview/llstatslistener.cpp
new file mode 100644
index 0000000000..b0f8d54231
--- /dev/null
+++ b/indra/newview/llstatslistener.cpp
@@ -0,0 +1,200 @@
+/**
+ * @file llstatslistener.cpp
+ * @brief EventAPI interface for querying performance statistics
+ *
+ * $LicenseInfo:firstyear=2026&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2026, 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 "llstatslistener.h"
+
+#include "llinventorymodel.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llimagegl.h"
+#include "llviewerstats.h"
+
+namespace
+{
+template <typename STAT, typename EXTRACTOR>
+LLSD collectPeriodArray(LLTrace::PeriodicRecording& recording,
+ size_t num_periods,
+ const STAT& stat,
+ EXTRACTOR extractor)
+{
+ LLSD values = LLSD::emptyArray();
+ for (size_t i = 1; i <= num_periods; ++i)
+ {
+ LLTrace::Recording& period = recording.getPrevRecording(i);
+ if (period.hasValue(stat))
+ {
+ values.append((F64)extractor(period, stat));
+ }
+ }
+ return values;
+}
+
+template <typename STAT, typename EXTRACTOR>
+void setPeriodArray(LLSD& out,
+ const char* key,
+ LLTrace::Recording& last,
+ LLTrace::PeriodicRecording& recording,
+ size_t num_periods,
+ const STAT& stat,
+ EXTRACTOR extractor)
+{
+ if (last.hasValue(stat))
+ {
+ out[key] = collectPeriodArray(recording, num_periods, stat, extractor);
+ }
+}
+}
+
+LLStatsListener::LLStatsListener()
+ : LLEventAPI("LLStats", "Query performance statistics")
+{
+ add("getPerfData",
+ "Get performance data from the frame recording buffer, plus texture memory\n"
+ "and inventory loading timing information.\n"
+ "Reply contains [\"stats\"] with nested group maps.",
+ &LLStatsListener::getPerfData,
+ llsd::map("reply", LLSD()));
+}
+
+void LLStatsListener::getPerfData(LLSD const & evt)
+{
+ LLEventAPI::Response response(LLSD(), evt);
+
+ // get_frame_recording() is a PeriodicRecording with 200 periods
+ LLTrace::PeriodicRecording& recording = LLTrace::get_frame_recording();
+ LLTrace::Recording& last = recording.getLastRecording();
+
+ size_t num_periods = recording.getNumRecordedPeriods();
+ F64 total_duration = recording.getDuration().value();
+
+ LLSD stats;
+ stats["total_periods_duration"] = total_duration;
+ stats["num_periods"] = (LLSD::Integer)num_periods;
+
+ LLSD frametime;
+
+ setPeriodArray(frametime, "fps", last, recording, num_periods, LLStatViewer::FPS,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getPerSec(stat); });
+
+ setPeriodArray(frametime, "frame_time_ms", last, recording, num_periods, LLStatViewer::FRAMETIME,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+
+ setPeriodArray(frametime, "do_frame_time_us", last, recording, num_periods, LLStatViewer::DOFRAME_TIME_US,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+
+ setPeriodArray(frametime, "frame_time_jitter_ms", last, recording, num_periods, LLStatViewer::FRAMETIME_JITTER,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+
+ // Normalized jitter - scalar samples updated per frame
+ // report the current (last) value since they are session/period rolling stats
+ if (last.hasValue(LLStatViewer::NOTRMALIZED_FRAMETIME_JITTER_SESSION))
+ {
+ frametime["normalized_jitter_session"] = last.getLastValue(LLStatViewer::NOTRMALIZED_FRAMETIME_JITTER_SESSION);
+ }
+ if (last.hasValue(LLStatViewer::NORMALIZED_FRAMTIME_JITTER_PERIOD))
+ {
+ frametime["normalized_jitter_period"] = last.getLastValue(LLStatViewer::NORMALIZED_FRAMTIME_JITTER_PERIOD);
+ }
+ if (last.hasValue(LLStatViewer::NFTV))
+ {
+ frametime["normalized_frametime_variation"] = last.getLastValue(LLStatViewer::NFTV);
+ }
+
+ // Jitter event minute counters: running avg per minute and count in last completed minute
+ // These are already minute-window aggregates, so sending single value, not arrays
+ if (last.hasValue(LLStatViewer::FRAMETIME_JITTER_EVENTS_PER_MINUTE))
+ {
+ frametime["frame_time_jitter_events_per_minute"] = (F64)last.getLastValue(LLStatViewer::FRAMETIME_JITTER_EVENTS_PER_MINUTE);
+ }
+ if (last.hasValue(LLStatViewer::FRAMETIME_JITTER_EVENTS_LAST_MINUTE))
+ {
+ frametime["frame_time_jitter_events_last_minute"] = (F64)last.getLastValue(LLStatViewer::FRAMETIME_JITTER_EVENTS_LAST_MINUTE);
+ }
+
+ // Jitter percentiles / cumulative
+ setPeriodArray(frametime, "jitter_cumulative_ms", last, recording, num_periods, LLStatViewer::FRAMETIME_JITTER_CUMULATIVE,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+ setPeriodArray(frametime, "jitter_99th_ms", last, recording, num_periods, LLStatViewer::FRAMETIME_JITTER_99TH,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+ setPeriodArray(frametime, "jitter_95th_ms", last, recording, num_periods, LLStatViewer::FRAMETIME_JITTER_95TH,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+ setPeriodArray(frametime, "jitter_stddev_ms", last, recording, num_periods, LLStatViewer::FRAMETIME_JITTER_STDDEV,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+
+ // Frame time percentiles
+ setPeriodArray(frametime, "frametime_99th_ms", last, recording, num_periods, LLStatViewer::FRAMETIME_99TH,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+ setPeriodArray(frametime, "frametime_95th_ms", last, recording, num_periods, LLStatViewer::FRAMETIME_95TH,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+ setPeriodArray(frametime, "frametime_stddev_ms", last, recording, num_periods, LLStatViewer::FRAMETIME_STDDEV,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+
+ // Frametime jitter event count
+ setPeriodArray(frametime, "frametime_jitter_events", last, recording, num_periods, LLStatViewer::FRAMETIME_JITTER_EVENTS,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+
+ stats["frametime"] = frametime;
+
+ LLSD other;
+
+ // Packet loss
+ setPeriodArray(other, "packet_loss_percent", last, recording, num_periods, LLStatViewer::PACKETS_LOST_PERCENT,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+
+ // Sim ping
+ setPeriodArray(other, "sim_ping_ms", last, recording, num_periods, LLStatViewer::SIM_PING,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+
+ // Triangle rendering
+ setPeriodArray(other, "ktris_per_frame", last, recording, num_periods, LLStatViewer::TRIANGLES_DRAWN,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getSum(stat); });
+ setPeriodArray(other, "ktris_per_sec", last, recording, num_periods, LLStatViewer::TRIANGLES_DRAWN,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getPerSec(stat); });
+
+ // Object counts
+ setPeriodArray(other, "num_objects", last, recording, num_periods, LLStatViewer::NUM_OBJECTS,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+ setPeriodArray(other, "num_active_objects", last, recording, num_periods, LLStatViewer::NUM_ACTIVE_OBJECTS,
+ [](LLTrace::Recording& period, const auto& stat) { return period.getMean(stat); });
+
+ stats["other"] = other;
+
+ // texture memory usage
+ LLSD memory;
+ memory["texture_bytes_alloc_mb"] = (F64)LLImageGL::getTextureBytesAllocated() / 1024.0 / 512.0;
+ stats["memory"] = memory;
+
+ LLSD inventory;
+ // library skeleton cache load duration
+ inventory["skeleton_load_time_library_seconds"] = gInventory.getLibrarySkeletonLoadTime();
+ // agent skeleton cache load duration
+ inventory["skeleton_load_time_agent_seconds"] = gInventory.getAgentSkeletonLoadTime();
+ // initial recursive inventory/library background fetch duration
+ inventory["initial_fetch_time_seconds"] = LLInventoryModelBackgroundFetch::instance().getInitialFetchDuration();
+ inventory["fetch_completed"] = LLInventoryModelBackgroundFetch::instance().isEverythingFetched();
+ stats["inventory"] = inventory;
+
+ response["stats"] = stats;
+}
diff --git a/indra/newview/tests/llwlparamset_stub.cpp b/indra/newview/llstatslistener.h
index e6c4221895..77777034c7 100644
--- a/indra/newview/tests/llwlparamset_stub.cpp
+++ b/indra/newview/llstatslistener.h
@@ -1,10 +1,10 @@
/**
- * @file llwlparamset_stub.cpp
- * @brief stub class to allow unit testing
+ * @file llstatslistener.h
+ * @brief EventAPI interface for querying performance statistics
*
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2026&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
+ * Copyright (C) 2026, 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,18 +24,18 @@
* $/LicenseInfo$
*/
-LLWLParamSet::LLWLParamSet(void)
-{
-}
+#ifndef LL_LLSTATSLISTENER_H
+#define LL_LLSTATSLISTENER_H
-void LLWLParamSet::updateCloudScrolling()
-{
-}
+#include "lleventapi.h"
-void LLWLParamSet::set(const std::string& name, const LLVector4& val)
+class LLStatsListener : public LLEventAPI
{
-}
+public:
+ LLStatsListener();
-void LLWLParamSet::update(LLGLSLShader *shader) const
-{
-}
+private:
+ void getPerfData(LLSD const & evt);
+};
+
+#endif // LL_LLSTATSLISTENER_H
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 8c8734b52f..f6ba52365b 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -157,7 +157,7 @@ protected:
LLAtomicS32 mBytesRead;
};
-class LLTextureCacheLocalFileWorker : public LLTextureCacheWorker
+class LLTextureCacheLocalFileWorker final : public LLTextureCacheWorker
{
public:
LLTextureCacheLocalFileWorker(LLTextureCache* cache, const std::string& filename, const LLUUID& id,
@@ -165,7 +165,7 @@ public:
S32 imagesize, // for writes
LLTextureCache::Responder* responder)
: LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder),
- mFileName(filename)
+ mFileName(fsyspath(filename))
{
}
@@ -174,19 +174,24 @@ public:
virtual bool doWrite();
private:
- std::string mFileName;
+ std::filesystem::path mFileName;
};
bool LLTextureCacheLocalFileWorker::doRead()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool());
-
- if (local_size > 0 && mFileName.size() > 4)
+ S32 local_size = (S32)LLFile::size(mFileName);
+ if (local_size > 0 && mFileName.native().size() > 4)
{
mDataSize = local_size; // Only a complete file is valid
- std::string extension = mFileName.substr(mFileName.size() - 3, 3);
+#if LL_WINDOWS
+ std::wstring_view native_path = mFileName.native();
+ std::wstring_view extension = native_path.substr(native_path.size() - 3, 3);
+#else
+ std::string_view native_path = mFileName.native();
+ std::string_view extension = native_path.substr(native_path.size() - 3, 3);
+#endif
mImageFormat = LLImageBase::getCodecFromExtension(extension);
@@ -210,8 +215,7 @@ bool LLTextureCacheLocalFileWorker::doRead()
}
mReadData = (U8*)ll_aligned_malloc_16(mDataSize);
- S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());
-
+ S32 bytes_read = (S32)LLFile::read(mFileName, mReadData, mOffset, mDataSize);
if (bytes_read != mDataSize)
{
// LL_WARNS() << "Error reading file from local cache: " << mFileName
@@ -235,7 +239,7 @@ bool LLTextureCacheLocalFileWorker::doWrite()
return false;
}
-class LLTextureCacheRemoteWorker : public LLTextureCacheWorker
+class LLTextureCacheRemoteWorker final : public LLTextureCacheWorker
{
public:
LLTextureCacheRemoteWorker(LLTextureCache* cache, const LLUUID& id,
@@ -296,7 +300,7 @@ bool LLTextureCacheRemoteWorker::doRead()
// Is it a JPEG2000 file?
{
local_filename = filename + ".j2c";
- local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
+ local_size = (S32)LLFile::size(local_filename);
if (local_size > 0)
{
mImageFormat = IMG_CODEC_J2C;
@@ -306,7 +310,7 @@ bool LLTextureCacheRemoteWorker::doRead()
if (local_size == 0)
{
local_filename = filename + ".jpg";
- local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
+ local_size = (S32)LLFile::size(local_filename);
if (local_size > 0)
{
mImageFormat = IMG_CODEC_JPEG;
@@ -317,7 +321,7 @@ bool LLTextureCacheRemoteWorker::doRead()
if (local_size == 0)
{
local_filename = filename + ".tga";
- local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
+ local_size = (S32)LLFile::size(local_filename);
if (local_size > 0)
{
mImageFormat = IMG_CODEC_TGA;
@@ -337,7 +341,7 @@ bool LLTextureCacheRemoteWorker::doRead()
if (!done && (mState == LOCAL))
{
llassert(local_size != 0); // we're assuming there is a non empty local file here...
- if (!mDataSize || mDataSize > local_size)
+ if (mDataSize <= 0 || mDataSize > local_size)
{
mDataSize = local_size;
}
@@ -346,12 +350,10 @@ bool LLTextureCacheRemoteWorker::doRead()
if (mReadData)
{
- S32 bytes_read = LLAPRFile::readEx( local_filename,
- mReadData,
- mOffset,
- mDataSize,
- mCache->getLocalAPRFilePool());
-
+ S32 bytes_read = (S32)LLFile::read(local_filename,
+ mReadData,
+ mOffset,
+ mDataSize);
if (bytes_read != mDataSize)
{
LL_WARNS() << "Error reading file from local cache: " << local_filename
@@ -410,8 +412,7 @@ bool LLTextureCacheRemoteWorker::doRead()
mReadData = (U8*)ll_aligned_malloc_16(size);
if (mReadData)
{
- S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName,
- mReadData, offset, size, mCache->getLocalAPRFilePool());
+ S32 bytes_read = (S32)LLFile::read(mCache->mHeaderDataFilePath, mReadData, offset, size);
if (bytes_read != size)
{
LL_WARNS() << "LLTextureCacheWorker: " << mID
@@ -445,10 +446,10 @@ bool LLTextureCacheRemoteWorker::doRead()
// Fourth state / stage : read the rest of the data from the UUID based cached file
if (!done && (mState == BODY))
{
- std::string filename = mCache->getTextureFileName(mID);
- S32 filesize = LLAPRFile::size(filename, mCache->getLocalAPRFilePool());
+ std::filesystem::path file_path = fsyspath(mCache->getTextureFileName(mID));
+ S32 filesize = (S32)LLFile::size(file_path);
- if (filesize && (filesize + TEXTURE_CACHE_ENTRY_SIZE) > mOffset)
+ if (filesize > 0 && (filesize + TEXTURE_CACHE_ENTRY_SIZE) > mOffset)
{
S32 max_datasize = TEXTURE_CACHE_ENTRY_SIZE + filesize - mOffset;
mDataSize = llmin(max_datasize, mDataSize);
@@ -487,10 +488,9 @@ bool LLTextureCacheRemoteWorker::doRead()
mReadData = data;
// Read the data at last
- S32 bytes_read = LLAPRFile::readEx(filename,
- mReadData + data_offset,
- file_offset, file_size,
- mCache->getLocalAPRFilePool());
+ S32 bytes_read = (S32)LLFile::read(file_path,
+ mReadData + data_offset,
+ file_offset, file_size);
if (bytes_read != file_size)
{
LL_WARNS() << "LLTextureCacheWorker: " << mID
@@ -516,7 +516,7 @@ bool LLTextureCacheRemoteWorker::doRead()
{
// No body, we're done.
mDataSize = llmax(TEXTURE_CACHE_ENTRY_SIZE - mOffset, 0);
- LL_DEBUGS() << "No body file for: " << filename << LL_ENDL;
+ LL_DEBUGS() << "No body file for: " << file_path << LL_ENDL;
}
// Nothing else to do at that point...
done = true;
@@ -636,13 +636,13 @@ bool LLTextureCacheRemoteWorker::doWrite()
U8* padBuffer = (U8*)ll_aligned_malloc_16(TEXTURE_CACHE_ENTRY_SIZE);
memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE); // Init with zeros
memcpy(padBuffer, mWriteData, mDataSize); // Copy the write buffer
- bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool());
+ bytes_written = (S32)LLFile::write(mCache->mHeaderDataFilePath, padBuffer, offset, size);
ll_aligned_free_16(padBuffer);
}
else
{
// Write the header record (== first TEXTURE_CACHE_ENTRY_SIZE bytes of the raw file) in the header file
- bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size, mCache->getLocalAPRFilePool());
+ bytes_written = (S32)LLFile::write(mCache->mHeaderDataFilePath, mWriteData, offset, size);
}
if (bytes_written <= 0)
@@ -678,15 +678,11 @@ bool LLTextureCacheRemoteWorker::doWrite()
else
{
S32 file_size = mDataSize - TEXTURE_CACHE_ENTRY_SIZE;
-
{
// build the cache file name from the UUID
std::string filename = mCache->getTextureFileName(mID);
// LL_INFOS() << "Writing Body: " << filename << " Bytes: " << file_offset+file_size << LL_ENDL;
- S32 bytes_written = LLAPRFile::writeEx(filename,
- mWriteData + TEXTURE_CACHE_ENTRY_SIZE,
- 0, file_size,
- mCache->getLocalAPRFilePool());
+ S32 bytes_written = (S32)LLFile::write(filename, mWriteData + TEXTURE_CACHE_ENTRY_SIZE, 0, file_size);
if (bytes_written <= 0)
{
LL_WARNS() << "LLTextureCacheWorker: " << mID
@@ -866,9 +862,9 @@ std::string LLTextureCache::getLocalFileName(const LLUUID& id)
std::string LLTextureCache::getTextureFileName(const LLUUID& id)
{
- std::string idstr = id.asString();
- std::string delem = gDirUtilp->getDirDelimiter();
- std::string filename = mTexturesDirName + delem + idstr[0] + delem + idstr + ".texture";
+ char idstr[UUID_STR_LENGTH]{};
+ id.to_chars(idstr);
+ std::string filename = llformat("%s%s%c%s%s.texture", mTexturesDirName.c_str(), gDirUtilp->getDirDelimiter().c_str(), idstr[0], gDirUtilp->getDirDelimiter().c_str(), idstr);
return filename;
}
@@ -891,7 +887,7 @@ bool LLTextureCache::isInLocal(const LLUUID& id)
// Is it a JPEG2000 file?
{
local_filename = filename + ".j2c";
- local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
+ local_size = (S32)LLFile::size(local_filename);
if (local_size > 0)
{
return true ;
@@ -901,7 +897,7 @@ bool LLTextureCache::isInLocal(const LLUUID& id)
// If not, is it a jpeg file?
{
local_filename = filename + ".jpg";
- local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
+ local_size = (S32)LLFile::size(local_filename);
if (local_size > 0)
{
return true ;
@@ -911,7 +907,7 @@ bool LLTextureCache::isInLocal(const LLUUID& id)
// Hmm... What about a targa file? (used for UI texture mostly)
{
local_filename = filename + ".tga";
- local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
+ local_size = (S32)LLFile::size(local_filename);
if (local_size > 0)
{
return true ;
@@ -943,10 +939,10 @@ 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);
+ mHeaderDataFilePath = fsyspath(gDirUtilp->getExpandedFilename(location, textures_dirname, cache_filename));
+ mHeaderEntriesFilePath = fsyspath(mHeaderEntriesFileName);
+
mTexturesDirName = gDirUtilp->getExpandedFilename(location, textures_dirname);
mFastCacheFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, fast_cache_filename);
}
@@ -966,11 +962,10 @@ void LLTextureCache::purgeCache(ELLPath location, bool remove_dir)
if(LLFile::isdir(mTexturesDirName))
{
std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename);
- // mHeaderAPRFilePoolp because we are under header mutex, and can be in main thread
- LLAPRFile::remove(file_name, mHeaderAPRFilePoolp);
+ LLFile::remove(file_name);
file_name = gDirUtilp->getExpandedFilename(location, cache_filename);
- LLAPRFile::remove(file_name, mHeaderAPRFilePoolp);
+ LLFile::remove(file_name);
purgeAllTextures(true);
}
@@ -1073,10 +1068,9 @@ void LLTextureCache::readEntriesHeader()
{
// mHeaderEntriesInfo initializes to default values so safe not to read it
llassert_always(mHeaderAPRFile == NULL);
- if (LLAPRFile::isExist(mHeaderEntriesFileName, mHeaderAPRFilePoolp))
+ if (LLFile::isfile(mHeaderEntriesFilePath))
{
- LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
- mHeaderAPRFilePoolp);
+ LLFile::read(mHeaderEntriesFilePath, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
}
else //create an empty entries header.
{
@@ -1092,7 +1086,7 @@ void LLTextureCache::setEntriesHeader()
// For simplicity we use predefined size of header, so if version string
// doesn't fit, either getEngineInfo() returned malformed string or
// sHeaderEncoderStringSize need to be increased.
- // Also take into accout that c_str() returns additional null character
+ // Also take into account that c_str() returns additional null character
LL_ERRS() << "Version string doesn't fit in header" << LL_ENDL;
}
@@ -1107,8 +1101,7 @@ void LLTextureCache::writeEntriesHeader()
llassert_always(mHeaderAPRFile == NULL);
if (!mReadOnly)
{
- LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
- mHeaderAPRFilePoolp);
+ LLFile::write(mHeaderEntriesFilePath, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
}
}
@@ -1224,8 +1217,7 @@ void LLTextureCache::writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool
idx = -1 ;//mark the idx invalid.
return ;
}
-
- mHeaderAPRFile->seek(APR_SET, offset);
+ aprfile->seek(APR_SET, offset);
}
else
{
@@ -1362,21 +1354,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;
@@ -1387,17 +1384,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;
@@ -1632,7 +1629,7 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
gDirUtilp->deleteFilesInDir(mTexturesDirName, mask); // headers, fast cache
if (purge_directories)
{
- LLFile::rmdir(mTexturesDirName);
+ LLFile::remove(mTexturesDirName);
}
}
{
@@ -1822,8 +1819,7 @@ void LLTextureCache::purgeTextures(bool validate)
{
std::string filename = getTextureFileName(entries[idx].mID);
LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL;
- // mHeaderAPRFilePoolp because this is under header mutex in main thread
- S32 bodysize = LLAPRFile::size(filename, mHeaderAPRFilePoolp);
+ S32 bodysize = (S32)LLFile::size(filename);
if (bodysize != entries[idx].mBodySize)
{
LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize << filename << LL_ENDL;
@@ -2177,7 +2173,7 @@ void LLTextureCache::openFastCache(bool first_time)
mFastCachePadBuffer = (U8*)ll_aligned_malloc_16(TEXTURE_FAST_CACHE_ENTRY_SIZE);
}
mFastCachePoolp = new LLVolatileAPRPool(); // is_local= true by default, so not thread safe by default
- if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp))
+ if (LLFile::isfile(mFastCacheFileName))
{
mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ;
}
@@ -2263,9 +2259,7 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)
LLMutexLock lock(&mHeaderIDMapMutex);
mHeaderIDMap.erase(id);
}
- // We are inside header's mutex so mHeaderAPRFilePoolp is safe to use,
- // but getLocalAPRFilePool() is not safe, it might be in use by worker
- LLAPRFile::remove(getTextureFileName(id), mHeaderAPRFilePoolp);
+ LLFile::remove(getTextureFileName(id));
}
//called after mHeaderMutex is locked.
@@ -2278,9 +2272,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
if (entry.mBodySize == 0) // Always attempt to remove when mBodySize > 0.
{
// Sanity check. Shouldn't exist when body size is 0.
- // We are inside header's mutex so mHeaderAPRFilePoolp is safe to use,
- // but getLocalAPRFilePool() is not safe, it might be in use by worker
- if (LLAPRFile::isExist(filename, mHeaderAPRFilePoolp))
+ if (LLFile::isfile(filename))
{
LL_WARNS("TextureCache") << "Entry has body size of zero but file " << filename << " exists. Deleting this file, too." << LL_ENDL;
}
@@ -2303,7 +2295,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
if (file_maybe_exists)
{
- LLAPRFile::remove(filename, mHeaderAPRFilePoolp);
+ LLFile::remove(filename);
}
}
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index a09bcc1572..100527fbfc 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -219,7 +219,8 @@ private:
// HEADERS (Include first mip)
std::string mHeaderEntriesFileName;
- std::string mHeaderDataFileName;
+ std::filesystem::path mHeaderEntriesFilePath;
+ std::filesystem::path mHeaderDataFilePath;
std::string mFastCacheFileName;
EntriesInfo mHeaderEntriesInfo;
std::set<S32> mFreeList; // deleted entries
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 8cbede8303..cbe2dac52a 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -250,7 +250,7 @@ void LLTextureBar::draw()
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
// Draw the progress bar.
- S32 bar_width = 100;
+ S32 bar_width = 110;
S32 bar_left = 260;
left = bar_left;
right = left + bar_width;
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 3de61dffc7..e905a879cb 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -301,7 +301,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
mIsScriptDialog = (notif_name == "ScriptDialog" || notif_name == "ScriptDialogGroup");
static LLCachedControl<S32> btn_width(gSavedSettings, "ToastButtonWidth", 90);
- static LLCachedControl<S32> script_button_width(gSavedSettings, "ScriptToastButtonWidth", 110);
+ static LLCachedControl<S32> script_button_width(gSavedSettings, "ScriptToastButtonWidth", 127);
mButtonWidth = mIsScriptDialog ? script_button_width : btn_width;
bool is_content_trusted = (notif_name != "LoadWebPage");
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index c1ec5fa183..c401a00fd7 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -420,7 +420,7 @@ void LLToolBarView::saveToolbars() const
if(!output_node->isNull())
{
const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "toolbars.xml");
- LLFILE *fp = LLFile::fopen(filename, "w");
+ LLFILE *fp = LLFile::fopen(filename, LLFILE_MODE("w"));
if (fp != NULL)
{
LLXMLNode::writeHeaderToFile(fp);
diff --git a/indra/newview/lltoolview.cpp b/indra/newview/lltoolview.cpp
deleted file mode 100644
index 179aae1e02..0000000000
--- a/indra/newview/lltoolview.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/**
- * @file lltoolview.cpp
- * @brief A UI contains for tool palette tools
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "lltoolview.h"
-
-#include "llfontgl.h"
-#include "llrect.h"
-
-#include "llagent.h"
-#include "llbutton.h"
-#include "llpanel.h"
-#include "lltool.h"
-#include "lltoolmgr.h"
-#include "lltextbox.h"
-#include "llresmgr.h"
-
-
-LLToolContainer::LLToolContainer(LLToolView* parent)
-: mParent(parent),
- mButton(NULL),
- mPanel(NULL),
- mTool(NULL)
-{ }
-
-
-LLToolContainer::~LLToolContainer()
-{
- // mParent is a pointer to the tool view
- // mButton is owned by the tool view
- // mPanel is owned by the tool view
- delete mTool;
- mTool = NULL;
-}
-
-
-LLToolView::LLToolView(const std::string& name, const LLRect& rect)
-: mButtonCount(0)
-{
- LLView::init(LLView::Params().name(name).rect(rect).mouse_opaque(true));
-}
-
-
-LLToolView::~LLToolView()
-{
- for_each(mContainList.begin(), mContainList.end(), DeletePointer());
- mContainList.clear();
-}
-
-//*TODO:translate?
-// void LLToolView::addTool(const std::string& icon_off, const std::string& icon_on, LLPanel* panel, LLTool* tool, LLView* hoverView, const char* label)
-// {
-// llassert(tool);
-
-// LLToolContainer* contain = new LLToolContainer(this);
-
-// LLRect btn_rect = getButtonRect(mButtonCount);
-
-// contain->mButton = new LLButton("ToolBtn",
-// btn_rect,
-// icon_off,
-// icon_on,
-// "",
-// &LLToolView::onClickToolButton,
-// contain,
-// LLFontGL::getFontSansSerif());
-
-// contain->mPanel = panel;
-// contain->mTool = tool;
-
-// addChild(contain->mButton);
-// mButtonCount++;
-
-// const S32 LABEL_TOP_SPACING = 0;
-// const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
-// S32 label_width = font->getWidth( label );
-// LLRect label_rect;
-// label_rect.setLeftTopAndSize(
-// btn_rect.mLeft + btn_rect.getWidth() / 2 - label_width / 2,
-// btn_rect.mBottom - LABEL_TOP_SPACING,
-// label_width,
-// llfloor(font->getLineHeight()));
-// addChild( new LLTextBox( "tool label", label_rect, label, font ) );
-
-// // Can optionally ignore panel
-// if (contain->mPanel)
-// {
-// contain->mPanel->setBackgroundVisible( FALSE );
-// contain->mPanel->setBorderVisible( FALSE );
-// addChild(contain->mPanel);
-// }
-
-// mContainList.push_back(contain);
-// }
-
-
-LLRect LLToolView::getButtonRect(S32 button_index)
-{
- const S32 HPAD = 7;
- const S32 VPAD = 7;
- const S32 TOOL_SIZE = 32;
- const S32 HORIZ_SPACING = TOOL_SIZE + 5;
- const S32 VERT_SPACING = TOOL_SIZE + 14;
-
- S32 tools_per_row = getRect().getWidth() / HORIZ_SPACING;
-
- S32 row = button_index / tools_per_row;
- S32 column = button_index % tools_per_row;
-
- // Build the rectangle, recalling the origin is at lower left
- // and we want the icons to build down from the top.
- LLRect rect;
- rect.setLeftTopAndSize( HPAD + (column * HORIZ_SPACING),
- -VPAD + getRect().getHeight() - (row * VERT_SPACING),
- TOOL_SIZE,
- TOOL_SIZE
- );
-
- return rect;
-}
-
-
-void LLToolView::draw()
-{
- // turn off highlighting for all containers
- // and hide all option panels except for the selected one.
- LLTool* selected = LLToolMgr::getInstance()->getCurrentToolset()->getSelectedTool();
- for (contain_list_t::iterator iter = mContainList.begin();
- iter != mContainList.end(); ++iter)
- {
- LLToolContainer* contain = *iter;
- BOOL state = (contain->mTool == selected);
- contain->mButton->setToggleState( state );
- if (contain->mPanel)
- {
- contain->mPanel->setVisible( state );
- }
- }
-
- // Draw children normally
- LLView::draw();
-}
-
-// protected
-LLToolContainer* LLToolView::findToolContainer( LLTool *tool )
-{
- // Find the container for this tool
- llassert( tool );
- for (contain_list_t::iterator iter = mContainList.begin();
- iter != mContainList.end(); ++iter)
- {
- LLToolContainer* contain = *iter;
- if( contain->mTool == tool )
- {
- return contain;
- }
- }
- LL_ERRS() << "LLToolView::findToolContainer - tool not found" << LL_ENDL;
- return NULL;
-}
-
-// static
-void LLToolView::onClickToolButton(void* userdata)
-{
- LLToolContainer* clicked = (LLToolContainer*) userdata;
-
- // Switch to this one
- LLToolMgr::getInstance()->getCurrentToolset()->selectTool( clicked->mTool );
-}
-
-
-
diff --git a/indra/newview/lltoolview.h b/indra/newview/lltoolview.h
deleted file mode 100644
index 7b348e7088..0000000000
--- a/indra/newview/lltoolview.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * @file lltoolview.h
- * @brief UI container for tools.
- *
- * $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_LLTOOLVIEW_H
-#define LL_LLTOOLVIEW_H
-
-// requires stdtypes.h
-#include "llpanel.h"
-
-// forward declares
-class LLTool;
-class LLButton;
-
-class LLToolView;
-
-
-// Utility class, container for the package of information we need about
-// each tool. The package can either point directly to a tool, or indirectly
-// to another view of tools.
-class LLToolContainer
-{
-public:
- LLToolContainer(LLToolView* parent);
- ~LLToolContainer();
-
-public:
- LLToolView* mParent; // toolview that owns this container
- LLButton* mButton;
- LLPanel* mPanel;
- LLTool* mTool; // if not NULL, this is a tool ref
-};
-
-
-// A view containing automatically arranged button icons representing
-// tools. The icons sit on top of panels containing options for each
-// tool.
-class LLToolView
-: public LLView
-{
-public:
- LLToolView(const std::string& name, const LLRect& rect);
- ~LLToolView();
-
- virtual void draw(); // handle juggling tool button highlights, panel visibility
-
- static void onClickToolButton(void* container);
-
- LLView* getCurrentHoverView();
-
-private:
- LLRect getButtonRect(S32 button_index); // return rect for button to add, zero-based index
- LLToolContainer *findToolContainer(LLTool *tool);
-
-
-private:
- typedef std::vector<LLToolContainer*> contain_list_t;
- contain_list_t mContainList;
- S32 mButtonCount; // used to compute rectangles
-};
-
-#endif
diff --git a/indra/newview/llvelopack.cpp b/indra/newview/llvelopack.cpp
index f76d68ed72..927a5bbc2c 100644
--- a/indra/newview/llvelopack.cpp
+++ b/indra/newview/llvelopack.cpp
@@ -31,6 +31,7 @@
#include "llstring.h"
#include "llcorehttputil.h"
#include "llversioninfo.h"
+#include "llversioninfovars.h" // LL_VIEWER_CHANNEL
#include <boost/json.hpp>
#include <fstream>
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 178f10257d..bac291cd19 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) \
@@ -52,7 +54,6 @@ LLVersionInfo::LLVersionInfo():
// macro expands to the string name of the channel, but without quotes. We
// need to turn it into a quoted string. LL_TO_STRING() does that.
mWorkingChannelName(LL_TO_STRING(LL_VIEWER_CHANNEL)),
- build_configuration(LLBUILD_CONFIG), // set in indra/cmake/BuildVersion.cmake
// instantiate an LLEventMailDrop with canonical name to listen for news
// from the Viewer Version Manager
mPump{new LLEventMailDrop("relnotes")},
@@ -168,7 +169,15 @@ LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity() const
std::string LLVersionInfo::getBuildConfig() const
{
- return build_configuration;
+#if LL_DEBUG
+ return "Debug";
+#elif LL_RELEASE_WITH_DEBUG_INFO
+ return "RelWithDebInfo";
+#elif LL_RELEASE_FOR_DOWNLOAD
+ return "Release";
+#else
+ return "Unknown";
+#endif
}
std::string LLVersionInfo::getReleaseNotes() const
diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h
index a2b93597e6..bffee086be 100644
--- a/indra/newview/llversioninfo.h
+++ b/indra/newview/llversioninfo.h
@@ -108,7 +108,6 @@ private:
// Storage for the "version and channel" string.
// This will get reset too.
mutable std::string mVersionChannel;
- std::string build_configuration;
std::string mReleaseNotes;
// Store unique_ptrs to the next couple things so we don't have to explain
// to every consumer of this header file all the details of each.
diff --git a/indra/newview/macutil_Prefix.h b/indra/newview/llversioninfovars.h.in
index 4972ee4fa5..2984f05bb3 100644
--- a/indra/newview/macutil_Prefix.h
+++ b/indra/newview/llversioninfovars.h.in
@@ -1,10 +1,9 @@
/**
- * @file macutil_Prefix.h
- * @brief Precompiled prefix file
+ * @file llversioninfovars.h.in
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * 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
@@ -24,15 +23,8 @@
* $/LicenseInfo$
*/
-/*
- *
- * Precompiled prefix file used for
- * AutoUpdater
- * crashreporter
- *
- */
-
-#include "fix_macros.h"
-
-#undef verify
-#undef require
+#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@
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 657fb0ffc1..296ba1d715 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -183,7 +183,7 @@ void LLViewerAssetStorage::storeAssetData(
else
{
// LLAssetStorage metric: Successful Request
- S32 size = LLFileSystem::getFileSize(asset_id, asset_type);
+ S32 size = vfile.getSize();
const char *message = "Added to upload queue";
reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message );
@@ -280,7 +280,7 @@ void LLViewerAssetStorage::storeAssetData(
LL_DEBUGS("AssetStorage") << "ASSET_ID: " << asset_id << LL_ENDL;
S32 size = 0;
- LLFILE* fp = LLFile::fopen(filename, "rb");
+ LLFILE* fp = LLFile::fopen(filename, LLFILE_MODE("rb"));
if (fp)
{
fseek(fp, 0, SEEK_END);
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 65a69acc88..bc87e862b9 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -45,11 +45,7 @@
#include "llappviewer.h"
#include "llviewerstats.h"
#include "llfilesystem.h"
-#include "llgesturemgr.h"
-#include "llpreviewnotecard.h"
-#include "llpreviewgesture.h"
#include "llcoproceduremanager.h"
-#include "llthread.h"
#include "llkeyframemotion.h"
#include "lldatapacker.h"
#include "llvoavatarself.h"
@@ -405,6 +401,7 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
std::string errorMessage;
std::string errorLabel;
+ std::error_code ec;
bool error = false;
@@ -475,30 +472,38 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
error = true;
// read from getFileName()
- LLAPRFile infile;
- infile.open(getFileName(),LL_APR_RB);
- if (!infile.getFileHandle())
+ LLFile infile(getFileName(), LLFile::in | LLFile::binary, ec);
+ if (ec || !infile)
{
LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL;
errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str());
}
else
{
- S32 size = LLAPRFile::size(getFileName());
+ S64 size = infile.size(ec);
+ if (ec || size <= 0)
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Invalid file" << LL_ENDL;
+ }
+ else if (size > INT_MAX)
+ {
+ LL_ERRS() << "File " << getFileName() << " is too big, size: " << size << LL_ENDL;
+ }
U8* buffer = new(std::nothrow) U8[size];
if (!buffer)
{
LLError::LLUserWarningMsg::showOutOfMemory();
LL_ERRS() << "Bad memory allocation for buffer, size: " << size << LL_ENDL;
}
- S32 size_read = infile.read(buffer,size);
- if (size_read != size)
+ S64 size_read = infile.read(buffer, size, ec);
+ if (ec || size_read != size)
{
errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read);
}
else
{
- LLDataPackerBinaryBuffer dp(buffer, size);
+ LLDataPackerBinaryBuffer dp(buffer, (S32)size);
LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId());
motionp->setCharacter(gAgentAvatarp);
if (motionp->deserialize(dp, getAssetId(), false))
@@ -544,18 +549,17 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
setAssetType(assetType);
// copy this file into the cache for upload
- S32 file_size;
- LLAPRFile infile;
- infile.open(filename, LL_APR_RB, NULL, &file_size);
- if (infile.getFileHandle())
+ LLFile infile(filename, LLFile::in | LLFile::binary, ec);
+ if (!ec && infile.size(ec) > 0)
{
LLFileSystem file(getAssetId(), assetType, LLFileSystem::APPEND);
+ S64 read_bytes;
const S32 buf_size = 65536;
U8 copy_buf[buf_size];
- while ((file_size = infile.read(copy_buf, buf_size)))
+ while (((read_bytes = infile.read(copy_buf, buf_size, ec))) > 0)
{
- file.write(copy_buf, file_size);
+ file.write(copy_buf, (S32)read_bytes);
}
}
else
@@ -569,7 +573,6 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
}
return LLSD();
-
}
//=========================================================================
@@ -881,6 +884,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
if (uploadInfo->showUploadDialog())
{
+ // todo: localize this string
std::string uploadMessage = "Uploading...\n\n";
uploadMessage.append(uploadInfo->getDisplayName());
LLUploadDialog::modalUploadDialog(uploadMessage);
@@ -888,66 +892,90 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
LLSD body = uploadInfo->generatePostBody();
- result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOptions);
+ // Retry stage-2 upload by re-requesting a fresh one-time uploader capability (up to 3 attempts total)
+ const S32 MAX_UPLOAD_RETRIES = 2;
+ S32 upload_retry_count = 0;
+ LLCore::HttpStatus status;
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if ((!status) || (result.has("error")))
+ while (upload_retry_count <= MAX_UPLOAD_RETRIES)
{
- HandleUploadError(status, result, uploadInfo);
- if (uploadInfo->showUploadDialog())
- LLUploadDialog::modalUploadFinished();
- return;
- }
+ // Stage 1: Request uploader URL
+ result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOptions);
- std::string uploader = result["uploader"].asString();
-
- bool success = false;
- if (!uploader.empty() && uploadInfo->getAssetId().notNull())
- {
- result = httpAdapter->postFileAndSuspend(httpRequest, uploader, uploadInfo->getAssetId(), uploadInfo->getAssetType(), httpOptions);
- httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- std::string ulstate = result["state"].asString();
-
- if ((!status) || (ulstate != "complete"))
+ if ((!status) || (result.has("error")))
{
HandleUploadError(status, result, uploadInfo);
if (uploadInfo->showUploadDialog())
LLUploadDialog::modalUploadFinished();
return;
}
- if (!result.has("success"))
+
+ std::string uploader = result["uploader"].asString();
+ if (uploader.empty() || uploadInfo->getAssetId().isNull())
{
- result["success"] = LLSD::Boolean((ulstate == "complete") && status);
+ LL_WARNS() << "No upload url provided. Nothing uploaded, responding with previous result." << LL_ENDL;
+ break;
}
- S32 uploadPrice = result["upload_price"].asInteger();
+ // Stage 2: Upload to the uploader URL
+ result = httpAdapter->postFileAndSuspend(httpRequest, uploader, uploadInfo->getAssetId(), uploadInfo->getAssetType(), httpOptions);
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- if (uploadPrice > 0)
- {
- // this upload costed us L$, update our balance
- // and display something saying that it cost L$
- LLStatusBar::sendMoneyBalanceRequest();
+ std::string ulstate = result["state"].asString();
- LLSD args;
- args["AMOUNT"] = llformat("%d", uploadPrice);
- LLNotificationsUtil::add("UploadPayment", args);
+ if ((!status) || (ulstate != "complete"))
+ {
+ if (upload_retry_count < MAX_UPLOAD_RETRIES)
+ {
+ upload_retry_count++;
+ LL_WARNS() << "Upload to uploader failed (attempt " << upload_retry_count
+ << " of " << (MAX_UPLOAD_RETRIES + 1) << "), re-requesting uploader..." << LL_ENDL;
+ llcoro::suspendUntilTimeout(1.0f);
+ continue;
+ }
+ else
+ {
+ HandleUploadError(status, result, uploadInfo);
+ if (uploadInfo->showUploadDialog())
+ LLUploadDialog::modalUploadFinished();
+ return;
+ }
}
+
+ // Success!
+ break;
}
- else
+
+ if (!result.has("success"))
{
- LL_WARNS() << "No upload url provided. Nothing uploaded, responding with previous result." << LL_ENDL;
+ result["success"] = LLSD::Boolean((result["state"].asString() == "complete") && status);
}
+
+ S32 uploadPrice = result["upload_price"].asInteger();
+
+ if (uploadPrice > 0)
+ {
+ // this upload costed us L$, update our balance
+ // and display something saying that it cost L$
+ LLStatusBar::sendMoneyBalanceRequest();
+
+ LLSD args;
+ args["AMOUNT"] = llformat("%d", uploadPrice);
+ LLNotificationsUtil::add("UploadPayment", args);
+ }
+
LLUUID serverInventoryItem = uploadInfo->finishUpload(result);
+ bool succeeded = false;
if (uploadInfo->showInventoryPanel())
{
if (serverInventoryItem.notNull())
{
- success = true;
+ succeeded = true;
LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
@@ -973,7 +1001,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot && floater_snapshot->isShown())
{
- floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
+ floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", succeeded).with("msg", "inventory")));
}
}
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 0c93b24751..6d825441ca 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);
@@ -435,16 +446,6 @@ static bool handleUploadBakedTexOldChanged(const LLSD& newvalue)
return true;
}
-
-static bool handleWLSkyDetailChanged(const LLSD&)
-{
- if (gSky.mVOWLSkyp.notNull())
- {
- gSky.mVOWLSkyp->updateGeometry(gSky.mVOWLSkyp->mDrawable);
- }
- return true;
-}
-
static bool handleRepartition(const LLSD&)
{
if (gPipeline.isInit())
@@ -830,10 +831,12 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized);
setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFSAAType", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderHighPrecisionPostProcess", handleReleaseGLBufferChanged);
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);
@@ -890,7 +893,6 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged);
- setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged);
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 9dfa9a0efd..3f06fe3320 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"
@@ -217,9 +216,10 @@ void display_update_camera()
{
final_far *= 0.5f;
}
- else if (LLViewerTexture::sDesiredDiscardBias > 2.f)
+ // When system memory is critically low or recovering, shrink draw distance.
+ else if (const F32 mem_factor = LLMemory::getSystemMemoryBudgetFactor(); mem_factor > 1.f)
{
- final_far = llmax(32.f, final_far / (LLViewerTexture::sDesiredDiscardBias - 1.f));
+ final_far = llmax(32.f, final_far / mem_factor);
}
LLViewerCamera::getInstance()->setFar(final_far);
LLVOAvatar::sRenderDistance = llclamp(final_far, 16.f, 256.f);
@@ -1074,7 +1074,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;
@@ -1140,15 +1140,12 @@ std::string getProfileStatsFilename()
// same second), may produce (e.g.) sec==61, but avoids collisions and
// preserves chronological filename sort order.
std::string name;
- std::error_code ec;
do
{
// base + missing 2-digit seconds, append ".json"
// post-increment sec in case we have to try again
name = stringize(base, std::setw(2), std::setfill('0'), sec++, ".json");
- } while (std::filesystem::exists(fsyspath(name), ec));
- // Ignoring ec means we might potentially return a name that does already
- // exist -- but if we can't check its existence, what more can we do?
+ } while (LLFile::exists(name));
return name;
}
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp
index 3c79f0b21c..5741d7f5fb 100644
--- a/indra/newview/llviewerinput.cpp
+++ b/indra/newview/llviewerinput.cpp
@@ -1430,7 +1430,7 @@ S32 LLViewerInput::loadBindingsXML(const std::string& filename)
// file in app_settings is supposed to be up to date
// this is only for the file from user_settings
LL_INFOS("ViewerInput") << "Updating file " << filename << " to a newer version" << LL_ENDL;
- LLFILE *fp = LLFile::fopen(filename, "w");
+ LLFILE *fp = LLFile::fopen(filename, LLFILE_MODE("w"));
if (fp != NULL)
{
LLXMLNode::writeHeaderToFile(fp);
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 42aed5906b..a910d8ec2a 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
@@ -235,8 +229,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 1365c1ee48..ec410a3138 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 28dd62792c..5d01e08875 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1800,6 +1800,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);
@@ -1807,16 +1814,13 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
user_data_path_cache += gDirUtilp->getDirDelimiter();
// See if the plugin executable exists
- llstat s;
- if(LLFile::stat(launcher_name, &s))
+ if (!LLFile::isfile(launcher_name))
{
LL_WARNS_ONCE("Media") << "Couldn't find launcher at " << launcher_name << LL_ENDL;
}
- else if(LLFile::stat(plugin_name, &s))
+ else if (!LLFile::isfile(plugin_name))
{
-#if !LL_LINUX
LL_WARNS_ONCE("Media") << "Couldn't find plugin at " << plugin_name << LL_ENDL;
-#endif
}
else
{
@@ -1848,6 +1852,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());
@@ -1869,9 +1878,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())
{
@@ -3620,7 +3627,7 @@ LLViewerMediaImpl::canUndo() const
if (mMediaSource)
return mMediaSource->canUndo();
else
- return FALSE;
+ return false;
}
////////////////////////////////////////////////////////////////////////////////
@@ -3640,7 +3647,7 @@ LLViewerMediaImpl::canRedo() const
if (mMediaSource)
return mMediaSource->canRedo();
else
- return FALSE;
+ return false;
}
////////////////////////////////////////////////////////////////////////////////
@@ -3720,7 +3727,7 @@ LLViewerMediaImpl::canDoDelete() const
if (mMediaSource)
return mMediaSource->canDoDelete();
else
- return FALSE;
+ return false;
}
////////////////////////////////////////////////////////////////////////////////
@@ -3740,7 +3747,7 @@ LLViewerMediaImpl::canSelectAll() const
if (mMediaSource)
return mMediaSource->canSelectAll();
else
- return FALSE;
+ return false;
}
void LLViewerMediaImpl::setUpdated(bool updated)
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 79d7d41836..ce95d7363e 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
@@ -1163,7 +1163,7 @@ void handle_compress_image()
// so doing dirty, but OS independent fopen and fseek
size_t get_file_size(std::string &filename)
{
- LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ LLFILE* file = LLFile::fopen(filename, LLFILE_MODE("rb")); /*Flawfinder: ignore*/
if (!file)
{
LL_WARNS() << "Error opening " << filename << LL_ENDL;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index e435ce08e3..fcfddb091e 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -40,6 +40,7 @@
#include "llinventorydefines.h"
#include "lllslconstants.h"
#include "llmaterialtable.h"
+#include "llmemory.h"
#include "llregionhandle.h"
#include "llsd.h"
#include "llsdserialize.h"
@@ -3390,11 +3391,12 @@ void send_agent_update(bool force_send, bool send_reliable)
static F32 last_draw_disatance_step = 1024;
F32 memory_limited_draw_distance = gAgentCamera.mDrawDistance;
-
- if (LLViewerTexture::isSystemMemoryCritical())
+ const F32 mem_factor = LLMemory::getSystemMemoryBudgetFactor();
+ if (mem_factor > 1.f)
{
- // If we are low on memory, reduce requested draw distance
- memory_limited_draw_distance = llmax(gAgentCamera.mDrawDistance / LLViewerTexture::getSystemMemoryBudgetFactor(), gAgentCamera.mDrawDistance / 2.f);
+ // We are critically low on memory or recovering,
+ // limit requested draw distance
+ memory_limited_draw_distance = llmax(gAgentCamera.mDrawDistance / mem_factor, gAgentCamera.mDrawDistance / 2.f);
}
if (tp_state == LLAgent::TELEPORT_ARRIVING || LLStartUp::getStartupState() < STATE_MISC)
@@ -3756,9 +3758,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;
}
@@ -3830,9 +3830,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.cpp b/indra/newview/llvieweroctree.cpp
index b1673d2232..3b79666f7c 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -1143,6 +1143,8 @@ void LLOcclusionCullingGroup::checkOcclusion()
GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query result");
+ // Ping watchdog before a blocking GL_QUERY_RESULT GPU call
+ LLAppViewer::instance()->pingMainloopTimeout("Display:CullQueryResult");
glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT, &query_result);
}
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index adfe709b04..fb6fa8bac4 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:
@@ -339,7 +335,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..100644
--- 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/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 5f73d8e901..5f73d8e901 100755..100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 6bbea54e43..8c66046524 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -580,6 +580,7 @@ void LLViewerShaderMgr::setShaders()
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
LLPipeline::RenderAvatarCloth = gSavedSettings.getBOOL("RenderAvatarCloth");
+ LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
if (gViewerWindow)
{
@@ -1002,7 +1003,10 @@ bool LLViewerShaderMgr::loadShadersWater()
return loadShadersWater();
}
- LLWorld::getInstance()->updateWaterObjects();
+ if (LLWorld::instanceExists())
+ {
+ LLWorld::getInstance()->updateWaterObjects();
+ }
return true;
}
@@ -2656,10 +2660,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);
@@ -2682,10 +2686,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);
@@ -2708,10 +2712,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/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 5057ba2289..742ff95f26 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -232,6 +232,8 @@ LLTrace::SampleStatHandle<U32> FRAMETIME_JITTER_EVENTS("frametimeevents", "Numbe
FRAMETIME_JITTER_EVENTS_PER_MINUTE("frametimeeventspm", "Average number of frametime events per minute."),
FRAMETIME_JITTER_EVENTS_LAST_MINUTE("frametimeeventslastmin", "Number of frametime events in the last minute.");
+LLTrace::SampleStatHandle<U64> DOFRAME_TIME_US("doframetimeus", "doFrame wall time in microseconds.");
+
LLTrace::SampleStatHandle<F64> NOTRMALIZED_FRAMETIME_JITTER_SESSION("normalizedframetimejitter", "Normalized frametime jitter over the session.");
LLTrace::SampleStatHandle<F64> NFTV("nftv", "Normalized frametime variation.");
LLTrace::SampleStatHandle<F64> NORMALIZED_FRAMTIME_JITTER_PERIOD("normalizedframetimejitterperiod", "Normalized frametime jitter over the last 5 seconds.");
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 8ec0dd0024..7da74e716b 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -209,29 +209,44 @@ extern SimMeasurement<F64Megabytes > SIM_PHYSICS_MEM;
extern LLTrace::SampleStatHandle<F64Milliseconds > FRAMETIME_JITTER,
- SIM_PING;
+ FRAMETIME,
+ SIM_PING,
+ FRAMETIME_JITTER_99TH,
+ FRAMETIME_JITTER_95TH,
+ FRAMETIME_99TH,
+ FRAMETIME_95TH,
+ FRAMETIME_JITTER_CUMULATIVE,
+ FRAMETIME_JITTER_STDDEV,
+ FRAMETIME_STDDEV;
+
+extern LLTrace::SampleStatHandle<U32> FRAMETIME_JITTER_EVENTS,
+ FRAMETIME_JITTER_EVENTS_PER_MINUTE,
+ FRAMETIME_JITTER_EVENTS_LAST_MINUTE;
+
+extern LLTrace::SampleStatHandle<U64> DOFRAME_TIME_US;
+
+extern LLTrace::SampleStatHandle<F64> NOTRMALIZED_FRAMETIME_JITTER_SESSION;
+extern LLTrace::SampleStatHandle<F64> NFTV;
+extern LLTrace::SampleStatHandle<F64> NORMALIZED_FRAMTIME_JITTER_PERIOD;
extern LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Meters> > AGENT_POSITION_SNAP;
extern LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY;
extern LLTrace::EventStatHandle<F64Milliseconds > REGION_CROSSING_TIME,
- FRAME_STACKTIME,
- UPDATE_STACKTIME,
- NETWORK_STACKTIME,
- IMAGE_STACKTIME,
- REBUILD_STACKTIME,
- RENDER_STACKTIME;
+ FRAME_STACKTIME,
+ UPDATE_STACKTIME,
+ NETWORK_STACKTIME,
+ IMAGE_STACKTIME,
+ REBUILD_STACKTIME,
+ RENDER_STACKTIME;
extern LLTrace::EventStatHandle<F64Seconds > AVATAR_EDIT_TIME,
- TOOLBOX_TIME,
- MOUSELOOK_TIME;
+ TOOLBOX_TIME,
+ MOUSELOOK_TIME;
extern LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE;
-extern LLTrace::SampleStatHandle<F64> NOTRMALIZED_FRAMETIME_JITTER_SESSION;
-extern LLTrace::SampleStatHandle<F64> NORMALIZED_FRAMTIME_JITTER_PERIOD;
-
extern LLTrace::SampleStatHandle<U32> WEBRTC_PACKETS_IN_LOST, WEBRTC_PACKETS_IN_RECEIVED, WEBRTC_PACKETS_OUT_SENT, WEBRTC_PACKETS_OUT_LOST;
extern LLTrace::SampleStatHandle<F32> WEBRTC_JITTER_OUT, WEBRTC_JITTER_IN, WEBRTC_LATENCY, WEBRTC_UPLOAD_BANDWIDTH, WEBRTC_JITTER_BUFFER;
diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp
index 58065ecce5..a183d7c8de 100644
--- a/indra/newview/llviewerstatsrecorder.cpp
+++ b/indra/newview/llviewerstatsrecorder.cpp
@@ -194,7 +194,7 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )
// Open the data file
makeStatsFileName();
- mStatsFile = LLFile::fopen(mStatsFileName, "wb");
+ mStatsFile = LLFile::fopen(mStatsFileName, LLFILE_MODE("wb"));
if (mStatsFile)
{
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 0f23596c9a..6e05555c45 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -533,7 +533,7 @@ void LLViewerTexture::updateClass()
if (is_sys_low)
{
// Not having system memory is more serious, so discard harder
- sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f * getSystemMemoryBudgetFactor());
+ sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f * LLMemory::getSystemMemoryBudgetFactor());
}
else
{
@@ -679,20 +679,6 @@ bool LLViewerTexture::isSystemMemoryCritical()
return getFreeSystemMemory() < get_render_free_main_memory_treshold() / 2;
}
-F32 LLViewerTexture::getSystemMemoryBudgetFactor()
-{
- const S32Megabytes MIN_FREE_MAIN_MEMORY(get_render_free_main_memory_treshold() / 2);
- S32 free_budget = (S32Megabytes)getFreeSystemMemory() - MIN_FREE_MAIN_MEMORY;
- if (free_budget < 0)
- {
- // Leave some padding, otherwise we will crash out of memory before hitting factor 2.
- const S32Megabytes PAD_BUFFER(32);
- // Result should range from 1 at 0 free budget to 2 at -224 free budget, 2.14 at -256MB
- return 1.f - free_budget / (MIN_FREE_MAIN_MEMORY - PAD_BUFFER);
- }
- return 1.f;
-}
-
//end of static functions
//-------------------------------------------------------------------------------------------
const U32 LLViewerTexture::sCurrentFileVersion = 1;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 2937651995..20aaa8a058 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -116,7 +116,6 @@ public:
static void updateClass();
static bool isSystemMemoryLow();
static bool isSystemMemoryCritical();
- static F32 getSystemMemoryBudgetFactor();
LLViewerTexture(bool usemipmaps = true);
LLViewerTexture(const LLUUID& id, bool usemipmaps) ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 4bee11b6f7..4d64f897b1 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1014,38 +1014,6 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
}
imagep->addTextureStats(max_vsize);
-
- // Derive stream priority channel from face lists.
- // Map render texture channels to priority channels:
- // 0 = normal, 1 = diffuse, 2 = specular, 3 = emissive
- {
- static const S32 render_to_priority[] = {
- 1, // DIFFUSE_MAP (0)
- 0, // NORMAL_MAP / ALTERNATE_DIFFUSE_MAP (1)
- 2, // SPECULAR_MAP (2)
- 1, // BASECOLOR_MAP (3)
- 2, // METALLIC_ROUGHNESS_MAP (4)
- 0, // GLTF_NORMAL_MAP (5)
- 3, // EMISSIVE_MAP (6)
- };
-
- S32 priority_channel = 1; // default to diffuse
- for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
- {
- if (imagep->getNumFaces(i) > 0)
- {
- priority_channel = llmin(priority_channel, render_to_priority[i]);
- }
- }
-
- static LLCachedControl<LLVector4> channel_priority(gSavedSettings, "TextureChannelPriority",
- LLVector4(10.0f, 20.0f, 40.0f, 20.0f));
- F32 factor = llmax(channel_priority().mV[priority_channel], 0.1f);
- if (factor != 1.0f)
- {
- imagep->mMaxVirtualSize /= factor;
- }
- }
}
#if 0
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ce8aed8d6f..8730b14614 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -33,8 +33,6 @@
#include <iostream>
#include <fstream>
#include <algorithm>
-#include <boost/filesystem.hpp>
-#include <boost/regex.hpp>
#include "llagent.h"
#include "llagentcamera.h"
@@ -189,7 +187,6 @@
#include "llviewerjoystick.h"
#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llviewernetwork.h"
-#include "llpostprocess.h"
#include "llfloaterimnearbychat.h"
#include "llagentui.h"
#include "llwearablelist.h"
@@ -204,6 +201,7 @@
#include "llwindowlistener.h"
#include "llviewerwindowlistener.h"
+#include "llstatslistener.h"
#include "llcleanup.h"
#if LL_WINDOWS
@@ -782,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;
@@ -1836,7 +1834,7 @@ bool LLViewerWindow::handleTimerEvent(LLWindow *window)
return false;
}
-bool LLViewerWindow::handleDeviceChange(LLWindow *window)
+bool LLViewerWindow::handleDeviceChange(LLWindow *window, const std::string& change_type)
{
// give a chance to use a joystick after startup (hot-plugging)
if (!LLViewerJoystick::getInstance()->isJoystickInitialized() )
@@ -1844,6 +1842,10 @@ bool LLViewerWindow::handleDeviceChange(LLWindow *window)
LLViewerJoystick::getInstance()->init(true);
return true;
}
+ else
+ {
+ LL_INFOS("Window") << "Device change event: " << change_type << LL_ENDL;
+ }
return false;
}
@@ -1865,6 +1867,7 @@ bool LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32
bool LLViewerWindow::handleDisplayChanged()
{
+ LL_INFOS("Window") << "Display change event" << LL_ENDL;
LLFontGL::sResolutionGeneration++;
return false;
}
@@ -1946,6 +1949,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
LLWindowListener::KeyboardGetter getter = [](){ return gKeyboard; };
mWindowListener = std::make_unique<LLWindowListener>(this, getter);
mViewerWindowListener = std::make_unique<LLViewerWindowListener>(this);
+ mStatsListener = std::make_unique<LLStatsListener>();
mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything));
mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible"));
@@ -1994,13 +1998,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)
@@ -3122,7 +3121,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,
@@ -4910,14 +4909,10 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save
return;
}
-// Check if there is enough free space to save snapshot
-#ifdef LL_WINDOWS
- boost::filesystem::path b_path(ll_convert<std::wstring>(lastSnapshotDir));
-#else
- boost::filesystem::path b_path(lastSnapshotDir);
-#endif
- boost::system::error_code ec;
- if (!boost::filesystem::is_directory(b_path, ec) || ec.failed())
+ // Check if there is enough free space to save snapshot
+ std::filesystem::path b_path = fsyspath(lastSnapshotDir);
+ std::error_code ec;
+ if (!std::filesystem::is_directory(b_path, ec) || ec)
{
LLSD args;
args["PATH"] = lastSnapshotDir;
@@ -4926,8 +4921,8 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save
failure_cb();
return;
}
- boost::filesystem::space_info b_space = boost::filesystem::space(b_path, ec);
- if (ec.failed())
+ std::filesystem::space_info b_space = std::filesystem::space(b_path, ec);
+ if (ec)
{
LLSD args;
args["PATH"] = lastSnapshotDir;
@@ -5728,11 +5723,6 @@ void* LLViewerWindow::getPlatformWindow() const
return mWindow->getPlatformWindow();
}
-void* LLViewerWindow::getMediaWindow() const
-{
- return mWindow->getMediaWindow();
-}
-
void LLViewerWindow::focusClient() const
{
return mWindow->focusClient();
@@ -5954,11 +5944,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 b68956d853..06d49df56d 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -66,6 +66,7 @@ class LLWindow;
class LLRootView;
class LLWindowListener;
class LLViewerWindowListener;
+class LLStatsListener;
class LLVOPartGroup;
class LLPopupView;
class LLCubeMap;
@@ -233,7 +234,7 @@ public:
/*virtual*/ void handleWindowUnblock(LLWindow *window);
/*virtual*/ void handleDataCopy(LLWindow *window, S32 data_type, void *data);
/*virtual*/ bool handleTimerEvent(LLWindow *window);
- /*virtual*/ bool handleDeviceChange(LLWindow *window);
+ /*virtual*/ bool handleDeviceChange(LLWindow *window, const std::string& change_type);
/*virtual*/ bool handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
/*virtual*/ bool handleDisplayChanged();
/*virtual*/ bool handleWindowDidChangeScreen(LLWindow *window);
@@ -279,7 +280,6 @@ public:
LLWindow* getWindow() const { return mWindow; }
void* getPlatformWindow() const;
- void* getMediaWindow() const;
void focusClient() const;
LLCoordGL getLastMouse() const { return mLastMousePoint; }
@@ -566,6 +566,7 @@ private:
std::unique_ptr<LLWindowListener> mWindowListener;
std::unique_ptr<LLViewerWindowListener> mViewerWindowListener;
+ std::unique_ptr<LLStatsListener> mStatsListener;
// Object temporarily hovered over while dragging
LLPointer<LLViewerObject> mDragHoveredObject;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 78d9c1fa4c..85d32e19cb 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -699,7 +699,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),
@@ -3125,7 +3124,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (isImpostor() && !mNeedsImpostorUpdate)
{
- LL_ALIGN_16(LLVector4a ext[2]);
+ LLVector4a ext[2];
F32 distance;
LLVector3 angle;
@@ -5489,7 +5488,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);
@@ -8618,6 +8617,10 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading)
if (changed && isSelf())
{
+ // Agent's own avatar doesn't track bakes the same way as other avatars.
+ // So just update here, on cloud removal.
+ markBodyPartsComplexityDirty();
+
// to know about outfit switching
LLAvatarRenderNotifier::getInstance()->updateNotificationState();
}
@@ -8634,7 +8637,8 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading)
bool LLVOAvatar::isFullyLoaded() const
{
- return (mRenderUnloadedAvatar && !isSelf()) || mFullyLoaded;
+ static LLCachedControl<bool> render_unloaded_avatar(gSavedSettings, "RenderUnloadedAvatar", false);
+ return (render_unloaded_avatar && !isSelf()) || mFullyLoaded;
}
bool LLVOAvatar::hasFirstFullAttachmentData() const
@@ -10213,6 +10217,10 @@ void LLVOAvatar::onInitialBakedTextureLoaded( bool success, LLViewerFetchedTextu
}
if (final || !success )
{
+ if (selfp)
+ {
+ selfp->markBodyPartsComplexityDirty();
+ }
delete avatar_idp;
}
}
@@ -11530,7 +11538,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
// Store results
mVisualComplexity = total_cost;
- // Call the existing reporting function with the aggregated lists
+ // Call the reporting function with the aggregated lists
processComplexityCostChange(hud_complexity_list, object_complexity_list);
// Stop processing until something changes
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 0ac4db8fcf..37a7be7efb 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -265,7 +265,7 @@ public:
private: //aligned members
- LL_ALIGN_16(LLVector4a mImpostorExtents[2]);
+ LLVector4a mImpostorExtents[2];
//--------------------------------------------------------------------
// Updates
@@ -745,8 +745,6 @@ private:
LLVector3 mLastAnimExtents[2];
LLVector3 mLastAnimBasePos;
- LLCachedControl<bool> mRenderUnloadedAvatar;
-
//--------------------------------------------------------------------
// Wind rippling in clothes
//--------------------------------------------------------------------
@@ -1113,7 +1111,7 @@ public:
void startTyping() { mTyping = true; mTypingTimer.reset(); }
void stopTyping() { mTyping = false; }
private:
- bool mVisibleChat;
+ bool mVisibleChat = false;
//--------------------------------------------------------------------
// Lip synch morphs
@@ -1295,7 +1293,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/llvocache.cpp b/indra/newview/llvocache.cpp
index 520bc588de..df14b46acd 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -32,6 +32,7 @@
#include "lldrawable.h"
#include "llviewerregion.h"
#include "llagentcamera.h"
+#include "llmemory.h"
#include "llsdserialize.h"
#include "llworld.h" // For LLWorld::getInstance()
//static variables
@@ -488,11 +489,12 @@ void LLVOCacheEntry::updateDebugSettings()
static const F32 MIN_RADIUS = 1.0f;
F32 draw_radius = gAgentCamera.mDrawDistance;
- if (LLViewerTexture::isSystemMemoryCritical())
+ const F32 mem_factor = LLMemory::getSystemMemoryBudgetFactor();
+ if (mem_factor > 1.f)
{
// Factor is intended to go from 1.0 to 2.0
// For safety cap reduction at 50%, we don't want to go below half of draw distance
- draw_radius = llmax(draw_radius / LLViewerTexture::getSystemMemoryBudgetFactor(), draw_radius / 2.f);
+ draw_radius = llmax(draw_radius / mem_factor, draw_radius / 2.f);
}
const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance]
sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor);
@@ -1250,7 +1252,7 @@ void LLVOCache::removeCache(ELLPath location, bool started)
std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
LL_INFOS() << "Removing cache at " << cache_dir << LL_ENDL;
gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files
- LLFile::rmdir(cache_dir);
+ LLFile::remove(cache_dir);
clearCacheInMemory();
mInitialized = false;
@@ -1370,7 +1372,7 @@ void LLVOCache::removeFromCache(HeaderEntryInfo* entry)
std::string filename;
getObjectCacheFilename(entry->mHandle, filename);
LL_WARNS("GLTF", "VOCache") << "Removing object cache for handle " << entry->mHandle << "Filename: " << filename << LL_ENDL;
- LLAPRFile::remove(filename, mLocalAPRFilePoolp);
+ LLFile::remove(filename);
// Note: `removeFromCache` should take responsibility for cleaning up all cache artefacts specfic to the handle/entry.
// as such this now includes the generic extras
@@ -1394,7 +1396,7 @@ void LLVOCache::readCacheHeader()
clearCacheInMemory();
bool success = true ;
- if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
+ if (LLFile::isfile(mHeaderFileName))
{
LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 53d82ff989..b91b4b180b 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -25,7 +25,9 @@
*/
#include "llvoiceclient.h"
+#ifndef DISABLE_WEBRTC
#include "llvoicewebrtc.h"
+#endif
#include "llviewernetwork.h"
#include "llviewercontrol.h"
#include "llcommandhandler.h"
@@ -39,6 +41,7 @@
#include "lltrans.h"
#include "lluiusage.h"
#include "llnearbyvoicemoderation.h"
+#include "llmutelist.h"
const F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f;
@@ -116,11 +119,13 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv
LLVoiceModuleInterface *getVoiceModule(const std::string &voice_server_type)
{
+#ifndef DISABLE_WEBRTC
if (voice_server_type == WEBRTC_VOICE_SERVER_TYPE)
{
return (LLVoiceModuleInterface *) LLWebRTCVoiceClient::getInstance();
}
else
+#endif
{
LLNotificationsUtil::add("VoiceVersionMismatch");
return nullptr;
@@ -161,7 +166,9 @@ void LLVoiceClient::init(LLPumpIO *pump)
{
// Initialize all of the voice modules
m_servicePump = pump;
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->init(pump);
+#endif
}
void LLVoiceClient::userAuthorized(const std::string& user_id, const LLUUID &agentID)
@@ -171,16 +178,20 @@ 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
}
void LLVoiceClient::handleSimulatorFeaturesReceived(const LLSD &simulatorFeatures)
{
std::string voiceServerType = simulatorFeatures["VoiceServerType"].asString();
+#ifndef DISABLE_WEBRTC
if (voiceServerType.empty())
{
voiceServerType = WEBRTC_VOICE_SERVER_TYPE;
}
+#endif
if (mSpatialVoiceModule && !mNonSpatialVoiceModule)
{
@@ -280,15 +291,19 @@ 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
}
void LLVoiceClient::terminate()
{
+#ifndef DISABLE_WEBRTC
if (LLWebRTCVoiceClient::instanceExists())
{
LLWebRTCVoiceClient::getInstance()->terminate();
}
+#endif
mSpatialVoiceModule = NULL;
m_servicePump = NULL;
@@ -323,7 +338,9 @@ void LLVoiceClient::updateSettings()
updateMicMuteLogic();
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->updateSettings();
+#endif
}
//--------------------------------------------------
@@ -331,32 +348,48 @@ void LLVoiceClient::updateSettings()
void LLVoiceClient::tuningStart()
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->tuningStart();
+#endif
}
void LLVoiceClient::tuningStop()
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->tuningStop();
+#endif
}
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
}
//------------------------------------------------
@@ -364,38 +397,62 @@ 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)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setCaptureDevice(name);
+#endif
}
void LLVoiceClient::setRenderDevice(const std::string& 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
}
@@ -404,12 +461,18 @@ const LLVoiceDeviceList& LLVoiceClient::getRenderDevices()
void LLVoiceClient::getParticipantList(std::set<LLUUID> &participants) const
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->getParticipantList(participants);
+#endif
}
bool LLVoiceClient::isParticipant(const LLUUID &speaker_id) const
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->isParticipant(speaker_id);
+#else
+ return false;
+#endif
}
@@ -501,12 +564,20 @@ void LLVoiceClient::activateSpatialChannel(bool activate)
bool LLVoiceClient::isCurrentChannel(const LLSD& channelInfo)
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->isCurrentChannel(channelInfo);
+#else
+ return false;
+#endif
}
bool LLVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2)
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->compareChannels(channelInfo1, channelInfo2);
+#else
+ return false;
+#endif
}
LLVoiceP2PIncomingCallInterfacePtr LLVoiceClient::getIncomingCallInterface(const LLSD& voice_call_info)
@@ -531,12 +602,14 @@ LLVoiceP2POutgoingCallInterface *LLVoiceClient::getOutgoingCallInterface(const L
LLVoiceVersionInfo versionInfo = LLVoiceClient::getInstance()->getVersion();
voice_server_type = versionInfo.internalVoiceServerType;
}
+#ifndef DISABLE_WEBRTC
if (voiceChannelInfo.has("voice_server_type") && voiceChannelInfo["voice_server_type"] != voice_server_type)
{
// there's a mismatch between what the peer is offering and what our server
// can handle, so default to webrtc
voice_server_type = WEBRTC_VOICE_SERVER_TYPE;
}
+#endif
LLVoiceModuleInterface *module = getVoiceModule(voice_server_type);
return dynamic_cast<LLVoiceP2POutgoingCallInterface *>(module);
}
@@ -547,12 +620,16 @@ LLVoiceP2POutgoingCallInterface *LLVoiceClient::getOutgoingCallInterface(const L
void LLVoiceClient::setVoiceVolume(F32 volume)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setVoiceVolume(volume);
+#endif
}
void LLVoiceClient::setMicGain(F32 gain)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setMicGain(gain);
+#endif
}
@@ -598,10 +675,12 @@ bool LLVoiceClient::voiceEnabled()
void LLVoiceClient::setVoiceEnabled(bool enabled)
{
+#ifndef DISABLE_WEBRTC
if (LLWebRTCVoiceClient::instanceExists())
{
LLWebRTCVoiceClient::getInstance()->setVoiceEnabled(enabled);
}
+#endif
}
void LLVoiceClient::updateMicMuteLogic()
@@ -620,7 +699,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
}
void LLVoiceClient::setMuteMic(bool muted)
@@ -717,13 +798,21 @@ bool LLVoiceClient::getVoiceEnabled(const LLUUID& id) const
std::string LLVoiceClient::getDisplayName(const LLUUID& id) const
{
+#ifndef DISABLE_WEBRTC
std::string result = LLWebRTCVoiceClient::getInstance()->getDisplayName(id);
+#else
+ std::string result;
+#endif
return result;
}
bool LLVoiceClient::isVoiceWorking() const
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->isVoiceWorking();
+#else
+ return false;
+#endif
}
bool LLVoiceClient::isParticipantAvatar(const LLUUID& id)
@@ -738,19 +827,31 @@ bool LLVoiceClient::isOnlineSIP(const LLUUID& id)
bool LLVoiceClient::getIsSpeaking(const LLUUID& id)
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->getIsSpeaking(id);
+#else
+ return false;
+#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);
+#else
+ return false;
+#endif
}
F32 LLVoiceClient::getCurrentPower(const LLUUID& id)
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->getCurrentPower(id);
+#else
+ return 0.f;
+#endif
}
bool LLVoiceClient::getOnMuteList(const LLUUID& id)
@@ -762,12 +863,18 @@ bool LLVoiceClient::getOnMuteList(const LLUUID& id)
F32 LLVoiceClient::getUserVolume(const LLUUID& id)
{
+#ifndef DISABLE_WEBRTC
return LLWebRTCVoiceClient::getInstance()->getUserVolume(id);
+#else
+ return 0.f;
+#endif
}
void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->setUserVolume(id, volume);
+#endif
}
//--------------------------------------------------
@@ -775,41 +882,53 @@ void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->addObserver(observer);
+#endif
}
void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer)
{
+#ifndef DISABLE_WEBRTC
if (LLWebRTCVoiceClient::instanceExists())
{
LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
}
+#endif
}
void LLVoiceClient::addObserver(LLFriendObserver* observer)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->addObserver(observer);
+#endif
}
void LLVoiceClient::removeObserver(LLFriendObserver* observer)
{
+#ifndef DISABLE_WEBRTC
if (LLWebRTCVoiceClient::instanceExists())
{
LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
}
+#endif
}
void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer)
{
+#ifndef DISABLE_WEBRTC
LLWebRTCVoiceClient::getInstance()->addObserver(observer);
+#endif
}
void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer)
{
+#ifndef DISABLE_WEBRTC
if (LLWebRTCVoiceClient::instanceExists())
{
LLWebRTCVoiceClient::getInstance()->removeObserver(observer);
}
+#endif
}
LLSD LLVoiceClient::getP2PChannelInfoTemplate(const LLUUID& id) const
@@ -852,11 +971,13 @@ class LLViewerRequiredVoiceVersion : public LLHTTPNode
LLVoiceModuleInterface *voiceModule = NULL;
+#ifndef DISABLE_WEBRTC
if (voice_server_type == "webrtc" || voice_server_type.empty())
{
voiceModule = (LLVoiceModuleInterface *) LLWebRTCVoiceClient::getInstance();
}
else
+#endif
{
LL_WARNS("Voice") << "Unknown voice server type " << voice_server_type << LL_ENDL;
if (!sAlertedUser)
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index c5704982b8..e6dac0530d 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -32,7 +32,6 @@
#include "llviewerprecompiledheaders.h"
#include "llviewercontrol.h"
#include "llglheaders.h"
-#include "llsphere.h"
#include "llvoicevisualizer.h"
#include "llviewercamera.h"
#include "llviewerobject.h"
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index b2bb5990b1..9b4a371cec 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -1711,6 +1711,14 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
mVoiceEnabled = enabled;
LLVoiceClientStatusObserver::EStatusType status;
+ // Gate the audio devices on voice being enabled: the capture mic and
+ // playout speaker only run while voice is on, and the mic isn't held
+ // open when voice is off.
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->setVoiceEnabled(enabled);
+ }
+
if (enabled)
{
LL_DEBUGS("Voice") << "enabling" << LL_ENDL;
@@ -2408,7 +2416,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);
@@ -3023,7 +3031,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)
@@ -3068,7 +3076,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;
}
}
@@ -3460,9 +3468,10 @@ void LLVoiceWebRTCConnection::OnStatsDelivered(const llwebrtc::LLWebRTCStatsMap&
{
if (attributes.contains("packetsLost"))
{
- U32 out_packets_lost = 0;
- LLStringUtil::convertToU32(attributes.at("packetsLost"), out_packets_lost);
- sample(LLStatViewer::WEBRTC_PACKETS_OUT_LOST, out_packets_lost);
+ // packetsLost may be negative, clamp to zero for unsigned Viewer stats
+ S32 out_packets_lost = 0;
+ LLStringUtil::convertToS32(attributes.at("packetsLost"), out_packets_lost);
+ sample(LLStatViewer::WEBRTC_PACKETS_OUT_LOST, static_cast<U32>(llmax(out_packets_lost, 0)));
}
if (attributes.contains("jitter"))
{
@@ -3476,9 +3485,10 @@ void LLVoiceWebRTCConnection::OnStatsDelivered(const llwebrtc::LLWebRTCStatsMap&
{
if (attributes.contains("packetsLost"))
{
- U32 in_packets_lost = 0;
- LLStringUtil::convertToU32(attributes.at("packetsLost"), in_packets_lost);
- sample(LLStatViewer::WEBRTC_PACKETS_IN_LOST, in_packets_lost);
+ // packetsLost may be negative, clamp to zero for unsigned Viewer stats
+ S32 in_packets_lost = 0;
+ LLStringUtil::convertToS32(attributes.at("packetsLost"), in_packets_lost);
+ sample(LLStatViewer::WEBRTC_PACKETS_IN_LOST, static_cast<U32>(llmax(in_packets_lost, 0)));
}
if (attributes.contains("packetsReceived"))
{
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index b5ee42f36c..98d771f8da 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -36,17 +36,16 @@
#include "llenvironment.h"
#include "llsettingssky.h"
-constexpr U32 MIN_SKY_DETAIL = 8;
-constexpr U32 MAX_SKY_DETAIL = 180;
+constexpr U32 SKY_DETAIL = 18; // Any lower and there will be artifacts
inline U32 LLVOWLSky::getNumStacks(void)
{
- return llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail")));
+ return SKY_DETAIL;
}
inline U32 LLVOWLSky::getNumSlices(void)
{
- return 2 * llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail")));
+ return 2 * SKY_DETAIL;
}
inline U32 LLVOWLSky::getStripsNumVerts(void)
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 8e7b86eb00..8e7b86eb00 100755..100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 7b0bf6f251..a9183109ef 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -211,7 +211,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 = std::make_shared<LLCore::HttpHeaders>();
diff --git a/indra/newview/macview_Prefix.h b/indra/newview/macview_Prefix.h
deleted file mode 100644
index faad8fa704..0000000000
--- a/indra/newview/macview_Prefix.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/**
- * @file macview_Prefix.h
- * @brief Prefix header for all source files of the 'newview' target in the 'newview' project.
- *
- * $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$
- */
-
-// MBW -- This doesn't work. There are some conflicts between things in Carbon.h and some of the linden source.
-//#include <Carbon/Carbon.h>
-
-////////////////// From llagent.cpp
-#include "llpreprocessor.h"
-#include "stdtypes.h"
-#include "stdenums.h"
-
-#include "llagent.h"
-
-#include "llcoordframe.h"
-#include "indra_constants.h"
-#include "llmath.h"
-#include "llcriticaldamp.h"
-#include "llfocusmgr.h"
-#include "llparcel.h"
-#include "llpermissions.h"
-#include "llregionhandle.h"
-#include "m3math.h"
-#include "m4math.h"
-#include "message.h"
-#include "qmath.h"
-#include "v3math.h"
-#include "v4math.h"
-#include "vmath.h"
-//#include "llteleportflags.h"
-
-#include "llbox.h"
-#include "llbutton.h"
-#include "llconsole.h"
-#include "lldrawable.h"
-#include "llfirstuse.h"
-#include "llfloater.h"
-#include "llfloaterbuildoptions.h"
-#include "llfloaterchat.h"
-#include "llfloatergroups.h"
-#include "llfloaterworldmap.h"
-#include "llfloatermute.h"
-#include "llconversation.h"
-#include "llfloatertools.h"
-#include "llhudeffectlookat.h"
-#include "llhudmanager.h"
-#include "lljoystickbutton.h"
-#include "llmenugl.h"
-#include "llmorphview.h"
-#include "llmoveview.h"
-#include "llselectmgr.h"
-#include "llsky.h"
-#include "llrendersphere.h"
-#include "llstatusbar.h"
-#include "lltalkview.h"
-#include "lltool.h"
-#include "lltoolfocus.h"
-#include "lltoolcomp.h" // for gToolGun
-#include "lltoolgrab.h"
-#include "lltoolmgr.h"
-#include "lltoolpie.h"
-#include "llui.h" // for make_ui_sound
-#include "llviewercamera.h"
-#include "llviewermenu.h"
-#include "llviewerobjectlist.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerparceloverlay.h"
-#include "llviewerregion.h"
-#include "llviewerstats.h"
-#include "llviewerwindow.h"
-#include "llvoavatar.h"
-#include "llvoground.h"
-#include "llvosky.h"
-#include "llworld.h"
-#include "pipeline.h"
-
-/////////////////// From llfloater.cpp
-#include "llbutton.h"
-#include "lldraghandle.h"
-#include "llfocusmgr.h"
-#include "llresizebar.h"
-#include "llresizehandle.h"
-#include "llresmgr.h"
-#include "llui.h"
-#include "llviewborder.h"
-#include "lluictrlfactory.h"
-
-
-/////////////////// From lldrawpool.cpp
-#include "llface.h"
-#include "llcontrol.h"
-#include "pipeline.h"
-
-#include "llviewerobjectlist.h" // For debug listing.
-
-//extern LLPipeline gPipeline;
-
-#include "lldrawpoolsimple.h"
-#include "lldrawpoolalpha.h"
-#include "lldrawpoolavatar.h"
-#include "lldrawpooltree.h"
-#include "lldrawpoolterrain.h"
-#include "lldrawpoolsky.h"
-#include "lldrawpoolwater.h"
-#include "lldrawpoolground.h"
-#include "lldrawpoolbump.h"
-
-/////////////////// From llface.cpp
-#include "llgl.h"
-#include "llviewerimage.h"
-#include "llsky.h"
-#include "llvosky.h"
-#include "llcontrol.h"
-#include "v3color.h"
-#include "pipeline.h"
-#include "llvolume.h"
-#include "llviewercamera.h"
-#include "lllightconstants.h"
-
-#include "llvovolume.h"
-#include "m3math.h"
-#include "lldrawpoolbump.h"
-
-
-
-/////////////////// From llpanel.cpp
-#include "llpanel.h"
-
-#include "llfontgl.h"
-#include "llrect.h"
-#include "llerror.h"
-#include "lltimer.h"
-
-#include "llmenugl.h"
-#include "llstatusbar.h"
-#include "llui.h"
-#include "llkeyboard.h"
-#include "llviewerwindow.h"
-#include "llcontrol.h"
-#include "lluictrl.h"
-#include "lluictrlfactory.h"
-#include "llviewborder.h"
-#include "llviewerimagelist.h"
-#include "llbutton.h"
-#include "llfocusmgr.h"
-
-
-
-/////////////////// From llvovolume.cpp
-#include "llvovolume.h"
-#include "llviewerimagelist.h"
-
-#include "llcontrol.h"
-
-#include "object_flags.h"
-
-#include "material_codes.h"
-#include "llagent.h"
-#include "llworld.h"
-#include "llviewerregion.h"
-#include "llprimitive.h"
-#include "llvolume.h"
-#include "lldrawable.h"
-#include "llface.h"
-#include "llvolumemgr.h"
-#include "llsky.h"
-
-#include "pipeline.h"
-#include "llmaterialtable.h"
-#include "message.h"
-#include "llviewertextureanim.h"
-#include "llviewercamera.h"
-#include "lldrawpoolbump.h"
-
-
-/////////////////// From llagentpilot.cpp
-#include "llagentpilot.h"
-#include "llagent.h"
-#include "llframestats.h"
-#include "viewer.h"
-#include "llcontrol.h"
-
-
-/////////////////// From llloginview.cpp
-#include "llloginview.h"
-
-#include "indra_constants.h" // for key and mask constants
-#include "llfontgl.h"
-#include "v4color.h"
-#include "llwindow_impl.h"
-
-#include "llbutton.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llcontrol.h"
-#include "lllineeditor.h"
-#include "lltextbox.h"
-#include "llui.h"
-//#include "lluiconstants.h"
-#include "llviewerimagelist.h"
-#include "llviewermenu.h" // for handle_preferences()
-#include "llviewerwindow.h" // to link into child list
-#include "llfocusmgr.h"
-#include "llmd5.h"
-#include "llversion.h"
-#include "viewer.h"
-
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 54fa7a2c09..ab7058b5df 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;
@@ -821,9 +832,8 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
-
- static LLCachedControl<bool> has_hdr(gSavedSettings, "RenderHDREnabled", true);
- bool hdr = gGLManager.mGLVersion > 4.05f && has_hdr();
+ bool has_hdr = gSavedSettings.getBOOL("RenderHDREnabled");
+ bool hdr = gGLManager.mGLVersion > 4.05f && has_hdr;
if (mRT == &mMainRT)
{ // hacky -- allocate auxillary buffer
@@ -889,6 +899,8 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY)
if (!gCubeSnapshot) // hack to not re-allocate various targets for cube snapshots
{
+ U32 post_color_fmt = gSavedSettings.getBOOL("RenderHighPrecisionPostProcess") ? GL_RGBA16F : GL_RGBA;
+
if (RenderUIBuffer)
{
if (!mUIScreen.allocate(resX, resY, GL_RGBA))
@@ -899,10 +911,10 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY)
if (RenderFSAAType > 0)
{
- if (!mFXAAMap.allocate(resX, resY, GL_RGBA)) return false;
+ if (!mFXAAMap.allocate(resX, resY, post_color_fmt)) return false;
if (RenderFSAAType == 2)
{
- if (!mSMAABlendBuffer.allocate(resX, resY, GL_RGBA, false)) return false;
+ if (!mSMAABlendBuffer.allocate(resX, resY, post_color_fmt, false)) return false;
}
}
else
@@ -923,8 +935,8 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY)
mSceneMap.release();
}
- mPostPingMap.allocate(resX, resY, GL_RGBA);
- mPostPongMap.allocate(resX, resY, GL_RGBA);
+ mPostPingMap.allocate(resX, resY, post_color_fmt);
+ mPostPongMap.allocate(resX, resY, post_color_fmt);
// The water exclusion mask needs its own depth buffer so we can take care of the problem of multiple water planes.
// Should we ever make water not just a plane, it also aids with that as well as the water planes will be rendered into the mask.
@@ -1020,7 +1032,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);
}
}
@@ -1037,7 +1049,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);
}
}
@@ -4365,7 +4377,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);
@@ -4407,7 +4419,7 @@ void LLPipeline::renderPhysicsDisplay()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
}
- glLineWidth(1.f);
+ gGL.setLineWidth(1.f);
gDebugProgram.unbind();
}
@@ -4491,8 +4503,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);
@@ -4516,7 +4527,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
@@ -4631,11 +4642,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 );
@@ -4658,7 +4669,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"));
@@ -4685,7 +4696,7 @@ void LLPipeline::renderDebug()
gPathfindingProgram.bind();
gGL.flush();
- glLineWidth(1.0f);
+ gGL.setLineWidth(1.0f);
}
glPolygonOffset(0.f, 0.f);
@@ -4978,7 +4989,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)
{
@@ -4996,7 +5007,7 @@ void LLPipeline::renderDebug()
}
}
gGL.flush();
- glLineWidth(1.f);*/
+ gGL.setLineWidth(1.f);*/
}
}
@@ -7012,7 +7023,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:
@@ -9398,7 +9409,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/res/have_artwork_bundle.marker b/indra/newview/res/have_artwork_bundle.marker
index 1dbb238d53..1dbb238d53 100755..100644
--- a/indra/newview/res/have_artwork_bundle.marker
+++ b/indra/newview/res/have_artwork_bundle.marker
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index c9ca758555..c9ca758555 100755..100644
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
diff --git a/indra/newview/secondlife-i686.supp b/indra/newview/secondlife-i686.supp
index 863c8364ab..863c8364ab 100755..100644
--- a/indra/newview/secondlife-i686.supp
+++ b/indra/newview/secondlife-i686.supp
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 99dca7b395..83934f2132 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
@@ -76,19 +76,19 @@
height="16"
increment="1"
initial_value="8"
- label="Post process quality:"
+ label="Glow quality:"
label_width="185"
layout="topleft"
left="30"
min_val="8"
max_val="9"
- name="RenderPostProcess"
+ name="GlowResolution"
show_text="false"
top_delta="16"
width="300">
<slider.commit_callback
function="Pref.UpdateSliderText"
- parameter="PostProcessText" />
+ parameter="GlowResolutionText" />
</slider>
<text
type="string"
@@ -96,7 +96,7 @@
follows="left|top"
height="16"
layout="topleft"
- name="PostProcessText"
+ name="GlowResolutionText"
top_delta="0"
left_delta="304"
width="65">
@@ -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">
@@ -657,25 +689,25 @@
</check_box>
<slider
- control_name="WLSkyDetail"
+ control_name="RenderHighPrecisionPostProcess"
decimal_digits="0"
follows="left|top"
height="16"
- increment="8"
+ increment="1"
initial_value="160"
- label="Sky:"
+ label="Post Process Quality:"
label_width="164"
layout="topleft"
left="420"
- min_val="16"
- max_val="128"
- name="SkyMeshDetail"
+ min_val="0"
+ max_val="1"
+ name="RenderPostProcess"
show_text="false"
top_delta="22"
width="260">
<slider.commit_callback
function="Pref.UpdateSliderText"
- parameter="SkyMeshDetailText" />
+ parameter="PostProcessText" />
</slider>
<text
type="string"
@@ -684,7 +716,7 @@
height="16"
layout="topleft"
left_delta="264"
- name="SkyMeshDetailText"
+ name="PostProcessText"
text_readonly_color="LabelDisabledColor"
top_delta="0"
width="65">
diff --git a/indra/newview/skins/default/xui/en/floater_profile.xml b/indra/newview/skins/default/xui/en/floater_profile.xml
index 32ab811a6e..3a33572785 100644
--- a/indra/newview/skins/default/xui/en/floater_profile.xml
+++ b/indra/newview/skins/default/xui/en/floater_profile.xml
@@ -31,7 +31,7 @@
follows="all"
layout="topleft"
halign="center"
- tab_min_width="81"
+ tab_min_width="80"
tab_height="30"
tab_position="top"
>
diff --git a/indra/newview/skins/default/xui/en/floater_script.xml b/indra/newview/skins/default/xui/en/floater_script.xml
index ae6e68de17..20feec615c 100644
--- a/indra/newview/skins/default/xui/en/floater_script.xml
+++ b/indra/newview/skins/default/xui/en/floater_script.xml
@@ -8,8 +8,8 @@
can_dock="true"
can_minimize="true"
visible="false"
- width="350"
+ width="402"
can_resize="false"
- min_width="350"
+ min_width="402"
min_height="200">
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
index fb68193006..fb68193006 100755..100644
--- a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
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_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
index 90bdea93fa..018306826e 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
@@ -60,10 +60,22 @@
name="Large(512x512)"
value="[i512,i512]" />
<combo_box.item
+ label="Wide (1024x512)"
+ name="Wide(1024x512)"
+ value="[i1024,i512]" />
+ <combo_box.item
label="Huge (1024x1024)"
name="Huge(1024x1024)"
value="[i1024,i1024]" />
<combo_box.item
+ label="Full Wide (2048x1024)"
+ name="Full(2048x1024)"
+ value="[i2048,i1024]" />
+ <combo_box.item
+ label="Full (2048x2048)"
+ name="Full(2048x2048)"
+ value="[i2048,i2048]" />
+ <combo_box.item
label="Current Window"
name="CurrentWindow"
value="[i0,i0]" />
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
index 52f9068264..0a56a7b638 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
@@ -75,6 +75,26 @@
name="1600x1200"
value="[i1600,i1200]" />
<combo_box.item
+ label="1920x1080"
+ name="1920x1080"
+ value="[i1920,i1080]" />
+ <combo_box.item
+ label="2560x1440"
+ name="2560x1440"
+ value="[i2560,i1440]" />
+ <combo_box.item
+ label="3840x2160"
+ name="3840x2160"
+ value="[i3840,i2160]" />
+ <combo_box.item
+ label="5120x2880"
+ name="5120x2880"
+ value="[i5120,i2880]" />
+ <combo_box.item
+ label="7680x4320"
+ name="7680x4320"
+ value="[i7680,i4320]" />
+ <combo_box.item
label="Custom"
name="Custom"
value="[i-1,i-1]" />
diff --git a/indra/newview/tests/gpus_results.txt b/indra/newview/tests/gpus_results.txt
deleted file mode 100644
index 3b3fb1aeb6..0000000000
--- a/indra/newview/tests/gpus_results.txt
+++ /dev/null
@@ -1,3111 +0,0 @@
-GPU String Supported? Class Stats OpenGL Recognizer
------------------------------------------------------------------------------------------------------- ----------- ----- ----- ------ ------------------------------------
-AMD BARTS (HD 6800) supported 3 1 2.1 AMD BARTS (HD 6800)
-AMD CAICOS (HD 6400) supported 3 0 0 AMD CAICOS (HD 6400)
-AMD CAYMAN (HD 6900) supported 3 0 0 AMD CAYMAN (HD 6900)
-AMD CEDAR (HD 5450) supported 2 0 2.1 AMD CEDAR (HD 5450)
-AMD JUNIPER (HD 5700) supported 3 0 0 AMD JUNIPER (HD 5700)
-AMD PARK supported 3 0 0 AMD PARK
-AMD REDWOOD (HD 5500/5600) supported 3 0 1.4 AMD REDWOOD (HD 5500/5600)
-AMD RS780 (HD 3200) supported 0 1 2.1 AMD RS780 (HD 3200)
-AMD RS880 (HD 4200) supported 0 1 3.2 AMD RS880 (HD 4200)
-AMD RV610 (HD 2400) supported 1 0 0 AMD RV610 (HD 2400)
-AMD RV620 (HD 3400) supported 1 0 0 AMD RV620 (HD 3400)
-AMD RV630 (HD 2600) supported 2 0 0 AMD RV630 (HD 2600)
-AMD RV635 (HD 3600) supported 3 0 1.4 AMD RV635 (HD 3600)
-AMD RV670 (HD 3800) supported 3 0 0 AMD RV670 (HD 3800)
-AMD RV710 (HD 4300) supported 0 1 1.4 AMD RV710 (HD 4300)
-AMD RV730 (HD 4600) supported 3 0 1.4 AMD RV730 (HD 4600)
-AMD RV770 (HD 4800) supported 3 0 0 AMD RV770 (HD 4800)
-AMD RV790 (HD 4800) supported 3 0 0 AMD RV790 (HD 4800)
-AMD TURKS (HD 6500/6600) supported 3 0 2.1 AMD TURKS (HD 6500/6600)
-ATI NO MATCH
-ATI 760G/Radeon 3000 supported 1 1 4 ATI Radeon 3000
-ATI ASUS AH24xx supported 1 1 4 ATI Radeon HD 2400
-ATI ASUS AH34xx supported 1 1 4 ATI Radeon HD 3400
-ATI ASUS AH36xx supported 3 1 4 ATI Radeon HD 3600
-ATI ASUS AH46xx supported 3 1 4 ATI Radeon HD 4600
-ATI ASUS AX3xx supported 2 1 4 ATI Radeon HD 4300
-ATI ASUS AX5xx supported 1 1 4 ATI Radeon HD 5xx
-ATI ASUS EAH38xx supported 3 1 4 ATI Radeon HD 3800
-ATI ASUS EAH43xx supported 2 1 4 ATI Radeon HD 4300
-ATI ASUS EAH45xx supported 2 1 3.3 ATI Radeon HD 4500
-ATI ASUS EAH48xx supported 3 1 4 ATI Radeon HD 4800
-ATI ASUS EAH54xx supported 3 1 4.2 ATI Radeon HD 5400
-ATI ASUS EAH57xx supported 3 1 4.2 ATI Radeon HD 5700
-ATI ASUS EAH58xx supported 4 1 4.2 ATI Radeon HD 5800
-ATI ASUS EAH64xx supported 3 1 4.2 ATI Radeon HD 6400
-ATI ASUS EAH65xx supported 3 1 4.2 ATI Radeon HD 6500
-ATI ASUS EAH66xx supported 3 1 4.2 ATI Radeon HD 6600
-ATI ASUS EAH67xx supported 3 1 4.2 ATI Radeon HD 6700
-ATI ASUS EAH68xx supported 4 1 4.2 ATI Radeon HD 6800
-ATI ASUS EAH69xx supported 5 1 4.2 ATI Radeon HD 6900
-ATI ASUS EAH6xxx supported 5 1 4.2 ATI Radeon HD 6x00
-ATI ASUS EAH77xx supported 4 1 4.2 ATI Radeon HD 7700
-ATI ASUS HD7700 supported 4 1 4.2 ATI Radeon HD 7700
-ATI ASUS Radeon X1xxx supported 2 0 2.1 ATI Radeon X1xxx
-ATI All-in-Wonder HD supported 1 1 3.3 ATI All-in-Wonder HD
-ATI All-in-Wonder PCI-E supported 1 0 0 ATI All-in-Wonder PCI-E
-ATI Display Adapter supported 1 1 4.1 ATI Display Adapter
-ATI FireGL supported 4 1 4.2 ATI FireGL
-ATI FireGL 5200 supported 4 1 4.2 ATI FireGL
-ATI FireGL 5xxx supported 4 1 4.2 ATI FireGL
-ATI FireMV supported 0 1 3.2 ATI FireMV
-ATI FirePro 2000 supported 2 1 4.2 ATI FirePro 2000
-ATI FirePro 4000 supported 2 0 4.1 ATI FirePro 4000
-ATI FirePro M supported 3 1 4.2 ATI FirePro M
-ATI FirePro M3900 supported 2 0 4.1 ATI FirePro M3900
-ATI FirePro M5800 supported 3 0 0 ATI FirePro M5800
-ATI FirePro M7740 supported 3 0 0 ATI FirePro M7740
-ATI FirePro M7820 supported 5 1 4.2 ATI FirePro M7820
-ATI Geforce 9500 GT unsupported 0 0 0 ATI GeForce Lulz
-ATI Geforce 9600 GT unsupported 0 0 0 ATI GeForce Lulz
-ATI Geforce 9800 GT unsupported 0 0 0 ATI GeForce Lulz
-ATI IGP 340M unsupported 0 0 1.3 ATI IGP 340M
-ATI Mobility Radeon supported 3 0 0 ATI Radeon
-ATI Mobility Radeon 4100 supported 1 1 3.3 ATI Mobility Radeon 4100
-ATI Mobility Radeon 7xxx supported 0 1 1.3 ATI Mobility Radeon 7xxx
-ATI Mobility Radeon 9600 supported 1 1 2.1 ATI Mobility Radeon 9600
-ATI Mobility Radeon 9700 supported 0 1 2.1 ATI Mobility Radeon 9700
-ATI Mobility Radeon 9800 supported 1 0 0 ATI Mobility Radeon 9800
-ATI Mobility Radeon HD 2300 supported 0 1 2.1 ATI Mobility Radeon HD 2300
-ATI Mobility Radeon HD 2400 supported 1 1 3.3 ATI Mobility Radeon HD 2400
-ATI Mobility Radeon HD 2600 supported 1 1 3.3 ATI Mobility Radeon HD 2600
-ATI Mobility Radeon HD 2700 supported 3 0 0 ATI Mobility Radeon HD 2700
-ATI Mobility Radeon HD 3400 supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Mobility Radeon HD 3600 supported 1 1 4 ATI Mobility Radeon HD 3600
-ATI Mobility Radeon HD 3800 supported 3 1 3.3 ATI Mobility Radeon HD 3800
-ATI Mobility Radeon HD 4200 supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Mobility Radeon HD 4300 supported 1 1 4 ATI Mobility Radeon HD 4300
-ATI Mobility Radeon HD 4500 supported 1 1 4 ATI Mobility Radeon HD 4500
-ATI Mobility Radeon HD 4600 supported 2 1 3.3 ATI Mobility Radeon HD 4600
-ATI Mobility Radeon HD 4800 supported 3 1 3.3 ATI Mobility Radeon HD 4800
-ATI Mobility Radeon HD 5100 supported 3 1 3.2 ATI Mobility Radeon HD 5100
-ATI Mobility Radeon HD 5300 supported 3 0 0 ATI Mobility Radeon HD 5300
-ATI Mobility Radeon HD 530v supported 1 1 3.3 ATI Mobility Radeon HD 530v
-ATI Mobility Radeon HD 5400 supported 2 1 4.2 ATI Mobility Radeon HD 5400
-ATI Mobility Radeon HD 540v supported 1 1 3.3 ATI Mobility Radeon HD 540v
-ATI Mobility Radeon HD 545v supported 2 1 4 ATI Mobility Radeon HD 545v
-ATI Mobility Radeon HD 5500 supported 3 0 4.2 ATI Mobility Radeon HD 5500
-ATI Mobility Radeon HD 550v supported 3 1 4 ATI Mobility Radeon HD 550v
-ATI Mobility Radeon HD 5600 supported 3 1 4.2 ATI Mobility Radeon HD 5600
-ATI Mobility Radeon HD 560v supported 3 1 3.2 ATI Mobility Radeon HD 560v
-ATI Mobility Radeon HD 565v supported 3 1 3.3 ATI Mobility Radeon HD 565v
-ATI Mobility Radeon HD 5700 supported 3 1 4.1 ATI Mobility Radeon HD 5700
-ATI Mobility Radeon HD 6300 supported 1 1 4.2 ATI Radeon HD 6300
-ATI Mobility Radeon HD 6500 supported 3 1 4.2 ATI Radeon HD 6500
-ATI Mobility Radeon HD 6500M supported 3 1 4.2 ATI Radeon HD 6500
-ATI Mobility Radeon X1xxx supported 2 0 2.1 ATI Mobility Radeon X1000
-ATI Mobility Radeon X2xxx supported 2 0 2.1 ATI Radeon X2xxx
-ATI Mobility Radeon X3xx supported 1 1 2.1 ATI Radeon X300
-ATI Mobility Radeon X6xx supported 1 1 2.1 ATI Radeon X600
-ATI Mobility Radeon X7xx supported 2 1 2.1 ATI Radeon X700
-ATI Mobility Radeon Xxxx supported 2 0 2.1 ATI Mobility Radeon XX000
-ATI R300 (9700) supported 0 1 2.1 ATI R300 (9700)
-ATI RV410 (X700) supported 1 0 0 ATI RV410 (X700)
-ATI RV530 supported 1 0 0 ATI RV530
-ATI Radeon supported 3 0 0 ATI Radeon
-ATI Radeon 2100 supported 0 1 2.1 ATI Radeon 2100
-ATI Radeon 3000 supported 1 1 4 ATI Radeon 3000
-ATI Radeon 3100 supported 0 1 3.3 ATI Radeon 3100
-ATI Radeon 5xxx supported 3 0 0 ATI Radeon 5xxx
-ATI Radeon 7000 supported 0 1 2 ATI Radeon 7xxx
-ATI Radeon 7xxx supported 0 1 2 ATI Radeon 7xxx
-ATI Radeon 8xxx supported 0 0 0 ATI Radeon 8xxx
-ATI Radeon 9000 supported 0 1 1.3 ATI Radeon 9000
-ATI Radeon 9100 supported 0 0 0 ATI Radeon 9100
-ATI Radeon 9200 supported 0 1 1.3 ATI Radeon 9200
-ATI Radeon 9500 supported 0 1 2.1 ATI Radeon 9500
-ATI Radeon 9600 supported 0 1 2.1 ATI Radeon 9600
-ATI Radeon 9700 supported 1 0 0 ATI Radeon 9700
-ATI Radeon 9800 supported 1 1 2.1 ATI Radeon 9800
-ATI Radeon HD 2300 supported 0 1 3.3 ATI Radeon HD 2300
-ATI Radeon HD 2400 supported 1 1 4 ATI Radeon HD 2400
-ATI Radeon HD 2600 supported 2 1 4 ATI Radeon HD 2600
-ATI Radeon HD 2900 supported 3 1 3.3 ATI Radeon HD 2900
-ATI Radeon HD 3000 supported 0 0 0 ATI Radeon HD 3000
-ATI Radeon HD 3100 supported 1 0 0 ATI Radeon HD 3100
-ATI Radeon HD 3200 supported 1 1 4 ATI Radeon HD 3200
-ATI Radeon HD 3300 supported 1 1 3.3 ATI Radeon HD 3300
-ATI Radeon HD 3400 supported 1 1 4 ATI Radeon HD 3400
-ATI Radeon HD 3500 supported 2 0 0 ATI Radeon HD 3500
-ATI Radeon HD 3600 supported 3 1 4 ATI Radeon HD 3600
-ATI Radeon HD 3700 supported 3 0 3.3 ATI Radeon HD 3700
-ATI Radeon HD 3800 supported 3 1 4 ATI Radeon HD 3800
-ATI Radeon HD 4200 supported 1 1 4 ATI Radeon HD 4200
-ATI Radeon HD 4300 supported 2 1 4 ATI Radeon HD 4300
-ATI Radeon HD 4400 supported 2 0 0 ATI Radeon HD 4400
-ATI Radeon HD 4500 supported 2 1 3.3 ATI Radeon HD 4500
-ATI Radeon HD 4600 supported 3 1 4 ATI Radeon HD 4600
-ATI Radeon HD 4700 supported 3 1 3.3 ATI Radeon HD 4700
-ATI Radeon HD 4800 supported 3 1 4 ATI Radeon HD 4800
-ATI Radeon HD 5400 supported 3 1 4.2 ATI Radeon HD 5400
-ATI Radeon HD 5500 supported 3 1 4.2 ATI Radeon HD 5500
-ATI Radeon HD 5600 supported 3 1 4.2 ATI Radeon HD 5600
-ATI Radeon HD 5700 supported 3 1 4.2 ATI Radeon HD 5700
-ATI Radeon HD 5800 supported 4 1 4.2 ATI Radeon HD 5800
-ATI Radeon HD 5900 supported 4 1 4.2 ATI Radeon HD 5900
-ATI Radeon HD 6200 supported 0 1 4.2 ATI Radeon HD 6200
-ATI Radeon HD 6300 supported 1 1 4.2 ATI Radeon HD 6300
-ATI Radeon HD 6300M supported 1 1 4.2 ATI Radeon HD 6300
-ATI Radeon HD 6400 supported 3 1 4.2 ATI Radeon HD 6400
-ATI Radeon HD 64xx supported 3 1 4.2 ATI Radeon HD 6400
-ATI Radeon HD 6500 supported 3 1 4.2 ATI Radeon HD 6500
-ATI Radeon HD 65xx supported 3 1 4.2 ATI Radeon HD 6500
-ATI Radeon HD 6600 supported 3 1 4.2 ATI Radeon HD 6600
-ATI Radeon HD 66xx supported 3 1 4.2 ATI Radeon HD 6600
-ATI Radeon HD 6700 supported 3 1 4.2 ATI Radeon HD 6700
-ATI Radeon HD 6700M supported 3 1 4.2 ATI Radeon HD 6700
-ATI Radeon HD 6800 supported 4 1 4.2 ATI Radeon HD 6800
-ATI Radeon HD 6900 supported 5 1 4.2 ATI Radeon HD 6900
-ATI Radeon HD 7200 supported 2 0 4.2 ATI Radeon HD 7200
-ATI Radeon HD 7300 supported 2 0 4.2 ATI Radeon HD 7300
-ATI Radeon HD 7400 supported 2 0 4.2 ATI Radeon HD 7400
-ATI Radeon HD 7500 supported 3 1 4.2 ATI Radeon HD 7500
-ATI Radeon HD 7600 supported 3 0 4.2 ATI Radeon HD 7600
-ATI Radeon HD 7700 supported 4 1 4.2 ATI Radeon HD 7700
-ATI Radeon HD 7800 supported 5 1 4.2 ATI Radeon HD 7800
-ATI Radeon HD 7900 supported 5 1 4.2 ATI Radeon HD 7900
-ATI Radeon X1000 supported 2 0 2.1 ATI Radeon X1000
-ATI Radeon X1200 supported 2 0 2.1 ATI Radeon X1200
-ATI Radeon X1300 supported 2 1 2.1 ATI Radeon X1300
-ATI Radeon X13xx supported 2 1 2.1 ATI Radeon X1300
-ATI Radeon X1400 supported 2 1 2.1 ATI Radeon X1400
-ATI Radeon X1500 supported 2 1 2.1 ATI Radeon X1500
-ATI Radeon X15xx supported 2 1 2.1 ATI Radeon X1500
-ATI Radeon X1600 supported 2 1 2.1 ATI Radeon X1600
-ATI Radeon X16xx supported 2 1 2.1 ATI Radeon X1600
-ATI Radeon X17xx supported 2 1 2.1 ATI Radeon X1700
-ATI Radeon X1800 supported 3 1 2.1 ATI Radeon X1800
-ATI Radeon X18xx supported 3 1 2.1 ATI Radeon X1800
-ATI Radeon X1900 supported 2 1 2.1 ATI Radeon X1900
-ATI Radeon X19xx supported 2 1 2.1 ATI Radeon X1900
-ATI Radeon X1xxx supported 2 0 2.1 ATI Radeon X1xxx
-ATI Radeon X2xxx supported 2 0 2.1 ATI Radeon X2xxx
-ATI Radeon X300 supported 1 1 2.1 ATI Radeon X300
-ATI Radeon X500 supported 1 1 2.1 ATI Radeon X500
-ATI Radeon X600 supported 1 1 2.1 ATI Radeon X600
-ATI Radeon X700 supported 2 1 2.1 ATI Radeon X700
-ATI Radeon X800 supported 1 1 2.1 ATI Radeon X800
-ATI Radeon Xpress supported 0 1 2.1 ATI Radeon Xpress
-ATI Rage 128 supported 0 0 0 ATI Rage 128
-ATI Technologies NO MATCH
-ATI Technologies Inc. NO MATCH
-ATI Technologies Inc. (DNA-AMD GFX) AMD Radeon HD 6290 Graphics supported 0 1 4.2 ATI Radeon HD 6200
-ATI Technologies Inc. (DNA-ATi 5.1.7.5x32) ATI Mobility Radeon HD 2 NO MATCH
-ATI Technologies Inc. (Vista) ATI Mobility Radeon HD 5730 supported 3 1 4.1 ATI Mobility Radeon HD 5700
-ATI Technologies Inc. (Vista) ATI Mobility Radeon HD 5870 supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. 128MB ATI RADEON X600 SE supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. 128MB ATI RADEON X600 SE x86/SSE2 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. 128MB ATI Radeon X1300 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. 128MB ATI Radeon X1300 x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. 128MB ATI Radeon X1300 x86/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. 256MB ATI RADEON X600 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. 256MB ATI Radeon X1300PRO supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. 256MB ATI Radeon X1300PRO x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. 256MB ATI Radeon X1300PRO x86/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. 3DP (ATI RADEON XPRESS 200M) supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. 3DP Edition v10.04 (Mobility Radeon X1600) x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. 7900 MOD - AMD Radeon HD 7400M Series supported 3 0 4.2 ATI Radeon HD 7400D/G/M
-ATI Technologies Inc. 7900 MOD - AMD Radeon HD 7640G supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. ALL-IN-WONDER 9600 SERIES supported 1 0 2.1 ATI All-in-Wonder 9xxx
-ATI Technologies Inc. AMD (ATI) FirePro M5950 (FireGL) Mobility Pro Graphics supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD (ATI) FirePro M4000 (FireGL V) Mobility Pro Graphics supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD (ATI) FirePro M5950 (FireGL) Mobility Pro Graphics supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD (ATI) FirePro M6000 (FireGL V) Mobility Pro Graphics supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD (ATI) FirePro M8900 (FireGL) Mobility Pro supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD (ATI) FirePro M8900 (FireGL) Mobility Pro Graphics supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD 760G supported 1 1 3.3 ATI 760G/Radeon 3000
-ATI Technologies Inc. AMD 760G (Microsoft Corporation WDDM 1.1) supported 1 1 3.3 ATI 760G/Radeon 3000
-ATI Technologies Inc. AMD FirePro 2270 supported 2 1 4.2 ATI FirePro 2000
-ATI Technologies Inc. AMD FirePro 2460 supported 2 1 4.2 ATI FirePro 2000
-ATI Technologies Inc. AMD FirePro M2000 supported 3 1 4.2 ATI FirePro M
-ATI Technologies Inc. AMD FirePro M3900 supported 2 0 4.1 ATI FirePro M3900
-ATI Technologies Inc. AMD FirePro M4000 supported 3 1 4.2 ATI FirePro M
-ATI Technologies Inc. AMD FirePro M5950 supported 3 1 4.2 ATI FirePro M
-ATI Technologies Inc. AMD FirePro M5950 Mobility Professional Graphics supported 3 1 4.2 ATI FirePro M
-ATI Technologies Inc. AMD FirePro V3900 supported 2 0 0 ATI FirePro 3000
-ATI Technologies Inc. AMD FirePro V3900 (ATI FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro V4900 supported 2 0 4.1 ATI FirePro 4000
-ATI Technologies Inc. AMD FirePro V4900 (ATI FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro V4900 (FireGL V) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro V4900 (FireGL V) Graphics Adapter supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro V5900 supported 3 0 0 ATI FirePro 5000
-ATI Technologies Inc. AMD FirePro V5900 (ATI FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro V5900 (FireGL V) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro V5900 (FireGL V) Graphics Adapter supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro V7900 supported 3 0 0 ATI FirePro 7000
-ATI Technologies Inc. AMD FirePro V7900 (ATI FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro V7900 (FireGL V) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro V7900 (FireGL V) Graphics Adapter supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro W5000 (FireGL V) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD FirePro W9000 (FireGL V) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. AMD M860G with ATI Mobility Radeon 4100 supported 1 1 3.3 ATI Mobility Radeon 4100
-ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4200 supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4225 supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4250 supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. AMD RADEON HD 6350 supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD RADEON HD 6450 supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. AMD RADEON HD 6450A supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. AMD RADEON HD 6670 supported 3 1 4.2 ATI Radeon HD 6600
-ATI Technologies Inc. AMD RADEON HD 7450 supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. AMD RADEON HD6370D Graphics supported 3 1 4.2 ATI Radeon HD 6300D/G/M
-ATI Technologies Inc. AMD RADEON HD6410D Graphics supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD RADEON HD6530D Graphics supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD RADEON HD6550D Graphics supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon supported 3 0 0 ATI Radeon
-ATI Technologies Inc. AMD Radeon (TM) HD 8500M/8700M supported 4 0 4.2 ATI Radeon HD 8500D/G/M
-ATI Technologies Inc. AMD Radeon 6600M and 6700M Series supported 0 0 0 ATI Radeon 6xxx
-ATI Technologies Inc. AMD Radeon 6600M and 6700M Series (Microsoft Corporation - WDDM v1.20) supported 0 0 0 ATI Radeon 6xxx
-ATI Technologies Inc. AMD Radeon HD 5450 supported 3 1 4.2 ATI Radeon HD 5400
-ATI Technologies Inc. AMD Radeon HD 5500 Series supported 3 1 4.2 ATI Radeon HD 5500
-ATI Technologies Inc. AMD Radeon HD 5500 Series (Microsoft Corporation - WDDM v1.20) supported 3 1 4.2 ATI Radeon HD 5500
-ATI Technologies Inc. AMD Radeon HD 6200 series Graphics supported 0 1 4.2 ATI Radeon HD 6200
-ATI Technologies Inc. AMD Radeon HD 6250 supported 0 1 4.2 ATI Radeon HD 6200
-ATI Technologies Inc. AMD Radeon HD 6250 Graphics supported 0 1 4.2 ATI Radeon HD 6200
-ATI Technologies Inc. AMD Radeon HD 6250M supported 3 0 4.2 ATI Radeon HD 6200D/G/M
-ATI Technologies Inc. AMD Radeon HD 6290 supported 0 1 4.2 ATI Radeon HD 6200
-ATI Technologies Inc. AMD Radeon HD 6290 Graphics supported 0 1 4.2 ATI Radeon HD 6200
-ATI Technologies Inc. AMD Radeon HD 6290M supported 3 0 4.2 ATI Radeon HD 6200D/G/M
-ATI Technologies Inc. AMD Radeon HD 6300 series Graphics supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6300M Series supported 3 1 4.2 ATI Radeon HD 6300D/G/M
-ATI Technologies Inc. AMD Radeon HD 6310 supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics (Engineering Sample - WDDM v1.20) supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics (Microsoft Corporation - WDDM v1.3) supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics (Microsoft Corporation- WDDM v1.20) supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6310M supported 3 1 4.2 ATI Radeon HD 6300D/G/M
-ATI Technologies Inc. AMD Radeon HD 6320 supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6320 Graphics supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6320 Graphic supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6320 Graphics supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6320 Graphics (Microsoft Corporation - WDDM v1.20) supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6320 series Graphics supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6320M supported 3 1 4.2 ATI Radeon HD 6300D/G/M
-ATI Technologies Inc. AMD Radeon HD 6330M supported 3 1 4.2 ATI Radeon HD 6300D/G/M
-ATI Technologies Inc. AMD Radeon HD 6350 supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. AMD Radeon HD 6370D supported 3 1 4.2 ATI Radeon HD 6300D/G/M
-ATI Technologies Inc. AMD Radeon HD 6370M supported 3 1 4.2 ATI Radeon HD 6300D/G/M
-ATI Technologies Inc. AMD Radeon HD 6380G supported 3 1 4.2 ATI Radeon HD 6300D/G/M
-ATI Technologies Inc. AMD Radeon HD 6400 Series supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. AMD Radeon HD 6400M Series supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon HD 6410D supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon HD 6410D Graphics supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon HD 6450 supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. AMD Radeon HD 6450 (Microsoft Corporation - WDDM v1.2) supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. AMD Radeon HD 6450 Graphics supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. AMD Radeon HD 6450A supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. AMD Radeon HD 6450A Graphics supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. AMD Radeon HD 6450M supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon HD 6470M supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon HD 6470M/7400M Series supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon HD 6480G supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon HD 6480M supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon HD 6490M supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon HD 6500 Series supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. AMD Radeon HD 6500 series graphics supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. AMD Radeon HD 6500M Series supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6500M/5600/5700 Series supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6510 Series supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. AMD Radeon HD 6520G supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6530D supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6530D Graphics supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6530M supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6550A supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. AMD Radeon HD 6550D supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6550D Graphics supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6550M supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6570 supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. AMD Radeon HD 6570 (Microsoft Corporation - WDDM v1.2) supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. AMD Radeon HD 6570 (Microsoft Corporation - WDDM v1.20) supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. AMD Radeon HD 6570M supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6570M/5700 Series supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6570M/5730 supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon HD 6600 Series supported 3 1 4.2 ATI Radeon HD 6600
-ATI Technologies Inc. AMD Radeon HD 6600M Series supported 4 0 4.2 ATI Radeon HD 6600D/G/M
-ATI Technologies Inc. AMD Radeon HD 6610M Graphics supported 4 0 4.2 ATI Radeon HD 6600D/G/M
-ATI Technologies Inc. AMD Radeon HD 6620G supported 4 0 4.2 ATI Radeon HD 6600D/G/M
-ATI Technologies Inc. AMD Radeon HD 6625M Graphics supported 4 0 4.2 ATI Radeon HD 6600D/G/M
-ATI Technologies Inc. AMD Radeon HD 6630M supported 4 0 4.2 ATI Radeon HD 6600D/G/M
-ATI Technologies Inc. AMD Radeon HD 6650A Graphics supported 3 1 4.2 ATI Radeon HD 6600
-ATI Technologies Inc. AMD Radeon HD 6650M supported 4 0 4.2 ATI Radeon HD 6600D/G/M
-ATI Technologies Inc. AMD Radeon HD 6670 supported 3 1 4.2 ATI Radeon HD 6600
-ATI Technologies Inc. AMD Radeon HD 6670 (Microsoft Corporation - WDDM v1.2) supported 3 1 4.2 ATI Radeon HD 6600
-ATI Technologies Inc. AMD Radeon HD 6670 (Microsoft Corporation - WDDM v1.20) supported 3 1 4.2 ATI Radeon HD 6600
-ATI Technologies Inc. AMD Radeon HD 6700 Series supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. AMD Radeon HD 6700 series supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. AMD Radeon HD 6700M Series supported 4 0 4.2 ATI Radeon HD 6700D/G/M
-ATI Technologies Inc. AMD Radeon HD 6700M Series (Microsoft Corporation - WDDM v1.20) supported 4 0 4.2 ATI Radeon HD 6700D/G/M
-ATI Technologies Inc. AMD Radeon HD 6700M/7700M/7900M Series supported 4 0 4.2 ATI Radeon HD 6700D/G/M
-ATI Technologies Inc. AMD Radeon HD 6730M supported 4 0 4.2 ATI Radeon HD 6700D/G/M
-ATI Technologies Inc. AMD Radeon HD 6750 supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. AMD Radeon HD 6750M supported 4 0 4.2 ATI Radeon HD 6700D/G/M
-ATI Technologies Inc. AMD Radeon HD 6770 supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. AMD Radeon HD 6770M supported 4 0 4.2 ATI Radeon HD 6700D/G/M
-ATI Technologies Inc. AMD Radeon HD 6770M OpenGL Engine supported 4 0 4.2 ATI Radeon HD 6700D/G/M
-ATI Technologies Inc. AMD Radeon HD 6800 Series supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. AMD Radeon HD 6800 Series (Engineering Sample - WDDM v1.20) supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. AMD Radeon HD 6800 Series (Microsoft Corporation - WDDM v1.2) supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. AMD Radeon HD 6800 Series (Microsoft Corporation - WDDM v1.20) supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. AMD Radeon HD 6800M Series supported 4 0 4.2 ATI Radeon HD 6800D/G/M
-ATI Technologies Inc. AMD Radeon HD 6850 supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. AMD Radeon HD 6850 X2 supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. AMD Radeon HD 6850M supported 4 0 4.2 ATI Radeon HD 6800D/G/M
-ATI Technologies Inc. AMD Radeon HD 6870 supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. AMD Radeon HD 6870M supported 4 0 4.2 ATI Radeon HD 6800D/G/M
-ATI Technologies Inc. AMD Radeon HD 6900 Series supported 5 1 4.2 ATI Radeon HD 6900
-ATI Technologies Inc. AMD Radeon HD 6900 Series (Microsoft Corporation - WDDM v1.2) supported 5 1 4.2 ATI Radeon HD 6900
-ATI Technologies Inc. AMD Radeon HD 6900M Series supported 4 0 4.2 ATI Radeon HD 6900D/G/M
-ATI Technologies Inc. AMD Radeon HD 6970 supported 5 1 4.2 ATI Radeon HD 6900
-ATI Technologies Inc. AMD Radeon HD 6970M supported 4 0 4.2 ATI Radeon HD 6900D/G/M
-ATI Technologies Inc. AMD Radeon HD 6990 supported 5 1 4.2 ATI Radeon HD 6900
-ATI Technologies Inc. AMD Radeon HD 6990M supported 4 0 4.2 ATI Radeon HD 6900D/G/M
-ATI Technologies Inc. AMD Radeon HD 7000 series supported 3 1 4.2 ATI Radeon HD 7000 Series
-ATI Technologies Inc. AMD Radeon HD 7290 Graphics supported 2 0 4.2 ATI Radeon HD 7200
-ATI Technologies Inc. AMD Radeon HD 7300 Series (Microsoft Corporation - WDDM v1.2) supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon HD 7300 Series Graphics supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon HD 7310 supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon HD 7310 Graphics supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon HD 7310 Graphics supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon HD 7310 Graphics (Microsoft Corporation - WDDM v1.2) supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon HD 7310G supported 3 0 4.2 ATI Radeon HD 7300D/G/M
-ATI Technologies Inc. AMD Radeon HD 7310M supported 3 0 4.2 ATI Radeon HD 7300D/G/M
-ATI Technologies Inc. AMD Radeon HD 7340 supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon HD 7340 Graphics supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon HD 7340G supported 3 0 4.2 ATI Radeon HD 7300D/G/M
-ATI Technologies Inc. AMD Radeon HD 7340M supported 3 0 4.2 ATI Radeon HD 7300D/G/M
-ATI Technologies Inc. AMD Radeon HD 7350 supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon HD 7350 Graphics supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon HD 7370M supported 3 0 4.2 ATI Radeon HD 7300D/G/M
-ATI Technologies Inc. AMD Radeon HD 7400 Series supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. AMD Radeon HD 7400 Series (Microsoft Corporation - WDDM v1.2) supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. AMD Radeon HD 7400G supported 3 0 4.2 ATI Radeon HD 7400D/G/M
-ATI Technologies Inc. AMD Radeon HD 7400M Series supported 3 0 4.2 ATI Radeon HD 7400D/G/M
-ATI Technologies Inc. AMD Radeon HD 7400M Series (Microsoft Corporation - WDDM v1.20) supported 3 0 4.2 ATI Radeon HD 7400D/G/M
-ATI Technologies Inc. AMD Radeon HD 7410M supported 3 0 4.2 ATI Radeon HD 7400D/G/M
-ATI Technologies Inc. AMD Radeon HD 7420G supported 3 0 4.2 ATI Radeon HD 7400D/G/M
-ATI Technologies Inc. AMD Radeon HD 7450 supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. AMD Radeon HD 7450 Graphics supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. AMD Radeon HD 7450A Graphics supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. AMD Radeon HD 7450M supported 3 0 4.2 ATI Radeon HD 7400D/G/M
-ATI Technologies Inc. AMD Radeon HD 7470 supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. AMD Radeon HD 7470 Series supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. AMD Radeon HD 7470M supported 3 0 4.2 ATI Radeon HD 7400D/G/M
-ATI Technologies Inc. AMD Radeon HD 7480D supported 3 0 4.2 ATI Radeon HD 7400D/G/M
-ATI Technologies Inc. AMD Radeon HD 7500 Series supported 3 1 4.2 ATI Radeon HD 7500
-ATI Technologies Inc. AMD Radeon HD 7500 Series (Microsoft Corporation - WDDM v1.2) supported 3 1 4.2 ATI Radeon HD 7500
-ATI Technologies Inc. AMD Radeon HD 7500 Series (Microsoft Corporation - WDDM v1.20) supported 3 1 4.2 ATI Radeon HD 7500
-ATI Technologies Inc. AMD Radeon HD 7500/7600 Series supported 3 1 4.2 ATI Radeon HD 7500
-ATI Technologies Inc. AMD Radeon HD 7500G supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7500G + 7500M/7600M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7500M/7600M Series supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7510 supported 3 1 4.2 ATI Radeon HD 7500
-ATI Technologies Inc. AMD Radeon HD 7520G supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7520G + 6400M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7520G + 7470M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7520G + 7500/7600 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7520G + 7600M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7520G + 7610M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7520G + 7670M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7540D supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7540D + 7450 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7550M supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7550M/7650M Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7560D supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7560D (Microsoft Corporation - WDDM v1.20) supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7560D + 6570 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7560D + 6670 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7560D + 7560D Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7560D + 7600 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7560D + 7670 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7570 supported 3 1 4.2 ATI Radeon HD 7500
-ATI Technologies Inc. AMD Radeon HD 7570 Graphics supported 3 1 4.2 ATI Radeon HD 7500
-ATI Technologies Inc. AMD Radeon HD 7570 Series supported 3 1 4.2 ATI Radeon HD 7500
-ATI Technologies Inc. AMD Radeon HD 7570M supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7570M/HD 7670M Graphics supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7580D supported 4 0 4.2 ATI Radeon HD 7500D/G/M
-ATI Technologies Inc. AMD Radeon HD 7600 Series (Microsoft Corporation - WDDM v1.20) supported 3 0 4.2 ATI Radeon HD 7600
-ATI Technologies Inc. AMD Radeon HD 7600G supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7600G + 7500M/7600M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7600G + 7550M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7600M + 7600M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7600M Series supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7610M supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7620G supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7640G supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7640G + 6400M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7640G + 7450M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7640G + 7470M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7640G + 7500/7600 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7640G + 7500M/7600M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7640G + 7600M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7640G + 7610M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7640G + 7670M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7650A supported 3 0 4.2 ATI Radeon HD 7600
-ATI Technologies Inc. AMD Radeon HD 7650A Graphics supported 3 0 4.2 ATI Radeon HD 7600
-ATI Technologies Inc. AMD Radeon HD 7650M supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7650M Series supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660D supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660D + 6570 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660D + 6670 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660D + 7670 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660D + 7700 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660G supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660G + 6400M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660G + 7400M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660G + 7470M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660G + 7500/7600 Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660G + 7600M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660G + 7610M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660G + 7670M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7660G + 7700M Dual Graphics supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7670 supported 3 0 4.2 ATI Radeon HD 7600
-ATI Technologies Inc. AMD Radeon HD 7670M supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7690M supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD 7700 Series supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. AMD Radeon HD 7700 Series (Microsoft Corporation - WDDM v1.3) supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. AMD Radeon HD 7700M Series supported 4 0 4.2 ATI Radeon HD 7700D/G/M
-ATI Technologies Inc. AMD Radeon HD 7730M supported 4 0 4.2 ATI Radeon HD 7700D/G/M
-ATI Technologies Inc. AMD Radeon HD 7770 supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. AMD Radeon HD 7770 GHz Edition supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. AMD Radeon HD 7800 Series supported 5 1 4.2 ATI Radeon HD 7800
-ATI Technologies Inc. AMD Radeon HD 7800 Series (Engineering Sample - WDDM v1.20) supported 5 1 4.2 ATI Radeon HD 7800
-ATI Technologies Inc. AMD Radeon HD 7800 Series (Microsoft Corporation - WDDM v1.20) supported 5 1 4.2 ATI Radeon HD 7800
-ATI Technologies Inc. AMD Radeon HD 7800 Series (Microsoft Corporation - WDDM v1.3) supported 5 1 4.2 ATI Radeon HD 7800
-ATI Technologies Inc. AMD Radeon HD 7800M Series supported 4 0 4.2 ATI Radeon HD 7800D/G/M
-ATI Technologies Inc. AMD Radeon HD 7870 supported 5 1 4.2 ATI Radeon HD 7800
-ATI Technologies Inc. AMD Radeon HD 7870M supported 4 0 4.2 ATI Radeon HD 7800D/G/M
-ATI Technologies Inc. AMD Radeon HD 7900 Series supported 5 1 4.2 ATI Radeon HD 7900
-ATI Technologies Inc. AMD Radeon HD 7900 Series (Microsoft Corporation - WDDM v1.3) supported 5 1 4.2 ATI Radeon HD 7900
-ATI Technologies Inc. AMD Radeon HD 7950 supported 5 1 4.2 ATI Radeon HD 7900
-ATI Technologies Inc. AMD Radeon HD 7970 supported 5 1 4.2 ATI Radeon HD 7900
-ATI Technologies Inc. AMD Radeon HD 7970M supported 4 0 4.2 ATI Radeon HD 7900D/G/M
-ATI Technologies Inc. AMD Radeon HD 8210 supported 2 0 4.2 ATI Radeon HD 8200
-ATI Technologies Inc. AMD Radeon HD 8240 supported 2 0 4.2 ATI Radeon HD 8200
-ATI Technologies Inc. AMD Radeon HD 8250 supported 2 0 4.2 ATI Radeon HD 8200
-ATI Technologies Inc. AMD Radeon HD 8280G supported 3 0 4.2 ATI Radeon HD 8200D/G/M
-ATI Technologies Inc. AMD Radeon HD 8330 supported 2 0 4.2 ATI Radeon HD 8300 (OEM)
-ATI Technologies Inc. AMD Radeon HD 8350 supported 2 0 4.2 ATI Radeon HD 8300 (OEM)
-ATI Technologies Inc. AMD Radeon HD 8350G supported 3 0 4.2 ATI Radeon HD 8300D/G/M
-ATI Technologies Inc. AMD Radeon HD 8400 supported 2 0 4.2 ATI Radeon HD 8400 (OEM)
-ATI Technologies Inc. AMD Radeon HD 8450 supported 2 0 4.2 ATI Radeon HD 8400 (OEM)
-ATI Technologies Inc. AMD Radeon HD 8450G supported 4 0 4.2 ATI Radeon HD 8400D/G/M
-ATI Technologies Inc. AMD Radeon HD 8470 supported 2 0 4.2 ATI Radeon HD 8400 (OEM)
-ATI Technologies Inc. AMD Radeon HD 8470D supported 4 0 4.2 ATI Radeon HD 8400D/G/M
-ATI Technologies Inc. AMD Radeon HD 8550G supported 4 0 4.2 ATI Radeon HD 8500D/G/M
-ATI Technologies Inc. AMD Radeon HD 8570 supported 3 1 4.2 ATI Radeon HD 8500 (OEM)
-ATI Technologies Inc. AMD Radeon HD 8570D supported 4 0 4.2 ATI Radeon HD 8500D/G/M
-ATI Technologies Inc. AMD Radeon HD 8610G supported 4 0 4.2 ATI Radeon HD 8600D/G/M
-ATI Technologies Inc. AMD Radeon HD 8650G supported 4 0 4.2 ATI Radeon HD 8600D/G/M
-ATI Technologies Inc. AMD Radeon HD 8670D supported 4 0 4.2 ATI Radeon HD 8600D/G/M
-ATI Technologies Inc. AMD Radeon HD 8670D + 6670 Dual Graphics supported 4 0 4.2 ATI Radeon HD 8600D/G/M
-ATI Technologies Inc. AMD Radeon HD 8700M Series supported 4 0 4.2 ATI Radeon HD 8700D/G/M
-ATI Technologies Inc. AMD Radeon HD 8730M supported 4 0 4.2 ATI Radeon HD 8700D/G/M
-ATI Technologies Inc. AMD Radeon HD 8750M supported 4 0 4.2 ATI Radeon HD 8700D/G/M
-ATI Technologies Inc. AMD Radeon HD 8760 supported 4 1 4.2 ATI Radeon HD 8700 (OEM)
-ATI Technologies Inc. AMD Radeon HD 8800M Series supported 4 0 4.2 ATI Radeon HD 8800D/G/M
-ATI Technologies Inc. AMD Radeon HD 8900 Series (OEM) supported 5 1 4.2 ATI Radeon HD 8900 (OEM)
-ATI Technologies Inc. AMD Radeon HD 8950 supported 5 1 4.2 ATI Radeon HD 8900 (OEM)
-ATI Technologies Inc. AMD Radeon HD HD7850M supported 4 0 4.2 ATI Radeon HD 7800D/G/M
-ATI Technologies Inc. AMD Radeon HD6370D Graphics supported 3 1 4.2 ATI Radeon HD 6300D/G/M
-ATI Technologies Inc. AMD Radeon HD7610M supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon HD7700 Series supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. AMD Radeon HD7770 supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. AMD Radeon HD7770 GHz Edition supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. AMD Radeon HD8350 supported 2 0 4.2 ATI Radeon HD 8300 (OEM)
-ATI Technologies Inc. AMD Radeon(TM) HD 6380G supported 3 1 4.2 ATI Radeon HD 6300D/G/M
-ATI Technologies Inc. AMD Radeon(TM) HD 6470M supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon(TM) HD 6480G supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon(TM) HD 6480G (Microsoft Corporation - WDDM v1.20) supported 3 0 4.2 ATI Radeon HD 6400D/G/M
-ATI Technologies Inc. AMD Radeon(TM) HD 6520G supported 4 1 4.2 ATI Radeon HD 6500D/G/M
-ATI Technologies Inc. AMD Radeon(TM) HD 6620G supported 4 0 4.2 ATI Radeon HD 6600D/G/M
-ATI Technologies Inc. AMD Radeon(TM) HD 6630M supported 4 0 4.2 ATI Radeon HD 6600D/G/M
-ATI Technologies Inc. AMD Radeon(TM) HD 6650M supported 4 0 4.2 ATI Radeon HD 6600D/G/M
-ATI Technologies Inc. AMD Radeon(TM) HD 7450 supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. AMD Radeon(TM) HD 7450A Graphics supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. AMD Radeon(TM) HD 7650A Graphics supported 3 0 4.2 ATI Radeon HD 7600
-ATI Technologies Inc. AMD Radeon(TM) HD 7670A Graphics supported 3 0 4.2 ATI Radeon HD 7600
-ATI Technologies Inc. AMD Radeon(TM) HD 7670M supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon(TM) HD 8350 supported 2 0 4.2 ATI Radeon HD 8300 (OEM)
-ATI Technologies Inc. AMD Radeon(TM) HD8490 supported 2 0 4.2 ATI Radeon HD 8400 (OEM)
-ATI Technologies Inc. AMD Radeon. HD 7350 supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. AMD Radeon. HD 7670M supported 4 0 4.2 ATI Radeon HD 7600D/G/M
-ATI Technologies Inc. AMD Radeon. HD 7730M supported 4 0 4.2 ATI Radeon HD 7700D/G/M
-ATI Technologies Inc. ASUS AH3450 Series supported 1 1 4 ATI Radeon HD 3400
-ATI Technologies Inc. ASUS AH3650 Series supported 3 1 4 ATI Radeon HD 3600
-ATI Technologies Inc. ASUS AH4650 Series supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ASUS ARES unsupported 0 0 0 ATI ARES
-ATI Technologies Inc. ASUS ARES2 unsupported 0 0 0 ATI ARES
-ATI Technologies Inc. ASUS EAH2400 Series supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ASUS EAH2600 Series supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. ASUS EAH3450 Series supported 1 1 4 ATI Radeon HD 3400
-ATI Technologies Inc. ASUS EAH3650 Series supported 3 1 4 ATI Radeon HD 3600
-ATI Technologies Inc. ASUS EAH3850 Series supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ASUS EAH3870 Series supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ASUS EAH4350 series supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. ASUS EAH4550 series supported 2 1 3.3 ATI Radeon HD 4500
-ATI Technologies Inc. ASUS EAH4650 series supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ASUS EAH4670 series supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ASUS EAH4770 Series supported 3 1 3.3 ATI Radeon HD 4700
-ATI Technologies Inc. ASUS EAH4770 series supported 3 1 3.3 ATI Radeon HD 4700
-ATI Technologies Inc. ASUS EAH4850 series supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ASUS EAH4870 series supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ASUS EAH4870x2 supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ASUS EAH4890 supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ASUS EAH5450 Series supported 3 1 4.2 ATI Radeon HD 5400
-ATI Technologies Inc. ASUS EAH5550 Series supported 3 1 4.2 ATI Radeon HD 5500
-ATI Technologies Inc. ASUS EAH5570 series supported 3 1 4.2 ATI Radeon HD 5500
-ATI Technologies Inc. ASUS EAH5670 Series supported 3 1 4.2 ATI Radeon HD 5600
-ATI Technologies Inc. ASUS EAH5750 Series supported 3 1 4.2 ATI Radeon HD 5700
-ATI Technologies Inc. ASUS EAH5770 Series supported 3 1 4.2 ATI Radeon HD 5700
-ATI Technologies Inc. ASUS EAH5830 Series supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ASUS EAH5850 Series supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ASUS EAH5870 Series supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ASUS EAH6450 Series supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. ASUS EAH6570 Series supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. ASUS EAH6670 Series supported 3 1 4.2 ATI Radeon HD 6600
-ATI Technologies Inc. ASUS EAH6750 Series supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. ASUS EAH6770 Series supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. ASUS EAH6850 Series supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. ASUS EAH6870 Series supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. ASUS EAH6950 Series supported 5 1 4.2 ATI Radeon HD 6900
-ATI Technologies Inc. ASUS EAH6970 Series supported 5 1 4.2 ATI Radeon HD 6900
-ATI Technologies Inc. ASUS Extreme AX300 Series supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. ASUS Extreme AX300SE/T supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. ASUS Extreme AX550 Series supported 3 1 4.2 ATI Radeon HD 5500
-ATI Technologies Inc. ASUS Extreme AX550 Series x86/SSE2 supported 3 1 4.2 ATI Radeon HD 5500
-ATI Technologies Inc. ASUS Extreme AX600 Series supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. ASUS HD 7350 supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. ASUS HD7470 Series supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. ASUS HD7670 Series supported 3 0 4.2 ATI Radeon HD 7600
-ATI Technologies Inc. ASUS HD7750 Series supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. ASUS HD7770 Series supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. ASUS HD7790 Series supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. ASUS HD7850 Series supported 5 1 4.2 ATI Radeon HD 7800
-ATI Technologies Inc. ASUS HD7870 Series supported 5 1 4.2 ATI Radeon HD 7800
-ATI Technologies Inc. ASUS HD7950 Series supported 5 1 4.2 ATI Radeon HD 7900
-ATI Technologies Inc. ASUS HD7970 Series supported 5 1 4.2 ATI Radeon HD 7900
-ATI Technologies Inc. ASUS X1300 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ASUS X1300 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ASUS X1300 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ASUS X1300 x86/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ASUS X1550 Series supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. ASUS X1550 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. ASUS X1550 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. ASUS X1600 Series supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ASUS X1600 Series x86 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ASUS X1600 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ASUS X1600 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ASUS X1650 Series supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ASUS X1650 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ASUS X1650 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ASUS X1950 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. ATI Radeon HD 5000 Series supported 3 1 4.2 ATI Radeon HD 5000
-ATI Technologies Inc. ATI Radeon HD 6350 supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. ATI All-in-Wonder HD supported 1 1 3.3 ATI All-in-Wonder HD
-ATI Technologies Inc. ATI Display Adapter supported 1 1 4.1 ATI Display Adapter
-ATI Technologies Inc. ATI FireGL V3100 supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V3200 Pentium 4 (SSE2) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V3300 supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V3350 supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V3350 Pentium 4 (SSE2) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V3400 (Microsoft Corporation - WDDM) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V3400 Pentium 4 (SSE2) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V3600 supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V5200 (Microsoft Corporation - WDDM) supported 1 1 2.1 ATI FireGL 5200
-ATI Technologies Inc. ATI FireGL V5200 Pentium 4 (SSE2) supported 1 1 2.1 ATI FireGL 5200
-ATI Technologies Inc. ATI FireGL V5600 supported 2 1 3.3 ATI FireGL 5xxx
-ATI Technologies Inc. ATI FireGL V7200 supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V7200 Pentium 4 (SSE2) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V7600 supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireGL V7700 supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FireMV 2250 supported 0 1 3.2 ATI FireMV
-ATI Technologies Inc. ATI FireMV 2250 x86/SSE2 supported 0 1 3.2 ATI FireMV
-ATI Technologies Inc. ATI FirePro 2260 supported 2 1 4.2 ATI FirePro 2000
-ATI Technologies Inc. ATI FirePro 2450 supported 2 1 4.2 ATI FirePro 2000
-ATI Technologies Inc. ATI FirePro 3800 (FireGL) Graphics Adapter supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro M5800 supported 3 0 0 ATI FirePro M5800
-ATI Technologies Inc. ATI FirePro M7740 supported 3 0 0 ATI FirePro M7740
-ATI Technologies Inc. ATI FirePro M7820 supported 5 1 4.2 ATI FirePro M7820
-ATI Technologies Inc. ATI FirePro M7820 (FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V3700 (FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V3800 supported 2 0 0 ATI FirePro 3000
-ATI Technologies Inc. ATI FirePro V3800 (FireGL V) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V3800 (FireGL V) Graphics Adapter supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V3800 (FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V4800 supported 2 0 4.1 ATI FirePro 4000
-ATI Technologies Inc. ATI FirePro V4800 (FireGL V) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V4800 (FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V5700 (FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V5800 (FireGL V) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V5800 (FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V7800 (FireGL V) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V7800 (FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V8700 (FireGL) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI FirePro V9800 (FireGL V) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI MOBILITY FIRE GL T2/T2e supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI MOBILITY FireGL V3200 supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. ATI MOBILITY FireGL V5000 Pentium 4 (SSE2) supported 2 1 3.3 ATI FireGL 5xxx
-ATI Technologies Inc. ATI MOBILITY FireGL V5200 supported 1 1 2.1 ATI FireGL 5200
-ATI Technologies Inc. ATI MOBILITY FireGL V5200 Pentium 4 (SSE2) supported 1 1 2.1 ATI FireGL 5200
-ATI Technologies Inc. ATI MOBILITY FireGL V5250 supported 1 1 2.1 ATI FireGL 5200
-ATI Technologies Inc. ATI MOBILITY RADEON 9600 Series supported 1 1 2.1 ATI Mobility Radeon 9600
-ATI Technologies Inc. ATI MOBILITY RADEON 9600/9700 supported 1 1 2.1 ATI Mobility Radeon 9600
-ATI Technologies Inc. ATI MOBILITY RADEON 9600/9700 Series supported 1 1 2.1 ATI Mobility Radeon 9600
-ATI Technologies Inc. ATI MOBILITY RADEON 9600/9700 Series (Omega 3 supported 1 1 2.1 ATI Mobility Radeon 9600
-ATI Technologies Inc. ATI MOBILITY RADEON HD 2300 supported 0 1 2.1 ATI Mobility Radeon HD 2300
-ATI Technologies Inc. ATI MOBILITY RADEON HD 2400 supported 1 1 3.3 ATI Mobility Radeon HD 2400
-ATI Technologies Inc. ATI MOBILITY RADEON HD 2600 supported 1 1 3.3 ATI Mobility Radeon HD 2600
-ATI Technologies Inc. ATI MOBILITY RADEON HD 3430 supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI MOBILITY RADEON HD 3450 supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI MOBILITY RADEON HD 3650 supported 1 1 4 ATI Mobility Radeon HD 3600
-ATI Technologies Inc. ATI MOBILITY RADEON HD 4530 / 4570 supported 1 1 4 ATI Mobility Radeon HD 4500
-ATI Technologies Inc. ATI MOBILITY RADEON X1300 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ATI MOBILITY RADEON X1350 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ATI MOBILITY RADEON X1400 supported 2 1 2.1 ATI Radeon X1400
-ATI Technologies Inc. ATI MOBILITY RADEON X1600 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ATI MOBILITY RADEON X1700 supported 2 1 2.1 ATI Radeon X1700
-ATI Technologies Inc. ATI MOBILITY RADEON X1800 supported 3 1 2.1 ATI Radeon X1800
-ATI Technologies Inc. ATI MOBILITY RADEON X1900 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. ATI MOBILITY RADEON X2300 supported 2 0 2.1 ATI Mobility Radeon X2300
-ATI Technologies Inc. ATI MOBILITY RADEON X2300 x86/MMX/3DNow!/SSE2 supported 2 0 2.1 ATI Mobility Radeon X2300
-ATI Technologies Inc. ATI MOBILITY RADEON X300 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. ATI MOBILITY RADEON X300 x86/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. ATI MOBILITY RADEON X600 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. ATI MOBILITY RADEON X600 SE supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. ATI MOBILITY RADEON X700 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. ATI MOBILITY RADEON XPRESS 200 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI MOBILITY RADEON XPRESS 200 x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI MOBILITY Radeon HD 4650 supported 2 1 3.3 ATI Mobility Radeon HD 4600
-ATI Technologies Inc. ATI Mobility FireGL V5700 supported 2 1 3.3 ATI FireGL 5xxx
-ATI Technologies Inc. ATI Mobility FireGL V5725 supported 2 1 3.3 ATI FireGL 5xxx
-ATI Technologies Inc. ATI Mobility Radeon 4100 supported 1 1 3.3 ATI Mobility Radeon 4100
-ATI Technologies Inc. ATI Mobility Radeon Graphics NO MATCH
-ATI Technologies Inc. ATI Mobility Radeon HD 2300 supported 0 1 2.1 ATI Mobility Radeon HD 2300
-ATI Technologies Inc. ATI Mobility Radeon HD 2300 x86/SSE2 supported 0 1 2.1 ATI Mobility Radeon HD 2300
-ATI Technologies Inc. ATI Mobility Radeon HD 2400 supported 1 1 3.3 ATI Mobility Radeon HD 2400
-ATI Technologies Inc. ATI Mobility Radeon HD 2400 (Omega 3.8.442) supported 1 1 3.3 ATI Mobility Radeon HD 2400
-ATI Technologies Inc. ATI Mobility Radeon HD 2400 XT supported 1 1 3.3 ATI Mobility Radeon HD 2400
-ATI Technologies Inc. ATI Mobility Radeon HD 2600 supported 1 1 3.3 ATI Mobility Radeon HD 2600
-ATI Technologies Inc. ATI Mobility Radeon HD 2600 XT supported 1 1 3.3 ATI Mobility Radeon HD 2600
-ATI Technologies Inc. ATI Mobility Radeon HD 2600 XT (Microsoft Corporation WDDM 1.1) supported 1 1 3.3 ATI Mobility Radeon HD 2600
-ATI Technologies Inc. ATI Mobility Radeon HD 2700 supported 3 0 0 ATI Mobility Radeon HD 2700
-ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series (Microsoft Corporation WDDM 1.1) supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series (Microsoft Corporation- WDDM v1.1) supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI Mobility Radeon HD 3410 supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI Mobility Radeon HD 3430 supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI Mobility Radeon HD 3430 (Microsoft Corporation- WDDM v1.1) supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI Mobility Radeon HD 3450 supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI Mobility Radeon HD 3470 supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI Mobility Radeon HD 3470 Hybrid X2 supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI Mobility Radeon HD 3470 Series supported 1 1 4 ATI Mobility Radeon HD 3400
-ATI Technologies Inc. ATI Mobility Radeon HD 3650 supported 1 1 4 ATI Mobility Radeon HD 3600
-ATI Technologies Inc. ATI Mobility Radeon HD 3670 supported 1 1 4 ATI Mobility Radeon HD 3600
-ATI Technologies Inc. ATI Mobility Radeon HD 3850 supported 3 1 3.3 ATI Mobility Radeon HD 3800
-ATI Technologies Inc. ATI Mobility Radeon HD 3870 supported 3 1 3.3 ATI Mobility Radeon HD 3800
-ATI Technologies Inc. ATI Mobility Radeon HD 3870 X2 supported 3 1 3.3 ATI Mobility Radeon HD 3800
-ATI Technologies Inc. ATI Mobility Radeon HD 4200 supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4200 Series supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4200 Series (Microsoft Corporation - WDDM v1.1) supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4225 supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4225 Series supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4250 supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4250 Graphics supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4250 Series supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4270 supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4270 Series supported 1 1 4 ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4300 Series supported 1 1 4 ATI Mobility Radeon HD 4300
-ATI Technologies Inc. ATI Mobility Radeon HD 4300/4500 Series supported 1 1 4 ATI Mobility Radeon HD 4300
-ATI Technologies Inc. ATI Mobility Radeon HD 4330 supported 1 1 4 ATI Mobility Radeon HD 4300
-ATI Technologies Inc. ATI Mobility Radeon HD 4330 Series supported 1 1 4 ATI Mobility Radeon HD 4300
-ATI Technologies Inc. ATI Mobility Radeon HD 4350 supported 1 1 4 ATI Mobility Radeon HD 4300
-ATI Technologies Inc. ATI Mobility Radeon HD 4350 Series supported 1 1 4 ATI Mobility Radeon HD 4300
-ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series supported 1 1 4 ATI Mobility Radeon HD 4500
-ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series (Microsoft Corporation - WDDM v1.1) supported 1 1 4 ATI Mobility Radeon HD 4500
-ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series (Microsoft Corporation WDDM 1.1) supported 1 1 4 ATI Mobility Radeon HD 4500
-ATI Technologies Inc. ATI Mobility Radeon HD 4500/5100 Series supported 1 1 4 ATI Mobility Radeon HD 4500
-ATI Technologies Inc. ATI Mobility Radeon HD 4530 supported 1 1 4 ATI Mobility Radeon HD 4500
-ATI Technologies Inc. ATI Mobility Radeon HD 4530 Series supported 1 1 4 ATI Mobility Radeon HD 4500
-ATI Technologies Inc. ATI Mobility Radeon HD 4550 supported 1 1 4 ATI Mobility Radeon HD 4500
-ATI Technologies Inc. ATI Mobility Radeon HD 4570 supported 1 1 4 ATI Mobility Radeon HD 4500
-ATI Technologies Inc. ATI Mobility Radeon HD 4600 Series supported 2 1 3.3 ATI Mobility Radeon HD 4600
-ATI Technologies Inc. ATI Mobility Radeon HD 4650 supported 2 1 3.3 ATI Mobility Radeon HD 4600
-ATI Technologies Inc. ATI Mobility Radeon HD 4650 (Microsoft Corporation - WDDM v1.1) supported 2 1 3.3 ATI Mobility Radeon HD 4600
-ATI Technologies Inc. ATI Mobility Radeon HD 4650 (Microsoft Corporation- WDDM v1.1) supported 2 1 3.3 ATI Mobility Radeon HD 4600
-ATI Technologies Inc. ATI Mobility Radeon HD 4650 Series supported 2 1 3.3 ATI Mobility Radeon HD 4600
-ATI Technologies Inc. ATI Mobility Radeon HD 4670 supported 2 1 3.3 ATI Mobility Radeon HD 4600
-ATI Technologies Inc. ATI Mobility Radeon HD 4670 (Microsoft Corporation - WDDM v1.1) supported 2 1 3.3 ATI Mobility Radeon HD 4600
-ATI Technologies Inc. ATI Mobility Radeon HD 4830 supported 3 1 3.3 ATI Mobility Radeon HD 4800
-ATI Technologies Inc. ATI Mobility Radeon HD 4830 Series supported 3 1 3.3 ATI Mobility Radeon HD 4800
-ATI Technologies Inc. ATI Mobility Radeon HD 4850 supported 3 1 3.3 ATI Mobility Radeon HD 4800
-ATI Technologies Inc. ATI Mobility Radeon HD 4870 supported 3 1 3.3 ATI Mobility Radeon HD 4800
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 supported 1 1 4.2 ATI Mobility Radeon 5000
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series supported 1 1 4.2 ATI Mobility Radeon 5000
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series (Engineering Sample - WDDM v1.20) supported 1 1 4.2 ATI Mobility Radeon 5000
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series (Microsoft Corporation - WDDM v1.2) supported 1 1 4.2 ATI Mobility Radeon 5000
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series (Microsoft Corporation - WDDM v1.20) supported 1 1 4.2 ATI Mobility Radeon 5000
-ATI Technologies Inc. ATI Mobility Radeon HD 5100 supported 3 1 3.2 ATI Mobility Radeon HD 5100
-ATI Technologies Inc. ATI Mobility Radeon HD 5145 supported 3 1 3.2 ATI Mobility Radeon HD 5100
-ATI Technologies Inc. ATI Mobility Radeon HD 5165 supported 3 1 3.2 ATI Mobility Radeon HD 5100
-ATI Technologies Inc. ATI Mobility Radeon HD 530v supported 1 1 3.3 ATI Mobility Radeon HD 530v
-ATI Technologies Inc. ATI Mobility Radeon HD 5400 supported 2 1 4.2 ATI Mobility Radeon HD 5400
-ATI Technologies Inc. ATI Mobility Radeon HD 5400 Series supported 2 1 4.2 ATI Mobility Radeon HD 5400
-ATI Technologies Inc. ATI Mobility Radeon HD 540v supported 1 1 3.3 ATI Mobility Radeon HD 540v
-ATI Technologies Inc. ATI Mobility Radeon HD 5430 supported 2 1 4.2 ATI Mobility Radeon HD 5400
-ATI Technologies Inc. ATI Mobility Radeon HD 5450 supported 2 1 4.2 ATI Mobility Radeon HD 5400
-ATI Technologies Inc. ATI Mobility Radeon HD 5450 Series supported 2 1 4.2 ATI Mobility Radeon HD 5400
-ATI Technologies Inc. ATI Mobility Radeon HD 545v supported 2 1 4 ATI Mobility Radeon HD 545v
-ATI Technologies Inc. ATI Mobility Radeon HD 5470 supported 2 1 4.2 ATI Mobility Radeon HD 5400
-ATI Technologies Inc. ATI Mobility Radeon HD 550v supported 3 1 4 ATI Mobility Radeon HD 550v
-ATI Technologies Inc. ATI Mobility Radeon HD 5570 supported 3 0 4.2 ATI Mobility Radeon HD 5500
-ATI Technologies Inc. ATI Mobility Radeon HD 5600/5700 Series supported 3 1 4.2 ATI Mobility Radeon HD 5600
-ATI Technologies Inc. ATI Mobility Radeon HD 560v supported 3 1 3.2 ATI Mobility Radeon HD 560v
-ATI Technologies Inc. ATI Mobility Radeon HD 5650 supported 3 1 4.2 ATI Mobility Radeon HD 5600
-ATI Technologies Inc. ATI Mobility Radeon HD 565v supported 3 1 3.3 ATI Mobility Radeon HD 565v
-ATI Technologies Inc. ATI Mobility Radeon HD 5700 Series supported 3 1 4.1 ATI Mobility Radeon HD 5700
-ATI Technologies Inc. ATI Mobility Radeon HD 5730 supported 3 1 4.1 ATI Mobility Radeon HD 5700
-ATI Technologies Inc. ATI Mobility Radeon HD 5800 Series supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ATI Mobility Radeon HD 5800 Series (Microsoft Corporation - WDDM v1.20) supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ATI Mobility Radeon HD 5830 Series supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ATI Mobility Radeon HD 5850 supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ATI Mobility Radeon HD 5870 supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ATI Mobility Radeon HD 6370 supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. ATI Mobility Radeon HD 6550 supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. ATI Mobility Radeon HD 6570 supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. ATI Mobility Radeon X1300 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ATI Mobility Radeon X1300 (Omega 3.8.252) x86/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ATI Mobility Radeon X1300 x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ATI Mobility Radeon X1300 x86/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ATI Mobility Radeon X1350 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ATI Mobility Radeon X1350 x86/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ATI Mobility Radeon X1400 supported 2 1 2.1 ATI Radeon X1400
-ATI Technologies Inc. ATI Mobility Radeon X1400 (Omega 3.8.442) supported 2 1 2.1 ATI Radeon X1400
-ATI Technologies Inc. ATI Mobility Radeon X1400 x86 supported 2 1 2.1 ATI Radeon X1400
-ATI Technologies Inc. ATI Mobility Radeon X1400 x86/SSE2 supported 2 1 2.1 ATI Radeon X1400
-ATI Technologies Inc. ATI Mobility Radeon X1450 x86/SSE2 supported 2 1 2.1 ATI Radeon X1400
-ATI Technologies Inc. ATI Mobility Radeon X1600 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ATI Mobility Radeon X1600 x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ATI Mobility Radeon X1600 x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ATI Mobility Radeon X1700 supported 2 1 2.1 ATI Radeon X1700
-ATI Technologies Inc. ATI Mobility Radeon X1700 x86 supported 2 1 2.1 ATI Radeon X1700
-ATI Technologies Inc. ATI Mobility Radeon X1700 x86/SSE2 supported 2 1 2.1 ATI Radeon X1700
-ATI Technologies Inc. ATI Mobility Radeon X1800 x86/SSE2 supported 3 1 2.1 ATI Radeon X1800
-ATI Technologies Inc. ATI Mobility Radeon X1900 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. ATI Mobility Radeon X2300 supported 2 0 2.1 ATI Mobility Radeon X2300
-ATI Technologies Inc. ATI Mobility Radeon X2300 x86/MMX/3DNow! supported 2 0 2.1 ATI Mobility Radeon X2300
-ATI Technologies Inc. ATI Mobility Radeon X2300 x86/MMX/3DNow!/SSE2 supported 2 0 2.1 ATI Mobility Radeon X2300
-ATI Technologies Inc. ATI Mobility Radeon X2300 x86/SSE2 supported 2 0 2.1 ATI Mobility Radeon X2300
-ATI Technologies Inc. ATI Mobility Radeon X2500 supported 2 0 2.1 ATI Mobility Radeon X2500
-ATI Technologies Inc. ATI Mobility Radeon. HD 530v supported 1 1 3.3 ATI Mobility Radeon HD 530v
-ATI Technologies Inc. ATI Mobility Radeon. HD 5470 supported 2 1 4.2 ATI Mobility Radeon HD 5400
-ATI Technologies Inc. ATI RADEON 9600 Series supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. ATI RADEON 9600/X1050 Series supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. ATI RADEON E4690 supported 3 1 4 ATI RADEON E4690
-ATI Technologies Inc. ATI RADEON HD 3200 Graphics supported 1 1 4 ATI Radeon HD 3200
-ATI Technologies Inc. ATI RADEON XPRESS 1100 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 1100 Series supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 1100 x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 1200 Series supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 200 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 200 Series supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 200 Series x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 200 x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 200M SERIES supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 200M Series supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 200M Series (Microsoft Corporation) supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 200M Series (Omega 3.8.421) x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI RADEON XPRESS 200M Series x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon 2100 supported 0 1 2.1 ATI Radeon 2100
-ATI Technologies Inc. ATI Radeon 2100 (Microsoft Corporation - WDDM) supported 0 1 2.1 ATI Radeon 2100
-ATI Technologies Inc. ATI Radeon 2100 Graphics supported 0 1 2.1 ATI Radeon 2100
-ATI Technologies Inc. ATI Radeon 3000 supported 1 1 4 ATI Radeon 3000
-ATI Technologies Inc. ATI Radeon 3000 Graphics supported 1 1 4 ATI Radeon 3000
-ATI Technologies Inc. ATI Radeon 3000 Graphics (Engineering Sample - WDDM v1.1) supported 1 1 4 ATI Radeon 3000
-ATI Technologies Inc. ATI Radeon 3000 Series Graphics supported 1 1 4 ATI Radeon 3000
-ATI Technologies Inc. ATI Radeon 3100 Graphics supported 0 1 3.3 ATI Radeon 3100
-ATI Technologies Inc. ATI Radeon 3100 Graphics (Microsoft Corporation WDDM 1.1) supported 0 1 3.3 ATI Radeon 3100
-ATI Technologies Inc. ATI Radeon 3100 Series Graphics supported 0 1 3.3 ATI Radeon 3100
-ATI Technologies Inc. ATI Radeon 9550 / X1050 supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. ATI Radeon 9550 / X1050 Series supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. ATI Radeon 9550 / X1050 Series x86/SSE2 supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. ATI Radeon 9550 / X1050 Series(Microsoft Corporation - WDDM) supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. ATI Radeon 9600 / X1050 Series supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. ATI Radeon 9600 / X1050 Series x86/SSE2 supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. ATI Radeon 9600/9550/X1050 Series supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. ATI Radeon BA Prototype OpenGL Engine supported 3 1 2.1 AMD BA (HD 6800)
-ATI Technologies Inc. ATI Radeon Barts PRO Prototype OpenGL Engine supported 3 1 2.1 AMD BARTS (HD 6800)
-ATI Technologies Inc. ATI Radeon Barts XT Prototype OpenGL Engine supported 3 1 2.1 AMD BARTS (HD 6800)
-ATI Technologies Inc. ATI Radeon Caicos PRO Prototype OpenGL Engine supported 3 0 0 AMD CAICOS (HD 6400)
-ATI Technologies Inc. ATI Radeon Caicos Unknown Prototype OpenGL Engine supported 3 0 0 AMD CAICOS (HD 6400)
-ATI Technologies Inc. ATI Radeon Cedar PRO Prototype OpenGL Engine supported 2 0 2.1 AMD CEDAR (HD 5450)
-ATI Technologies Inc. ATI Radeon Graphics Processor NO MATCH
-ATI Technologies Inc. ATI Radeon HD 2350 supported 0 1 3.3 ATI Radeon HD 2300
-ATI Technologies Inc. ATI Radeon HD 2400 supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2400 OpenGL Engine supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2400 PCI supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2400 PRO supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2400 PRO AGP supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2400 Pro supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2400 Series supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2400 Series AGP supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2400 XT supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2400 XT OpenGL Engine supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2600 OpenGL Engine supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. ATI Radeon HD 2600 PRO supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. ATI Radeon HD 2600 PRO OpenGL Engine supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. ATI Radeon HD 2600 Pro supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. ATI Radeon HD 2600 Pro AGP supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. ATI Radeon HD 2600 Series supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. ATI Radeon HD 2600 Series AGP supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. ATI Radeon HD 2600 XT supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. ATI Radeon HD 2600/3600 Series supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. ATI Radeon HD 2900 GT supported 3 1 3.3 ATI Radeon HD 2900
-ATI Technologies Inc. ATI Radeon HD 2900 PRO supported 3 1 3.3 ATI Radeon HD 2900
-ATI Technologies Inc. ATI Radeon HD 2900 XT supported 3 1 3.3 ATI Radeon HD 2900
-ATI Technologies Inc. ATI Radeon HD 3200 Graphics supported 1 1 4 ATI Radeon HD 3200
-ATI Technologies Inc. ATI Radeon HD 3200 Graphics (Microsoft Corporation - WDDM v1.1) supported 1 1 4 ATI Radeon HD 3200
-ATI Technologies Inc. ATI Radeon HD 3200 Graphics (Microsoft Corporation WDDM 1.1) supported 1 1 4 ATI Radeon HD 3200
-ATI Technologies Inc. ATI Radeon HD 3300 Graphics supported 1 1 3.3 ATI Radeon HD 3300
-ATI Technologies Inc. ATI Radeon HD 3400 Series supported 1 1 4 ATI Radeon HD 3400
-ATI Technologies Inc. ATI Radeon HD 3450 supported 1 1 4 ATI Radeon HD 3400
-ATI Technologies Inc. ATI Radeon HD 3450 - Dell Optiplex supported 1 1 4 ATI Radeon HD 3400
-ATI Technologies Inc. ATI Radeon HD 3450 AGP supported 1 1 4 ATI Radeon HD 3400
-ATI Technologies Inc. ATI Radeon HD 3470 supported 1 1 4 ATI Radeon HD 3400
-ATI Technologies Inc. ATI Radeon HD 3470 - Dell Optiplex supported 1 1 4 ATI Radeon HD 3400
-ATI Technologies Inc. ATI Radeon HD 3600 Series supported 3 1 4 ATI Radeon HD 3600
-ATI Technologies Inc. ATI Radeon HD 3600 Series (Microsoft Corporation - WDDM v1.1) supported 3 1 4 ATI Radeon HD 3600
-ATI Technologies Inc. ATI Radeon HD 3600 Series (Microsoft Corporation WDDM 1.1) supported 3 1 4 ATI Radeon HD 3600
-ATI Technologies Inc. ATI Radeon HD 3650 supported 3 1 4 ATI Radeon HD 3600
-ATI Technologies Inc. ATI Radeon HD 3650 AGP supported 3 1 4 ATI Radeon HD 3600
-ATI Technologies Inc. ATI Radeon HD 3800 Series supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ATI Radeon HD 3850 supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ATI Radeon HD 3850 (Microsoft Corporation - WDDM v1.1) supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ATI Radeon HD 3850 AGP supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ATI Radeon HD 3870 supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ATI Radeon HD 3870 (Engineering Sample - WDDM v1.1) supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ATI Radeon HD 3870 (Microsoft Corporation - WDDM v1.1) supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ATI Radeon HD 3870 OpenGL Engine supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ATI Radeon HD 3870 X2 supported 3 1 4 ATI Radeon HD 3800
-ATI Technologies Inc. ATI Radeon HD 4200 supported 1 1 4 ATI Radeon HD 4200
-ATI Technologies Inc. ATI Radeon HD 4200 (Microsoft Corporation - WDDM v1.1) supported 1 1 4 ATI Radeon HD 4200
-ATI Technologies Inc. ATI Radeon HD 4250 supported 1 1 4 ATI Radeon HD 4200
-ATI Technologies Inc. ATI Radeon HD 4250 (Engineering Sample - WDDM v1.1) supported 1 1 4 ATI Radeon HD 4200
-ATI Technologies Inc. ATI Radeon HD 4250 (Microsoft Corporation - WDDM v1.1) supported 1 1 4 ATI Radeon HD 4200
-ATI Technologies Inc. ATI Radeon HD 4250 Graphics supported 1 1 4 ATI Radeon HD 4200
-ATI Technologies Inc. ATI Radeon HD 4270 supported 1 1 4 ATI Radeon HD 4200
-ATI Technologies Inc. ATI Radeon HD 4290 supported 1 1 4 ATI Radeon HD 4200
-ATI Technologies Inc. ATI Radeon HD 4300 Series supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. ATI Radeon HD 4300/4500 Series supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. ATI Radeon HD 4300/4500 Series (Microsoft Corporation - WDDM v1.1) supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. ATI Radeon HD 4300/4500 Series (Microsoft Corporation- WDDM v1.1) supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. ATI Radeon HD 4350 supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. ATI Radeon HD 4350 (Microsoft Corporation WDDM 1.1) supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. ATI Radeon HD 4450 supported 2 0 0 ATI Radeon HD 4400
-ATI Technologies Inc. ATI Radeon HD 4500 Series supported 2 1 3.3 ATI Radeon HD 4500
-ATI Technologies Inc. ATI Radeon HD 4520 supported 2 1 3.3 ATI Radeon HD 4500
-ATI Technologies Inc. ATI Radeon HD 4550 supported 2 1 3.3 ATI Radeon HD 4500
-ATI Technologies Inc. ATI Radeon HD 4550 (Microsoft Corporation - WDDM v1.1) supported 2 1 3.3 ATI Radeon HD 4500
-ATI Technologies Inc. ATI Radeon HD 4570 supported 2 1 3.3 ATI Radeon HD 4500
-ATI Technologies Inc. ATI Radeon HD 4580 supported 2 1 3.3 ATI Radeon HD 4500
-ATI Technologies Inc. ATI Radeon HD 4590 supported 2 1 3.3 ATI Radeon HD 4500
-ATI Technologies Inc. ATI Radeon HD 4600 Series supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ATI Radeon HD 4600 Series (Engineering Sample - WDDM v1.1) supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ATI Radeon HD 4600 Series (Microsoft Corporation - WDDM v1.1) supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ATI Radeon HD 4600-serie (Microsoft Corporation - WDDM v1.1) supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ATI Radeon HD 4650 supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ATI Radeon HD 4650 (Microsoft Corporation WDDM 1.1) supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ATI Radeon HD 4670 supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ATI Radeon HD 4670 OpenGL Engine supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ATI Radeon HD 4700 supported 3 1 3.3 ATI Radeon HD 4700
-ATI Technologies Inc. ATI Radeon HD 4700 Series supported 3 1 3.3 ATI Radeon HD 4700
-ATI Technologies Inc. ATI Radeon HD 4720 supported 3 1 3.3 ATI Radeon HD 4700
-ATI Technologies Inc. ATI Radeon HD 4730 supported 3 1 3.3 ATI Radeon HD 4700
-ATI Technologies Inc. ATI Radeon HD 4730 Series supported 3 1 3.3 ATI Radeon HD 4700
-ATI Technologies Inc. ATI Radeon HD 4770 supported 3 1 3.3 ATI Radeon HD 4700
-ATI Technologies Inc. ATI Radeon HD 4800 supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4800 Series supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4800 Series (Microsoft Corporation - WDDM v1.1) supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4810 series supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4830 supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4850 supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4850 OpenGL Engine supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4850 PRO OpenGL Engine supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4850 Series supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4850 X2 supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4870 supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4870 OpenGL Engine supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4870 Series supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4870 X2 supported 3 1 4 ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 5400 Series supported 3 1 4.2 ATI Radeon HD 5400
-ATI Technologies Inc. ATI Radeon HD 5450 supported 3 1 4.2 ATI Radeon HD 5400
-ATI Technologies Inc. ATI Radeon HD 5450 (Microsoft Corporation - WDDM v1.20) supported 3 1 4.2 ATI Radeon HD 5400
-ATI Technologies Inc. ATI Radeon HD 5470 supported 3 1 4.2 ATI Radeon HD 5400
-ATI Technologies Inc. ATI Radeon HD 5500 supported 3 1 4.2 ATI Radeon HD 5500
-ATI Technologies Inc. ATI Radeon HD 5500 Series supported 3 1 4.2 ATI Radeon HD 5500
-ATI Technologies Inc. ATI Radeon HD 5530 supported 3 1 4.2 ATI Radeon HD 5500
-ATI Technologies Inc. ATI Radeon HD 5570 supported 3 1 4.2 ATI Radeon HD 5500
-ATI Technologies Inc. ATI Radeon HD 5600 Series supported 3 1 4.2 ATI Radeon HD 5600
-ATI Technologies Inc. ATI Radeon HD 5600/5700 supported 3 1 4.2 ATI Radeon HD 5600
-ATI Technologies Inc. ATI Radeon HD 5630 supported 3 1 4.2 ATI Radeon HD 5600
-ATI Technologies Inc. ATI Radeon HD 5670 supported 3 1 4.2 ATI Radeon HD 5600
-ATI Technologies Inc. ATI Radeon HD 5670 OpenGL Engine supported 3 1 4.2 ATI Radeon HD 5600
-ATI Technologies Inc. ATI Radeon HD 5700 Series supported 3 1 4.2 ATI Radeon HD 5700
-ATI Technologies Inc. ATI Radeon HD 5700 Series (Microsoft Corporation - WDDM v1.2) supported 3 1 4.2 ATI Radeon HD 5700
-ATI Technologies Inc. ATI Radeon HD 5700 Series (Microsoft Corporation - WDDM v1.20) supported 3 1 4.2 ATI Radeon HD 5700
-ATI Technologies Inc. ATI Radeon HD 5750 supported 3 1 4.2 ATI Radeon HD 5700
-ATI Technologies Inc. ATI Radeon HD 5750 OpenGL Engine supported 3 1 4.2 ATI Radeon HD 5700
-ATI Technologies Inc. ATI Radeon HD 5750 Series supported 3 1 4.2 ATI Radeon HD 5700
-ATI Technologies Inc. ATI Radeon HD 5770 supported 3 1 4.2 ATI Radeon HD 5700
-ATI Technologies Inc. ATI Radeon HD 5770 OpenGL Engine supported 3 1 4.2 ATI Radeon HD 5700
-ATI Technologies Inc. ATI Radeon HD 5800 Series supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ATI Radeon HD 5850 supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ATI Radeon HD 5870 supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ATI Radeon HD 5870 OpenGL Engine supported 4 1 4.2 ATI Radeon HD 5800
-ATI Technologies Inc. ATI Radeon HD 5900 Series supported 4 1 4.2 ATI Radeon HD 5900
-ATI Technologies Inc. ATI Radeon HD 5970 supported 4 1 4.2 ATI Radeon HD 5900
-ATI Technologies Inc. ATI Radeon HD 6230 supported 0 1 4.2 ATI Radeon HD 6200
-ATI Technologies Inc. ATI Radeon HD 6290 supported 0 1 4.2 ATI Radeon HD 6200
-ATI Technologies Inc. ATI Radeon HD 6350 supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. ATI Radeon HD 6390 supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. ATI Radeon HD 6490 supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. ATI Radeon HD 6490M OpenGL Engine supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. ATI Radeon HD 6510 supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. ATI Radeon HD 6570M supported 3 1 4.2 ATI Radeon HD 6500
-ATI Technologies Inc. ATI Radeon HD 6630M OpenGL Engine supported 3 1 4.2 ATI Radeon HD 6600
-ATI Technologies Inc. ATI Radeon HD 6750M OpenGL Engine supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. ATI Radeon HD 6770 supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. ATI Radeon HD 6770M OpenGL Engine supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. ATI Radeon HD 6970M OpenGL Engine supported 5 1 4.2 ATI Radeon HD 6900
-ATI Technologies Inc. ATI Radeon HD 7350 supported 2 0 4.2 ATI Radeon HD 7300
-ATI Technologies Inc. ATI Radeon HD 7950 OpenGL Engine supported 5 1 4.2 ATI Radeon HD 7900
-ATI Technologies Inc. ATI Radeon HD Pitcairn XT Prototype OpenGL Engine supported 3 0 2.1 AMD PITCAIRN (HD 7870)
-ATI Technologies Inc. ATI Radeon HD Tahiti XT Prototype OpenGL Engine supported 3 0 2.1 AMD TAHITI (HD 7000)
-ATI Technologies Inc. ATI Radeon HD Verde XT Prototype OpenGL Engine unsupported 0 0 0 ATI Radeon VE
-ATI Technologies Inc. ATI Radeon HD3750 supported 3 0 3.3 ATI Radeon HD 3700
-ATI Technologies Inc. ATI Radeon HD4300/HD4500 series supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. ATI Radeon HD4650 supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ATI Radeon HD4670 supported 3 1 4 ATI Radeon HD 4600
-ATI Technologies Inc. ATI Radeon RV730 Prototype OpenGL Engine supported 3 0 1.4 AMD RV730 (HD 4600)
-ATI Technologies Inc. ATI Radeon RV790 Prototype OpenGL Engine supported 3 0 0 AMD RV790 (HD 4800)
-ATI Technologies Inc. ATI Radeon Redwood XT Prototype OpenGL Engine supported 3 0 1.4 AMD REDWOOD (HD 5500/5600)
-ATI Technologies Inc. ATI Radeon Turks PRO Prototype OpenGL Engine supported 3 0 2.1 AMD TURKS (HD 6500/6600)
-ATI Technologies Inc. ATI Radeon Turks XT Prototype OpenGL Engine supported 3 0 2.1 AMD TURKS (HD 6500/6600)
-ATI Technologies Inc. ATI Radeon X1050 supported 2 0 2.1 ATI Radeon X1000
-ATI Technologies Inc. ATI Radeon X1050 Series supported 2 0 2.1 ATI Radeon X1000
-ATI Technologies Inc. ATI Radeon X1050 x86/MMX/3DNow!/SSE2 supported 2 0 2.1 ATI Radeon X1000
-ATI Technologies Inc. ATI Radeon X1050 x86/SSE2 supported 2 0 2.1 ATI Radeon X1000
-ATI Technologies Inc. ATI Radeon X1200 supported 2 0 2.1 ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1200 Series supported 2 0 2.1 ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1200 Series (Microsoft Corporation - WDDM) supported 2 0 2.1 ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1200 Series x86/MMX/3DNow!/SSE2 supported 2 0 2.1 ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1200 x86/MMX/3DNow!/SSE2 supported 2 0 2.1 ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1250 supported 2 0 2.1 ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1250 x86/MMX/3DNow!/SSE2 supported 2 0 2.1 ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1270 supported 2 0 2.1 ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1270 x86/MMX/3DNow!/SSE2 supported 2 0 2.1 ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1300 / X1550 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ATI Radeon X1300/X1550 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. ATI Radeon X1550 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. ATI Radeon X1550 Series supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. ATI Radeon X1550 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. ATI Radeon X1550 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. ATI Radeon X1550 x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. ATI Radeon X1550 x86/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. ATI Radeon X1600 OpenGL Engine supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. ATI Radeon X1900 OpenGL Engine supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. ATI Radeon X1950 GT supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. ATI Radeon X1950 GT x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. ATI Radeon X1950 GT x86/SSE2 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. ATI Radeon X300/X550/X1050 Series supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. ATI Radeon X600/X550/X1050 Series supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. ATI Radeon Xpress 1100 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1100 x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1150 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1150 Series supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1150 x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1200 Series supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1200 Series (Microsoft Corporation - WDDM) supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1200 Series x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1200 x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1250 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1250 x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1250 x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress 1270 x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress Series supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ATI Radeon Xpress Series x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. All-in-Wonder 2006 PCI-E Edition supported 1 0 0 ATI All-in-Wonder PCI-E
-ATI Technologies Inc. All-in-Wonder 2006 PCI-E Edition x86/MMX/3DNow!/SSE2 supported 1 0 0 ATI All-in-Wonder PCI-E
-ATI Technologies Inc. Diamond Radeon X1550 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Diamond Radeon X1550 Series supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Diamond Radeon X1550 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Diamond Radeon X1550 x86/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Diamond X1600 PRO 512MB PCI-E x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. FireGL V3100 Pentium 4 (SSE2) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. FireGL V3200 Pentium 4 (SSE2) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. FireGL X1-128 supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. FireMV 2400 PCI DDR x86 supported 0 1 3.2 ATI FireMV
-ATI Technologies Inc. FireMV 2400 PCI DDR x86/SSE2 supported 0 1 3.2 ATI FireMV
-ATI Technologies Inc. FirePro M3900 Mobility Professional Graphics supported 2 0 4.1 ATI FirePro M3900
-ATI Technologies Inc. GIGABYTE RADEON 9600 PRO supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. GIGABYTE Radeon X1300 Pro supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. GIGABYTE Radeon X1300 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. GIGABYTE Radeon X1600 PRO supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. GeCube RADEON 9600XT supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. GeCube RADEON X550 x86/SSE2 supported 1 1 2.1 ATI Radeon X500
-ATI Technologies Inc. GeCube RADEON X700 Series supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. GeCube Radeon X1550 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. GeCube Radeon X1550 Series supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. GeForce 9600 GT x86/SSE2 unsupported 0 0 0 ATI GeForce Lulz
-ATI Technologies Inc. GigaByte Radeon X1050 supported 2 0 2.1 ATI Radeon X1000
-ATI Technologies Inc. Gigabyte RADEON X300 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. Gigabyte RADEON X300 SE supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. Gigabyte RADEON X300 x86/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. HD3730 supported 3 0 3.3 ATI HD3700
-ATI Technologies Inc. HIGHTECH EXCALIBUR RADEON 9550SE Series supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. HIGHTECH EXCALIBUR RADEON 9550SE Series x86/SSE2 supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. HIGHTECH RADEON 9600XT supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. HIS Radeon X1550 x86/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. M52 x86 supported 1 0 0 ATI M52
-ATI Technologies Inc. M72-M supported 1 0 0 ATI M72
-ATI Technologies Inc. MEDION RADEON 9600 TX supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. MEDION RADEON X740XL x86/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. MOBILITY FIREGL T2 Pentium 4 (SSE2) supported 4 1 4.2 ATI FireGL
-ATI Technologies Inc. MOBILITY RADEON 7000 IGP DDR x86/SSE2 supported 0 1 1.3 ATI Mobility Radeon 7xxx
-ATI Technologies Inc. MOBILITY RADEON 7500 DDR x86/SSE2 supported 0 1 1.3 ATI Mobility Radeon 7xxx
-ATI Technologies Inc. MOBILITY RADEON 9000 DDR x86 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. MOBILITY RADEON 9000 DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. MOBILITY RADEON 9000 IGPRADEON 9100 IGP DDR x86 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. MOBILITY RADEON 9000 IGPRADEON 9100 IGP DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. MOBILITY RADEON 9000/9100 IGP Series DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. MOBILITY RADEON 9000/9100 PRO IGP Series DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. MOBILITY RADEON 9200 DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. MOBILITY RADEON 9600 x86 supported 1 1 2.1 ATI Mobility Radeon 9600
-ATI Technologies Inc. MOBILITY RADEON 9600 x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Mobility Radeon 9600
-ATI Technologies Inc. MOBILITY RADEON 9600 x86/SSE2 supported 1 1 2.1 ATI Mobility Radeon 9600
-ATI Technologies Inc. MOBILITY RADEON 9700 x86 supported 0 1 2.1 ATI Mobility Radeon 9700
-ATI Technologies Inc. MOBILITY RADEON 9700 x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Mobility Radeon 9700
-ATI Technologies Inc. MOBILITY RADEON 9700 x86/SSE2 supported 0 1 2.1 ATI Mobility Radeon 9700
-ATI Technologies Inc. MOBILITY RADEON 9800 x86/SSE2 supported 1 0 0 ATI Mobility Radeon 9800
-ATI Technologies Inc. MOBILITY RADEON X300 x86 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. MOBILITY RADEON X300 x86/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. MOBILITY RADEON X600 SE x86/SSE2 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. MOBILITY RADEON X600 x86 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. MOBILITY RADEON X600 x86/SSE2 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. MOBILITY RADEON X700 SE x86/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. MOBILITY RADEON X700 x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. MOBILITY RADEON X700 x86/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. MOBILITY RADEON Xpress 200 Series SW TCL x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. MOBILITY/RADEON 9000 DDR x86/MMX/3DNow!/SSE2 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. MOBILITY/RADEON 9000 DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. MOBILITY/RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. MOBILITY/RADEON 9250/9200 Series DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. MSI RX9550SE x86/MMX/3DNow!/SSE supported 1 0 0 ATI Radeon RX9550
-ATI Technologies Inc. MSI Radeon X1550 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Mobility Radeon X2300 HD supported 2 0 2.1 ATI Mobility Radeon X2300
-ATI Technologies Inc. Mobility Radeon X2300 HD x86/SSE2 supported 2 0 2.1 ATI Mobility Radeon X2300
-ATI Technologies Inc. RADEON 7000 DDR x86/MMX/3DNow!/SSE2 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. RADEON 7000 DDR x86/SSE2 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. RADEON 7000 SDR x86 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. RADEON 7000 SW TCL x86/SSE2 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. RADEON 7200 DDR x86/MMX/3DNow!/SSE2 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. RADEON 7200 DDR x86/SSE2 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. RADEON 7200 SDR x86/SSE2 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. RADEON 7500 DDR x86/SSE2 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. RADEON 8500 DDR x86/MMX/3DNow!/SSE2 supported 0 0 0 ATI Radeon 8xxx
-ATI Technologies Inc. RADEON 8500 DDR x86/SSE2 supported 0 0 0 ATI Radeon 8xxx
-ATI Technologies Inc. RADEON 9000 DDR x86/MMX/3DNow!/SSE2 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. RADEON 9000 DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. RADEON 9000 PRO DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. RADEON 9000 XT IGPRADEON 9100 XT IGP DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9000
-ATI Technologies Inc. RADEON 9100 DDR x86/MMX/3DNow!/SSE2 supported 0 0 0 ATI Radeon 9100
-ATI Technologies Inc. RADEON 9100 DDR x86/SSE2 supported 0 0 0 ATI Radeon 9100
-ATI Technologies Inc. RADEON 9100 IGP DDR x86 supported 0 0 0 ATI Radeon 9100
-ATI Technologies Inc. RADEON 9100 IGP DDR x86/SSE2 supported 0 0 0 ATI Radeon 9100
-ATI Technologies Inc. RADEON 9200 DDR x86/MMX/3DNow!/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9200 DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9200 LE DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9200 PRO DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9200 Series DDR x86 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow! supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9200SE DDR x86/MMX/3DNow!/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9200SE DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9250/9000 Series DDR x86/MMX/3DNow!/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. RADEON 9500 supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. RADEON 9500 PRO / 9700 supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. RADEON 9550 supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. RADEON 9550 x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. RADEON 9550 x86/SSE2 supported 0 1 2.1 ATI Radeon 9500
-ATI Technologies Inc. RADEON 9600 SERIES supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. RADEON 9600 TX supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. RADEON 9600 TX x86/SSE2 supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. RADEON 9600 XT x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. RADEON 9600 XT x86/SSE2 supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. RADEON 9600 x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. RADEON 9600 x86/SSE2 supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. RADEON 9600SE x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. RADEON 9600SE x86/SSE2 supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. RADEON 9700 PRO supported 1 0 0 ATI Radeon 9700
-ATI Technologies Inc. RADEON 9800 PRO supported 1 1 2.1 ATI Radeon 9800
-ATI Technologies Inc. RADEON 9800 PRO (Microsoft Corporation - WDDM) supported 1 1 2.1 ATI Radeon 9800
-ATI Technologies Inc. RADEON 9800 PRO - Secondary supported 1 1 2.1 ATI Radeon 9800
-ATI Technologies Inc. RADEON 9800 Pro x86/SSE2 supported 1 1 2.1 ATI Radeon 9800
-ATI Technologies Inc. RADEON 9800 SERIES supported 1 1 2.1 ATI Radeon 9800
-ATI Technologies Inc. RADEON 9800 XT supported 1 1 2.1 ATI Radeon 9800
-ATI Technologies Inc. RADEON 9800 XT x86/SSE2 supported 1 1 2.1 ATI Radeon 9800
-ATI Technologies Inc. RADEON 9800 x86/SSE2 supported 1 1 2.1 ATI Radeon 9800
-ATI Technologies Inc. RADEON IGP 340M DDR x86/SSE2 unsupported 0 0 1.3 ATI IGP 340M
-ATI Technologies Inc. RADEON Radeon X300/X550/X1050 Series x86/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. RADEON X1600 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. RADEON X1600 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. RADEON X300 SE 128MB HyperMemory x86/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. RADEON X300 SE x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. RADEON X300 Series supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. RADEON X300 Series x86/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. RADEON X300 x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. RADEON X300 x86/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. RADEON X300/X550 Series x86 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. RADEON X300/X550 Series x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. RADEON X300/X550 Series x86/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. RADEON X550 x86/MMX/3DNow! supported 1 1 2.1 ATI Radeon X500
-ATI Technologies Inc. RADEON X550 x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Radeon X500
-ATI Technologies Inc. RADEON X550 x86/SSE2 supported 1 1 2.1 ATI Radeon X500
-ATI Technologies Inc. RADEON X550XT supported 1 1 2.1 ATI Radeon X500
-ATI Technologies Inc. RADEON X600 256MB HyperMemory x86/SSE2 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X600 PRO x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X600 PRO x86/SSE2 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X600 SE x86/SSE2 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X600 Series supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X600 x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X600 x86/SSE2 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X600/X550 Series supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X600/X550 Series (Microsoft Corporation - WDDM) supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X600/X550 Series Secondary supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X600/X550 Series x86/SSE2 supported 1 1 2.1 ATI Radeon X600
-ATI Technologies Inc. RADEON X700 PRO x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. RADEON X700 PRO x86/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. RADEON X700 SE supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. RADEON X700 SE x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. RADEON X700 SE x86/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. RADEON X700 Series supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. RADEON X700 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. RADEON X700 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. RADEON X700 x86/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. RADEON X700/X550 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X700
-ATI Technologies Inc. RADEON X800 GT x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 GTO supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 GTO x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 GTO x86/SSE2 supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 PRO/GTO supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 SE x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 SE x86/SSE2 supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 Series supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 XL x86/MMX/3DNow!/SSE2 supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 XL x86/SSE2 supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 XT supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 XT (Microsoft Corporation - WDDM) supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800 XT x86/SSE2 supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800/X850 Series supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X800GT supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X850 Series supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X850 XT Platinum Edition (Microsoft Corporation - WDDM) supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X850 XT Platinum Edition x86/SSE2 supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON X850 XT x86/SSE2 supported 1 1 2.1 ATI Radeon X800
-ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/MMX/3DNow! supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200 Series x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200 Series x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200M Series (Microsoft Corporation - WDDM) supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/MMX/3DNow! supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200M Series x86/MMX/3DNow! supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200M Series x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS 200M Series x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS Series x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON XPRESS Series x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON Xpress 200 Series SW TCL x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. RADEON Xpress 200G Series SW TCL x86/MMX/3DNow!/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. ROBSON CE supported 3 0 4 ATI ROBSON
-ATI Technologies Inc. ROBSON LE supported 3 0 4 ATI ROBSON
-ATI Technologies Inc. RS780M supported 0 1 2.1 AMD RS780 (HD 3200)
-ATI Technologies Inc. RS880 supported 0 1 3.2 AMD RS880 (HD 4200)
-ATI Technologies Inc. RV250 DDR x86/SSE2 supported 0 0 0 ATI Radeon RV250
-ATI Technologies Inc. Radeon X1300XT/X1600 Pro Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300XT/X1600Pro/X1650 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon (TM) HD 7670M supported 3 0 4.2 ATI Radeon HD 7600
-ATI Technologies Inc. Radeon (TM) HD 6370M supported 1 1 4.2 ATI Radeon HD 6300
-ATI Technologies Inc. Radeon (TM) HD 6470M supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. Radeon (TM) HD 6490M supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. Radeon (TM) HD 6630M supported 3 1 4.2 ATI Radeon HD 6600
-ATI Technologies Inc. Radeon (TM) HD 6750M supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. Radeon (TM) HD 6770M supported 3 1 4.2 ATI Radeon HD 6700
-ATI Technologies Inc. Radeon (TM) HD 6850M supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. Radeon (TM) HD 7450M supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. Radeon (TM) HD 7470M supported 2 0 4.2 ATI Radeon HD 7400
-ATI Technologies Inc. Radeon (TM) HD 7670M supported 3 0 4.2 ATI Radeon HD 7600
-ATI Technologies Inc. Radeon (TM) HD 7690M XT supported 3 0 4.2 ATI Radeon HD 7600
-ATI Technologies Inc. Radeon (TM) HD 7750M supported 4 1 4.2 ATI Radeon HD 7700
-ATI Technologies Inc. Radeon (TM) HD 7850M supported 5 1 4.2 ATI Radeon HD 7800
-ATI Technologies Inc. Radeon (TM) HD 8750M supported 4 1 4.2 ATI Radeon HD 8700 (OEM)
-ATI Technologies Inc. Radeon 7000 DDR x86/SSE2 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. Radeon 7500 DDR x86 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. Radeon 7500 DDR x86/SSE2 supported 0 1 2 ATI Radeon 7xxx
-ATI Technologies Inc. Radeon 9100 DDR x86/MMX/3DNow!/SSE2 supported 0 0 0 ATI Radeon 9100
-ATI Technologies Inc. Radeon 9200 DDR x86/SSE2 supported 0 1 1.3 ATI Radeon 9200
-ATI Technologies Inc. Radeon HD 2600 PRO (Omega 3.8.442) supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. Radeon HD 6470M supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. Radeon HD 6490M supported 3 1 4.2 ATI Radeon HD 6400
-ATI Technologies Inc. Radeon HD 6800 Series supported 4 1 4.2 ATI Radeon HD 6800
-ATI Technologies Inc. Radeon Radeon X300/X550/X1050 Series x86/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. Radeon X1050 supported 2 0 2.1 ATI Radeon X1000
-ATI Technologies Inc. Radeon X1050 Series (Omega 3.8.442) supported 2 0 2.1 ATI Radeon X1000
-ATI Technologies Inc. Radeon X1200 Series (Omega 3.8.442) supported 2 0 2.1 ATI Radeon X1200
-ATI Technologies Inc. Radeon X1300 / X1550 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300 / X1550 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300 / X1550 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300 / X1600 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300/X1550 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300/X1550 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300/X1550 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300/X1550 Series (Omega 3.8.442) supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300/X1550 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1300/X1550 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Radeon X1550 64-bit (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Radeon X1550 64-bit x86/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Radeon X1550 Series supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Radeon X1550 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Radeon X1550 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Radeon X1550 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. Radeon X1600 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600 Pro / X1300XT supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600 Pro / X1300XT x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600 Series supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600 Series (Omega 3.8.442) supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600 x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600/1650 Series supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600/X1650 Series supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1600/X1650 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1650 GTO supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1650 SE supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1650 SE x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1650 Series supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1650 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1650 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1650 Series (Omega 3.8.442) supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1650 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1650 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1650/X1700 Series (Omega 3.8.442) supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Radeon X1700 FSC supported 2 1 2.1 ATI Radeon X1700
-ATI Technologies Inc. Radeon X1800 CrossFire Edition supported 3 1 2.1 ATI Radeon X1800
-ATI Technologies Inc. Radeon X1800 Series supported 3 1 2.1 ATI Radeon X1800
-ATI Technologies Inc. Radeon X1800 Series x86/MMX/3DNow!/SSE2 supported 3 1 2.1 ATI Radeon X1800
-ATI Technologies Inc. Radeon X1900 CrossFire Edition supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1900 GT supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1900 GT x86/SSE2 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1900 Series supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1900 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1900 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1900 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1950 CrossFire Edition supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1950 Pro supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1950 Pro (Omega 3.8.442) supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1950 Pro x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1950 Pro x86/SSE2 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1950 Series supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1950 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1950 Series (Microsoft Corporation - WDDM) supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1950 Series x86/MMX/3DNow!/SSE2 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X1950 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1900
-ATI Technologies Inc. Radeon X300/X550/X1050 Series supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. Radeon X300/X550/X1050 Series (Microsoft Corporation - WDDM) supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. Radeon X300/X550/X1050 Series (Microsoft Corporation - WDDM) supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. Radeon X300/X550/X1050 Series (Omega 3.8.442) supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. Radeon X300/X550/X1050 Series x86/SSE2 supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. Radeon X550/X700 Series supported 1 1 2.1 ATI Radeon X500
-ATI Technologies Inc. Radeon X550XTX supported 1 1 2.1 ATI Radeon X500
-ATI Technologies Inc. Radeon Xpress 200 Series (Omega 3.8.442) x86/SSE2 supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. Radeon Xpress 200M Series (Omega 3.8.442) supported 0 1 2.1 ATI Radeon Xpress
-ATI Technologies Inc. SAPPHIRE RADEON 9600 ATLANTIS supported 0 1 2.1 ATI Radeon 9600
-ATI Technologies Inc. SAPPHIRE RADEON X300SE supported 1 1 2.1 ATI Radeon X300
-ATI Technologies Inc. SAPPHIRE Radeon X1550 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. SAPPHIRE Radeon X1550 Series supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. SAPPHIRE Radeon X1550 Series x86/SSE2 supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. SUMO 9640 supported 3 1 4.1 AMD SUMO
-ATI Technologies Inc. SUMO 964A supported 3 1 4.1 AMD SUMO
-ATI Technologies Inc. Sapphire RADEON X1600 PRO supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Sapphire RADEON X1600 PRO x86/SSE2 supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Sapphire RADEON X1600 XT supported 2 1 2.1 ATI Radeon X1600
-ATI Technologies Inc. Tul Corporation, RADEON X1300 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. Tul Corporation, RADEON X300SE supported 1 1 2.1 ATI RADEON X300SE
-ATI Technologies Inc. VisionTek Radeon 4350 supported 2 1 4 ATI Radeon HD 4300
-ATI Technologies Inc. VisionTek Radeon HD 2400 PCI supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. VisionTek Radeon HD 2600 XT AGP supported 2 1 4 ATI Radeon HD 2600
-ATI Technologies Inc. VisionTek Radeon HD 5450 supported 3 1 4.2 ATI Radeon HD 5400
-ATI Technologies Inc. VisionTek Radeon HD2400 Pro AGP supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. VisionTek Radeon HD2400 Pro PCI supported 1 1 4 ATI Radeon HD 2400
-ATI Technologies Inc. VisionTek Radeon X1300 supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. VisionTek Radeon X1300 Series supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. VisionTek Radeon X1300 XGE supported 2 1 2.1 ATI Radeon X1300
-ATI Technologies Inc. VisionTek Radeon X1550 Series supported 2 1 2.1 ATI Radeon X1500
-ATI Technologies Inc. WRESTLER 9802 supported 3 1 4 AMD WRESTLER
-ATI Technologies Inc. XFX Radeon HD 4570 supported 2 1 3.3 ATI Radeon HD 4500
-Advanced Micro Devices, Inc. Mesa DRI R600 (RS880 9712) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 0 1 3.2 AMD RS880 (HD 4200)
-Alex Mohr GL Hijacker! unsupported 0 0 0 Hijacker
-Brian Paul Mesa X11 unsupported 1 1 3 Mesa
-Gallium supported 1 1 2.1 Gallium
-Humper supported 0 1 2.1 Humper
-Humper Chromium supported 0 1 2.1 Humper
-Imagination Technologies 3D-Analyze v2.3 - http://www.tommti-systems.com unsupported 0 0 0 ATI 3D-Analyze
-Imagination Technologies PowerVR SGX545 supported 1 1 3 PowerVR SGX545
-Intel NO MATCH
-Intel 3D-Analyze v2.3 - http://www.tommti-systems.com supported 2 0 0 Intel 3D-Analyze
-Intel 4 Series Internal supported 1 1 2.1 Intel 4 Series Internal
-Intel 845G unsupported 0 1 1.4 Intel 845G
-Intel 855GM unsupported 0 1 1.4 Intel 855GM
-Intel 865G unsupported 0 1 1.4 Intel 865G
-Intel 915G unsupported 0 1 1.4 Intel 915G
-Intel 915GM unsupported 0 1 1.4 Intel 915GM
-Intel 945G supported 0 1 1.4 Intel 945G
-Intel 945GM supported 0 1 1.4 Intel 945GM
-Intel 950 supported 0 1 1.4 Intel 950
-Intel 965 supported 0 1 2.1 Intel 965
-Intel Bear Lake unsupported 1 1 1.4 Intel Bear Lake
-Intel Broadwater unsupported 0 1 1.4 Intel Broadwater
-Intel Brookdale unsupported 0 1 1.3 Intel Brookdale
-Intel Cantiga unsupported 0 1 2 Intel Cantiga
-Intel Corporation Intel(R) Graphics Media Accelerator 3600 Series supported 0 1 3 Intel GMA 3600
-Intel Eaglelake supported 1 1 2 Intel Eaglelake
-Intel G33 unsupported 1 1 1.4 Intel G33
-Intel G41 supported 1 1 2.1 Intel G41
-Intel G45 supported 1 1 2.1 Intel G45
-Intel Graphics Media HD supported 1 1 2.1 Intel Graphics Media HD
-Intel HD Graphics supported 2 1 4 Intel HD Graphics
-Intel HD Graphics 2000 supported 2 0 3.1 Intel HD Graphics 2000
-Intel HD Graphics 3000 supported 3 1 3.1 Intel HD Graphics 3000
-Intel HD Graphics 4000 supported 3 1 4.2 Intel HD Graphics 4000
-Intel Inc. Intel GMA 950 OpenGL Engine supported 0 1 1.4 Intel 950
-Intel Inc. Intel GMA X3100 OpenGL Engine supported 1 1 2.1 Intel X3100
-Intel Inc. Intel HD Graphics 3000 OpenGL Engine supported 3 1 3.1 Intel HD Graphics 3000
-Intel Inc. Intel HD Graphics 4000 OpenGL Engine supported 3 1 4.2 Intel HD Graphics 4000
-Intel Inc. Intel HD Graphics 5000 OpenGL Engine supported 4 0 4 Intel HD Graphics 5000
-Intel Inc. Intel HD Graphics OpenGL Engine supported 2 1 4 Intel HD Graphics
-Intel Intel 845G unsupported 0 1 1.4 Intel 845G
-Intel Intel 855GM unsupported 0 1 1.4 Intel 855GM
-Intel Intel 865G unsupported 0 1 1.4 Intel 865G
-Intel Intel 915G unsupported 0 1 1.4 Intel 915G
-Intel Intel 915GM unsupported 0 1 1.4 Intel 915GM
-Intel Intel 945G supported 0 1 1.4 Intel 945G
-Intel Intel 945GM supported 0 1 1.4 Intel 945GM
-Intel Intel 965/963 Graphics Media Accelerator supported 0 1 2.1 Intel 965
-Intel Intel Bear Lake B unsupported 1 1 1.4 Intel Bear Lake
-Intel Intel Broadwater G unsupported 0 1 1.4 Intel Broadwater
-Intel Intel Brookdale-G unsupported 0 1 1.3 Intel Brookdale
-Intel Intel Cantiga unsupported 0 1 2 Intel Cantiga
-Intel Intel Eaglelake supported 1 1 2 Intel Eaglelake
-Intel Intel Grantsdale-G supported 1 0 0 Intel Grantsdale
-Intel Intel Iris Pro Graphics 5200 supported 4 0 4 Intel Intel Iris Pro Graphics 5200
-Intel Intel Montara-GM unsupported 0 1 1.3 Intel Montara
-Intel Intel Pineview Platform supported 0 1 1.4 Intel Pineview
-Intel Intel Springdale-G unsupported 0 1 1.3 Intel Springdale
-Intel Intel(R) HD Graphics Family supported 2 1 4 Intel HD Graphics
-Intel Intel(R) 4 Series Internal Chipset supported 1 1 2.1 Intel 4 Series Internal
-Intel Intel(R) B43 Express Chipset supported 1 1 2.1 Intel B45/B43
-Intel Intel(R) G41 Express Chipset supported 1 1 2.1 Intel G41
-Intel Intel(R) G41 Express Chipset (Microsoft Corporation - WDDM 1.1) supported 1 1 2.1 Intel G41
-Intel Intel(R) G41 Express Chipset v2 supported 1 1 2.1 Intel G41
-Intel Intel(R) G45/G43 Express Chipset supported 1 1 2.1 Intel G45
-Intel Intel(R) G45/G43/G41 Express Chipset supported 1 1 2.1 Intel G41
-Intel Intel(R) Graphics Media Accelerator HD supported 1 1 2.1 Intel Graphics Media HD
-Intel Intel(R) HD Graphics supported 2 1 4 Intel HD Graphics
-Intel Intel(R) HD Graphics 100 supported 2 1 4 Intel HD Graphics
-Intel Intel(R) HD Graphics 2000 supported 2 0 3.1 Intel HD Graphics 2000
-Intel Intel(R) HD Graphics 2500 supported 2 0 4.2 Intel HD Graphics 2500
-Intel Intel(R) HD Graphics 3000 supported 3 1 3.1 Intel HD Graphics 3000
-Intel Intel(R) HD Graphics 4000 supported 3 1 4.2 Intel HD Graphics 4000
-Intel Intel(R) HD Graphics 4400 supported 3 0 4.2 Intel HD Graphics 4400
-Intel Intel(R) HD Graphics 4600 supported 3 0 4.2 Intel HD Graphics 4600
-Intel Intel(R) HD Graphics 5000 supported 4 0 4 Intel HD Graphics 5000
-Intel Intel(R) HD Graphics BR-1004-01Y1 supported 2 1 4 Intel HD Graphics
-Intel Intel(R) HD Graphics Family supported 2 1 4 Intel HD Graphics
-Intel Intel(R) HD Graphics P3000 supported 2 1 4 Intel HD Graphics
-Intel Intel(R) HD Graphics P4000 supported 2 1 4 Intel HD Graphics
-Intel Intel(R) Q45/Q43 Express Chipset supported 1 1 2.1 Intel Q45/Q43
-Intel Iris OpenGL Graphics Engine supported 4 0 4 Intel Intel Iris OpenGL Engine
-Intel Mobile 4 Series supported 0 1 2.1 Intel Mobile 4 Series
-Intel Mobile Intel(R) 4 Series Express Chipset Family supported 0 1 2.1 Intel Mobile 4 Series
-Intel Mobile Intel(R) 4 Series Express Chipset Family v2 supported 0 1 2.1 Intel Mobile 4 Series
-Intel Mobile Intel(R) 45 Express Chipset Family (Microsoft Corporation - WDDM 1.1) supported 0 0 2.1 Intel Mobile 45 Express
-Intel Mobile Intel(R) HD Graphics supported 2 1 4 Intel HD Graphics
-Intel Montara unsupported 0 1 1.3 Intel Montara
-Intel Open Source Technology Center Mesa DRI Intel(R) 852GM/855GM x86/MMX/SSE2 unsupported 0 1 1.4 Intel 855GM
-Intel Open Source Technology Center Mesa DRI Intel(R) 915G unsupported 0 1 1.4 Intel 915G
-Intel Open Source Technology Center Mesa DRI Intel(R) 915G x86/MMX/SSE2 unsupported 0 1 1.4 Intel 915G
-Intel Open Source Technology Center Mesa DRI Intel(R) 915GM x86/MMX/SSE2 unsupported 0 1 1.4 Intel 915GM
-Intel Open Source Technology Center Mesa DRI Intel(R) 945G supported 0 1 1.4 Intel 945G
-Intel Open Source Technology Center Mesa DRI Intel(R) 945G x86/MMX/SSE2 supported 0 1 1.4 Intel 945G
-Intel Open Source Technology Center Mesa DRI Intel(R) 945GM supported 0 1 1.4 Intel 945GM
-Intel Open Source Technology Center Mesa DRI Intel(R) 945GM x86/MMX/SSE2 supported 0 1 1.4 Intel 945GM
-Intel Open Source Technology Center Mesa DRI Intel(R) 945GME x86/MMX/SSE2 supported 0 1 1.4 Intel 945GM
-Intel Open Source Technology Center Mesa DRI Intel(R) 965G x86/MMX/SSE2 supported 0 1 2.1 Intel 965
-Intel Open Source Technology Center Mesa DRI Intel(R) 965GM supported 0 1 2.1 Intel 965
-Intel Open Source Technology Center Mesa DRI Intel(R) 965GM x86/MMX/SSE2 supported 0 1 2.1 Intel 965
-Intel Open Source Technology Center Mesa DRI Intel(R) 965GME/GLE supported 0 1 2.1 Intel 965
-Intel Open Source Technology Center Mesa DRI Intel(R) 965Q supported 0 1 2.1 Intel 965
-Intel Open Source Technology Center Mesa DRI Intel(R) 965Q x86/MMX/SSE2 supported 0 1 2.1 Intel 965
-Intel Open Source Technology Center Mesa DRI Intel(R) G33 x86/MMX/SSE2 unsupported 1 1 1.4 Intel G33
-Intel Open Source Technology Center Mesa DRI Intel(R) G41 x86/MMX/SSE2 supported 1 1 2.1 Intel G41
-Intel Open Source Technology Center Mesa DRI Intel(R) G45/G43 supported 1 1 2.1 Intel G45
-Intel Open Source Technology Center Mesa DRI Intel(R) G45/G43 x86/MMX/SSE2 supported 1 1 2.1 Intel G45
-Intel Open Source Technology Center Mesa DRI Intel(R) IGD unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) IGD x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Ironlake Desktop x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Ironlake Mobile unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Ironlake Mobile x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Ivybridge Desktop unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Ivybridge Desktop x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Ivybridge Mobile unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Ivybridge Mobile x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Q35 unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Q35 x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Q45/Q43 supported 1 1 2.1 Intel Q45/Q43
-Intel Open Source Technology Center Mesa DRI Intel(R) Q45/Q43 x86/MMX/SSE2 supported 1 1 2.1 Intel Q45/Q43
-Intel Open Source Technology Center Mesa DRI Intel(R) Sandybridge Desktop unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Sandybridge Desktop x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Sandybridge Mobile unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Intel(R) Sandybridge Mobile x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Mobile Intel(R) GM45 Express Chipset unsupported 1 1 3 Mesa
-Intel Open Source Technology Center Mesa DRI Mobile Intel(R) GM45 Express Chipset x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Intel Pineview supported 0 1 1.4 Intel Pineview
-Intel Q45/Q43 supported 1 1 2.1 Intel Q45/Q43
-Intel Royal BNA Driver unsupported 0 0 0 Intel Royal BNA
-Intel Springdale unsupported 0 1 1.3 Intel Springdale
-Intel X3100 supported 1 1 2.1 Intel X3100
-Matrox Graphics Inc. Matrox ICD for M-Series unsupported 0 0 0 Matrox
-Matrox Graphics Inc. Matrox G400 unsupported 0 0 0 Matrox
-Matrox Graphics Inc. Matrox ICD for Parhelia unsupported 0 0 0 Matrox
-Mesa unsupported 1 1 3 Mesa
-Mesa Project Software Rasterizer unsupported 1 1 3 Mesa
-Mesa project: www.mesa3d.org Mesa GLX Indirect unsupported 1 1 3 Mesa
-NVIDIA 205 supported 3 1 3.3 NVIDIA 205
-NVIDIA 210 supported 3 1 3.3 NVIDIA 210
-NVIDIA 310 supported 3 1 3.3 NVIDIA 310
-NVIDIA 310M supported 2 0 3.3 NVIDIA 310M
-NVIDIA 315 supported 3 1 3.3 NVIDIA 315
-NVIDIA 315M supported 2 0 3.3 NVIDIA 310M
-NVIDIA 320M supported 2 0 3.3 NVIDIA 320M
-NVIDIA 405 supported 3 0 3.3 NVIDIA 405
-NVIDIA 410 supported 3 0 3.3 NVIDIA 410
-NVIDIA 510 supported 3 0 0 NVIDIA 510
-NVIDIA 610M supported 3 1 4.3 NVIDIA 610M
-NVIDIA Corporation /PCI/SSE2 NO MATCH
-NVIDIA Corporation 3D-Analyze v2.3 - http://www.tommti-systems.com unsupported 0 0 0 ATI 3D-Analyze
-NVIDIA Corporation C51/PCI/SSE2/3DNOW! supported 0 1 2 NVIDIA C51
-NVIDIA Corporation C51G/PCI/SSE2/3DNOW! supported 0 1 2 NVIDIA C51
-NVIDIA Corporation D10P1-25/PCI/SSE2/3DNOW! unsupported 0 0 0 NVIDIA D1xP1
-NVIDIA Corporation D14P1-30/PCIe/SSE2 unsupported 0 0 0 NVIDIA D1xP1
-NVIDIA Corporation D9M-20/PCI/SSE2 supported 1 0 0 NVIDIA D9M
-NVIDIA Corporation D9M-20/PCI/SSE2/3DNOW! supported 1 0 0 NVIDIA D9M
-NVIDIA Corporation G72/PCI/SSE2/3DNOW! supported 1 0 0 NVIDIA G72
-NVIDIA Corporation G73/AGP/SSE2/3DNOW! supported 1 0 0 NVIDIA G73
-NVIDIA Corporation G73/PCI/SSE2/3DNOW! supported 1 0 0 NVIDIA G73
-NVIDIA Corporation G84-50/PCI/SSE2 supported 2 0 0 NVIDIA G84
-NVIDIA Corporation G92-100/PCI/SSE2/3DNOW! supported 3 0 0 NVIDIA G92
-NVIDIA Corporation GK106/PCIe/SSE2 supported 5 0 4.3 NVIDIA GK106
-NVIDIA Corporation GRID K2/PCIe/SSE2 unsupported 0 0 1.5 NVIDIA GRID
-NVIDIA Corporation GeForce GTX 555/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 550
-NVIDIA Corporation GeForce GTX 555/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 550
-NVIDIA Corporation GeForce 205/PCI/SSE2 supported 3 1 3.3 NVIDIA 205
-NVIDIA Corporation GeForce 210/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 210
-NVIDIA Corporation GeForce 210/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 210
-NVIDIA Corporation GeForce 210/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 210
-NVIDIA Corporation GeForce 210/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 210
-NVIDIA Corporation GeForce 310/PCI/SSE2 supported 3 1 3.3 NVIDIA 310
-NVIDIA Corporation GeForce 310/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA 310
-NVIDIA Corporation GeForce 310/PCIe/SSE2 supported 3 1 3.3 NVIDIA 310
-NVIDIA Corporation GeForce 310/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA 310
-NVIDIA Corporation GeForce 310M/PCI/SSE2 supported 2 0 3.3 NVIDIA 310M
-NVIDIA Corporation GeForce 310M/PCIe/SSE2 supported 2 0 3.3 NVIDIA 310M
-NVIDIA Corporation GeForce 315/PCI/SSE2 supported 3 1 3.3 NVIDIA 315
-NVIDIA Corporation GeForce 315/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA 315
-NVIDIA Corporation GeForce 315/PCIe/SSE2 supported 3 1 3.3 NVIDIA 315
-NVIDIA Corporation GeForce 315/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA 315
-NVIDIA Corporation GeForce 315M/PCI/SSE2 supported 2 0 3.3 NVIDIA 310M
-NVIDIA Corporation GeForce 315M/PCIe/SSE2 supported 2 0 3.3 NVIDIA 310M
-NVIDIA Corporation GeForce 320M/PCI/SSE2 supported 2 0 3.3 NVIDIA 320M
-NVIDIA Corporation GeForce 320M/integrated/SSE2 supported 2 0 3.3 NVIDIA 320M
-NVIDIA Corporation GeForce 405/PCI/SSE2 supported 3 0 3.3 NVIDIA 405
-NVIDIA Corporation GeForce 405/PCI/SSE2/3DNOW! supported 3 0 3.3 NVIDIA 405
-NVIDIA Corporation GeForce 405/PCIe/SSE2 supported 3 0 3.3 NVIDIA 405
-NVIDIA Corporation GeForce 405/PCIe/SSE2/3DNOW! supported 3 0 3.3 NVIDIA 405
-NVIDIA Corporation GeForce 410M/PCI/SSE2 supported 3 0 0 NVIDIA 410M
-NVIDIA Corporation GeForce 410M/PCIe/SSE2 supported 3 0 0 NVIDIA 410M
-NVIDIA Corporation GeForce 505/PCIe/SSE2 supported 3 0 0 NVIDIA 505
-NVIDIA Corporation GeForce 510/PCI/SSE2 supported 3 0 0 NVIDIA 510
-NVIDIA Corporation GeForce 510/PCIe/SSE2 supported 3 0 0 NVIDIA 510
-NVIDIA Corporation GeForce 605/PCI/SSE2 supported 3 1 4.3 NVIDIA 605
-NVIDIA Corporation GeForce 605/PCIe/SSE2 supported 3 1 4.3 NVIDIA 605
-NVIDIA Corporation GeForce 605/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA 605
-NVIDIA Corporation GeForce 610/PCIe/SSE2 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6100 nForce 400/PCI/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6100 nForce 400/integrated/SSE2 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6100 nForce 400/integrated/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6100 nForce 405/PCI/SSE2 supported 3 0 3.3 NVIDIA 405
-NVIDIA Corporation GeForce 6100 nForce 405/PCI/SSE2/3DNOW! supported 3 0 3.3 NVIDIA 405
-NVIDIA Corporation GeForce 6100 nForce 405/integrated/SSE2 supported 3 0 3.3 NVIDIA 405
-NVIDIA Corporation GeForce 6100 nForce 405/integrated/SSE2/3DNOW! supported 3 0 3.3 NVIDIA 405
-NVIDIA Corporation GeForce 6100 nForce 420/PCI/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6100 nForce 430/PCI/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6100/PCI/SSE2 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6100/PCI/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6100/integrated/SSE2 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6100/integrated/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 610M/PCI/SSE2 supported 3 1 4.3 NVIDIA 610M
-NVIDIA Corporation GeForce 610M/PCIe/SSE2 supported 3 1 4.3 NVIDIA 610M
-NVIDIA Corporation GeForce 615/PCIe/SSE2 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150 LE/PCI/SSE2 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150 LE/PCI/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150 LE/integrated/SSE2 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150 LE/integrated/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150 SE/PCI/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150/PCI/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150/integrated/SSE2 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150/integrated/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150SE nForce 430/PCI/SSE2 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150SE nForce 430/PCI/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150SE nForce 430/integrated/SSE2 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150SE nForce 430/integrated/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6150SE/PCI/SSE2/3DNOW! supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA Corporation GeForce 6200 A-LE/AGP/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 A-LE/AGP/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 A-LE/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 A-LE/PCI/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 LE/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 LE/PCI/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 LE/PCIe/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 LE/PCIe/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 TurboCache(TM)/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 TurboCache(TM)/PCI/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 TurboCache(TM)/PCIe/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200 TurboCache(TM)/PCIe/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200/AGP/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200/AGP/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200/PCI/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200/PCIe/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200/PCIe/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200SE TurboCache(TM)/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200SE TurboCache(TM)/PCI/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200SE TurboCache(TM)/PCIe/SSE2 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6200SE TurboCache(TM)/PCIe/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA Corporation GeForce 6500/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 6500
-NVIDIA Corporation GeForce 6500/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6500
-NVIDIA Corporation GeForce 6500/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 6500
-NVIDIA Corporation GeForce 6500/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6500
-NVIDIA Corporation GeForce 6600 GT/AGP/SSE2 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600 GT/AGP/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600 GT/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600 GT/PCI/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600 GT/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600 GT/PCIe/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600 LE/AGP/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600 LE/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600 LE/PCI/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600 LE/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600 LE/PCIe/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600/AGP/SSE2 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600/AGP/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600/PCI/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6600/PCIe/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6610 XL/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6610 XL/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation GeForce 6700 XL/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 6700
-NVIDIA Corporation GeForce 6700 XL/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 6700
-NVIDIA Corporation GeForce 6800 GS/AGP/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 GS/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 GS/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 GS/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 GT/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 GT/AGP/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 GT/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 GT/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 LE/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 LE/AGP/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 LE/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 Ultra/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 Ultra/AGP/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 Ultra/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 Ultra/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 Ultra/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 XT/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 XT/AGP/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 XT/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 XT/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 XT/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800 XT/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800/AGP/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 6800/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA Corporation GeForce 7000M / nForce 610M/PCI/SSE2 supported 3 1 4.3 NVIDIA 610M
-NVIDIA Corporation GeForce 7000M / nForce 610M/PCI/SSE2/3DNOW! supported 3 1 4.3 NVIDIA 610M
-NVIDIA Corporation GeForce 7025 / NVIDIA nForce 630a/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7025 / NVIDIA nForce 630a/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7025 / nForce 630a/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7025 / nForce 630a/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7025 / nForce 630a/integrated/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7025 / nForce 630a/integrated/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 / NVIDIA nForce 610i/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 / NVIDIA nForce 620i/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 / NVIDIA nForce 630i/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 / nForce 610i/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 / nForce 610i/integrated/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 / nForce 620i/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 / nForce 620i/integrated/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 / nForce 630i/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 / nForce 630i/integrated/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 PV / NVIDIA nForce 630a/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 PV / nForce 630a/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 PV / nForce 630a/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 PV / nForce 630a/integrated/SSE2 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7050 PV / nForce 630a/integrated/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA Corporation GeForce 7100 / NVIDIA nForce 620i/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7100 / NVIDIA nForce 630i/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7100 / nForce 630i/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7100 / nForce 630i/integrated/SSE2 supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7100 GS/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7100 GS/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7100 GS/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7100 GS/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 710A/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 710M/PCIe/SSE2 supported 3 0 4.3 NVIDIA 710M
-NVIDIA Corporation GeForce 7150 / nForce 630i/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7150M / nForce 630M/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7150M / nForce 630M/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7150M / nForce 630M/integrated/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA Corporation GeForce 7300 GS/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 GS/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 GS/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 GS/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 GT/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 GT/AGP/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 GT/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 GT/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 GT/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 GT/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 LE/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 LE/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 LE/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 LE/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 SE/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 SE/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7300 SE/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7350 LE/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7350 LE/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7350 LE/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation GeForce 7500 LE/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 7500
-NVIDIA Corporation GeForce 7500 LE/PCI/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7500
-NVIDIA Corporation GeForce 7500 LE/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 7500
-NVIDIA Corporation GeForce 7500 LE/PCIe/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7500
-NVIDIA Corporation GeForce 7600 GS/AGP/SSE2 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GS/AGP/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GS/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GS/PCI/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GS/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GS/PCIe/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GT/AGP/SSE2 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GT/AGP/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GT/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GT/PCI/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GT/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 GT/PCIe/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7600 LE/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7650 GS/AGP/SSE2 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7650 GS/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7650 GS/PCI/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7650 GS/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation GeForce 7800 GS/AGP/SSE2 supported 2 1 2.1 NVIDIA GeForce 7800
-NVIDIA Corporation GeForce 7800 GS/AGP/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7800
-NVIDIA Corporation GeForce 7800 GS/PCI/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7800
-NVIDIA Corporation GeForce 7800 GT/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 7800
-NVIDIA Corporation GeForce 7800 GT/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 7800
-NVIDIA Corporation GeForce 7800 GT/PCIe/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7800
-NVIDIA Corporation GeForce 7800 GTX/PCI/SSE2 supported 2 1 2.1 NVIDIA GeForce 7800
-NVIDIA Corporation GeForce 7800 GTX/PCIe/SSE2 supported 2 1 2.1 NVIDIA GeForce 7800
-NVIDIA Corporation GeForce 7800 GTX/PCIe/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 7800
-NVIDIA Corporation GeForce 7900 GS/AGP/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GS/AGP/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GS/PCI/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GS/PCI/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GS/PCIe/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GS/PCIe/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GT/GTO/PCI/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GT/GTO/PCIe/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GT/GTO/PCIe/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GT/PCI/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GTX/PCI/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GTX/PCI/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GTX/PCIe/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7900 GTX/PCIe/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7950 GT/AGP/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7950 GT/AGP/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7950 GT/PCI/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7950 GT/PCI/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7950 GT/PCIe/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7950 GT/PCIe/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7950 GX2/PCI/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7950 GX2/PCIe/SSE2 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 7950 GX2/PCIe/SSE2/3DNOW! supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation GeForce 8100 / nForce 720a/PCI/SSE2 supported 1 0 3.3 NVIDIA GeForce 8100
-NVIDIA Corporation GeForce 8100 / nForce 720a/PCI/SSE2/3DNOW! supported 1 0 3.3 NVIDIA GeForce 8100
-NVIDIA Corporation GeForce 8100 / nForce 720a/integrated/SSE2 supported 1 0 3.3 NVIDIA GeForce 8100
-NVIDIA Corporation GeForce 8100 / nForce 720a/integrated/SSE2/3DNOW! supported 1 0 3.3 NVIDIA GeForce 8100
-NVIDIA Corporation GeForce 8200/PCI/SSE2 supported 1 0 3.3 NVIDIA GeForce 8200
-NVIDIA Corporation GeForce 8200/PCI/SSE2/3DNOW! supported 1 0 3.3 NVIDIA GeForce 8200
-NVIDIA Corporation GeForce 8200/integrated/SSE2 supported 1 0 3.3 NVIDIA GeForce 8200
-NVIDIA Corporation GeForce 8200/integrated/SSE2/3DNOW! supported 1 0 3.3 NVIDIA GeForce 8200
-NVIDIA Corporation GeForce 8200M G/PCI/SSE2 supported 1 0 3.3 NVIDIA GeForce 8200M
-NVIDIA Corporation GeForce 8200M G/PCI/SSE2/3DNOW! supported 1 0 3.3 NVIDIA GeForce 8200M
-NVIDIA Corporation GeForce 8200M G/integrated/SSE2 supported 1 0 3.3 NVIDIA GeForce 8200M
-NVIDIA Corporation GeForce 8200M G/integrated/SSE2/3DNOW! supported 1 0 3.3 NVIDIA GeForce 8200M
-NVIDIA Corporation GeForce 8200M/PCI/SSE2/3DNOW! supported 1 0 3.3 NVIDIA GeForce 8200M
-NVIDIA Corporation GeForce 8300 GS/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8300
-NVIDIA Corporation GeForce 8300 GS/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8300
-NVIDIA Corporation GeForce 8300 GS/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 8300
-NVIDIA Corporation GeForce 8300 GS/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8300
-NVIDIA Corporation GeForce 8300/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8300
-NVIDIA Corporation GeForce 8300/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8300
-NVIDIA Corporation GeForce 8300/integrated/SSE2 supported 3 1 3.3 NVIDIA GeForce 8300
-NVIDIA Corporation GeForce 8300/integrated/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8300
-NVIDIA Corporation GeForce 8400 GS/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400 GS/PCI/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400 GS/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400 GS/PCIe/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400 SE/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400 SE/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400/PCI/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400/PCIe/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400GS/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400GS/PCI/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400GS/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400GS/PCIe/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation GeForce 8400M G/PCI/SSE2 supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA Corporation GeForce 8400M G/PCI/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA Corporation GeForce 8400M G/PCIe/SSE2 supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA Corporation GeForce 8400M G/PCIe/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA Corporation GeForce 8400M GS/PCI/SSE2 supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA Corporation GeForce 8400M GS/PCI/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA Corporation GeForce 8400M GS/PCIe/SSE2 supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA Corporation GeForce 8400M GS/PCIe/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA Corporation GeForce 8400M GT/PCI/SSE2 supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA Corporation GeForce 8400M GT/PCIe/SSE2 supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA Corporation GeForce 8500 GT/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 8500
-NVIDIA Corporation GeForce 8500 GT/PCI/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8500
-NVIDIA Corporation GeForce 8500 GT/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 8500
-NVIDIA Corporation GeForce 8500 GT/PCIe/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8500
-NVIDIA Corporation GeForce 8600 GS/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GS/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GS/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GS/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GT/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GT/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GT/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GT/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GTS/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GTS/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GTS/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600 GTS/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600GS/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600GS/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation GeForce 8600M GS/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 8600M
-NVIDIA Corporation GeForce 8600M GS/PCI/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8600M
-NVIDIA Corporation GeForce 8600M GS/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 8600M
-NVIDIA Corporation GeForce 8600M GS/PCIe/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8600M
-NVIDIA Corporation GeForce 8600M GT/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 8600M
-NVIDIA Corporation GeForce 8600M GT/PCI/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8600M
-NVIDIA Corporation GeForce 8600M GT/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 8600M
-NVIDIA Corporation GeForce 8600M GT/PCIe/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 8600M
-NVIDIA Corporation GeForce 8700M GT/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 8700M
-NVIDIA Corporation GeForce 8700M GT/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 8700M
-NVIDIA Corporation GeForce 8800 GS/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GS/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GS/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GS/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GT/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GT/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GT/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GT/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTS 512/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTS 512/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTS 512/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTS 512/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTS/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTS/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTS/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTS/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTX/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTX/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTX/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 GTX/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 Ultra/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 Ultra/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800 Ultra/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation GeForce 8800M GTS/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 8800M
-NVIDIA Corporation GeForce 8800M GTS/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 8800M
-NVIDIA Corporation GeForce 8800M GTX/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 8800M
-NVIDIA Corporation GeForce 8800M GTX/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 8800M
-NVIDIA Corporation GeForce 9100/PCI/SSE2 supported 0 0 3.3 NVIDIA GeForce 9100
-NVIDIA Corporation GeForce 9100/PCI/SSE2/3DNOW! supported 0 0 3.3 NVIDIA GeForce 9100
-NVIDIA Corporation GeForce 9100/integrated/SSE2 supported 0 0 3.3 NVIDIA GeForce 9100
-NVIDIA Corporation GeForce 9100/integrated/SSE2/3DNOW! supported 0 0 3.3 NVIDIA GeForce 9100
-NVIDIA Corporation GeForce 9100M G/PCI/SSE2 supported 0 0 3.3 NVIDIA GeForce 9100M
-NVIDIA Corporation GeForce 9100M G/PCI/SSE2/3DNOW! supported 0 0 3.3 NVIDIA GeForce 9100M
-NVIDIA Corporation GeForce 9100M G/integrated/SSE2 supported 0 0 3.3 NVIDIA GeForce 9100M
-NVIDIA Corporation GeForce 9100M G/integrated/SSE2/3DNOW! supported 0 0 3.3 NVIDIA GeForce 9100M
-NVIDIA Corporation GeForce 9200/PCI/SSE2 supported 1 0 3.3 NVIDIA GeForce 9200
-NVIDIA Corporation GeForce 9200/PCI/SSE2/3DNOW! supported 1 0 3.3 NVIDIA GeForce 9200
-NVIDIA Corporation GeForce 9200/integrated/SSE2 supported 1 0 3.3 NVIDIA GeForce 9200
-NVIDIA Corporation GeForce 9200/integrated/SSE2/3DNOW! supported 1 0 3.3 NVIDIA GeForce 9200
-NVIDIA Corporation GeForce 9200M GE/PCI/SSE2 supported 1 0 3.3 NVIDIA GeForce 9200M
-NVIDIA Corporation GeForce 9200M GE/PCIe/SSE2 supported 1 0 3.3 NVIDIA GeForce 9200M
-NVIDIA Corporation GeForce 9200M GS/PCI/SSE2 supported 1 0 3.3 NVIDIA GeForce 9200M
-NVIDIA Corporation GeForce 9200M GS/PCIe/SSE2 supported 1 0 3.3 NVIDIA GeForce 9200M
-NVIDIA Corporation GeForce 9300 / nForce 730i/integrated/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300 GE/PCI/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300 GE/PCI/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300 GE/PCIe/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300 GE/PCIe/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300 GS/PCI/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300 GS/PCI/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300 GS/PCIe/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300 GS/PCIe/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300 SE/PCIe/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300/PCI/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300/integrated/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA Corporation GeForce 9300M G/PCI/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300M
-NVIDIA Corporation GeForce 9300M G/PCIe/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300M
-NVIDIA Corporation GeForce 9300M G/PCIe/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 9300M
-NVIDIA Corporation GeForce 9300M GS/PCI/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300M
-NVIDIA Corporation GeForce 9300M GS/PCI/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 9300M
-NVIDIA Corporation GeForce 9300M GS/PCIe/SSE2 supported 1 1 3.3 NVIDIA GeForce 9300M
-NVIDIA Corporation GeForce 9400 GT/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9400
-NVIDIA Corporation GeForce 9400 GT/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9400
-NVIDIA Corporation GeForce 9400 GT/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9400
-NVIDIA Corporation GeForce 9400 GT/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9400
-NVIDIA Corporation GeForce 9400/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9400
-NVIDIA Corporation GeForce 9400/integrated/SSE2 supported 3 1 3.3 NVIDIA GeForce 9400
-NVIDIA Corporation GeForce 9400M G/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 9400M
-NVIDIA Corporation GeForce 9400M G/integrated/SSE2 supported 2 1 3.3 NVIDIA GeForce 9400M
-NVIDIA Corporation GeForce 9400M/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 9400M
-NVIDIA Corporation GeForce 9400M/integrated/SSE2 supported 2 1 3.3 NVIDIA GeForce 9400M
-NVIDIA Corporation GeForce 9500 GS/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9500
-NVIDIA Corporation GeForce 9500 GS/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9500
-NVIDIA Corporation GeForce 9500 GS/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9500
-NVIDIA Corporation GeForce 9500 GS/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9500
-NVIDIA Corporation GeForce 9500 GT/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9500
-NVIDIA Corporation GeForce 9500 GT/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9500
-NVIDIA Corporation GeForce 9500 GT/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9500
-NVIDIA Corporation GeForce 9500 GT/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9500
-NVIDIA Corporation GeForce 9500M GS/PCI/SSE2 supported 1 1 3.3 NVIDIA GeForce 9500M
-NVIDIA Corporation GeForce 9500M GS/PCI/SSE2/3DNOW! supported 1 1 3.3 NVIDIA GeForce 9500M
-NVIDIA Corporation GeForce 9500M GS/PCIe/SSE2 supported 1 1 3.3 NVIDIA GeForce 9500M
-NVIDIA Corporation GeForce 9600 GS/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GS/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GS/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GS/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GSO 512/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GSO 512/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GSO 512/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GSO 512/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GSO/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GSO/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GSO/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GSO/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GT/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GT/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GT/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600 GT/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9600M GS/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 9600M
-NVIDIA Corporation GeForce 9600M GS/PCI/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 9600M
-NVIDIA Corporation GeForce 9600M GS/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 9600M
-NVIDIA Corporation GeForce 9600M GT/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 9600M
-NVIDIA Corporation GeForce 9600M GT/PCI/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 9600M
-NVIDIA Corporation GeForce 9600M GT/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 9600M
-NVIDIA Corporation GeForce 9600M GT/PCIe/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GeForce 9600M
-NVIDIA Corporation GeForce 9650M GS/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9650M GT/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9650M GT/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation GeForce 9700M GT/PCI/SSE2 supported 0 1 3.3 NVIDIA GeForce 9700M
-NVIDIA Corporation GeForce 9700M GT/PCIe/SSE2 supported 0 1 3.3 NVIDIA GeForce 9700M
-NVIDIA Corporation GeForce 9700M GTS/PCI/SSE2 supported 0 1 3.3 NVIDIA GeForce 9700M
-NVIDIA Corporation GeForce 9700M GTS/PCIe/SSE2 supported 0 1 3.3 NVIDIA GeForce 9700M
-NVIDIA Corporation GeForce 9800 GT/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GT/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GT/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GT/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GTX+/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GTX+/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GTX+/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GTX+/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GTX/9800 GTX+/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GTX/9800 GTX+/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GTX/9800 GTX+/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GTX/9800 GTX+/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GTX/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 GX2/PCIe/SSE2 supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800 S/PCI/SSE2 supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation GeForce 9800M GS/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 9800M
-NVIDIA Corporation GeForce 9800M GS/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 9800M
-NVIDIA Corporation GeForce 9800M GT/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 9800M
-NVIDIA Corporation GeForce 9800M GT/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 9800M
-NVIDIA Corporation GeForce 9800M GTS/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 9800M
-NVIDIA Corporation GeForce 9800M GTS/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 9800M
-NVIDIA Corporation GeForce 9800M GTX/PCI/SSE2 supported 2 1 3.3 NVIDIA GeForce 9800M
-NVIDIA Corporation GeForce 9800M GTX/PCIe/SSE2 supported 2 1 3.3 NVIDIA GeForce 9800M
-NVIDIA Corporation GeForce FX 5100/AGP/SSE2 supported 3 0 0 NVIDIA 510
-NVIDIA Corporation GeForce FX 5200 Ultra/AGP/SSE2 supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA Corporation GeForce FX 5200 Ultra/AGP/SSE2/3DNOW! supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA Corporation GeForce FX 5200/AGP/SSE/3DNOW! supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA Corporation GeForce FX 5200/AGP/SSE2 supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA Corporation GeForce FX 5200/AGP/SSE2/3DNOW! supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA Corporation GeForce FX 5200/PCI/SSE2 supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA Corporation GeForce FX 5200/PCI/SSE2/3DNOW! supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA Corporation GeForce FX 5200LE/AGP/SSE2 supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA Corporation GeForce FX 5200LE/AGP/SSE2/3DNOW! supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA Corporation GeForce FX 5200SE/AGP/SSE2 supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA Corporation GeForce FX 5500/AGP/SSE2 supported 0 1 2.1 NVIDIA GeForce FX 5500
-NVIDIA Corporation GeForce FX 5500/AGP/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce FX 5500
-NVIDIA Corporation GeForce FX 5500/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce FX 5500
-NVIDIA Corporation GeForce FX 5500/PCI/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce FX 5500
-NVIDIA Corporation GeForce FX 5600/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce FX 5600
-NVIDIA Corporation GeForce FX 5600XT/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce FX 5600
-NVIDIA Corporation GeForce FX 5600XT/AGP/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce FX 5600
-NVIDIA Corporation GeForce FX 5600XT/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce FX 5600
-NVIDIA Corporation GeForce FX 5700/AGP/SSE2 supported 0 1 2.1 NVIDIA GeForce FX 5700
-NVIDIA Corporation GeForce FX 5700/AGP/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce FX 5700
-NVIDIA Corporation GeForce FX 5700LE/AGP/SSE2 supported 0 1 2.1 NVIDIA GeForce FX 5700
-NVIDIA Corporation GeForce FX 5700LE/AGP/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce FX 5700
-NVIDIA Corporation GeForce FX 5700LE/PCI/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce FX 5700
-NVIDIA Corporation GeForce FX 5700VE/AGP/SSE2 supported 0 1 2.1 NVIDIA GeForce FX 5700
-NVIDIA Corporation GeForce FX 5700VE/AGP/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce FX 5700
-NVIDIA Corporation GeForce FX 5900 Ultra/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce FX 5900
-NVIDIA Corporation GeForce FX 5900/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce FX 5900
-NVIDIA Corporation GeForce FX 5900XT/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce FX 5900
-NVIDIA Corporation GeForce FX 5900ZT/AGP/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce FX 5900
-NVIDIA Corporation GeForce FX 5950 Ultra/AGP/SSE2 supported 1 1 2.1 NVIDIA GeForce FX 5900
-NVIDIA Corporation GeForce FX 5950 Ultra/AGP/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce FX 5900
-NVIDIA Corporation GeForce FX Go5200 32M/64M/AGP/SSE2 supported 0 0 1.5 NVIDIA GeForce FX Go5200
-NVIDIA Corporation GeForce FX Go5200/AGP/SSE2 supported 0 0 1.5 NVIDIA GeForce FX Go5200
-NVIDIA Corporation GeForce FX Go5200/AGP/SSE2/3DNOW! supported 0 0 1.5 NVIDIA GeForce FX Go5200
-NVIDIA Corporation GeForce FX Go5200/PCI/SSE2 supported 0 0 1.5 NVIDIA GeForce FX Go5200
-NVIDIA Corporation GeForce FX Go5300/AGP/SSE2 supported 0 0 0 NVIDIA GeForce FX Go5300
-NVIDIA Corporation GeForce FX Go53xx Series/AGP/SSE2 supported 0 0 0 NVIDIA GeForce FX Go5300
-NVIDIA Corporation GeForce FX Go5600/AGP/SSE2 supported 0 1 2.1 NVIDIA GeForce FX Go5600
-NVIDIA Corporation GeForce FX Go5650/AGP/SSE2 supported 0 1 2.1 NVIDIA GeForce FX Go5600
-NVIDIA Corporation GeForce FX Go5700/AGP/SSE2 supported 1 1 1.5 NVIDIA GeForce FX Go5700
-NVIDIA Corporation GeForce FX Go5700/AGP/SSE2/3DNOW! supported 1 1 1.5 NVIDIA GeForce FX Go5700
-NVIDIA Corporation GeForce G 103M/PCI/SSE2 supported 1 1 3.3 NVIDIA G 100M
-NVIDIA Corporation GeForce G 103M/PCIe/SSE2 supported 1 1 3.3 NVIDIA G 100M
-NVIDIA Corporation GeForce G 105M/PCI/SSE2 supported 1 1 3.3 NVIDIA G 100M
-NVIDIA Corporation GeForce G 105M/PCIe/SSE2 supported 1 1 3.3 NVIDIA G 100M
-NVIDIA Corporation GeForce G 110M/PCI/SSE2 supported 1 1 3.3 NVIDIA G 110M
-NVIDIA Corporation GeForce G100/PCI/SSE2 supported 3 1 4.2 NVIDIA G100
-NVIDIA Corporation GeForce G100/PCI/SSE2/3DNOW! supported 3 1 4.2 NVIDIA G100
-NVIDIA Corporation GeForce G100/PCIe/SSE2 supported 3 1 4.2 NVIDIA G100
-NVIDIA Corporation GeForce G100/PCIe/SSE2/3DNOW! supported 3 1 4.2 NVIDIA G100
-NVIDIA Corporation GeForce G102M/PCI/SSE2 supported 1 1 3.3 NVIDIA G 100M
-NVIDIA Corporation GeForce G102M/integrated/SSE2 supported 1 1 3.3 NVIDIA G 100M
-NVIDIA Corporation GeForce G105M/PCI/SSE2 supported 1 1 3.3 NVIDIA G 100M
-NVIDIA Corporation GeForce G105M/PCIe/SSE2 supported 1 1 3.3 NVIDIA G 100M
-NVIDIA Corporation GeForce G200/PCI/SSE2 supported 2 1 3.3 NVIDIA G200
-NVIDIA Corporation GeForce G200/integrated/SSE2 supported 2 1 3.3 NVIDIA G200
-NVIDIA Corporation GeForce G205M/PCI/SSE2 supported 1 0 0 NVIDIA G 200M
-NVIDIA Corporation GeForce G205M/integrated/SSE2 supported 1 0 0 NVIDIA G 200M
-NVIDIA Corporation GeForce G210/PCI/SSE2 supported 3 1 3.3 NVIDIA G210
-NVIDIA Corporation GeForce G210/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA G210
-NVIDIA Corporation GeForce G210/PCIe/SSE2 supported 3 1 3.3 NVIDIA G210
-NVIDIA Corporation GeForce G210/PCIe/SSE2/3DNOW! supported 3 1 3.3 NVIDIA G210
-NVIDIA Corporation GeForce G210M/PCI/SSE2 supported 3 0 3.3 NVIDIA G210M
-NVIDIA Corporation GeForce G210M/PCIe/SSE2 supported 3 0 3.3 NVIDIA G210M
-NVIDIA Corporation GeForce GT 120/PCI/SSE2 supported 2 0 3.3 NVIDIA GT 120
-NVIDIA Corporation GeForce GT 120/PCI/SSE2/3DNOW! supported 2 0 3.3 NVIDIA GT 120
-NVIDIA Corporation GeForce GT 120/PCIe/SSE2 supported 2 0 3.3 NVIDIA GT 120
-NVIDIA Corporation GeForce GT 120/PCIe/SSE2/3DNOW! supported 2 0 3.3 NVIDIA GT 120
-NVIDIA Corporation GeForce GT 120M/PCI/SSE2 supported 2 0 3.3 NVIDIA GT 120
-NVIDIA Corporation GeForce GT 120M/PCIe/SSE2 supported 2 0 3.3 NVIDIA GT 120
-NVIDIA Corporation GeForce GT 130/PCI/SSE2 supported 2 0 3.3 NVIDIA GT 130
-NVIDIA Corporation GeForce GT 130/PCIe/SSE2 supported 2 0 3.3 NVIDIA GT 130
-NVIDIA Corporation GeForce GT 130/PCIe/SSE2/3DNOW! supported 2 0 3.3 NVIDIA GT 130
-NVIDIA Corporation GeForce GT 130M/PCI/SSE2 supported 3 1 3.3 NVIDIA GT 130M
-NVIDIA Corporation GeForce GT 130M/PCIe/SSE2 supported 3 1 3.3 NVIDIA GT 130M
-NVIDIA Corporation GeForce GT 140/PCI/SSE2 supported 2 0 3.3 NVIDIA GT 140
-NVIDIA Corporation GeForce GT 140/PCIe/SSE2 supported 2 0 3.3 NVIDIA GT 140
-NVIDIA Corporation GeForce GT 220/PCI/SSE2 supported 2 1 3.3 NVIDIA GT 220
-NVIDIA Corporation GeForce GT 220/PCI/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GT 220
-NVIDIA Corporation GeForce GT 220/PCIe/SSE2 supported 2 1 3.3 NVIDIA GT 220
-NVIDIA Corporation GeForce GT 220/PCIe/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GT 220
-NVIDIA Corporation GeForce GT 220M/PCI/SSE2 supported 3 1 3.3 NVIDIA GT 220M
-NVIDIA Corporation GeForce GT 220M/PCIe/SSE2 supported 3 1 3.3 NVIDIA GT 220M
-NVIDIA Corporation GeForce GT 230/PCI/SSE2 supported 2 1 3.3 NVIDIA GT 230
-NVIDIA Corporation GeForce GT 230/PCIe/SSE2 supported 2 1 3.3 NVIDIA GT 230
-NVIDIA Corporation GeForce GT 230/PCIe/SSE2/3DNOW! supported 2 1 3.3 NVIDIA GT 230
-NVIDIA Corporation GeForce GT 230M/PCI/SSE2 supported 3 1 3.3 NVIDIA GT 230M
-NVIDIA Corporation GeForce GT 230M/PCIe/SSE2 supported 3 1 3.3 NVIDIA GT 230M
-NVIDIA Corporation GeForce GT 240/PCI/SSE2 supported 4 1 3.3 NVIDIA GT 240
-NVIDIA Corporation GeForce GT 240/PCI/SSE2/3DNOW! supported 4 1 3.3 NVIDIA GT 240
-NVIDIA Corporation GeForce GT 240/PCIe/SSE2 supported 4 1 3.3 NVIDIA GT 240
-NVIDIA Corporation GeForce GT 240/PCIe/SSE2/3DNOW! supported 4 1 3.3 NVIDIA GT 240
-NVIDIA Corporation GeForce GT 240M LE/PCIe/SSE2 supported 3 1 3.3 NVIDIA GT 240M
-NVIDIA Corporation GeForce GT 240M/PCI/SSE2 supported 3 1 3.3 NVIDIA GT 240M
-NVIDIA Corporation GeForce GT 240M/PCI/SSE2/3DNOW! supported 3 1 3.3 NVIDIA GT 240M
-NVIDIA Corporation GeForce GT 240M/PCIe/SSE2 supported 3 1 3.3 NVIDIA GT 240M
-NVIDIA Corporation GeForce GT 320/PCI/SSE2 supported 3 0 3.3 NVIDIA GT 320
-NVIDIA Corporation GeForce GT 320/PCI/SSE2/3DNOW! supported 3 0 3.3 NVIDIA GT 320
-NVIDIA Corporation GeForce GT 320/PCIe/SSE2 supported 3 0 3.3 NVIDIA GT 320
-NVIDIA Corporation GeForce GT 320/PCIe/SSE2/3DNOW! supported 3 0 3.3 NVIDIA GT 320
-NVIDIA Corporation GeForce GT 320M/PCI/SSE2 supported 3 0 3.3 NVIDIA GT 320M
-NVIDIA Corporation GeForce GT 320M/PCIe/SSE2 supported 3 0 3.3 NVIDIA GT 320M
-NVIDIA Corporation GeForce GT 325M/PCI/SSE2 supported 3 0 3.3 NVIDIA GT 320M
-NVIDIA Corporation GeForce GT 325M/PCIe/SSE2 supported 3 0 3.3 NVIDIA GT 320M
-NVIDIA Corporation GeForce GT 330/PCI/SSE2 supported 3 0 3.3 NVIDIA GT 330
-NVIDIA Corporation GeForce GT 330/PCIe/SSE2 supported 3 0 3.3 NVIDIA GT 330
-NVIDIA Corporation GeForce GT 330/PCIe/SSE2/3DNOW! supported 3 0 3.3 NVIDIA GT 330
-NVIDIA Corporation GeForce GT 330M/PCI/SSE2 supported 3 1 3.3 NVIDIA GT 330M
-NVIDIA Corporation GeForce GT 330M/PCIe/SSE2 supported 3 1 3.3 NVIDIA GT 330M
-NVIDIA Corporation GeForce GT 335M/PCI/SSE2 supported 3 1 3.3 NVIDIA GT 330M
-NVIDIA Corporation GeForce GT 335M/PCIe/SSE2 supported 3 1 3.3 NVIDIA GT 330M
-NVIDIA Corporation GeForce GT 340/PCI/SSE2 supported 3 0 0 NVIDIA GT 340
-NVIDIA Corporation GeForce GT 340/PCIe/SSE2 supported 3 0 0 NVIDIA GT 340
-NVIDIA Corporation GeForce GT 415/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 415
-NVIDIA Corporation GeForce GT 415/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GT 415
-NVIDIA Corporation GeForce GT 415M/PCI/SSE2 supported 3 0 0 NVIDIA 410M
-NVIDIA Corporation GeForce GT 415M/PCIe/SSE2 supported 3 0 0 NVIDIA 410M
-NVIDIA Corporation GeForce GT 420/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 420
-NVIDIA Corporation GeForce GT 420/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 420
-NVIDIA Corporation GeForce GT 420/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GT 420
-NVIDIA Corporation GeForce GT 420M/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 420M
-NVIDIA Corporation GeForce GT 420M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 420M
-NVIDIA Corporation GeForce GT 425M/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 420M
-NVIDIA Corporation GeForce GT 425M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 420M
-NVIDIA Corporation GeForce GT 430/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 430
-NVIDIA Corporation GeForce GT 430/PCI/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GT 430
-NVIDIA Corporation GeForce GT 430/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 430
-NVIDIA Corporation GeForce GT 430/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GT 430
-NVIDIA Corporation GeForce GT 435M/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 430M
-NVIDIA Corporation GeForce GT 435M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 430M
-NVIDIA Corporation GeForce GT 440/PCI/SSE2 supported 4 1 4.3 NVIDIA GT 440
-NVIDIA Corporation GeForce GT 440/PCI/SSE2/3DNOW! supported 4 1 4.3 NVIDIA GT 440
-NVIDIA Corporation GeForce GT 440/PCIe/SSE2 supported 4 1 4.3 NVIDIA GT 440
-NVIDIA Corporation GeForce GT 440/PCIe/SSE2/3DNOW! supported 4 1 4.3 NVIDIA GT 440
-NVIDIA Corporation GeForce GT 445M/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 440M
-NVIDIA Corporation GeForce GT 445M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 440M
-NVIDIA Corporation GeForce GT 520/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 520
-NVIDIA Corporation GeForce GT 520/PCI/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GT 520
-NVIDIA Corporation GeForce GT 520/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 520
-NVIDIA Corporation GeForce GT 520/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GT 520
-NVIDIA Corporation GeForce GT 520M/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 520M
-NVIDIA Corporation GeForce GT 520M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 520M
-NVIDIA Corporation GeForce GT 520MX/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 520M
-NVIDIA Corporation GeForce GT 520MX/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 520M
-NVIDIA Corporation GeForce GT 525M/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 520M
-NVIDIA Corporation GeForce GT 525M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 520M
-NVIDIA Corporation GeForce GT 530/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 530
-NVIDIA Corporation GeForce GT 530/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 530
-NVIDIA Corporation GeForce GT 530/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GT 530
-NVIDIA Corporation GeForce GT 540M/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 540M
-NVIDIA Corporation GeForce GT 540M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 540M
-NVIDIA Corporation GeForce GT 545/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 540
-NVIDIA Corporation GeForce GT 545/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 540
-NVIDIA Corporation GeForce GT 545/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GT 540
-NVIDIA Corporation GeForce GT 550M/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 550M
-NVIDIA Corporation GeForce GT 550M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 550M
-NVIDIA Corporation GeForce GT 555M/PCI/SSE2 supported 3 1 4.3 NVIDIA GT 550M
-NVIDIA Corporation GeForce GT 555M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 550M
-NVIDIA Corporation GeForce GT 610/PCIe/SSE2 supported 3 1 4.3 NVIDIA GT 61x
-NVIDIA Corporation GeForce GT 610/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GT 61x
-NVIDIA Corporation GeForce GT 620/PCI/SSE2 supported 3 0 4.3 NVIDIA GT 62x
-NVIDIA Corporation GeForce GT 620/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 62x
-NVIDIA Corporation GeForce GT 620/PCIe/SSE2/3DNOW! supported 3 0 4.3 NVIDIA GT 62x
-NVIDIA Corporation GeForce GT 620M/PCI/SSE2 supported 3 0 4.3 NVIDIA GT 620M
-NVIDIA Corporation GeForce GT 620M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 620M
-NVIDIA Corporation GeForce GT 625/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 62x
-NVIDIA Corporation GeForce GT 625M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 620M
-NVIDIA Corporation GeForce GT 630/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 63x
-NVIDIA Corporation GeForce GT 630/PCIe/SSE2/3DNOW! supported 3 0 4.3 NVIDIA GT 63x
-NVIDIA Corporation GeForce GT 630M/PCI/SSE2 supported 3 0 4.3 NVIDIA GT 630M
-NVIDIA Corporation GeForce GT 630M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 630M
-NVIDIA Corporation GeForce GT 635M/PCI/SSE2 supported 3 0 4.3 NVIDIA GT 630M
-NVIDIA Corporation GeForce GT 635M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 630M
-NVIDIA Corporation GeForce GT 640/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 64x
-NVIDIA Corporation GeForce GT 640/PCIe/SSE2/3DNOW! supported 3 0 4.3 NVIDIA GT 64x
-NVIDIA Corporation GeForce GT 640M LE/PCI/SSE2 supported 3 0 4.3 NVIDIA GT 640M
-NVIDIA Corporation GeForce GT 640M LE/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 640M
-NVIDIA Corporation GeForce GT 640M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 640M
-NVIDIA Corporation GeForce GT 645/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 64x
-NVIDIA Corporation GeForce GT 645M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 640M
-NVIDIA Corporation GeForce GT 650M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 650M
-NVIDIA Corporation GeForce GT 720M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 720M
-NVIDIA Corporation GeForce GT 730M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 730M
-NVIDIA Corporation GeForce GT 735M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 730M
-NVIDIA Corporation GeForce GT 740M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 740M
-NVIDIA Corporation GeForce GT 750M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 750M
-NVIDIA Corporation GeForce GT620M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 620M
-NVIDIA Corporation GeForce GT625M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GT 620M
-NVIDIA Corporation GeForce GTS 150/PCI/SSE2 supported 2 0 0 NVIDIA GTS 150
-NVIDIA Corporation GeForce GTS 160M/PCI/SSE2 supported 2 0 0 NVIDIA GTS 160M
-NVIDIA Corporation GeForce GTS 160M/PCIe/SSE2 supported 2 0 0 NVIDIA GTS 160M
-NVIDIA Corporation GeForce GTS 240/PCI/SSE2 supported 4 1 3.3 NVIDIA GTS 240
-NVIDIA Corporation GeForce GTS 240/PCIe/SSE2 supported 4 1 3.3 NVIDIA GTS 240
-NVIDIA Corporation GeForce GTS 240/PCIe/SSE2/3DNOW! supported 4 1 3.3 NVIDIA GTS 240
-NVIDIA Corporation GeForce GTS 250/PCI/SSE2 supported 4 1 3.3 NVIDIA GTS 250
-NVIDIA Corporation GeForce GTS 250/PCI/SSE2/3DNOW! supported 4 1 3.3 NVIDIA GTS 250
-NVIDIA Corporation GeForce GTS 250/PCIe/SSE2 supported 4 1 3.3 NVIDIA GTS 250
-NVIDIA Corporation GeForce GTS 250/PCIe/SSE2/3DNOW! supported 4 1 3.3 NVIDIA GTS 250
-NVIDIA Corporation GeForce GTS 250M/PCI/SSE2 supported 3 0 3.3 NVIDIA GTS 250M
-NVIDIA Corporation GeForce GTS 250M/PCIe/SSE2 supported 3 0 3.3 NVIDIA GTS 250M
-NVIDIA Corporation GeForce GTS 350M/PCI/SSE2 supported 4 1 3.3 NVIDIA GTS 350M
-NVIDIA Corporation GeForce GTS 350M/PCIe/SSE2 supported 4 1 3.3 NVIDIA GTS 350M
-NVIDIA Corporation GeForce GTS 360M/PCI/SSE2 supported 5 1 3.3 NVIDIA GTS 360M
-NVIDIA Corporation GeForce GTS 360M/PCIe/SSE2 supported 5 1 3.3 NVIDIA GTS 360M
-NVIDIA Corporation GeForce GTS 450/PCI/SSE2 supported 4 1 4.3 NVIDIA GTS 450
-NVIDIA Corporation GeForce GTS 450/PCI/SSE2/3DNOW! supported 4 1 4.3 NVIDIA GTS 450
-NVIDIA Corporation GeForce GTS 450/PCIe/SSE2 supported 4 1 4.3 NVIDIA GTS 450
-NVIDIA Corporation GeForce GTS 450/PCIe/SSE2/3DNOW! supported 4 1 4.3 NVIDIA GTS 450
-NVIDIA Corporation GeForce GTX 260/PCI/SSE2 supported 4 1 3.3 NVIDIA GTX 260
-NVIDIA Corporation GeForce GTX 260/PCI/SSE2/3DNOW! supported 4 1 3.3 NVIDIA GTX 260
-NVIDIA Corporation GeForce GTX 260/PCIe/SSE2 supported 4 1 3.3 NVIDIA GTX 260
-NVIDIA Corporation GeForce GTX 260/PCIe/SSE2/3DNOW! supported 4 1 3.3 NVIDIA GTX 260
-NVIDIA Corporation GeForce GTX 260M/PCI/SSE2 supported 3 0 3.3 NVIDIA GTX 260M
-NVIDIA Corporation GeForce GTX 260M/PCIe/SSE2 supported 3 0 3.3 NVIDIA GTX 260M
-NVIDIA Corporation GeForce GTX 275/PCI/SSE2 supported 4 0 3.3 NVIDIA GTX 270
-NVIDIA Corporation GeForce GTX 275/PCI/SSE2/3DNOW! supported 4 0 3.3 NVIDIA GTX 270
-NVIDIA Corporation GeForce GTX 275/PCIe/SSE2 supported 4 0 3.3 NVIDIA GTX 270
-NVIDIA Corporation GeForce GTX 275/PCIe/SSE2/3DNOW! supported 4 0 3.3 NVIDIA GTX 270
-NVIDIA Corporation GeForce GTX 280/PCI/SSE2 supported 4 1 3.3 NVIDIA GTX 280
-NVIDIA Corporation GeForce GTX 280/PCIe/SSE2 supported 4 1 3.3 NVIDIA GTX 280
-NVIDIA Corporation GeForce GTX 280/PCIe/SSE2/3DNOW! supported 4 1 3.3 NVIDIA GTX 280
-NVIDIA Corporation GeForce GTX 280M/PCI/SSE2 supported 3 0 3.3 NVIDIA GTX 280M
-NVIDIA Corporation GeForce GTX 280M/PCIe/SSE2 supported 3 0 3.3 NVIDIA GTX 280M
-NVIDIA Corporation GeForce GTX 285/PCI/SSE2 supported 4 1 3.3 NVIDIA GTX 280
-NVIDIA Corporation GeForce GTX 285/PCIe/SSE2 supported 4 1 3.3 NVIDIA GTX 280
-NVIDIA Corporation GeForce GTX 285/PCIe/SSE2/3DNOW! supported 4 1 3.3 NVIDIA GTX 280
-NVIDIA Corporation GeForce GTX 285M/PCI/SSE2 supported 3 0 3.3 NVIDIA GTX 280M
-NVIDIA Corporation GeForce GTX 285M/PCIe/SSE2 supported 3 0 3.3 NVIDIA GTX 280M
-NVIDIA Corporation GeForce GTX 295/PCI/SSE2 supported 5 0 3.3 NVIDIA GTX 290
-NVIDIA Corporation GeForce GTX 295/PCIe/SSE2 supported 5 0 3.3 NVIDIA GTX 290
-NVIDIA Corporation GeForce GTX 295/PCIe/SSE2/3DNOW! supported 5 0 3.3 NVIDIA GTX 290
-NVIDIA Corporation GeForce GTX 460 SE/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460 SE/PCI/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460 SE/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460 SE/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460 v2/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460 v2/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460 v2/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460/PCI/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 460M/PCI/SSE2 supported 4 1 4.3 NVIDIA GTX 460M
-NVIDIA Corporation GeForce GTX 460M/PCIe/SSE2 supported 4 1 4.3 NVIDIA GTX 460M
-NVIDIA Corporation GeForce GTX 465/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 465/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 465/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation GeForce GTX 470/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 470
-NVIDIA Corporation GeForce GTX 470/PCI/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 470
-NVIDIA Corporation GeForce GTX 470/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 470
-NVIDIA Corporation GeForce GTX 470/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 470
-NVIDIA Corporation GeForce GTX 470M/PCI/SSE2 supported 3 0 4.3 NVIDIA GTX 470M
-NVIDIA Corporation GeForce GTX 480/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 480
-NVIDIA Corporation GeForce GTX 480/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 480
-NVIDIA Corporation GeForce GTX 480/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 480
-NVIDIA Corporation GeForce GTX 480M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GTX 480M
-NVIDIA Corporation GeForce GTX 485M/PCI/SSE2 supported 3 1 4.3 NVIDIA GTX 480M
-NVIDIA Corporation GeForce GTX 485M/PCIe/SSE2 supported 3 1 4.3 NVIDIA GTX 480M
-NVIDIA Corporation GeForce GTX 550 Ti/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 550
-NVIDIA Corporation GeForce GTX 550 Ti/PCI/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 550
-NVIDIA Corporation GeForce GTX 550 Ti/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 550
-NVIDIA Corporation GeForce GTX 550 Ti/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 550
-NVIDIA Corporation GeForce GTX 560 SE/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation GeForce GTX 560 Ti/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation GeForce GTX 560 Ti/PCI/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation GeForce GTX 560 Ti/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation GeForce GTX 560 Ti/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation GeForce GTX 560/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation GeForce GTX 560/PCI/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation GeForce GTX 560/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation GeForce GTX 560/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation GeForce GTX 560M/PCI/SSE2 supported 3 0 4.3 NVIDIA GTX 560M
-NVIDIA Corporation GeForce GTX 560M/PCIe/SSE2 supported 3 0 4.3 NVIDIA GTX 560M
-NVIDIA Corporation GeForce GTX 570/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 570
-NVIDIA Corporation GeForce GTX 570/PCI/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 570
-NVIDIA Corporation GeForce GTX 570/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 570
-NVIDIA Corporation GeForce GTX 570/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 570
-NVIDIA Corporation GeForce GTX 570M/PCI/SSE2 supported 5 0 4.3 NVIDIA GTX 570M
-NVIDIA Corporation GeForce GTX 570M/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 570M
-NVIDIA Corporation GeForce GTX 580/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 580
-NVIDIA Corporation GeForce GTX 580/PCI/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 580
-NVIDIA Corporation GeForce GTX 580/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 580
-NVIDIA Corporation GeForce GTX 580/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 580
-NVIDIA Corporation GeForce GTX 580M/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 580M
-NVIDIA Corporation GeForce GTX 580M/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 580M
-NVIDIA Corporation GeForce GTX 590/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 590
-NVIDIA Corporation GeForce GTX 590/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 590
-NVIDIA Corporation GeForce GTX 590/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 590
-NVIDIA Corporation GeForce GTX 645/PCIe/SSE2 supported 3 1 4.3 NVIDIA GTX 64x
-NVIDIA Corporation GeForce GTX 650 Ti BOOST/PCIe/SSE2 supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA Corporation GeForce GTX 650 Ti BOOST/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA Corporation GeForce GTX 650 Ti Boost/PCIe/SSE2 supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA Corporation GeForce GTX 650 Ti Boost/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA Corporation GeForce GTX 650 Ti/PCIe/SSE2 supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA Corporation GeForce GTX 650 Ti/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA Corporation GeForce GTX 650/PCIe/SSE2 supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA Corporation GeForce GTX 650/PCIe/SSE2/3DNOW! supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA Corporation GeForce GTX 660 Ti/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 66x
-NVIDIA Corporation GeForce GTX 660 Ti/PCIe/SSE2/3DNOW! supported 5 0 4.3 NVIDIA GTX 66x
-NVIDIA Corporation GeForce GTX 660/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 66x
-NVIDIA Corporation GeForce GTX 660/PCIe/SSE2/3DNOW! supported 5 0 4.3 NVIDIA GTX 66x
-NVIDIA Corporation GeForce GTX 660M/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 660M
-NVIDIA Corporation GeForce GTX 670/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 67x
-NVIDIA Corporation GeForce GTX 670/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 67x
-NVIDIA Corporation GeForce GTX 670M/PCI/SSE2 supported 5 1 4.3 NVIDIA GTX 670M
-NVIDIA Corporation GeForce GTX 670M/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 670M
-NVIDIA Corporation GeForce GTX 670MX/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 670M
-NVIDIA Corporation GeForce GTX 675M/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 670M
-NVIDIA Corporation GeForce GTX 675MX/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 670M
-NVIDIA Corporation GeForce GTX 680/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 68x
-NVIDIA Corporation GeForce GTX 680/PCIe/SSE2/3DNOW! supported 5 1 4.3 NVIDIA GTX 68x
-NVIDIA Corporation GeForce GTX 680M/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 680M
-NVIDIA Corporation GeForce GTX 680MX/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 680M
-NVIDIA Corporation GeForce GTX 690/PCIe/SSE2 supported 5 1 4.3 NVIDIA GTX 69x
-NVIDIA Corporation GeForce GTX 760/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 76x
-NVIDIA Corporation GeForce GTX 760M/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 760M
-NVIDIA Corporation GeForce GTX 765M/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 760M
-NVIDIA Corporation GeForce GTX 770/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 77x
-NVIDIA Corporation GeForce GTX 770/PCIe/SSE2/3DNOW! supported 5 0 4.3 NVIDIA GTX 77x
-NVIDIA Corporation GeForce GTX 770M/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 770M
-NVIDIA Corporation GeForce GTX 780/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 78x
-NVIDIA Corporation GeForce GTX 780M/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX 780M
-NVIDIA Corporation GeForce GTX TITAN/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX TITAN
-NVIDIA Corporation GeForce GTX TITAN/PCIe/SSE2/3DNOW! supported 5 0 4.3 NVIDIA GTX TITAN
-NVIDIA Corporation GeForce GTX Titan/PCIe/SSE2 supported 5 0 4.3 NVIDIA GTX TITAN
-NVIDIA Corporation GeForce Go 6100/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce Go 6100
-NVIDIA Corporation GeForce Go 6100/PCI/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce Go 6100
-NVIDIA Corporation GeForce Go 6150/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce Go 6100
-NVIDIA Corporation GeForce Go 6150/PCI/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce Go 6100
-NVIDIA Corporation GeForce Go 6150/integrated/SSE2/3DNOW! supported 0 1 2.1 NVIDIA GeForce Go 6100
-NVIDIA Corporation GeForce Go 6200/PCI/SSE2 supported 0 0 1.5 NVIDIA GeForce Go 6200
-NVIDIA Corporation GeForce Go 6200/PCI/SSE2/3DNOW! supported 0 0 1.5 NVIDIA GeForce Go 6200
-NVIDIA Corporation GeForce Go 6400/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 6400
-NVIDIA Corporation GeForce Go 6400/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 6400
-NVIDIA Corporation GeForce Go 6600 TE/6200 TE/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce Go 6600
-NVIDIA Corporation GeForce Go 6600/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce Go 6600
-NVIDIA Corporation GeForce Go 6800 Ultra/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce Go 6800
-NVIDIA Corporation GeForce Go 6800/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce Go 6800
-NVIDIA Corporation GeForce Go 6800/PCIe/SSE2 supported 0 1 2.1 NVIDIA GeForce Go 6800
-NVIDIA Corporation GeForce Go 7200/PCI/SSE2 supported 1 0 2.1 NVIDIA GeForce Go 7200
-NVIDIA Corporation GeForce Go 7200/PCI/SSE2/3DNOW! supported 1 0 2.1 NVIDIA GeForce Go 7200
-NVIDIA Corporation GeForce Go 7300/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7300
-NVIDIA Corporation GeForce Go 7300/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce Go 7300
-NVIDIA Corporation GeForce Go 7300/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7300
-NVIDIA Corporation GeForce Go 7400/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7400
-NVIDIA Corporation GeForce Go 7400/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce Go 7400
-NVIDIA Corporation GeForce Go 7400/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7400
-NVIDIA Corporation GeForce Go 7600 GT/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7600
-NVIDIA Corporation GeForce Go 7600/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7600
-NVIDIA Corporation GeForce Go 7600/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce Go 7600
-NVIDIA Corporation GeForce Go 7600/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7600
-NVIDIA Corporation GeForce Go 7600/PCIe/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce Go 7600
-NVIDIA Corporation GeForce Go 7700/PCI/SSE2 supported 0 1 2.1 NVIDIA GeForce Go 7700
-NVIDIA Corporation GeForce Go 7800 GTX/PCI/SSE2 supported 2 0 0 NVIDIA GeForce Go 7800
-NVIDIA Corporation GeForce Go 7800/PCI/SSE2 supported 2 0 0 NVIDIA GeForce Go 7800
-NVIDIA Corporation GeForce Go 7900 GS/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7900
-NVIDIA Corporation GeForce Go 7900 GS/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce Go 7900
-NVIDIA Corporation GeForce Go 7900 GS/PCIe/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7900
-NVIDIA Corporation GeForce Go 7900 GTX/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7900
-NVIDIA Corporation GeForce Go 7950 GTX/PCI/SSE2 supported 1 1 2.1 NVIDIA GeForce Go 7900
-NVIDIA Corporation GeForce Go 7950 GTX/PCI/SSE2/3DNOW! supported 1 1 2.1 NVIDIA GeForce Go 7900
-NVIDIA Corporation GeForce PCX 5300/PCI/SSE2 supported 0 0 1.5 NVIDIA GeForce PCX
-NVIDIA Corporation GeForce PCX 5750/PCI/SSE2 supported 0 0 1.5 NVIDIA GeForce PCX
-NVIDIA Corporation GeForce2 GTS/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 2
-NVIDIA Corporation GeForce2 MX/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 2
-NVIDIA Corporation GeForce2 MX/AGP/SSE2/3DNOW! supported 0 1 1.5 NVIDIA GeForce 2
-NVIDIA Corporation GeForce2 MX/PCI/SSE2 supported 0 1 1.5 NVIDIA GeForce 2
-NVIDIA Corporation GeForce3/AGP/SSE2 supported 2 1 2.1 NVIDIA GeForce 3
-NVIDIA Corporation GeForce3/AGP/SSE2/3DNOW! supported 2 1 2.1 NVIDIA GeForce 3
-NVIDIA Corporation GeForce4 420 Go 32M/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 420 Go 32M/AGP/SSE2/3DNOW! supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 420 Go 32M/PCI/SSE2/3DNOW! supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 420 Go/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 4200 Go/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 440 Go 64M/AGP/SSE2/3DNOW! supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 440 Go 64M/PCI/SSE2/3DNOW! supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 440 Go/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 448 Go/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 4000/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 4000/AGP/SSE2/3DNOW! supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 4000/PCI/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 4000/PCI/SSE2/3DNOW! supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 420/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 420/PCI/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 440 with AGP8X/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 440 with AGP8X/AGP/SSE2/3DNOW! supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 440 with AGP8X/PCI/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 440/440SE/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 440/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 440/AGP/SSE2/3DNOW! supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 440/PCI/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 440SE with AGP8X/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 440SE with AGP8X/PCI/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 460/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 MX 460/AGP/SSE2/3DNOW! supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 Ti 4200 with AGP8X/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 Ti 4200 with AGP8X/PCI/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 Ti 4200/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 Ti 4400/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 Ti 4600/AGP/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation GeForce4 Ti 4600/PCI/SSE2 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA Corporation ION LE/PCI/SSE2 supported 2 1 3.3 NVIDIA ION b
-NVIDIA Corporation ION LE/integrated/SSE2 supported 2 1 3.3 NVIDIA ION b
-NVIDIA Corporation ION/PCI/SSE2 supported 2 1 3.3 NVIDIA ION b
-NVIDIA Corporation ION/PCIe/SSE2 supported 2 1 3.3 NVIDIA ION b
-NVIDIA Corporation ION/PCIe/SSE2/3DNOW! supported 2 1 3.3 NVIDIA ION b
-NVIDIA Corporation ION/integrated/SSE2 supported 2 1 3.3 NVIDIA ION b
-NVIDIA Corporation MCP61/PCI/SSE2/3DNOW! supported 1 0 2.1 NVIDIA MCP61
-NVIDIA Corporation MCP7A-O/PCI/SSE2 supported 1 0 0 NVIDIA MCP7A
-NVIDIA Corporation MCP7A-P/PCI/SSE2 supported 1 0 0 NVIDIA MCP7A
-NVIDIA Corporation N10P-GV2/PCI/SSE2 supported 1 0 2.1 NVIDIA N10
-NVIDIA Corporation N11M-GE2/PCI/SSE2 supported 2 0 3.1 NVIDIA Corporation N11M
-NVIDIA Corporation N12P-GVR-B-A1/PCI/SSE2 supported 1 1 4.1 NVIDIA Corporation N12P
-NVIDIA Corporation NB9M-GE1/PCI/SSE2 supported 1 0 0 NVIDIA NB9M
-NVIDIA Corporation NB9M-GS/PCI/SSE2 supported 1 0 0 NVIDIA NB9M
-NVIDIA Corporation NV17/AGP/SSE2 supported 0 0 0 NVIDIA NV17
-NVIDIA Corporation NVIDIA GeForce 210 OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 210
-NVIDIA Corporation NVIDIA GeForce 310M OpenGL Engine supported 2 0 3.3 NVIDIA 310M
-NVIDIA Corporation NVIDIA GeForce 320M OpenGL Engine supported 2 0 3.3 NVIDIA 320M
-NVIDIA Corporation NVIDIA GeForce 6600 GT OpenGL Engine supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA Corporation NVIDIA GeForce 7300 GT OpenGL Engine supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA Corporation NVIDIA GeForce 7600 GT OpenGL Engine supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA Corporation NVIDIA GeForce 7950 GT OpenGL Engine supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA Corporation NVIDIA GeForce 8400 GS OpenGL Engine supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA Corporation NVIDIA GeForce 8500 GT OpenGL Engine supported 2 1 3.3 NVIDIA GeForce 8500
-NVIDIA Corporation NVIDIA GeForce 8600 GT OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation NVIDIA GeForce 8600 GTS OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA Corporation NVIDIA GeForce 8600M GT OpenGL Engine supported 2 1 3.3 NVIDIA GeForce 8600M
-NVIDIA Corporation NVIDIA GeForce 8800 GS OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation NVIDIA GeForce 8800 GT OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation NVIDIA GeForce 8800 GTS 512 OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation NVIDIA GeForce 8800 GTS OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation NVIDIA GeForce 8800 GTX OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation NVIDIA GeForce 8800 Ultra OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA Corporation NVIDIA GeForce 9200M GS OpenGL Engine supported 1 0 3.3 NVIDIA GeForce 9200M
-NVIDIA Corporation NVIDIA GeForce 9400 GT OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 9400
-NVIDIA Corporation NVIDIA GeForce 9400 OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 9400
-NVIDIA Corporation NVIDIA GeForce 9400M OpenGL Engine supported 2 1 3.3 NVIDIA GeForce 9400M
-NVIDIA Corporation NVIDIA GeForce 9500 GT OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 9500
-NVIDIA Corporation NVIDIA GeForce 9600 GT OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA Corporation NVIDIA GeForce 9600M GT OpenGL Engine supported 2 1 3.3 NVIDIA GeForce 9600M
-NVIDIA Corporation NVIDIA GeForce 9800 GT OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation NVIDIA GeForce 9800 GTX+ OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA Corporation NVIDIA GeForce GT 120 OpenGL Engine supported 2 0 3.3 NVIDIA GT 120
-NVIDIA Corporation NVIDIA GeForce GT 130 OpenGL Engine supported 2 0 3.3 NVIDIA GT 130
-NVIDIA Corporation NVIDIA GeForce GT 220 OpenGL Engine supported 2 1 3.3 NVIDIA GT 220
-NVIDIA Corporation NVIDIA GeForce GT 240 OpenGL Engine supported 4 1 3.3 NVIDIA GT 240
-NVIDIA Corporation NVIDIA GeForce GT 320M OpenGL Engine supported 3 0 3.3 NVIDIA GT 320M
-NVIDIA Corporation NVIDIA GeForce GT 330M OpenGL Engine supported 3 1 3.3 NVIDIA GT 330M
-NVIDIA Corporation NVIDIA GeForce GT 430 OpenGL Engine supported 3 1 4.3 NVIDIA GT 430
-NVIDIA Corporation NVIDIA GeForce GT 440 OpenGL Engine supported 4 1 4.3 NVIDIA GT 440
-NVIDIA Corporation NVIDIA GeForce GT 520 OpenGL Engine supported 3 1 4.3 NVIDIA GT 520
-NVIDIA Corporation NVIDIA GeForce GT 630 OpenGL Engine supported 3 0 4.3 NVIDIA GT 63x
-NVIDIA Corporation NVIDIA GeForce GT 640 OpenGL Engine supported 3 0 4.3 NVIDIA GT 64x
-NVIDIA Corporation NVIDIA GeForce GT 640M OpenGL Engine supported 3 0 4.3 NVIDIA GT 640M
-NVIDIA Corporation NVIDIA GeForce GT 650M OpenGL Engine supported 3 0 4.3 NVIDIA GT 650M
-NVIDIA Corporation NVIDIA GeForce GTS 250 OpenGL Engine supported 4 1 3.3 NVIDIA GTS 250
-NVIDIA Corporation NVIDIA GeForce GTS 450 OpenGL Engine supported 4 1 4.3 NVIDIA GTS 450
-NVIDIA Corporation NVIDIA GeForce GTX 260 OpenGL Engine supported 4 1 3.3 NVIDIA GTX 260
-NVIDIA Corporation NVIDIA GeForce GTX 280 OpenGL Engine supported 4 1 3.3 NVIDIA GTX 280
-NVIDIA Corporation NVIDIA GeForce GTX 285 OpenGL Engine supported 4 1 3.3 NVIDIA GTX 280
-NVIDIA Corporation NVIDIA GeForce GTX 460 OpenGL Engine supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA Corporation NVIDIA GeForce GTX 470 OpenGL Engine supported 5 1 4.3 NVIDIA GTX 470
-NVIDIA Corporation NVIDIA GeForce GTX 480 OpenGL Engine supported 5 1 4.3 NVIDIA GTX 480
-NVIDIA Corporation NVIDIA GeForce GTX 550 Ti OpenGL Engine supported 5 1 4.3 NVIDIA GTX 550
-NVIDIA Corporation NVIDIA GeForce GTX 560 OpenGL Engine supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation NVIDIA GeForce GTX 560 Ti OpenGL Engine supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA Corporation NVIDIA GeForce GTX 570 OpenGL Engine supported 5 1 4.3 NVIDIA GTX 570
-NVIDIA Corporation NVIDIA GeForce GTX 580 OpenGL Engine supported 5 1 4.3 NVIDIA GTX 580
-NVIDIA Corporation NVIDIA GeForce GTX 650 OpenGL Engine supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA Corporation NVIDIA GeForce GTX 650 Ti OpenGL Engine supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA Corporation NVIDIA GeForce GTX 660 OpenGL Engine supported 5 0 4.3 NVIDIA GTX 66x
-NVIDIA Corporation NVIDIA GeForce GTX 660 Ti OpenGL Engine supported 5 0 4.3 NVIDIA GTX 66x
-NVIDIA Corporation NVIDIA GeForce GTX 660M OpenGL Engine supported 5 0 4.3 NVIDIA GTX 660M
-NVIDIA Corporation NVIDIA GeForce GTX 670 OpenGL Engine supported 5 1 4.3 NVIDIA GTX 67x
-NVIDIA Corporation NVIDIA GeForce GTX 675MX OpenGL Engine supported 5 1 4.3 NVIDIA GTX 670M
-NVIDIA Corporation NVIDIA GeForce GTX 680 OpenGL Engine supported 5 1 4.3 NVIDIA GTX 68x
-NVIDIA Corporation NVIDIA GeForce GTX 680MX OpenGL Engine supported 5 0 4.3 NVIDIA GTX 680M
-NVIDIA Corporation NVIDIA GeForce GTX 775M OpenGL Engine supported 5 0 4.3 NVIDIA GTX 770M
-NVIDIA Corporation NVIDIA GeForce GTX 780M OpenGL Engine supported 5 0 4.3 NVIDIA GTX 780M
-NVIDIA Corporation NVIDIA GeForce Go 7600 OpenGL Engine supported 1 1 2.1 NVIDIA GeForce Go 7600
-NVIDIA Corporation NVIDIA GeForce Pre-Release D14P2-30 OpenGL Engine supported 2 1 3.3 NVIDIA GeForce Pre-Release
-NVIDIA Corporation NVIDIA GeForce Pre-Release GK104 OpenGL Engine supported 2 1 3.3 NVIDIA GeForce Pre-Release
-NVIDIA Corporation NVIDIA GeForce Pre-Release ION OpenGL Engine supported 2 1 3.3 NVIDIA GeForce Pre-Release
-NVIDIA Corporation NVIDIA GeForce Pre-Release Unknown OpenGL Engine supported 2 1 3.3 NVIDIA GeForce Pre-Release
-NVIDIA Corporation NVIDIA NV34MAP OpenGL Engine supported 0 0 0 NVIDIA NV34
-NVIDIA Corporation NVIDIA Quadro 4000 OpenGL Engine supported 3 0 4.2 NVIDIA Quadro 4000
-NVIDIA Corporation NVIDIA Quadro FX 4500 OpenGL Engine supported 3 0 2.1 NVIDIA Quadro FX 4500
-NVIDIA Corporation NVIDIA Quadro FX 4800 OpenGL Engine supported 3 0 3.1 NVIDIA Quadro FX 4800
-NVIDIA Corporation NVIDIA Quadro FX 5600 OpenGL Engine supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation NVIDIA Quadro FX 580 OpenGL Engine supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation NVIDIA Quadro FX 770M OpenGL Engine supported 2 0 3.3 NVIDIA Quadro FX 770M
-NVIDIA Corporation NVS 2100M/PCI/SSE2 supported 2 0 3.3 NVIDIA Quadro NVS 2100M
-NVIDIA Corporation NVS 2100M/PCIe/SSE2 supported 2 0 3.3 NVIDIA Quadro NVS 2100M
-NVIDIA Corporation NVS 300/PCI/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation NVS 300/PCI/SSE2/3DNOW! supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation NVS 300/PCIe/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation NVS 310/PCIe/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation NVS 3100M/PCI/SSE2 supported 2 0 3.3 NVIDIA Quadro NVS 3100M
-NVIDIA Corporation NVS 3100M/PCIe/SSE2 supported 2 0 3.3 NVIDIA Quadro NVS 3100M
-NVIDIA Corporation NVS 315/PCIe/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation NVS 4200M/PCI/SSE2 supported 2 0 4.2 NVIDIA Quadro NVS 4200M
-NVIDIA Corporation NVS 4200M/PCIe/SSE2 supported 2 0 4.2 NVIDIA Quadro NVS 4200M
-NVIDIA Corporation NVS 510/PCIe/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation NVS 5100M/PCI/SSE2 supported 2 0 0 NVIDIA Quadro NVS 5100M
-NVIDIA Corporation NVS 5100M/PCIe/SSE2 supported 2 0 0 NVIDIA Quadro NVS 5100M
-NVIDIA Corporation NVS 5200M/PCI/SSE2 supported 2 0 0 NVIDIA Quadro NVS 5200M
-NVIDIA Corporation NVS 5200M/PCIe/SSE2 supported 2 0 0 NVIDIA Quadro NVS 5200M
-NVIDIA Corporation NVS 5400M/PCIe/SSE2 supported 2 0 0 NVIDIA Quadro NVS 5400M
-NVIDIA Corporation Quadro 1000M/PCI/SSE2 supported 2 0 4.2 NVIDIA Quadro 1000M
-NVIDIA Corporation Quadro 1000M/PCIe/SSE2 supported 2 0 4.2 NVIDIA Quadro 1000M
-NVIDIA Corporation Quadro 1100M/PCIe/SSE2 supported 2 0 3.3 NVIDIA Quadro 1100M
-NVIDIA Corporation Quadro 2000 D/PCI/SSE2 supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Corporation Quadro 2000/PCI/SSE2 supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Corporation Quadro 2000/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Corporation Quadro 2000D/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Corporation Quadro 2000M/PCI/SSE2 supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Corporation Quadro 2000M/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Corporation Quadro 3000M/PCI/SSE2 supported 3 0 4.2 NVIDIA Quadro 3000M
-NVIDIA Corporation Quadro 3000M/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 3000M
-NVIDIA Corporation Quadro 400/PCI/SSE2 supported 2 0 3.3 NVIDIA Quadro 400
-NVIDIA Corporation Quadro 400/PCI/SSE2/3DNOW! supported 2 0 3.3 NVIDIA Quadro 400
-NVIDIA Corporation Quadro 400/PCIe/SSE2 supported 2 0 3.3 NVIDIA Quadro 400
-NVIDIA Corporation Quadro 4000/PCI/SSE2 supported 3 0 4.2 NVIDIA Quadro 4000
-NVIDIA Corporation Quadro 4000/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 4000
-NVIDIA Corporation Quadro 4000M/PCI/SSE2 supported 3 0 4.2 NVIDIA Quadro 4000M
-NVIDIA Corporation Quadro 4000M/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 4000M
-NVIDIA Corporation Quadro 410/PCIe/SSE2 supported 3 0 3.3 NVIDIA 410
-NVIDIA Corporation Quadro 5000/PCI/SSE2 supported 3 0 4.2 NVIDIA Quadro 50x0 M
-NVIDIA Corporation Quadro 5000/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 50x0 M
-NVIDIA Corporation Quadro 5000M/PCI/SSE2 supported 3 0 4.2 NVIDIA Quadro 50x0 M
-NVIDIA Corporation Quadro 5000M/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 50x0 M
-NVIDIA Corporation Quadro 5010M/PCI/SSE2 supported 3 0 4.2 NVIDIA Quadro 50x0 M
-NVIDIA Corporation Quadro 5010M/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 50x0 M
-NVIDIA Corporation Quadro 600/PCI/SSE2 supported 2 0 4.2 NVIDIA Quadro K600
-NVIDIA Corporation Quadro 600/PCIe/SSE2 supported 2 0 4.2 NVIDIA Quadro K600
-NVIDIA Corporation Quadro 600/PCIe/SSE2/3DNOW! supported 2 0 4.2 NVIDIA Quadro K600
-NVIDIA Corporation Quadro 6000/PCIe/SSE2 supported 3 0 0 NVIDIA Quadro 6000
-NVIDIA Corporation Quadro FX 1000/AGP/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1100/AGP/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1300/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1400/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1400/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1400/PCIe/SSE2/3DNOW! supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1500/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1500/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1500/PCIe/SSE2/3DNOW! supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1500M/PCI/SSE2 supported 1 0 2.1 NVIDIA Quadro FX 1500M
-NVIDIA Corporation Quadro FX 1600M/PCI/SSE2 supported 2 0 3.3 NVIDIA Quadro FX 1600M
-NVIDIA Corporation Quadro FX 1600M/PCIe/SSE2 supported 2 0 3.3 NVIDIA Quadro FX 1600M
-NVIDIA Corporation Quadro FX 1700/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1700/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1700/PCIe/SSE2/3DNOW! supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1700M/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1700M/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1800/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1800/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1800M/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 1800M/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 2000/AGP/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 2500M/PCI/SSE2 supported 2 0 2.1 NVIDIA Quadro FX 2500M
-NVIDIA Corporation Quadro FX 2500M/PCIe/SSE2 supported 2 0 2.1 NVIDIA Quadro FX 2500M
-NVIDIA Corporation Quadro FX 2700M/PCI/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 2700M
-NVIDIA Corporation Quadro FX 2700M/PCIe/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 2700M
-NVIDIA Corporation Quadro FX 2800M/PCI/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 2800M
-NVIDIA Corporation Quadro FX 2800M/PCIe/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 2800M
-NVIDIA Corporation Quadro FX 3000/AGP/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 3400/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 3450/4000 SDI/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 3450/4000 SDI/PCI/SSE2/3DNOW! supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 3450/4000 SDI/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 3500/PCI/SSE2 supported 2 0 2.1 NVIDIA Quadro FX 3500
-NVIDIA Corporation Quadro FX 3500/PCIe/SSE2 supported 2 0 2.1 NVIDIA Quadro FX 3500
-NVIDIA Corporation Quadro FX 3500M/PCI/SSE2 supported 2 0 2.1 NVIDIA Quadro FX 3500
-NVIDIA Corporation Quadro FX 350M/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 3600M/PCI/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 3600
-NVIDIA Corporation Quadro FX 3600M/PCIe/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 3600
-NVIDIA Corporation Quadro FX 360M/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 360M/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 370 Low Profile/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 370/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 370/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 370/PCIe/SSE2/3DNOW! supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 3700/PCI/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 3700
-NVIDIA Corporation Quadro FX 3700/PCIe/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 3700
-NVIDIA Corporation Quadro FX 3700M/PCI/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 3700
-NVIDIA Corporation Quadro FX 3700M/PCIe/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 3700
-NVIDIA Corporation Quadro FX 370M/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 370M/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 380 LP/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 380 LP/PCIe/SSE2/3DNOW! supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 380/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 380/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 3800/PCI/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 3800
-NVIDIA Corporation Quadro FX 3800/PCIe/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 3800
-NVIDIA Corporation Quadro FX 3800M/PCI/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 3800
-NVIDIA Corporation Quadro FX 3800M/PCIe/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 3800
-NVIDIA Corporation Quadro FX 380M/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 380M/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 4500/PCI/SSE2 supported 3 0 2.1 NVIDIA Quadro FX 4500
-NVIDIA Corporation Quadro FX 4500/PCIe/SSE2 supported 3 0 2.1 NVIDIA Quadro FX 4500
-NVIDIA Corporation Quadro FX 4600/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 4800/PCI/SSE2 supported 3 0 3.1 NVIDIA Quadro FX 4800
-NVIDIA Corporation Quadro FX 4800/PCIe/SSE2 supported 3 0 3.1 NVIDIA Quadro FX 4800
-NVIDIA Corporation Quadro FX 500/AGP/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 500/FX 600/AGP/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 500/FX 600/AGP/SSE2/3DNOW! supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 500/FX 600/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 540/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 540/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 550/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 550/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 5500/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 560/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 560/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 5600/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 570/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 570/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 570M/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 570M/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 580/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 580/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 5800/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX 770M/PCI/SSE2 supported 2 0 3.3 NVIDIA Quadro FX 770M
-NVIDIA Corporation Quadro FX 770M/PCIe/SSE2 supported 2 0 3.3 NVIDIA Quadro FX 770M
-NVIDIA Corporation Quadro FX 880M/PCI/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 880M
-NVIDIA Corporation Quadro FX 880M/PCIe/SSE2 supported 3 0 3.3 NVIDIA Quadro FX 880M
-NVIDIA Corporation Quadro FX Go1400/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX Go1400/PCIe/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro FX Go700/AGP/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation Quadro K1000/PCIe/SSE2 supported 2 0 4.2 NVIDIA Quadro K1000
-NVIDIA Corporation Quadro K1000M/PCIe/SSE2 supported 2 0 4.2 NVIDIA Quadro 1000M
-NVIDIA Corporation Quadro K2000/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Corporation Quadro K2000D/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Corporation Quadro K2000M/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Corporation Quadro K3000M/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 3000M
-NVIDIA Corporation Quadro K4000/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 4000
-NVIDIA Corporation Quadro K4000M/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 4000M
-NVIDIA Corporation Quadro K5000/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 50x0 M
-NVIDIA Corporation Quadro K5000M/PCIe/SSE2 supported 3 0 4.2 NVIDIA Quadro 50x0 M
-NVIDIA Corporation Quadro K600/PCIe/SSE2 supported 2 0 4.2 NVIDIA Quadro K600
-NVIDIA Corporation Quadro NVS 110M/PCI/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 130M/PCI/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 130M/PCIe/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 135M/PCI/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 135M/PCIe/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 140M/PCI/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 140M/PCIe/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 150M/PCI/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 150M/PCIe/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 160M/PCI/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 160M/PCIe/SSE2 supported 0 1 3.3 NVIDIA Quadro NVS 1xxM
-NVIDIA Corporation Quadro NVS 210S / GeForce 6150LE/PCI/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 210S / GeForce 6150LE/PCI/SSE2/3DNOW! supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 210S / GeForce 6150LE/integrated/SSE2/3DNOW! supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 210S / NVIDIA GeForce 6150LE/PCI/SSE2/3DNOW! supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 210S/PCI/SSE2/3DNOW! supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 280 PCI-E/PCI/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 280 SD/AGP/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 285/PCI/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 285/PCIe/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 290/PCI/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 290/PCIe/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 290/PCIe/SSE2/3DNOW! supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 295/PCI/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 295/PCIe/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 300M/PCI/SSE2 supported 2 0 0 NVIDIA Quadro NVS 300M
-NVIDIA Corporation Quadro NVS 320M/PCI/SSE2 supported 2 0 0 NVIDIA Quadro NVS 320M
-NVIDIA Corporation Quadro NVS 320M/PCIe/SSE2 supported 2 0 0 NVIDIA Quadro NVS 320M
-NVIDIA Corporation Quadro NVS 420/PCI/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 420/PCIe/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 420/PCIe/SSE2/3DNOW! supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 450/PCIe/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 510M/PCI/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS 55/280 PCI/PCI/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS with AGP8X/AGP/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro NVS/AGP/SSE2 supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Corporation Quadro PCI-E Series/PCI/SSE2 NO MATCH
-NVIDIA Corporation Quadro2 MXR/AGP/SSE2 supported 0 0 1.5 NVIDIA Quadro2
-NVIDIA Corporation Quadro4 380 XGL/AGP/SSE2 supported 0 0 1.5 NVIDIA Quadro4
-NVIDIA Corporation Quadro4 550 XGL/AGP/SSE2 supported 0 0 1.5 NVIDIA Quadro4
-NVIDIA Corporation Quadro4 700 XGL/AGP/SSE2 supported 0 0 1.5 NVIDIA Quadro4
-NVIDIA Corporation Quadro4 980 XGL/AGP/SSE2 supported 0 0 1.5 NVIDIA Quadro4
-NVIDIA Corporation RIVA TNT2/AGP/SSE2 unsupported 0 0 1.5 NVIDIA RIVA TNT
-NVIDIA Corporation RIVA TNT2/AGP/SSE2/3DNOW! unsupported 0 0 1.5 NVIDIA RIVA TNT
-NVIDIA Corporation Stinger/emulated by Quadro FX 500/FX 600/PCI/SSE2 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Corporation nForce 750a SLI/PCI/SSE2 unsupported 0 0 3.3 NVIDIA nForce
-NVIDIA Corporation nForce 750a SLI/integrated/SSE2 unsupported 0 0 3.3 NVIDIA nForce
-NVIDIA Corporation nForce 760i SLI/integrated/SSE2 unsupported 0 0 3.3 NVIDIA nForce
-NVIDIA Corporation nForce 980a/780a SLI/integrated/SSE2 unsupported 0 0 3.3 NVIDIA nForce
-NVIDIA Corporation unknown board/AGP/SSE2 unsupported 0 0 2.1 NVIDIA Generic Unknown
-NVIDIA Corporation unknown board/PCI/SSE2 unsupported 0 0 2.1 NVIDIA Generic Unknown
-NVIDIA Corporation unknown board/PCI/SSE2/3DNOW! unsupported 0 0 2.1 NVIDIA Generic Unknown
-NVIDIA Corporation unknown board/PCIe/SSE2 unsupported 0 0 2.1 NVIDIA Generic Unknown
-NVIDIA D9M supported 1 0 0 NVIDIA D9M
-NVIDIA G 103M supported 1 1 3.3 NVIDIA G 100M
-NVIDIA G 105M supported 1 1 3.3 NVIDIA G 100M
-NVIDIA G 110M supported 1 1 3.3 NVIDIA G 110M
-NVIDIA G 120M supported 1 1 3.3 NVIDIA G 120M
-NVIDIA G 200 supported 2 1 3.3 NVIDIA G200
-NVIDIA G 205M supported 1 0 0 NVIDIA G 200M
-NVIDIA G 210 supported 3 1 3.3 NVIDIA G210
-NVIDIA G 310M supported 2 0 3.3 NVIDIA G 310M
-NVIDIA G 320M supported 3 0 3.3 NVIDIA GT 320M
-NVIDIA G 405 supported 3 0 3.3 NVIDIA 405
-NVIDIA G 410M supported 3 1 4.2 NVIDIA G 410M
-NVIDIA G 610M supported 3 1 4.3 NVIDIA 610M
-NVIDIA G100 supported 3 1 4.2 NVIDIA G100
-NVIDIA G100M supported 1 1 3.3 NVIDIA G 100M
-NVIDIA G102M supported 1 1 3.3 NVIDIA G 100M
-NVIDIA G103M supported 1 1 3.3 NVIDIA G 100M
-NVIDIA G105M supported 1 1 3.3 NVIDIA G 100M
-NVIDIA G200 supported 2 1 3.3 NVIDIA G200
-NVIDIA G210 supported 3 1 3.3 NVIDIA G210
-NVIDIA G210M supported 3 0 3.3 NVIDIA G210M
-NVIDIA G73 supported 1 0 0 NVIDIA G73
-NVIDIA G84 supported 2 0 0 NVIDIA G84
-NVIDIA G92 supported 3 0 0 NVIDIA G92
-NVIDIA G94 supported 3 0 0 NVIDIA G94
-NVIDIA GT 120 supported 2 0 3.3 NVIDIA GT 120
-NVIDIA GT 120M supported 2 0 3.3 NVIDIA GT 120
-NVIDIA GT 130 supported 2 0 3.3 NVIDIA GT 130
-NVIDIA GT 130M supported 3 1 3.3 NVIDIA GT 130M
-NVIDIA GT 140 supported 2 0 3.3 NVIDIA GT 140
-NVIDIA GT 140M supported 3 1 3.3 NVIDIA GT 140M
-NVIDIA GT 150 supported 2 1 3.3 NVIDIA GT 150
-NVIDIA GT 220 supported 2 1 3.3 NVIDIA GT 220
-NVIDIA GT 220M supported 3 1 3.3 NVIDIA GT 220M
-NVIDIA GT 230 supported 2 1 3.3 NVIDIA GT 230
-NVIDIA GT 230M supported 3 1 3.3 NVIDIA GT 230M
-NVIDIA GT 240 supported 4 1 3.3 NVIDIA GT 240
-NVIDIA GT 240M supported 3 1 3.3 NVIDIA GT 240M
-NVIDIA GT 260M supported 3 1 3.3 NVIDIA GT 260M
-NVIDIA GT 320 supported 3 0 3.3 NVIDIA GT 320
-NVIDIA GT 320M supported 3 0 3.3 NVIDIA GT 320M
-NVIDIA GT 325M supported 3 0 3.3 NVIDIA GT 320M
-NVIDIA GT 330 supported 3 0 3.3 NVIDIA GT 330
-NVIDIA GT 330M supported 3 1 3.3 NVIDIA GT 330M
-NVIDIA GT 335M supported 3 1 3.3 NVIDIA GT 330M
-NVIDIA GT 340 supported 3 0 0 NVIDIA GT 340
-NVIDIA GT 340M supported 4 1 3.3 NVIDIA GT 340M
-NVIDIA GT 415M supported 3 0 0 NVIDIA 410M
-NVIDIA GT 420 supported 3 1 4.3 NVIDIA GT 420
-NVIDIA GT 420M supported 3 1 4.3 NVIDIA GT 420M
-NVIDIA GT 425M supported 3 1 4.3 NVIDIA GT 420M
-NVIDIA GT 430 supported 3 1 4.3 NVIDIA GT 430
-NVIDIA GT 430M supported 3 1 4.3 NVIDIA GT 430M
-NVIDIA GT 435M supported 3 1 4.3 NVIDIA GT 430M
-NVIDIA GT 440 supported 4 1 4.3 NVIDIA GT 440
-NVIDIA GT 440M supported 3 1 4.3 NVIDIA GT 440M
-NVIDIA GT 445M supported 3 1 4.3 NVIDIA GT 440M
-NVIDIA GT 450 supported 4 1 4.3 NVIDIA GT 450
-NVIDIA GT 520 supported 3 1 4.3 NVIDIA GT 520
-NVIDIA GT 520M supported 3 1 4.3 NVIDIA GT 520M
-NVIDIA GT 525M supported 3 1 4.3 NVIDIA GT 520M
-NVIDIA GT 530M supported 3 1 4.3 NVIDIA GT 530M
-NVIDIA GT 540 supported 3 1 4.3 NVIDIA GT 540
-NVIDIA GT 540M supported 3 1 4.3 NVIDIA GT 540M
-NVIDIA GT 550 supported 3 1 4.3 NVIDIA GT 550
-NVIDIA GT 550M supported 3 1 4.3 NVIDIA GT 550M
-NVIDIA GT 555M supported 3 1 4.3 NVIDIA GT 550M
-NVIDIA GT 610 supported 3 1 4.3 NVIDIA GT 61x
-NVIDIA GT 620 supported 3 0 4.3 NVIDIA GT 62x
-NVIDIA GT 620M supported 3 0 4.3 NVIDIA GT 620M
-NVIDIA GT 630 supported 3 0 4.3 NVIDIA GT 63x
-NVIDIA GT 630M supported 3 0 4.3 NVIDIA GT 630M
-NVIDIA GT 635M supported 3 0 4.3 NVIDIA GT 630M
-NVIDIA GT 640 supported 3 0 4.3 NVIDIA GT 64x
-NVIDIA GT 640M supported 3 0 4.3 NVIDIA GT 640M
-NVIDIA GT 650 supported 3 1 4.3 NVIDIA GT 65x
-NVIDIA GT 650M supported 3 0 4.3 NVIDIA GT 650M
-NVIDIA GTS 160M supported 2 0 0 NVIDIA GTS 160M
-NVIDIA GTS 240 supported 4 1 3.3 NVIDIA GTS 240
-NVIDIA GTS 250 supported 4 1 3.3 NVIDIA GTS 250
-NVIDIA GTS 350M supported 4 1 3.3 NVIDIA GTS 350M
-NVIDIA GTS 360 supported 4 1 3.3 NVIDIA GTS 360
-NVIDIA GTS 360M supported 5 1 3.3 NVIDIA GTS 360M
-NVIDIA GTS 450 supported 4 1 4.3 NVIDIA GTS 450
-NVIDIA GTX 260 supported 4 1 3.3 NVIDIA GTX 260
-NVIDIA GTX 270 supported 4 0 3.3 NVIDIA GTX 270
-NVIDIA GTX 275 supported 4 0 3.3 NVIDIA GTX 270
-NVIDIA GTX 280 supported 4 1 3.3 NVIDIA GTX 280
-NVIDIA GTX 285 supported 4 1 3.3 NVIDIA GTX 280
-NVIDIA GTX 290 supported 5 0 3.3 NVIDIA GTX 290
-NVIDIA GTX 295 supported 5 0 3.3 NVIDIA GTX 290
-NVIDIA GTX 460 supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA GTX 460M supported 4 1 4.3 NVIDIA GTX 460M
-NVIDIA GTX 465 supported 5 1 4.3 NVIDIA GTX 460
-NVIDIA GTX 470 supported 5 1 4.3 NVIDIA GTX 470
-NVIDIA GTX 470M supported 3 0 4.3 NVIDIA GTX 470M
-NVIDIA GTX 480 supported 5 1 4.3 NVIDIA GTX 480
-NVIDIA GTX 480M supported 3 1 4.3 NVIDIA GTX 480M
-NVIDIA GTX 485M supported 3 1 4.3 NVIDIA GTX 480M
-NVIDIA GTX 550 supported 5 1 4.3 NVIDIA GTX 550
-NVIDIA GTX 560 supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA GTX 560 Ti supported 5 1 4.3 NVIDIA GTX 560
-NVIDIA GTX 570 supported 5 1 4.3 NVIDIA GTX 570
-NVIDIA GTX 580 supported 5 1 4.3 NVIDIA GTX 580
-NVIDIA GTX 580M supported 5 1 4.3 NVIDIA GTX 580M
-NVIDIA GTX 590 supported 5 1 4.3 NVIDIA GTX 590
-NVIDIA GTX 650 supported 3 1 4.3 NVIDIA GTX 65x
-NVIDIA GTX 660 supported 5 0 4.3 NVIDIA GTX 66x
-NVIDIA GTX 670 supported 5 1 4.3 NVIDIA GTX 67x
-NVIDIA GTX 670M supported 5 1 4.3 NVIDIA GTX 670M
-NVIDIA GTX 675M supported 5 1 4.3 NVIDIA GTX 670M
-NVIDIA GTX 680 supported 5 1 4.3 NVIDIA GTX 68x
-NVIDIA GTX 680M supported 5 0 4.3 NVIDIA GTX 680M
-NVIDIA GTX 690 supported 5 1 4.3 NVIDIA GTX 69x
-NVIDIA GTX 770 supported 5 0 4.3 NVIDIA GTX 77x
-NVIDIA GTX TITAN supported 5 0 4.3 NVIDIA GTX TITAN
-NVIDIA GeForce 2 supported 0 1 1.5 NVIDIA GeForce 2
-NVIDIA GeForce 3 supported 2 1 2.1 NVIDIA GeForce 3
-NVIDIA GeForce 4 supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA GeForce 4 Go supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA GeForce 4 MX supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA GeForce 4 Ti supported 0 1 1.5 NVIDIA GeForce 4
-NVIDIA GeForce 6100 supported 3 1 4.2 NVIDIA GeForce 6100
-NVIDIA GeForce 6200 supported 0 1 2.1 NVIDIA GeForce 6200
-NVIDIA GeForce 6500 supported 1 1 2.1 NVIDIA GeForce 6500
-NVIDIA GeForce 6600 supported 2 1 2.1 NVIDIA GeForce 6600
-NVIDIA GeForce 6700 supported 2 1 2.1 NVIDIA GeForce 6700
-NVIDIA GeForce 6800 supported 1 1 2.1 NVIDIA GeForce 6800
-NVIDIA GeForce 7000 supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA GeForce 7000M supported 1 1 2.1 NVIDIA GeForce 7000
-NVIDIA GeForce 7100 supported 1 1 2.1 NVIDIA GeForce 7100
-NVIDIA GeForce 7300 supported 1 1 2.1 NVIDIA GeForce 7300
-NVIDIA GeForce 7500 supported 2 1 2.1 NVIDIA GeForce 7500
-NVIDIA GeForce 7600 supported 2 1 2.1 NVIDIA GeForce 7600
-NVIDIA GeForce 7800 supported 2 1 2.1 NVIDIA GeForce 7800
-NVIDIA GeForce 7900 supported 3 1 2.1 NVIDIA GeForce 7900
-NVIDIA GeForce 8100 supported 1 0 3.3 NVIDIA GeForce 8100
-NVIDIA GeForce 8200 supported 1 0 3.3 NVIDIA GeForce 8200
-NVIDIA GeForce 8200M supported 1 0 3.3 NVIDIA GeForce 8200M
-NVIDIA GeForce 8300 supported 3 1 3.3 NVIDIA GeForce 8300
-NVIDIA GeForce 8400 supported 2 1 3.3 NVIDIA GeForce 8400
-NVIDIA GeForce 8400M supported 1 1 3.3 NVIDIA GeForce 8400M
-NVIDIA GeForce 8500 supported 2 1 3.3 NVIDIA GeForce 8500
-NVIDIA GeForce 8600 supported 3 1 3.3 NVIDIA GeForce 8600
-NVIDIA GeForce 8600M supported 2 1 3.3 NVIDIA GeForce 8600M
-NVIDIA GeForce 8700 supported 3 0 0 NVIDIA GeForce 8700
-NVIDIA GeForce 8700M supported 2 1 3.3 NVIDIA GeForce 8700M
-NVIDIA GeForce 8800 supported 3 1 3.3 NVIDIA GeForce 8800
-NVIDIA GeForce 8800M supported 2 1 3.3 NVIDIA GeForce 8800M
-NVIDIA GeForce 9100 supported 0 0 3.3 NVIDIA GeForce 9100
-NVIDIA GeForce 9100M supported 0 0 3.3 NVIDIA GeForce 9100M
-NVIDIA GeForce 9200 supported 1 0 3.3 NVIDIA GeForce 9200
-NVIDIA GeForce 9200M supported 1 0 3.3 NVIDIA GeForce 9200M
-NVIDIA GeForce 9300 supported 1 1 3.3 NVIDIA GeForce 9300
-NVIDIA GeForce 9300M supported 1 1 3.3 NVIDIA GeForce 9300M
-NVIDIA GeForce 9400 supported 3 1 3.3 NVIDIA GeForce 9400
-NVIDIA GeForce 9400M supported 2 1 3.3 NVIDIA GeForce 9400M
-NVIDIA GeForce 9500 supported 3 1 3.3 NVIDIA GeForce 9500
-NVIDIA GeForce 9500M supported 1 1 3.3 NVIDIA GeForce 9500M
-NVIDIA GeForce 9600 supported 3 1 3.3 NVIDIA GeForce 9600
-NVIDIA GeForce 9600M supported 2 1 3.3 NVIDIA GeForce 9600M
-NVIDIA GeForce 9700M supported 0 1 3.3 NVIDIA GeForce 9700M
-NVIDIA GeForce 9800 supported 3 1 3.3 NVIDIA GeForce 9800
-NVIDIA GeForce 9800M supported 2 1 3.3 NVIDIA GeForce 9800M
-NVIDIA GeForce FX 5200 supported 0 0 2.1 NVIDIA GeForce FX 5200
-NVIDIA GeForce FX 5500 supported 0 1 2.1 NVIDIA GeForce FX 5500
-NVIDIA GeForce FX 5600 supported 1 1 2.1 NVIDIA GeForce FX 5600
-NVIDIA GeForce FX 5700 supported 0 1 2.1 NVIDIA GeForce FX 5700
-NVIDIA GeForce FX 5900 supported 1 1 2.1 NVIDIA GeForce FX 5900
-NVIDIA GeForce FX Go5100 supported 3 0 0 NVIDIA 510
-NVIDIA GeForce FX Go5200 supported 0 0 1.5 NVIDIA GeForce FX Go5200
-NVIDIA GeForce FX Go5600 supported 0 1 2.1 NVIDIA GeForce FX Go5600
-NVIDIA GeForce FX Go5700 supported 1 1 1.5 NVIDIA GeForce FX Go5700
-NVIDIA GeForce Go 6 supported 1 0 0 NVIDIA GeForce Go 6
-NVIDIA GeForce Go 6100 supported 0 1 2.1 NVIDIA GeForce Go 6100
-NVIDIA GeForce Go 6200 supported 0 0 1.5 NVIDIA GeForce Go 6200
-NVIDIA GeForce Go 6400 supported 1 1 2.1 NVIDIA GeForce Go 6400
-NVIDIA GeForce Go 6600 supported 0 1 2.1 NVIDIA GeForce Go 6600
-NVIDIA GeForce Go 6800 supported 0 1 2.1 NVIDIA GeForce Go 6800
-NVIDIA GeForce Go 7200 supported 1 0 2.1 NVIDIA GeForce Go 7200
-NVIDIA GeForce Go 7300 supported 1 1 2.1 NVIDIA GeForce Go 7300
-NVIDIA GeForce Go 7400 supported 1 1 2.1 NVIDIA GeForce Go 7400
-NVIDIA GeForce Go 7600 supported 1 1 2.1 NVIDIA GeForce Go 7600
-NVIDIA GeForce Go 7700 supported 0 1 2.1 NVIDIA GeForce Go 7700
-NVIDIA GeForce Go 7800 supported 2 0 0 NVIDIA GeForce Go 7800
-NVIDIA GeForce Go 7900 supported 1 1 2.1 NVIDIA GeForce Go 7900
-NVIDIA GeForce PCX supported 0 0 1.5 NVIDIA GeForce PCX
-NVIDIA Generic unsupported 0 0 2.1 NVIDIA Generic
-NVIDIA ION supported 2 1 3.3 NVIDIA ION a
-NVIDIA MCP61 supported 1 0 2.1 NVIDIA MCP61
-NVIDIA NV34 supported 0 0 0 NVIDIA NV34
-NVIDIA PCI unsupported 0 0 2.1 NVIDIA PCI
-NVIDIA Quadro 2000 supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Quadro 2000 M/D supported 3 0 4.2 NVIDIA Quadro 2000 M/D
-NVIDIA Quadro 3000M supported 3 0 4.2 NVIDIA Quadro 3000M
-NVIDIA Quadro 400 supported 2 0 3.3 NVIDIA Quadro 400
-NVIDIA Quadro 4000 supported 3 0 4.2 NVIDIA Quadro 4000
-NVIDIA Quadro 4000M supported 3 0 4.2 NVIDIA Quadro 4000M
-NVIDIA Quadro 50x0 M supported 3 0 4.2 NVIDIA Quadro 50x0 M
-NVIDIA Quadro 600 supported 2 0 4.2 NVIDIA Quadro 600
-NVIDIA Quadro 6000 supported 3 0 0 NVIDIA Quadro 6000
-NVIDIA Quadro FX supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Quadro FX 1500M supported 1 0 2.1 NVIDIA Quadro FX 1500M
-NVIDIA Quadro FX 1800 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Quadro FX 2500M supported 2 0 2.1 NVIDIA Quadro FX 2500M
-NVIDIA Quadro FX 2700M supported 3 0 3.3 NVIDIA Quadro FX 2700M
-NVIDIA Quadro FX 2800M supported 3 0 3.3 NVIDIA Quadro FX 2800M
-NVIDIA Quadro FX 3500 supported 2 0 2.1 NVIDIA Quadro FX 3500
-NVIDIA Quadro FX 3700 supported 3 0 3.3 NVIDIA Quadro FX 3700
-NVIDIA Quadro FX 3800 supported 3 0 3.3 NVIDIA Quadro FX 3800
-NVIDIA Quadro FX 4500 supported 3 0 2.1 NVIDIA Quadro FX 4500
-NVIDIA Quadro FX 4800 supported 3 0 3.1 NVIDIA Quadro FX 4800
-NVIDIA Quadro FX 550 supported 1 0 3.3 NVIDIA Quadro FX
-NVIDIA Quadro FX 770M supported 2 0 3.3 NVIDIA Quadro FX 770M
-NVIDIA Quadro FX 880M supported 3 0 3.3 NVIDIA Quadro FX 880M
-NVIDIA Quadro NVS supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Quadro NVS 1xxM supported 0 0 4.2 NVIDIA Quadro NVS
-NVIDIA Quadro NVS 4200M supported 2 0 4.2 NVIDIA Quadro NVS 4200M
-NVIDIA Quadro2 supported 0 0 1.5 NVIDIA Quadro2
-NVIDIA nForce unsupported 0 0 3.3 NVIDIA nForce
-Oracle VirtualBox Graphics supported 0 1 2.1 Oracle
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon Barts XT Prototype OpenGL Engine supported 3 1 2.1 AMD BARTS (HD 6800)
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 2600 OpenGL Engine supported 2 1 4 ATI Radeon HD 2600
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 2600 PRO OpenGL Engine supported 2 1 4 ATI Radeon HD 2600
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 4670 OpenGL Engine supported 3 1 4 ATI Radeon HD 4600
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 4850 OpenGL Engine supported 3 1 4 ATI Radeon HD 4800
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5670 OpenGL Engine supported 3 1 4.2 ATI Radeon HD 5600
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5750 OpenGL Engine supported 3 1 4.2 ATI Radeon HD 5700
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5770 OpenGL Engine supported 3 1 4.2 ATI Radeon HD 5700
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6630M OpenGL Engine supported 3 1 4.2 ATI Radeon HD 6600
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6750M OpenGL Engine supported 3 1 4.2 ATI Radeon HD 6700
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6770M OpenGL Engine supported 3 1 4.2 ATI Radeon HD 6700
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6970M OpenGL Engine supported 5 1 4.2 ATI Radeon HD 6900
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon X1600 OpenGL Engine supported 2 1 2.1 ATI Radeon X1600
-Parallels and Intel Inc. Parallels using Intel GMA X3100 OpenGL Engine supported 1 1 2.1 Intel X3100
-Parallels and Intel Inc. Parallels using Intel HD Graphics 3000 OpenGL Engine supported 3 1 3.1 Intel HD Graphics 3000
-Parallels and Intel Inc. Parallels using Intel HD Graphics 4000 OpenGL Engine supported 3 1 4.2 Intel HD Graphics 4000
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 320M OpenGL Engine supported 2 0 3.3 NVIDIA 320M
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 8800 GS OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 8800
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 9400 OpenGL Engine supported 3 1 3.3 NVIDIA GeForce 9400
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 9400M OpenGL Engine supported 2 1 3.3 NVIDIA GeForce 9400M
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 9600M GT OpenGL Engine supported 2 1 3.3 NVIDIA GeForce 9600M
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GT 130 OpenGL Engine supported 2 0 3.3 NVIDIA GT 130
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GT 330M OpenGL Engine supported 3 1 3.3 NVIDIA GT 330M
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GT 640 OpenGL Engine supported 3 0 4.3 NVIDIA GT 64x
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GT 640M OpenGL Engine supported 3 0 4.3 NVIDIA GT 640M
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GT 650M OpenGL Engine supported 3 0 4.3 NVIDIA GT 650M
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 570 OpenGL Engine supported 5 1 4.3 NVIDIA GTX 570
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 660 OpenGL Engine supported 5 0 4.3 NVIDIA GTX 66x
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 660 Ti OpenGL Engine supported 5 0 4.3 NVIDIA GTX 66x
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 670 OpenGL Engine supported 5 1 4.3 NVIDIA GTX 67x
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 680MX OpenGL Engine supported 5 0 4.3 NVIDIA GTX 680M
-PowerVR SGX545 supported 1 1 3 PowerVR SGX545
-S3 unsupported 0 1 1.4 S3
-S3 Graphics K8M800/MMX/K3D unsupported 0 1 1.4 S3
-S3 Graphics KM400/KN400/MMX/SSE unsupported 0 1 1.4 S3
-S3 Graphics P8M800/MMX/SSE unsupported 0 1 1.4 S3
-S3 Graphics Unknown Device/MMX/SSE unsupported 0 1 1.4 S3
-S3 Graphics VIA/S3G UniChrome IGP/MMX/SSE unsupported 0 1 1.4 S3
-S3 Graphics VIA/S3G UniChrome Pro IGP/MMX/SSE unsupported 0 1 1.4 S3
-S3 Graphics, Incorporated ProSavage/Twister unsupported 0 1 1.4 S3
-S3 Graphics, Incorporated S3 Graphics Chrome9 HC unsupported 0 1 1.4 S3
-S3 Graphics, Incorporated S3 Graphics DeltaChrome unsupported 0 1 1.4 S3
-S3 Graphics, Incorporated VIA Chrome9 HC IGP unsupported 0 1 1.4 S3
-S3 Graphics, Incorporated VIA Chrome9 HC3 IGP unsupported 0 1 1.4 S3
-S3 Graphics, Incorporated VIA Chrome9 HD Pro IGP unsupported 0 1 1.4 S3
-SiS unsupported 0 1 1.5 SiS
-SiS 3D-Analyze v2.3 - http://www.tommti-systems.com unsupported 0 1 1.5 SiS
-SiS 650/M650 VGA unsupported 0 1 1.5 SiS
-SiS 650/M650 VGA / MMX/SSE2 /AGP unsupported 0 1 1.5 SiS
-SiS 661 VGA unsupported 0 1 1.5 SiS
-SiS 662 VGA unsupported 0 1 1.5 SiS
-SiS 760 VGA unsupported 0 1 1.5 SiS
-SiS 761GX VGA unsupported 0 1 1.5 SiS
-SiS Mirage Graphics3 unsupported 0 1 1.4 S3
-SiS Xabre VGA unsupported 0 1 1.5 SiS
-Tungsten Graphics, Inc Mesa DRI Intel(R) 845G unsupported 0 1 1.4 Intel 845G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 852GM/855GM unsupported 0 1 1.4 Intel 855GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 852GM/855GM x86/MMX/SSE2 unsupported 0 1 1.4 Intel 855GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 865G unsupported 0 1 1.4 Intel 865G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 865G x86/MMX/SSE2 unsupported 0 1 1.4 Intel 865G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915G unsupported 0 1 1.4 Intel 915G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915G x86/MMX/SSE2 unsupported 0 1 1.4 Intel 915G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915GM unsupported 0 1 1.4 Intel 915GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915GM 20061017 x86/MMX/SSE2 unsupported 0 1 1.4 Intel 915GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915GM GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 1 1.4 Intel 915GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915GM x86/MMX/SSE2 unsupported 0 1 1.4 Intel 915GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945G GEM 20091221 2009Q4 x86/MMX/SSE2 supported 0 1 1.4 Intel 945G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 supported 0 1 1.4 Intel 945G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945G x86/MMX/SSE2 supported 0 1 1.4 Intel 945G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945GM GEM 20091221 2009Q4 x86/MMX/SSE2 supported 0 1 1.4 Intel 945GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945GM x86/MMX/SSE2 supported 0 1 1.4 Intel 945GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945GME supported 0 1 1.4 Intel 945GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945GME GEM 20091221 2009Q4 x86/MMX/SSE2 supported 0 1 1.4 Intel 945GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945GME x86/MMX/SSE2 supported 0 1 1.4 Intel 945GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965GM supported 0 1 2.1 Intel 965
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965GM GEM 20091221 2009Q4 x86/MMX/SSE2 supported 0 1 2.1 Intel 965
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965GM x86/MMX/SSE2 supported 0 1 2.1 Intel 965
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965GME/GLE x86/MMX/SSE2 supported 0 1 2.1 Intel 965
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965Q supported 0 1 2.1 Intel 965
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965Q GEM 20091221 2009Q4 x86/MMX/SSE2 supported 0 1 2.1 Intel 965
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965Q x86/MMX/SSE2 supported 0 1 2.1 Intel 965
-Tungsten Graphics, Inc Mesa DRI Intel(R) G33 GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 1 1 1.4 Intel G33
-Tungsten Graphics, Inc Mesa DRI Intel(R) G33 x86/MMX/SSE2 unsupported 1 1 1.4 Intel G33
-Tungsten Graphics, Inc Mesa DRI Intel(R) G41 GEM 20091221 2009Q4 x86/MMX/SSE2 supported 1 1 2.1 Intel G41
-Tungsten Graphics, Inc Mesa DRI Intel(R) G41 GEM 20100330 DEVELOPMENT x86/MMX/SSE2 supported 1 1 2.1 Intel G41
-Tungsten Graphics, Inc Mesa DRI Intel(R) G41 x86/MMX/SSE2 supported 1 1 2.1 Intel G41
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD GEM 20091221 2009Q4 supported 1 1 2.1 Intel Q45/Q43
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD GEM 20091221 2009Q4 x86/MMX/SSE2 supported 1 1 2.1 Intel Q45/Q43
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGDNG_M GEM 20091221 2009Q4 supported 1 1 2.1 Intel Q45/Q43
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGDNG_M GEM 20091221 2009Q4 x86/MMX/SSE2 supported 1 1 2.1 Intel Q45/Q43
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Desktop unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Desktop x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Mobile unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Mobile GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Mobile x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ivybridge Desktop unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ivybridge Desktop x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ivybridge Mobile unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ivybridge Mobile x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Q35 GEM 20091221 2009Q4 x86/MMX/SSE2 supported 1 1 2.1 Intel Q45/Q43
-Tungsten Graphics, Inc Mesa DRI Intel(R) Q35 x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Q45/Q43 x86/MMX/SSE2 supported 1 1 2.1 Intel Q45/Q43
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Desktop unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Desktop x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Mobile unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Mobile x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Mobile GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Mobile x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Server unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset GEM 20091221 2009Q4 supported 1 1 2.1 Intel Q45/Q43
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset GEM 20091221 2009Q4 x86/MMX/SSE2 supported 1 1 2.1 Intel Q45/Q43
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset GEM 20100330 DEVELOPMENT x86/MMX unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset x86/MMX/SSE2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc. Mesa DRI R100 (RS200 4437) x86/MMX/SSE2 NO-TCL DRI2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc. Mesa DRI R100 (RV200 4C57) TCL DRI2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc. Mesa DRI R100 (RV200 4C57) x86/MMX/SSE2 TCL DRI2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc. Mesa DRI R200 (RV250 4C66) x86/MMX/SSE2 TCL DRI2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc. Mesa DRI R200 (RV280 5960) x86/MMX+/3DNow!+/SSE2 TCL DRI2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc. Mesa DRI R200 (RV280 5960) x86/MMX/SSE2 TCL DRI2 unsupported 1 1 3 Mesa
-Tungsten Graphics, Inc. Mesa DRI R200 (RV280 5961) x86/MMX/SSE2 TCL DRI2 unsupported 1 1 3 Mesa
-VMware, Inc. Gallium 0.3 on SVGA3D; build: RELEASE; supported 1 1 2.1 Gallium
-VMware, Inc. Gallium 0.4 on SVGA3D; build: RELEASE; supported 1 1 2.1 Gallium
-VMware, Inc. Gallium 0.4 on i915 (chipset: 945GME) supported 1 1 2.1 Gallium
-VMware, Inc. Gallium 0.4 on llvmpipe supported 1 1 2.1 Gallium
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x209) supported 1 1 2.1 Gallium
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x300) supported 1 1 2.1 Gallium
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x301) supported 1 1 2.1 Gallium
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x302) supported 1 1 2.1 Gallium
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 3.2, 128 bits) supported 1 1 2.1 Gallium
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 3.2, 256 bits) supported 1 1 2.1 Gallium
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 3.3, 128 bits) supported 1 1 2.1 Gallium
-X.Org Gallium 0.4 on AMD ARUBA supported 3 1 2.1 AMD ARUBA (HD 6800)
-X.Org Gallium 0.4 on AMD BARTS supported 3 1 2.1 AMD BARTS (HD 6800)
-X.Org Gallium 0.4 on AMD CAICOS supported 3 0 0 AMD CAICOS (HD 6400)
-X.Org Gallium 0.4 on AMD CAPE VERDE supported 1 1 2.1 Gallium
-X.Org Gallium 0.4 on AMD CEDAR supported 2 0 2.1 AMD CEDAR (HD 5450)
-X.Org Gallium 0.4 on AMD CYPRESS supported 3 0 0 AMD CYPRESS (HD 5800)
-X.Org Gallium 0.4 on AMD JUNIPER supported 3 0 0 AMD JUNIPER (HD 5700)
-X.Org Gallium 0.4 on AMD PALM supported 1 1 2.1 Gallium
-X.Org Gallium 0.4 on AMD REDWOOD supported 3 0 1.4 AMD REDWOOD (HD 5500/5600)
-X.Org Gallium 0.4 on AMD RS780 supported 0 1 2.1 AMD RS780 (HD 3200)
-X.Org Gallium 0.4 on AMD RS880 supported 0 1 3.2 AMD RS880 (HD 4200)
-X.Org Gallium 0.4 on AMD RV610 supported 1 0 0 AMD RV610 (HD 2400)
-X.Org Gallium 0.4 on AMD RV620 supported 1 0 0 AMD RV620 (HD 3400)
-X.Org Gallium 0.4 on AMD RV630 supported 2 0 0 AMD RV630 (HD 2600)
-X.Org Gallium 0.4 on AMD RV635 supported 3 0 1.4 AMD RV635 (HD 3600)
-X.Org Gallium 0.4 on AMD RV670 supported 3 0 0 AMD RV670 (HD 3800)
-X.Org Gallium 0.4 on AMD RV710 supported 0 1 1.4 AMD RV710 (HD 4300)
-X.Org Gallium 0.4 on AMD RV730 supported 3 0 1.4 AMD RV730 (HD 4600)
-X.Org Gallium 0.4 on AMD RV740 supported 3 0 0 AMD RV740 (HD 4700)
-X.Org Gallium 0.4 on AMD RV770 supported 3 0 0 AMD RV770 (HD 4800)
-X.Org Gallium 0.4 on AMD SUMO supported 3 1 4.1 AMD SUMO
-X.Org Gallium 0.4 on AMD SUMO2 supported 3 1 4.1 AMD SUMO
-X.Org Gallium 0.4 on AMD TURKS supported 3 0 2.1 AMD TURKS (HD 6500/6600)
-X.Org R300 Project Gallium 0.4 on ATI R350 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI R580 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RC410 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RS480 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RS482 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RS600 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RS690 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RV350 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RV370 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RV380 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RV410 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RV515 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RV530 supported 0 1 2.1 ATI R300 (9700)
-X.Org R300 Project Gallium 0.4 on ATI RV570 supported 0 1 2.1 ATI R300 (9700)
-XGI Volari V3 unsupported 0 0 0 XGI
-http://TitaniumGL.tk NVIDIA GeForce GTX 690/3999M VRAM/TitaniumGL/4 THREADs/3D GRAPHICS ACCELERATION supported 5 1 4.3 NVIDIA GTX 69x
-nouveau Gallium 0.4 on NV34 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV42 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV44 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV46 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV49 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV4A supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV4B supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV4C supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV4E supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV50 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV63 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV67 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV84 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV86 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV92 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV94 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV96 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NV98 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVA0 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVA3 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVA5 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVA8 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVAA supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVAC supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVAF supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVC0 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVC1 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVC3 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVC4 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVCE supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVCF supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVD9 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVE4 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVE6 supported 1 1 2.1 Gallium
-nouveau Gallium 0.4 on NVE7 supported 1 1 2.1 Gallium
diff --git a/indra/newview/tests/gpus_seen.txt b/indra/newview/tests/gpus_seen.txt
deleted file mode 100644
index 66cbeece97..0000000000
--- a/indra/newview/tests/gpus_seen.txt
+++ /dev/null
@@ -1,4225 +0,0 @@
-AMD BARTS (HD 6800)
-AMD BARTS (HD 6800)
-AMD CAICOS (HD 6400)
-AMD CAICOS (HD 6400)
-AMD CAYMAN (HD 6900)
-AMD CEDAR (HD 5450)
-AMD CEDAR (HD 5450)
-AMD JUNIPER (HD 5700)
-AMD PARK
-AMD REDWOOD (HD 5500/5600)
-AMD RS780 (HD 3200)
-AMD RS880 (HD 4200)
-AMD RS880 (HD 4200)
-AMD RV610 (HD 2400)
-AMD RV620 (HD 3400)
-AMD RV630 (HD 2600)
-AMD RV635 (HD 3600)
-AMD RV670 (HD 3800)
-AMD RV710 (HD 4300)
-AMD RV730 (HD 4600)
-AMD RV770 (HD 4800)
-AMD RV790 (HD 4800)
-AMD TURKS (HD 6500/6600)
-ATI
-ATI 760G/Radeon 3000
-ATI ASUS AH24xx
-ATI ASUS AH34xx
-ATI ASUS AH36xx
-ATI ASUS AH46xx
-ATI ASUS AX3xx
-ATI ASUS AX5xx
-ATI ASUS EAH38xx
-ATI ASUS EAH43xx
-ATI ASUS EAH45xx
-ATI ASUS EAH48xx
-ATI ASUS EAH54xx
-ATI ASUS EAH57xx
-ATI ASUS EAH58xx
-ATI ASUS EAH64xx
-ATI ASUS EAH65xx
-ATI ASUS EAH66xx
-ATI ASUS EAH67xx
-ATI ASUS EAH68xx
-ATI ASUS EAH69xx
-ATI ASUS EAH6xxx
-ATI ASUS EAH77xx
-ATI ASUS HD7700
-ATI ASUS Radeon X1xxx
-ATI All-in-Wonder HD
-ATI All-in-Wonder PCI-E
-ATI Display Adapter
-ATI FireGL
-ATI FireGL 5200
-ATI FireGL 5xxx
-ATI FireMV
-ATI FirePro 2000
-ATI FirePro 4000
-ATI FirePro M
-ATI FirePro M3900
-ATI FirePro M5800
-ATI FirePro M7740
-ATI FirePro M7820
-ATI Geforce 9500 GT
-ATI Geforce 9600 GT
-ATI Geforce 9800 GT
-ATI IGP 340M
-ATI Mobility Radeon
-ATI Mobility Radeon 4100
-ATI Mobility Radeon 4100
-ATI Mobility Radeon 7xxx
-ATI Mobility Radeon 9600
-ATI Mobility Radeon 9700
-ATI Mobility Radeon 9800
-ATI Mobility Radeon HD 2300
-ATI Mobility Radeon HD 2300
-ATI Mobility Radeon HD 2400
-ATI Mobility Radeon HD 2400
-ATI Mobility Radeon HD 2600
-ATI Mobility Radeon HD 2600
-ATI Mobility Radeon HD 2700
-ATI Mobility Radeon HD 3400
-ATI Mobility Radeon HD 3400
-ATI Mobility Radeon HD 3600
-ATI Mobility Radeon HD 3600
-ATI Mobility Radeon HD 3800
-ATI Mobility Radeon HD 4200
-ATI Mobility Radeon HD 4200
-ATI Mobility Radeon HD 4300
-ATI Mobility Radeon HD 4500
-ATI Mobility Radeon HD 4600
-ATI Mobility Radeon HD 4800
-ATI Mobility Radeon HD 5100
-ATI Mobility Radeon HD 5100
-ATI Mobility Radeon HD 5300
-ATI Mobility Radeon HD 530v
-ATI Mobility Radeon HD 5400
-ATI Mobility Radeon HD 5400
-ATI Mobility Radeon HD 540v
-ATI Mobility Radeon HD 545v
-ATI Mobility Radeon HD 5500
-ATI Mobility Radeon HD 550v
-ATI Mobility Radeon HD 5600
-ATI Mobility Radeon HD 5600
-ATI Mobility Radeon HD 560v
-ATI Mobility Radeon HD 565v
-ATI Mobility Radeon HD 5700
-ATI Mobility Radeon HD 6300
-ATI Mobility Radeon HD 6300
-ATI Mobility Radeon HD 6500
-ATI Mobility Radeon HD 6500M
-ATI Mobility Radeon X1xxx
-ATI Mobility Radeon X2xxx
-ATI Mobility Radeon X3xx
-ATI Mobility Radeon X6xx
-ATI Mobility Radeon X7xx
-ATI Mobility Radeon Xxxx
-ATI Mobility Radeon Xxxx
-ATI R300 (9700)
-ATI RV410 (X700)
-ATI RV530
-ATI Radeon
-ATI Radeon 2100
-ATI Radeon 3000
-ATI Radeon 3100
-ATI Radeon 3100
-ATI Radeon 5xxx
-ATI Radeon 7000
-ATI Radeon 7xxx
-ATI Radeon 8xxx
-ATI Radeon 9000
-ATI Radeon 9100
-ATI Radeon 9200
-ATI Radeon 9500
-ATI Radeon 9600
-ATI Radeon 9700
-ATI Radeon 9800
-ATI Radeon HD 2300
-ATI Radeon HD 2300
-ATI Radeon HD 2400
-ATI Radeon HD 2400
-ATI Radeon HD 2600
-ATI Radeon HD 2900
-ATI Radeon HD 3000
-ATI Radeon HD 3100
-ATI Radeon HD 3200
-ATI Radeon HD 3200
-ATI Radeon HD 3300
-ATI Radeon HD 3400
-ATI Radeon HD 3400
-ATI Radeon HD 3400
-ATI Radeon HD 3500
-ATI Radeon HD 3600
-ATI Radeon HD 3700
-ATI Radeon HD 3800
-ATI Radeon HD 4200
-ATI Radeon HD 4300
-ATI Radeon HD 4300
-ATI Radeon HD 4400
-ATI Radeon HD 4500
-ATI Radeon HD 4500
-ATI Radeon HD 4600
-ATI Radeon HD 4700
-ATI Radeon HD 4800
-ATI Radeon HD 4800
-ATI Radeon HD 5400
-ATI Radeon HD 5400
-ATI Radeon HD 5500
-ATI Radeon HD 5500
-ATI Radeon HD 5600
-ATI Radeon HD 5700
-ATI Radeon HD 5700
-ATI Radeon HD 5800
-ATI Radeon HD 5900
-ATI Radeon HD 6200
-ATI Radeon HD 6200
-ATI Radeon HD 6300
-ATI Radeon HD 6300
-ATI Radeon HD 6300
-ATI Radeon HD 6300M
-ATI Radeon HD 6400
-ATI Radeon HD 64xx
-ATI Radeon HD 64xx
-ATI Radeon HD 6500
-ATI Radeon HD 65xx
-ATI Radeon HD 65xx
-ATI Radeon HD 6600
-ATI Radeon HD 66xx
-ATI Radeon HD 6700
-ATI Radeon HD 6700
-ATI Radeon HD 6700M
-ATI Radeon HD 6800
-ATI Radeon HD 6900
-ATI Radeon HD 6900
-ATI Radeon HD 7200
-ATI Radeon HD 7300
-ATI Radeon HD 7300
-ATI Radeon HD 7400
-ATI Radeon HD 7400
-ATI Radeon HD 7500
-ATI Radeon HD 7600
-ATI Radeon HD 7700
-ATI Radeon HD 7800
-ATI Radeon HD 7900
-ATI Radeon X1000
-ATI Radeon X1200
-ATI Radeon X1300
-ATI Radeon X13xx
-ATI Radeon X1400
-ATI Radeon X1500
-ATI Radeon X15xx
-ATI Radeon X1600
-ATI Radeon X16xx
-ATI Radeon X17xx
-ATI Radeon X1800
-ATI Radeon X18xx
-ATI Radeon X1900
-ATI Radeon X1900
-ATI Radeon X19xx
-ATI Radeon X1xxx
-ATI Radeon X1xxx
-ATI Radeon X1xxx
-ATI Radeon X1xxx
-ATI Radeon X2xxx
-ATI Radeon X2xxx
-ATI Radeon X300
-ATI Radeon X500
-ATI Radeon X500
-ATI Radeon X500
-ATI Radeon X600
-ATI Radeon X700
-ATI Radeon X800
-ATI Radeon Xpress
-ATI Radeon Xpress
-ATI Rage 128
-ATI Technologies
-ATI Technologies Inc.
-ATI Technologies Inc. (DNA-AMD GFX) AMD Radeon HD 6290 Graphics
-ATI Technologies Inc. (DNA-ATi 5.1.7.5x32) ATI Mobility Radeon HD 2
-ATI Technologies Inc. (Vista) ATI Mobility Radeon HD 5730
-ATI Technologies Inc. (Vista) ATI Mobility Radeon HD 5870
-ATI Technologies Inc. 128MB ATI RADEON X600 SE
-ATI Technologies Inc. 128MB ATI RADEON X600 SE x86/SSE2
-ATI Technologies Inc. 128MB ATI Radeon X1300
-ATI Technologies Inc. 128MB ATI Radeon X1300 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. 128MB ATI Radeon X1300 x86/SSE2
-ATI Technologies Inc. 256MB ATI RADEON X600
-ATI Technologies Inc. 256MB ATI Radeon X1300PRO
-ATI Technologies Inc. 256MB ATI Radeon X1300PRO x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. 256MB ATI Radeon X1300PRO x86/SSE2
-ATI Technologies Inc. 3DP (ATI RADEON XPRESS 200M)
-ATI Technologies Inc. 3DP Edition v10.04 (Mobility Radeon X1600) x86/SSE2
-ATI Technologies Inc. 7900 MOD - AMD Radeon HD 7400M Series
-ATI Technologies Inc. 7900 MOD - AMD Radeon HD 7640G
-ATI Technologies Inc. ALL-IN-WONDER 9600 SERIES
-ATI Technologies Inc. AMD (ATI) FirePro M5950 (FireGL) Mobility Pro Graphics
-ATI Technologies Inc. AMD (ATI) FirePro M4000 (FireGL V) Mobility Pro Graphics
-ATI Technologies Inc. AMD (ATI) FirePro M5950 (FireGL) Mobility Pro Graphics
-ATI Technologies Inc. AMD (ATI) FirePro M6000 (FireGL V) Mobility Pro Graphics
-ATI Technologies Inc. AMD (ATI) FirePro M8900 (FireGL) Mobility Pro
-ATI Technologies Inc. AMD (ATI) FirePro M8900 (FireGL) Mobility Pro Graphics
-ATI Technologies Inc. AMD (ATI) FirePro M8900 (FireGL) Mobility Pro Graphics
-ATI Technologies Inc. AMD 760G
-ATI Technologies Inc. AMD 760G
-ATI Technologies Inc. AMD 760G (Microsoft Corporation WDDM 1.1)
-ATI Technologies Inc. AMD FirePro 2270
-ATI Technologies Inc. AMD FirePro 2460
-ATI Technologies Inc. AMD FirePro M2000
-ATI Technologies Inc. AMD FirePro M3900
-ATI Technologies Inc. AMD FirePro M4000
-ATI Technologies Inc. AMD FirePro M5950
-ATI Technologies Inc. AMD FirePro M5950 Mobility Professional Graphics
-ATI Technologies Inc. AMD FirePro M5950 Mobility Professional Graphics
-ATI Technologies Inc. AMD FirePro V3900
-ATI Technologies Inc. AMD FirePro V3900 (ATI FireGL)
-ATI Technologies Inc. AMD FirePro V4900
-ATI Technologies Inc. AMD FirePro V4900 (ATI FireGL)
-ATI Technologies Inc. AMD FirePro V4900 (FireGL V)
-ATI Technologies Inc. AMD FirePro V4900 (FireGL V) Graphics Adapter
-ATI Technologies Inc. AMD FirePro V5900
-ATI Technologies Inc. AMD FirePro V5900 (ATI FireGL)
-ATI Technologies Inc. AMD FirePro V5900 (FireGL V)
-ATI Technologies Inc. AMD FirePro V5900 (FireGL V) Graphics Adapter
-ATI Technologies Inc. AMD FirePro V7900
-ATI Technologies Inc. AMD FirePro V7900 (ATI FireGL)
-ATI Technologies Inc. AMD FirePro V7900 (FireGL V)
-ATI Technologies Inc. AMD FirePro V7900 (FireGL V) Graphics Adapter
-ATI Technologies Inc. AMD FirePro W5000 (FireGL V)
-ATI Technologies Inc. AMD FirePro W9000 (FireGL V)
-ATI Technologies Inc. AMD M860G with ATI Mobility Radeon 4100
-ATI Technologies Inc. AMD M860G with ATI Mobility Radeon 4100
-ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4200
-ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4200
-ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4200
-ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4225
-ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4250
-ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4250
-ATI Technologies Inc. AMD RADEON HD 6350
-ATI Technologies Inc. AMD RADEON HD 6350
-ATI Technologies Inc. AMD RADEON HD 6450
-ATI Technologies Inc. AMD RADEON HD 6450
-ATI Technologies Inc. AMD RADEON HD 6450A
-ATI Technologies Inc. AMD RADEON HD 6670
-ATI Technologies Inc. AMD RADEON HD 6670
-ATI Technologies Inc. AMD RADEON HD 7450
-ATI Technologies Inc. AMD RADEON HD6370D Graphics
-ATI Technologies Inc. AMD RADEON HD6370D Graphics
-ATI Technologies Inc. AMD RADEON HD6410D Graphics
-ATI Technologies Inc. AMD RADEON HD6410D Graphics
-ATI Technologies Inc. AMD RADEON HD6530D Graphics
-ATI Technologies Inc. AMD RADEON HD6550D Graphics
-ATI Technologies Inc. AMD Radeon
-ATI Technologies Inc. AMD Radeon
-ATI Technologies Inc. AMD Radeon (TM) HD 8500M/8700M
-ATI Technologies Inc. AMD Radeon (TM) HD 8500M/8700M
-ATI Technologies Inc. AMD Radeon 6600M and 6700M Series
-ATI Technologies Inc. AMD Radeon 6600M and 6700M Series
-ATI Technologies Inc. AMD Radeon 6600M and 6700M Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 5450
-ATI Technologies Inc. AMD Radeon HD 5500 Series
-ATI Technologies Inc. AMD Radeon HD 5500 Series
-ATI Technologies Inc. AMD Radeon HD 5500 Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 6200 series Graphics
-ATI Technologies Inc. AMD Radeon HD 6200 series Graphics
-ATI Technologies Inc. AMD Radeon HD 6250
-ATI Technologies Inc. AMD Radeon HD 6250 Graphics
-ATI Technologies Inc. AMD Radeon HD 6250 Graphics
-ATI Technologies Inc. AMD Radeon HD 6250M
-ATI Technologies Inc. AMD Radeon HD 6250M
-ATI Technologies Inc. AMD Radeon HD 6290
-ATI Technologies Inc. AMD Radeon HD 6290 Graphics
-ATI Technologies Inc. AMD Radeon HD 6290 Graphics
-ATI Technologies Inc. AMD Radeon HD 6290M
-ATI Technologies Inc. AMD Radeon HD 6290M
-ATI Technologies Inc. AMD Radeon HD 6300 series Graphics
-ATI Technologies Inc. AMD Radeon HD 6300 series Graphics
-ATI Technologies Inc. AMD Radeon HD 6300M Series
-ATI Technologies Inc. AMD Radeon HD 6300M Series
-ATI Technologies Inc. AMD Radeon HD 6310
-ATI Technologies Inc. AMD Radeon HD 6310
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics (Engineering Sample - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics (Microsoft Corporation - WDDM v1.3)
-ATI Technologies Inc. AMD Radeon HD 6310 Graphics (Microsoft Corporation- WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 6310M
-ATI Technologies Inc. AMD Radeon HD 6310M
-ATI Technologies Inc. AMD Radeon HD 6320
-ATI Technologies Inc. AMD Radeon HD 6320 Graphics
-ATI Technologies Inc. AMD Radeon HD 6320 Graphic
-ATI Technologies Inc. AMD Radeon HD 6320 Graphics
-ATI Technologies Inc. AMD Radeon HD 6320 Graphics
-ATI Technologies Inc. AMD Radeon HD 6320 Graphics (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 6320 series Graphics
-ATI Technologies Inc. AMD Radeon HD 6320 series Graphics
-ATI Technologies Inc. AMD Radeon HD 6320M
-ATI Technologies Inc. AMD Radeon HD 6330M
-ATI Technologies Inc. AMD Radeon HD 6350
-ATI Technologies Inc. AMD Radeon HD 6350
-ATI Technologies Inc. AMD Radeon HD 6370D
-ATI Technologies Inc. AMD Radeon HD 6370M
-ATI Technologies Inc. AMD Radeon HD 6370M
-ATI Technologies Inc. AMD Radeon HD 6380G
-ATI Technologies Inc. AMD Radeon HD 6400 Series
-ATI Technologies Inc. AMD Radeon HD 6400M Series
-ATI Technologies Inc. AMD Radeon HD 6410D
-ATI Technologies Inc. AMD Radeon HD 6410D
-ATI Technologies Inc. AMD Radeon HD 6410D Graphics
-ATI Technologies Inc. AMD Radeon HD 6410D Graphics
-ATI Technologies Inc. AMD Radeon HD 6450
-ATI Technologies Inc. AMD Radeon HD 6450
-ATI Technologies Inc. AMD Radeon HD 6450 (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. AMD Radeon HD 6450 Graphics
-ATI Technologies Inc. AMD Radeon HD 6450A
-ATI Technologies Inc. AMD Radeon HD 6450A Graphics
-ATI Technologies Inc. AMD Radeon HD 6450M
-ATI Technologies Inc. AMD Radeon HD 6450M
-ATI Technologies Inc. AMD Radeon HD 6470M
-ATI Technologies Inc. AMD Radeon HD 6470M
-ATI Technologies Inc. AMD Radeon HD 6470M/7400M Series
-ATI Technologies Inc. AMD Radeon HD 6480G
-ATI Technologies Inc. AMD Radeon HD 6480M
-ATI Technologies Inc. AMD Radeon HD 6490M
-ATI Technologies Inc. AMD Radeon HD 6500 Series
-ATI Technologies Inc. AMD Radeon HD 6500 Series
-ATI Technologies Inc. AMD Radeon HD 6500 series graphics
-ATI Technologies Inc. AMD Radeon HD 6500M Series
-ATI Technologies Inc. AMD Radeon HD 6500M/5600/5700 Series
-ATI Technologies Inc. AMD Radeon HD 6500M/5600/5700 Series
-ATI Technologies Inc. AMD Radeon HD 6500M/5600/5700 Series
-ATI Technologies Inc. AMD Radeon HD 6510 Series
-ATI Technologies Inc. AMD Radeon HD 6510 Series
-ATI Technologies Inc. AMD Radeon HD 6520G
-ATI Technologies Inc. AMD Radeon HD 6520G
-ATI Technologies Inc. AMD Radeon HD 6530D
-ATI Technologies Inc. AMD Radeon HD 6530D
-ATI Technologies Inc. AMD Radeon HD 6530D Graphics
-ATI Technologies Inc. AMD Radeon HD 6530D Graphics
-ATI Technologies Inc. AMD Radeon HD 6530M
-ATI Technologies Inc. AMD Radeon HD 6550A
-ATI Technologies Inc. AMD Radeon HD 6550A
-ATI Technologies Inc. AMD Radeon HD 6550D
-ATI Technologies Inc. AMD Radeon HD 6550D
-ATI Technologies Inc. AMD Radeon HD 6550D Graphics
-ATI Technologies Inc. AMD Radeon HD 6550D Graphics
-ATI Technologies Inc. AMD Radeon HD 6550M
-ATI Technologies Inc. AMD Radeon HD 6550M
-ATI Technologies Inc. AMD Radeon HD 6570
-ATI Technologies Inc. AMD Radeon HD 6570
-ATI Technologies Inc. AMD Radeon HD 6570 (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. AMD Radeon HD 6570 (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 6570M
-ATI Technologies Inc. AMD Radeon HD 6570M/5700 Series
-ATI Technologies Inc. AMD Radeon HD 6570M/5700 Series
-ATI Technologies Inc. AMD Radeon HD 6570M/5730
-ATI Technologies Inc. AMD Radeon HD 6600 Series
-ATI Technologies Inc. AMD Radeon HD 6600 Series
-ATI Technologies Inc. AMD Radeon HD 6600M Series
-ATI Technologies Inc. AMD Radeon HD 6610M Graphics
-ATI Technologies Inc. AMD Radeon HD 6620G
-ATI Technologies Inc. AMD Radeon HD 6620G
-ATI Technologies Inc. AMD Radeon HD 6625M Graphics
-ATI Technologies Inc. AMD Radeon HD 6630M
-ATI Technologies Inc. AMD Radeon HD 6630M
-ATI Technologies Inc. AMD Radeon HD 6650A Graphics
-ATI Technologies Inc. AMD Radeon HD 6650M
-ATI Technologies Inc. AMD Radeon HD 6650M
-ATI Technologies Inc. AMD Radeon HD 6670
-ATI Technologies Inc. AMD Radeon HD 6670
-ATI Technologies Inc. AMD Radeon HD 6670 (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. AMD Radeon HD 6670 (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 6700 Series
-ATI Technologies Inc. AMD Radeon HD 6700 Series
-ATI Technologies Inc. AMD Radeon HD 6700 series
-ATI Technologies Inc. AMD Radeon HD 6700M Series
-ATI Technologies Inc. AMD Radeon HD 6700M Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 6700M/7700M/7900M Series
-ATI Technologies Inc. AMD Radeon HD 6730M
-ATI Technologies Inc. AMD Radeon HD 6750
-ATI Technologies Inc. AMD Radeon HD 6750M
-ATI Technologies Inc. AMD Radeon HD 6750M
-ATI Technologies Inc. AMD Radeon HD 6770
-ATI Technologies Inc. AMD Radeon HD 6770M
-ATI Technologies Inc. AMD Radeon HD 6770M
-ATI Technologies Inc. AMD Radeon HD 6770M OpenGL Engine
-ATI Technologies Inc. AMD Radeon HD 6800 Series
-ATI Technologies Inc. AMD Radeon HD 6800 Series
-ATI Technologies Inc. AMD Radeon HD 6800 Series
-ATI Technologies Inc. AMD Radeon HD 6800 Series (Engineering Sample - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 6800 Series (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. AMD Radeon HD 6800 Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 6800M Series
-ATI Technologies Inc. AMD Radeon HD 6800M Series
-ATI Technologies Inc. AMD Radeon HD 6850
-ATI Technologies Inc. AMD Radeon HD 6850
-ATI Technologies Inc. AMD Radeon HD 6850 X2
-ATI Technologies Inc. AMD Radeon HD 6850M
-ATI Technologies Inc. AMD Radeon HD 6850M
-ATI Technologies Inc. AMD Radeon HD 6870
-ATI Technologies Inc. AMD Radeon HD 6870M
-ATI Technologies Inc. AMD Radeon HD 6870M
-ATI Technologies Inc. AMD Radeon HD 6900 Series
-ATI Technologies Inc. AMD Radeon HD 6900 Series
-ATI Technologies Inc. AMD Radeon HD 6900 Series
-ATI Technologies Inc. AMD Radeon HD 6900 Series
-ATI Technologies Inc. AMD Radeon HD 6900 Series (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. AMD Radeon HD 6900 Series (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. AMD Radeon HD 6900M Series
-ATI Technologies Inc. AMD Radeon HD 6900M Series
-ATI Technologies Inc. AMD Radeon HD 6970
-ATI Technologies Inc. AMD Radeon HD 6970
-ATI Technologies Inc. AMD Radeon HD 6970M
-ATI Technologies Inc. AMD Radeon HD 6970M
-ATI Technologies Inc. AMD Radeon HD 6990
-ATI Technologies Inc. AMD Radeon HD 6990
-ATI Technologies Inc. AMD Radeon HD 6990M
-ATI Technologies Inc. AMD Radeon HD 6990M
-ATI Technologies Inc. AMD Radeon HD 6990M
-ATI Technologies Inc. AMD Radeon HD 7000 series
-ATI Technologies Inc. AMD Radeon HD 7000 series
-ATI Technologies Inc. AMD Radeon HD 7290 Graphics
-ATI Technologies Inc. AMD Radeon HD 7300 Series (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. AMD Radeon HD 7300 Series Graphics
-ATI Technologies Inc. AMD Radeon HD 7300 Series Graphics
-ATI Technologies Inc. AMD Radeon HD 7310
-ATI Technologies Inc. AMD Radeon HD 7310
-ATI Technologies Inc. AMD Radeon HD 7310 Graphics
-ATI Technologies Inc. AMD Radeon HD 7310 Graphics
-ATI Technologies Inc. AMD Radeon HD 7310 Graphics
-ATI Technologies Inc. AMD Radeon HD 7310 Graphics (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. AMD Radeon HD 7310G
-ATI Technologies Inc. AMD Radeon HD 7310M
-ATI Technologies Inc. AMD Radeon HD 7310M
-ATI Technologies Inc. AMD Radeon HD 7340
-ATI Technologies Inc. AMD Radeon HD 7340
-ATI Technologies Inc. AMD Radeon HD 7340 Graphics
-ATI Technologies Inc. AMD Radeon HD 7340 Graphics
-ATI Technologies Inc. AMD Radeon HD 7340G
-ATI Technologies Inc. AMD Radeon HD 7340G
-ATI Technologies Inc. AMD Radeon HD 7340M
-ATI Technologies Inc. AMD Radeon HD 7340M
-ATI Technologies Inc. AMD Radeon HD 7350
-ATI Technologies Inc. AMD Radeon HD 7350
-ATI Technologies Inc. AMD Radeon HD 7350 Graphics
-ATI Technologies Inc. AMD Radeon HD 7370M
-ATI Technologies Inc. AMD Radeon HD 7400 Series
-ATI Technologies Inc. AMD Radeon HD 7400 Series (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. AMD Radeon HD 7400G
-ATI Technologies Inc. AMD Radeon HD 7400G
-ATI Technologies Inc. AMD Radeon HD 7400M Series
-ATI Technologies Inc. AMD Radeon HD 7400M Series
-ATI Technologies Inc. AMD Radeon HD 7400M Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 7410M
-ATI Technologies Inc. AMD Radeon HD 7420G
-ATI Technologies Inc. AMD Radeon HD 7420G
-ATI Technologies Inc. AMD Radeon HD 7450
-ATI Technologies Inc. AMD Radeon HD 7450
-ATI Technologies Inc. AMD Radeon HD 7450
-ATI Technologies Inc. AMD Radeon HD 7450 Graphics
-ATI Technologies Inc. AMD Radeon HD 7450A Graphics
-ATI Technologies Inc. AMD Radeon HD 7450A Graphics
-ATI Technologies Inc. AMD Radeon HD 7450M
-ATI Technologies Inc. AMD Radeon HD 7470
-ATI Technologies Inc. AMD Radeon HD 7470
-ATI Technologies Inc. AMD Radeon HD 7470
-ATI Technologies Inc. AMD Radeon HD 7470 Series
-ATI Technologies Inc. AMD Radeon HD 7470 Series
-ATI Technologies Inc. AMD Radeon HD 7470M
-ATI Technologies Inc. AMD Radeon HD 7470M
-ATI Technologies Inc. AMD Radeon HD 7480D
-ATI Technologies Inc. AMD Radeon HD 7480D
-ATI Technologies Inc. AMD Radeon HD 7500 Series
-ATI Technologies Inc. AMD Radeon HD 7500 Series (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. AMD Radeon HD 7500 Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 7500/7600 Series
-ATI Technologies Inc. AMD Radeon HD 7500G
-ATI Technologies Inc. AMD Radeon HD 7500G
-ATI Technologies Inc. AMD Radeon HD 7500G + 7500M/7600M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7500M/7600M Series
-ATI Technologies Inc. AMD Radeon HD 7510
-ATI Technologies Inc. AMD Radeon HD 7510
-ATI Technologies Inc. AMD Radeon HD 7520G
-ATI Technologies Inc. AMD Radeon HD 7520G
-ATI Technologies Inc. AMD Radeon HD 7520G + 6400M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7520G + 7470M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7520G + 7470M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7520G + 7500/7600 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7520G + 7600M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7520G + 7610M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7520G + 7670M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7520G + 7670M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7540D
-ATI Technologies Inc. AMD Radeon HD 7540D
-ATI Technologies Inc. AMD Radeon HD 7540D + 7450 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7550M
-ATI Technologies Inc. AMD Radeon HD 7550M
-ATI Technologies Inc. AMD Radeon HD 7550M/7650M Graphics
-ATI Technologies Inc. AMD Radeon HD 7550M/7650M Graphics
-ATI Technologies Inc. AMD Radeon HD 7560D
-ATI Technologies Inc. AMD Radeon HD 7560D
-ATI Technologies Inc. AMD Radeon HD 7560D (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 7560D + 6570 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7560D + 6670 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7560D + 7560D Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7560D + 7600 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7560D + 7670 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7570
-ATI Technologies Inc. AMD Radeon HD 7570
-ATI Technologies Inc. AMD Radeon HD 7570 Graphics
-ATI Technologies Inc. AMD Radeon HD 7570 Series
-ATI Technologies Inc. AMD Radeon HD 7570M
-ATI Technologies Inc. AMD Radeon HD 7570M/HD 7670M Graphics
-ATI Technologies Inc. AMD Radeon HD 7580D
-ATI Technologies Inc. AMD Radeon HD 7600 Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 7600G
-ATI Technologies Inc. AMD Radeon HD 7600G + 7500M/7600M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7600G + 7550M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7600M + 7600M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7600M Series
-ATI Technologies Inc. AMD Radeon HD 7600M Series
-ATI Technologies Inc. AMD Radeon HD 7610M
-ATI Technologies Inc. AMD Radeon HD 7610M
-ATI Technologies Inc. AMD Radeon HD 7620G
-ATI Technologies Inc. AMD Radeon HD 7640G
-ATI Technologies Inc. AMD Radeon HD 7640G
-ATI Technologies Inc. AMD Radeon HD 7640G + 6400M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7640G + 7450M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7640G + 7470M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7640G + 7470M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7640G + 7500/7600 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7640G + 7500M/7600M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7640G + 7600M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7640G + 7610M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7640G + 7670M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7650A
-ATI Technologies Inc. AMD Radeon HD 7650A Graphics
-ATI Technologies Inc. AMD Radeon HD 7650M
-ATI Technologies Inc. AMD Radeon HD 7650M
-ATI Technologies Inc. AMD Radeon HD 7650M Series
-ATI Technologies Inc. AMD Radeon HD 7660D
-ATI Technologies Inc. AMD Radeon HD 7660D
-ATI Technologies Inc. AMD Radeon HD 7660D + 6570 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660D + 6670 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660D + 7670 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660D + 7700 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660G
-ATI Technologies Inc. AMD Radeon HD 7660G
-ATI Technologies Inc. AMD Radeon HD 7660G + 6400M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660G + 7400M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660G + 7470M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660G + 7500/7600 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660G + 7600M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660G + 7610M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660G + 7670M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660G + 7670M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7660G + 7700M Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 7670
-ATI Technologies Inc. AMD Radeon HD 7670
-ATI Technologies Inc. AMD Radeon HD 7670M
-ATI Technologies Inc. AMD Radeon HD 7670M
-ATI Technologies Inc. AMD Radeon HD 7690M
-ATI Technologies Inc. AMD Radeon HD 7700 Series
-ATI Technologies Inc. AMD Radeon HD 7700 Series
-ATI Technologies Inc. AMD Radeon HD 7700 Series
-ATI Technologies Inc. AMD Radeon HD 7700 Series (Microsoft Corporation - WDDM v1.3)
-ATI Technologies Inc. AMD Radeon HD 7700M Series
-ATI Technologies Inc. AMD Radeon HD 7730M
-ATI Technologies Inc. AMD Radeon HD 7770
-ATI Technologies Inc. AMD Radeon HD 7770
-ATI Technologies Inc. AMD Radeon HD 7770 GHz Edition
-ATI Technologies Inc. AMD Radeon HD 7800 Series
-ATI Technologies Inc. AMD Radeon HD 7800 Series
-ATI Technologies Inc. AMD Radeon HD 7800 Series
-ATI Technologies Inc. AMD Radeon HD 7800 Series
-ATI Technologies Inc. AMD Radeon HD 7800 Series (Engineering Sample - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 7800 Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon HD 7800 Series (Microsoft Corporation - WDDM v1.3)
-ATI Technologies Inc. AMD Radeon HD 7800 Series (Microsoft Corporation - WDDM v1.3)
-ATI Technologies Inc. AMD Radeon HD 7800M Series
-ATI Technologies Inc. AMD Radeon HD 7800M Series
-ATI Technologies Inc. AMD Radeon HD 7870
-ATI Technologies Inc. AMD Radeon HD 7870
-ATI Technologies Inc. AMD Radeon HD 7870M
-ATI Technologies Inc. AMD Radeon HD 7870M
-ATI Technologies Inc. AMD Radeon HD 7900 Series
-ATI Technologies Inc. AMD Radeon HD 7900 Series
-ATI Technologies Inc. AMD Radeon HD 7900 Series
-ATI Technologies Inc. AMD Radeon HD 7900 Series
-ATI Technologies Inc. AMD Radeon HD 7900 Series (Microsoft Corporation - WDDM v1.3)
-ATI Technologies Inc. AMD Radeon HD 7950
-ATI Technologies Inc. AMD Radeon HD 7950
-ATI Technologies Inc. AMD Radeon HD 7950
-ATI Technologies Inc. AMD Radeon HD 7970
-ATI Technologies Inc. AMD Radeon HD 7970
-ATI Technologies Inc. AMD Radeon HD 7970M
-ATI Technologies Inc. AMD Radeon HD 7970M
-ATI Technologies Inc. AMD Radeon HD 7970M
-ATI Technologies Inc. AMD Radeon HD 8210
-ATI Technologies Inc. AMD Radeon HD 8240
-ATI Technologies Inc. AMD Radeon HD 8250
-ATI Technologies Inc. AMD Radeon HD 8280G
-ATI Technologies Inc. AMD Radeon HD 8330
-ATI Technologies Inc. AMD Radeon HD 8330
-ATI Technologies Inc. AMD Radeon HD 8350
-ATI Technologies Inc. AMD Radeon HD 8350
-ATI Technologies Inc. AMD Radeon HD 8350G
-ATI Technologies Inc. AMD Radeon HD 8400
-ATI Technologies Inc. AMD Radeon HD 8450
-ATI Technologies Inc. AMD Radeon HD 8450G
-ATI Technologies Inc. AMD Radeon HD 8470
-ATI Technologies Inc. AMD Radeon HD 8470
-ATI Technologies Inc. AMD Radeon HD 8470D
-ATI Technologies Inc. AMD Radeon HD 8550G
-ATI Technologies Inc. AMD Radeon HD 8550G
-ATI Technologies Inc. AMD Radeon HD 8570
-ATI Technologies Inc. AMD Radeon HD 8570
-ATI Technologies Inc. AMD Radeon HD 8570D
-ATI Technologies Inc. AMD Radeon HD 8570D
-ATI Technologies Inc. AMD Radeon HD 8610G
-ATI Technologies Inc. AMD Radeon HD 8650G
-ATI Technologies Inc. AMD Radeon HD 8650G
-ATI Technologies Inc. AMD Radeon HD 8670D
-ATI Technologies Inc. AMD Radeon HD 8670D
-ATI Technologies Inc. AMD Radeon HD 8670D
-ATI Technologies Inc. AMD Radeon HD 8670D + 6670 Dual Graphics
-ATI Technologies Inc. AMD Radeon HD 8700M Series
-ATI Technologies Inc. AMD Radeon HD 8700M Series
-ATI Technologies Inc. AMD Radeon HD 8730M
-ATI Technologies Inc. AMD Radeon HD 8730M
-ATI Technologies Inc. AMD Radeon HD 8730M
-ATI Technologies Inc. AMD Radeon HD 8750M
-ATI Technologies Inc. AMD Radeon HD 8760
-ATI Technologies Inc. AMD Radeon HD 8760
-ATI Technologies Inc. AMD Radeon HD 8760
-ATI Technologies Inc. AMD Radeon HD 8800M Series
-ATI Technologies Inc. AMD Radeon HD 8800M Series
-ATI Technologies Inc. AMD Radeon HD 8900 Series (OEM)
-ATI Technologies Inc. AMD Radeon HD 8950
-ATI Technologies Inc. AMD Radeon HD 8950
-ATI Technologies Inc. AMD Radeon HD HD7850M
-ATI Technologies Inc. AMD Radeon HD HD7850M
-ATI Technologies Inc. AMD Radeon HD6370D Graphics
-ATI Technologies Inc. AMD Radeon HD6370D Graphics
-ATI Technologies Inc. AMD Radeon HD7610M
-ATI Technologies Inc. AMD Radeon HD7610M
-ATI Technologies Inc. AMD Radeon HD7700 Series
-ATI Technologies Inc. AMD Radeon HD7700 Series
-ATI Technologies Inc. AMD Radeon HD7700 Series
-ATI Technologies Inc. AMD Radeon HD7770
-ATI Technologies Inc. AMD Radeon HD7770
-ATI Technologies Inc. AMD Radeon HD7770 GHz Edition
-ATI Technologies Inc. AMD Radeon HD7770 GHz Edition
-ATI Technologies Inc. AMD Radeon HD8350
-ATI Technologies Inc. AMD Radeon(TM) HD 6380G
-ATI Technologies Inc. AMD Radeon(TM) HD 6380G
-ATI Technologies Inc. AMD Radeon(TM) HD 6470M
-ATI Technologies Inc. AMD Radeon(TM) HD 6470M
-ATI Technologies Inc. AMD Radeon(TM) HD 6480G
-ATI Technologies Inc. AMD Radeon(TM) HD 6480G
-ATI Technologies Inc. AMD Radeon(TM) HD 6480G (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. AMD Radeon(TM) HD 6520G
-ATI Technologies Inc. AMD Radeon(TM) HD 6520G
-ATI Technologies Inc. AMD Radeon(TM) HD 6620G
-ATI Technologies Inc. AMD Radeon(TM) HD 6620G
-ATI Technologies Inc. AMD Radeon(TM) HD 6630M
-ATI Technologies Inc. AMD Radeon(TM) HD 6650M
-ATI Technologies Inc. AMD Radeon(TM) HD 7450
-ATI Technologies Inc. AMD Radeon(TM) HD 7450A Graphics
-ATI Technologies Inc. AMD Radeon(TM) HD 7650A Graphics
-ATI Technologies Inc. AMD Radeon(TM) HD 7670A Graphics
-ATI Technologies Inc. AMD Radeon(TM) HD 7670M
-ATI Technologies Inc. AMD Radeon(TM) HD 8350
-ATI Technologies Inc. AMD Radeon(TM) HD8490
-ATI Technologies Inc. AMD Radeon. HD 7350
-ATI Technologies Inc. AMD Radeon. HD 7670M
-ATI Technologies Inc. AMD Radeon. HD 7730M
-ATI Technologies Inc. AMD Radeon. HD 7730M
-ATI Technologies Inc. ASUS AH3450 Series
-ATI Technologies Inc. ASUS AH3450 Series
-ATI Technologies Inc. ASUS AH3650 Series
-ATI Technologies Inc. ASUS AH4650 Series
-ATI Technologies Inc. ASUS ARES
-ATI Technologies Inc. ASUS ARES2
-ATI Technologies Inc. ASUS EAH2400 Series
-ATI Technologies Inc. ASUS EAH2600 Series
-ATI Technologies Inc. ASUS EAH3450 Series
-ATI Technologies Inc. ASUS EAH3650 Series
-ATI Technologies Inc. ASUS EAH3850 Series
-ATI Technologies Inc. ASUS EAH3870 Series
-ATI Technologies Inc. ASUS EAH4350 series
-ATI Technologies Inc. ASUS EAH4350 series
-ATI Technologies Inc. ASUS EAH4550 series
-ATI Technologies Inc. ASUS EAH4650 series
-ATI Technologies Inc. ASUS EAH4670 series
-ATI Technologies Inc. ASUS EAH4770 Series
-ATI Technologies Inc. ASUS EAH4770 series
-ATI Technologies Inc. ASUS EAH4850 series
-ATI Technologies Inc. ASUS EAH4870 series
-ATI Technologies Inc. ASUS EAH4870x2
-ATI Technologies Inc. ASUS EAH4890
-ATI Technologies Inc. ASUS EAH5450 Series
-ATI Technologies Inc. ASUS EAH5450 Series
-ATI Technologies Inc. ASUS EAH5550 Series
-ATI Technologies Inc. ASUS EAH5550 Series
-ATI Technologies Inc. ASUS EAH5570 series
-ATI Technologies Inc. ASUS EAH5570 series
-ATI Technologies Inc. ASUS EAH5670 Series
-ATI Technologies Inc. ASUS EAH5750 Series
-ATI Technologies Inc. ASUS EAH5750 Series
-ATI Technologies Inc. ASUS EAH5770 Series
-ATI Technologies Inc. ASUS EAH5770 Series
-ATI Technologies Inc. ASUS EAH5830 Series
-ATI Technologies Inc. ASUS EAH5830 Series
-ATI Technologies Inc. ASUS EAH5850 Series
-ATI Technologies Inc. ASUS EAH5850 Series
-ATI Technologies Inc. ASUS EAH5870 Series
-ATI Technologies Inc. ASUS EAH5870 Series
-ATI Technologies Inc. ASUS EAH6450 Series
-ATI Technologies Inc. ASUS EAH6450 Series
-ATI Technologies Inc. ASUS EAH6570 Series
-ATI Technologies Inc. ASUS EAH6570 Series
-ATI Technologies Inc. ASUS EAH6670 Series
-ATI Technologies Inc. ASUS EAH6670 Series
-ATI Technologies Inc. ASUS EAH6750 Series
-ATI Technologies Inc. ASUS EAH6750 Series
-ATI Technologies Inc. ASUS EAH6770 Series
-ATI Technologies Inc. ASUS EAH6770 Series
-ATI Technologies Inc. ASUS EAH6850 Series
-ATI Technologies Inc. ASUS EAH6850 Series
-ATI Technologies Inc. ASUS EAH6870 Series
-ATI Technologies Inc. ASUS EAH6870 Series
-ATI Technologies Inc. ASUS EAH6950 Series
-ATI Technologies Inc. ASUS EAH6950 Series
-ATI Technologies Inc. ASUS EAH6970 Series
-ATI Technologies Inc. ASUS EAH6970 Series
-ATI Technologies Inc. ASUS Extreme AX300 Series
-ATI Technologies Inc. ASUS Extreme AX300SE/T
-ATI Technologies Inc. ASUS Extreme AX550 Series
-ATI Technologies Inc. ASUS Extreme AX550 Series x86/SSE2
-ATI Technologies Inc. ASUS Extreme AX600 Series
-ATI Technologies Inc. ASUS HD 7350
-ATI Technologies Inc. ASUS HD7470 Series
-ATI Technologies Inc. ASUS HD7670 Series
-ATI Technologies Inc. ASUS HD7670 Series
-ATI Technologies Inc. ASUS HD7750 Series
-ATI Technologies Inc. ASUS HD7750 Series
-ATI Technologies Inc. ASUS HD7770 Series
-ATI Technologies Inc. ASUS HD7770 Series
-ATI Technologies Inc. ASUS HD7790 Series
-ATI Technologies Inc. ASUS HD7850 Series
-ATI Technologies Inc. ASUS HD7850 Series
-ATI Technologies Inc. ASUS HD7850 Series
-ATI Technologies Inc. ASUS HD7870 Series
-ATI Technologies Inc. ASUS HD7870 Series
-ATI Technologies Inc. ASUS HD7870 Series
-ATI Technologies Inc. ASUS HD7870 Series
-ATI Technologies Inc. ASUS HD7950 Series
-ATI Technologies Inc. ASUS HD7950 Series
-ATI Technologies Inc. ASUS HD7950 Series
-ATI Technologies Inc. ASUS HD7970 Series
-ATI Technologies Inc. ASUS HD7970 Series
-ATI Technologies Inc. ASUS HD7970 Series
-ATI Technologies Inc. ASUS X1300 Series
-ATI Technologies Inc. ASUS X1300 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ASUS X1300 Series x86/SSE2
-ATI Technologies Inc. ASUS X1300 x86/SSE2
-ATI Technologies Inc. ASUS X1550 Series
-ATI Technologies Inc. ASUS X1550 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ASUS X1550 Series x86/SSE2
-ATI Technologies Inc. ASUS X1600 Series
-ATI Technologies Inc. ASUS X1600 Series x86
-ATI Technologies Inc. ASUS X1600 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ASUS X1600 Series x86/SSE2
-ATI Technologies Inc. ASUS X1650 Series
-ATI Technologies Inc. ASUS X1650 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ASUS X1650 Series x86/SSE2
-ATI Technologies Inc. ASUS X1950 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon HD 5000 Series
-ATI Technologies Inc. ATI Radeon HD 6350
-ATI Technologies Inc. ATI All-in-Wonder HD
-ATI Technologies Inc. ATI Display Adapter
-ATI Technologies Inc. ATI FireGL V3100
-ATI Technologies Inc. ATI FireGL V3200 Pentium 4 (SSE2)
-ATI Technologies Inc. ATI FireGL V3300
-ATI Technologies Inc. ATI FireGL V3350
-ATI Technologies Inc. ATI FireGL V3350 Pentium 4 (SSE2)
-ATI Technologies Inc. ATI FireGL V3400 (Microsoft Corporation - WDDM)
-ATI Technologies Inc. ATI FireGL V3400 Pentium 4 (SSE2)
-ATI Technologies Inc. ATI FireGL V3600
-ATI Technologies Inc. ATI FireGL V5200 (Microsoft Corporation - WDDM)
-ATI Technologies Inc. ATI FireGL V5200 Pentium 4 (SSE2)
-ATI Technologies Inc. ATI FireGL V5600
-ATI Technologies Inc. ATI FireGL V7200
-ATI Technologies Inc. ATI FireGL V7200 Pentium 4 (SSE2)
-ATI Technologies Inc. ATI FireGL V7600
-ATI Technologies Inc. ATI FireGL V7700
-ATI Technologies Inc. ATI FireMV 2250
-ATI Technologies Inc. ATI FireMV 2250 x86/SSE2
-ATI Technologies Inc. ATI FirePro 2260
-ATI Technologies Inc. ATI FirePro 2260
-ATI Technologies Inc. ATI FirePro 2450
-ATI Technologies Inc. ATI FirePro 3800 (FireGL) Graphics Adapter
-ATI Technologies Inc. ATI FirePro M5800
-ATI Technologies Inc. ATI FirePro M7740
-ATI Technologies Inc. ATI FirePro M7820
-ATI Technologies Inc. ATI FirePro M7820
-ATI Technologies Inc. ATI FirePro M7820 (FireGL)
-ATI Technologies Inc. ATI FirePro V3700 (FireGL)
-ATI Technologies Inc. ATI FirePro V3800
-ATI Technologies Inc. ATI FirePro V3800 (FireGL V)
-ATI Technologies Inc. ATI FirePro V3800 (FireGL V) Graphics Adapter
-ATI Technologies Inc. ATI FirePro V3800 (FireGL)
-ATI Technologies Inc. ATI FirePro V4800
-ATI Technologies Inc. ATI FirePro V4800 (FireGL V)
-ATI Technologies Inc. ATI FirePro V4800 (FireGL)
-ATI Technologies Inc. ATI FirePro V5700 (FireGL)
-ATI Technologies Inc. ATI FirePro V5800 (FireGL V)
-ATI Technologies Inc. ATI FirePro V5800 (FireGL)
-ATI Technologies Inc. ATI FirePro V7800 (FireGL V)
-ATI Technologies Inc. ATI FirePro V7800 (FireGL)
-ATI Technologies Inc. ATI FirePro V8700 (FireGL)
-ATI Technologies Inc. ATI FirePro V9800 (FireGL V)
-ATI Technologies Inc. ATI MOBILITY FIRE GL T2/T2e
-ATI Technologies Inc. ATI MOBILITY FireGL V3200
-ATI Technologies Inc. ATI MOBILITY FireGL V5000 Pentium 4 (SSE2)
-ATI Technologies Inc. ATI MOBILITY FireGL V5200
-ATI Technologies Inc. ATI MOBILITY FireGL V5200 Pentium 4 (SSE2)
-ATI Technologies Inc. ATI MOBILITY FireGL V5250
-ATI Technologies Inc. ATI MOBILITY RADEON 9600 Series
-ATI Technologies Inc. ATI MOBILITY RADEON 9600/9700
-ATI Technologies Inc. ATI MOBILITY RADEON 9600/9700
-ATI Technologies Inc. ATI MOBILITY RADEON 9600/9700 Series
-ATI Technologies Inc. ATI MOBILITY RADEON 9600/9700 Series
-ATI Technologies Inc. ATI MOBILITY RADEON 9600/9700 Series (Omega 3
-ATI Technologies Inc. ATI MOBILITY RADEON HD 2300
-ATI Technologies Inc. ATI MOBILITY RADEON HD 2400
-ATI Technologies Inc. ATI MOBILITY RADEON HD 2600
-ATI Technologies Inc. ATI MOBILITY RADEON HD 3430
-ATI Technologies Inc. ATI MOBILITY RADEON HD 3450
-ATI Technologies Inc. ATI MOBILITY RADEON HD 3650
-ATI Technologies Inc. ATI MOBILITY RADEON HD 4530 / 4570
-ATI Technologies Inc. ATI MOBILITY RADEON X1300
-ATI Technologies Inc. ATI MOBILITY RADEON X1350
-ATI Technologies Inc. ATI MOBILITY RADEON X1400
-ATI Technologies Inc. ATI MOBILITY RADEON X1600
-ATI Technologies Inc. ATI MOBILITY RADEON X1700
-ATI Technologies Inc. ATI MOBILITY RADEON X1800
-ATI Technologies Inc. ATI MOBILITY RADEON X1900
-ATI Technologies Inc. ATI MOBILITY RADEON X2300
-ATI Technologies Inc. ATI MOBILITY RADEON X2300 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI MOBILITY RADEON X300
-ATI Technologies Inc. ATI MOBILITY RADEON X300 x86/SSE2
-ATI Technologies Inc. ATI MOBILITY RADEON X600
-ATI Technologies Inc. ATI MOBILITY RADEON X600 SE
-ATI Technologies Inc. ATI MOBILITY RADEON X700
-ATI Technologies Inc. ATI MOBILITY RADEON XPRESS 200
-ATI Technologies Inc. ATI MOBILITY RADEON XPRESS 200 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI MOBILITY Radeon HD 4650
-ATI Technologies Inc. ATI Mobility FireGL V5700
-ATI Technologies Inc. ATI Mobility FireGL V5725
-ATI Technologies Inc. ATI Mobility FireGL V5725
-ATI Technologies Inc. ATI Mobility Radeon 4100
-ATI Technologies Inc. ATI Mobility Radeon Graphics
-ATI Technologies Inc. ATI Mobility Radeon HD 2300
-ATI Technologies Inc. ATI Mobility Radeon HD 2300 x86/SSE2
-ATI Technologies Inc. ATI Mobility Radeon HD 2400
-ATI Technologies Inc. ATI Mobility Radeon HD 2400
-ATI Technologies Inc. ATI Mobility Radeon HD 2400 (Omega 3.8.442)
-ATI Technologies Inc. ATI Mobility Radeon HD 2400 XT
-ATI Technologies Inc. ATI Mobility Radeon HD 2600
-ATI Technologies Inc. ATI Mobility Radeon HD 2600
-ATI Technologies Inc. ATI Mobility Radeon HD 2600 XT
-ATI Technologies Inc. ATI Mobility Radeon HD 2600 XT (Microsoft Corporation WDDM 1.1)
-ATI Technologies Inc. ATI Mobility Radeon HD 2700
-ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series (Microsoft Corporation WDDM 1.1)
-ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series (Microsoft Corporation- WDDM v1.1)
-ATI Technologies Inc. ATI Mobility Radeon HD 3410
-ATI Technologies Inc. ATI Mobility Radeon HD 3430
-ATI Technologies Inc. ATI Mobility Radeon HD 3430
-ATI Technologies Inc. ATI Mobility Radeon HD 3430 (Microsoft Corporation- WDDM v1.1)
-ATI Technologies Inc. ATI Mobility Radeon HD 3450
-ATI Technologies Inc. ATI Mobility Radeon HD 3470
-ATI Technologies Inc. ATI Mobility Radeon HD 3470
-ATI Technologies Inc. ATI Mobility Radeon HD 3470 Hybrid X2
-ATI Technologies Inc. ATI Mobility Radeon HD 3470 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 3650
-ATI Technologies Inc. ATI Mobility Radeon HD 3650
-ATI Technologies Inc. ATI Mobility Radeon HD 3670
-ATI Technologies Inc. ATI Mobility Radeon HD 3850
-ATI Technologies Inc. ATI Mobility Radeon HD 3870
-ATI Technologies Inc. ATI Mobility Radeon HD 3870 X2
-ATI Technologies Inc. ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4200
-ATI Technologies Inc. ATI Mobility Radeon HD 4200 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4200 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4200 Series (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Mobility Radeon HD 4225
-ATI Technologies Inc. ATI Mobility Radeon HD 4225 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4250
-ATI Technologies Inc. ATI Mobility Radeon HD 4250
-ATI Technologies Inc. ATI Mobility Radeon HD 4250 Graphics
-ATI Technologies Inc. ATI Mobility Radeon HD 4250 Graphics
-ATI Technologies Inc. ATI Mobility Radeon HD 4250 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4270
-ATI Technologies Inc. ATI Mobility Radeon HD 4270 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4300 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4300 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4300/4500 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4330
-ATI Technologies Inc. ATI Mobility Radeon HD 4330
-ATI Technologies Inc. ATI Mobility Radeon HD 4330 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4350
-ATI Technologies Inc. ATI Mobility Radeon HD 4350 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series (Microsoft Corporation WDDM 1.1)
-ATI Technologies Inc. ATI Mobility Radeon HD 4500/5100 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4500/5100 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4530
-ATI Technologies Inc. ATI Mobility Radeon HD 4530 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4530 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4550
-ATI Technologies Inc. ATI Mobility Radeon HD 4570
-ATI Technologies Inc. ATI Mobility Radeon HD 4570
-ATI Technologies Inc. ATI Mobility Radeon HD 4600 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4650
-ATI Technologies Inc. ATI Mobility Radeon HD 4650
-ATI Technologies Inc. ATI Mobility Radeon HD 4650 (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Mobility Radeon HD 4650 (Microsoft Corporation- WDDM v1.1)
-ATI Technologies Inc. ATI Mobility Radeon HD 4650 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4670
-ATI Technologies Inc. ATI Mobility Radeon HD 4670 (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Mobility Radeon HD 4830
-ATI Technologies Inc. ATI Mobility Radeon HD 4830 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 4850
-ATI Technologies Inc. ATI Mobility Radeon HD 4870
-ATI Technologies Inc. ATI Mobility Radeon HD 5000
-ATI Technologies Inc. ATI Mobility Radeon HD 5000
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series (Engineering Sample - WDDM v1.20)
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. ATI Mobility Radeon HD 5100
-ATI Technologies Inc. ATI Mobility Radeon HD 5145
-ATI Technologies Inc. ATI Mobility Radeon HD 5145
-ATI Technologies Inc. ATI Mobility Radeon HD 5165
-ATI Technologies Inc. ATI Mobility Radeon HD 5165
-ATI Technologies Inc. ATI Mobility Radeon HD 530v
-ATI Technologies Inc. ATI Mobility Radeon HD 530v
-ATI Technologies Inc. ATI Mobility Radeon HD 5400
-ATI Technologies Inc. ATI Mobility Radeon HD 5400 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 5400 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 540v
-ATI Technologies Inc. ATI Mobility Radeon HD 5430
-ATI Technologies Inc. ATI Mobility Radeon HD 5450
-ATI Technologies Inc. ATI Mobility Radeon HD 5450 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 545v
-ATI Technologies Inc. ATI Mobility Radeon HD 545v
-ATI Technologies Inc. ATI Mobility Radeon HD 5470
-ATI Technologies Inc. ATI Mobility Radeon HD 5470
-ATI Technologies Inc. ATI Mobility Radeon HD 550v
-ATI Technologies Inc. ATI Mobility Radeon HD 5570
-ATI Technologies Inc. ATI Mobility Radeon HD 5600/5700 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 560v
-ATI Technologies Inc. ATI Mobility Radeon HD 5650
-ATI Technologies Inc. ATI Mobility Radeon HD 5650
-ATI Technologies Inc. ATI Mobility Radeon HD 565v
-ATI Technologies Inc. ATI Mobility Radeon HD 5700 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 5730
-ATI Technologies Inc. ATI Mobility Radeon HD 5800 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 5800 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 5800 Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. ATI Mobility Radeon HD 5830 Series
-ATI Technologies Inc. ATI Mobility Radeon HD 5850
-ATI Technologies Inc. ATI Mobility Radeon HD 5850
-ATI Technologies Inc. ATI Mobility Radeon HD 5870
-ATI Technologies Inc. ATI Mobility Radeon HD 6370
-ATI Technologies Inc. ATI Mobility Radeon HD 6370
-ATI Technologies Inc. ATI Mobility Radeon HD 6550
-ATI Technologies Inc. ATI Mobility Radeon HD 6550
-ATI Technologies Inc. ATI Mobility Radeon HD 6550
-ATI Technologies Inc. ATI Mobility Radeon HD 6570
-ATI Technologies Inc. ATI Mobility Radeon HD 6570
-ATI Technologies Inc. ATI Mobility Radeon X1300
-ATI Technologies Inc. ATI Mobility Radeon X1300 (Omega 3.8.252) x86/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X1300 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X1300 x86/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X1350
-ATI Technologies Inc. ATI Mobility Radeon X1350 x86/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X1400
-ATI Technologies Inc. ATI Mobility Radeon X1400 (Omega 3.8.442)
-ATI Technologies Inc. ATI Mobility Radeon X1400 x86
-ATI Technologies Inc. ATI Mobility Radeon X1400 x86/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X1450 x86/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X1600
-ATI Technologies Inc. ATI Mobility Radeon X1600 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X1600 x86/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X1700
-ATI Technologies Inc. ATI Mobility Radeon X1700 x86
-ATI Technologies Inc. ATI Mobility Radeon X1700 x86/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X1800 x86/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X1900
-ATI Technologies Inc. ATI Mobility Radeon X2300
-ATI Technologies Inc. ATI Mobility Radeon X2300
-ATI Technologies Inc. ATI Mobility Radeon X2300 x86/MMX/3DNow!
-ATI Technologies Inc. ATI Mobility Radeon X2300 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X2300 x86/SSE2
-ATI Technologies Inc. ATI Mobility Radeon X2500
-ATI Technologies Inc. ATI Mobility Radeon. HD 530v
-ATI Technologies Inc. ATI Mobility Radeon. HD 5470
-ATI Technologies Inc. ATI RADEON 9600 Series
-ATI Technologies Inc. ATI RADEON 9600/X1050 Series
-ATI Technologies Inc. ATI RADEON E4690
-ATI Technologies Inc. ATI RADEON HD 3200 Graphics
-ATI Technologies Inc. ATI RADEON XPRESS 1100
-ATI Technologies Inc. ATI RADEON XPRESS 1100 Series
-ATI Technologies Inc. ATI RADEON XPRESS 1100 Series
-ATI Technologies Inc. ATI RADEON XPRESS 1100 x86/SSE2
-ATI Technologies Inc. ATI RADEON XPRESS 1200 Series
-ATI Technologies Inc. ATI RADEON XPRESS 200
-ATI Technologies Inc. ATI RADEON XPRESS 200 Series
-ATI Technologies Inc. ATI RADEON XPRESS 200 Series
-ATI Technologies Inc. ATI RADEON XPRESS 200 Series x86/SSE2
-ATI Technologies Inc. ATI RADEON XPRESS 200 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI RADEON XPRESS 200M SERIES
-ATI Technologies Inc. ATI RADEON XPRESS 200M Series
-ATI Technologies Inc. ATI RADEON XPRESS 200M Series (Microsoft Corporation)
-ATI Technologies Inc. ATI RADEON XPRESS 200M Series (Omega 3.8.421) x86/SSE2
-ATI Technologies Inc. ATI RADEON XPRESS 200M Series x86/SSE2
-ATI Technologies Inc. ATI Radeon 2100
-ATI Technologies Inc. ATI Radeon 2100 (Microsoft Corporation - WDDM)
-ATI Technologies Inc. ATI Radeon 2100 (Microsoft Corporation - WDDM)
-ATI Technologies Inc. ATI Radeon 2100 Graphics
-ATI Technologies Inc. ATI Radeon 3000
-ATI Technologies Inc. ATI Radeon 3000 Graphics
-ATI Technologies Inc. ATI Radeon 3000 Graphics
-ATI Technologies Inc. ATI Radeon 3000 Graphics
-ATI Technologies Inc. ATI Radeon 3000 Graphics (Engineering Sample - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon 3000 Series Graphics
-ATI Technologies Inc. ATI Radeon 3100 Graphics
-ATI Technologies Inc. ATI Radeon 3100 Graphics
-ATI Technologies Inc. ATI Radeon 3100 Graphics (Microsoft Corporation WDDM 1.1)
-ATI Technologies Inc. ATI Radeon 3100 Series Graphics
-ATI Technologies Inc. ATI Radeon 9550 / X1050
-ATI Technologies Inc. ATI Radeon 9550 / X1050 Series
-ATI Technologies Inc. ATI Radeon 9550 / X1050 Series x86/SSE2
-ATI Technologies Inc. ATI Radeon 9550 / X1050 Series(Microsoft Corporation - WDDM)
-ATI Technologies Inc. ATI Radeon 9600 / X1050 Series
-ATI Technologies Inc. ATI Radeon 9600 / X1050 Series x86/SSE2
-ATI Technologies Inc. ATI Radeon 9600/9550/X1050 Series
-ATI Technologies Inc. ATI Radeon BA Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon BA Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Barts PRO Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Barts PRO Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Barts PRO Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Barts XT Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Barts XT Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Caicos PRO Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Caicos Unknown Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Cedar PRO Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Graphics Processor
-ATI Technologies Inc. ATI Radeon HD 2350
-ATI Technologies Inc. ATI Radeon HD 2400
-ATI Technologies Inc. ATI Radeon HD 2400 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 2400 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 2400 PCI
-ATI Technologies Inc. ATI Radeon HD 2400 PRO
-ATI Technologies Inc. ATI Radeon HD 2400 PRO AGP
-ATI Technologies Inc. ATI Radeon HD 2400 Pro
-ATI Technologies Inc. ATI Radeon HD 2400 Series
-ATI Technologies Inc. ATI Radeon HD 2400 Series AGP
-ATI Technologies Inc. ATI Radeon HD 2400 XT
-ATI Technologies Inc. ATI Radeon HD 2400 XT OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 2400 XT OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 2400 XT OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 2600 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 2600 PRO
-ATI Technologies Inc. ATI Radeon HD 2600 PRO OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 2600 PRO OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 2600 Pro
-ATI Technologies Inc. ATI Radeon HD 2600 Pro AGP
-ATI Technologies Inc. ATI Radeon HD 2600 Series
-ATI Technologies Inc. ATI Radeon HD 2600 Series AGP
-ATI Technologies Inc. ATI Radeon HD 2600 XT
-ATI Technologies Inc. ATI Radeon HD 2600/3600 Series
-ATI Technologies Inc. ATI Radeon HD 2900 GT
-ATI Technologies Inc. ATI Radeon HD 2900 PRO
-ATI Technologies Inc. ATI Radeon HD 2900 XT
-ATI Technologies Inc. ATI Radeon HD 3200 Graphics
-ATI Technologies Inc. ATI Radeon HD 3200 Graphics
-ATI Technologies Inc. ATI Radeon HD 3200 Graphics (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 3200 Graphics (Microsoft Corporation WDDM 1.1)
-ATI Technologies Inc. ATI Radeon HD 3300 Graphics
-ATI Technologies Inc. ATI Radeon HD 3400 Series
-ATI Technologies Inc. ATI Radeon HD 3400 Series
-ATI Technologies Inc. ATI Radeon HD 3450
-ATI Technologies Inc. ATI Radeon HD 3450
-ATI Technologies Inc. ATI Radeon HD 3450 - Dell Optiplex
-ATI Technologies Inc. ATI Radeon HD 3450 AGP
-ATI Technologies Inc. ATI Radeon HD 3470
-ATI Technologies Inc. ATI Radeon HD 3470 - Dell Optiplex
-ATI Technologies Inc. ATI Radeon HD 3600 Series
-ATI Technologies Inc. ATI Radeon HD 3600 Series
-ATI Technologies Inc. ATI Radeon HD 3600 Series (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 3600 Series (Microsoft Corporation WDDM 1.1)
-ATI Technologies Inc. ATI Radeon HD 3650
-ATI Technologies Inc. ATI Radeon HD 3650 AGP
-ATI Technologies Inc. ATI Radeon HD 3800 Series
-ATI Technologies Inc. ATI Radeon HD 3850
-ATI Technologies Inc. ATI Radeon HD 3850 (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 3850 AGP
-ATI Technologies Inc. ATI Radeon HD 3870
-ATI Technologies Inc. ATI Radeon HD 3870 (Engineering Sample - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 3870 (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 3870 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 3870 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 3870 X2
-ATI Technologies Inc. ATI Radeon HD 4200
-ATI Technologies Inc. ATI Radeon HD 4200
-ATI Technologies Inc. ATI Radeon HD 4200 (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 4250
-ATI Technologies Inc. ATI Radeon HD 4250
-ATI Technologies Inc. ATI Radeon HD 4250 (Engineering Sample - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 4250 (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 4250 Graphics
-ATI Technologies Inc. ATI Radeon HD 4250 Graphics
-ATI Technologies Inc. ATI Radeon HD 4270
-ATI Technologies Inc. ATI Radeon HD 4270
-ATI Technologies Inc. ATI Radeon HD 4290
-ATI Technologies Inc. ATI Radeon HD 4300 Series
-ATI Technologies Inc. ATI Radeon HD 4300 Series
-ATI Technologies Inc. ATI Radeon HD 4300/4500 Series
-ATI Technologies Inc. ATI Radeon HD 4300/4500 Series
-ATI Technologies Inc. ATI Radeon HD 4300/4500 Series (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 4300/4500 Series (Microsoft Corporation- WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 4350
-ATI Technologies Inc. ATI Radeon HD 4350
-ATI Technologies Inc. ATI Radeon HD 4350 (Microsoft Corporation WDDM 1.1)
-ATI Technologies Inc. ATI Radeon HD 4450
-ATI Technologies Inc. ATI Radeon HD 4500 Series
-ATI Technologies Inc. ATI Radeon HD 4520
-ATI Technologies Inc. ATI Radeon HD 4550
-ATI Technologies Inc. ATI Radeon HD 4550
-ATI Technologies Inc. ATI Radeon HD 4550 (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 4570
-ATI Technologies Inc. ATI Radeon HD 4580
-ATI Technologies Inc. ATI Radeon HD 4590
-ATI Technologies Inc. ATI Radeon HD 4600 Series
-ATI Technologies Inc. ATI Radeon HD 4600 Series
-ATI Technologies Inc. ATI Radeon HD 4600 Series (Engineering Sample - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 4600 Series (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 4600-serie (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 4650
-ATI Technologies Inc. ATI Radeon HD 4650
-ATI Technologies Inc. ATI Radeon HD 4650 (Microsoft Corporation WDDM 1.1)
-ATI Technologies Inc. ATI Radeon HD 4670
-ATI Technologies Inc. ATI Radeon HD 4670
-ATI Technologies Inc. ATI Radeon HD 4670 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 4670 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 4670 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 4700
-ATI Technologies Inc. ATI Radeon HD 4700 Series
-ATI Technologies Inc. ATI Radeon HD 4700 Series
-ATI Technologies Inc. ATI Radeon HD 4720
-ATI Technologies Inc. ATI Radeon HD 4730
-ATI Technologies Inc. ATI Radeon HD 4730 Series
-ATI Technologies Inc. ATI Radeon HD 4770
-ATI Technologies Inc. ATI Radeon HD 4770
-ATI Technologies Inc. ATI Radeon HD 4800
-ATI Technologies Inc. ATI Radeon HD 4800 Series
-ATI Technologies Inc. ATI Radeon HD 4800 Series
-ATI Technologies Inc. ATI Radeon HD 4800 Series (Microsoft Corporation - WDDM v1.1)
-ATI Technologies Inc. ATI Radeon HD 4810 series
-ATI Technologies Inc. ATI Radeon HD 4830
-ATI Technologies Inc. ATI Radeon HD 4850
-ATI Technologies Inc. ATI Radeon HD 4850 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 4850 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 4850 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 4850 PRO OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 4850 Series
-ATI Technologies Inc. ATI Radeon HD 4850 X2
-ATI Technologies Inc. ATI Radeon HD 4870
-ATI Technologies Inc. ATI Radeon HD 4870 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 4870 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 4870 Series
-ATI Technologies Inc. ATI Radeon HD 4870 X2
-ATI Technologies Inc. ATI Radeon HD 5400 Series
-ATI Technologies Inc. ATI Radeon HD 5400 Series
-ATI Technologies Inc. ATI Radeon HD 5450
-ATI Technologies Inc. ATI Radeon HD 5450
-ATI Technologies Inc. ATI Radeon HD 5450
-ATI Technologies Inc. ATI Radeon HD 5450 (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. ATI Radeon HD 5470
-ATI Technologies Inc. ATI Radeon HD 5500
-ATI Technologies Inc. ATI Radeon HD 5500 Series
-ATI Technologies Inc. ATI Radeon HD 5500 Series
-ATI Technologies Inc. ATI Radeon HD 5530
-ATI Technologies Inc. ATI Radeon HD 5570
-ATI Technologies Inc. ATI Radeon HD 5570
-ATI Technologies Inc. ATI Radeon HD 5600 Series
-ATI Technologies Inc. ATI Radeon HD 5600 Series
-ATI Technologies Inc. ATI Radeon HD 5600/5700
-ATI Technologies Inc. ATI Radeon HD 5630
-ATI Technologies Inc. ATI Radeon HD 5670
-ATI Technologies Inc. ATI Radeon HD 5670
-ATI Technologies Inc. ATI Radeon HD 5670 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5670 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5670 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5700 Series
-ATI Technologies Inc. ATI Radeon HD 5700 Series
-ATI Technologies Inc. ATI Radeon HD 5700 Series (Microsoft Corporation - WDDM v1.2)
-ATI Technologies Inc. ATI Radeon HD 5700 Series (Microsoft Corporation - WDDM v1.20)
-ATI Technologies Inc. ATI Radeon HD 5750
-ATI Technologies Inc. ATI Radeon HD 5750 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5750 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5750 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5750 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5750 Series
-ATI Technologies Inc. ATI Radeon HD 5770
-ATI Technologies Inc. ATI Radeon HD 5770
-ATI Technologies Inc. ATI Radeon HD 5770 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5770 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5770 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5770 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5800 Series
-ATI Technologies Inc. ATI Radeon HD 5800 Series
-ATI Technologies Inc. ATI Radeon HD 5800 Series
-ATI Technologies Inc. ATI Radeon HD 5850
-ATI Technologies Inc. ATI Radeon HD 5850
-ATI Technologies Inc. ATI Radeon HD 5870
-ATI Technologies Inc. ATI Radeon HD 5870 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5870 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5870 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 5900 Series
-ATI Technologies Inc. ATI Radeon HD 5900 Series
-ATI Technologies Inc. ATI Radeon HD 5970
-ATI Technologies Inc. ATI Radeon HD 6230
-ATI Technologies Inc. ATI Radeon HD 6230
-ATI Technologies Inc. ATI Radeon HD 6290
-ATI Technologies Inc. ATI Radeon HD 6350
-ATI Technologies Inc. ATI Radeon HD 6390
-ATI Technologies Inc. ATI Radeon HD 6490
-ATI Technologies Inc. ATI Radeon HD 6490M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6490M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6490M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6510
-ATI Technologies Inc. ATI Radeon HD 6510
-ATI Technologies Inc. ATI Radeon HD 6570M
-ATI Technologies Inc. ATI Radeon HD 6630M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6630M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6630M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6750M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6750M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6750M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6770
-ATI Technologies Inc. ATI Radeon HD 6770
-ATI Technologies Inc. ATI Radeon HD 6770M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6770M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6770M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6970M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6970M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 6970M OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 7350
-ATI Technologies Inc. ATI Radeon HD 7350
-ATI Technologies Inc. ATI Radeon HD 7950 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 7950 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD 7950 OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD Pitcairn XT Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD Tahiti XT Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD Tahiti XT Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD Verde XT Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon HD3750
-ATI Technologies Inc. ATI Radeon HD4300/HD4500 series
-ATI Technologies Inc. ATI Radeon HD4300/HD4500 series
-ATI Technologies Inc. ATI Radeon HD4650
-ATI Technologies Inc. ATI Radeon HD4670
-ATI Technologies Inc. ATI Radeon HD4670
-ATI Technologies Inc. ATI Radeon RV730 Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon RV790 Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon RV790 Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon RV790 Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Redwood XT Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Turks PRO Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Turks XT Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon Turks XT Prototype OpenGL Engine
-ATI Technologies Inc. ATI Radeon X1050
-ATI Technologies Inc. ATI Radeon X1050 Series
-ATI Technologies Inc. ATI Radeon X1050 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon X1050 x86/SSE2
-ATI Technologies Inc. ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1200
-ATI Technologies Inc. ATI Radeon X1200 Series
-ATI Technologies Inc. ATI Radeon X1200 Series
-ATI Technologies Inc. ATI Radeon X1200 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. ATI Radeon X1200 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon X1200 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon X1250
-ATI Technologies Inc. ATI Radeon X1250
-ATI Technologies Inc. ATI Radeon X1250
-ATI Technologies Inc. ATI Radeon X1250 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon X1270
-ATI Technologies Inc. ATI Radeon X1270 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon X1300 / X1550 Series
-ATI Technologies Inc. ATI Radeon X1300/X1550 Series
-ATI Technologies Inc. ATI Radeon X1550
-ATI Technologies Inc. ATI Radeon X1550 Series
-ATI Technologies Inc. ATI Radeon X1550 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon X1550 Series x86/SSE2
-ATI Technologies Inc. ATI Radeon X1550 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon X1550 x86/SSE2
-ATI Technologies Inc. ATI Radeon X1600 OpenGL Engine
-ATI Technologies Inc. ATI Radeon X1600 OpenGL Engine
-ATI Technologies Inc. ATI Radeon X1600 OpenGL Engine
-ATI Technologies Inc. ATI Radeon X1900 OpenGL Engine
-ATI Technologies Inc. ATI Radeon X1950 GT
-ATI Technologies Inc. ATI Radeon X1950 GT x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon X1950 GT x86/SSE2
-ATI Technologies Inc. ATI Radeon X300/X550/X1050 Series
-ATI Technologies Inc. ATI Radeon X300/X550/X1050 Series
-ATI Technologies Inc. ATI Radeon X600/X550/X1050 Series
-ATI Technologies Inc. ATI Radeon Xpress 1100
-ATI Technologies Inc. ATI Radeon Xpress 1100 x86/SSE2
-ATI Technologies Inc. ATI Radeon Xpress 1150
-ATI Technologies Inc. ATI Radeon Xpress 1150 Series
-ATI Technologies Inc. ATI Radeon Xpress 1150 Series
-ATI Technologies Inc. ATI Radeon Xpress 1150 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon Xpress 1200 Series
-ATI Technologies Inc. ATI Radeon Xpress 1200 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. ATI Radeon Xpress 1200 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon Xpress 1200 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon Xpress 1200 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon Xpress 1250
-ATI Technologies Inc. ATI Radeon Xpress 1250 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon Xpress 1250 x86/SSE2
-ATI Technologies Inc. ATI Radeon Xpress 1270 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ATI Radeon Xpress Series
-ATI Technologies Inc. ATI Radeon Xpress Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. All-in-Wonder 2006 PCI-E Edition
-ATI Technologies Inc. All-in-Wonder 2006 PCI-E Edition x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Diamond Radeon X1550
-ATI Technologies Inc. Diamond Radeon X1550 Series
-ATI Technologies Inc. Diamond Radeon X1550 Series x86/SSE2
-ATI Technologies Inc. Diamond Radeon X1550 x86/SSE2
-ATI Technologies Inc. Diamond X1600 PRO 512MB PCI-E x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. FireGL V3100 Pentium 4 (SSE2)
-ATI Technologies Inc. FireGL V3200 Pentium 4 (SSE2)
-ATI Technologies Inc. FireGL X1-128
-ATI Technologies Inc. FireMV 2400 PCI DDR x86
-ATI Technologies Inc. FireMV 2400 PCI DDR x86/SSE2
-ATI Technologies Inc. FirePro M3900 Mobility Professional Graphics
-ATI Technologies Inc. GIGABYTE RADEON 9600 PRO
-ATI Technologies Inc. GIGABYTE Radeon X1300 Pro
-ATI Technologies Inc. GIGABYTE Radeon X1300 Series
-ATI Technologies Inc. GIGABYTE Radeon X1600 PRO
-ATI Technologies Inc. GeCube RADEON 9600XT
-ATI Technologies Inc. GeCube RADEON X550 x86/SSE2
-ATI Technologies Inc. GeCube RADEON X700 Series
-ATI Technologies Inc. GeCube Radeon X1550
-ATI Technologies Inc. GeCube Radeon X1550 Series
-ATI Technologies Inc. GeCube Radeon X1550 Series
-ATI Technologies Inc. GeForce 9600 GT x86/SSE2
-ATI Technologies Inc. GigaByte Radeon X1050
-ATI Technologies Inc. Gigabyte RADEON X300
-ATI Technologies Inc. Gigabyte RADEON X300
-ATI Technologies Inc. Gigabyte RADEON X300 SE
-ATI Technologies Inc. Gigabyte RADEON X300 x86/SSE2
-ATI Technologies Inc. HD3730
-ATI Technologies Inc. HIGHTECH EXCALIBUR RADEON 9550SE Series
-ATI Technologies Inc. HIGHTECH EXCALIBUR RADEON 9550SE Series x86/SSE2
-ATI Technologies Inc. HIGHTECH RADEON 9600XT
-ATI Technologies Inc. HIS Radeon X1550 x86/SSE2
-ATI Technologies Inc. M52 x86
-ATI Technologies Inc. M72-M
-ATI Technologies Inc. MEDION RADEON 9600 TX
-ATI Technologies Inc. MEDION RADEON X740XL x86/SSE2
-ATI Technologies Inc. MOBILITY FIREGL T2 Pentium 4 (SSE2)
-ATI Technologies Inc. MOBILITY RADEON 7000 IGP DDR x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON 7500 DDR x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON 9000 DDR x86
-ATI Technologies Inc. MOBILITY RADEON 9000 DDR x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON 9000 IGPRADEON 9100 IGP DDR x86
-ATI Technologies Inc. MOBILITY RADEON 9000 IGPRADEON 9100 IGP DDR x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON 9000/9100 IGP Series DDR x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON 9000/9100 PRO IGP Series DDR x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON 9200 DDR x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON 9600 x86
-ATI Technologies Inc. MOBILITY RADEON 9600 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. MOBILITY RADEON 9600 x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON 9700 x86
-ATI Technologies Inc. MOBILITY RADEON 9700 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. MOBILITY RADEON 9700 x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON 9800 x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON X300 x86
-ATI Technologies Inc. MOBILITY RADEON X300 x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON X300 x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON X600 SE x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON X600 x86
-ATI Technologies Inc. MOBILITY RADEON X600 x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON X700 SE x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON X700 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. MOBILITY RADEON X700 x86/SSE2
-ATI Technologies Inc. MOBILITY RADEON Xpress 200 Series SW TCL x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. MOBILITY/RADEON 9000 DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. MOBILITY/RADEON 9000 DDR x86/SSE2
-ATI Technologies Inc. MOBILITY/RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. MOBILITY/RADEON 9250/9200 Series DDR x86/SSE2
-ATI Technologies Inc. MSI RX9550SE x86/MMX/3DNow!/SSE
-ATI Technologies Inc. MSI Radeon X1550
-ATI Technologies Inc. Mobility Radeon X2300 HD
-ATI Technologies Inc. Mobility Radeon X2300 HD x86/SSE2
-ATI Technologies Inc. RADEON 7000 DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 7000 DDR x86/SSE2
-ATI Technologies Inc. RADEON 7000 SDR x86
-ATI Technologies Inc. RADEON 7000 SW TCL x86/SSE2
-ATI Technologies Inc. RADEON 7200 DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 7200 DDR x86/SSE2
-ATI Technologies Inc. RADEON 7200 SDR x86/SSE2
-ATI Technologies Inc. RADEON 7500 DDR x86/SSE2
-ATI Technologies Inc. RADEON 8500 DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 8500 DDR x86/SSE2
-ATI Technologies Inc. RADEON 9000 DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9000 DDR x86/SSE2
-ATI Technologies Inc. RADEON 9000 PRO DDR x86/SSE2
-ATI Technologies Inc. RADEON 9000 XT IGPRADEON 9100 XT IGP DDR x86/SSE2
-ATI Technologies Inc. RADEON 9100 DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9100 DDR x86/SSE2
-ATI Technologies Inc. RADEON 9100 IGP DDR x86
-ATI Technologies Inc. RADEON 9100 IGP DDR x86/SSE2
-ATI Technologies Inc. RADEON 9200 DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9200 DDR x86/SSE2
-ATI Technologies Inc. RADEON 9200 LE DDR x86/SSE2
-ATI Technologies Inc. RADEON 9200 PRO DDR x86/SSE2
-ATI Technologies Inc. RADEON 9200 Series DDR x86
-ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!
-ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE2
-ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE2
-ATI Technologies Inc. RADEON 9200SE DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9200SE DDR x86/SSE2
-ATI Technologies Inc. RADEON 9200SE DDR x86/SSE2
-ATI Technologies Inc. RADEON 9250/9000 Series DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/SSE2
-ATI Technologies Inc. RADEON 9500
-ATI Technologies Inc. RADEON 9500 PRO / 9700
-ATI Technologies Inc. RADEON 9550
-ATI Technologies Inc. RADEON 9550 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9550 x86/SSE2
-ATI Technologies Inc. RADEON 9600 SERIES
-ATI Technologies Inc. RADEON 9600 TX
-ATI Technologies Inc. RADEON 9600 TX x86/SSE2
-ATI Technologies Inc. RADEON 9600 XT x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9600 XT x86/SSE2
-ATI Technologies Inc. RADEON 9600 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9600 x86/SSE2
-ATI Technologies Inc. RADEON 9600SE x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON 9600SE x86/SSE2
-ATI Technologies Inc. RADEON 9700 PRO
-ATI Technologies Inc. RADEON 9800 PRO
-ATI Technologies Inc. RADEON 9800 PRO (Microsoft Corporation - WDDM)
-ATI Technologies Inc. RADEON 9800 PRO - Secondary
-ATI Technologies Inc. RADEON 9800 Pro x86/SSE2
-ATI Technologies Inc. RADEON 9800 SERIES
-ATI Technologies Inc. RADEON 9800 XT
-ATI Technologies Inc. RADEON 9800 XT x86/SSE2
-ATI Technologies Inc. RADEON 9800 x86/SSE2
-ATI Technologies Inc. RADEON IGP 340M DDR x86/SSE2
-ATI Technologies Inc. RADEON Radeon X300/X550/X1050 Series x86/SSE2
-ATI Technologies Inc. RADEON X1600 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X1600 Series x86/SSE2
-ATI Technologies Inc. RADEON X300 SE 128MB HyperMemory x86/SSE2
-ATI Technologies Inc. RADEON X300 SE x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X300 Series
-ATI Technologies Inc. RADEON X300 Series x86/SSE2
-ATI Technologies Inc. RADEON X300 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X300 x86/SSE2
-ATI Technologies Inc. RADEON X300/X550 Series x86
-ATI Technologies Inc. RADEON X300/X550 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X300/X550 Series x86/SSE2
-ATI Technologies Inc. RADEON X300/X550 Series x86/SSE2
-ATI Technologies Inc. RADEON X550 x86/MMX/3DNow!
-ATI Technologies Inc. RADEON X550 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X550 x86/SSE2
-ATI Technologies Inc. RADEON X550XT
-ATI Technologies Inc. RADEON X600 256MB HyperMemory x86/SSE2
-ATI Technologies Inc. RADEON X600 PRO x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X600 PRO x86/SSE2
-ATI Technologies Inc. RADEON X600 SE x86/SSE2
-ATI Technologies Inc. RADEON X600 Series
-ATI Technologies Inc. RADEON X600 x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X600 x86/SSE2
-ATI Technologies Inc. RADEON X600/X550 Series
-ATI Technologies Inc. RADEON X600/X550 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. RADEON X600/X550 Series Secondary
-ATI Technologies Inc. RADEON X600/X550 Series x86/SSE2
-ATI Technologies Inc. RADEON X700 PRO x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X700 PRO x86/SSE2
-ATI Technologies Inc. RADEON X700 SE
-ATI Technologies Inc. RADEON X700 SE x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X700 SE x86/SSE2
-ATI Technologies Inc. RADEON X700 Series
-ATI Technologies Inc. RADEON X700 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X700 Series x86/SSE2
-ATI Technologies Inc. RADEON X700 x86/SSE2
-ATI Technologies Inc. RADEON X700/X550 Series x86/SSE2
-ATI Technologies Inc. RADEON X800 GT x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X800 GTO
-ATI Technologies Inc. RADEON X800 GTO x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X800 GTO x86/SSE2
-ATI Technologies Inc. RADEON X800 PRO/GTO
-ATI Technologies Inc. RADEON X800 SE x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X800 SE x86/SSE2
-ATI Technologies Inc. RADEON X800 Series
-ATI Technologies Inc. RADEON X800 Series
-ATI Technologies Inc. RADEON X800 XL x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON X800 XL x86/SSE2
-ATI Technologies Inc. RADEON X800 XT
-ATI Technologies Inc. RADEON X800 XT (Microsoft Corporation - WDDM)
-ATI Technologies Inc. RADEON X800 XT x86/SSE2
-ATI Technologies Inc. RADEON X800/X850 Series
-ATI Technologies Inc. RADEON X800GT
-ATI Technologies Inc. RADEON X850 Series
-ATI Technologies Inc. RADEON X850 XT Platinum Edition (Microsoft Corporation - WDDM)
-ATI Technologies Inc. RADEON X850 XT Platinum Edition x86/SSE2
-ATI Technologies Inc. RADEON X850 XT x86/SSE2
-ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86
-ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/MMX/3DNow!
-ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/SSE2
-ATI Technologies Inc. RADEON XPRESS 200 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON XPRESS 200 Series x86/SSE2
-ATI Technologies Inc. RADEON XPRESS 200M Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86
-ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/MMX/3DNow!
-ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/SSE2
-ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/SSE2
-ATI Technologies Inc. RADEON XPRESS 200M Series x86/MMX/3DNow!
-ATI Technologies Inc. RADEON XPRESS 200M Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON XPRESS 200M Series x86/SSE2
-ATI Technologies Inc. RADEON XPRESS Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON XPRESS Series x86/SSE2
-ATI Technologies Inc. RADEON Xpress 200 Series SW TCL x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. RADEON Xpress 200G Series SW TCL x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. ROBSON CE
-ATI Technologies Inc. ROBSON LE
-ATI Technologies Inc. RS780M
-ATI Technologies Inc. RS880
-ATI Technologies Inc. RS880
-ATI Technologies Inc. RV250 DDR x86/SSE2
-ATI Technologies Inc. Radeon X1300XT/X1600 Pro Series
-ATI Technologies Inc. Radeon X1300XT/X1600Pro/X1650 Series
-ATI Technologies Inc. Radeon X1300XT/X1600Pro/X1650 Series
-ATI Technologies Inc. Radeon (TM) HD 7670M
-ATI Technologies Inc. Radeon (TM) HD 7670M
-ATI Technologies Inc. Radeon (TM) HD 6370M
-ATI Technologies Inc. Radeon (TM) HD 6470M
-ATI Technologies Inc. Radeon (TM) HD 6470M
-ATI Technologies Inc. Radeon (TM) HD 6490M
-ATI Technologies Inc. Radeon (TM) HD 6490M
-ATI Technologies Inc. Radeon (TM) HD 6490M
-ATI Technologies Inc. Radeon (TM) HD 6630M
-ATI Technologies Inc. Radeon (TM) HD 6750M
-ATI Technologies Inc. Radeon (TM) HD 6750M
-ATI Technologies Inc. Radeon (TM) HD 6770M
-ATI Technologies Inc. Radeon (TM) HD 6770M
-ATI Technologies Inc. Radeon (TM) HD 6770M
-ATI Technologies Inc. Radeon (TM) HD 6850M
-ATI Technologies Inc. Radeon (TM) HD 6850M
-ATI Technologies Inc. Radeon (TM) HD 7450M
-ATI Technologies Inc. Radeon (TM) HD 7470M
-ATI Technologies Inc. Radeon (TM) HD 7670M
-ATI Technologies Inc. Radeon (TM) HD 7670M
-ATI Technologies Inc. Radeon (TM) HD 7670M
-ATI Technologies Inc. Radeon (TM) HD 7690M XT
-ATI Technologies Inc. Radeon (TM) HD 7690M XT
-ATI Technologies Inc. Radeon (TM) HD 7690M XT
-ATI Technologies Inc. Radeon (TM) HD 7750M
-ATI Technologies Inc. Radeon (TM) HD 7750M
-ATI Technologies Inc. Radeon (TM) HD 7850M
-ATI Technologies Inc. Radeon (TM) HD 7850M
-ATI Technologies Inc. Radeon (TM) HD 8750M
-ATI Technologies Inc. Radeon (TM) HD 8750M
-ATI Technologies Inc. Radeon 7000 DDR x86/SSE2
-ATI Technologies Inc. Radeon 7500 DDR x86
-ATI Technologies Inc. Radeon 7500 DDR x86/SSE2
-ATI Technologies Inc. Radeon 9100 DDR x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon 9200 DDR x86/SSE2
-ATI Technologies Inc. Radeon HD 2600 PRO (Omega 3.8.442)
-ATI Technologies Inc. Radeon HD 6470M
-ATI Technologies Inc. Radeon HD 6470M
-ATI Technologies Inc. Radeon HD 6490M
-ATI Technologies Inc. Radeon HD 6800 Series
-ATI Technologies Inc. Radeon HD 6800 Series
-ATI Technologies Inc. Radeon Radeon X300/X550/X1050 Series x86/SSE2
-ATI Technologies Inc. Radeon X1050
-ATI Technologies Inc. Radeon X1050 Series (Omega 3.8.442)
-ATI Technologies Inc. Radeon X1200 Series (Omega 3.8.442)
-ATI Technologies Inc. Radeon X1300 / X1550 Series
-ATI Technologies Inc. Radeon X1300 / X1550 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1300 / X1550 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1300 / X1600 Series
-ATI Technologies Inc. Radeon X1300 Series
-ATI Technologies Inc. Radeon X1300 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon X1300 Series x86/SSE2
-ATI Technologies Inc. Radeon X1300 Series x86/SSE2
-ATI Technologies Inc. Radeon X1300/X1550 Series
-ATI Technologies Inc. Radeon X1300/X1550 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1300/X1550 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1300/X1550 Series (Omega 3.8.442)
-ATI Technologies Inc. Radeon X1300/X1550 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon X1300/X1550 Series x86/SSE2
-ATI Technologies Inc. Radeon X1550 64-bit (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1550 64-bit x86/SSE2
-ATI Technologies Inc. Radeon X1550 Series
-ATI Technologies Inc. Radeon X1550 Series
-ATI Technologies Inc. Radeon X1550 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1550 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon X1550 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon X1550 Series x86/SSE2
-ATI Technologies Inc. Radeon X1600
-ATI Technologies Inc. Radeon X1600 Pro / X1300XT
-ATI Technologies Inc. Radeon X1600 Pro / X1300XT x86/SSE2
-ATI Technologies Inc. Radeon X1600 Series
-ATI Technologies Inc. Radeon X1600 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1600 Series (Omega 3.8.442)
-ATI Technologies Inc. Radeon X1600 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon X1600 Series x86/SSE2
-ATI Technologies Inc. Radeon X1600 x86/SSE2
-ATI Technologies Inc. Radeon X1600/1650 Series
-ATI Technologies Inc. Radeon X1600/X1650 Series
-ATI Technologies Inc. Radeon X1600/X1650 Series x86/SSE2
-ATI Technologies Inc. Radeon X1650 GTO
-ATI Technologies Inc. Radeon X1650 SE
-ATI Technologies Inc. Radeon X1650 SE x86/SSE2
-ATI Technologies Inc. Radeon X1650 Series
-ATI Technologies Inc. Radeon X1650 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1650 Series
-ATI Technologies Inc. Radeon X1650 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1650 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1650 Series (Omega 3.8.442)
-ATI Technologies Inc. Radeon X1650 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon X1650 Series x86/SSE2
-ATI Technologies Inc. Radeon X1650 Series x86/SSE2
-ATI Technologies Inc. Radeon X1650/X1700 Series (Omega 3.8.442)
-ATI Technologies Inc. Radeon X1700 FSC
-ATI Technologies Inc. Radeon X1800 CrossFire Edition
-ATI Technologies Inc. Radeon X1800 Series
-ATI Technologies Inc. Radeon X1800 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon X1900 CrossFire Edition
-ATI Technologies Inc. Radeon X1900 GT
-ATI Technologies Inc. Radeon X1900 GT x86/SSE2
-ATI Technologies Inc. Radeon X1900 Series
-ATI Technologies Inc. Radeon X1900 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1900 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon X1900 Series x86/SSE2
-ATI Technologies Inc. Radeon X1950 CrossFire Edition
-ATI Technologies Inc. Radeon X1950 Pro
-ATI Technologies Inc. Radeon X1950 Pro (Omega 3.8.442)
-ATI Technologies Inc. Radeon X1950 Pro x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon X1950 Pro x86/SSE2
-ATI Technologies Inc. Radeon X1950 Series
-ATI Technologies Inc. Radeon X1950 Series
-ATI Technologies Inc. Radeon X1950 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1950 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X1950 Series x86/MMX/3DNow!/SSE2
-ATI Technologies Inc. Radeon X1950 Series x86/SSE2
-ATI Technologies Inc. Radeon X300/X550/X1050 Series
-ATI Technologies Inc. Radeon X300/X550/X1050 Series
-ATI Technologies Inc. Radeon X300/X550/X1050 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X300/X550/X1050 Series (Microsoft Corporation - WDDM)
-ATI Technologies Inc. Radeon X300/X550/X1050 Series (Omega 3.8.442)
-ATI Technologies Inc. Radeon X300/X550/X1050 Series x86/SSE2
-ATI Technologies Inc. Radeon X550/X700 Series
-ATI Technologies Inc. Radeon X550XTX
-ATI Technologies Inc. Radeon Xpress 200 Series (Omega 3.8.442) x86/SSE2
-ATI Technologies Inc. Radeon Xpress 200M Series (Omega 3.8.442)
-ATI Technologies Inc. SAPPHIRE RADEON 9600 ATLANTIS
-ATI Technologies Inc. SAPPHIRE RADEON X300SE
-ATI Technologies Inc. SAPPHIRE Radeon X1550
-ATI Technologies Inc. SAPPHIRE Radeon X1550 Series
-ATI Technologies Inc. SAPPHIRE Radeon X1550 Series x86/SSE2
-ATI Technologies Inc. SUMO 9640
-ATI Technologies Inc. SUMO 964A
-ATI Technologies Inc. Sapphire RADEON X1600 PRO
-ATI Technologies Inc. Sapphire RADEON X1600 PRO x86/SSE2
-ATI Technologies Inc. Sapphire RADEON X1600 XT
-ATI Technologies Inc. Tul Corporation, RADEON X1300 Series
-ATI Technologies Inc. Tul Corporation, RADEON X300SE
-ATI Technologies Inc. VisionTek Radeon 4350
-ATI Technologies Inc. VisionTek Radeon 4350
-ATI Technologies Inc. VisionTek Radeon HD 2400 PCI
-ATI Technologies Inc. VisionTek Radeon HD 2600 XT AGP
-ATI Technologies Inc. VisionTek Radeon HD 5450
-ATI Technologies Inc. VisionTek Radeon HD2400 Pro AGP
-ATI Technologies Inc. VisionTek Radeon HD2400 Pro PCI
-ATI Technologies Inc. VisionTek Radeon X1300
-ATI Technologies Inc. VisionTek Radeon X1300 Series
-ATI Technologies Inc. VisionTek Radeon X1300 XGE
-ATI Technologies Inc. VisionTek Radeon X1550 Series
-ATI Technologies Inc. WRESTLER 9802
-ATI Technologies Inc. XFX Radeon HD 4570
-Advanced Micro Devices, Inc. Mesa DRI R600 (RS880 9712) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2
-Alex Mohr GL Hijacker!
-Brian Paul Mesa X11
-Gallium
-Humper
-Humper Chromium
-Humper Chromium
-Imagination Technologies 3D-Analyze v2.3 - http://www.tommti-systems.com
-Imagination Technologies PowerVR SGX545
-Imagination Technologies PowerVR SGX545
-Intel
-Intel 3D-Analyze v2.3 - http://www.tommti-systems.com
-Intel 4 Series Internal
-Intel 845G
-Intel 855GM
-Intel 865G
-Intel 915G
-Intel 915GM
-Intel 945G
-Intel 945GM
-Intel 950
-Intel 965
-Intel 965
-Intel 965
-Intel Bear Lake
-Intel Broadwater
-Intel Brookdale
-Intel Cantiga
-Intel Corporation Intel(R) Graphics Media Accelerator 3600 Series
-Intel Corporation Intel(R) Graphics Media Accelerator 3600 Series
-Intel Eaglelake
-Intel G33
-Intel G41
-Intel G45
-Intel Graphics Media HD
-Intel Graphics Media HD
-Intel HD Graphics
-Intel HD Graphics
-Intel HD Graphics
-Intel HD Graphics
-Intel HD Graphics 2000
-Intel HD Graphics 2000
-Intel HD Graphics 3000
-Intel HD Graphics 3000
-Intel HD Graphics 4000
-Intel HD Graphics 4000
-Intel Inc. Intel GMA 950 OpenGL Engine
-Intel Inc. Intel GMA 950 OpenGL Engine
-Intel Inc. Intel GMA X3100 OpenGL Engine
-Intel Inc. Intel GMA X3100 OpenGL Engine
-Intel Inc. Intel GMA X3100 OpenGL Engine
-Intel Inc. Intel HD Graphics 3000 OpenGL Engine
-Intel Inc. Intel HD Graphics 3000 OpenGL Engine
-Intel Inc. Intel HD Graphics 3000 OpenGL Engine
-Intel Inc. Intel HD Graphics 4000 OpenGL Engine
-Intel Inc. Intel HD Graphics 4000 OpenGL Engine
-Intel Inc. Intel HD Graphics 4000 OpenGL Engine
-Intel Inc. Intel HD Graphics 4000 OpenGL Engine
-Intel Inc. Intel HD Graphics 5000 OpenGL Engine
-Intel Inc. Intel HD Graphics 5000 OpenGL Engine
-Intel Inc. Intel HD Graphics 5000 OpenGL Engine
-Intel Inc. Intel HD Graphics OpenGL Engine
-Intel Intel 845G
-Intel Intel 845G
-Intel Intel 855GM
-Intel Intel 855GM
-Intel Intel 865G
-Intel Intel 865G
-Intel Intel 915G
-Intel Intel 915G
-Intel Intel 915GM
-Intel Intel 915GM
-Intel Intel 945G
-Intel Intel 945G
-Intel Intel 945GM
-Intel Intel 945GM
-Intel Intel 965/963 Graphics Media Accelerator
-Intel Intel 965/963 Graphics Media Accelerator
-Intel Intel Bear Lake B
-Intel Intel Bear Lake B
-Intel Intel Broadwater G
-Intel Intel Brookdale-G
-Intel Intel Cantiga
-Intel Intel Cantiga
-Intel Intel Eaglelake
-Intel Intel Eaglelake
-Intel Intel Grantsdale-G
-Intel Intel Grantsdale-G
-Intel Intel Iris Pro Graphics 5200
-Intel Intel Montara-GM
-Intel Intel Pineview Platform
-Intel Intel Pineview Platform
-Intel Intel Springdale-G
-Intel Intel(R) HD Graphics Family
-Intel Intel(R) 4 Series Internal Chipset
-Intel Intel(R) 4 Series Internal Chipset
-Intel Intel(R) B43 Express Chipset
-Intel Intel(R) B43 Express Chipset
-Intel Intel(R) G41 Express Chipset
-Intel Intel(R) G41 Express Chipset
-Intel Intel(R) G41 Express Chipset
-Intel Intel(R) G41 Express Chipset (Microsoft Corporation - WDDM 1.1)
-Intel Intel(R) G41 Express Chipset v2
-Intel Intel(R) G45/G43 Express Chipset
-Intel Intel(R) G45/G43 Express Chipset
-Intel Intel(R) G45/G43 Express Chipset
-Intel Intel(R) G45/G43/G41 Express Chipset
-Intel Intel(R) Graphics Media Accelerator HD
-Intel Intel(R) Graphics Media Accelerator HD
-Intel Intel(R) Graphics Media Accelerator HD
-Intel Intel(R) HD Graphics
-Intel Intel(R) HD Graphics
-Intel Intel(R) HD Graphics
-Intel Intel(R) HD Graphics 100
-Intel Intel(R) HD Graphics 2000
-Intel Intel(R) HD Graphics 2000
-Intel Intel(R) HD Graphics 2500
-Intel Intel(R) HD Graphics 2500
-Intel Intel(R) HD Graphics 3000
-Intel Intel(R) HD Graphics 3000
-Intel Intel(R) HD Graphics 3000
-Intel Intel(R) HD Graphics 4000
-Intel Intel(R) HD Graphics 4000
-Intel Intel(R) HD Graphics 4000
-Intel Intel(R) HD Graphics 4000
-Intel Intel(R) HD Graphics 4400
-Intel Intel(R) HD Graphics 4600
-Intel Intel(R) HD Graphics 4600
-Intel Intel(R) HD Graphics 5000
-Intel Intel(R) HD Graphics BR-1004-01Y1
-Intel Intel(R) HD Graphics Family
-Intel Intel(R) HD Graphics Family
-Intel Intel(R) HD Graphics P3000
-Intel Intel(R) HD Graphics P4000
-Intel Intel(R) Q45/Q43 Express Chipset
-Intel Intel(R) Q45/Q43 Express Chipset
-Intel Iris OpenGL Graphics Engine
-Intel Mobile 4 Series
-Intel Mobile Intel(R) 4 Series Express Chipset Family
-Intel Mobile Intel(R) 4 Series Express Chipset Family
-Intel Mobile Intel(R) 4 Series Express Chipset Family v2
-Intel Mobile Intel(R) 45 Express Chipset Family (Microsoft Corporation - WDDM 1.1)
-Intel Mobile Intel(R) HD Graphics
-Intel Mobile Intel(R) HD Graphics
-Intel Montara
-Intel Open Source Technology Center Mesa DRI Intel(R) 852GM/855GM x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) 915G
-Intel Open Source Technology Center Mesa DRI Intel(R) 915G x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) 915GM x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) 945G
-Intel Open Source Technology Center Mesa DRI Intel(R) 945G x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) 945GM
-Intel Open Source Technology Center Mesa DRI Intel(R) 945GM x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) 945GME x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) 965G x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) 965GM
-Intel Open Source Technology Center Mesa DRI Intel(R) 965GM x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) 965GME/GLE
-Intel Open Source Technology Center Mesa DRI Intel(R) 965Q
-Intel Open Source Technology Center Mesa DRI Intel(R) 965Q x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) G33 x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) G41 x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) G45/G43
-Intel Open Source Technology Center Mesa DRI Intel(R) G45/G43 x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) IGD
-Intel Open Source Technology Center Mesa DRI Intel(R) IGD x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) Ironlake Desktop x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) Ironlake Mobile
-Intel Open Source Technology Center Mesa DRI Intel(R) Ironlake Mobile x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) Ivybridge Desktop
-Intel Open Source Technology Center Mesa DRI Intel(R) Ivybridge Desktop x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) Ivybridge Mobile
-Intel Open Source Technology Center Mesa DRI Intel(R) Ivybridge Mobile x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) Q35
-Intel Open Source Technology Center Mesa DRI Intel(R) Q35 x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) Q45/Q43
-Intel Open Source Technology Center Mesa DRI Intel(R) Q45/Q43 x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) Sandybridge Desktop
-Intel Open Source Technology Center Mesa DRI Intel(R) Sandybridge Desktop x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) Sandybridge Mobile
-Intel Open Source Technology Center Mesa DRI Intel(R) Sandybridge Mobile x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Intel(R) Sandybridge Mobile x86/MMX/SSE2
-Intel Open Source Technology Center Mesa DRI Mobile Intel(R) GM45 Express Chipset
-Intel Open Source Technology Center Mesa DRI Mobile Intel(R) GM45 Express Chipset x86/MMX/SSE2
-Intel Pineview
-Intel Q45/Q43
-Intel Royal BNA Driver
-Intel Springdale
-Intel X3100
-Intel X3100
-Matrox Graphics Inc. Matrox ICD for M-Series
-Matrox Graphics Inc. Matrox G400
-Matrox Graphics Inc. Matrox ICD for Parhelia
-Mesa
-Mesa
-Mesa Project Software Rasterizer
-Mesa project: www.mesa3d.org Mesa GLX Indirect
-NVIDIA 205
-NVIDIA 210
-NVIDIA 210
-NVIDIA 310
-NVIDIA 310
-NVIDIA 310
-NVIDIA 310M
-NVIDIA 310M
-NVIDIA 315
-NVIDIA 315M
-NVIDIA 315M
-NVIDIA 320M
-NVIDIA 320M
-NVIDIA 405
-NVIDIA 410
-NVIDIA 510
-NVIDIA 610M
-NVIDIA Corporation /PCI/SSE2
-NVIDIA Corporation 3D-Analyze v2.3 - http://www.tommti-systems.com
-NVIDIA Corporation C51/PCI/SSE2/3DNOW!
-NVIDIA Corporation C51G/PCI/SSE2/3DNOW!
-NVIDIA Corporation D10P1-25/PCI/SSE2/3DNOW!
-NVIDIA Corporation D14P1-30/PCIe/SSE2
-NVIDIA Corporation D9M-20/PCI/SSE2
-NVIDIA Corporation D9M-20/PCI/SSE2/3DNOW!
-NVIDIA Corporation G72/PCI/SSE2/3DNOW!
-NVIDIA Corporation G73/AGP/SSE2/3DNOW!
-NVIDIA Corporation G73/PCI/SSE2/3DNOW!
-NVIDIA Corporation G84-50/PCI/SSE2
-NVIDIA Corporation G92-100/PCI/SSE2/3DNOW!
-NVIDIA Corporation GK106/PCIe/SSE2
-NVIDIA Corporation GRID K2/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 555/PCI/SSE2
-NVIDIA Corporation GeForce GTX 555/PCI/SSE2
-NVIDIA Corporation GeForce GTX 555/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 555/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 555/PCIe/SSE2
-NVIDIA Corporation GeForce 205/PCI/SSE2
-NVIDIA Corporation GeForce 210/PCI/SSE2
-NVIDIA Corporation GeForce 210/PCI/SSE2
-NVIDIA Corporation GeForce 210/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 210/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 210/PCIe/SSE2
-NVIDIA Corporation GeForce 210/PCIe/SSE2
-NVIDIA Corporation GeForce 210/PCIe/SSE2
-NVIDIA Corporation GeForce 210/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 210/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 310/PCI/SSE2
-NVIDIA Corporation GeForce 310/PCI/SSE2
-NVIDIA Corporation GeForce 310/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 310/PCIe/SSE2
-NVIDIA Corporation GeForce 310/PCIe/SSE2
-NVIDIA Corporation GeForce 310/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 310M/PCI/SSE2
-NVIDIA Corporation GeForce 310M/PCI/SSE2
-NVIDIA Corporation GeForce 310M/PCIe/SSE2
-NVIDIA Corporation GeForce 310M/PCIe/SSE2
-NVIDIA Corporation GeForce 310M/PCIe/SSE2
-NVIDIA Corporation GeForce 315/PCI/SSE2
-NVIDIA Corporation GeForce 315/PCI/SSE2
-NVIDIA Corporation GeForce 315/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 315/PCIe/SSE2
-NVIDIA Corporation GeForce 315/PCIe/SSE2
-NVIDIA Corporation GeForce 315/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 315M/PCI/SSE2
-NVIDIA Corporation GeForce 315M/PCI/SSE2
-NVIDIA Corporation GeForce 315M/PCI/SSE2
-NVIDIA Corporation GeForce 315M/PCIe/SSE2
-NVIDIA Corporation GeForce 315M/PCIe/SSE2
-NVIDIA Corporation GeForce 320M/PCI/SSE2
-NVIDIA Corporation GeForce 320M/PCI/SSE2
-NVIDIA Corporation GeForce 320M/integrated/SSE2
-NVIDIA Corporation GeForce 405/PCI/SSE2
-NVIDIA Corporation GeForce 405/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 405/PCIe/SSE2
-NVIDIA Corporation GeForce 405/PCIe/SSE2
-NVIDIA Corporation GeForce 405/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 410M/PCI/SSE2
-NVIDIA Corporation GeForce 410M/PCI/SSE2
-NVIDIA Corporation GeForce 410M/PCIe/SSE2
-NVIDIA Corporation GeForce 410M/PCIe/SSE2
-NVIDIA Corporation GeForce 505/PCIe/SSE2
-NVIDIA Corporation GeForce 510/PCI/SSE2
-NVIDIA Corporation GeForce 510/PCI/SSE2
-NVIDIA Corporation GeForce 510/PCIe/SSE2
-NVIDIA Corporation GeForce 510/PCIe/SSE2
-NVIDIA Corporation GeForce 510/PCIe/SSE2
-NVIDIA Corporation GeForce 605/PCI/SSE2
-NVIDIA Corporation GeForce 605/PCIe/SSE2
-NVIDIA Corporation GeForce 605/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 610/PCIe/SSE2
-NVIDIA Corporation GeForce 6100 nForce 400/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100 nForce 400/integrated/SSE2
-NVIDIA Corporation GeForce 6100 nForce 400/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100 nForce 405/PCI/SSE2
-NVIDIA Corporation GeForce 6100 nForce 405/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100 nForce 405/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100 nForce 405/integrated/SSE2
-NVIDIA Corporation GeForce 6100 nForce 405/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100 nForce 405/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100 nForce 420/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100 nForce 430/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100 nForce 430/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100/PCI/SSE2
-NVIDIA Corporation GeForce 6100/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6100/integrated/SSE2
-NVIDIA Corporation GeForce 6100/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 610M/PCI/SSE2
-NVIDIA Corporation GeForce 610M/PCIe/SSE2
-NVIDIA Corporation GeForce 610M/PCIe/SSE2
-NVIDIA Corporation GeForce 610M/PCIe/SSE2
-NVIDIA Corporation GeForce 615/PCIe/SSE2
-NVIDIA Corporation GeForce 6150 LE/PCI/SSE2
-NVIDIA Corporation GeForce 6150 LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150 LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150 LE/integrated/SSE2
-NVIDIA Corporation GeForce 6150 LE/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150 LE/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150 SE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150/integrated/SSE2
-NVIDIA Corporation GeForce 6150/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150SE nForce 430/PCI/SSE2
-NVIDIA Corporation GeForce 6150SE nForce 430/PCI/SSE2
-NVIDIA Corporation GeForce 6150SE nForce 430/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150SE nForce 430/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150SE nForce 430/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150SE nForce 430/integrated/SSE2
-NVIDIA Corporation GeForce 6150SE nForce 430/integrated/SSE2
-NVIDIA Corporation GeForce 6150SE nForce 430/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150SE nForce 430/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6150SE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200 A-LE/AGP/SSE2
-NVIDIA Corporation GeForce 6200 A-LE/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200 A-LE/PCI/SSE2
-NVIDIA Corporation GeForce 6200 A-LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200 LE/PCI/SSE2
-NVIDIA Corporation GeForce 6200 LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200 LE/PCIe/SSE2
-NVIDIA Corporation GeForce 6200 LE/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200 TurboCache(TM)/PCI/SSE2
-NVIDIA Corporation GeForce 6200 TurboCache(TM)/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200 TurboCache(TM)/PCIe/SSE2
-NVIDIA Corporation GeForce 6200 TurboCache(TM)/PCIe/SSE2
-NVIDIA Corporation GeForce 6200 TurboCache(TM)/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200/AGP/SSE2
-NVIDIA Corporation GeForce 6200/AGP/SSE2
-NVIDIA Corporation GeForce 6200/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200/PCI/SSE2
-NVIDIA Corporation GeForce 6200/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200/PCIe/SSE2
-NVIDIA Corporation GeForce 6200/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200SE TurboCache(TM)/PCI/SSE2
-NVIDIA Corporation GeForce 6200SE TurboCache(TM)/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6200SE TurboCache(TM)/PCIe/SSE2
-NVIDIA Corporation GeForce 6200SE TurboCache(TM)/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6500/PCI/SSE2
-NVIDIA Corporation GeForce 6500/PCI/SSE2
-NVIDIA Corporation GeForce 6500/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6500/PCIe/SSE2
-NVIDIA Corporation GeForce 6500/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6600 GT/AGP/SSE2
-NVIDIA Corporation GeForce 6600 GT/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6600 GT/PCI/SSE2
-NVIDIA Corporation GeForce 6600 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6600 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 6600 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 6600 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6600 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6600 LE/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6600 LE/PCI/SSE2
-NVIDIA Corporation GeForce 6600 LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6600 LE/PCIe/SSE2
-NVIDIA Corporation GeForce 6600 LE/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6600/AGP/SSE2
-NVIDIA Corporation GeForce 6600/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6600/PCI/SSE2
-NVIDIA Corporation GeForce 6600/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6600/PCIe/SSE2
-NVIDIA Corporation GeForce 6600/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6610 XL/PCI/SSE2
-NVIDIA Corporation GeForce 6610 XL/PCIe/SSE2
-NVIDIA Corporation GeForce 6700 XL/PCI/SSE2
-NVIDIA Corporation GeForce 6700 XL/PCIe/SSE2
-NVIDIA Corporation GeForce 6800 GS/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800 GS/PCI/SSE2
-NVIDIA Corporation GeForce 6800 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 6800 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800 GT/AGP/SSE2
-NVIDIA Corporation GeForce 6800 GT/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 6800 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800 LE/AGP/SSE2
-NVIDIA Corporation GeForce 6800 LE/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800 LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800 Ultra/AGP/SSE2
-NVIDIA Corporation GeForce 6800 Ultra/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800 Ultra/PCI/SSE2
-NVIDIA Corporation GeForce 6800 Ultra/PCIe/SSE2
-NVIDIA Corporation GeForce 6800 Ultra/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800 XT/AGP/SSE2
-NVIDIA Corporation GeForce 6800 XT/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800 XT/PCI/SSE2
-NVIDIA Corporation GeForce 6800 XT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800 XT/PCIe/SSE2
-NVIDIA Corporation GeForce 6800 XT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800/AGP/SSE2
-NVIDIA Corporation GeForce 6800/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 6800/PCI/SSE2
-NVIDIA Corporation GeForce 6800/PCIe/SSE2
-NVIDIA Corporation GeForce 6800/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7000M / nForce 610M/PCI/SSE2
-NVIDIA Corporation GeForce 7000M / nForce 610M/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7000M / nForce 610M/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7000M / nForce 610M/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7025 / NVIDIA nForce 630a/PCI/SSE2
-NVIDIA Corporation GeForce 7025 / NVIDIA nForce 630a/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7025 / NVIDIA nForce 630a/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7025 / nForce 630a/PCI/SSE2
-NVIDIA Corporation GeForce 7025 / nForce 630a/PCI/SSE2
-NVIDIA Corporation GeForce 7025 / nForce 630a/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7025 / nForce 630a/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7025 / nForce 630a/integrated/SSE2
-NVIDIA Corporation GeForce 7025 / nForce 630a/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7025 / nForce 630a/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7050 / NVIDIA nForce 610i/PCI/SSE2
-NVIDIA Corporation GeForce 7050 / NVIDIA nForce 620i/PCI/SSE2
-NVIDIA Corporation GeForce 7050 / NVIDIA nForce 630i/PCI/SSE2
-NVIDIA Corporation GeForce 7050 / nForce 610i/PCI/SSE2
-NVIDIA Corporation GeForce 7050 / nForce 610i/integrated/SSE2
-NVIDIA Corporation GeForce 7050 / nForce 610i/integrated/SSE2
-NVIDIA Corporation GeForce 7050 / nForce 620i/PCI/SSE2
-NVIDIA Corporation GeForce 7050 / nForce 620i/PCI/SSE2
-NVIDIA Corporation GeForce 7050 / nForce 620i/integrated/SSE2
-NVIDIA Corporation GeForce 7050 / nForce 620i/integrated/SSE2
-NVIDIA Corporation GeForce 7050 / nForce 630i/PCI/SSE2
-NVIDIA Corporation GeForce 7050 / nForce 630i/integrated/SSE2
-NVIDIA Corporation GeForce 7050 PV / NVIDIA nForce 630a/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7050 PV / nForce 630a/PCI/SSE2
-NVIDIA Corporation GeForce 7050 PV / nForce 630a/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7050 PV / nForce 630a/integrated/SSE2
-NVIDIA Corporation GeForce 7050 PV / nForce 630a/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7050 PV / nForce 630a/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7100 / NVIDIA nForce 620i/PCI/SSE2
-NVIDIA Corporation GeForce 7100 / NVIDIA nForce 630i/PCI/SSE2
-NVIDIA Corporation GeForce 7100 / nForce 630i/PCI/SSE2
-NVIDIA Corporation GeForce 7100 / nForce 630i/PCI/SSE2
-NVIDIA Corporation GeForce 7100 / nForce 630i/integrated/SSE2
-NVIDIA Corporation GeForce 7100 / nForce 630i/integrated/SSE2
-NVIDIA Corporation GeForce 7100 GS/PCI/SSE2
-NVIDIA Corporation GeForce 7100 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7100 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 7100 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 7100 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 710A/PCIe/SSE2
-NVIDIA Corporation GeForce 710M/PCIe/SSE2
-NVIDIA Corporation GeForce 710M/PCIe/SSE2
-NVIDIA Corporation GeForce 710M/PCIe/SSE2
-NVIDIA Corporation GeForce 7150 / nForce 630i/PCI/SSE2
-NVIDIA Corporation GeForce 7150M / nForce 630M/PCI/SSE2
-NVIDIA Corporation GeForce 7150M / nForce 630M/PCI/SSE2
-NVIDIA Corporation GeForce 7150M / nForce 630M/PCI/SSE2
-NVIDIA Corporation GeForce 7150M / nForce 630M/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7150M / nForce 630M/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7150M / nForce 630M/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7150M / nForce 630M/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 GS/PCI/SSE2
-NVIDIA Corporation GeForce 7300 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 7300 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 7300 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 GT/AGP/SSE2
-NVIDIA Corporation GeForce 7300 GT/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 GT/PCI/SSE2
-NVIDIA Corporation GeForce 7300 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 7300 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 7300 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 LE/PCI/SSE2
-NVIDIA Corporation GeForce 7300 LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 LE/PCIe/SSE2
-NVIDIA Corporation GeForce 7300 LE/PCIe/SSE2
-NVIDIA Corporation GeForce 7300 LE/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCI/SSE2
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCI/SSE2
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 SE/7200 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 SE/PCI/SSE2
-NVIDIA Corporation GeForce 7300 SE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7300 SE/PCIe/SSE2
-NVIDIA Corporation GeForce 7350 LE/PCI/SSE2
-NVIDIA Corporation GeForce 7350 LE/PCIe/SSE2
-NVIDIA Corporation GeForce 7350 LE/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7500 LE/PCI/SSE2
-NVIDIA Corporation GeForce 7500 LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7500 LE/PCIe/SSE2
-NVIDIA Corporation GeForce 7500 LE/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7600 GS/AGP/SSE2
-NVIDIA Corporation GeForce 7600 GS/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7600 GS/PCI/SSE2
-NVIDIA Corporation GeForce 7600 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7600 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7600 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 7600 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7600 GT/AGP/SSE2
-NVIDIA Corporation GeForce 7600 GT/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7600 GT/PCI/SSE2
-NVIDIA Corporation GeForce 7600 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7600 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 7600 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 7600 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7600 LE/PCIe/SSE2
-NVIDIA Corporation GeForce 7650 GS/AGP/SSE2
-NVIDIA Corporation GeForce 7650 GS/PCI/SSE2
-NVIDIA Corporation GeForce 7650 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7650 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 7800 GS/AGP/SSE2
-NVIDIA Corporation GeForce 7800 GS/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7800 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7800 GT/PCI/SSE2
-NVIDIA Corporation GeForce 7800 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 7800 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7800 GTX/PCI/SSE2
-NVIDIA Corporation GeForce 7800 GTX/PCIe/SSE2
-NVIDIA Corporation GeForce 7800 GTX/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7900 GS/AGP/SSE2
-NVIDIA Corporation GeForce 7900 GS/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7900 GS/PCI/SSE2
-NVIDIA Corporation GeForce 7900 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7900 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 7900 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7900 GT/GTO/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7900 GT/GTO/PCIe/SSE2
-NVIDIA Corporation GeForce 7900 GT/GTO/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7900 GT/PCI/SSE2
-NVIDIA Corporation GeForce 7900 GTX/PCI/SSE2
-NVIDIA Corporation GeForce 7900 GTX/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7900 GTX/PCIe/SSE2
-NVIDIA Corporation GeForce 7900 GTX/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7950 GT/AGP/SSE2
-NVIDIA Corporation GeForce 7950 GT/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7950 GT/PCI/SSE2
-NVIDIA Corporation GeForce 7950 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7950 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 7950 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 7950 GX2/PCI/SSE2
-NVIDIA Corporation GeForce 7950 GX2/PCIe/SSE2
-NVIDIA Corporation GeForce 7950 GX2/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8100 / nForce 720a/PCI/SSE2
-NVIDIA Corporation GeForce 8100 / nForce 720a/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8100 / nForce 720a/integrated/SSE2
-NVIDIA Corporation GeForce 8100 / nForce 720a/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8200/PCI/SSE2
-NVIDIA Corporation GeForce 8200/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8200/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8200/integrated/SSE2
-NVIDIA Corporation GeForce 8200/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8200/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8200M G/PCI/SSE2
-NVIDIA Corporation GeForce 8200M G/PCI/SSE2
-NVIDIA Corporation GeForce 8200M G/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8200M G/integrated/SSE2
-NVIDIA Corporation GeForce 8200M G/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8200M/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8300 GS/PCI/SSE2
-NVIDIA Corporation GeForce 8300 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8300 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8300 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8300/PCI/SSE2
-NVIDIA Corporation GeForce 8300/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8300/integrated/SSE2
-NVIDIA Corporation GeForce 8300/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400 GS/PCI/SSE2
-NVIDIA Corporation GeForce 8400 GS/PCI/SSE2
-NVIDIA Corporation GeForce 8400 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8400 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8400 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400 SE/PCI/SSE2
-NVIDIA Corporation GeForce 8400 SE/PCIe/SSE2
-NVIDIA Corporation GeForce 8400/PCI/SSE2
-NVIDIA Corporation GeForce 8400/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400/PCIe/SSE2
-NVIDIA Corporation GeForce 8400/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400GS/PCI/SSE2
-NVIDIA Corporation GeForce 8400GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8400GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8400GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400M G/PCI/SSE2
-NVIDIA Corporation GeForce 8400M G/PCI/SSE2
-NVIDIA Corporation GeForce 8400M G/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400M G/PCIe/SSE2
-NVIDIA Corporation GeForce 8400M G/PCIe/SSE2
-NVIDIA Corporation GeForce 8400M G/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400M GS/PCI/SSE2
-NVIDIA Corporation GeForce 8400M GS/PCI/SSE2
-NVIDIA Corporation GeForce 8400M GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8400M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8400M GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400M GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8400M GT/PCI/SSE2
-NVIDIA Corporation GeForce 8400M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 8500 GT/PCI/SSE2
-NVIDIA Corporation GeForce 8500 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8500 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8500 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 8500 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8500 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600 GS/PCI/SSE2
-NVIDIA Corporation GeForce 8600 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8600 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600 GT/PCI/SSE2
-NVIDIA Corporation GeForce 8600 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 8600 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 8600 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600 GTS/PCI/SSE2
-NVIDIA Corporation GeForce 8600 GTS/PCI/SSE2
-NVIDIA Corporation GeForce 8600 GTS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600 GTS/PCIe/SSE2
-NVIDIA Corporation GeForce 8600 GTS/PCIe/SSE2
-NVIDIA Corporation GeForce 8600 GTS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600GS/PCI/SSE2
-NVIDIA Corporation GeForce 8600GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600M GS/PCI/SSE2
-NVIDIA Corporation GeForce 8600M GS/PCI/SSE2
-NVIDIA Corporation GeForce 8600M GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8600M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8600M GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600M GT/PCI/SSE2
-NVIDIA Corporation GeForce 8600M GT/PCI/SSE2
-NVIDIA Corporation GeForce 8600M GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8600M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 8600M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 8600M GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8700M GT/PCI/SSE2
-NVIDIA Corporation GeForce 8700M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 8700M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 8800 GS/PCI/SSE2
-NVIDIA Corporation GeForce 8800 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8800 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 8800 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800 GT/PCI/SSE2
-NVIDIA Corporation GeForce 8800 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 8800 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 8800 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800 GTS 512/PCI/SSE2
-NVIDIA Corporation GeForce 8800 GTS 512/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800 GTS 512/PCIe/SSE2
-NVIDIA Corporation GeForce 8800 GTS 512/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800 GTS/PCI/SSE2
-NVIDIA Corporation GeForce 8800 GTS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800 GTS/PCIe/SSE2
-NVIDIA Corporation GeForce 8800 GTS/PCIe/SSE2
-NVIDIA Corporation GeForce 8800 GTS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800 GTX/PCI/SSE2
-NVIDIA Corporation GeForce 8800 GTX/PCI/SSE2
-NVIDIA Corporation GeForce 8800 GTX/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800 GTX/PCIe/SSE2
-NVIDIA Corporation GeForce 8800 GTX/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800 Ultra/PCI/SSE2
-NVIDIA Corporation GeForce 8800 Ultra/PCIe/SSE2
-NVIDIA Corporation GeForce 8800 Ultra/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 8800M GTS/PCI/SSE2
-NVIDIA Corporation GeForce 8800M GTS/PCIe/SSE2
-NVIDIA Corporation GeForce 8800M GTX/PCI/SSE2
-NVIDIA Corporation GeForce 8800M GTX/PCIe/SSE2
-NVIDIA Corporation GeForce 9100/PCI/SSE2
-NVIDIA Corporation GeForce 9100/PCI/SSE2
-NVIDIA Corporation GeForce 9100/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9100/integrated/SSE2
-NVIDIA Corporation GeForce 9100/integrated/SSE2
-NVIDIA Corporation GeForce 9100/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9100M G/PCI/SSE2
-NVIDIA Corporation GeForce 9100M G/PCI/SSE2
-NVIDIA Corporation GeForce 9100M G/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9100M G/integrated/SSE2
-NVIDIA Corporation GeForce 9100M G/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9200/PCI/SSE2
-NVIDIA Corporation GeForce 9200/PCI/SSE2
-NVIDIA Corporation GeForce 9200/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9200/integrated/SSE2
-NVIDIA Corporation GeForce 9200/integrated/SSE2
-NVIDIA Corporation GeForce 9200/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9200/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9200M GE/PCI/SSE2
-NVIDIA Corporation GeForce 9200M GE/PCI/SSE2
-NVIDIA Corporation GeForce 9200M GE/PCIe/SSE2
-NVIDIA Corporation GeForce 9200M GS/PCI/SSE2
-NVIDIA Corporation GeForce 9200M GS/PCI/SSE2
-NVIDIA Corporation GeForce 9200M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9200M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9300 / nForce 730i/integrated/SSE2
-NVIDIA Corporation GeForce 9300 GE/PCI/SSE2
-NVIDIA Corporation GeForce 9300 GE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9300 GE/PCIe/SSE2
-NVIDIA Corporation GeForce 9300 GE/PCIe/SSE2
-NVIDIA Corporation GeForce 9300 GE/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9300 GS/PCI/SSE2
-NVIDIA Corporation GeForce 9300 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9300 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9300 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9300 SE/PCIe/SSE2
-NVIDIA Corporation GeForce 9300/PCI/SSE2
-NVIDIA Corporation GeForce 9300/integrated/SSE2
-NVIDIA Corporation GeForce 9300M G/PCI/SSE2
-NVIDIA Corporation GeForce 9300M G/PCI/SSE2
-NVIDIA Corporation GeForce 9300M G/PCI/SSE2
-NVIDIA Corporation GeForce 9300M G/PCIe/SSE2
-NVIDIA Corporation GeForce 9300M G/PCIe/SSE2
-NVIDIA Corporation GeForce 9300M G/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9300M GS/PCI/SSE2
-NVIDIA Corporation GeForce 9300M GS/PCI/SSE2
-NVIDIA Corporation GeForce 9300M GS/PCI/SSE2
-NVIDIA Corporation GeForce 9300M GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9300M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9300M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9300M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9400 GT/PCI/SSE2
-NVIDIA Corporation GeForce 9400 GT/PCI/SSE2
-NVIDIA Corporation GeForce 9400 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9400 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9400 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9400 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9400/PCI/SSE2
-NVIDIA Corporation GeForce 9400/integrated/SSE2
-NVIDIA Corporation GeForce 9400/integrated/SSE2
-NVIDIA Corporation GeForce 9400M G/PCI/SSE2
-NVIDIA Corporation GeForce 9400M G/PCI/SSE2
-NVIDIA Corporation GeForce 9400M G/integrated/SSE2
-NVIDIA Corporation GeForce 9400M/PCI/SSE2
-NVIDIA Corporation GeForce 9400M/integrated/SSE2
-NVIDIA Corporation GeForce 9500 GS/PCI/SSE2
-NVIDIA Corporation GeForce 9500 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9500 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9500 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9500 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9500 GT/PCI/SSE2
-NVIDIA Corporation GeForce 9500 GT/PCI/SSE2
-NVIDIA Corporation GeForce 9500 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9500 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9500 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9500 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9500 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9500 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9500 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9500 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9500M GS/PCI/SSE2
-NVIDIA Corporation GeForce 9500M GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9500M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9600 GS/PCI/SSE2
-NVIDIA Corporation GeForce 9600 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600 GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9600 GS/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600 GSO 512/PCI/SSE2
-NVIDIA Corporation GeForce 9600 GSO 512/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600 GSO 512/PCIe/SSE2
-NVIDIA Corporation GeForce 9600 GSO 512/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600 GSO/PCI/SSE2
-NVIDIA Corporation GeForce 9600 GSO/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600 GSO/PCIe/SSE2
-NVIDIA Corporation GeForce 9600 GSO/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600 GT/PCI/SSE2
-NVIDIA Corporation GeForce 9600 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9600 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9600 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9600 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600M GS/PCI/SSE2
-NVIDIA Corporation GeForce 9600M GS/PCI/SSE2
-NVIDIA Corporation GeForce 9600M GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9600M GT/PCI/SSE2
-NVIDIA Corporation GeForce 9600M GT/PCI/SSE2
-NVIDIA Corporation GeForce 9600M GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9600M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9600M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9600M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9600M GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9650M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9650M GT/PCI/SSE2
-NVIDIA Corporation GeForce 9650M GT/PCI/SSE2
-NVIDIA Corporation GeForce 9650M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9700M GT/PCI/SSE2
-NVIDIA Corporation GeForce 9700M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9700M GTS/PCI/SSE2
-NVIDIA Corporation GeForce 9700M GTS/PCI/SSE2
-NVIDIA Corporation GeForce 9700M GTS/PCIe/SSE2
-NVIDIA Corporation GeForce 9800 GT/PCI/SSE2
-NVIDIA Corporation GeForce 9800 GT/PCI/SSE2
-NVIDIA Corporation GeForce 9800 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9800 GT/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9800 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9800 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9800 GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9800 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9800 GT/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9800 GTX+/PCI/SSE2
-NVIDIA Corporation GeForce 9800 GTX+/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9800 GTX+/PCIe/SSE2
-NVIDIA Corporation GeForce 9800 GTX+/PCIe/SSE2
-NVIDIA Corporation GeForce 9800 GTX+/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9800 GTX/9800 GTX+/PCI/SSE2
-NVIDIA Corporation GeForce 9800 GTX/9800 GTX+/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9800 GTX/9800 GTX+/PCIe/SSE2
-NVIDIA Corporation GeForce 9800 GTX/9800 GTX+/PCIe/SSE2
-NVIDIA Corporation GeForce 9800 GTX/9800 GTX+/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce 9800 GTX/PCI/SSE2
-NVIDIA Corporation GeForce 9800 GTX/PCI/SSE2
-NVIDIA Corporation GeForce 9800 GX2/PCIe/SSE2
-NVIDIA Corporation GeForce 9800 S/PCI/SSE2
-NVIDIA Corporation GeForce 9800M GS/PCI/SSE2
-NVIDIA Corporation GeForce 9800M GS/PCIe/SSE2
-NVIDIA Corporation GeForce 9800M GT/PCI/SSE2
-NVIDIA Corporation GeForce 9800M GT/PCIe/SSE2
-NVIDIA Corporation GeForce 9800M GTS/PCI/SSE2
-NVIDIA Corporation GeForce 9800M GTS/PCIe/SSE2
-NVIDIA Corporation GeForce 9800M GTX/PCI/SSE2
-NVIDIA Corporation GeForce 9800M GTX/PCIe/SSE2
-NVIDIA Corporation GeForce FX 5100/AGP/SSE2
-NVIDIA Corporation GeForce FX 5200 Ultra/AGP/SSE2
-NVIDIA Corporation GeForce FX 5200 Ultra/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5200/AGP/SSE/3DNOW!
-NVIDIA Corporation GeForce FX 5200/AGP/SSE2
-NVIDIA Corporation GeForce FX 5200/AGP/SSE2
-NVIDIA Corporation GeForce FX 5200/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5200/PCI/SSE2
-NVIDIA Corporation GeForce FX 5200/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5200LE/AGP/SSE2
-NVIDIA Corporation GeForce FX 5200LE/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5200SE/AGP/SSE2
-NVIDIA Corporation GeForce FX 5500/AGP/SSE2
-NVIDIA Corporation GeForce FX 5500/AGP/SSE2
-NVIDIA Corporation GeForce FX 5500/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5500/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5500/PCI/SSE2
-NVIDIA Corporation GeForce FX 5500/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5600/AGP/SSE2
-NVIDIA Corporation GeForce FX 5600XT/AGP/SSE2
-NVIDIA Corporation GeForce FX 5600XT/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5600XT/PCI/SSE2
-NVIDIA Corporation GeForce FX 5700/AGP/SSE2
-NVIDIA Corporation GeForce FX 5700/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5700LE/AGP/SSE2
-NVIDIA Corporation GeForce FX 5700LE/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5700LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5700VE/AGP/SSE2
-NVIDIA Corporation GeForce FX 5700VE/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5900 Ultra/AGP/SSE2
-NVIDIA Corporation GeForce FX 5900/AGP/SSE2
-NVIDIA Corporation GeForce FX 5900XT/AGP/SSE2
-NVIDIA Corporation GeForce FX 5900ZT/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX 5950 Ultra/AGP/SSE2
-NVIDIA Corporation GeForce FX 5950 Ultra/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX Go5200 32M/64M/AGP/SSE2
-NVIDIA Corporation GeForce FX Go5200/AGP/SSE2
-NVIDIA Corporation GeForce FX Go5200/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce FX Go5200/PCI/SSE2
-NVIDIA Corporation GeForce FX Go5300/AGP/SSE2
-NVIDIA Corporation GeForce FX Go53xx Series/AGP/SSE2
-NVIDIA Corporation GeForce FX Go5600/AGP/SSE2
-NVIDIA Corporation GeForce FX Go5650/AGP/SSE2
-NVIDIA Corporation GeForce FX Go5700/AGP/SSE2
-NVIDIA Corporation GeForce FX Go5700/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce G 103M/PCI/SSE2
-NVIDIA Corporation GeForce G 103M/PCI/SSE2
-NVIDIA Corporation GeForce G 103M/PCIe/SSE2
-NVIDIA Corporation GeForce G 103M/PCIe/SSE2
-NVIDIA Corporation GeForce G 105M/PCI/SSE2
-NVIDIA Corporation GeForce G 105M/PCIe/SSE2
-NVIDIA Corporation GeForce G 105M/PCIe/SSE2
-NVIDIA Corporation GeForce G 110M/PCI/SSE2
-NVIDIA Corporation GeForce G100/PCI/SSE2
-NVIDIA Corporation GeForce G100/PCI/SSE2
-NVIDIA Corporation GeForce G100/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce G100/PCIe/SSE2
-NVIDIA Corporation GeForce G100/PCIe/SSE2
-NVIDIA Corporation GeForce G100/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce G100/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce G102M/PCI/SSE2
-NVIDIA Corporation GeForce G102M/PCI/SSE2
-NVIDIA Corporation GeForce G102M/integrated/SSE2
-NVIDIA Corporation GeForce G102M/integrated/SSE2
-NVIDIA Corporation GeForce G105M/PCI/SSE2
-NVIDIA Corporation GeForce G105M/PCI/SSE2
-NVIDIA Corporation GeForce G105M/PCIe/SSE2
-NVIDIA Corporation GeForce G105M/PCIe/SSE2
-NVIDIA Corporation GeForce G200/PCI/SSE2
-NVIDIA Corporation GeForce G200/PCI/SSE2
-NVIDIA Corporation GeForce G200/integrated/SSE2
-NVIDIA Corporation GeForce G205M/PCI/SSE2
-NVIDIA Corporation GeForce G205M/integrated/SSE2
-NVIDIA Corporation GeForce G205M/integrated/SSE2
-NVIDIA Corporation GeForce G210/PCI/SSE2
-NVIDIA Corporation GeForce G210/PCI/SSE2
-NVIDIA Corporation GeForce G210/PCI/SSE2
-NVIDIA Corporation GeForce G210/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce G210/PCIe/SSE2
-NVIDIA Corporation GeForce G210/PCIe/SSE2
-NVIDIA Corporation GeForce G210/PCIe/SSE2
-NVIDIA Corporation GeForce G210/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce G210M/PCI/SSE2
-NVIDIA Corporation GeForce G210M/PCI/SSE2
-NVIDIA Corporation GeForce G210M/PCIe/SSE2
-NVIDIA Corporation GeForce G210M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 120/PCI/SSE2
-NVIDIA Corporation GeForce GT 120/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 120/PCIe/SSE2
-NVIDIA Corporation GeForce GT 120/PCIe/SSE2
-NVIDIA Corporation GeForce GT 120/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 120M/PCI/SSE2
-NVIDIA Corporation GeForce GT 120M/PCI/SSE2
-NVIDIA Corporation GeForce GT 120M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 120M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 130/PCI/SSE2
-NVIDIA Corporation GeForce GT 130/PCIe/SSE2
-NVIDIA Corporation GeForce GT 130/PCIe/SSE2
-NVIDIA Corporation GeForce GT 130/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 130M/PCI/SSE2
-NVIDIA Corporation GeForce GT 130M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 130M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 140/PCI/SSE2
-NVIDIA Corporation GeForce GT 140/PCIe/SSE2
-NVIDIA Corporation GeForce GT 220/PCI/SSE2
-NVIDIA Corporation GeForce GT 220/PCI/SSE2
-NVIDIA Corporation GeForce GT 220/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 220/PCIe/SSE2
-NVIDIA Corporation GeForce GT 220/PCIe/SSE2
-NVIDIA Corporation GeForce GT 220/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 220/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 220M/PCI/SSE2
-NVIDIA Corporation GeForce GT 220M/PCI/SSE2
-NVIDIA Corporation GeForce GT 220M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 220M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 220M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 230/PCI/SSE2
-NVIDIA Corporation GeForce GT 230/PCIe/SSE2
-NVIDIA Corporation GeForce GT 230/PCIe/SSE2
-NVIDIA Corporation GeForce GT 230/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 230M/PCI/SSE2
-NVIDIA Corporation GeForce GT 230M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 230M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 230M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 240/PCI/SSE2
-NVIDIA Corporation GeForce GT 240/PCI/SSE2
-NVIDIA Corporation GeForce GT 240/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 240/PCIe/SSE2
-NVIDIA Corporation GeForce GT 240/PCIe/SSE2
-NVIDIA Corporation GeForce GT 240/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 240/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 240M LE/PCIe/SSE2
-NVIDIA Corporation GeForce GT 240M/PCI/SSE2
-NVIDIA Corporation GeForce GT 240M/PCI/SSE2
-NVIDIA Corporation GeForce GT 240M/PCI/SSE2
-NVIDIA Corporation GeForce GT 240M/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 240M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 240M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 240M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 320/PCI/SSE2
-NVIDIA Corporation GeForce GT 320/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 320/PCIe/SSE2
-NVIDIA Corporation GeForce GT 320/PCIe/SSE2
-NVIDIA Corporation GeForce GT 320/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 320M/PCI/SSE2
-NVIDIA Corporation GeForce GT 320M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 320M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 325M/PCI/SSE2
-NVIDIA Corporation GeForce GT 325M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 330/PCI/SSE2
-NVIDIA Corporation GeForce GT 330/PCIe/SSE2
-NVIDIA Corporation GeForce GT 330/PCIe/SSE2
-NVIDIA Corporation GeForce GT 330/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 330M/PCI/SSE2
-NVIDIA Corporation GeForce GT 330M/PCI/SSE2
-NVIDIA Corporation GeForce GT 330M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 330M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 335M/PCI/SSE2
-NVIDIA Corporation GeForce GT 335M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 335M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 335M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 340/PCI/SSE2
-NVIDIA Corporation GeForce GT 340/PCIe/SSE2
-NVIDIA Corporation GeForce GT 415/PCIe/SSE2
-NVIDIA Corporation GeForce GT 415/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 415M/PCI/SSE2
-NVIDIA Corporation GeForce GT 415M/PCI/SSE2
-NVIDIA Corporation GeForce GT 415M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 415M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 420/PCI/SSE2
-NVIDIA Corporation GeForce GT 420/PCI/SSE2
-NVIDIA Corporation GeForce GT 420/PCIe/SSE2
-NVIDIA Corporation GeForce GT 420/PCIe/SSE2
-NVIDIA Corporation GeForce GT 420/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 420M/PCI/SSE2
-NVIDIA Corporation GeForce GT 420M/PCI/SSE2
-NVIDIA Corporation GeForce GT 420M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 420M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 425M/PCI/SSE2
-NVIDIA Corporation GeForce GT 425M/PCI/SSE2
-NVIDIA Corporation GeForce GT 425M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 425M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 430/PCI/SSE2
-NVIDIA Corporation GeForce GT 430/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 430/PCIe/SSE2
-NVIDIA Corporation GeForce GT 430/PCIe/SSE2
-NVIDIA Corporation GeForce GT 430/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 430/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 435M/PCI/SSE2
-NVIDIA Corporation GeForce GT 435M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 435M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 440/PCI/SSE2
-NVIDIA Corporation GeForce GT 440/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 440/PCIe/SSE2
-NVIDIA Corporation GeForce GT 440/PCIe/SSE2
-NVIDIA Corporation GeForce GT 440/PCIe/SSE2
-NVIDIA Corporation GeForce GT 440/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 440/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 445M/PCI/SSE2
-NVIDIA Corporation GeForce GT 445M/PCI/SSE2
-NVIDIA Corporation GeForce GT 445M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 445M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 445M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 520/PCI/SSE2
-NVIDIA Corporation GeForce GT 520/PCI/SSE2
-NVIDIA Corporation GeForce GT 520/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 520/PCIe/SSE2
-NVIDIA Corporation GeForce GT 520/PCIe/SSE2
-NVIDIA Corporation GeForce GT 520/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 520/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 520M/PCI/SSE2
-NVIDIA Corporation GeForce GT 520M/PCI/SSE2
-NVIDIA Corporation GeForce GT 520M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 520M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 520MX/PCI/SSE2
-NVIDIA Corporation GeForce GT 520MX/PCI/SSE2
-NVIDIA Corporation GeForce GT 520MX/PCIe/SSE2
-NVIDIA Corporation GeForce GT 520MX/PCIe/SSE2
-NVIDIA Corporation GeForce GT 525M/PCI/SSE2
-NVIDIA Corporation GeForce GT 525M/PCI/SSE2
-NVIDIA Corporation GeForce GT 525M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 525M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 530/PCI/SSE2
-NVIDIA Corporation GeForce GT 530/PCI/SSE2
-NVIDIA Corporation GeForce GT 530/PCIe/SSE2
-NVIDIA Corporation GeForce GT 530/PCIe/SSE2
-NVIDIA Corporation GeForce GT 530/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 540M/PCI/SSE2
-NVIDIA Corporation GeForce GT 540M/PCI/SSE2
-NVIDIA Corporation GeForce GT 540M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 540M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 545/PCI/SSE2
-NVIDIA Corporation GeForce GT 545/PCIe/SSE2
-NVIDIA Corporation GeForce GT 545/PCIe/SSE2
-NVIDIA Corporation GeForce GT 545/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 550M/PCI/SSE2
-NVIDIA Corporation GeForce GT 550M/PCI/SSE2
-NVIDIA Corporation GeForce GT 550M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 550M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 555M/PCI/SSE2
-NVIDIA Corporation GeForce GT 555M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 555M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 610/PCIe/SSE2
-NVIDIA Corporation GeForce GT 610/PCIe/SSE2
-NVIDIA Corporation GeForce GT 610/PCIe/SSE2
-NVIDIA Corporation GeForce GT 610/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 610/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 620/PCI/SSE2
-NVIDIA Corporation GeForce GT 620/PCIe/SSE2
-NVIDIA Corporation GeForce GT 620/PCIe/SSE2
-NVIDIA Corporation GeForce GT 620/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 620/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 620M/PCI/SSE2
-NVIDIA Corporation GeForce GT 620M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 620M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 625/PCIe/SSE2
-NVIDIA Corporation GeForce GT 625M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 625M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 630/PCIe/SSE2
-NVIDIA Corporation GeForce GT 630/PCIe/SSE2
-NVIDIA Corporation GeForce GT 630/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 630/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 630M/PCI/SSE2
-NVIDIA Corporation GeForce GT 630M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 630M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 630M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 635M/PCI/SSE2
-NVIDIA Corporation GeForce GT 635M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 635M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 640/PCIe/SSE2
-NVIDIA Corporation GeForce GT 640/PCIe/SSE2
-NVIDIA Corporation GeForce GT 640/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 640/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GT 640M LE/PCI/SSE2
-NVIDIA Corporation GeForce GT 640M LE/PCIe/SSE2
-NVIDIA Corporation GeForce GT 640M LE/PCIe/SSE2
-NVIDIA Corporation GeForce GT 640M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 640M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 645/PCIe/SSE2
-NVIDIA Corporation GeForce GT 645/PCIe/SSE2
-NVIDIA Corporation GeForce GT 645M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 645M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 650M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 650M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 650M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 720M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 720M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 730M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 730M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 735M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 735M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 740M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 740M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 750M/PCIe/SSE2
-NVIDIA Corporation GeForce GT 750M/PCIe/SSE2
-NVIDIA Corporation GeForce GT620M/PCIe/SSE2
-NVIDIA Corporation GeForce GT625M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 150/PCI/SSE2
-NVIDIA Corporation GeForce GTS 160M/PCI/SSE2
-NVIDIA Corporation GeForce GTS 160M/PCI/SSE2
-NVIDIA Corporation GeForce GTS 160M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 160M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 240/PCI/SSE2
-NVIDIA Corporation GeForce GTS 240/PCI/SSE2
-NVIDIA Corporation GeForce GTS 240/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 240/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 240/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTS 250/PCI/SSE2
-NVIDIA Corporation GeForce GTS 250/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTS 250/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 250/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 250/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 250/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTS 250/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTS 250M/PCI/SSE2
-NVIDIA Corporation GeForce GTS 250M/PCI/SSE2
-NVIDIA Corporation GeForce GTS 250M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 250M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 350M/PCI/SSE2
-NVIDIA Corporation GeForce GTS 350M/PCI/SSE2
-NVIDIA Corporation GeForce GTS 350M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 350M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 360M/PCI/SSE2
-NVIDIA Corporation GeForce GTS 360M/PCI/SSE2
-NVIDIA Corporation GeForce GTS 360M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 360M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 360M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 360M/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 450/PCI/SSE2
-NVIDIA Corporation GeForce GTS 450/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTS 450/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 450/PCIe/SSE2
-NVIDIA Corporation GeForce GTS 450/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTS 450/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 260/PCI/SSE2
-NVIDIA Corporation GeForce GTX 260/PCI/SSE2
-NVIDIA Corporation GeForce GTX 260/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 260/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 260/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 260/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 260/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 260/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 260M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 260M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 260M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 260M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 260M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 275/PCI/SSE2
-NVIDIA Corporation GeForce GTX 275/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 275/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 275/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 275/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 275/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 280/PCI/SSE2
-NVIDIA Corporation GeForce GTX 280/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 280/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 280M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 280M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 280M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 280M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 285/PCI/SSE2
-NVIDIA Corporation GeForce GTX 285/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 285/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 285/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 285M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 285M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 285M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 285M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 295/PCI/SSE2
-NVIDIA Corporation GeForce GTX 295/PCI/SSE2
-NVIDIA Corporation GeForce GTX 295/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 295/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 295/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 295/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 295/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460 SE/PCI/SSE2
-NVIDIA Corporation GeForce GTX 460 SE/PCI/SSE2
-NVIDIA Corporation GeForce GTX 460 SE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460 SE/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460 SE/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460 SE/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460 SE/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460 SE/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460 SE/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460 v2/PCI/SSE2
-NVIDIA Corporation GeForce GTX 460 v2/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460 v2/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460 v2/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460 v2/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460 v2/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460/PCI/SSE2
-NVIDIA Corporation GeForce GTX 460/PCI/SSE2
-NVIDIA Corporation GeForce GTX 460/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 460M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 460M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 460M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 460M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 460M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 465/PCI/SSE2
-NVIDIA Corporation GeForce GTX 465/PCI/SSE2
-NVIDIA Corporation GeForce GTX 465/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 465/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 465/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 465/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 465/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 465/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 470/PCI/SSE2
-NVIDIA Corporation GeForce GTX 470/PCI/SSE2
-NVIDIA Corporation GeForce GTX 470/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 470/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 470/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 470/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 470/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 470/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 470/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 470M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 470M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 480/PCI/SSE2
-NVIDIA Corporation GeForce GTX 480/PCI/SSE2
-NVIDIA Corporation GeForce GTX 480/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 480/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 480/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 480/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 480/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 480/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 480M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 480M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 485M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 485M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 485M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 550 Ti/PCI/SSE2
-NVIDIA Corporation GeForce GTX 550 Ti/PCI/SSE2
-NVIDIA Corporation GeForce GTX 550 Ti/PCI/SSE2
-NVIDIA Corporation GeForce GTX 550 Ti/PCI/SSE2
-NVIDIA Corporation GeForce GTX 550 Ti/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 550 Ti/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 550 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 550 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 550 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 550 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 550 Ti/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 550 Ti/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 550 Ti/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 560 SE/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560 SE/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560 SE/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560 Ti/PCI/SSE2
-NVIDIA Corporation GeForce GTX 560 Ti/PCI/SSE2
-NVIDIA Corporation GeForce GTX 560 Ti/PCI/SSE2
-NVIDIA Corporation GeForce GTX 560 Ti/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 560 Ti/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 560 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560 Ti/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 560 Ti/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 560 Ti/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 560/PCI/SSE2
-NVIDIA Corporation GeForce GTX 560/PCI/SSE2
-NVIDIA Corporation GeForce GTX 560/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 560/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 560/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 560/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 560M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 560M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 560M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 560M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 560M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 570/PCI/SSE2
-NVIDIA Corporation GeForce GTX 570/PCI/SSE2
-NVIDIA Corporation GeForce GTX 570/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 570/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 570/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 570/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 570/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 570/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 570/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 570/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 570M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 570M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 570M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 570M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 580/PCI/SSE2
-NVIDIA Corporation GeForce GTX 580/PCI/SSE2
-NVIDIA Corporation GeForce GTX 580/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 580/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 580/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 580/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 580/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 580/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 580/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 580/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 580M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 580M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 580M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 580M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 590/PCI/SSE2
-NVIDIA Corporation GeForce GTX 590/PCI/SSE2
-NVIDIA Corporation GeForce GTX 590/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 590/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 590/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 590/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 645/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 645/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 650 Ti BOOST/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 650 Ti BOOST/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 650 Ti BOOST/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 650 Ti Boost/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 650 Ti Boost/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 650 Ti Boost/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 650 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 650 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 650 Ti/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 650 Ti/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 650/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 650/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 650/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 650/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 650/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 660 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660 Ti/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660 Ti/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 660 Ti/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 660/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 660/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 660/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 660M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 660M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 670/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 670/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 670/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 670/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 670/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 670/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 670/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 670M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 670M/PCI/SSE2
-NVIDIA Corporation GeForce GTX 670M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 670M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 670M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 670MX/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 670MX/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 670MX/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 675M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 675M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 675M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 675MX/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 675MX/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 675MX/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 680/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 680/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 680/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 680/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 680/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 680/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 680M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 680M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 680M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 680MX/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 680MX/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 690/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 690/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 690/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 760/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 760/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 760M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 760M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 765M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 765M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 770/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 770/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 770/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 770/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX 770M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 770M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 780/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 780/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 780/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 780M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX 780M/PCIe/SSE2
-NVIDIA Corporation GeForce GTX TITAN/PCIe/SSE2
-NVIDIA Corporation GeForce GTX TITAN/PCIe/SSE2
-NVIDIA Corporation GeForce GTX TITAN/PCIe/SSE2
-NVIDIA Corporation GeForce GTX TITAN/PCIe/SSE2
-NVIDIA Corporation GeForce GTX TITAN/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce GTX Titan/PCIe/SSE2
-NVIDIA Corporation GeForce GTX Titan/PCIe/SSE2
-NVIDIA Corporation GeForce Go 6100/PCI/SSE2
-NVIDIA Corporation GeForce Go 6100/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 6100/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 6150/PCI/SSE2
-NVIDIA Corporation GeForce Go 6150/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 6150/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 6150/integrated/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 6200/PCI/SSE2
-NVIDIA Corporation GeForce Go 6200/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 6400/PCI/SSE2
-NVIDIA Corporation GeForce Go 6400/PCIe/SSE2
-NVIDIA Corporation GeForce Go 6600 TE/6200 TE/PCI/SSE2
-NVIDIA Corporation GeForce Go 6600/PCI/SSE2
-NVIDIA Corporation GeForce Go 6800 Ultra/PCI/SSE2
-NVIDIA Corporation GeForce Go 6800/PCI/SSE2
-NVIDIA Corporation GeForce Go 6800/PCIe/SSE2
-NVIDIA Corporation GeForce Go 7200/PCI/SSE2
-NVIDIA Corporation GeForce Go 7200/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 7300/PCI/SSE2
-NVIDIA Corporation GeForce Go 7300/PCI/SSE2
-NVIDIA Corporation GeForce Go 7300/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 7300/PCIe/SSE2
-NVIDIA Corporation GeForce Go 7400/PCI/SSE2
-NVIDIA Corporation GeForce Go 7400/PCI/SSE2
-NVIDIA Corporation GeForce Go 7400/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 7400/PCIe/SSE2
-NVIDIA Corporation GeForce Go 7600 GT/PCI/SSE2
-NVIDIA Corporation GeForce Go 7600/PCI/SSE2
-NVIDIA Corporation GeForce Go 7600/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 7600/PCIe/SSE2
-NVIDIA Corporation GeForce Go 7600/PCIe/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 7700/PCI/SSE2
-NVIDIA Corporation GeForce Go 7800 GTX/PCI/SSE2
-NVIDIA Corporation GeForce Go 7800/PCI/SSE2
-NVIDIA Corporation GeForce Go 7800/PCI/SSE2
-NVIDIA Corporation GeForce Go 7900 GS/PCI/SSE2
-NVIDIA Corporation GeForce Go 7900 GS/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce Go 7900 GS/PCIe/SSE2
-NVIDIA Corporation GeForce Go 7900 GTX/PCI/SSE2
-NVIDIA Corporation GeForce Go 7950 GTX/PCI/SSE2
-NVIDIA Corporation GeForce Go 7950 GTX/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce PCX 5300/PCI/SSE2
-NVIDIA Corporation GeForce PCX 5750/PCI/SSE2
-NVIDIA Corporation GeForce2 GTS/AGP/SSE2
-NVIDIA Corporation GeForce2 MX/AGP/SSE2
-NVIDIA Corporation GeForce2 MX/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce2 MX/PCI/SSE2
-NVIDIA Corporation GeForce3/AGP/SSE2
-NVIDIA Corporation GeForce3/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce4 420 Go 32M/AGP/SSE2
-NVIDIA Corporation GeForce4 420 Go 32M/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce4 420 Go 32M/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce4 420 Go/AGP/SSE2
-NVIDIA Corporation GeForce4 4200 Go/AGP/SSE2
-NVIDIA Corporation GeForce4 440 Go 64M/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce4 440 Go 64M/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce4 440 Go/AGP/SSE2
-NVIDIA Corporation GeForce4 448 Go/AGP/SSE2
-NVIDIA Corporation GeForce4 MX 4000/AGP/SSE2
-NVIDIA Corporation GeForce4 MX 4000/AGP/SSE2
-NVIDIA Corporation GeForce4 MX 4000/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce4 MX 4000/PCI/SSE2
-NVIDIA Corporation GeForce4 MX 4000/PCI/SSE2/3DNOW!
-NVIDIA Corporation GeForce4 MX 420/AGP/SSE2
-NVIDIA Corporation GeForce4 MX 420/PCI/SSE2
-NVIDIA Corporation GeForce4 MX 440 with AGP8X/AGP/SSE2
-NVIDIA Corporation GeForce4 MX 440 with AGP8X/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce4 MX 440 with AGP8X/PCI/SSE2
-NVIDIA Corporation GeForce4 MX 440/440SE/AGP/SSE2
-NVIDIA Corporation GeForce4 MX 440/AGP/SSE2
-NVIDIA Corporation GeForce4 MX 440/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce4 MX 440/PCI/SSE2
-NVIDIA Corporation GeForce4 MX 440SE with AGP8X/AGP/SSE2
-NVIDIA Corporation GeForce4 MX 440SE with AGP8X/PCI/SSE2
-NVIDIA Corporation GeForce4 MX 460/AGP/SSE2
-NVIDIA Corporation GeForce4 MX 460/AGP/SSE2/3DNOW!
-NVIDIA Corporation GeForce4 Ti 4200 with AGP8X/AGP/SSE2
-NVIDIA Corporation GeForce4 Ti 4200 with AGP8X/PCI/SSE2
-NVIDIA Corporation GeForce4 Ti 4200/AGP/SSE2
-NVIDIA Corporation GeForce4 Ti 4400/AGP/SSE2
-NVIDIA Corporation GeForce4 Ti 4600/AGP/SSE2
-NVIDIA Corporation GeForce4 Ti 4600/PCI/SSE2
-NVIDIA Corporation ION LE/PCI/SSE2
-NVIDIA Corporation ION LE/integrated/SSE2
-NVIDIA Corporation ION LE/integrated/SSE2
-NVIDIA Corporation ION/PCI/SSE2
-NVIDIA Corporation ION/PCIe/SSE2
-NVIDIA Corporation ION/PCIe/SSE2
-NVIDIA Corporation ION/PCIe/SSE2/3DNOW!
-NVIDIA Corporation ION/integrated/SSE2
-NVIDIA Corporation ION/integrated/SSE2
-NVIDIA Corporation MCP61/PCI/SSE2/3DNOW!
-NVIDIA Corporation MCP7A-O/PCI/SSE2
-NVIDIA Corporation MCP7A-P/PCI/SSE2
-NVIDIA Corporation N10P-GV2/PCI/SSE2
-NVIDIA Corporation N11M-GE2/PCI/SSE2
-NVIDIA Corporation N11M-GE2/PCI/SSE2
-NVIDIA Corporation N12P-GVR-B-A1/PCI/SSE2
-NVIDIA Corporation N12P-GVR-B-A1/PCI/SSE2
-NVIDIA Corporation NB9M-GE1/PCI/SSE2
-NVIDIA Corporation NB9M-GS/PCI/SSE2
-NVIDIA Corporation NV17/AGP/SSE2
-NVIDIA Corporation NVIDIA GeForce 210 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 210 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 310M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 320M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 320M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 6600 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 7300 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 7600 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 7950 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 7950 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8400 GS OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8500 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8600 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8600 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8600 GTS OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8600M GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8600M GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8800 GS OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8800 GS OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8800 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8800 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8800 GTS 512 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8800 GTS OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8800 GTX OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 8800 Ultra OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9200M GS OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9400 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9400 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9400 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9400 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9400 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9400M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9400M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9500 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9500 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9600 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9600M GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9600M GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9800 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9800 GT OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9800 GTX+ OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce 9800 GTX+ OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 120 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 120 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 120 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 130 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 130 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 220 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 220 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 240 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 240 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 320M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 330M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 330M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 330M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 430 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 440 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 440 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 520 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 630 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 640 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 640 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 640M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 640M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 640M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 650M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 650M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GT 650M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTS 250 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTS 250 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTS 450 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 260 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 280 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 280 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 285 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 285 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 460 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 470 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 480 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 480 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 550 Ti OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 550 Ti OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 560 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 560 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 560 Ti OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 560 Ti OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 570 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 570 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 580 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 650 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 650 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 650 Ti OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 650 Ti OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 660 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 660 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 660 Ti OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 660 Ti OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 660 Ti OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 660M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 660M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 660M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 670 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 670 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 675MX OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 675MX OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 675MX OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 675MX OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 680 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 680 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 680 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 680MX OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 680MX OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 680MX OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 775M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce GTX 780M OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce Go 7600 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce Pre-Release D14P2-30 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce Pre-Release GK104 OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce Pre-Release ION OpenGL Engine
-NVIDIA Corporation NVIDIA GeForce Pre-Release Unknown OpenGL Engine
-NVIDIA Corporation NVIDIA NV34MAP OpenGL Engine
-NVIDIA Corporation NVIDIA Quadro 4000 OpenGL Engine
-NVIDIA Corporation NVIDIA Quadro 4000 OpenGL Engine
-NVIDIA Corporation NVIDIA Quadro FX 4500 OpenGL Engine
-NVIDIA Corporation NVIDIA Quadro FX 4500 OpenGL Engine
-NVIDIA Corporation NVIDIA Quadro FX 4800 OpenGL Engine
-NVIDIA Corporation NVIDIA Quadro FX 4800 OpenGL Engine
-NVIDIA Corporation NVIDIA Quadro FX 5600 OpenGL Engine
-NVIDIA Corporation NVIDIA Quadro FX 580 OpenGL Engine
-NVIDIA Corporation NVIDIA Quadro FX 770M OpenGL Engine
-NVIDIA Corporation NVS 2100M/PCI/SSE2
-NVIDIA Corporation NVS 2100M/PCIe/SSE2
-NVIDIA Corporation NVS 2100M/PCIe/SSE2
-NVIDIA Corporation NVS 300/PCI/SSE2
-NVIDIA Corporation NVS 300/PCI/SSE2/3DNOW!
-NVIDIA Corporation NVS 300/PCIe/SSE2
-NVIDIA Corporation NVS 310/PCIe/SSE2
-NVIDIA Corporation NVS 310/PCIe/SSE2
-NVIDIA Corporation NVS 3100M/PCI/SSE2
-NVIDIA Corporation NVS 3100M/PCI/SSE2
-NVIDIA Corporation NVS 3100M/PCIe/SSE2
-NVIDIA Corporation NVS 3100M/PCIe/SSE2
-NVIDIA Corporation NVS 315/PCIe/SSE2
-NVIDIA Corporation NVS 4200M/PCI/SSE2
-NVIDIA Corporation NVS 4200M/PCI/SSE2
-NVIDIA Corporation NVS 4200M/PCIe/SSE2
-NVIDIA Corporation NVS 4200M/PCIe/SSE2
-NVIDIA Corporation NVS 510/PCIe/SSE2
-NVIDIA Corporation NVS 510/PCIe/SSE2
-NVIDIA Corporation NVS 5100M/PCI/SSE2
-NVIDIA Corporation NVS 5100M/PCIe/SSE2
-NVIDIA Corporation NVS 5100M/PCIe/SSE2
-NVIDIA Corporation NVS 5200M/PCI/SSE2
-NVIDIA Corporation NVS 5200M/PCIe/SSE2
-NVIDIA Corporation NVS 5200M/PCIe/SSE2
-NVIDIA Corporation NVS 5400M/PCIe/SSE2
-NVIDIA Corporation NVS 5400M/PCIe/SSE2
-NVIDIA Corporation Quadro 1000M/PCI/SSE2
-NVIDIA Corporation Quadro 1000M/PCIe/SSE2
-NVIDIA Corporation Quadro 1000M/PCIe/SSE2
-NVIDIA Corporation Quadro 1100M/PCIe/SSE2
-NVIDIA Corporation Quadro 2000 D/PCI/SSE2
-NVIDIA Corporation Quadro 2000/PCI/SSE2
-NVIDIA Corporation Quadro 2000/PCIe/SSE2
-NVIDIA Corporation Quadro 2000/PCIe/SSE2
-NVIDIA Corporation Quadro 2000D/PCIe/SSE2
-NVIDIA Corporation Quadro 2000M/PCI/SSE2
-NVIDIA Corporation Quadro 2000M/PCIe/SSE2
-NVIDIA Corporation Quadro 3000M/PCI/SSE2
-NVIDIA Corporation Quadro 3000M/PCIe/SSE2
-NVIDIA Corporation Quadro 3000M/PCIe/SSE2
-NVIDIA Corporation Quadro 400/PCI/SSE2
-NVIDIA Corporation Quadro 400/PCI/SSE2
-NVIDIA Corporation Quadro 400/PCI/SSE2/3DNOW!
-NVIDIA Corporation Quadro 400/PCIe/SSE2
-NVIDIA Corporation Quadro 4000/PCI/SSE2
-NVIDIA Corporation Quadro 4000/PCIe/SSE2
-NVIDIA Corporation Quadro 4000/PCIe/SSE2
-NVIDIA Corporation Quadro 4000M/PCI/SSE2
-NVIDIA Corporation Quadro 4000M/PCI/SSE2
-NVIDIA Corporation Quadro 4000M/PCIe/SSE2
-NVIDIA Corporation Quadro 410/PCIe/SSE2
-NVIDIA Corporation Quadro 5000/PCI/SSE2
-NVIDIA Corporation Quadro 5000/PCIe/SSE2
-NVIDIA Corporation Quadro 5000M/PCI/SSE2
-NVIDIA Corporation Quadro 5000M/PCIe/SSE2
-NVIDIA Corporation Quadro 5010M/PCI/SSE2
-NVIDIA Corporation Quadro 5010M/PCIe/SSE2
-NVIDIA Corporation Quadro 5010M/PCIe/SSE2
-NVIDIA Corporation Quadro 600/PCI/SSE2
-NVIDIA Corporation Quadro 600/PCI/SSE2
-NVIDIA Corporation Quadro 600/PCIe/SSE2
-NVIDIA Corporation Quadro 600/PCIe/SSE2
-NVIDIA Corporation Quadro 600/PCIe/SSE2/3DNOW!
-NVIDIA Corporation Quadro 6000/PCIe/SSE2
-NVIDIA Corporation Quadro FX 1000/AGP/SSE2
-NVIDIA Corporation Quadro FX 1100/AGP/SSE2
-NVIDIA Corporation Quadro FX 1300/PCI/SSE2
-NVIDIA Corporation Quadro FX 1400/PCI/SSE2
-NVIDIA Corporation Quadro FX 1400/PCI/SSE2
-NVIDIA Corporation Quadro FX 1400/PCIe/SSE2
-NVIDIA Corporation Quadro FX 1400/PCIe/SSE2
-NVIDIA Corporation Quadro FX 1400/PCIe/SSE2/3DNOW!
-NVIDIA Corporation Quadro FX 1500/PCI/SSE2
-NVIDIA Corporation Quadro FX 1500/PCIe/SSE2
-NVIDIA Corporation Quadro FX 1500/PCIe/SSE2/3DNOW!
-NVIDIA Corporation Quadro FX 1500M/PCI/SSE2
-NVIDIA Corporation Quadro FX 1600M/PCI/SSE2
-NVIDIA Corporation Quadro FX 1600M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 1700/PCI/SSE2
-NVIDIA Corporation Quadro FX 1700/PCIe/SSE2
-NVIDIA Corporation Quadro FX 1700/PCIe/SSE2
-NVIDIA Corporation Quadro FX 1700/PCIe/SSE2/3DNOW!
-NVIDIA Corporation Quadro FX 1700M/PCI/SSE2
-NVIDIA Corporation Quadro FX 1700M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 1800/PCI/SSE2
-NVIDIA Corporation Quadro FX 1800/PCIe/SSE2
-NVIDIA Corporation Quadro FX 1800M/PCI/SSE2
-NVIDIA Corporation Quadro FX 1800M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 2000/AGP/SSE2
-NVIDIA Corporation Quadro FX 2500M/PCI/SSE2
-NVIDIA Corporation Quadro FX 2500M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 2700M/PCI/SSE2
-NVIDIA Corporation Quadro FX 2700M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 2800M/PCI/SSE2
-NVIDIA Corporation Quadro FX 2800M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 3000/AGP/SSE2
-NVIDIA Corporation Quadro FX 3400/PCI/SSE2
-NVIDIA Corporation Quadro FX 3400/PCI/SSE2
-NVIDIA Corporation Quadro FX 3450/4000 SDI/PCI/SSE2
-NVIDIA Corporation Quadro FX 3450/4000 SDI/PCI/SSE2
-NVIDIA Corporation Quadro FX 3450/4000 SDI/PCI/SSE2/3DNOW!
-NVIDIA Corporation Quadro FX 3450/4000 SDI/PCI/SSE2/3DNOW!
-NVIDIA Corporation Quadro FX 3450/4000 SDI/PCIe/SSE2
-NVIDIA Corporation Quadro FX 3450/4000 SDI/PCIe/SSE2
-NVIDIA Corporation Quadro FX 3500/PCI/SSE2
-NVIDIA Corporation Quadro FX 3500/PCIe/SSE2
-NVIDIA Corporation Quadro FX 3500M/PCI/SSE2
-NVIDIA Corporation Quadro FX 350M/PCI/SSE2
-NVIDIA Corporation Quadro FX 3600M/PCI/SSE2
-NVIDIA Corporation Quadro FX 3600M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 360M/PCI/SSE2
-NVIDIA Corporation Quadro FX 360M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 370 Low Profile/PCIe/SSE2
-NVIDIA Corporation Quadro FX 370/PCI/SSE2
-NVIDIA Corporation Quadro FX 370/PCIe/SSE2
-NVIDIA Corporation Quadro FX 370/PCIe/SSE2/3DNOW!
-NVIDIA Corporation Quadro FX 3700/PCI/SSE2
-NVIDIA Corporation Quadro FX 3700/PCIe/SSE2
-NVIDIA Corporation Quadro FX 3700M/PCI/SSE2
-NVIDIA Corporation Quadro FX 3700M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 370M/PCI/SSE2
-NVIDIA Corporation Quadro FX 370M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 380 LP/PCIe/SSE2
-NVIDIA Corporation Quadro FX 380 LP/PCIe/SSE2/3DNOW!
-NVIDIA Corporation Quadro FX 380/PCI/SSE2
-NVIDIA Corporation Quadro FX 380/PCIe/SSE2
-NVIDIA Corporation Quadro FX 3800/PCI/SSE2
-NVIDIA Corporation Quadro FX 3800/PCIe/SSE2
-NVIDIA Corporation Quadro FX 3800M/PCI/SSE2
-NVIDIA Corporation Quadro FX 3800M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 380M/PCI/SSE2
-NVIDIA Corporation Quadro FX 380M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 4500/PCI/SSE2
-NVIDIA Corporation Quadro FX 4500/PCIe/SSE2
-NVIDIA Corporation Quadro FX 4600/PCIe/SSE2
-NVIDIA Corporation Quadro FX 4800/PCI/SSE2
-NVIDIA Corporation Quadro FX 4800/PCIe/SSE2
-NVIDIA Corporation Quadro FX 500/AGP/SSE2
-NVIDIA Corporation Quadro FX 500/FX 600/AGP/SSE2
-NVIDIA Corporation Quadro FX 500/FX 600/AGP/SSE2/3DNOW!
-NVIDIA Corporation Quadro FX 500/FX 600/PCI/SSE2
-NVIDIA Corporation Quadro FX 540/PCI/SSE2
-NVIDIA Corporation Quadro FX 540/PCIe/SSE2
-NVIDIA Corporation Quadro FX 550/PCI/SSE2
-NVIDIA Corporation Quadro FX 550/PCIe/SSE2
-NVIDIA Corporation Quadro FX 5500/PCI/SSE2
-NVIDIA Corporation Quadro FX 560/PCI/SSE2
-NVIDIA Corporation Quadro FX 560/PCIe/SSE2
-NVIDIA Corporation Quadro FX 5600/PCIe/SSE2
-NVIDIA Corporation Quadro FX 570/PCI/SSE2
-NVIDIA Corporation Quadro FX 570/PCIe/SSE2
-NVIDIA Corporation Quadro FX 570M/PCI/SSE2
-NVIDIA Corporation Quadro FX 570M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 580/PCI/SSE2
-NVIDIA Corporation Quadro FX 580/PCIe/SSE2
-NVIDIA Corporation Quadro FX 5800/PCIe/SSE2
-NVIDIA Corporation Quadro FX 770M/PCI/SSE2
-NVIDIA Corporation Quadro FX 770M/PCIe/SSE2
-NVIDIA Corporation Quadro FX 880M/PCI/SSE2
-NVIDIA Corporation Quadro FX 880M/PCIe/SSE2
-NVIDIA Corporation Quadro FX Go1400/PCI/SSE2
-NVIDIA Corporation Quadro FX Go1400/PCI/SSE2
-NVIDIA Corporation Quadro FX Go1400/PCIe/SSE2
-NVIDIA Corporation Quadro FX Go700/AGP/SSE2
-NVIDIA Corporation Quadro K1000/PCIe/SSE2
-NVIDIA Corporation Quadro K1000M/PCIe/SSE2
-NVIDIA Corporation Quadro K2000/PCIe/SSE2
-NVIDIA Corporation Quadro K2000/PCIe/SSE2
-NVIDIA Corporation Quadro K2000D/PCIe/SSE2
-NVIDIA Corporation Quadro K2000M/PCIe/SSE2
-NVIDIA Corporation Quadro K2000M/PCIe/SSE2
-NVIDIA Corporation Quadro K3000M/PCIe/SSE2
-NVIDIA Corporation Quadro K4000/PCIe/SSE2
-NVIDIA Corporation Quadro K4000/PCIe/SSE2
-NVIDIA Corporation Quadro K4000/PCIe/SSE2
-NVIDIA Corporation Quadro K4000M/PCIe/SSE2
-NVIDIA Corporation Quadro K5000/PCIe/SSE2
-NVIDIA Corporation Quadro K5000M/PCIe/SSE2
-NVIDIA Corporation Quadro K600/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 110M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 110M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 130M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 130M/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 130M/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 135M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 135M/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 140M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 140M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 140M/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 150M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 150M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 150M/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 160M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 160M/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 210S / GeForce 6150LE/PCI/SSE2
-NVIDIA Corporation Quadro NVS 210S / GeForce 6150LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation Quadro NVS 210S / GeForce 6150LE/integrated/SSE2/3DNOW!
-NVIDIA Corporation Quadro NVS 210S / NVIDIA GeForce 6150LE/PCI/SSE2/3DNOW!
-NVIDIA Corporation Quadro NVS 210S/PCI/SSE2/3DNOW!
-NVIDIA Corporation Quadro NVS 280 PCI-E/PCI/SSE2
-NVIDIA Corporation Quadro NVS 280 SD/AGP/SSE2
-NVIDIA Corporation Quadro NVS 285/PCI/SSE2
-NVIDIA Corporation Quadro NVS 285/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 290/PCI/SSE2
-NVIDIA Corporation Quadro NVS 290/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 290/PCIe/SSE2/3DNOW!
-NVIDIA Corporation Quadro NVS 295/PCI/SSE2
-NVIDIA Corporation Quadro NVS 295/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 300M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 320M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 320M/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 420/PCI/SSE2
-NVIDIA Corporation Quadro NVS 420/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 420/PCIe/SSE2/3DNOW!
-NVIDIA Corporation Quadro NVS 450/PCIe/SSE2
-NVIDIA Corporation Quadro NVS 510M/PCI/SSE2
-NVIDIA Corporation Quadro NVS 55/280 PCI/PCI/SSE2
-NVIDIA Corporation Quadro NVS with AGP8X/AGP/SSE2
-NVIDIA Corporation Quadro NVS/AGP/SSE2
-NVIDIA Corporation Quadro PCI-E Series/PCI/SSE2
-NVIDIA Corporation Quadro2 MXR/AGP/SSE2
-NVIDIA Corporation Quadro4 380 XGL/AGP/SSE2
-NVIDIA Corporation Quadro4 550 XGL/AGP/SSE2
-NVIDIA Corporation Quadro4 700 XGL/AGP/SSE2
-NVIDIA Corporation Quadro4 980 XGL/AGP/SSE2
-NVIDIA Corporation RIVA TNT2/AGP/SSE2
-NVIDIA Corporation RIVA TNT2/AGP/SSE2/3DNOW!
-NVIDIA Corporation Stinger/emulated by Quadro FX 500/FX 600/PCI/SSE2
-NVIDIA Corporation nForce 750a SLI/PCI/SSE2
-NVIDIA Corporation nForce 750a SLI/integrated/SSE2
-NVIDIA Corporation nForce 760i SLI/integrated/SSE2
-NVIDIA Corporation nForce 980a/780a SLI/integrated/SSE2
-NVIDIA Corporation unknown board/AGP/SSE2
-NVIDIA Corporation unknown board/PCI/SSE2
-NVIDIA Corporation unknown board/PCI/SSE2/3DNOW!
-NVIDIA Corporation unknown board/PCIe/SSE2
-NVIDIA D9M
-NVIDIA G 103M
-NVIDIA G 105M
-NVIDIA G 110M
-NVIDIA G 120M
-NVIDIA G 200
-NVIDIA G 205M
-NVIDIA G 210
-NVIDIA G 310M
-NVIDIA G 320M
-NVIDIA G 405
-NVIDIA G 410M
-NVIDIA G 610M
-NVIDIA G100
-NVIDIA G100M
-NVIDIA G102M
-NVIDIA G103M
-NVIDIA G105M
-NVIDIA G200
-NVIDIA G210
-NVIDIA G210M
-NVIDIA G73
-NVIDIA G84
-NVIDIA G84
-NVIDIA G92
-NVIDIA G94
-NVIDIA GT 120
-NVIDIA GT 120
-NVIDIA GT 120M
-NVIDIA GT 130
-NVIDIA GT 130
-NVIDIA GT 130
-NVIDIA GT 130M
-NVIDIA GT 140
-NVIDIA GT 140M
-NVIDIA GT 150
-NVIDIA GT 220
-NVIDIA GT 220
-NVIDIA GT 220
-NVIDIA GT 220
-NVIDIA GT 220M
-NVIDIA GT 230
-NVIDIA GT 230
-NVIDIA GT 230M
-NVIDIA GT 240
-NVIDIA GT 240
-NVIDIA GT 240
-NVIDIA GT 240M
-NVIDIA GT 260M
-NVIDIA GT 320
-NVIDIA GT 320M
-NVIDIA GT 320M
-NVIDIA GT 325M
-NVIDIA GT 330
-NVIDIA GT 330
-NVIDIA GT 330
-NVIDIA GT 330M
-NVIDIA GT 330M
-NVIDIA GT 335M
-NVIDIA GT 340
-NVIDIA GT 340M
-NVIDIA GT 415M
-NVIDIA GT 420
-NVIDIA GT 420M
-NVIDIA GT 425M
-NVIDIA GT 430
-NVIDIA GT 430M
-NVIDIA GT 435M
-NVIDIA GT 440
-NVIDIA GT 440M
-NVIDIA GT 445M
-NVIDIA GT 450
-NVIDIA GT 520
-NVIDIA GT 520
-NVIDIA GT 520M
-NVIDIA GT 525M
-NVIDIA GT 530M
-NVIDIA GT 540
-NVIDIA GT 540M
-NVIDIA GT 550
-NVIDIA GT 550M
-NVIDIA GT 555M
-NVIDIA GT 610
-NVIDIA GT 620
-NVIDIA GT 620M
-NVIDIA GT 630
-NVIDIA GT 630M
-NVIDIA GT 635M
-NVIDIA GT 640
-NVIDIA GT 640M
-NVIDIA GT 650
-NVIDIA GT 650M
-NVIDIA GT 650M
-NVIDIA GTS 160M
-NVIDIA GTS 240
-NVIDIA GTS 240
-NVIDIA GTS 250
-NVIDIA GTS 350M
-NVIDIA GTS 360
-NVIDIA GTS 360M
-NVIDIA GTS 450
-NVIDIA GTX 260
-NVIDIA GTX 270
-NVIDIA GTX 275
-NVIDIA GTX 280
-NVIDIA GTX 285
-NVIDIA GTX 290
-NVIDIA GTX 295
-NVIDIA GTX 460
-NVIDIA GTX 460M
-NVIDIA GTX 465
-NVIDIA GTX 470
-NVIDIA GTX 470M
-NVIDIA GTX 480
-NVIDIA GTX 480M
-NVIDIA GTX 485M
-NVIDIA GTX 550
-NVIDIA GTX 560
-NVIDIA GTX 560
-NVIDIA GTX 560
-NVIDIA GTX 560 Ti
-NVIDIA GTX 570
-NVIDIA GTX 580
-NVIDIA GTX 580M
-NVIDIA GTX 590
-NVIDIA GTX 650
-NVIDIA GTX 660
-NVIDIA GTX 660
-NVIDIA GTX 670
-NVIDIA GTX 670
-NVIDIA GTX 670M
-NVIDIA GTX 675M
-NVIDIA GTX 675M
-NVIDIA GTX 680
-NVIDIA GTX 680
-NVIDIA GTX 680M
-NVIDIA GTX 690
-NVIDIA GTX 770
-NVIDIA GTX 770
-NVIDIA GTX TITAN
-NVIDIA GeForce 2
-NVIDIA GeForce 3
-NVIDIA GeForce 4
-NVIDIA GeForce 4 Go
-NVIDIA GeForce 4 MX
-NVIDIA GeForce 4 Ti
-NVIDIA GeForce 6100
-NVIDIA GeForce 6100
-NVIDIA GeForce 6200
-NVIDIA GeForce 6200
-NVIDIA GeForce 6500
-NVIDIA GeForce 6600
-NVIDIA GeForce 6700
-NVIDIA GeForce 6800
-NVIDIA GeForce 7000
-NVIDIA GeForce 7000M
-NVIDIA GeForce 7100
-NVIDIA GeForce 7300
-NVIDIA GeForce 7300
-NVIDIA GeForce 7500
-NVIDIA GeForce 7600
-NVIDIA GeForce 7600
-NVIDIA GeForce 7800
-NVIDIA GeForce 7800
-NVIDIA GeForce 7900
-NVIDIA GeForce 7900
-NVIDIA GeForce 8100
-NVIDIA GeForce 8200
-NVIDIA GeForce 8200M
-NVIDIA GeForce 8300
-NVIDIA GeForce 8300
-NVIDIA GeForce 8400
-NVIDIA GeForce 8400
-NVIDIA GeForce 8400M
-NVIDIA GeForce 8400M
-NVIDIA GeForce 8500
-NVIDIA GeForce 8500
-NVIDIA GeForce 8600
-NVIDIA GeForce 8600M
-NVIDIA GeForce 8600M
-NVIDIA GeForce 8700
-NVIDIA GeForce 8700M
-NVIDIA GeForce 8800
-NVIDIA GeForce 8800M
-NVIDIA GeForce 9100
-NVIDIA GeForce 9100M
-NVIDIA GeForce 9200
-NVIDIA GeForce 9200
-NVIDIA GeForce 9200M
-NVIDIA GeForce 9300
-NVIDIA GeForce 9300
-NVIDIA GeForce 9300M
-NVIDIA GeForce 9300M
-NVIDIA GeForce 9400
-NVIDIA GeForce 9400
-NVIDIA GeForce 9400M
-NVIDIA GeForce 9400M
-NVIDIA GeForce 9500
-NVIDIA GeForce 9500M
-NVIDIA GeForce 9600
-NVIDIA GeForce 9600
-NVIDIA GeForce 9600M
-NVIDIA GeForce 9600M
-NVIDIA GeForce 9700M
-NVIDIA GeForce 9800
-NVIDIA GeForce 9800M
-NVIDIA GeForce FX 5200
-NVIDIA GeForce FX 5200
-NVIDIA GeForce FX 5500
-NVIDIA GeForce FX 5500
-NVIDIA GeForce FX 5600
-NVIDIA GeForce FX 5700
-NVIDIA GeForce FX 5900
-NVIDIA GeForce FX Go5100
-NVIDIA GeForce FX Go5200
-NVIDIA GeForce FX Go5600
-NVIDIA GeForce FX Go5700
-NVIDIA GeForce Go 6
-NVIDIA GeForce Go 6100
-NVIDIA GeForce Go 6200
-NVIDIA GeForce Go 6400
-NVIDIA GeForce Go 6600
-NVIDIA GeForce Go 6800
-NVIDIA GeForce Go 7200
-NVIDIA GeForce Go 7300
-NVIDIA GeForce Go 7400
-NVIDIA GeForce Go 7600
-NVIDIA GeForce Go 7700
-NVIDIA GeForce Go 7800
-NVIDIA GeForce Go 7900
-NVIDIA GeForce PCX
-NVIDIA Generic
-NVIDIA ION
-NVIDIA MCP61
-NVIDIA NV34
-NVIDIA PCI
-NVIDIA Quadro 2000
-NVIDIA Quadro 2000 M/D
-NVIDIA Quadro 2000 M/D
-NVIDIA Quadro 3000M
-NVIDIA Quadro 400
-NVIDIA Quadro 4000
-NVIDIA Quadro 4000
-NVIDIA Quadro 4000M
-NVIDIA Quadro 50x0 M
-NVIDIA Quadro 600
-NVIDIA Quadro 6000
-NVIDIA Quadro FX
-NVIDIA Quadro FX 1500M
-NVIDIA Quadro FX 1800
-NVIDIA Quadro FX 2500M
-NVIDIA Quadro FX 2700M
-NVIDIA Quadro FX 2800M
-NVIDIA Quadro FX 3500
-NVIDIA Quadro FX 3700
-NVIDIA Quadro FX 3800
-NVIDIA Quadro FX 4500
-NVIDIA Quadro FX 4800
-NVIDIA Quadro FX 550
-NVIDIA Quadro FX 770M
-NVIDIA Quadro FX 880M
-NVIDIA Quadro NVS
-NVIDIA Quadro NVS 1xxM
-NVIDIA Quadro NVS 4200M
-NVIDIA Quadro2
-NVIDIA nForce
-Oracle VirtualBox Graphics
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon Barts XT Prototype OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 2600 OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 2600 PRO OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 4670 OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 4850 OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5670 OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5750 OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5770 OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6630M OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6750M OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6770M OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6970M OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6970M OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6970M OpenGL Engine
-Parallels and ATI Technologies Inc. Parallels using ATI Radeon X1600 OpenGL Engine
-Parallels and Intel Inc. Parallels using Intel GMA X3100 OpenGL Engine
-Parallels and Intel Inc. Parallels using Intel HD Graphics 3000 OpenGL Engine
-Parallels and Intel Inc. Parallels using Intel HD Graphics 4000 OpenGL Engine
-Parallels and Intel Inc. Parallels using Intel HD Graphics 4000 OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 320M OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 8800 GS OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 9400 OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 9400M OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 9600M GT OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GT 130 OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GT 330M OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GT 640 OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GT 640M OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GT 650M OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 570 OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 660 OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 660 Ti OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 670 OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 680MX OpenGL Engine
-Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce GTX 680MX OpenGL Engine
-PowerVR SGX545
-S3
-S3 Graphics K8M800/MMX/K3D
-S3 Graphics KM400/KN400/MMX/SSE
-S3 Graphics P8M800/MMX/SSE
-S3 Graphics Unknown Device/MMX/SSE
-S3 Graphics VIA/S3G UniChrome IGP/MMX/SSE
-S3 Graphics VIA/S3G UniChrome Pro IGP/MMX/SSE
-S3 Graphics VIA/S3G UniChrome Pro IGP/MMX/SSE
-S3 Graphics, Incorporated ProSavage/Twister
-S3 Graphics, Incorporated S3 Graphics Chrome9 HC
-S3 Graphics, Incorporated S3 Graphics DeltaChrome
-S3 Graphics, Incorporated VIA Chrome9 HC IGP
-S3 Graphics, Incorporated VIA Chrome9 HC IGP
-S3 Graphics, Incorporated VIA Chrome9 HC3 IGP
-S3 Graphics, Incorporated VIA Chrome9 HD Pro IGP
-S3 Graphics, Incorporated VIA Chrome9 HD Pro IGP
-SiS
-SiS 3D-Analyze v2.3 - http://www.tommti-systems.com
-SiS 650/M650 VGA
-SiS 650/M650 VGA / MMX/SSE2 /AGP
-SiS 661 VGA
-SiS 662 VGA
-SiS 760 VGA
-SiS 761GX VGA
-SiS Mirage Graphics3
-SiS Mirage Graphics3
-SiS Xabre VGA
-Tungsten Graphics, Inc Mesa DRI Intel(R) 845G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 852GM/855GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 852GM/855GM x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 865G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 865G x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915G
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915G x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915GM 20061017 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915GM GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915GM GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 915GM x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945G GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945G GEM 20100330 DEVELOPMENT x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945G x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945GM GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945GM x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945GME
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945GME GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 945GME x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965GM
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965GM GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965GM GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965GM x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965GM x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965GME/GLE x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965Q
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965Q GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) 965Q x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) G33 GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) G33 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) G41 GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) G41 GEM 20100330 DEVELOPMENT x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) G41 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) G41 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD GEM 20091221 2009Q4
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGD x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGDNG_M GEM 20091221 2009Q4
-Tungsten Graphics, Inc Mesa DRI Intel(R) IGDNG_M GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Desktop
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Desktop x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Mobile
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Mobile GEM 20100330 DEVELOPMENT x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Mobile x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ironlake Mobile x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ivybridge Desktop
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ivybridge Desktop x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ivybridge Mobile
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ivybridge Mobile x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Ivybridge Mobile x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Q35 GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Q35 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Q45/Q43 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Desktop
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Desktop x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Mobile x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Mobile
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Mobile GEM 20100330 DEVELOPMENT x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Mobile x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Mobile x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Intel(R) Sandybridge Server
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset GEM 20091221 2009Q4
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset GEM 20091221 2009Q4 x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset GEM 20100330 DEVELOPMENT x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset x86/MMX/SSE2
-Tungsten Graphics, Inc Mesa DRI Mobile Intel(R) GM45 Express Chipset x86/MMX/SSE2
-Tungsten Graphics, Inc. Mesa DRI R100 (RS200 4437) x86/MMX/SSE2 NO-TCL DRI2
-Tungsten Graphics, Inc. Mesa DRI R100 (RV200 4C57) TCL DRI2
-Tungsten Graphics, Inc. Mesa DRI R100 (RV200 4C57) x86/MMX/SSE2 TCL DRI2
-Tungsten Graphics, Inc. Mesa DRI R200 (RV250 4C66) x86/MMX/SSE2 TCL DRI2
-Tungsten Graphics, Inc. Mesa DRI R200 (RV280 5960) x86/MMX+/3DNow!+/SSE2 TCL DRI2
-Tungsten Graphics, Inc. Mesa DRI R200 (RV280 5960) x86/MMX/SSE2 TCL DRI2
-Tungsten Graphics, Inc. Mesa DRI R200 (RV280 5961) x86/MMX/SSE2 TCL DRI2
-VMware, Inc. Gallium 0.3 on SVGA3D; build: RELEASE;
-VMware, Inc. Gallium 0.3 on SVGA3D; build: RELEASE;
-VMware, Inc. Gallium 0.4 on SVGA3D; build: RELEASE;
-VMware, Inc. Gallium 0.4 on SVGA3D; build: RELEASE;
-VMware, Inc. Gallium 0.4 on i915 (chipset: 945GME)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x209)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x209)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x300)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x300)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x301)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x301)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x302)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 0x302)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 3.2, 128 bits)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 3.2, 128 bits)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 3.2, 256 bits)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 3.2, 256 bits)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 3.3, 128 bits)
-VMware, Inc. Gallium 0.4 on llvmpipe (LLVM 3.3, 128 bits)
-VMware, Inc. Gallium 0.4 on llvmpipe
-X.Org Gallium 0.4 on AMD ARUBA
-X.Org Gallium 0.4 on AMD ARUBA
-X.Org Gallium 0.4 on AMD BARTS
-X.Org Gallium 0.4 on AMD BARTS
-X.Org Gallium 0.4 on AMD CAICOS
-X.Org Gallium 0.4 on AMD CAPE VERDE
-X.Org Gallium 0.4 on AMD CEDAR
-X.Org Gallium 0.4 on AMD CYPRESS
-X.Org Gallium 0.4 on AMD JUNIPER
-X.Org Gallium 0.4 on AMD PALM
-X.Org Gallium 0.4 on AMD PALM
-X.Org Gallium 0.4 on AMD REDWOOD
-X.Org Gallium 0.4 on AMD REDWOOD
-X.Org Gallium 0.4 on AMD RS780
-X.Org Gallium 0.4 on AMD RS780
-X.Org Gallium 0.4 on AMD RS880
-X.Org Gallium 0.4 on AMD RV610
-X.Org Gallium 0.4 on AMD RV610
-X.Org Gallium 0.4 on AMD RV620
-X.Org Gallium 0.4 on AMD RV630
-X.Org Gallium 0.4 on AMD RV635
-X.Org Gallium 0.4 on AMD RV670
-X.Org Gallium 0.4 on AMD RV710
-X.Org Gallium 0.4 on AMD RV710
-X.Org Gallium 0.4 on AMD RV730
-X.Org Gallium 0.4 on AMD RV730
-X.Org Gallium 0.4 on AMD RV740
-X.Org Gallium 0.4 on AMD RV770
-X.Org Gallium 0.4 on AMD SUMO
-X.Org Gallium 0.4 on AMD SUMO
-X.Org Gallium 0.4 on AMD SUMO2
-X.Org Gallium 0.4 on AMD TURKS
-X.Org R300 Project Gallium 0.4 on ATI R350
-X.Org R300 Project Gallium 0.4 on ATI R580
-X.Org R300 Project Gallium 0.4 on ATI RC410
-X.Org R300 Project Gallium 0.4 on ATI RS480
-X.Org R300 Project Gallium 0.4 on ATI RS480
-X.Org R300 Project Gallium 0.4 on ATI RS482
-X.Org R300 Project Gallium 0.4 on ATI RS600
-X.Org R300 Project Gallium 0.4 on ATI RS690
-X.Org R300 Project Gallium 0.4 on ATI RV350
-X.Org R300 Project Gallium 0.4 on ATI RV350
-X.Org R300 Project Gallium 0.4 on ATI RV370
-X.Org R300 Project Gallium 0.4 on ATI RV380
-X.Org R300 Project Gallium 0.4 on ATI RV410
-X.Org R300 Project Gallium 0.4 on ATI RV515
-X.Org R300 Project Gallium 0.4 on ATI RV530
-X.Org R300 Project Gallium 0.4 on ATI RV530
-X.Org R300 Project Gallium 0.4 on ATI RV570
-XGI Volari V3
-http://TitaniumGL.tk NVIDIA GeForce GTX 690/3999M VRAM/TitaniumGL/4 THREADs/3D GRAPHICS ACCELERATION/4 TMUs
-nouveau Gallium 0.4 on NV34
-nouveau Gallium 0.4 on NV34
-nouveau Gallium 0.4 on NV42
-nouveau Gallium 0.4 on NV42
-nouveau Gallium 0.4 on NV44
-nouveau Gallium 0.4 on NV44
-nouveau Gallium 0.4 on NV46
-nouveau Gallium 0.4 on NV49
-nouveau Gallium 0.4 on NV4A
-nouveau Gallium 0.4 on NV4A
-nouveau Gallium 0.4 on NV4B
-nouveau Gallium 0.4 on NV4B
-nouveau Gallium 0.4 on NV4C
-nouveau Gallium 0.4 on NV4C
-nouveau Gallium 0.4 on NV4E
-nouveau Gallium 0.4 on NV50
-nouveau Gallium 0.4 on NV63
-nouveau Gallium 0.4 on NV67
-nouveau Gallium 0.4 on NV84
-nouveau Gallium 0.4 on NV84
-nouveau Gallium 0.4 on NV86
-nouveau Gallium 0.4 on NV86
-nouveau Gallium 0.4 on NV92
-nouveau Gallium 0.4 on NV92
-nouveau Gallium 0.4 on NV94
-nouveau Gallium 0.4 on NV94
-nouveau Gallium 0.4 on NV96
-nouveau Gallium 0.4 on NV96
-nouveau Gallium 0.4 on NV98
-nouveau Gallium 0.4 on NV98
-nouveau Gallium 0.4 on NVA0
-nouveau Gallium 0.4 on NVA0
-nouveau Gallium 0.4 on NVA3
-nouveau Gallium 0.4 on NVA3
-nouveau Gallium 0.4 on NVA5
-nouveau Gallium 0.4 on NVA5
-nouveau Gallium 0.4 on NVA8
-nouveau Gallium 0.4 on NVA8
-nouveau Gallium 0.4 on NVAA
-nouveau Gallium 0.4 on NVAA
-nouveau Gallium 0.4 on NVAC
-nouveau Gallium 0.4 on NVAC
-nouveau Gallium 0.4 on NVAF
-nouveau Gallium 0.4 on NVC0
-nouveau Gallium 0.4 on NVC0
-nouveau Gallium 0.4 on NVC1
-nouveau Gallium 0.4 on NVC1
-nouveau Gallium 0.4 on NVC3
-nouveau Gallium 0.4 on NVC4
-nouveau Gallium 0.4 on NVC4
-nouveau Gallium 0.4 on NVCE
-nouveau Gallium 0.4 on NVCE
-nouveau Gallium 0.4 on NVCF
-nouveau Gallium 0.4 on NVCF
-nouveau Gallium 0.4 on NVD9
-nouveau Gallium 0.4 on NVD9
-nouveau Gallium 0.4 on NVE4
-nouveau Gallium 0.4 on NVE6
-nouveau Gallium 0.4 on NVE7
-nouveau Gallium 0.4 on NVE7
diff --git a/indra/newview/tests/gpus_unmatched.txt b/indra/newview/tests/gpus_unmatched.txt
deleted file mode 100644
index 083f29aaa0..0000000000
--- a/indra/newview/tests/gpus_unmatched.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-ATI NO MATCH
-ATI Technologies NO MATCH
-ATI Technologies Inc. NO MATCH
-ATI Technologies Inc. (DNA-ATi 5.1.7.5x32) ATI Mobility Radeon HD 2 NO MATCH
-ATI Technologies Inc. ATI Mobility Radeon Graphics NO MATCH
-ATI Technologies Inc. ATI Radeon Graphics Processor NO MATCH
-Intel NO MATCH
-NVIDIA Corporation /PCI/SSE2 NO MATCH
-NVIDIA Corporation Quadro PCI-E Series/PCI/SSE2 NO MATCH
diff --git a/indra/newview/tests/lldir_stub.cpp b/indra/newview/tests/lldir_stub.cpp
index 5d9c2f718b..ff4a4daf6d 100644
--- a/indra/newview/tests/lldir_stub.cpp
+++ b/indra/newview/tests/lldir_stub.cpp
@@ -28,7 +28,7 @@
LLDir::LLDir() {}
LLDir::~LLDir() {}
-BOOL LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) { return true; }
+S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) { return 1; }
void LLDir::setChatLogsDir(const std::string &path) {}
void LLDir::setPerAccountChatLogsDir(const std::string &) {}
void LLDir::updatePerAccountChatLogsDir() {}
diff --git a/indra/newview/tests/llpipeline_stub.cpp b/indra/newview/tests/llpipeline_stub.cpp
deleted file mode 100644
index 62b71e51e5..0000000000
--- a/indra/newview/tests/llpipeline_stub.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * @file llpipeline_stub.cpp
- * @brief stub class to allow unit testing
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-class LLPipeline
-{
-public: BOOL canUseWindLightShaders() const;
-};
-BOOL LLPipeline::canUseWindLightShaders() const {return TRUE;}
-LLPipeline gPipeline;
diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp
index c8fa2fbd6f..9f3d7454ad 100644
--- a/indra/newview/tests/llremoteparcelrequest_test.cpp
+++ b/indra/newview/tests/llremoteparcelrequest_test.cpp
@@ -27,7 +27,6 @@
#include "linden_common.h"
#include "../test/lltut.h"
-#if 0
#include "../llremoteparcelrequest.h"
@@ -40,16 +39,6 @@ namespace {
const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111");
}
-LLCurl::Responder::Responder() { }
-LLCurl::Responder::~Responder() { }
-void LLCurl::Responder::httpFailure() { }
-void LLCurl::Responder::httpSuccess() { }
-void LLCurl::Responder::httpCompleted() { }
-void LLCurl::Responder::failureResult(S32 status, const std::string& reason, const LLSD& content) { }
-void LLCurl::Responder::successResult(const LLSD& content) { }
-void LLCurl::Responder::completeResult(S32 status, const std::string& reason, const LLSD& content) { }
-std::string LLCurl::Responder::dumpResponse() const { return "(failure)"; }
-void LLCurl::Responder::completedRaw(LLChannelDescriptors const &,std::shared_ptr<LLBufferArray> const &) { }
void LLMessageSystem::getF32(char const *,char const *,F32 &,S32) { }
void LLMessageSystem::getU8(char const *,char const *,U8 &,S32) { }
void LLMessageSystem::getS32(char const *,char const *,S32 &,S32) { }
@@ -136,4 +125,3 @@ namespace tut
processor.processParcelInfoReply(gMessageSystem, NULL);
}
}
-#endif
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/lltextureinfo_test.cpp b/indra/newview/tests/lltextureinfo_test.cpp
index d491ce0f65..58451a1069 100644
--- a/indra/newview/tests/lltextureinfo_test.cpp
+++ b/indra/newview/tests/lltextureinfo_test.cpp
@@ -32,6 +32,13 @@
// Dependencies
#include "../lltextureinfodetails.cpp"
+#include "../llagent.h"
+#include "../llappviewer.h"
+#include "../llmeshrepository.h"
+#include "../lltexturecache.h"
+#include "../lltexturefetch.h"
+#include "../llvocache.h"
+
// Tut header
#include "../test/lltut.h"
@@ -43,6 +50,39 @@
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
+LLControlGroup gSavedSettings("Global");
+
+void send_texture_stats_to_sim(const LLSD& texture_stats) {}
+
+LLAgent gAgent;
+LLAgent::LLAgent() : mAgentAccess(nullptr) { }
+LLAgent::~LLAgent() { }
+LLViewerRegion* LLAgent::getRegion() const { return nullptr; }
+
+LLTextureCache* LLAppViewer::sTextureCache = nullptr;
+LLTextureFetch* LLAppViewer::sTextureFetch = nullptr;
+
+U32 LLMeshRepository::sCacheReads = 0;
+std::atomic<U32> LLMeshRepository::sCacheWrites = 0;
+
+S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit
+
+void LLTextureFetch::getStateStats(U32* cache_read, U32* cache_write, U32* res_wait)
+{
+ *cache_read = 0;
+ *cache_write = 0;
+ *res_wait = 0;
+}
+
+LLVOCache::LLVOCache(bool read_only) :
+ mInitialized(false),
+ mReadOnly(read_only),
+ mNumEntries(0),
+ mCacheSize(1),
+ mEnabled(true)
+{}
+
+LLVOCache::~LLVOCache() {}
// End Stubbing
// -------------------------------------------------------------------------------------------
@@ -89,7 +129,7 @@ namespace tut
void textureinfo_object_t::test<1>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
ensure("have we crashed?", true);
}
@@ -98,7 +138,7 @@ namespace tut
void textureinfo_object_t::test<2>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
LLUUID nonExistant("3a0efa3b-84dc-4e17-9b8c-79ea028850c1");
ensure(!tex_info.has(nonExistant));
@@ -109,7 +149,7 @@ namespace tut
void textureinfo_object_t::test<3>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestStartTime(id, 200);
@@ -122,7 +162,7 @@ namespace tut
void textureinfo_object_t::test<4>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
LLUUID nonExistant("3a0efa3b-84dc-4e17-9b8c-79ea028850c1");
ensure_equals(tex_info.getRequestStartTime(nonExistant), 0);
@@ -133,7 +173,7 @@ namespace tut
void textureinfo_object_t::test<5>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
LLUUID nonExistant("3a0efa3b-84dc-4e17-9b8c-79ea028850c1");
ensure_equals(tex_info.getRequestCompleteTime(nonExistant), 0);
@@ -144,7 +184,7 @@ namespace tut
void textureinfo_object_t::test<6>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestSize(id, 600);
@@ -157,7 +197,7 @@ namespace tut
void textureinfo_object_t::test<7>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestType(id, LLTextureInfoDetails::REQUEST_TYPE_HTTP);
@@ -170,7 +210,7 @@ namespace tut
void textureinfo_object_t::test<8>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestType(id, LLTextureInfoDetails::REQUEST_TYPE_UDP);
@@ -183,7 +223,7 @@ namespace tut
void textureinfo_object_t::test<9>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestOffset(id, 1234);
@@ -195,11 +235,13 @@ namespace tut
template<> template<>
void textureinfo_object_t::test<10>()
{
+ skip("Test skipped due to use of LLTrace stats failing in test");
+
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
S32 requestStartTimeOne = 200;
- S32 requestEndTimeOne = 400;
+ U64Microseconds requestEndTimeOne(400);
S32 requestSizeOne = 1024;
S32 requestSizeOneBits = requestSizeOne * 8;
LLUUID id1("10e65d70-46fd-429f-841a-bf698e9424d3");
@@ -209,7 +251,7 @@ namespace tut
tex_info.setRequestCompleteTimeAndLog(id1, requestEndTimeOne);
U32 requestStartTimeTwo = 100;
- U32 requestEndTimeTwo = 500;
+ U64Microseconds requestEndTimeTwo(500);
U32 requestSizeTwo = 2048;
S32 requestSizeTwoBits = requestSizeTwo * 8;
LLUUID id2("10e65d70-46fd-429f-841a-bf698e9424d4");
@@ -218,8 +260,9 @@ namespace tut
tex_info.setRequestType(id2, LLTextureInfoDetails::REQUEST_TYPE_HTTP);
tex_info.setRequestCompleteTimeAndLog(id2, requestEndTimeTwo);
- S32 averageBitRate = ((requestSizeOneBits/(requestEndTimeOne - requestStartTimeOne)) +
- (requestSizeTwoBits/(requestEndTimeTwo - requestStartTimeTwo))) / 2;
+ S32 averageBitRate = ((requestSizeOneBits / (S32(requestEndTimeOne.value()) - requestStartTimeOne)) +
+ (requestSizeTwoBits / (S32(requestEndTimeTwo.value()) - requestStartTimeTwo))) /
+ 2;
S32 totalBytes = requestSizeOne + requestSizeTwo;
@@ -234,10 +277,10 @@ namespace tut
void textureinfo_object_t::test<11>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
S32 requestStartTimeOne = 200;
- S32 requestEndTimeOne = 400;
+ U64Microseconds requestEndTimeOne(400);
S32 requestSizeOne = 1024;
LLUUID id1("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestStartTime(id1, requestStartTimeOne);
@@ -246,7 +289,7 @@ namespace tut
tex_info.setRequestCompleteTimeAndLog(id1, requestEndTimeOne);
tex_info.getAverages();
- tex_info.reset();
+ tex_info.resetTextureStatistics();
LLSD results = tex_info.getAverages();
ensure_equals("is average bits per second correct", results["bits_per_second"].asInteger(), 0);
ensure_equals("is total bytes is correct", results["bytes_downloaded"].asInteger(), 0);
@@ -258,10 +301,10 @@ namespace tut
void textureinfo_object_t::test<12>()
{
LLTextureInfo tex_info;
- tex_info.setUpLogging(true, true);
+ tex_info.setLogging(true);
S32 requestStartTimeOne = 200;
- S32 requestEndTimeOne = 400;
+ U64Microseconds requestEndTimeOne(400);
S32 requestSizeOne = 1024;
LLUUID id1("10e65d70-46fd-429f-841a-bf698e9424d3");
tex_info.setRequestStartTime(id1, requestStartTimeOne);
diff --git a/indra/newview/tests/lltexturestatsuploader_test.cpp b/indra/newview/tests/lltexturestatsuploader_test.cpp
deleted file mode 100644
index 782a4892b9..0000000000
--- a/indra/newview/tests/lltexturestatsuploader_test.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * @file lltexturestatsuploader_test.cpp
- * @author Si
- * @date 2009-05-27
- *
- * $LicenseInfo:firstyear=2006&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$
- */
-
-// Precompiled header: almost always required for newview cpp files
-#include "../llviewerprecompiledheaders.h"
-// Class to test
-#include "../lltexturestatsuploader.h"
-// Dependencies
-
-// Tut header
-#include "../test/lltut.h"
-
-// -------------------------------------------------------------------------------------------
-// Stubbing: Declarations required to link and run the class being tested
-// Notes:
-// * Add here stubbed implementation of the few classes and methods used in the class to be tested
-// * Add as little as possible (let the link errors guide you)
-// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
-// * A simulator for a class can be implemented here. Please comment and document thoroughly.
-
-#include "boost/intrusive_ptr.hpp"
-void boost::intrusive_ptr_add_ref(LLCurl::Responder*){}
-void boost::intrusive_ptr_release(LLCurl::Responder* p){}
-const F32 HTTP_REQUEST_EXPIRY_SECS = 0.0f;
-
-static std::string most_recent_url;
-static LLSD most_recent_body;
-
-void LLHTTPClient::post(
- const std::string& url,
- const LLSD& body,
- ResponderPtr,
- const LLSD& headers,
- const F32 timeout)
-{
- // set some sensor code
- most_recent_url = url;
- most_recent_body = body;
- return;
-}
-
-// End Stubbing
-// -------------------------------------------------------------------------------------------
-
-// -------------------------------------------------------------------------------------------
-// TUT
-// -------------------------------------------------------------------------------------------
-
-namespace tut
-{
- // Test wrapper declarations
- struct texturestatsuploader_test
- {
- // Constructor and destructor of the test wrapper
- texturestatsuploader_test()
- {
- most_recent_url = "some sort of default text that should never match anything the tests are expecting!";
- LLSD blank_llsd;
- most_recent_body = blank_llsd;
- }
- ~texturestatsuploader_test()
- {
- }
- };
-
- // Tut templating thingamagic: test group, object and test instance
- typedef test_group<texturestatsuploader_test> texturestatsuploader_t;
- typedef texturestatsuploader_t::object texturestatsuploader_object_t;
- tut::texturestatsuploader_t tut_texturestatsuploader("LLTextureStatsUploader");
-
-
- // ---------------------------------------------------------------------------------------
- // Test functions
- // Notes:
- // * Test as many as you possibly can without requiring a full blown simulation of everything
- // * The tests are executed in sequence so the test instance state may change between calls
- // * Remember that you cannot test private methods with tut
- // ---------------------------------------------------------------------------------------
-
- // ---------------------------------------------------------------------------------------
- // Test the LLTextureInfo
- // ---------------------------------------------------------------------------------------
-
-
- // Test instantiation
- template<> template<>
- void texturestatsuploader_object_t::test<1>()
- {
- LLTextureStatsUploader tsu;
- LL_INFOS() << &tsu << LL_ENDL;
- ensure("have we crashed?", true);
- }
-
- // does it call out to the provided url if we ask it to?
- template<> template<>
- void texturestatsuploader_object_t::test<2>()
- {
- LLTextureStatsUploader tsu;
- std::string url = "http://blahblahblah";
- LLSD texture_stats;
- tsu.uploadStatsToSimulator(url, texture_stats);
- ensure_equals("did the right url get called?", most_recent_url, url);
- ensure_equals("did the right body get sent?", most_recent_body, texture_stats);
- }
-
- // does it not call out to the provided url if we send it an ungranted cap?
- template<> template<>
- void texturestatsuploader_object_t::test<3>()
- {
- LLTextureStatsUploader tsu;
-
- // this url left intentionally blank to mirror
- // not getting a cap in the caller.
- std::string url_for_ungranted_cap = "";
-
- LLSD texture_stats;
- std::string most_recent_url_before_test = most_recent_url;
- tsu.uploadStatsToSimulator(url_for_ungranted_cap, texture_stats);
-
- ensure_equals("hopefully no url got called!", most_recent_url, most_recent_url_before_test);
- }
-
- // does it call out if the data is empty?
- // should it even do that?
-}
-
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/tests/llvieweroctree_stub.cpp b/indra/newview/tests/llvieweroctree_stub.cpp
index caf9299a2f..e850efd9ac 100644
--- a/indra/newview/tests/llvieweroctree_stub.cpp
+++ b/indra/newview/tests/llvieweroctree_stub.cpp
@@ -35,7 +35,7 @@ bool LLViewerOctreeCull::checkObjects(const OctreeNode* branch, const LLViewerOc
void LLViewerOctreeCull::processGroup(LLViewerOctreeGroup* group) {}
-bool LLViewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) { return false; }
+bool LLViewerOctreeGroup::boundObjects(bool empty, LLVector4a& minOut, LLVector4a& maxOut) { return false; }
void LLViewerOctreeGroup::unbound() {}
void LLViewerOctreeGroup::rebound() {}
void LLViewerOctreeGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj) {}
@@ -55,8 +55,8 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode) {}
void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode) {}
void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode *parent, OctreeNode *child) {}
-BOOL LLOcclusionCullingGroup::isRecentlyVisible() const { return FALSE; }
-BOOL LLOcclusionCullingGroup::isAnyRecentlyVisible() const { return FALSE; }
+bool LLOcclusionCullingGroup::isRecentlyVisible() const { return false; }
+bool LLOcclusionCullingGroup::isAnyRecentlyVisible() const { return false; }
LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node) : mOctreeNode(node) {}
@@ -81,6 +81,6 @@ LLViewerOctreePartition::LLViewerOctreePartition() = default;
LLViewerOctreePartition::~LLViewerOctreePartition() = default;
void LLViewerOctreePartition::cleanup() {}
-BOOL LLViewerOctreeGroup::isRecentlyVisible() const { return FALSE; }
+bool LLViewerOctreeGroup::isRecentlyVisible() const { return false; }
diff --git a/indra/newview/tests/llviewershadermgr_stub.cpp b/indra/newview/tests/llviewershadermgr_stub.cpp
deleted file mode 100644
index 5d6cb33019..0000000000
--- a/indra/newview/tests/llviewershadermgr_stub.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file llglslshader_stub.cpp
- * @brief stub class to allow unit testing
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "../llviewershadermgr.h"
-
-LLShaderMgr::LLShaderMgr() {}
-LLShaderMgr::~LLShaderMgr() {}
-
-LLViewerShaderMgr::LLViewerShaderMgr() {}
-LLViewerShaderMgr::~LLViewerShaderMgr() {}
-
-LLViewerShaderMgr* stub_instance = NULL;
-
-LLViewerShaderMgr* LLViewerShaderMgr::instance() {
- if(NULL == stub_instance)
- {
- stub_instance = new LLViewerShaderMgr();
- }
-
- return stub_instance;
-}
-LLViewerShaderMgr::shader_iter fake_iter;
-LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const {return fake_iter;}
-LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const {return fake_iter;}
-
-void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader* shader) {return;}
-std::string LLViewerShaderMgr::getShaderDirPrefix() {return "SHADER_DIR_PREFIX-";}
diff --git a/indra/newview/tests/llwlanimator_stub.cpp b/indra/newview/tests/llwlanimator_stub.cpp
deleted file mode 100644
index 2b4510a6b7..0000000000
--- a/indra/newview/tests/llwlanimator_stub.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @file llwlanimator_stub.cpp
- * @brief stub class to allow unit testing
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-LLWLAnimator::LLWLAnimator(void) {}
-void LLWLAnimator::update(LLWLParamSet& set) {}
-void LLWLAnimator::setTrack(std::map<F32, LLWLParamKey>& track, F32 dayRate, F64 dayTime, bool run) {}
diff --git a/indra/newview/tests/llwlparammanager_test.cpp b/indra/newview/tests/llwlparammanager_test.cpp
deleted file mode 100644
index 2838ddb719..0000000000
--- a/indra/newview/tests/llwlparammanager_test.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
- * @file llwlparammanager_test.cpp
- * @brief LLWLParamManager tests
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-// Precompiled headers
-#include "../llviewerprecompiledheaders.h"
-
-// Class to test
-#include "../llwlparammanager.h"
-
-// Dependencies
-#include "linden_common.h"
-
-// TUT header
-#include "lltut.h"
-
-// Stubs
-#include "llwldaycycle_stub.cpp"
-#include "llwlparamset_stub.cpp"
-#include "llwlanimator_stub.cpp"
-#include "llglslshader_stub.cpp"
-#include "lldir_stub.cpp"
-#include "llsky_stub.cpp"
-#include "llpipeline_stub.cpp"
-#include "llviewershadermgr_stub.cpp"
-
-void assert_glerror(void) {}
-LLViewerCamera::LLViewerCamera() {}
-void LLViewerCamera::setView(F32 vertical_fov_rads) {}
-std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) { return std::string(""); }
-
-char* curl_unescape(const char* c_str, int length)
-{
- char* copy = new char[length+4];
- memcpy(copy, c_str, length);
- copy[length+0] = 'E';
- copy[length+1] = 'S';
- copy[length+2] = 'C';
- copy[length+3] = '\0';
- return copy;
-}
-void curl_free(void* p) {delete[] ((char*)p);}
-char* curl_escape(const char* c_str, int length) {
- char* copy = new char[length+6];
- memcpy(copy, c_str, length);
- copy[length+0] = 'U';
- copy[length+1] = 'N';
- copy[length+2] = 'E';
- copy[length+3] = 'S';
- copy[length+4] = 'C';
- copy[length+5] = '\0';
- return copy;
-}
-
-namespace tut
-{
- // Main Setup
- struct LLWLParamManagerFixture
- {
- class LLWLParamManagerTest
- {
- };
-
- LLWLParamManager* mTestManager;
-
- LLWLParamManagerFixture()
- : mTestManager(LLWLParamManager::getInstance())
- {
- }
-
- ~LLWLParamManagerFixture()
- {
- }
- };
- typedef test_group<LLWLParamManagerFixture> factory;
- typedef factory::object object;
- factory tf("LLWLParamManager test");
-
- // Tests
- template<> template<>
- void object::test<1>()
- {
- try
- {
- std::string preset =
- "<llsd>\
- <map>\
- <key>ambient</key>\
- <array>\
- <real>1.0499999523162842</real>\
- <real>1.0499999523162842</real>\
- <real>1.0499999523162842</real>\
- <real>0.34999999403953552</real>\
- </array>\
- <key>blue_density</key>\
- <array>\
- <real>0.2447581488182351</real>\
- <real>0.44872328639030457</real>\
- <real>0.75999999046325684</real>\
- <real>0.38000004053115788</real>\
- </array>\
- <key>blue_horizon</key>\
- <array>\
- <real>0.49548382097675159</real>\
- <real>0.49548381382419748</real>\
- <real>0.63999999284744291</real>\
- <real>0.31999999642372146</real>\
- </array>\
- <key>cloud_color</key>\
- <array>\
- <real>0.40999999165535073</real>\
- <real>0.40999999165535073</real>\
- <real>0.40999999165535073</real>\
- <real>0.40999999165535073</real>\
- </array>\
- <key>cloud_pos_density1</key>\
- <array>\
- <real>1.6884100437164307</real>\
- <real>0.52609699964523315</real>\
- <real>0.99999999999999289</real>\
- <real>1</real>\
- </array>\
- <key>cloud_pos_density2</key>\
- <array>\
- <real>1.6884100437164307</real>\
- <real>0.52609699964523315</real>\
- <real>0.125</real>\
- <real>1</real>\
- </array>\
- <key>cloud_scale</key>\
- <array>\
- <real>0.4199999868869746</real>\
- <real>0</real>\
- <real>0</real>\
- <real>1</real>\
- </array>\
- <key>cloud_scroll_rate</key>\
- <array>\
- <real>10.199999809265137</real>\
- <real>10.01099967956543</real>\
- </array>\
- <key>cloud_shadow</key>\
- <array>\
- <real>0.26999998092651367</real>\
- <real>0</real>\
- <real>0</real>\
- <real>1</real>\
- </array>\
- <key>density_multiplier</key>\
- <array>\
- <real>0.00017999998817685818</real>\
- <real>0</real>\
- <real>0</real>\
- <real>1</real>\
- </array>\
- <key>distance_multiplier</key>\
- <array>\
- <real>0.80000001192093606</real>\
- <real>0</real>\
- <real>0</real>\
- <real>1</real>\
- </array>\
- <key>east_angle</key>\
- <real>0</real>\
- <key>enable_cloud_scroll</key>\
- <array>\
- <boolean>1</boolean>\
- <boolean>1</boolean>\
- </array>\
- <key>gamma</key>\
- <array>\
- <real>1</real>\
- <real>0</real>\
- <real>0</real>\
- <real>1</real>\
- </array>\
- <key>glow</key>\
- <array>\
- <real>5</real>\
- <real>0.0010000000474974513</real>\
- <real>-0.47999998927116394</real>\
- <real>1</real>\
- </array>\
- <key>haze_density</key>\
- <array>\
- <real>0.69999998807907104</real>\
- <real>0</real>\
- <real>0</real>\
- <real>1</real>\
- </array>\
- <key>haze_horizon</key>\
- <array>\
- <real>0.18999999761581243</real>\
- <real>0.19915600121021271</real>\
- <real>0.19915600121021271</real>\
- <real>1</real>\
- </array>\
- <key>lightnorm</key>\
- <array>\
- <real>0</real>\
- <real>0.70710659027099609</real>\
- <real>-0.70710694789886475</real>\
- <real>0</real>\
- </array>\
- <key>max_y</key>\
- <array>\
- <real>1605</real>\
- <real>0</real>\
- <real>0</real>\
- <real>1</real>\
- </array>\
- <key>preset_num</key>\
- <integer>22</integer>\
- <key>star_brightness</key>\
- <real>0</real>\
- <key>sun_angle</key>\
- <real>2.3561947345733643</real>\
- <key>sunlight_color</key>\
- <array>\
- <real>0.73421055078505759</real>\
- <real>0.78157895803450828</real>\
- <real>0.89999997615813498</real>\
- <real>0.29999998211860301</real>\
- </array>\
- </map>\
- </llsd>";
-
- std::stringstream preset_stream(preset);
- mTestManager->loadPresetFromXML(LLWLParamKey("test1", LLWLParamKey::SCOPE_LOCAL), preset_stream);
- LLWLParamSet dummy;
- ensure("Couldn't get ParamSet after loading it", mTestManager->getParamSet(LLWLParamKey("test1", LLWLParamKey::SCOPE_LOCAL), dummy));
- }
- catch (...)
- {
- fail("loadPresetFromXML test crashed!");
- }
- }
-
- template<> template<>
- void object::test<2>()
- {
- mTestManager->propagateParameters();
- ensure_equals("Wrong value from getDomeOffset()", mTestManager->getDomeOffset(), 0.96f);
- ensure_equals("Wrong value from getDomeRadius()", mTestManager->getDomeRadius(), 15000.f);
- ensure_equals("Wrong value from getLightDir()", mTestManager->getLightDir(), LLVector4(-0,0,1,0));
- ensure_equals("Wrong value from getClampedLightDir()", mTestManager->getClampedLightDir(), LLVector4(-0,0,1,0));
- ensure_equals("Wrong value from getRotatedLightDir()", mTestManager->getRotatedLightDir(), LLVector4(0,0,0,1));
- }
-}
diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp
index ee6281fc24..c77ce367c5 100644
--- a/indra/newview/tests/llxmlrpclistener_test.cpp
+++ b/indra/newview/tests/llxmlrpclistener_test.cpp
@@ -62,8 +62,8 @@ namespace tut
// These variables are required by machinery used by
// LLXMLRPCTransaction. The values reflect reality for this test
// executable; hopefully these values are correct.
- gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", LLControlVariable::PERSIST_NO); // don't persist
- gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", LLControlVariable::PERSIST_NO); // don't persist
+ gSavedSettings.declareBOOL("BrowserProxyEnabled", false, "", LLControlVariable::PERSIST_NO); // don't persist
+ gSavedSettings.declareBOOL("NoVerifySSLCert", true, "", LLControlVariable::PERSIST_NO); // don't persist
}
// LLEventPump listener signature
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 8e59c26316..96fb3f7a17 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -764,7 +764,7 @@ class Windows_x86_64_Manifest(ViewerManifest):
pack_version = '.'.join(self.args['version'][:3])
if len(self.args['version']) > 3 and self.args['version'][3]:
pack_version += '-' + self.args['version'][3]
- pack_title = self.app_name() # Display name with spaces
+ pack_title = pack_id #Wrapper exe, don't use spaces
pack_dir = self.get_dst_prefix()
main_exe = self.final_exe()
installer_base = self.installer_base_name()
@@ -1333,33 +1333,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)
@@ -1368,32 +1368,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' ), dst="lib"):
- self.path( "libvlc*.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*" )
- # 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, 'bin', 'release'), dst="bin"):
+ self.path( "chrome-sandbox" )
+ self.path( "dullahan_host" )
+
+ 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
@@ -1408,8 +1445,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':
@@ -1417,87 +1464,54 @@ 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*")
- # 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*")
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 246fc5e6f8..c1e63a7470 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -10,110 +10,41 @@ include(Tut)
include(LLAddBuildTest)
include(bugsplat)
-set(test_SOURCE_FILES
- io.cpp
- llapp_tut.cpp
- llbuffer_tut.cpp
- lldoubledispatch_tut.cpp
- llevents_tut.cpp
- llhttpdate_tut.cpp
- llhttpnode_tut.cpp
- lliohttpserver_tut.cpp
- llmessageconfig_tut.cpp
- llpermissions_tut.cpp
- llpipeutil.cpp
- llsaleinfo_tut.cpp
- llsdmessagebuilder_tut.cpp
- llsdmessagereader_tut.cpp
- llsd_new_tut.cpp
- llsdutil_tut.cpp
- llservicebuilder_tut.cpp
- llstreamtools_tut.cpp
- lltemplatemessagebuilder_tut.cpp
+set(test_lib_SOURCE_FILES
lltut.cpp
- message_tut.cpp
test.cpp
)
-set(test_HEADER_FILES
+set(test_lib_HEADER_FILES
CMakeLists.txt
+ catch_and_store_what_in.h
+ chained_callback.h
debug.h
- llpipeutil.h
llsdtraits.h
+ lltestapp.h
lltut.h
+ namedtempfile.h
+ print.h
+ setenv.h
sync.h
+ test.h
)
-if (NOT WINDOWS)
- list(APPEND test_SOURCE_FILES
- llmessagetemplateparser_tut.cpp
- )
-endif (NOT WINDOWS)
+list(APPEND test_lib_SOURCE_FILES ${test_lib_HEADER_FILES})
-list(APPEND test_SOURCE_FILES ${test_HEADER_FILES})
+add_library(lltut_runner_lib ${test_lib_SOURCE_FILES})
-add_executable(lltest ${test_SOURCE_FILES})
+target_link_libraries(lltut_runner_lib PRIVATE llcommon)
-target_link_libraries(lltest
- llinventory
- llmessage
- llmath
- llfilesystem
- llxml
- llcommon
- llcorehttp
+set_target_properties(lltut_runner_lib
+ PROPERTIES
+ FOLDER "Tests"
)
-if (WINDOWS)
- set_target_properties(lltest
- PROPERTIES
- LINK_FLAGS "/NODEFAULTLIB:LIBCMT"
- LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\""
- RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
+if (DARWIN)
+ set_target_properties(lltut_runner_lib
+ PROPERTIES
+ OSX_ARCHITECTURES ${LL_MACOS_TEST_ARCHITECTURE}
)
-elseif (DARWIN)
- # 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
- # CREATE_LINK, so fudge it.
- file(CREATE_LINK "../sharedlibs/Release/Resources" "${CMAKE_BINARY_DIR}/test/Resources"
- SYMBOLIC)
-endif (WINDOWS)
-
-set(TEST_EXE $<TARGET_FILE:lltest>)
-
-SET_TEST_PATH(LD_LIBRARY_PATH)
-
-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")
-
-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"
- )
-
-set(test_results ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt)
-
-# 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})
- if(DARWIN)
- # 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
- # CREATE_LINK, so fudge it.
- add_custom_command( TARGET lltest POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E create_symlink ${SHARED_LIB_STAGING_DIR} ${CMAKE_BINARY_DIR}/test/Resources
- )
- endif()
-endif (LL_TESTS)
+endif ()
diff --git a/indra/test/hexdump.h b/indra/test/hexdump.h
deleted file mode 100644
index 95f1e297c3..0000000000
--- a/indra/test/hexdump.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file hexdump.h
- * @author Nat Goodspeed
- * @date 2023-09-08
- * @brief Provide hexdump() and hexmix() ostream formatters
- *
- * $LicenseInfo:firstyear=2023&license=viewerlgpl$
- * Copyright (c) 2023, Linden Research, Inc.
- * $/LicenseInfo$
- */
-
-#if ! defined(LL_HEXDUMP_H)
-#define LL_HEXDUMP_H
-
-#include <cctype>
-#include <iomanip>
-#include <iostream>
-#include <string_view>
-
-// Format a given byte string as 2-digit hex values, no separators
-// Usage: std::cout << hexdump(somestring) << ...
-class hexdump
-{
-public:
- hexdump(const std::string_view& data):
- hexdump(data.data(), data.length())
- {}
-
- hexdump(const char* data, size_t len):
- hexdump(reinterpret_cast<const unsigned char*>(data), len)
- {}
-
- hexdump(const unsigned char* data, size_t len):
- mData(data, data + len)
- {}
-
- friend std::ostream& operator<<(std::ostream& out, const hexdump& self)
- {
- auto oldfmt{ out.flags() };
- auto oldfill{ out.fill() };
- out.setf(std::ios_base::hex, std::ios_base::basefield);
- out.fill('0');
- for (auto c : self.mData)
- {
- out << std::setw(2) << unsigned(c);
- }
- out.setf(oldfmt, std::ios_base::basefield);
- out.fill(oldfill);
- return out;
- }
-
-private:
- std::vector<unsigned char> mData;
-};
-
-// Format a given byte string as a mix of printable characters and, for each
-// non-printable character, "\xnn"
-// Usage: std::cout << hexmix(somestring) << ...
-class hexmix
-{
-public:
- hexmix(const std::string_view& data):
- mData(data)
- {}
-
- hexmix(const char* data, size_t len):
- mData(data, len)
- {}
-
- friend std::ostream& operator<<(std::ostream& out, const hexmix& self)
- {
- auto oldfmt{ out.flags() };
- auto oldfill{ out.fill() };
- out.setf(std::ios_base::hex, std::ios_base::basefield);
- out.fill('0');
- for (auto c : self.mData)
- {
- // std::isprint() must be passed an unsigned char!
- if (std::isprint(static_cast<unsigned char>(c)))
- {
- out << c;
- }
- else
- {
- out << "\\x" << std::setw(2) << unsigned(c);
- }
- }
- out.setf(oldfmt, std::ios_base::basefield);
- out.fill(oldfill);
- return out;
- }
-
-private:
- std::string mData;
-};
-
-#endif /* ! defined(LL_HEXDUMP_H) */
diff --git a/indra/test/llassetuploadqueue_tut.cpp b/indra/test/llassetuploadqueue_tut.cpp
deleted file mode 100644
index be5f9e4288..0000000000
--- a/indra/test/llassetuploadqueue_tut.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * @file asset_upload_queue_tut.cpp
- * @brief Tests for newview/llassetuploadqueue.cpp
- *
- * $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 "lltut.h"
-
-#include "mock_http_client.h"
-#include "../newview/llassetuploadqueue.cpp"
-
-// Mock implementation.
-LLAssetUploadResponder::LLAssetUploadResponder(const LLSD& post_data,
- const LLUUID& vfile_id,
- LLAssetType::EType asset_type)
-{
-}
-
-LLAssetUploadResponder::LLAssetUploadResponder(const LLSD& post_data, const std::string& file_name)
-{
-}
-
-LLAssetUploadResponder::~LLAssetUploadResponder()
-{
-}
-
-void LLAssetUploadResponder::httpFailure()
-{
-}
-
-void LLAssetUploadResponder::httpSuccess()
-{
-}
-
-void LLAssetUploadResponder::uploadUpload(const LLSD& content)
-{
-}
-
-void LLAssetUploadResponder::uploadComplete(const LLSD& content)
-{
-}
-
-void LLAssetUploadResponder::uploadFailure(const LLSD& content)
-{
-}
-
-LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
- const LLUUID& vfile_id,
- LLAssetType::EType asset_type) :
- LLAssetUploadResponder(post_data, vfile_id, asset_type)
-{
-}
-
-LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
- const std::string& file_name) :
- LLAssetUploadResponder(post_data, file_name)
-{
-}
-
-LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
- const std::string& file_name,
- const LLUUID& queue_id) :
- LLAssetUploadResponder(post_data, file_name)
-{
-}
-
-void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
-{
-}
-
-namespace tut
-{
- class asset_upload_queue_test_data : public MockHttpClient {};
- typedef test_group<asset_upload_queue_test_data> asset_upload_queue_test;
- typedef asset_upload_queue_test::object asset_upload_queue_object;
- tut::asset_upload_queue_test asset_upload_queue("asset_upload_queue");
-
- void queue(LLAssetUploadQueue& q, const std::string& filename)
- {
- LLUUID task_id;
- LLUUID item_id;
- BOOL is_running = FALSE;
- BOOL is_target_mono = TRUE;
- LLUUID queue_id;
- q.queue(filename, task_id, item_id, is_running, is_target_mono, queue_id);
- }
-
- class LLTestSupplier : public LLAssetUploadQueueSupplier
- {
- public:
-
- void set(LLAssetUploadQueue* queue) {mQueue = queue;}
-
- virtual LLAssetUploadQueue* get() const
- {
- return mQueue;
- }
-
- private:
- LLAssetUploadQueue* mQueue;
- };
-
- template<> template<>
- void asset_upload_queue_object::test<1>()
- {
- setupTheServer();
- reset();
- LLTestSupplier* supplier = new LLTestSupplier();
- LLAssetUploadQueue q("http://localhost:8888/test/success", supplier);
- supplier->set(&q);
- queue(q, "foo.bar");
- ensure("upload queue not empty before request", q.isEmpty());
- runThePump(10);
- ensure("upload queue not empty after request", q.isEmpty());
- }
-
- template<> template<>
- void asset_upload_queue_object::test<2>()
- {
- reset();
- LLTestSupplier* supplier = new LLTestSupplier();
- LLAssetUploadQueue q("http://localhost:8888/test/error", supplier);
- supplier->set(&q);
- queue(q, "foo.bar");
- ensure("upload queue not empty before request", q.isEmpty());
- runThePump(10);
- ensure("upload queue not empty after request", q.isEmpty());
- }
-
- template<> template<>
- void asset_upload_queue_object::test<3>()
- {
- reset();
- LLTestSupplier* supplier = new LLTestSupplier();
- LLAssetUploadQueue q("http://localhost:8888/test/timeout", supplier);
- supplier->set(&q);
- queue(q, "foo.bar");
- ensure("upload queue not empty before request", q.isEmpty());
- runThePump(10);
- ensure("upload queue not empty after request", q.isEmpty());
- }
-
- template<> template<>
- void asset_upload_queue_object::test<4>()
- {
- reset();
- LLTestSupplier* supplier = new LLTestSupplier();
- LLAssetUploadQueue q("http://localhost:8888/test/success", supplier);
- supplier->set(&q);
- queue(q, "foo.bar");
- queue(q, "baz.bar");
- ensure("upload queue empty before request", !q.isEmpty());
- runThePump(10);
- ensure("upload queue not empty before request", q.isEmpty());
- runThePump(10);
- ensure("upload queue not empty after request", q.isEmpty());
- }
-
- template<> template<>
- void asset_upload_queue_object::test<5>()
- {
- reset();
- LLTestSupplier* supplier = new LLTestSupplier();
- LLAssetUploadQueue q("http://localhost:8888/test/success", supplier);
- supplier->set(&q);
- queue(q, "foo.bar");
- runThePump(10);
- ensure("upload queue not empty before request", q.isEmpty());
- queue(q, "baz.bar");
- ensure("upload queue not empty after request", q.isEmpty());
- runThePump(10);
- killServer();
- }
-}
diff --git a/indra/test/lltimestampcache_tut.cpp b/indra/test/lltimestampcache_tut.cpp
deleted file mode 100644
index 857dfe6e6e..0000000000
--- a/indra/test/lltimestampcache_tut.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * @file lltimestampcache_tut.cpp
- * @author James Tess
- * @date 2008-12-03
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include <tut/tut.hpp>
-
-#include "linden_common.h"
-#include "../mapserver/lltimestampcache.h"
-#include "lltut.h"
-
-
-namespace tut
-{
- struct LLTimestampCacheTestData
- {
- };
-
- typedef test_group<LLTimestampCacheTestData> LLTimestampCacheTestGroup;
- typedef LLTimestampCacheTestGroup::object LLTimestampCacheTestObject;
-
- LLTimestampCacheTestGroup timestampCacheTestGroup("LLTimestampCache");
-
- // Most common usage
- template<> template<>
- void LLTimestampCacheTestObject::test<1>()
- {
- LLTimestampCache<std::string, std::string> cache;
- // put in some data
- cache.insert("key1", "val1", 1);
- cache.insert("key2", "val2", 2);
- cache.insert("key3", "val3", 3);
- ensure_equals("size is 3", cache.size(), 3);
- // check some items
- ensure("has key1", cache.has("key1"));
- ensure("no invalid key", !cache.has("invalid key"));
- // get some items
- ensure_equals("get key1", cache.get("key1", 4), "val1");
- ensure_equals("get invalid key",
- cache.get("invalid key", 4), std::string() );
- // timestamps
- ensure_equals("key1 timestamp updated", cache.getTimestamp("key1"), 4);
- ensure_equals("invalid key timestamp",
- cache.getTimestamp("invalid key"), 0);
- }
-
- // New empty cache shouldn't have any entries
- template<> template<>
- void LLTimestampCacheTestObject::test<2>()
- {
- LLTimestampCache<std::string, std::string> cache;
- ensure_equals("starts empty", cache.size(), 0);
- ensure_equals("has nothing", cache.has("foo"), false);
- ensure_equals("gets nothing", cache.get("foo", 0), std::string() );
- U32 max_time = 0xFFFFFFFF;
- ensure_equals("erases nothing", cache.eraseBefore(max_time), 0);
- }
-
- // Non empty cache
- template<> template<>
- void LLTimestampCacheTestObject::test<3>()
- {
- LLTimestampCache<std::string, std::string> cache;
- cache.insert("foo", "bar", 123);
- ensure_equals("size one", cache.size(), 1);
- ensure_equals("has it", cache.has("foo"), true);
- ensure_equals("timestamp correct", cache.getTimestamp("foo"), 123);
- std::string value = cache.get("foo", 456);
- ensure_equals("get value", value, "bar");
- ensure_equals("timestamp updated", cache.getTimestamp("foo"), 456);
- ensure_equals("erase nothing", cache.eraseBefore(0), 0);
- ensure_equals("erase one", cache.eraseBefore(789), 1);
- ensure_equals("empty after erase", cache.size(), 0);
- }
-
- // Recache of item should update timestamp
- template<> template<>
- void LLTimestampCacheTestObject::test<4>()
- {
- LLTimestampCache<std::string, std::string> cache;
- cache.insert("foo", "bar", 123);
- cache.insert("foo", "bar", 456);
- ensure_equals("duplicate suppressed", cache.size(), 1);
- ensure_equals("timestamp replaced", cache.getTimestamp("foo"), 456);
- }
-
- // Erasing some items
- template<> template<>
- void LLTimestampCacheTestObject::test<5>()
- {
- LLTimestampCache<std::string, std::string> cache;
- cache.insert("key1", "val1", 1);
- cache.insert("key2", "val2", 2);
- cache.insert("key3", "val3", 3);
- cache.insert("key4", "val4", 4);
- size_t erased = cache.eraseBefore(3);
- ensure_equals("erase range", erased, 2);
- ensure_equals("cache post erase", cache.size(), 2);
- ensure_equals("has key3", cache.has("key3"), true);
- ensure_equals("not has key2", cache.has("key2"), false);
- }
-}
diff --git a/indra/test/lltranscode_tut.cpp b/indra/test/lltranscode_tut.cpp
deleted file mode 100644
index 23d554d46d..0000000000
--- a/indra/test/lltranscode_tut.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * @file llscriptresource_tut.cpp
- * @brief Test LLScriptResource
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-//#include <tut/tut.h>
-#include "linden_common.h"
-
-#include "lltut.h"
-
-#include "../newsim/lltranscode.cpp" // include TU to pull in newsim implementation.
-
-static const char test_utf8[] = "Edelwei\xc3\x9f";
-static const char test_utf7[] = "Edelwei+AN8-";
-static const char test_latin1[] = "Edelwei\xdf";
-static const char test_latin2[] = "Edelwei\xdf";
-
-namespace tut
-{
- class LLTranscodeTestData
- {
- };
-
- typedef test_group<LLTranscodeTestData> LLTranscodeTestGroup;
- typedef LLTranscodeTestGroup::object LLTranscodeTestObject;
- LLTranscodeTestGroup transcodeTestGroup("transcode");
-
- template<> template<>
- void LLTranscodeTestObject::test<1>()
- {
- // Test utf8
- std::stringstream input;
- std::stringstream output;
-
- input.str(test_utf7);
- output.clear();
- LLTranscode::transcode("charset=UTF-7", input, output);
- ensure_equals("UTF-7 to UTF-8 transcoding", output.str(),
- std::string(test_utf8));
-
- input.str(test_latin1);
- output.clear();
- LLTranscode::transcode("", input, output);
- ensure_equals("Default (latin_1) to UTF8 transcoding", output.str(),
- std::string(test_utf8));
-
- input.str(test_latin1);
- output.clear();
- LLTranscode::transcode("charset=iso-8859-1", input, output);
- ensure_equals("latin_1 (ISO-8859-1) to UTF8 transcoding", output.str(),
- std::string(test_utf8));
-
- input.str(test_latin2);
- output.clear();
- LLTranscode::transcode("charset=iso-8859-2", input, output);
- ensure_equals("latin_2 (ISO-8859-2) to UTF8 transcoding", output.str(),
- std::string(test_utf8));
-
- input.str(test_utf8);
- output.clear();
- LLTranscode::transcode("charset=utf-8", input, output);
- ensure_equals("UTF8 to UTF8 transcoding", output.str(),
- std::string(test_utf8));
- }
-}
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/mock_http_client.cpp b/indra/test/mock_http_client.cpp
deleted file mode 100644
index a97d31c7f4..0000000000
--- a/indra/test/mock_http_client.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * @file mock_http_client.cpp
- * @brief Framework for testing HTTP requests
- *
- * $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 "llhttpnode.h"
-
-namespace tut
-{
- class SuccessNode : public LLHTTPNode
- {
- public:
- void get(ResponsePtr r, const LLSD& context) const
- {
- LLSD result;
- result["state"] = "complete";
- result["test"] = "test";
- r->result(result);
- }
- void post(ResponsePtr r, const LLSD& context, const LLSD& input) const
- {
- LLSD result;
- result["state"] = "complete";
- result["test"] = "test";
- r->result(result);
- }
- };
-
- class ErrorNode : public LLHTTPNode
- {
- public:
- void get(ResponsePtr r, const LLSD& context) const
- { r->status(599, "Intentional error"); }
- void post(ResponsePtr r, const LLSD& context, const LLSD& input) const
- { r->status(input["status"], input["reason"]); }
- };
-
- class TimeOutNode : public LLHTTPNode
- {
- public:
- void get(ResponsePtr r, const LLSD& context) const
- {
- /* do nothing, the request will eventually time out */
- }
- };
-
- LLSD storage;
-
- class LLSDStorageNode : public LLHTTPNode
- {
- public:
- LLSD get() const{ return storage; }
- LLSD put(const LLSD& value) const{ storage = value; return LLSD(); }
- };
-
- LLHTTPRegistration<LLSDStorageNode> gStorageNode("/test/storage");
- LLHTTPRegistration<SuccessNode> gSuccessNode("/test/success");
- LLHTTPRegistration<ErrorNode> gErrorNode("/test/error");
- LLHTTPRegistration<TimeOutNode> gTimeOutNode("/test/timeout");
-}
diff --git a/indra/test/mock_http_client.h b/indra/test/mock_http_client.h
deleted file mode 100644
index ef268abc6e..0000000000
--- a/indra/test/mock_http_client.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/**
- * @file mock_http_client.cpp
- * @brief Framework for testing HTTP requests
- *
- * $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 "llsdhttpserver.h"
-#include "lliohttpserver.h"
-#include "llhttpclient.h"
-#include "llformat.h"
-#include "llpipeutil.h"
-#include "llpumpio.h"
-
-namespace tut
-{
- struct MockHttpClient
- {
- public:
- MockHttpClient()
- {
- apr_pool_create(&mPool, NULL);
- mServerPump = new LLPumpIO(mPool);
- mClientPump = new LLPumpIO(mPool);
-
- LLHTTPClient::setPump(*mClientPump);
- }
-
- ~MockHttpClient()
- {
- delete mServerPump;
- delete mClientPump;
- apr_pool_destroy(mPool);
- }
-
- void setupTheServer()
- {
- LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888);
-
- LLHTTPStandardServices::useServices();
- LLHTTPRegistrar::buildAllServices(root);
- }
-
- void runThePump(float timeout = 100.0f)
- {
- LLTimer timer;
- timer.setTimerExpirySec(timeout);
-
- while(!mSawCompleted && !timer.hasExpired())
- {
- if (mServerPump)
- {
- mServerPump->pump();
- mServerPump->callback();
- }
- if (mClientPump)
- {
- mClientPump->pump();
- mClientPump->callback();
- }
- }
- }
-
- void killServer()
- {
- delete mServerPump;
- mServerPump = NULL;
- }
-
- private:
- apr_pool_t* mPool;
- LLPumpIO* mServerPump;
- LLPumpIO* mClientPump;
-
-
- protected:
- void ensureStatusOK()
- {
- if (mSawError)
- {
- std::string msg =
- llformat("httpFailure() called when not expected, status %d",
- mStatus);
- fail(msg);
- }
- }
-
- void ensureStatusError()
- {
- if (!mSawError)
- {
- fail("httpFailure() wasn't called");
- }
- }
-
- LLSD getResult()
- {
- return mResult;
- }
-
- protected:
- bool mSawError;
- S32 mStatus;
- std::string mReason;
- bool mSawCompleted;
- LLSD mResult;
- bool mResultDeleted;
-
- class Result : public LLHTTPClient::Responder
- {
- protected:
- Result(MockHttpClient& client)
- : mClient(client)
- {
- }
-
- public:
- static boost::intrusive_ptr<Result> build(MockHttpClient& client)
- {
- return boost::intrusive_ptr<Result>(new Result(client));
- }
-
- ~Result()
- {
- mClient.mResultDeleted = true;
- }
-
- protected:
- virtual void httpFailure()
- {
- mClient.mSawError = true;
- mClient.mStatus = getStatus();
- mClient.mReason = getReason();
- }
-
- virtual void httpSuccess()
- {
- mClient.mResult = getContent();
- }
-
- virtual void httpCompleted()
- {
- LLHTTPClient::Responder::httpCompleted();
-
- mClient.mSawCompleted = true;
- }
-
- private:
- MockHttpClient& mClient;
- };
-
- friend class Result;
-
- protected:
-
- void reset()
- {
- mSawError = false;
- mStatus = 0;
- mSawCompleted = false;
- mResult.clear();
- mResultDeleted = false;
- }
-
- LLHTTPClient::ResponderPtr newResult()
- {
- reset();
- return Result::build(*this);
- }
- };
-}
diff --git a/indra/test/namedtempfile.h b/indra/test/namedtempfile.h
index 8027f95728..a38746759f 100644
--- a/indra/test/namedtempfile.h
+++ b/indra/test/namedtempfile.h
@@ -12,26 +12,29 @@
#if ! defined(LL_NAMEDTEMPFILE_H)
#define LL_NAMEDTEMPFILE_H
+#include "fsyspath.h"
#include "llerror.h"
#include "llstring.h"
#include "stringize.h"
#include <string>
-#include <boost/filesystem.hpp>
-#include <boost/filesystem/fstream.hpp>
-#include <boost/noncopyable.hpp>
+#include <fstream>
#include <functional>
#include <iostream>
#include <sstream>
#include <string_view>
+#include <random>
/**
* Create a text file with specified content "somewhere in the
* filesystem," cleaning up when it goes out of scope.
*/
-class NamedTempFile: public boost::noncopyable
+class NamedTempFile
{
LOG_CLASS(NamedTempFile);
public:
+ NamedTempFile(const NamedTempFile&) = delete;
+ NamedTempFile& operator=(const NamedTempFile&) = delete;
+
NamedTempFile(const std::string_view& pfx,
const std::string_view& content,
const std::string_view& sfx=std::string_view(""))
@@ -62,16 +65,16 @@ public:
virtual ~NamedTempFile()
{
- boost::filesystem::remove(mPath);
+ std::filesystem::remove(mPath);
}
- std::string getName() const { return mPath.string(); }
+ const std::filesystem::path& getPath() const { return mPath; }
template <typename CALLABLE>
void peep_via(CALLABLE&& callable) const
{
std::forward<CALLABLE>(callable)(stringize("File '", mPath, "' contains:"));
- boost::filesystem::ifstream reader(mPath, std::ios::binary);
+ std::ifstream reader(mPath, std::ios::binary);
std::string line;
while (std::getline(reader, line))
std::forward<CALLABLE>(callable)(line);
@@ -94,23 +97,27 @@ public:
return out;
}
- static boost::filesystem::path temp_path(const std::string_view& pfx="",
+ static std::filesystem::path temp_path(const std::string_view& pfx="",
const std::string_view& sfx="")
{
// This variable is set by GitHub actions and is the recommended place
// to put temp files belonging to an actions job.
const char* RUNNER_TEMP = getenv("RUNNER_TEMP");
- boost::filesystem::path tempdir{
+ std::filesystem::path tempdir{
// if RUNNER_TEMP is set and not empty
(RUNNER_TEMP && *RUNNER_TEMP)?
- boost::filesystem::path(RUNNER_TEMP) : // use RUNNER_TEMP if available
- boost::filesystem::temp_directory_path()}; // else canonical temp dir
- boost::filesystem::path tempname{
- // use filename template recommended by unique_path() doc, but
- // with underscores instead of hyphens: some use cases involve
- // temporary Python scripts
- tempdir / stringize(pfx, "%%%%_%%%%_%%%%_%%%%", sfx) };
- return boost::filesystem::unique_path(tempname);
+ fsyspath::path(RUNNER_TEMP) : // use RUNNER_TEMP if available
+ std::filesystem::temp_directory_path()}; // else canonical temp dir
+
+ static std::mt19937 random_generator{std::random_device{}()};
+ static std::uniform_int_distribution<> distribution{0, std::numeric_limits<uint8_t>::max()};
+ std::string tempname{};
+ static constexpr auto num_bits = 128;
+ for (auto i = 0; i < (num_bits / std::numeric_limits<uint8_t>::digits); ++i) {
+ tempname += llformat("%02x", distribution(random_generator));
+ }
+ tempname = std::string(pfx) + tempname + std::string(sfx);
+ return tempdir / tempname;
}
protected:
@@ -120,12 +127,12 @@ protected:
{
// Create file in a temporary place.
mPath = temp_path(pfx, sfx);
- boost::filesystem::ofstream out{ mPath, std::ios::binary };
+ std::ofstream out{ mPath, std::ios::binary };
// Write desired content.
func(out);
}
- boost::filesystem::path mPath;
+ std::filesystem::path mPath;
};
/**
diff --git a/indra/test/prim_linkability_tut.cpp b/indra/test/prim_linkability_tut.cpp
deleted file mode 100644
index 3603b25f18..0000000000
--- a/indra/test/prim_linkability_tut.cpp
+++ /dev/null
@@ -1,495 +0,0 @@
-/**
- * @file linkability.cpp
- * @author andrew@lindenlab.com
- * @date 2007-04-23
- * @brief Tests for the LLPrimLinkInfo template which computes the linkability of prims
- *
- * $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 "lltut.h"
-#include "llprimlinkinfo.h"
-#include "llrand.h"
-
-
-// helper function
-void randomize_sphere(LLSphere& sphere, F32 center_range, F32 radius_range)
-{
- F32 radius = ll_frand(2.f * radius_range) - radius_range;
- LLVector3 center;
- for (S32 i=0; i<3; ++i)
- {
- center.mV[i] = ll_frand(2.f * center_range) - center_range;
- }
- sphere.setRadius(radius);
- sphere.setCenter(center);
-}
-
-// helper function. Same as above with a min and max radius.
-void randomize_sphere(LLSphere& sphere, F32 center_range, F32 minimum_radius, F32 maximum_radius)
-{
- F32 radius = ll_frand(maximum_radius - minimum_radius) + minimum_radius;
- LLVector3 center;
- for (S32 i=0; i<3; ++i)
- {
- center.mV[i] = ll_frand(2.f * center_range) - center_range;
- }
- sphere.setRadius(radius);
- sphere.setCenter(center);
-}
-
-// helper function
-bool random_sort( const LLPrimLinkInfo< S32 >&, const LLPrimLinkInfo< S32 >& b)
-{
- return (ll_rand(64) < 32);
-}
-
-namespace tut
-{
- struct linkable_data
- {
- LLPrimLinkInfo<S32> info;
- };
-
- typedef test_group<linkable_data> linkable_test;
- typedef linkable_test::object linkable_object;
- tut::linkable_test wtf("prim linkability");
-
- template<> template<>
- void linkable_object::test<1>()
- {
- // Here we test the boundary of the LLPrimLinkInfo::canLink() method
- // between semi-random middle-sized objects.
-
- S32 number_of_tests = 100;
- for (S32 test = 0; test < number_of_tests; ++test)
- {
- // compute the radii that would provide the above max link distance
- F32 first_radius = 0.f;
- F32 second_radius = 0.f;
-
- // compute a random center for the first sphere
- // compute some random max link distance
- F32 max_link_span = ll_frand(MAX_OBJECT_SPAN);
- if (max_link_span < OBJECT_SPAN_BONUS)
- {
- max_link_span += OBJECT_SPAN_BONUS;
- }
- LLVector3 first_center(
- ll_frand(2.f * max_link_span) - max_link_span,
- ll_frand(2.f * max_link_span) - max_link_span,
- ll_frand(2.f * max_link_span) - max_link_span);
-
- // put the second sphere at the right distance from the origin
- // such that it is within the max_link_distance of the first
- LLVector3 direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
- direction.normalize();
- F32 half_milimeter = 0.0005f;
- LLVector3 second_center;
-
- // max_span = 3 * (first_radius + second_radius) + OBJECT_SPAN_BONUS
- // make sure they link at short distances
- {
- second_center = first_center + (OBJECT_SPAN_BONUS - half_milimeter) * direction;
- LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) );
- LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) );
- ensure("these nearby objects should link", first_info.canLink(second_info) );
- }
-
- // make sure they fail to link if we move them apart just a little bit
- {
- second_center = first_center + (OBJECT_SPAN_BONUS + half_milimeter) * direction;
- LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) );
- LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) );
- ensure("these nearby objects should NOT link", !first_info.canLink(second_info) );
- }
-
- // make sure the objects link or not at medium distances
- {
- first_radius = 0.3f * ll_frand(max_link_span - OBJECT_SPAN_BONUS);
-
- // This is the exact second radius that will link at exactly our random max_link_distance
- second_radius = ((max_link_span - OBJECT_SPAN_BONUS) / 3.f) - first_radius;
- second_center = first_center + (max_link_span - first_radius - second_radius - half_milimeter) * direction;
-
- LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) );
- LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) );
-
- ensure("these objects should link", first_info.canLink(second_info) );
- }
-
- // make sure they fail to link if we move them apart just a little bit
- {
- // move the second sphere such that it is a little too far from the first
- second_center += (2.f * half_milimeter) * direction;
- LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) );
- LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) );
-
- ensure("these objects should NOT link", !first_info.canLink(second_info) );
- }
-
- // make sure things don't link at far distances
- {
- second_center = first_center + (MAX_OBJECT_SPAN + 2.f * half_milimeter) * direction;
- second_radius = 0.3f * MAX_OBJECT_SPAN;
- LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) );
- LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) );
- ensure("these objects should NOT link", !first_info.canLink(second_info) );
- }
-
- }
- }
-
- template<> template<>
- void linkable_object::test<2>()
- {
-
- // Consider a row of eight spheres in a row, each 10m in diameter and centered
- // at 10m intervals: 01234567.
-
- F32 radius = 5.f;
- F32 spacing = 10.f;
-
- LLVector3 line_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
- line_direction.normalize();
-
- LLVector3 first_center(ll_frand(2.f * spacing) -spacing, ll_frand(2.f * spacing) - spacing, ll_frand(2.f * spacing) - spacing);
-
- LLPrimLinkInfo<S32> infos[8];
-
- for (S32 index = 0; index < 8; ++index)
- {
- LLVector3 center = first_center + ((F32)(index) * spacing) * line_direction;
- infos[index].set(index, LLSphere(center, radius));
- }
-
- // Max span for 2 spheres of 5m radius is 3 * (5 + 5) + 1 = 31m
- // spheres 0&2 have a 30m span (from outside edge to outside edge) and should link
- {
- LLPrimLinkInfo<S32> root_info = infos[0];
- std::list< LLPrimLinkInfo<S32> > info_list;
- info_list.push_back(infos[2]);
- root_info.mergeLinkableSet(info_list);
- S32 prim_count = root_info.getPrimCount();
- ensure_equals("0&2 prim count should be 2", prim_count, 2);
- ensure_equals("0&2 unlinkable list should have length 0", (S32) info_list.size(), 0);
- }
-
-
- // spheres 0&3 have a 40 meter span and should NOT link outright
- {
- LLPrimLinkInfo<S32> root_info = infos[0];
- std::list< LLPrimLinkInfo<S32> > info_list;
- info_list.push_back(infos[3]);
- root_info.mergeLinkableSet(info_list);
- S32 prim_count = root_info.getPrimCount();
- ensure_equals("0&4 prim count should be 1", prim_count, 1);
- ensure_equals("0&4 unlinkable list should have length 1", (S32) info_list.size(), 1);
- }
-
-
- // spheres 0-4 should link no matter what order : 01234
- // Total span = 50m, 012 link with a r=15.5 giving max span of 3 * (15.5 + 5) + 1 = 62.5, but the cap is 54m
- {
- LLPrimLinkInfo<S32> root_info = infos[0];
- std::list< LLPrimLinkInfo<S32> > info_list;
- for (S32 index = 1; index < 5; ++index)
- {
- info_list.push_back(infos[index]);
- }
- root_info.mergeLinkableSet(info_list);
- S32 prim_count = root_info.getPrimCount();
- ensure_equals("01234 prim count should be 5", prim_count, 5);
- ensure_equals("01234 unlinkable list should have length 0", (S32) info_list.size(), 0);
- }
-
-
- // spheres 0-5 should link no matter what order : 04321
- {
- LLPrimLinkInfo<S32> root_info = infos[0];
- std::list< LLPrimLinkInfo<S32> > info_list;
- for (S32 index = 4; index > 0; --index)
- {
- info_list.push_back(infos[index]);
- }
- root_info.mergeLinkableSet(info_list);
- S32 prim_count = root_info.getPrimCount();
- ensure_equals("04321 prim count should be 5", prim_count, 5);
- ensure_equals("04321 unlinkable list should have length 0", (S32) info_list.size(), 0);
- }
-
- // spheres 0-4 should link no matter what order : 01423
- {
- LLPrimLinkInfo<S32> root_info = infos[0];
- std::list< LLPrimLinkInfo<S32> > info_list;
- info_list.push_back(infos[1]);
- info_list.push_back(infos[4]);
- info_list.push_back(infos[2]);
- info_list.push_back(infos[3]);
- root_info.mergeLinkableSet(info_list);
- S32 prim_count = root_info.getPrimCount();
- ensure_equals("01423 prim count should be 5", prim_count, 5);
- ensure_equals("01423 unlinkable list should have length 0", (S32) info_list.size(), 0);
- }
-
- // spheres 0-5 should NOT fully link, only 0-4
- {
- LLPrimLinkInfo<S32> root_info = infos[0];
- std::list< LLPrimLinkInfo<S32> > info_list;
- for (S32 index = 1; index < 6; ++index)
- {
- info_list.push_back(infos[index]);
- }
- root_info.mergeLinkableSet(info_list);
- S32 prim_count = root_info.getPrimCount();
- ensure_equals("012345 prim count should be 5", prim_count, 5);
- ensure_equals("012345 unlinkable list should have length 1", (S32) info_list.size(), 1);
- std::list< LLPrimLinkInfo<S32> >::iterator info_itr = info_list.begin();
- if (info_itr != info_list.end())
- {
- // examine the contents of the unlinked info
- std::list<S32> unlinked_indecies;
- info_itr->getData(unlinked_indecies);
- // make sure there is only one index in the unlinked_info
- ensure_equals("012345 unlinkable index count should be 1", (S32) unlinked_indecies.size(), 1);
- // make sure its value is 6
- std::list<S32>::iterator unlinked_index_itr = unlinked_indecies.begin();
- S32 unlinkable_index = *unlinked_index_itr;
- ensure_equals("012345 unlinkable index should be 5", (S32) unlinkable_index, 5);
- }
- }
-
- // spheres 0-7 should NOT fully link, only 0-5
- {
- LLPrimLinkInfo<S32> root_info = infos[0];
- std::list< LLPrimLinkInfo<S32> > info_list;
- for (S32 index = 1; index < 8; ++index)
- {
- info_list.push_back(infos[index]);
- }
- root_info.mergeLinkableSet(info_list);
- S32 prim_count = root_info.getPrimCount();
- ensure_equals("01234567 prim count should be 5", prim_count, 5);
- // Should be 1 linkinfo on unlinkable that has 2 prims
- ensure_equals("01234567 unlinkable list should have length 1", (S32) info_list.size(), 1);
- std::list< LLPrimLinkInfo<S32> >::iterator info_itr = info_list.begin();
- if (info_itr != info_list.end())
- {
- // make sure there is only one index in the unlinked_info
- std::list<S32> unlinked_indecies;
- info_itr->getData(unlinked_indecies);
- ensure_equals("0123456 unlinkable index count should be 3", (S32) unlinked_indecies.size(), 3);
-
- // make sure its values are 6 and 7
- std::list<S32>::iterator unlinked_index_itr = unlinked_indecies.begin();
- S32 unlinkable_index = *unlinked_index_itr;
- ensure_equals("0123456 first unlinkable index should be 5", (S32) unlinkable_index, 5);
- ++unlinked_index_itr;
- unlinkable_index = *unlinked_index_itr;
- ensure_equals("0123456 second unlinkable index should be 6", (S32) unlinkable_index, 6);
- ++unlinked_index_itr;
- unlinkable_index = *unlinked_index_itr;
- ensure_equals("0123456 third unlinkable index should be 7", (S32) unlinkable_index, 7);
-
- }
- }
- }
-
- template<> template<>
- void linkable_object::test<3>()
- {
- // Here we test the link results between an LLPrimLinkInfo and a set of
- // randomized LLPrimLinkInfos where the expected results are known.
- S32 number_of_tests = 5;
- for (S32 test = 0; test < number_of_tests; ++test)
- {
- // the radii are known
- F32 first_radius = 1.f;
- F32 second_radius = 2.f;
- F32 third_radius = 3.f;
-
- // compute the distances
- F32 half_milimeter = 0.0005f;
- F32 max_first_second_span = 3.f * (first_radius + second_radius) + OBJECT_SPAN_BONUS;
- F32 linkable_distance = max_first_second_span - first_radius - second_radius - half_milimeter;
-
- F32 max_full_span = 3.f * (0.5f * max_first_second_span + third_radius) + OBJECT_SPAN_BONUS;
- F32 unlinkable_distance = max_full_span - 0.5f * linkable_distance - third_radius + half_milimeter;
-
- // compute some random directions
- LLVector3 first_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
- first_direction.normalize();
- LLVector3 second_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
- second_direction.normalize();
- LLVector3 third_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f);
- third_direction.normalize();
-
- // compute the centers
- LLVector3 first_center = ll_frand(10.f) * first_direction;
- LLVector3 second_center = first_center + ll_frand(linkable_distance) * second_direction;
- LLVector3 first_join_center = 0.5f * (first_center + second_center);
- LLVector3 third_center = first_join_center + unlinkable_distance * third_direction;
-
- // make sure the second info links and the third does not
- {
- // initialize the infos
- S32 index = 0;
- LLPrimLinkInfo<S32> first_info(index++, LLSphere(first_center, first_radius));
- LLPrimLinkInfo<S32> second_info(index++, LLSphere(second_center, second_radius));
- LLPrimLinkInfo<S32> third_info(index++, LLSphere(third_center, third_radius));
-
- // put the second and third infos in a list
- std::list< LLPrimLinkInfo<S32> > info_list;
- info_list.push_back(second_info);
- info_list.push_back(third_info);
-
- // merge the list with the first_info
- first_info.mergeLinkableSet(info_list);
- S32 prim_count = first_info.getPrimCount();
-
- ensure_equals("prim count should be 2", prim_count, 2);
- ensure_equals("unlinkable list should have length 1", (S32) info_list.size(), 1);
- }
-
- // reverse the order and make sure we get the same results
- {
- // initialize the infos
- S32 index = 0;
- LLPrimLinkInfo<S32> first_info(index++, LLSphere(first_center, first_radius));
- LLPrimLinkInfo<S32> second_info(index++, LLSphere(second_center, second_radius));
- LLPrimLinkInfo<S32> third_info(index++, LLSphere(third_center, third_radius));
-
- // build the list in the reverse order
- std::list< LLPrimLinkInfo<S32> > info_list;
- info_list.push_back(third_info);
- info_list.push_back(second_info);
-
- // merge the list with the first_info
- first_info.mergeLinkableSet(info_list);
- S32 prim_count = first_info.getPrimCount();
-
- ensure_equals("prim count should be 2", prim_count, 2);
- ensure_equals("unlinkable list should have length 1", (S32) info_list.size(), 1);
- }
- }
- }
-
- template<> template<>
- void linkable_object::test<4>()
- {
- // Here we test whether linkability is invarient under permutations
- // of link order. To do this we generate a bunch of random spheres
- // and then try to link them in different ways.
- //
- // NOTE: the linkability will only be invarient if there is only one
- // linkable solution. Multiple solutions will exist if the set of
- // candidates are larger than the maximum linkable distance, or more
- // numerous than a single linked object can contain. This is easily
- // understood by considering a very large set of link candidates,
- // and first linking preferentially to the left until linking fails,
- // then doing the same to the right -- the final solutions will differ.
- // Hence for this test we must generate candidate sets that lie within
- // the linkability envelope of a single object.
- //
- // NOTE: a random set of objects will tend to either be totally linkable
- // or totally not. That is, the random orientations that
-
- F32 root_center_range = 0.f;
- F32 min_prim_radius = 0.1f;
- F32 max_prim_radius = 2.f;
-
- // Linkability is min(MAX_OBJECT_SPAN,3 *( R1 + R2 ) + BONUS)
- // 3 * (min_prim_radius + min_prim_radius) + OBJECT_SPAN_BONUS = 6 * min_prim_radius + OBJECT_SPAN_BONUS;
- // Use .45 instead of .5 to gaurantee objects are within the minimum span.
- F32 child_center_range = 0.45f * ( (6*min_prim_radius) + OBJECT_SPAN_BONUS );
-
- S32 number_of_tests = 100;
- S32 number_of_spheres = 10;
- S32 number_of_scrambles = 10;
- S32 number_of_random_bubble_sorts = 10;
-
- for (S32 test = 0; test < number_of_tests; ++test)
- {
- LLSphere sphere;
- S32 sphere_index = 0;
-
- // build the root piece
- randomize_sphere(sphere, root_center_range, min_prim_radius, max_prim_radius);
- info.set( sphere_index++, sphere );
-
- // build the unlinked pieces
- std::list< LLPrimLinkInfo<S32> > info_list;
- for (; sphere_index < number_of_spheres; ++sphere_index)
- {
- randomize_sphere(sphere, child_center_range, min_prim_radius, max_prim_radius);
- LLPrimLinkInfo<S32> child_info( sphere_index, sphere );
- info_list.push_back(child_info);
- }
-
- // declare the variables used to store the results
- std::list<S32> first_linked_list;
-
- {
- // the link attempt will modify our original info's, so we
- // have to make copies of the originals for testing
- LLPrimLinkInfo<S32> test_info( 0, LLSphere(info.getCenter(), 0.5f * info.getDiameter()) );
- std::list< LLPrimLinkInfo<S32> > test_list;
- test_list.assign(info_list.begin(), info_list.end());
-
- // try to link
- test_info.mergeLinkableSet(test_list);
-
- ensure("All prims should link, but did not.",test_list.empty());
-
- // store the results
- test_info.getData(first_linked_list);
- first_linked_list.sort();
- }
-
- // try to link the spheres in various random orders
- for (S32 scramble = 0; scramble < number_of_scrambles; ++scramble)
- {
- LLPrimLinkInfo<S32> test_info(0, LLSphere(info.getCenter(), 0.5f * info.getDiameter()) );
-
- // scramble the order of the info_list
- std::list< LLPrimLinkInfo<S32> > test_list;
- test_list.assign(info_list.begin(), info_list.end());
- for (S32 i = 0; i < number_of_random_bubble_sorts; i++)
- {
- test_list.sort(random_sort);
- }
-
- // try to link
- test_info.mergeLinkableSet(test_list);
-
- // get the results
- std::list<S32> linked_list;
- test_info.getData(linked_list);
- linked_list.sort();
-
- ensure_equals("linked set size should be order independent",linked_list.size(),first_linked_list.size());
- }
- }
- }
-}
-
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index d32388cd45..cee8b84438 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -46,13 +46,6 @@
#include "apr_pools.h"
#include "apr_getopt.h"
-// the CTYPE_WORKAROUND is needed for linux dev stations that don't
-// have the broken libc6 packages needed by our out-of-date static
-// libs (such as libcrypto and libcurl). -- Leviathan 20060113
-#ifdef CTYPE_WORKAROUND
-# include "ctype_workaround.h"
-#endif
-
#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/stream.hpp>
@@ -86,7 +79,7 @@ public:
RecordToTempFile()
: LLError::Recorder(),
mTempFile("log", ""),
- mFile(mTempFile.getName().c_str())
+ mFile(mTempFile.getPath())
{
}
@@ -104,13 +97,13 @@ public:
void reset()
{
mFile.close();
- mFile.open(mTempFile.getName().c_str());
+ mFile.open(mTempFile.getPath());
}
void replay(std::ostream& out)
{
mFile.close();
- std::ifstream inf(mTempFile.getName().c_str());
+ llifstream inf(mTempFile.getPath());
std::string line;
while (std::getline(inf, line))
{
@@ -316,122 +309,6 @@ protected:
std::shared_ptr<LLReplayLog> mReplayer;
};
-// TeamCity specific class which emits service messages
-// http://confluence.jetbrains.net/display/TCD3/Build+Script+Interaction+with+TeamCity;#BuildScriptInteractionwithTeamCity-testReporting
-
-class LLTCTestCallback : public LLTestCallback
-{
-public:
- LLTCTestCallback(bool verbose_mode, std::ostream *stream,
- std::shared_ptr<LLReplayLog> replayer) :
- LLTestCallback(verbose_mode, stream, replayer)
- {
- }
-
- ~LLTCTestCallback()
- {
- }
-
- virtual void group_started(const std::string& name) {
- LLTestCallback::group_started(name);
- std::cout << "\n##teamcity[testSuiteStarted name='" << escape(name) << "']" << std::endl;
- }
-
- virtual void group_completed(const std::string& name) {
- LLTestCallback::group_completed(name);
- std::cout << "##teamcity[testSuiteFinished name='" << escape(name) << "']" << std::endl;
- }
-
- virtual void test_completed(const tut::test_result& tr)
- {
- std::string testname(STRINGIZE(tr.group << "." << tr.test));
- if (! tr.name.empty())
- {
- testname.append(":");
- testname.append(tr.name);
- }
- testname = escape(testname);
-
- // Sadly, tut::callback doesn't give us control at test start; have to
- // backfill start message into TC output.
- std::cout << "##teamcity[testStarted name='" << testname << "']" << std::endl;
-
- // now forward call to base class so any output produced there is in
- // the right TC context
- LLTestCallback::test_completed(tr);
-
- switch(tr.result)
- {
- case tut::test_result::ok:
- break;
-
- case tut::test_result::fail:
- case tut::test_result::ex:
- case tut::test_result::warn:
- case tut::test_result::term:
- std::cout << "##teamcity[testFailed name='" << testname
- << "' message='" << escape(tr.message) << "']" << std::endl;
- break;
-
- case tut::test_result::skip:
- std::cout << "##teamcity[testIgnored name='" << testname << "']" << std::endl;
- break;
-
- default:
- break;
- }
-
- std::cout << "##teamcity[testFinished name='" << testname << "']" << std::endl;
- }
-
- static std::string escape(const std::string& str)
- {
- // Per http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ServiceMessages
- std::string result;
- for (char c : str)
- {
- switch (c)
- {
- case '\'':
- result.append("|'");
- break;
- case '\n':
- result.append("|n");
- break;
- case '\r':
- result.append("|r");
- break;
-/*==========================================================================*|
- // These are not possible 'char' values from a std::string.
- case '\u0085': // next line
- result.append("|x");
- break;
- case '\u2028': // line separator
- result.append("|l");
- break;
- case '\u2029': // paragraph separator
- result.append("|p");
- break;
-|*==========================================================================*/
- case '|':
- result.append("||");
- break;
- case '[':
- result.append("|[");
- break;
- case ']':
- result.append("|]");
- break;
- default:
- result.push_back(c);
- break;
- }
- }
- return result;
- }
-};
-
-
static const apr_getopt_option_t TEST_CL_OPTIONS[] =
{
{"help", 'h', 0, "Print the help message."},
@@ -509,6 +386,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))
@@ -614,10 +496,6 @@ int main(int argc, char **argv)
LLFile::remove(test_log);
LLError::logToFile(test_log);
-#ifdef CTYPE_WORKAROUND
- ctype_workaround();
-#endif
-
if (!sMasterThreadRecorder)
{
sMasterThreadRecorder = new LLTrace::ThreadRecorder();
@@ -626,15 +504,7 @@ int main(int argc, char **argv)
// run the tests
- LLTestCallback* mycallback;
- if (getenv("TEAMCITY_PROJECT_NAME"))
- {
- mycallback = new LLTCTestCallback(verbose_mode, output.get(), replayer);
- }
- else
- {
- mycallback = new LLTestCallback(verbose_mode, output.get(), replayer);
- }
+ LLTestCallback* mycallback = new LLTestCallback(verbose_mode, output.get(), replayer);
// a chained_callback subclass must be linked with previous
mycallback->link();
diff --git a/scripts/code_tools/fix_whitespace.py b/scripts/code_tools/fix_whitespace.py
index d5f7ce1cce..d5f7ce1cce 100644..100755
--- a/scripts/code_tools/fix_whitespace.py
+++ b/scripts/code_tools/fix_whitespace.py
diff --git a/scripts/code_tools/fix_xml_indentations.py b/scripts/code_tools/fix_xml_indentations.py
index a196b0b7d4..a196b0b7d4 100644..100755
--- a/scripts/code_tools/fix_xml_indentations.py
+++ b/scripts/code_tools/fix_xml_indentations.py
diff --git a/scripts/code_tools/modified-strings.sh b/scripts/code_tools/modified-strings.sh
index 932b0a4bfc..932b0a4bfc 100644..100755
--- a/scripts/code_tools/modified-strings.sh
+++ b/scripts/code_tools/modified-strings.sh
diff --git a/scripts/code_tools/modified_strings.py b/scripts/code_tools/modified_strings.py
index c777fc8c0d..c777fc8c0d 100644..100755
--- a/scripts/code_tools/modified_strings.py
+++ b/scripts/code_tools/modified_strings.py
diff --git a/scripts/content_tools/anim_tool.py b/scripts/content_tools/anim_tool.py
index 07159a8052..07159a8052 100644..100755
--- a/scripts/content_tools/anim_tool.py
+++ b/scripts/content_tools/anim_tool.py
diff --git a/scripts/content_tools/arche_tool.py b/scripts/content_tools/arche_tool.py
index 9979c61b21..9979c61b21 100644..100755
--- a/scripts/content_tools/arche_tool.py
+++ b/scripts/content_tools/arche_tool.py
diff --git a/scripts/content_tools/dae_tool.py b/scripts/content_tools/dae_tool.py
index 5286c37de3..5286c37de3 100644..100755
--- a/scripts/content_tools/dae_tool.py
+++ b/scripts/content_tools/dae_tool.py
diff --git a/scripts/content_tools/skel_tool.py b/scripts/content_tools/skel_tool.py
index 604d2b7db9..604d2b7db9 100644..100755
--- a/scripts/content_tools/skel_tool.py
+++ b/scripts/content_tools/skel_tool.py
diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg
index 40ba2cc6b6..40ba2cc6b6 100755..100644
--- a/scripts/messages/message_template.msg
+++ b/scripts/messages/message_template.msg
diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1
index baa4f3f12b..baa4f3f12b 100755..100644
--- a/scripts/messages/message_template.msg.sha1
+++ b/scripts/messages/message_template.msg.sha1
diff --git a/scripts/metrics/slp_conv.py b/scripts/metrics/slp_conv.py
index 25f9a8c060..25f9a8c060 100644..100755
--- a/scripts/metrics/slp_conv.py
+++ b/scripts/metrics/slp_conv.py
diff --git a/scripts/metrics/viewer_asset_logs.py b/scripts/metrics/viewer_asset_logs.py
index 4fb9fd15b3..4fb9fd15b3 100644..100755
--- a/scripts/metrics/viewer_asset_logs.py
+++ b/scripts/metrics/viewer_asset_logs.py
diff --git a/scripts/perf/logsdir.py b/scripts/perf/logsdir.py
index 5ab45a28b6..5ab45a28b6 100644..100755
--- a/scripts/perf/logsdir.py
+++ b/scripts/perf/logsdir.py
diff --git a/scripts/perf/perfbot_run.py b/scripts/perf/perfbot_run.py
index 55ea2fae66..55ea2fae66 100644..100755
--- a/scripts/perf/perfbot_run.py
+++ b/scripts/perf/perfbot_run.py
diff --git a/scripts/perf/profile_cmp.py b/scripts/perf/profile_cmp.py
index 9dbfa3145b..9dbfa3145b 100644..100755
--- a/scripts/perf/profile_cmp.py
+++ b/scripts/perf/profile_cmp.py
diff --git a/scripts/perf/profile_csv.py b/scripts/perf/profile_csv.py
index 7a6b2b338e..7a6b2b338e 100644..100755
--- a/scripts/perf/profile_csv.py
+++ b/scripts/perf/profile_csv.py
diff --git a/scripts/perf/profile_pretty.py b/scripts/perf/profile_pretty.py
index 405b14b373..405b14b373 100644..100755
--- a/scripts/perf/profile_pretty.py
+++ b/scripts/perf/profile_pretty.py
diff --git a/scripts/templates/template-cpp.cpp b/scripts/templates/template-cpp.cpp
index 8ee04942bf..8ee04942bf 100755..100644
--- a/scripts/templates/template-cpp.cpp
+++ b/scripts/templates/template-cpp.cpp
diff --git a/scripts/templates/template-h.h b/scripts/templates/template-h.h
index d7677c256b..d7677c256b 100755..100644
--- a/scripts/templates/template-h.h
+++ b/scripts/templates/template-h.h