summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.gitignore1
-rw-r--r--autobuild.xml68
-rwxr-xr-xbuild.sh12
-rwxr-xr-xdoc/contributions.txt5
-rw-r--r--indra/cmake/00-Common.cmake13
-rw-r--r--indra/cmake/Copy3rdPartyLibs.cmake2
-rw-r--r--indra/cmake/LLCommon.cmake5
-rw-r--r--indra/cmake/Tracy.cmake29
-rw-r--r--indra/edit-me-to-trigger-new-build.txt1
-rw-r--r--indra/llappearance/llavatarappearance.cpp2
-rw-r--r--indra/llappearance/lldriverparam.h114
-rw-r--r--indra/llappearance/llpolymorph.cpp4
-rw-r--r--indra/llappearance/llpolymorph.h29
-rw-r--r--indra/llappearance/llpolyskeletaldistortion.cpp4
-rw-r--r--indra/llappearance/llpolyskeletaldistortion.h30
-rw-r--r--indra/llappearance/lltexlayer.cpp21
-rw-r--r--indra/llappearance/lltexlayerparams.cpp3
-rw-r--r--indra/llappearance/lltexlayerparams.h31
-rw-r--r--indra/llcharacter/llcharacter.cpp8
-rw-r--r--indra/llcharacter/lleditingmotion.cpp1
-rw-r--r--indra/llcharacter/lleditingmotion.h18
-rw-r--r--indra/llcharacter/llhandmotion.cpp1
-rw-r--r--indra/llcharacter/llheadrotmotion.cpp2
-rw-r--r--indra/llcharacter/lljoint.cpp8
-rw-r--r--indra/llcharacter/lljoint.h16
-rw-r--r--indra/llcharacter/llkeyframefallmotion.cpp1
-rw-r--r--indra/llcharacter/llkeyframemotion.cpp1
-rw-r--r--indra/llcharacter/llkeyframemotionparam.cpp1
-rw-r--r--indra/llcharacter/llkeyframestandmotion.h28
-rw-r--r--indra/llcharacter/llkeyframewalkmotion.cpp3
-rw-r--r--indra/llcharacter/llmotioncontroller.cpp10
-rw-r--r--indra/llcharacter/llpose.h6
-rw-r--r--indra/llcharacter/lltargetingmotion.cpp1
-rw-r--r--indra/llcommon/CMakeLists.txt12
-rw-r--r--indra/llcommon/chrono.h65
-rw-r--r--indra/llcommon/linden_common.h8
-rw-r--r--indra/llcommon/llcommon.cpp60
-rw-r--r--indra/llcommon/llcond.h24
-rw-r--r--indra/llcommon/lldate.cpp6
-rw-r--r--indra/llcommon/llerror.cpp12
-rw-r--r--indra/llcommon/llerror.h5
-rw-r--r--indra/llcommon/llerrorcontrol.h1
-rw-r--r--indra/llcommon/lleventfilter.h2
-rw-r--r--indra/llcommon/llfasttimer.cpp49
-rw-r--r--indra/llcommon/llfasttimer.h3
-rw-r--r--indra/llcommon/llframetimer.cpp5
-rw-r--r--indra/llcommon/llinstancetracker.h59
-rw-r--r--indra/llcommon/llleaplistener.cpp2
-rw-r--r--indra/llcommon/llmemory.cpp2
-rw-r--r--indra/llcommon/llmemory.h90
-rw-r--r--indra/llcommon/llmutex.cpp12
-rw-r--r--indra/llcommon/llprofiler.h111
-rw-r--r--indra/llcommon/llsd.cpp32
-rw-r--r--indra/llcommon/llsd.h12
-rw-r--r--indra/llcommon/llsdparam.cpp2
-rw-r--r--indra/llcommon/llsdparam.h3
-rw-r--r--indra/llcommon/llsdutil.cpp22
-rw-r--r--indra/llcommon/llsingleton.h27
-rw-r--r--indra/llcommon/llstring.cpp7
-rw-r--r--indra/llcommon/llsys.cpp5
-rw-r--r--indra/llcommon/llthread.cpp9
-rw-r--r--indra/llcommon/llthreadsafequeue.h514
-rw-r--r--indra/llcommon/lltrace.cpp1
-rw-r--r--indra/llcommon/lltrace.h148
-rw-r--r--indra/llcommon/lltraceaccumulators.cpp14
-rw-r--r--indra/llcommon/lltraceaccumulators.h19
-rw-r--r--indra/llcommon/lltracerecording.cpp136
-rw-r--r--indra/llcommon/lltracerecording.h50
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp4
-rw-r--r--indra/llcommon/lluuid.h11
-rw-r--r--indra/llcommon/tests/llinstancetracker_test.cpp14
-rw-r--r--indra/llcommon/tests/llprocess_test.cpp32
-rw-r--r--indra/llcommon/tests/threadsafeschedule_test.cpp69
-rw-r--r--indra/llcommon/tests/tuple_test.cpp47
-rw-r--r--indra/llcommon/tests/workqueue_test.cpp159
-rw-r--r--indra/llcommon/threadsafeschedule.h373
-rw-r--r--indra/llcommon/tuple.h84
-rw-r--r--indra/llcommon/workqueue.cpp130
-rw-r--r--indra/llcommon/workqueue.h335
-rw-r--r--indra/llimage/llimage.cpp9
-rw-r--r--indra/llimage/llimage.h3
-rw-r--r--indra/llimage/llimagej2c.cpp1
-rw-r--r--indra/llimage/llimagejpeg.cpp8
-rw-r--r--indra/llimage/llimageworker.cpp4
-rw-r--r--indra/llimage/tests/llimageworker_test.cpp3
-rw-r--r--indra/llinventory/llinventory.cpp24
-rw-r--r--indra/llinventory/llinventory.h2
-rw-r--r--indra/llinventory/llsettingsbase.cpp4
-rw-r--r--indra/llinventory/llsettingsdaycycle.cpp3
-rw-r--r--indra/llinventory/llsettingssky.cpp22
-rw-r--r--indra/llinventory/llsettingssky.h3
-rw-r--r--indra/llinventory/llsettingswater.cpp8
-rw-r--r--indra/llkdu/tests/llimagej2ckdu_test.cpp3
-rw-r--r--indra/llmath/llmatrix4a.h41
-rw-r--r--indra/llmath/lloctree.h13
-rw-r--r--indra/llmath/llrigginginfo.h29
-rw-r--r--indra/llmath/llvector4a.h11
-rw-r--r--indra/llmath/llvector4a.inl4
-rw-r--r--indra/llmath/llvolume.cpp25
-rw-r--r--indra/llmath/llvolumeoctree.h27
-rw-r--r--indra/llmath/m4math.cpp9
-rw-r--r--indra/llmath/m4math.h2
-rw-r--r--indra/llmath/v3math.cpp6
-rw-r--r--indra/llmath/v3math.h5
-rw-r--r--indra/llmessage/llfiltersd2xmlrpc.cpp14
-rw-r--r--indra/llmessage/llhttpnode.cpp4
-rw-r--r--indra/llmessage/lliohttpserver.cpp20
-rw-r--r--indra/llmessage/lliosocket.cpp10
-rw-r--r--indra/llmessage/llioutil.cpp6
-rw-r--r--indra/llmessage/llpumpio.cpp11
-rw-r--r--indra/llmessage/lltemplatemessagereader.cpp9
-rw-r--r--indra/llprimitive/lldaeloader.cpp16
-rw-r--r--indra/llprimitive/llmodel.cpp8
-rw-r--r--indra/llprimitive/llmodel.h17
-rw-r--r--indra/llrender/llcubemap.cpp2
-rw-r--r--indra/llrender/llfontbitmapcache.cpp18
-rw-r--r--indra/llrender/llfontbitmapcache.h2
-rw-r--r--indra/llrender/llfontfreetype.cpp10
-rw-r--r--indra/llrender/llfontfreetype.h2
-rw-r--r--indra/llrender/llfontgl.cpp35
-rw-r--r--indra/llrender/llfontgl.h4
-rw-r--r--indra/llrender/llfontregistry.cpp5
-rw-r--r--indra/llrender/llgl.cpp306
-rw-r--r--indra/llrender/llgl.h4
-rw-r--r--indra/llrender/llglheaders.h19
-rw-r--r--indra/llrender/llglslshader.cpp166
-rw-r--r--indra/llrender/llglslshader.h82
-rw-r--r--indra/llrender/llgltexture.cpp2
-rw-r--r--indra/llrender/llgltexture.h2
-rw-r--r--indra/llrender/llimagegl.cpp550
-rw-r--r--indra/llrender/llimagegl.h51
-rw-r--r--indra/llrender/llrender.cpp56
-rw-r--r--indra/llrender/llrender.h18
-rw-r--r--indra/llrender/llrender2dutils.cpp8
-rw-r--r--indra/llrender/llrendertarget.cpp2
-rw-r--r--indra/llrender/lltexture.h7
-rw-r--r--indra/llrender/llvertexbuffer.cpp422
-rw-r--r--indra/llrender/llvertexbuffer.h24
-rw-r--r--indra/llui/llfloater.cpp17
-rw-r--r--indra/llui/llfloater.h2
-rw-r--r--indra/llui/llfolderview.cpp10
-rw-r--r--indra/llui/llfolderviewmodel.h6
-rw-r--r--indra/llui/lllayoutstack.cpp4
-rw-r--r--indra/llui/llnotifications.cpp2
-rw-r--r--indra/llui/llpanel.cpp4
-rw-r--r--indra/llui/llscrolllistctrl.cpp7
-rw-r--r--indra/llui/llstatbar.cpp37
-rw-r--r--indra/llui/llstatbar.h6
-rw-r--r--indra/llui/lltextbase.cpp16
-rw-r--r--indra/llui/lluictrl.cpp17
-rw-r--r--indra/llui/lluictrlfactory.cpp15
-rw-r--r--indra/llui/lluictrlfactory.h16
-rw-r--r--indra/llui/llview.cpp13
-rw-r--r--indra/llui/llview.h3
-rw-r--r--indra/llui/llviewereventrecorder.cpp2
-rw-r--r--indra/llui/llviewereventrecorder.h10
-rw-r--r--indra/llui/llviewmodel.cpp20
-rw-r--r--indra/llui/llviewmodel.h3
-rw-r--r--indra/llwindow/GL/glh_extensions.h211
-rw-r--r--indra/llwindow/GL/glh_genext.h1674
-rw-r--r--indra/llwindow/llopenglview-objc.mm3
-rw-r--r--indra/llwindow/llwindow.cpp18
-rw-r--r--indra/llwindow/llwindow.h28
-rw-r--r--indra/llwindow/llwindowheadless.cpp2
-rw-r--r--indra/llwindow/llwindowheadless.h11
-rw-r--r--indra/llwindow/llwindowmacosx.cpp40
-rw-r--r--indra/llwindow/llwindowmacosx.h148
-rw-r--r--indra/llwindow/llwindowwin32.cpp2651
-rw-r--r--indra/llwindow/llwindowwin32.h68
-rw-r--r--indra/llxml/llcontrol.h8
-rw-r--r--indra/media_plugins/cef/CMakeLists.txt3
-rw-r--r--indra/newview/CMakeLists.txt4
-rw-r--r--indra/newview/app_settings/cmd_line.xml8
-rw-r--r--indra/newview/app_settings/settings.xml52
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl12
-rw-r--r--indra/newview/llagent.cpp2
-rw-r--r--indra/newview/llappviewer.cpp372
-rw-r--r--indra/newview/llappviewer.h7
-rw-r--r--indra/newview/llappviewerwin32.cpp5
-rw-r--r--indra/newview/llbrowsernotification.cpp4
-rw-r--r--indra/newview/llcallingcard.cpp5
-rw-r--r--indra/newview/llcontrolavatar.cpp2
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.cpp4
-rw-r--r--indra/newview/lldrawable.cpp84
-rw-r--r--indra/newview/lldrawable.h9
-rw-r--r--indra/newview/lldrawpool.cpp29
-rw-r--r--indra/newview/lldrawpoolalpha.cpp237
-rw-r--r--indra/newview/lldrawpoolalpha.h4
-rw-r--r--indra/newview/lldrawpoolavatar.cpp718
-rw-r--r--indra/newview/lldrawpoolavatar.h31
-rw-r--r--indra/newview/lldrawpoolbump.cpp66
-rw-r--r--indra/newview/lldrawpoolbump.h4
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp62
-rw-r--r--indra/newview/lldrawpoolmaterials.h2
-rw-r--r--indra/newview/lldrawpoolsimple.cpp41
-rw-r--r--indra/newview/lldrawpoolsimple.h1
-rw-r--r--indra/newview/lldrawpoolsky.cpp8
-rw-r--r--indra/newview/lldrawpoolterrain.cpp3
-rw-r--r--indra/newview/lldrawpooltree.cpp8
-rw-r--r--indra/newview/lldrawpoolwater.cpp21
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp6
-rw-r--r--indra/newview/lldynamictexture.cpp7
-rw-r--r--indra/newview/lldynamictexture.h10
-rw-r--r--indra/newview/llenvironment.cpp45
-rw-r--r--indra/newview/llenvironment.h29
-rw-r--r--indra/newview/llexperiencelog.cpp4
-rw-r--r--indra/newview/llface.cpp154
-rw-r--r--indra/newview/llface.h10
-rw-r--r--indra/newview/llfasttimerview.cpp19
-rw-r--r--indra/newview/llfeaturemanager.cpp6
-rw-r--r--indra/newview/llflexibleobject.cpp13
-rw-r--r--indra/newview/llfloaterimcontainer.cpp38
-rw-r--r--indra/newview/llfloatermodelpreview.cpp88
-rw-r--r--indra/newview/llfloaterpreference.cpp6
-rw-r--r--indra/newview/llfloaterwebcontent.cpp4
-rw-r--r--indra/newview/llglsandbox.cpp8
-rw-r--r--indra/newview/llgroupmgr.cpp14
-rw-r--r--indra/newview/llhudnametag.cpp2
-rw-r--r--indra/newview/llimview.cpp1
-rw-r--r--indra/newview/llinventorybridge.cpp25
-rw-r--r--indra/newview/llinventoryfilter.cpp4
-rw-r--r--indra/newview/llinventoryitemslist.cpp4
-rw-r--r--indra/newview/llinventorypanel.cpp6
-rw-r--r--indra/newview/lllegacyatmospherics.cpp44
-rw-r--r--indra/newview/lllegacyatmospherics.h6
-rw-r--r--indra/newview/llmaterialmgr.cpp4
-rw-r--r--indra/newview/llmeshrepository.cpp43
-rw-r--r--indra/newview/llmeshrepository.h5
-rw-r--r--indra/newview/llmodelpreview.cpp11
-rw-r--r--indra/newview/llnetmap.cpp1
-rw-r--r--indra/newview/llnotificationofferhandler.cpp4
-rw-r--r--indra/newview/llnotificationscripthandler.cpp3
-rw-r--r--indra/newview/llpersistentnotificationstorage.cpp8
-rw-r--r--indra/newview/llphysicsmotion.cpp1
-rw-r--r--indra/newview/llscenemonitor.cpp10
-rw-r--r--indra/newview/llscreenchannel.cpp6
-rw-r--r--indra/newview/llscripteditor.cpp6
-rw-r--r--indra/newview/llselectmgr.cpp4
-rw-r--r--indra/newview/llselectmgr.h8
-rw-r--r--indra/newview/llsettingsvo.cpp69
-rw-r--r--indra/newview/llsettingsvo.h4
-rw-r--r--indra/newview/llskinningutil.cpp62
-rw-r--r--indra/newview/llskinningutil.h4
-rw-r--r--indra/newview/llspatialpartition.cpp121
-rw-r--r--indra/newview/llspatialpartition.h11
-rw-r--r--indra/newview/llstartup.cpp3
-rw-r--r--indra/newview/llsurface.cpp1
-rw-r--r--indra/newview/llsurfacepatch.cpp1
-rw-r--r--indra/newview/lltelemetry.cpp145
-rw-r--r--indra/newview/lltelemetry.h81
-rw-r--r--indra/newview/llteleporthistory.cpp27
-rw-r--r--indra/newview/lltexturefetch.cpp8
-rw-r--r--indra/newview/lltoastpanel.cpp3
-rw-r--r--indra/newview/llviewercamera.cpp5
-rw-r--r--indra/newview/llviewercamera.h22
-rw-r--r--indra/newview/llviewercontrol.cpp22
-rw-r--r--indra/newview/llviewercontrollistener.cpp8
-rw-r--r--indra/newview/llviewerdisplay.cpp102
-rw-r--r--indra/newview/llviewerfloaterreg.cpp4
-rw-r--r--indra/newview/llviewerjointmesh.cpp6
-rw-r--r--indra/newview/llviewermedia.cpp7
-rw-r--r--indra/newview/llviewermenu.cpp1
-rw-r--r--indra/newview/llviewermessage.cpp20
-rw-r--r--indra/newview/llviewerobject.cpp31
-rw-r--r--indra/newview/llviewerobject.h3
-rw-r--r--indra/newview/llviewerobjectlist.cpp42
-rw-r--r--indra/newview/llvieweroctree.cpp65
-rw-r--r--indra/newview/llvieweroctree.h7
-rw-r--r--indra/newview/llviewerparceloverlay.cpp1
-rw-r--r--indra/newview/llviewershadermgr.cpp13
-rw-r--r--indra/newview/llviewerstats.cpp10
-rw-r--r--indra/newview/llviewerstats.h4
-rw-r--r--indra/newview/llviewertexture.cpp318
-rw-r--r--indra/newview/llviewertexture.h10
-rw-r--r--indra/newview/llviewertexturelist.cpp124
-rw-r--r--indra/newview/llviewerwindow.cpp100
-rw-r--r--indra/newview/llviewerwindow.h2
-rw-r--r--indra/newview/llvlcomposition.cpp1
-rw-r--r--indra/newview/llvoavatar.cpp123
-rw-r--r--indra/newview/llvoavatar.h19
-rw-r--r--indra/newview/llvocache.cpp10
-rw-r--r--indra/newview/llvocache.h6
-rw-r--r--indra/newview/llvograss.cpp4
-rw-r--r--indra/newview/llvoicevivox.cpp4
-rw-r--r--indra/newview/llvopartgroup.cpp12
-rw-r--r--indra/newview/llvosky.cpp359
-rw-r--r--indra/newview/llvosky.h23
-rw-r--r--indra/newview/llvosurfacepatch.cpp7
-rw-r--r--indra/newview/llvotree.cpp4
-rw-r--r--indra/newview/llvovolume.cpp338
-rw-r--r--indra/newview/llvovolume.h3
-rw-r--r--indra/newview/llvowater.cpp4
-rw-r--r--indra/newview/llvowlsky.cpp85
-rw-r--r--indra/newview/llvowlsky.h13
-rw-r--r--indra/newview/llworld.cpp12
-rw-r--r--indra/newview/llworld.h7
-rw-r--r--indra/newview/llworldmapmessage.cpp4
-rw-r--r--indra/newview/pipeline.cpp556
-rw-r--r--indra/newview/pipeline.h7
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml24
-rw-r--r--indra/newview/skins/default/xui/en/floater_stats.xml19
-rw-r--r--indra/test/test.cpp1
-rw-r--r--scripts/perf/perfbot_run.py204
304 files changed, 8549 insertions, 7775 deletions
diff --git a/.gitignore b/.gitignore
index 4af34870cf..3619681d82 100755
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ build-vc120-32/
build-vc120-64/
build-vc150-32/
build-vc150-64/
+build-vc160-64/
indra/CMakeFiles
indra/build-vc[0-9]*
indra/lib/mono/1.0/*.dll
diff --git a/autobuild.xml b/autobuild.xml
index f43b277264..1cfaaaa518 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1036,9 +1036,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>650e836255b6c2ecb93d3f1f7220051c</string>
+ <string>dce3f3c01fddb400cb143c3283fe9259</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55011/511905/glh_linear-0.0.0-common-538981.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82754/775367/glh_linear-0.0.0-common-560278.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
@@ -2977,6 +2977,70 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>version</key>
<string>4.10.0000.32327.5fc3fe7c.558436</string>
</map>
+ <key>tracy</key>
+ <map>
+ <key>canonical_repo</key>
+ <string>https://bitbucket.org/lindenlab/3p-tracy</string>
+ <key>copyright</key>
+ <string>Copyright (c) 2017-2021, Bartosz Taudul (wolf@nereid.pl)</string>
+ <key>description</key>
+ <string>Tracy Profiler Library</string>
+ <key>license</key>
+ <string>bsd</string>
+ <key>license_file</key>
+ <string>LICENSES/tracy_license.txt</string>
+ <key>name</key>
+ <string>tracy</string>
+ <key>platforms</key>
+ <map>
+ <key>darwin64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>da7317e4a81609f624f84780f28b07de</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86972/801630/tracy-v0.7.8.563351-darwin64-563351.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>darwin64</string>
+ </map>
+ <key>windows</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>47c696cd2966c5cc3c8ba6115dd1f886</string>
+ <key>hash_algorithm</key>
+ <string>md5</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86973/801641/tracy-v0.7.8.563351-windows-563351.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows</string>
+ </map>
+ <key>windows64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>b649ee6591e67d2341e886b3fc3484a7</string>
+ <key>hash_algorithm</key>
+ <string>md5</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86974/801642/tracy-v0.7.8.563351-windows64-563351.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows64</string>
+ </map>
+ </map>
+ <key>source</key>
+ <string>https://bitbucket.org/lindenlab/3p-tracy</string>
+ <key>source_type</key>
+ <string>git</string>
+ <key>version</key>
+ <string>v0.7.8.563351</string>
+ </map>
<key>tut</key>
<map>
<key>copyright</key>
diff --git a/build.sh b/build.sh
index 1b6dd17a4a..89609a9ffd 100755
--- a/build.sh
+++ b/build.sh
@@ -155,7 +155,11 @@ pre_build()
fi
set -x
- "$autobuild" configure --quiet -c $variant -- \
+ # honor autobuild_configure_parameters same as sling-buildscripts
+ eval_autobuild_configure_parameters=$(eval $(echo echo $autobuild_configure_parameters))
+
+ "$autobuild" configure --quiet -c $variant \
+ ${eval_autobuild_configure_parameters:---} \
-DPACKAGE:BOOL=ON \
-DHAVOK:BOOL="$HAVOK" \
-DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
@@ -205,7 +209,11 @@ build()
if $build_viewer
then
begin_section "autobuild $variant"
- "$autobuild" build --no-configure -c $variant || fatal "failed building $variant"
+ # honor autobuild_build_parameters same as sling-buildscripts
+ eval_autobuild_build_parameters=$(eval $(echo echo $autobuild_build_parameters))
+ "$autobuild" build --no-configure -c $variant \
+ $eval_autobuild_build_parameters \
+ || fatal "failed building $variant"
echo true >"$build_dir"/build_ok
end_section "autobuild $variant"
diff --git a/doc/contributions.txt b/doc/contributions.txt
index cc68162c2d..f10ea39275 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -271,6 +271,8 @@ Beq Janus
SL-14766
SL-14927
SL-11300
+ SL-15709
+ SL-16021
Beth Walcher
Bezilon Kasei
Biancaluce Robbiani
@@ -1360,7 +1362,7 @@ Sovereign Engineer
MAINT-7343
SL-11079
OPEN-343
- SL-11625
+ SL-11625
BUG-229030
SL-14705
SL-14706
@@ -1368,6 +1370,7 @@ Sovereign Engineer
SL-14731
SL-14732
SL-15096
+ SL-16127
SpacedOut Frye
VWR-34
VWR-45
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 8aea50e02b..7c9e07b099 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -42,8 +42,8 @@ if(NON_RELEASE_CRASH_REPORTING)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLL_SEND_CRASH_REPORTS=1")
endif()
-# Don't bother with a MinSizeRel build.
-set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING
+# Don't bother with MinSizeRel or Debug builds.
+set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release" CACHE STRING
"Supported build types." FORCE)
@@ -70,13 +70,18 @@ if (WINDOWS)
if( ADDRESS_SIZE EQUAL 32 )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /p:PreferredToolArchitecture=x64")
endif()
+
+ # Preserve first-pass-through versions (ie no FORCE overwrite). Prevents recursive addition of /Zo (04/2021)
+ set(OG_CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} CACHE STRING "OG_CXX_FLAGS_RELEASE")
+ set(OG_CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} CACHE STRING "OG_CXX_FLAGS_RELWITHDEBINFO")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
- "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo"
+ "${OG_CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo"
CACHE STRING "C++ compiler release-with-debug options" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE
- "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /Zo"
+ "${OG_CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /Zo"
CACHE STRING "C++ compiler release options" FORCE)
+
# zlib has assembly-language object files incompatible with SAFESEH
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE /SAFESEH:NO /NODEFAULTLIB:LIBCMT /IGNORE:4099")
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index b20d23cead..1c56f49486 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -104,6 +104,8 @@ if(WINDOWS)
set(MSVC_VER 120)
elseif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1920) # Visual Studio 2017
set(MSVC_VER 140)
+ elseif (MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1930) # Visual Studio 2019
+ set(MSVC_VER 140)
else (MSVC80)
MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake")
endif (MSVC80)
diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index 8900419f9b..34499aaa36 100644
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -3,12 +3,14 @@
include(APR)
include(Boost)
include(EXPAT)
+include(Tracy)
include(ZLIB)
set(LLCOMMON_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llcommon
${APRUTIL_INCLUDE_DIR}
${APR_INCLUDE_DIR}
+ ${TRACY_INCLUDE_DIR}
)
set(LLCOMMON_SYSTEM_INCLUDE_DIRS
${Boost_INCLUDE_DIRS}
@@ -30,7 +32,8 @@ else (LINUX)
${BOOST_FIBER_LIBRARY}
${BOOST_CONTEXT_LIBRARY}
${BOOST_THREAD_LIBRARY}
- ${BOOST_SYSTEM_LIBRARY} )
+ ${BOOST_SYSTEM_LIBRARY}
+ )
endif (LINUX)
set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.")
diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake
new file mode 100644
index 0000000000..cfff956bcf
--- /dev/null
+++ b/indra/cmake/Tracy.cmake
@@ -0,0 +1,29 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+set(USE_TRACY OFF CACHE BOOL "Use Tracy profiler.")
+
+if (USE_TRACY)
+ set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy)
+
+# See: indra/llcommon/llprofiler.h
+ add_definitions(-DLL_PROFILER_CONFIGURATION=3)
+ use_prebuilt_binary(tracy)
+
+ if (WINDOWS)
+ MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'")
+ endif (WINDOWS)
+
+ if (DARWIN)
+ MESSAGE(STATUS "Including Tracy for Darwin: '${TRACY_INCLUDE_DIR}'")
+ endif (DARWIN)
+
+ if (LINUX)
+ MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'")
+ endif (LINUX)
+else (USE_TRACY)
+ # Tracy.cmake should not set LLCOMMON_INCLUDE_DIRS, let LLCommon.cmake do that
+ set(TRACY_INCLUDE_DIR "")
+ set(TRACY_LIBRARY "")
+endif (USE_TRACY)
+
diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt
index ade83202cf..eab7c17b71 100644
--- a/indra/edit-me-to-trigger-new-build.txt
+++ b/indra/edit-me-to-trigger-new-build.txt
@@ -1,3 +1,4 @@
euclid 5/29/2020
euclid 7/23/2020
euclid 4/29/2021
+euclid 10/5/2021 DRTVWR-546
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 90dfa04f28..2d6d2a10d2 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -1590,7 +1590,7 @@ BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num )
delete_and_clear_array(mCollisionVolumes);
mNumCollisionVolumes = 0;
- mCollisionVolumes = new(std::nothrow) LLAvatarJointCollisionVolume[num];
+ mCollisionVolumes = new LLAvatarJointCollisionVolume[num];
if (!mCollisionVolumes)
{
LL_WARNS() << "Failed to allocate collision volumes" << LL_ENDL;
diff --git a/indra/llappearance/lldriverparam.h b/indra/llappearance/lldriverparam.h
index f278dcc2e2..a6261b507b 100644
--- a/indra/llappearance/lldriverparam.h
+++ b/indra/llappearance/lldriverparam.h
@@ -77,73 +77,63 @@ protected:
//-----------------------------------------------------------------------------
-LL_ALIGN_PREFIX(16)
-class LLDriverParam : public LLViewerVisualParam
+class alignas(16) LLDriverParam : public LLViewerVisualParam
{
+ LL_ALIGN_NEW
private:
- // Hide the default constructor. Force construction with LLAvatarAppearance.
- LLDriverParam() {}
+ // Hide the default constructor. Force construction with LLAvatarAppearance.
+ LLDriverParam() {}
public:
- LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable = NULL);
- ~LLDriverParam();
-
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
- // Special: These functions are overridden by child classes
- LLDriverParamInfo* getInfo() const { return (LLDriverParamInfo*)mInfo; }
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLDriverParamInfo *info);
-
- LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; }
- const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
-
- void updateCrossDrivenParams(LLWearableType::EType driven_type);
-
- /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
-
- // LLVisualParam Virtual functions
- /*virtual*/ void apply( ESex sex ) {} // apply is called separately for each driven param.
- /*virtual*/ void setWeight(F32 weight);
- /*virtual*/ void setAnimationTarget( F32 target_value);
- /*virtual*/ void stopAnimating();
- /*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
- /*virtual*/ void resetDrivenParams();
-
- // LLViewerVisualParam Virtual functions
- /*virtual*/ F32 getTotalDistortion();
- /*virtual*/ const LLVector4a& getAvgDistortion();
- /*virtual*/ F32 getMaxDistortion();
- /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
- /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
- /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
-
- S32 getDrivenParamsCount() const;
- const LLViewerVisualParam* getDrivenParam(S32 index) const;
-
- typedef std::vector<LLDrivenEntry> entry_list_t;
- entry_list_t& getDrivenList() { return mDriven; }
+ LLDriverParam(LLAvatarAppearance* appearance, LLWearable* wearable = NULL);
+ ~LLDriverParam();
+
+ // Special: These functions are overridden by child classes
+ LLDriverParamInfo* getInfo() const { return (LLDriverParamInfo*)mInfo; }
+ // This sets mInfo and calls initialization functions
+ BOOL setInfo(LLDriverParamInfo* info);
+
+ LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; }
+ const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
+
+ void updateCrossDrivenParams(LLWearableType::EType driven_type);
+
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
+
+ // LLVisualParam Virtual functions
+ /*virtual*/ void apply(ESex sex) {} // apply is called separately for each driven param.
+ /*virtual*/ void setWeight(F32 weight);
+ /*virtual*/ void setAnimationTarget(F32 target_value);
+ /*virtual*/ void stopAnimating();
+ /*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
+ /*virtual*/ void resetDrivenParams();
+
+ // LLViewerVisualParam Virtual functions
+ /*virtual*/ F32 getTotalDistortion();
+ /*virtual*/ const LLVector4a& getAvgDistortion();
+ /*virtual*/ F32 getMaxDistortion();
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh* poly_mesh);
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32* index, LLPolyMesh** poly_mesh);
+ /*virtual*/ const LLVector4a* getNextDistortion(U32* index, LLPolyMesh** poly_mesh);
+
+ S32 getDrivenParamsCount() const;
+ const LLViewerVisualParam* getDrivenParam(S32 index) const;
+
+ typedef std::vector<LLDrivenEntry> entry_list_t;
+ entry_list_t& getDrivenList() { return mDriven; }
void setDrivenList(entry_list_t& driven_list) { mDriven = driven_list; }
protected:
- LLDriverParam(const LLDriverParam& pOther);
- F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
- void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight);
-
-
- LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder
- entry_list_t mDriven;
- LLViewerVisualParam* mCurrentDistortionParam;
- // Backlink only; don't make this an LLPointer.
- LLAvatarAppearance* mAvatarAppearance;
- LLWearable* mWearablep;
-} LL_ALIGN_POSTFIX(16);
+ LLDriverParam(const LLDriverParam& pOther);
+ F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
+ void setDrivenWeight(LLDrivenEntry* driven, F32 driven_weight);
+
+
+ LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder
+ entry_list_t mDriven;
+ LLViewerVisualParam* mCurrentDistortionParam;
+ // Backlink only; don't make this an LLPointer.
+ LLAvatarAppearance* mAvatarAppearance;
+ LLWearable* mWearablep;
+};
#endif // LL_LLDRIVERPARAM_H
diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
index ce7010984a..16b5f1e204 100644
--- a/indra/llappearance/llpolymorph.cpp
+++ b/indra/llappearance/llpolymorph.cpp
@@ -539,8 +539,6 @@ F32 LLPolyMorphTarget::getMaxDistortion()
//-----------------------------------------------------------------------------
// apply()
//-----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_APPLY_MORPH_TARGET("Apply Morph");
-
void LLPolyMorphTarget::apply( ESex avatar_sex )
{
if (!mMorphData || mNumMorphMasksPending > 0)
@@ -548,7 +546,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
return;
}
- LL_RECORD_BLOCK_TIME(FTM_APPLY_MORPH_TARGET);
+ LL_PROFILE_ZONE_SCOPED;
mLastSex = avatar_sex;
diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h
index c6133cd831..29cd373636 100644
--- a/indra/llappearance/llpolymorph.h
+++ b/indra/llappearance/llpolymorph.h
@@ -41,24 +41,14 @@ class LLWearable;
//-----------------------------------------------------------------------------
// LLPolyMorphData()
//-----------------------------------------------------------------------------
-LL_ALIGN_PREFIX(16)
-class LLPolyMorphData
+class alignas(16) LLPolyMorphData
{
+ LL_ALIGN_NEW
public:
LLPolyMorphData(const std::string& morph_name);
~LLPolyMorphData();
LLPolyMorphData(const LLPolyMorphData &rhs);
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
BOOL loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh);
const std::string& getName() { return mName; }
@@ -76,7 +66,7 @@ public:
F32 mTotalDistortion; // vertex distortion summed over entire morph
F32 mMaxDistortion; // maximum single vertex distortion in a given morph
- LL_ALIGN_16(LLVector4a mAvgDistortion); // average vertex distortion, to infer directionality of the morph
+ LLVector4a mAvgDistortion; // average vertex distortion, to infer directionality of the morph
LLPolyMeshSharedData* mMesh;
private:
@@ -154,8 +144,9 @@ protected:
// These morph targets must be topologically consistent with a given Polymesh
// (share face sets)
//-----------------------------------------------------------------------------
-class LLPolyMorphTarget : public LLViewerVisualParam
+class alignas(16) LLPolyMorphTarget : public LLViewerVisualParam
{
+ LL_ALIGN_NEW
public:
LLPolyMorphTarget(LLPolyMesh *poly_mesh);
~LLPolyMorphTarget();
@@ -184,16 +175,6 @@ public:
void applyVolumeChanges(F32 delta_weight); // SL-315 - for resetSkeleton()
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
protected:
LLPolyMorphTarget(const LLPolyMorphTarget& pOther);
diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp
index ae38c25dbf..360f17508f 100644
--- a/indra/llappearance/llpolyskeletaldistortion.cpp
+++ b/indra/llappearance/llpolyskeletaldistortion.cpp
@@ -188,11 +188,9 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
//-----------------------------------------------------------------------------
// apply()
//-----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion");
-
void LLPolySkeletalDistortion::apply( ESex avatar_sex )
{
- LL_RECORD_BLOCK_TIME(FTM_POLYSKELETAL_DISTORTION_APPLY);
+ LL_PROFILE_ZONE_SCOPED;
F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h
index ab1a132d19..585d85f055 100644
--- a/indra/llappearance/llpolyskeletaldistortion.h
+++ b/indra/llappearance/llpolyskeletaldistortion.h
@@ -62,9 +62,9 @@ struct LLPolySkeletalBoneInfo
BOOL mHasPositionDeformation;
};
-LL_ALIGN_PREFIX(16)
-class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
+class alignas(16) LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
{
+ LL_ALIGN_NEW
friend class LLPolySkeletalDistortion;
public:
@@ -73,19 +73,6 @@ public:
/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
-
-
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
-
protected:
typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
bone_info_list_t mBoneInfoList;
@@ -95,19 +82,10 @@ protected:
// LLPolySkeletalDeformation
// A set of joint scale data for deforming the avatar mesh
//-----------------------------------------------------------------------------
-class LLPolySkeletalDistortion : public LLViewerVisualParam
+class alignas(16) LLPolySkeletalDistortion : public LLViewerVisualParam
{
+ LL_ALIGN_NEW
public:
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
LLPolySkeletalDistortion(LLAvatarAppearance *avatarp);
~LLPolySkeletalDistortion();
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index e5039141de..26e0ae9086 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -522,10 +522,9 @@ const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const
return mComposite;
}
-static LLTrace::BlockTimerStatHandle FTM_GATHER_MORPH_MASK_ALPHA("gatherMorphMaskAlpha");
void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height, LLRenderTarget* bound_target)
{
- LL_RECORD_BLOCK_TIME(FTM_GATHER_MORPH_MASK_ALPHA);
+ LL_PROFILE_ZONE_SCOPED;
memset(data, 255, width * height);
for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
@@ -538,10 +537,9 @@ void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S
renderAlphaMaskTextures(origin_x, origin_y, width, height, bound_target, true);
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_TEXTURES("renderAlphaMaskTextures");
void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target, bool forceClear)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_TEXTURES);
+ LL_PROFILE_ZONE_SCOPED;
const LLTexLayerSetInfo *info = getInfo();
bool use_shaders = LLGLSLShader::sNoFixedFunction;
@@ -1433,7 +1431,6 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
addAlphaMask(data, originX, originY, width, height, bound_target);
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_MORPH_MASKS("renderMorphMasks");
void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, LLRenderTarget* bound_target, bool force_render)
{
if (!force_render && !hasMorph())
@@ -1441,7 +1438,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
LL_DEBUGS() << "skipping renderMorphMasks for " << getUUID() << LL_ENDL;
return;
}
- LL_RECORD_BLOCK_TIME(FTM_RENDER_MORPH_MASKS);
+ LL_PROFILE_ZONE_SCOPED;
BOOL success = TRUE;
llassert( !mParamAlphaList.empty() );
@@ -1639,10 +1636,9 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
}
}
-static LLTrace::BlockTimerStatHandle FTM_ADD_ALPHA_MASK("addAlphaMask");
void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target)
{
- LL_RECORD_BLOCK_TIME(FTM_ADD_ALPHA_MASK);
+ LL_PROFILE_ZONE_SCOPED;
S32 size = width * height;
const U8* alphaData = getAlphaData();
if (!alphaData && hasAlphaParams())
@@ -1983,10 +1979,9 @@ void LLTexLayerStaticImageList::deleteCachedImages()
// Returns an LLImageTGA that contains the encoded data from a tga file named file_name.
// Caches the result to speed identical subsequent requests.
-static LLTrace::BlockTimerStatHandle FTM_LOAD_STATIC_TGA("getImageTGA");
LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name)
{
- LL_RECORD_BLOCK_TIME(FTM_LOAD_STATIC_TGA);
+ LL_PROFILE_ZONE_SCOPED;
const char *namekey = mImageNames.addString(file_name);
image_tga_map_t::const_iterator iter = mStaticImageListTGA.find(namekey);
if( iter != mStaticImageListTGA.end() )
@@ -2013,10 +2008,9 @@ LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name)
// Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name.
// Caches the result to speed identical subsequent requests.
-static LLTrace::BlockTimerStatHandle FTM_LOAD_STATIC_TEXTURE("getTexture");
LLGLTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask)
{
- LL_RECORD_BLOCK_TIME(FTM_LOAD_STATIC_TEXTURE);
+ LL_PROFILE_ZONE_SCOPED;
LLPointer<LLGLTexture> tex;
const char *namekey = mImageNames.addString(file_name);
@@ -2063,10 +2057,9 @@ LLGLTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name,
// Reads a .tga file, decodes it, and puts the decoded data in image_raw.
// Returns TRUE if successful.
-static LLTrace::BlockTimerStatHandle FTM_LOAD_IMAGE_RAW("loadImageRaw");
BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLImageRaw* image_raw)
{
- LL_RECORD_BLOCK_TIME(FTM_LOAD_IMAGE_RAW);
+ LL_PROFILE_ZONE_SCOPED;
BOOL success = FALSE;
std::string path;
path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name);
diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp
index ff682d6906..ce5c7142d5 100644
--- a/indra/llappearance/lltexlayerparams.cpp
+++ b/indra/llappearance/lltexlayerparams.cpp
@@ -261,10 +261,9 @@ BOOL LLTexLayerParamAlpha::getSkip() const
}
-static LLTrace::BlockTimerStatHandle FTM_TEX_LAYER_PARAM_ALPHA("alpha render");
BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
{
- LL_RECORD_BLOCK_TIME(FTM_TEX_LAYER_PARAM_ALPHA);
+ LL_PROFILE_ZONE_SCOPED;
BOOL success = TRUE;
if (!mTexLayer)
diff --git a/indra/llappearance/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h
index 0cb2dedbff..e2440998b3 100644
--- a/indra/llappearance/lltexlayerparams.h
+++ b/indra/llappearance/lltexlayerparams.h
@@ -63,23 +63,14 @@ protected:
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL_ALIGN_PREFIX(16)
-class LLTexLayerParamAlpha : public LLTexLayerParam
+class alignas(16) LLTexLayerParamAlpha : public LLTexLayerParam
{
+ LL_ALIGN_NEW
public:
LLTexLayerParamAlpha( LLTexLayerInterface* layer );
LLTexLayerParamAlpha( LLAvatarAppearance* appearance );
/*virtual*/ ~LLTexLayerParamAlpha();
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
// LLVisualParam Virtual functions
@@ -146,9 +137,9 @@ private:
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LL_ALIGN_PREFIX(16)
-class LLTexLayerParamColor : public LLTexLayerParam
+class alignas(16) LLTexLayerParamColor : public LLTexLayerParam
{
+ LL_ALIGN_NEW
public:
enum EColorOperation
{
@@ -161,16 +152,6 @@ public:
LLTexLayerParamColor( LLTexLayerInterface* layer );
LLTexLayerParamColor( LLAvatarAppearance* appearance );
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
/* virtual */ ~LLTexLayerParamColor();
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
@@ -198,8 +179,8 @@ protected:
virtual void onGlobalColorChanged() {}
private:
- LL_ALIGN_16(LLVector4a mAvgDistortionVec);
-} LL_ALIGN_POSTFIX(16);
+ LLVector4a mAvgDistortionVec;
+};
class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
{
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index b764ef0c7e..8874df32f5 100644
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -188,20 +188,15 @@ void LLCharacter::requestStopMotion( LLMotion* motion)
//-----------------------------------------------------------------------------
// updateMotions()
//-----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_ANIMATION("Update Animation");
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_HIDDEN_ANIMATION("Update Hidden Anim");
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_MOTIONS("Update Motions");
-
void LLCharacter::updateMotions(e_update_t update_type)
{
+ LL_PROFILE_ZONE_SCOPED;
if (update_type == HIDDEN_UPDATE)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_HIDDEN_ANIMATION);
mMotionController.updateMotionsMinimal();
}
else
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_ANIMATION);
// unpause if the number of outstanding pause requests has dropped to the initial one
if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1)
{
@@ -209,7 +204,6 @@ void LLCharacter::updateMotions(e_update_t update_type)
}
bool force_update = (update_type == FORCE_UPDATE);
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_MOTIONS);
mMotionController.updateMotions(force_update);
}
}
diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp
index ddf89f30f2..c5757163d9 100644
--- a/indra/llcharacter/lleditingmotion.cpp
+++ b/indra/llcharacter/lleditingmotion.cpp
@@ -163,6 +163,7 @@ BOOL LLEditingMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
LLVector3 focus_pt;
LLVector3* pointAtPt = (LLVector3*)mCharacter->getAnimationData("PointAtPoint");
diff --git a/indra/llcharacter/lleditingmotion.h b/indra/llcharacter/lleditingmotion.h
index 7b1c8bb059..80c1717a70 100644
--- a/indra/llcharacter/lleditingmotion.h
+++ b/indra/llcharacter/lleditingmotion.h
@@ -42,9 +42,11 @@
//-----------------------------------------------------------------------------
// class LLEditingMotion
//-----------------------------------------------------------------------------
+LL_ALIGN_PREFIX(16)
class LLEditingMotion :
public LLMotion
{
+ LL_ALIGN_NEW
public:
// Constructor
LLEditingMotion(const LLUUID &id);
@@ -108,6 +110,13 @@ 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);
+ LLJointSolverRP3 mIKSolver;
+
LLCharacter *mCharacter;
LLVector3 mWristOffset;
@@ -117,17 +126,10 @@ public:
LLPointer<LLJointState> mWristState;
LLPointer<LLJointState> mTorsoState;
- LLJoint mParentJoint;
- LLJoint mShoulderJoint;
- LLJoint mElbowJoint;
- LLJoint mWristJoint;
- LLJoint mTarget;
- LLJointSolverRP3 mIKSolver;
-
static S32 sHandPose;
static S32 sHandPosePriority;
LLVector3 mLastSelectPt;
-};
+} LL_ALIGN_POSTFIX(16);
#endif // LL_LLKEYFRAMEMOTION_H
diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp
index b3bf5a9a91..ceba956214 100644
--- a/indra/llcharacter/llhandmotion.cpp
+++ b/indra/llcharacter/llhandmotion.cpp
@@ -121,6 +121,7 @@ BOOL LLHandMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
eHandPose *requestedHandPose;
F32 timeDelta = time - mLastTime;
diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp
index e91de7a11d..fdf97266a3 100644
--- a/indra/llcharacter/llheadrotmotion.cpp
+++ b/indra/llcharacter/llheadrotmotion.cpp
@@ -175,6 +175,7 @@ BOOL LLHeadRotMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
LLQuaternion targetHeadRotWorld;
LLQuaternion currentRootRotWorld = mRootJoint->getWorldRotation();
LLQuaternion currentInvRootRotWorld = ~currentRootRotWorld;
@@ -458,6 +459,7 @@ void LLEyeMotion::adjustEyeTarget(LLVector3* targetPos, LLJointState& left_eye_s
//-----------------------------------------------------------------------------
BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
//calculate jitter
if (mEyeJitterTimer.getElapsedTimeF32() > mEyeJitterTime)
{
diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp
index dee642310e..d72282ab42 100644
--- a/indra/llcharacter/lljoint.cpp
+++ b/indra/llcharacter/lljoint.cpp
@@ -922,6 +922,13 @@ const LLMatrix4 &LLJoint::getWorldMatrix()
return mXform.getWorldMatrix();
}
+const LLMatrix4a& LLJoint::getWorldMatrix4a()
+{
+ updateWorldMatrixParent();
+
+ return mWorldMatrix;
+}
+
//--------------------------------------------------------------------
// setWorldMatrix()
@@ -1003,6 +1010,7 @@ void LLJoint::updateWorldMatrix()
{
sNumUpdates++;
mXform.updateMatrix(FALSE);
+ mWorldMatrix.loadu(mXform.getWorldMatrix());
mDirtyFlags = 0x0;
}
}
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index 1b646b641f..63d99b9209 100644
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -38,6 +38,7 @@
#include "m4math.h"
#include "llquaternion.h"
#include "xform.h"
+#include "llmatrix4a.h"
const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15;
// Need to set this to count of animate-able joints,
@@ -85,8 +86,10 @@ inline bool operator!=(const LLVector3OverrideMap& a, const LLVector3OverrideMap
//-----------------------------------------------------------------------------
// class LLJoint
//-----------------------------------------------------------------------------
+LL_ALIGN_PREFIX(16)
class LLJoint
{
+ LL_ALIGN_NEW
public:
// priority levels, from highest to lowest
enum JointPriority
@@ -114,16 +117,17 @@ public:
SUPPORT_EXTENDED
};
protected:
- std::string mName;
+ // explicit transformation members
+ LL_ALIGN_16(LLMatrix4a mWorldMatrix);
+ LLXformMatrix mXform;
+
+ std::string mName;
SupportCategory mSupport;
// parent joint
LLJoint *mParent;
- // explicit transformation members
- LLXformMatrix mXform;
-
LLVector3 mDefaultPosition;
LLVector3 mDefaultScale;
@@ -259,6 +263,8 @@ public:
const LLMatrix4 &getWorldMatrix();
void setWorldMatrix( const LLMatrix4& mat );
+ const LLMatrix4a& getWorldMatrix4a();
+
void updateWorldMatrixChildren();
void updateWorldMatrixParent();
@@ -296,6 +302,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/llkeyframefallmotion.cpp b/indra/llcharacter/llkeyframefallmotion.cpp
index 60ab2e9929..ac53bcd768 100644
--- a/indra/llcharacter/llkeyframefallmotion.cpp
+++ b/indra/llcharacter/llkeyframefallmotion.cpp
@@ -116,6 +116,7 @@ BOOL LLKeyframeFallMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLKeyframeFallMotion::onUpdate(F32 activeTime, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
BOOL result = LLKeyframeMotion::onUpdate(activeTime, joint_mask);
F32 slerp_amt = clamp_rescale(activeTime / getDuration(), 0.5f, 0.75f, 0.f, 1.f);
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index cde38c8091..429c479d0d 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -683,6 +683,7 @@ BOOL LLKeyframeMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLKeyframeMotion::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
// llassert(time >= 0.f); // This will fire
time = llmax(0.f, time);
diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp
index 6ed18bc445..aba1c5db39 100644
--- a/indra/llcharacter/llkeyframemotionparam.cpp
+++ b/indra/llcharacter/llkeyframemotionparam.cpp
@@ -158,6 +158,7 @@ BOOL LLKeyframeMotionParam::onActivate()
//-----------------------------------------------------------------------------
BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
F32 weightFactor = 1.f / (F32)mParameterizedMotions.size();
// zero out all pose weights
diff --git a/indra/llcharacter/llkeyframestandmotion.h b/indra/llcharacter/llkeyframestandmotion.h
index c2634ecd6d..1aa5b187ba 100644
--- a/indra/llcharacter/llkeyframestandmotion.h
+++ b/indra/llcharacter/llkeyframestandmotion.h
@@ -37,9 +37,11 @@
//-----------------------------------------------------------------------------
// class LLKeyframeStandMotion
//-----------------------------------------------------------------------------
+LL_ALIGN_PREFIX(16)
class LLKeyframeStandMotion :
public LLKeyframeMotion
{
+ LL_ALIGN_NEW
public:
// Constructor
LLKeyframeStandMotion(const LLUUID &id);
@@ -69,6 +71,18 @@ public:
//-------------------------------------------------------------------------
// Member Data
//-------------------------------------------------------------------------
+ LLJoint mPelvisJoint;
+
+ LLJoint mHipLeftJoint;
+ LLJoint mKneeLeftJoint;
+ LLJoint mAnkleLeftJoint;
+ LLJoint mTargetLeft;
+
+ LLJoint mHipRightJoint;
+ LLJoint mKneeRightJoint;
+ LLJoint mAnkleRightJoint;
+ LLJoint mTargetRight;
+
LLCharacter *mCharacter;
BOOL mFlipFeet;
@@ -83,18 +97,6 @@ public:
LLPointer<LLJointState> mKneeRightState;
LLPointer<LLJointState> mAnkleRightState;
- LLJoint mPelvisJoint;
-
- LLJoint mHipLeftJoint;
- LLJoint mKneeLeftJoint;
- LLJoint mAnkleLeftJoint;
- LLJoint mTargetLeft;
-
- LLJoint mHipRightJoint;
- LLJoint mKneeRightJoint;
- LLJoint mAnkleRightJoint;
- LLJoint mTargetRight;
-
LLJointSolverRP3 mIKLeft;
LLJointSolverRP3 mIKRight;
@@ -110,7 +112,7 @@ public:
BOOL mTrackAnkles;
S32 mFrameNum;
-};
+} LL_ALIGN_POSTFIX(16);
#endif // LL_LLKEYFRAMESTANDMOTION_H
diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp
index f180702385..298b37e60c 100644
--- a/indra/llcharacter/llkeyframewalkmotion.cpp
+++ b/indra/llcharacter/llkeyframewalkmotion.cpp
@@ -105,6 +105,7 @@ void LLKeyframeWalkMotion::onDeactivate()
//-----------------------------------------------------------------------------
BOOL LLKeyframeWalkMotion::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
// compute time since last update
F32 deltaTime = time - mRealTimeLast;
@@ -198,6 +199,7 @@ BOOL LLWalkAdjustMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
// delta_time is guaranteed to be non zero
F32 delta_time = llclamp(time - mLastTime, TIME_EPSILON, MAX_TIME_DELTA);
mLastTime = time;
@@ -373,6 +375,7 @@ BOOL LLFlyAdjustMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
LLVector3 ang_vel = mCharacter->getCharacterAngularVelocity() * mCharacter->getTimeDilation();
F32 speed = mCharacter->getCharacterVelocity().magVec();
diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp
index c48d02b652..d4546ce901 100644
--- a/indra/llcharacter/llmotioncontroller.cpp
+++ b/indra/llcharacter/llmotioncontroller.cpp
@@ -503,6 +503,7 @@ void LLMotionController::resetJointSignatures()
//-----------------------------------------------------------------------------
void LLMotionController::updateIdleMotion(LLMotion* motionp)
{
+ LL_PROFILE_ZONE_SCOPED;
if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration())
{
deactivateMotionInstance(motionp);
@@ -541,6 +542,7 @@ void LLMotionController::updateIdleMotion(LLMotion* motionp)
//-----------------------------------------------------------------------------
void LLMotionController::updateIdleActiveMotions()
{
+ LL_PROFILE_ZONE_SCOPED;
for (motion_list_t::iterator iter = mActiveMotions.begin();
iter != mActiveMotions.end(); )
{
@@ -553,10 +555,9 @@ void LLMotionController::updateIdleActiveMotions()
//-----------------------------------------------------------------------------
// updateMotionsByType()
//-----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_MOTION_ON_UPDATE("Motion onUpdate");
-
void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type)
{
+ LL_PROFILE_ZONE_SCOPED;
BOOL update_result = TRUE;
U8 last_joint_signature[LL_CHARACTER_MAX_ANIMATED_JOINTS];
@@ -712,7 +713,6 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
// perform motion update
{
- LL_RECORD_BLOCK_TIME(FTM_MOTION_ON_UPDATE);
update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature);
}
}
@@ -768,6 +768,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
//-----------------------------------------------------------------------------
void LLMotionController::updateLoadingMotions()
{
+ LL_PROFILE_ZONE_SCOPED;
// query pending motions for completion
for (motion_set_t::iterator iter = mLoadingMotions.begin();
iter != mLoadingMotions.end(); )
@@ -815,6 +816,7 @@ void LLMotionController::updateLoadingMotions()
//-----------------------------------------------------------------------------
void LLMotionController::updateMotions(bool force_update)
{
+ LL_PROFILE_ZONE_SCOPED;
// SL-763: "Distant animated objects run at super fast speed"
// The use_quantum optimization or possibly the associated code in setTimeStamp()
// does not work as implemented.
@@ -907,6 +909,7 @@ void LLMotionController::updateMotions(bool force_update)
//-----------------------------------------------------------------------------
void LLMotionController::updateMotionsMinimal()
{
+ LL_PROFILE_ZONE_SCOPED;
// Always update mPrevTimerElapsed
mPrevTimerElapsed = mTimer.getElapsedTimeF32();
@@ -924,6 +927,7 @@ void LLMotionController::updateMotionsMinimal()
//-----------------------------------------------------------------------------
BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time)
{
+ LL_PROFILE_ZONE_SCOPED;
// It's not clear why the getWeight() line seems to be crashing this, but
// hopefully this fixes it.
if (motion == NULL || motion->getPose() == NULL)
diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h
index c004a0f3b7..1405f1e053 100644
--- a/indra/llcharacter/llpose.h
+++ b/indra/llcharacter/llpose.h
@@ -80,8 +80,10 @@ public:
const S32 JSB_NUM_JOINT_STATES = 6;
+LL_ALIGN_PREFIX(16)
class LLJointStateBlender
{
+ LL_ALIGN_NEW
protected:
LLPointer<LLJointState> mJointStates[JSB_NUM_JOINT_STATES];
S32 mPriorities[JSB_NUM_JOINT_STATES];
@@ -96,8 +98,8 @@ public:
void resetCachedJoint();
public:
- LLJoint mJointCache;
-};
+ LL_ALIGN_16(LLJoint mJointCache);
+} LL_ALIGN_POSTFIX(16);
class LLMotion;
diff --git a/indra/llcharacter/lltargetingmotion.cpp b/indra/llcharacter/lltargetingmotion.cpp
index 69681e4197..ec75212a40 100644
--- a/indra/llcharacter/lltargetingmotion.cpp
+++ b/indra/llcharacter/lltargetingmotion.cpp
@@ -103,6 +103,7 @@ BOOL LLTargetingMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TORSO_TARGET_HALF_LIFE);
LLVector3 target;
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 766a1849f9..9defa6b6c1 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -12,6 +12,7 @@ include(JsonCpp)
include(Copy3rdPartyLibs)
include(ZLIB)
include(URIPARSER)
+include(Tracy)
include_directories(
${EXPAT_INCLUDE_DIRS}
@@ -19,6 +20,7 @@ include_directories(
${JSONCPP_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS}
${URIPARSER_INCLUDE_DIRS}
+ ${TRACY_INCLUDE_DIR}
)
# add_executable(lltreeiterators lltreeiterators.cpp)
@@ -119,12 +121,14 @@ set(llcommon_SOURCE_FILES
llworkerthread.cpp
timing.cpp
u64.cpp
+ workqueue.cpp
StackWalker.cpp
)
set(llcommon_HEADER_FILES
CMakeLists.txt
+ chrono.h
ctype_workaround.h
fix_macros.h
indra_constants.h
@@ -197,6 +201,7 @@ set(llcommon_HEADER_FILES
llmortician.h
llnametable.h
llpointer.h
+ llprofiler.h
llpounceable.h
llpredicate.h
llpreprocessor.h
@@ -251,8 +256,11 @@ set(llcommon_HEADER_FILES
lockstatic.h
stdtypes.h
stringize.h
+ threadsafeschedule.h
timer.h
+ tuple.h
u64.h
+ workqueue.h
StackWalker.h
)
@@ -299,6 +307,7 @@ target_link_libraries(
${BOOST_SYSTEM_LIBRARY}
${GOOGLE_PERFTOOLS_LIBRARIES}
${URIPARSER_LIBRARIES}
+ ${TRACY_LIBRARY}
)
if (DARWIN)
@@ -355,6 +364,9 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(threadsafeschedule "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(tuple "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(workqueue "" "${test_libs}")
## llexception_test.cpp isn't a regression test, and doesn't need to be run
## every build. It's to help a developer make implementation choices about
diff --git a/indra/llcommon/chrono.h b/indra/llcommon/chrono.h
new file mode 100644
index 0000000000..806e871892
--- /dev/null
+++ b/indra/llcommon/chrono.h
@@ -0,0 +1,65 @@
+/**
+ * @file chrono.h
+ * @author Nat Goodspeed
+ * @date 2021-10-05
+ * @brief supplement <chrono> with utility functions
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_CHRONO_H)
+#define LL_CHRONO_H
+
+#include <chrono>
+#include <type_traits> // std::enable_if
+
+namespace LL
+{
+
+// time_point_cast() is derived from https://stackoverflow.com/a/35293183
+// without the iteration: we think errors in the ~1 microsecond range are
+// probably acceptable.
+
+// This variant is for the optimal case when the source and dest use the same
+// clock: that case is handled by std::chrono.
+template <typename DestTimePoint, typename SrcTimePoint,
+ typename std::enable_if<std::is_same<typename DestTimePoint::clock,
+ typename SrcTimePoint::clock>::value,
+ bool>::type = true>
+DestTimePoint time_point_cast(const SrcTimePoint& time)
+{
+ return std::chrono::time_point_cast<typename DestTimePoint::duration>(time);
+}
+
+// This variant is for when the source and dest use different clocks -- see
+// the linked StackOverflow answer, also Howard Hinnant's, for more context.
+template <typename DestTimePoint, typename SrcTimePoint,
+ typename std::enable_if<! std::is_same<typename DestTimePoint::clock,
+ typename SrcTimePoint::clock>::value,
+ bool>::type = true>
+DestTimePoint time_point_cast(const SrcTimePoint& time)
+{
+ // The basic idea is that we must adjust the passed time_point by the
+ // difference between the clocks' epochs. But since time_point doesn't
+ // expose its epoch, we fall back on what each of them thinks is now().
+ // However, since we necessarily make sequential calls to those now()
+ // functions, the answers differ not only by the cycles spent executing
+ // those calls, but by potential OS interruptions between them. Try to
+ // reduce that error by capturing the source clock time both before and
+ // after the dest clock, and splitting the difference. Of course an
+ // interruption between two of these now() calls without a comparable
+ // interruption between the other two will skew the result, but better is
+ // more expensive.
+ const auto src_before = typename SrcTimePoint::clock::now();
+ const auto dest_now = typename DestTimePoint::clock::now();
+ const auto src_after = typename SrcTimePoint::clock::now();
+ const auto src_diff = src_after - src_before;
+ const auto src_now = src_before + src_diff / 2;
+ return dest_now + (time - src_now);
+}
+
+} // namespace LL
+
+#endif /* ! defined(LL_CHRONO_H) */
diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h
index e5a913a6a9..a228fd22be 100644
--- a/indra/llcommon/linden_common.h
+++ b/indra/llcommon/linden_common.h
@@ -27,6 +27,14 @@
#ifndef LL_LINDEN_COMMON_H
#define LL_LINDEN_COMMON_H
+#include "llprofiler.h"
+#if TRACY_ENABLE && !defined(LL_PROFILER_ENABLE_TRACY_OPENGL) // hooks for memory profiling
+void *tracy_aligned_malloc(size_t size, size_t alignment);
+void tracy_aligned_free(void *memblock);
+#define _aligned_malloc(X, Y) tracy_aligned_malloc((X), (Y))
+#define _aligned_free(X) tracy_aligned_free((X))
+#endif
+
// *NOTE: Please keep includes here to a minimum!
//
// Files included here are included in every library .cpp file and
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 96be913d17..25a809dad2 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -33,6 +33,66 @@
#include "lltracethreadrecorder.h"
#include "llcleanup.h"
+thread_local bool gProfilerEnabled = false;
+
+#if (TRACY_ENABLE)
+// Override new/delete for tracy memory profiling
+void *operator new(size_t size)
+{
+ void* ptr;
+ if (gProfilerEnabled)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ ptr = (malloc)(size);
+ }
+ else
+ {
+ ptr = (malloc)(size);
+ }
+ if (!ptr)
+ {
+ throw std::bad_alloc();
+ }
+ TracyAlloc(ptr, size);
+ return ptr;
+}
+
+void operator delete(void *ptr) noexcept
+{
+ TracyFree(ptr);
+ if (gProfilerEnabled)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ (free)(ptr);
+ }
+ else
+ {
+ (free)(ptr);
+ }
+}
+
+// C-style malloc/free can't be so easily overridden, so we define tracy versions and use
+// a pre-processor #define in linden_common.h to redirect to them. The parens around the native
+// functions below prevents recursive substitution by the preprocessor.
+//
+// Unaligned mallocs are rare in LL code but hooking them causes problems in 3p lib code (looking at
+// you, Havok), so we'll only capture the aligned version.
+
+void *tracy_aligned_malloc(size_t size, size_t alignment)
+{
+ auto ptr = ll_aligned_malloc_fallback(size, alignment);
+ if (ptr) TracyAlloc(ptr, size);
+ return ptr;
+}
+
+void tracy_aligned_free(void *memblock)
+{
+ TracyFree(memblock);
+ ll_aligned_free_fallback(memblock);
+}
+
+#endif
+
//static
BOOL LLCommon::sAprInitialized = FALSE;
diff --git a/indra/llcommon/llcond.h b/indra/llcommon/llcond.h
index e31b67d893..c08acb66a1 100644
--- a/indra/llcommon/llcond.h
+++ b/indra/llcommon/llcond.h
@@ -53,6 +53,8 @@ private:
LLCoros::Mutex mMutex;
// Use LLCoros::ConditionVariable for the same reason.
LLCoros::ConditionVariable mCond;
+ using LockType = LLCoros::LockType;
+ using cv_status = LLCoros::cv_status;
public:
/// LLCond can be explicitly initialized with a specific value for mData if
@@ -65,10 +67,14 @@ public:
LLCond(const LLCond&) = delete;
LLCond& operator=(const LLCond&) = delete;
- /// get() returns a const reference to the stored DATA. The only way to
- /// get a non-const reference -- to modify the stored DATA -- is via
- /// update_one() or update_all().
- const value_type& get() const { return mData; }
+ /// get() returns the stored DATA by value -- so to use get(), DATA must
+ /// be copyable. The only way to get a non-const reference -- to modify
+ /// the stored DATA -- is via update_one() or update_all().
+ value_type get()
+ {
+ LockType lk(mMutex);
+ return mData;
+ }
/**
* Pass update_one() an invocable accepting non-const (DATA&). The
@@ -83,7 +89,7 @@ public:
void update_one(MODIFY modify)
{
{ // scope of lock can/should end before notify_one()
- LLCoros::LockType lk(mMutex);
+ LockType lk(mMutex);
modify(mData);
}
mCond.notify_one();
@@ -102,7 +108,7 @@ public:
void update_all(MODIFY modify)
{
{ // scope of lock can/should end before notify_all()
- LLCoros::LockType lk(mMutex);
+ LockType lk(mMutex);
modify(mData);
}
mCond.notify_all();
@@ -118,7 +124,7 @@ public:
template <typename Pred>
void wait(Pred pred)
{
- LLCoros::LockType lk(mMutex);
+ LockType lk(mMutex);
// We must iterate explicitly since the predicate accepted by
// condition_variable::wait() requires a different signature:
// condition_variable::wait() calls its predicate with no arguments.
@@ -205,14 +211,14 @@ private:
template <typename Clock, typename Duration, typename Pred>
bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time, Pred pred)
{
- LLCoros::LockType lk(mMutex);
+ LockType lk(mMutex);
// We advise the caller to pass a predicate accepting (const DATA&).
// But what if they instead pass a predicate accepting non-const
// (DATA&)? Such a predicate could modify mData, which would be Bad.
// Forbid that.
while (! pred(const_cast<const value_type&>(mData)))
{
- if (LLCoros::cv_status::timeout == mCond.wait_until(lk, timeout_time))
+ if (cv_status::timeout == mCond.wait_until(lk, timeout_time))
{
// It's possible that wait_until() timed out AND the predicate
// became true more or less simultaneously. Even though
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 7a2a0869f4..2ddcf40895 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -86,11 +86,9 @@ std::string LLDate::asRFC1123() const
return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT"));
}
-LLTrace::BlockTimerStatHandle FT_DATE_FORMAT("Date Format");
-
std::string LLDate::toHTTPDateString (std::string fmt) const
{
- LL_RECORD_BLOCK_TIME(FT_DATE_FORMAT);
+ LL_PROFILE_ZONE_SCOPED;
time_t locSeconds = (time_t) mSecondsSinceEpoch;
struct tm * gmt = gmtime (&locSeconds);
@@ -99,7 +97,7 @@ std::string LLDate::toHTTPDateString (std::string fmt) const
std::string LLDate::toHTTPDateString (tm * gmt, std::string fmt)
{
- LL_RECORD_BLOCK_TIME(FT_DATE_FORMAT);
+ LL_PROFILE_ZONE_SCOPED;
// avoid calling setlocale() unnecessarily - it's expensive.
static std::string prev_locale = "";
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 51b0fe8be8..a4a5cb2d24 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -109,6 +109,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
+ LL_PROFILE_ZONE_SCOPED
int syslogPriority = LOG_CRIT;
switch (level) {
case LLError::LEVEL_DEBUG: syslogPriority = LOG_DEBUG; break;
@@ -166,6 +167,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
+ LL_PROFILE_ZONE_SCOPED
if (LLError::getAlwaysFlush())
{
mFile << message << std::endl;
@@ -208,6 +210,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
+ LL_PROFILE_ZONE_SCOPED
static std::string s_ansi_error = createANSI("31"); // red
static std::string s_ansi_warn = createANSI("34"); // blue
static std::string s_ansi_debug = createANSI("35"); // magenta
@@ -220,7 +223,8 @@ namespace {
}
else
{
- fprintf(stderr, "%s\n", message.c_str());
+ LL_PROFILE_ZONE_NAMED("fprintf");
+ fprintf(stderr, "%s\n", message.c_str());
}
}
@@ -229,6 +233,7 @@ namespace {
LL_FORCE_INLINE void writeANSI(const std::string& ansi_code, const std::string& message)
{
+ LL_PROFILE_ZONE_SCOPED
static std::string s_ansi_bold = createANSI("1"); // bold
static std::string s_ansi_reset = createANSI("0"); // reset
// ANSI color code escape sequence, message, and reset in one fprintf call
@@ -265,6 +270,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
+ LL_PROFILE_ZONE_SCOPED
mBuffer->addLine(message);
}
@@ -291,6 +297,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
+ LL_PROFILE_ZONE_SCOPED
debugger_print(message);
}
};
@@ -1172,6 +1179,7 @@ namespace
void writeToRecorders(const LLError::CallSite& site, const std::string& message)
{
+ LL_PROFILE_ZONE_SCOPED
LLError::ELevel level = site.mLevel;
SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
@@ -1306,6 +1314,7 @@ namespace LLError
bool Log::shouldLog(CallSite& site)
{
+ LL_PROFILE_ZONE_SCOPED
LLMutexTrylock lock(getMutex<LOG_MUTEX>(), 5);
if (!lock.isLocked())
{
@@ -1350,6 +1359,7 @@ namespace LLError
void Log::flush(const std::ostringstream& out, const CallSite& site)
{
+ LL_PROFILE_ZONE_SCOPED
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
if (!lock.isLocked())
{
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index d439136ca8..d06c0e2132 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -35,7 +35,9 @@
#include "stdtypes.h"
+#include "llprofiler.h"
#include "llpreprocessor.h"
+
#include <boost/static_assert.hpp>
const int LL_ERR_NOERR = 0;
@@ -348,7 +350,8 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
// if (condition) LL_INFOS() << "True" << LL_ENDL; else LL_INFOS()() << "False" << LL_ENDL;
#define lllog(level, once, ...) \
- do { \
+ do { \
+ LL_PROFILE_ZONE_NAMED("lllog"); \
const char* tags[] = {"", ##__VA_ARGS__}; \
static LLError::CallSite _site(lllog_site_args_(level, once, tags)); \
lllog_test_()
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index e87bb7bf35..57f10b7895 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -190,6 +190,7 @@ namespace LLError
{}
void recordMessage(LLError::ELevel level, const std::string& message) override
{
+ LL_PROFILE_ZONE_SCOPED
mCallable(level, message);
}
private:
diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h
index 48c2570732..7613850fb2 100644
--- a/indra/llcommon/lleventfilter.h
+++ b/indra/llcommon/lleventfilter.h
@@ -429,6 +429,8 @@ public:
// path, then stores it to mTarget.
virtual bool post(const LLSD& event)
{
+ LL_PROFILE_ZONE_SCOPED
+
// Extract the element specified by 'mPath' from 'event'. To perform a
// generic type-appropriate store through mTarget, construct an
// LLSDParam<T> and store that, thus engaging LLSDParam's custom
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 5b6a7b82f8..d38946004f 100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -191,29 +191,30 @@ TimeBlockTreeNode& BlockTimerStatHandle::getTreeNode() const
}
+
void BlockTimer::bootstrapTimerTree()
{
- for (auto& base : BlockTimerStatHandle::instance_snapshot())
- {
- // because of indirect derivation from LLInstanceTracker, have to downcast
- BlockTimerStatHandle& timer = static_cast<BlockTimerStatHandle&>(base);
- if (&timer == &BlockTimer::getRootTimeBlock()) continue;
-
- // bootstrap tree construction by attaching to last timer to be on stack
- // when this timer was called
- if (timer.getParent() == &BlockTimer::getRootTimeBlock())
- {
- TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator();
-
- if (accumulator.mLastCaller)
- {
- timer.setParent(accumulator.mLastCaller);
- accumulator.mParent = accumulator.mLastCaller;
- }
- // no need to push up tree on first use, flag can be set spuriously
- accumulator.mMoveUpTree = false;
- }
- }
+ for (auto& base : BlockTimerStatHandle::instance_snapshot())
+ {
+ // because of indirect derivation from LLInstanceTracker, have to downcast
+ BlockTimerStatHandle& timer = static_cast<BlockTimerStatHandle&>(base);
+ if (&timer == &BlockTimer::getRootTimeBlock()) continue;
+
+ // bootstrap tree construction by attaching to last timer to be on stack
+ // when this timer was called
+ if (timer.getParent() == &BlockTimer::getRootTimeBlock())
+ {
+ TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator();
+
+ if (accumulator.mLastCaller)
+ {
+ timer.setParent(accumulator.mLastCaller);
+ accumulator.mParent = accumulator.mLastCaller;
+ }
+ // no need to push up tree on first use, flag can be set spuriously
+ accumulator.mMoveUpTree = false;
+ }
+ }
}
// bump timers up tree if they have been flagged as being in the wrong place
@@ -221,6 +222,7 @@ void BlockTimer::bootstrapTimerTree()
// this preserves partial order derived from current frame's observations
void BlockTimer::incrementalUpdateTimerTree()
{
+ LL_PROFILE_ZONE_SCOPED;
for(block_timer_tree_df_post_iterator_t it = begin_block_timer_tree_df_post(BlockTimer::getRootTimeBlock());
it != end_block_timer_tree_df_post();
++it)
@@ -260,7 +262,8 @@ void BlockTimer::incrementalUpdateTimerTree()
void BlockTimer::updateTimes()
- {
+{
+ LL_PROFILE_ZONE_SCOPED;
// walk up stack of active timers and accumulate current time while leaving timing structures active
BlockTimerStackRecord* stack_record = LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance();
if (!stack_record) return;
@@ -271,7 +274,7 @@ void BlockTimer::updateTimes()
while(cur_timer
&& cur_timer->mParentTimerData.mActiveTimer != cur_timer) // root defined by parent pointing to self
- {
+ {
U64 cumulative_time_delta = cur_time - cur_timer->mStartTime;
cur_timer->mStartTime = cur_time;
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index dfc63d08a2..9bd93d7240 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -38,7 +38,10 @@
#define LL_FAST_TIMER_ON 1
#define LL_FASTTIMER_USE_RDTSC 1
+// NOTE: Also see llprofiler.h
+#if !defined(LL_PROFILER_CONFIGURATION)
#define LL_RECORD_BLOCK_TIME(timer_stat) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__);
+#endif // LL_PROFILER_CONFIGURATION
namespace LLTrace
{
diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp
index 1e9920746b..c54029e8b4 100644
--- a/indra/llcommon/llframetimer.cpp
+++ b/indra/llcommon/llframetimer.cpp
@@ -29,6 +29,11 @@
#include "llframetimer.h"
+// We don't bother building a stand alone lib; we just need to include the one source file for Tracy support
+#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER
+ #include "TracyClient.cpp"
+#endif // LL_PROFILER_CONFIGURATION
+
// Static members
//LLTimer LLFrameTimer::sInternalTimer;
U64 LLFrameTimer::sStartTotalTime = totalTime();
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 402333cca7..02535a59e7 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -83,13 +83,34 @@ class LLInstanceTracker
typedef llthread::LockStatic<StaticData> LockStatic;
public:
+ using ptr_t = std::shared_ptr<T>;
+ using weak_t = std::weak_ptr<T>;
+
+ /**
+ * Storing a dumb T* somewhere external is a bad idea, since
+ * LLInstanceTracker subclasses are explicitly destroyed rather than
+ * managed by smart pointers. It's legal to declare stack instances of an
+ * LLInstanceTracker subclass. But it's reasonable to store a
+ * std::weak_ptr<T>, which will become invalid when the T instance is
+ * destroyed.
+ */
+ weak_t getWeak()
+ {
+ return mSelf;
+ }
+
+ static S32 instanceCount()
+ {
+ return LockStatic()->mMap.size();
+ }
+
// snapshot of std::pair<const KEY, std::shared_ptr<T>> pairs
class snapshot
{
// It's very important that what we store in this snapshot are
// weak_ptrs, NOT shared_ptrs. That's how we discover whether any
// instance has been deleted during the lifespan of a snapshot.
- typedef std::vector<std::pair<const KEY, std::weak_ptr<T>>> VectorType;
+ typedef std::vector<std::pair<const KEY, weak_t>> VectorType;
// Dereferencing our iterator produces a std::shared_ptr for each
// instance that still exists. Since we store weak_ptrs, that involves
// two chained transformations:
@@ -98,7 +119,7 @@ public:
// It is very important that we filter lazily, that is, during
// traversal. Any one of our stored weak_ptrs might expire during
// traversal.
- typedef std::pair<const KEY, std::shared_ptr<T>> strong_pair;
+ typedef std::pair<const KEY, ptr_t> strong_pair;
// Note for future reference: nat has not yet had any luck (up to
// Boost 1.67) trying to use boost::transform_iterator with a hand-
// coded functor, only with actual functions. In my experience, an
@@ -202,17 +223,12 @@ public:
iterator end() { return iterator(snapshot::end(), key_getter); }
};
- static T* getInstance(const KEY& k)
+ static ptr_t getInstance(const KEY& k)
{
LockStatic lock;
const InstanceMap& map(lock->mMap);
typename InstanceMap::const_iterator found = map.find(k);
- return (found == map.end()) ? NULL : found->second.get();
- }
-
- static S32 instanceCount()
- {
- return LockStatic()->mMap.size();
+ return (found == map.end()) ? NULL : found->second;
}
protected:
@@ -222,7 +238,9 @@ protected:
// shared_ptr, so give it a no-op deleter. We store shared_ptrs in our
// InstanceMap specifically so snapshot can store weak_ptrs so we can
// detect deletions during traversals.
- std::shared_ptr<T> ptr(static_cast<T*>(this), [](T*){});
+ ptr_t ptr(static_cast<T*>(this), [](T*){});
+ // save corresponding weak_ptr for future reference
+ mSelf = ptr;
LockStatic lock;
add_(lock, key, ptr);
}
@@ -257,7 +275,7 @@ private:
static std::string report(const char* key) { return report(std::string(key)); }
// caller must instantiate LockStatic
- void add_(LockStatic& lock, const KEY& key, const std::shared_ptr<T>& ptr)
+ void add_(LockStatic& lock, const KEY& key, const ptr_t& ptr)
{
mInstanceKey = key;
InstanceMap& map = lock->mMap;
@@ -281,7 +299,7 @@ private:
break;
}
}
- std::shared_ptr<T> remove_(LockStatic& lock)
+ ptr_t remove_(LockStatic& lock)
{
InstanceMap& map = lock->mMap;
typename InstanceMap::iterator iter = map.find(mInstanceKey);
@@ -295,6 +313,9 @@ private:
}
private:
+ // Storing a weak_ptr to self is a bit like deriving from
+ // std::enable_shared_from_this(), except more explicit.
+ weak_t mSelf;
KEY mInstanceKey;
};
@@ -326,6 +347,9 @@ class LLInstanceTracker<T, void, KEY_COLLISION_BEHAVIOR>
typedef llthread::LockStatic<StaticData> LockStatic;
public:
+ using ptr_t = std::shared_ptr<T>;
+ using weak_t = std::weak_ptr<T>;
+
/**
* Storing a dumb T* somewhere external is a bad idea, since
* LLInstanceTracker subclasses are explicitly destroyed rather than
@@ -334,12 +358,15 @@ public:
* std::weak_ptr<T>, which will become invalid when the T instance is
* destroyed.
*/
- std::weak_ptr<T> getWeak()
+ weak_t getWeak()
{
return mSelf;
}
- static S32 instanceCount() { return LockStatic()->mSet.size(); }
+ static S32 instanceCount()
+ {
+ return LockStatic()->mSet.size();
+ }
// snapshot of std::shared_ptr<T> pointers
class snapshot
@@ -347,7 +374,7 @@ public:
// It's very important that what we store in this snapshot are
// weak_ptrs, NOT shared_ptrs. That's how we discover whether any
// instance has been deleted during the lifespan of a snapshot.
- typedef std::vector<std::weak_ptr<T>> VectorType;
+ typedef std::vector<weak_t> VectorType;
// Dereferencing our iterator produces a std::shared_ptr for each
// instance that still exists. Since we store weak_ptrs, that involves
// two chained transformations:
@@ -453,7 +480,7 @@ protected:
private:
// Storing a weak_ptr to self is a bit like deriving from
// std::enable_shared_from_this(), except more explicit.
- std::weak_ptr<T> mSelf;
+ weak_t mSelf;
};
#endif
diff --git a/indra/llcommon/llleaplistener.cpp b/indra/llcommon/llleaplistener.cpp
index 3e6ce9092c..11bfec1b31 100644
--- a/indra/llcommon/llleaplistener.cpp
+++ b/indra/llcommon/llleaplistener.cpp
@@ -220,7 +220,7 @@ void LLLeapListener::getAPI(const LLSD& request) const
{
Response reply(LLSD(), request);
- LLEventAPI* found = LLEventAPI::getInstance(request["api"]);
+ auto found = LLEventAPI::getInstance(request["api"]);
if (found)
{
reply["name"] = found->getName();
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index ea84e4c1ea..849867586a 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -82,6 +82,7 @@ void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size)
//static
void LLMemory::updateMemoryInfo()
{
+ LL_PROFILE_ZONE_SCOPED
#if LL_WINDOWS
PROCESS_MEMORY_COUNTERS counters;
@@ -145,6 +146,7 @@ void* LLMemory::tryToAlloc(void* address, U32 size)
//static
void LLMemory::logMemoryInfo(BOOL update)
{
+ LL_PROFILE_ZONE_SCOPED
if(update)
{
updateMemoryInfo() ;
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 24f86cc11e..41023b4ba4 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -101,6 +101,29 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
#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) \
+ { \
+ return ll_aligned_malloc_16(size); \
+ } \
+ \
+ void operator delete(void* ptr) \
+ { \
+ ll_aligned_free_16(ptr); \
+ } \
+ \
+ void* operator new[](size_t size) \
+ { \
+ return ll_aligned_malloc_16(size); \
+ } \
+ \
+ void operator delete[](void* ptr) \
+ { \
+ ll_aligned_free_16(ptr); \
+ }
+
+
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// for enable buffer overrun detection predefine LL_DEBUG_BUFFER_OVERRUN in current library
@@ -113,8 +136,9 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
#else
inline void* ll_aligned_malloc_fallback( size_t size, int align )
{
+ LL_PROFILE_ZONE_SCOPED;
#if defined(LL_WINDOWS)
- return _aligned_malloc(size, align);
+ void* ret = _aligned_malloc(size, align);
#else
char* aligned = NULL;
void* mem = malloc( size + (align - 1) + sizeof(void*) );
@@ -125,12 +149,16 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
((void**)aligned)[-1] = mem;
}
- return aligned;
+ void* ret = aligned;
#endif
+ LL_PROFILE_ALLOC(ret, size);
+ return ret;
}
inline void ll_aligned_free_fallback( void* ptr )
{
+ LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_FREE(ptr);
#if defined(LL_WINDOWS)
_aligned_free(ptr);
#else
@@ -146,21 +174,24 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16().
{
+ LL_PROFILE_ZONE_SCOPED;
#if defined(LL_WINDOWS)
- return _aligned_malloc(size, 16);
+ void* ret = _aligned_malloc(size, 16);
#elif defined(LL_DARWIN)
- return malloc(size); // default osx malloc is 16 byte aligned.
+ void* ret = malloc(size); // default osx malloc is 16 byte aligned.
#else
- void *rtn;
- if (LL_LIKELY(0 == posix_memalign(&rtn, 16, size)))
- return rtn;
- else // bad alignment requested, or out of memory
- return NULL;
+ void *ret;
+ if (0 != posix_memalign(&ret, 16, size))
+ return nullptr;
#endif
+ LL_PROFILE_ALLOC(ret, size);
+ return ret;
}
inline void ll_aligned_free_16(void *p)
{
+ LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_FREE(p);
#if defined(LL_WINDOWS)
_aligned_free(p);
#elif defined(LL_DARWIN)
@@ -172,10 +203,12 @@ inline void ll_aligned_free_16(void *p)
inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // returned hunk MUST be freed with ll_aligned_free_16().
{
+ LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_FREE(ptr);
#if defined(LL_WINDOWS)
- return _aligned_realloc(ptr, size, 16);
+ void* ret = _aligned_realloc(ptr, size, 16);
#elif defined(LL_DARWIN)
- return realloc(ptr,size); // default osx malloc is 16 byte aligned.
+ void* ret = realloc(ptr,size); // default osx malloc is 16 byte aligned.
#else
//FIXME: memcpy is SLOW
void* ret = ll_aligned_malloc_16(size);
@@ -188,27 +221,31 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // r
}
ll_aligned_free_16(ptr);
}
- return ret;
#endif
+ LL_PROFILE_ALLOC(ptr, size);
+ return ret;
}
inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32().
{
+ LL_PROFILE_ZONE_SCOPED;
#if defined(LL_WINDOWS)
- return _aligned_malloc(size, 32);
+ void* ret = _aligned_malloc(size, 32);
#elif defined(LL_DARWIN)
- return ll_aligned_malloc_fallback( size, 32 );
+ void* ret = ll_aligned_malloc_fallback( size, 32 );
#else
- void *rtn;
- if (LL_LIKELY(0 == posix_memalign(&rtn, 32, size)))
- return rtn;
- else // bad alignment requested, or out of memory
- return NULL;
+ void *ret;
+ if (0 != posix_memalign(&ret, 32, size))
+ return nullptr;
#endif
+ LL_PROFILE_ALLOC(ret, size);
+ return ret;
}
inline void ll_aligned_free_32(void *p)
{
+ LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_FREE(p);
#if defined(LL_WINDOWS)
_aligned_free(p);
#elif defined(LL_DARWIN)
@@ -222,29 +259,35 @@ inline void ll_aligned_free_32(void *p)
template<size_t ALIGNMENT>
LL_FORCE_INLINE void* ll_aligned_malloc(size_t size)
{
+ LL_PROFILE_ZONE_SCOPED;
+ void* ret;
if (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0)
{
- return malloc(size);
+ ret = malloc(size);
+ LL_PROFILE_ALLOC(ret, size);
}
else if (ALIGNMENT == 16)
{
- return ll_aligned_malloc_16(size);
+ ret = ll_aligned_malloc_16(size);
}
else if (ALIGNMENT == 32)
{
- return ll_aligned_malloc_32(size);
+ ret = ll_aligned_malloc_32(size);
}
else
{
- return ll_aligned_malloc_fallback(size, ALIGNMENT);
+ ret = ll_aligned_malloc_fallback(size, ALIGNMENT);
}
+ return ret;
}
template<size_t ALIGNMENT>
LL_FORCE_INLINE void ll_aligned_free(void* ptr)
{
+ LL_PROFILE_ZONE_SCOPED;
if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN)
{
+ LL_PROFILE_FREE(ptr);
free(ptr);
}
else if (ALIGNMENT == 16)
@@ -266,6 +309,7 @@ LL_FORCE_INLINE void ll_aligned_free(void* ptr)
//
inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes)
{
+ LL_PROFILE_ZONE_SCOPED;
assert(src != NULL);
assert(dst != NULL);
assert(bytes > 0);
diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp
index 4d73c04d07..a49002b5dc 100644
--- a/indra/llcommon/llmutex.cpp
+++ b/indra/llcommon/llmutex.cpp
@@ -44,6 +44,7 @@ LLMutex::~LLMutex()
void LLMutex::lock()
{
+ LL_PROFILE_ZONE_SCOPED
if(isSelfLocked())
{ //redundant lock
mCount++;
@@ -65,6 +66,7 @@ void LLMutex::lock()
void LLMutex::unlock()
{
+ LL_PROFILE_ZONE_SCOPED
if (mCount > 0)
{ //not the root unlock
mCount--;
@@ -85,6 +87,7 @@ void LLMutex::unlock()
bool LLMutex::isLocked()
{
+ LL_PROFILE_ZONE_SCOPED
if (!mMutex.try_lock())
{
return true;
@@ -108,6 +111,7 @@ LLThread::id_t LLMutex::lockingThread() const
bool LLMutex::trylock()
{
+ LL_PROFILE_ZONE_SCOPED
if(isSelfLocked())
{ //redundant lock
mCount++;
@@ -146,17 +150,20 @@ LLCondition::~LLCondition()
void LLCondition::wait()
{
+ LL_PROFILE_ZONE_SCOPED
std::unique_lock< std::mutex > lock(mMutex);
mCond.wait(lock);
}
void LLCondition::signal()
{
+ LL_PROFILE_ZONE_SCOPED
mCond.notify_one();
}
void LLCondition::broadcast()
{
+ LL_PROFILE_ZONE_SCOPED
mCond.notify_all();
}
@@ -166,6 +173,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex)
: mMutex(mutex),
mLocked(false)
{
+ LL_PROFILE_ZONE_SCOPED
if (mMutex)
mLocked = mMutex->trylock();
}
@@ -174,6 +182,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms)
: mMutex(mutex),
mLocked(false)
{
+ LL_PROFILE_ZONE_SCOPED
if (!mMutex)
return;
@@ -188,6 +197,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms)
LLMutexTrylock::~LLMutexTrylock()
{
+ LL_PROFILE_ZONE_SCOPED
if (mMutex && mLocked)
mMutex->unlock();
}
@@ -199,6 +209,7 @@ LLMutexTrylock::~LLMutexTrylock()
//
LLScopedLock::LLScopedLock(std::mutex* mutex) : mMutex(mutex)
{
+ LL_PROFILE_ZONE_SCOPED
if(mutex)
{
mutex->lock();
@@ -217,6 +228,7 @@ LLScopedLock::~LLScopedLock()
void LLScopedLock::unlock()
{
+ LL_PROFILE_ZONE_SCOPED
if(mLocked)
{
mMutex->unlock();
diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h
new file mode 100644
index 0000000000..ca60d23248
--- /dev/null
+++ b/indra/llcommon/llprofiler.h
@@ -0,0 +1,111 @@
+/**
+ * @file llprofiler.h
+ * @brief Wrapper for Tracy and/or other profilers
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, 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_PROFILER_H
+#define LL_PROFILER_H
+
+#define LL_PROFILER_CONFIG_NONE 0 // No profiling
+#define LL_PROFILER_CONFIG_FAST_TIMER 1 // Profiling on: Only Fast Timers
+#define LL_PROFILER_CONFIG_TRACY 2 // Profiling on: Only Tracy
+#define LL_PROFILER_CONFIG_TRACY_FAST_TIMER 3 // Profiling on: Fast Timers + Tracy
+
+#ifndef LL_PROFILER_CONFIGURATION
+#define LL_PROFILER_CONFIGURATION LL_PROFILER_CONFIG_FAST_TIMER
+#endif
+
+extern thread_local bool gProfilerEnabled;
+
+#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
+ #define TRACY_ENABLE 1
+// Normally these would be enabled but we want to be able to build any viewer with Tracy enabled and run the Tracy server on another machine
+// They must be undefined in order to work across multiple machines
+// #define TRACY_NO_BROADCAST 1
+// #define TRACY_ONLY_LOCALHOST 1
+ #define TRACY_ONLY_IPV4 1
+ #include "Tracy.hpp"
+
+ // Mutually exclusive with detailed memory tracing
+ #define LL_PROFILER_ENABLE_TRACY_OPENGL 0
+ #endif
+
+ #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY
+ #define LL_PROFILER_FRAME_END FrameMark
+ #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); gProfilerEnabled = true;
+ #define LL_RECORD_BLOCK_TIME(name) ZoneScoped // Want descriptive names; was: ZoneNamedN( ___tracy_scoped_zone, #name, true );
+ #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true );
+ #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB
+ #define LL_PROFILE_ZONE_SCOPED ZoneScoped
+
+ #define LL_PROFILE_ZONE_NUM( val ) ZoneValue( val )
+ #define LL_PROFILE_ZONE_TEXT( text, size ) ZoneText( text, size )
+
+ #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow
+ #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan
+ #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red
+ #define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size)
+ #define LL_PROFILE_FREE(ptr) TracyFree(ptr)
+ #endif
+ #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER
+ #define LL_PROFILER_FRAME_END
+ #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name)
+ #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__);
+ #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled
+ #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled
+ #define LL_PROFILE_ZONE_COLOR(name,color) // LL_RECORD_BLOCK_TIME(name)
+
+ #define LL_PROFILE_ZONE_NUM( val ) (void)( val ); // Not supported
+ #define LL_PROFILE_ZONE_TEXT( text, size ) (void)( text ); void( size ); // Not supported
+
+ #define LL_PROFILE_ZONE_ERR(name) (void)(name); // Not supported
+ #define LL_PROFILE_ZONE_INFO(name) (void)(name); // Not supported
+ #define LL_PROFILE_ZONE_WARN(name) (void)(name); // Not supported
+ #define LL_PROFILE_ALLOC(ptr, size) (void)(ptr); (void)(size);
+ #define LL_PROFILE_FREE(ptr) (void)(ptr);
+ #endif
+ #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER
+ #define LL_PROFILER_FRAME_END FrameMark
+ #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); gProfilerEnabled = true;
+ #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN(___tracy_scoped_zone, #name, true); const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__);
+ #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true );
+ #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB
+ #define LL_PROFILE_ZONE_SCOPED ZoneScoped
+
+ #define LL_PROFILE_ZONE_NUM( val ) ZoneValue( val )
+ #define LL_PROFILE_ZONE_TEXT( text, size ) ZoneText( text, size )
+
+ #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow
+ #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan
+ #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red
+ #define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size)
+ #define LL_PROFILE_FREE(ptr) TracyFree(ptr)
+ #endif
+#else
+ #define LL_PROFILER_FRAME_END
+ #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name)
+#endif // LL_PROFILER
+
+#endif // LL_PROFILER_H
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 57b746889d..605f6bf0e3 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -400,6 +400,7 @@ namespace
ImplMap& ImplMap::makeMap(LLSD::Impl*& var)
{
+ LL_PROFILE_ZONE_SCOPED;
if (shared())
{
ImplMap* i = new ImplMap(mData);
@@ -414,18 +415,21 @@ namespace
bool ImplMap::has(const LLSD::String& k) const
{
+ LL_PROFILE_ZONE_SCOPED;
DataMap::const_iterator i = mData.find(k);
return i != mData.end();
}
LLSD ImplMap::get(const LLSD::String& k) const
{
+ LL_PROFILE_ZONE_SCOPED;
DataMap::const_iterator i = mData.find(k);
return (i != mData.end()) ? i->second : LLSD();
}
LLSD ImplMap::getKeys() const
{
+ LL_PROFILE_ZONE_SCOPED;
LLSD keys = LLSD::emptyArray();
DataMap::const_iterator iter = mData.begin();
while (iter != mData.end())
@@ -438,11 +442,13 @@ namespace
void ImplMap::insert(const LLSD::String& k, const LLSD& v)
{
+ LL_PROFILE_ZONE_SCOPED;
mData.insert(DataMap::value_type(k, v));
}
void ImplMap::erase(const LLSD::String& k)
{
+ LL_PROFILE_ZONE_SCOPED;
mData.erase(k);
}
@@ -684,6 +690,7 @@ const LLSD::Impl& LLSD::Impl::safe(const Impl* impl)
ImplMap& LLSD::Impl::makeMap(Impl*& var)
{
+ LL_PROFILE_ZONE_SCOPED;
ImplMap* im = new ImplMap;
reset(var, im);
return *im;
@@ -887,11 +894,16 @@ LLSD& LLSD::with(const String& k, const LLSD& v)
}
void LLSD::erase(const String& k) { makeMap(impl).erase(k); }
-LLSD& LLSD::operator[](const String& k)
- { return makeMap(impl).ref(k); }
+LLSD& LLSD::operator[](const String& k)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ return makeMap(impl).ref(k);
+}
const LLSD& LLSD::operator[](const String& k) const
- { return safe(impl).ref(k); }
-
+{
+ LL_PROFILE_ZONE_SCOPED;
+ return safe(impl).ref(k);
+}
LLSD LLSD::emptyArray()
{
@@ -914,10 +926,16 @@ LLSD& LLSD::with(Integer i, const LLSD& v)
LLSD& LLSD::append(const LLSD& v) { return makeArray(impl).append(v); }
void LLSD::erase(Integer i) { makeArray(impl).erase(i); }
-LLSD& LLSD::operator[](Integer i)
- { return makeArray(impl).ref(i); }
+LLSD& LLSD::operator[](Integer i)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ return makeArray(impl).ref(i);
+}
const LLSD& LLSD::operator[](Integer i) const
- { return safe(impl).ref(i); }
+{
+ LL_PROFILE_ZONE_SCOPED;
+ return safe(impl).ref(i);
+}
static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
{
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index 5b6d5545af..b8ddf21596 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -290,9 +290,17 @@ public:
LLSD& with(const String&, const LLSD&);
LLSD& operator[](const String&);
- LLSD& operator[](const char* c) { return (*this)[String(c)]; }
+ LLSD& operator[](const char* c)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ return (*this)[String(c)];
+ }
const LLSD& operator[](const String&) const;
- const LLSD& operator[](const char* c) const { return (*this)[String(c)]; }
+ const LLSD& operator[](const char* c) const
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ return (*this)[String(c)];
+ }
//@}
/** @name Array Values */
diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
index 2e7b46f885..af4ccf25fd 100644
--- a/indra/llcommon/llsdparam.cpp
+++ b/indra/llcommon/llsdparam.cpp
@@ -37,8 +37,6 @@ static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs;
static LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs;
static const LLSD NO_VALUE_MARKER;
-LLTrace::BlockTimerStatHandle FTM_SD_PARAM_ADAPTOR("LLSD to LLInitParam conversion");
-
//
// LLParamSDParser
//
diff --git a/indra/llcommon/llsdparam.h b/indra/llcommon/llsdparam.h
index 93910b70ae..82a623a8a0 100644
--- a/indra/llcommon/llsdparam.h
+++ b/indra/llcommon/llsdparam.h
@@ -110,7 +110,6 @@ private:
};
-extern LL_COMMON_API LLTrace::BlockTimerStatHandle FTM_SD_PARAM_ADAPTOR;
template<typename T>
class LLSDParamAdapter : public T
{
@@ -118,7 +117,7 @@ public:
LLSDParamAdapter() {}
LLSDParamAdapter(const LLSD& sd)
{
- LL_RECORD_BLOCK_TIME(FTM_SD_PARAM_ADAPTOR);
+ LL_PROFILE_ZONE_SCOPED;
LLParamSDParser parser;
// don't spam for implicit parsing of LLSD, as we want to allow arbitrary freeform data and ignore most of it
bool parse_silently = true;
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index eb3a96b133..c2fe15e9b7 100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
@@ -214,6 +214,8 @@ BOOL compare_llsd_with_template(
const LLSD& template_llsd,
LLSD& resultant_llsd)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (
llsd_to_test.isUndefined() &&
template_llsd.isDefined() )
@@ -335,6 +337,8 @@ bool filter_llsd_with_template(
const LLSD & template_llsd,
LLSD & resultant_llsd)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (llsd_to_test.isUndefined() && template_llsd.isDefined())
{
resultant_llsd = template_llsd;
@@ -529,6 +533,8 @@ class TypeLookup
public:
TypeLookup()
{
+ LL_PROFILE_ZONE_SCOPED
+
for (const Data *di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di)
{
mMap[di->type] = di->name;
@@ -537,6 +543,8 @@ public:
std::string lookup(LLSD::Type type) const
{
+ LL_PROFILE_ZONE_SCOPED
+
MapType::const_iterator found = mMap.find(type);
if (found != mMap.end())
{
@@ -587,6 +595,8 @@ static std::string match_types(LLSD::Type expect, // prototype.type()
LLSD::Type actual, // type we're checking
const std::string& pfx) // as for llsd_matches
{
+ LL_PROFILE_ZONE_SCOPED
+
// Trivial case: if the actual type is exactly what we expect, we're good.
if (actual == expect)
return "";
@@ -624,6 +634,8 @@ static std::string match_types(LLSD::Type expect, // prototype.type()
// see docstring in .h file
std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::string& pfx)
{
+ LL_PROFILE_ZONE_SCOPED
+
// An undefined prototype means that any data is valid.
// An undefined slot in an array or map prototype means that any data
// may fill that slot.
@@ -756,6 +768,8 @@ std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::str
bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits)
{
+ LL_PROFILE_ZONE_SCOPED
+
// We're comparing strict equality of LLSD representation rather than
// performing any conversions. So if the types aren't equal, the LLSD
// values aren't equal.
@@ -864,6 +878,8 @@ namespace llsd
LLSD& drill(LLSD& blob, const LLSD& rawPath)
{
+ LL_PROFILE_ZONE_SCOPED
+
// Treat rawPath uniformly as an array. If it's not already an array,
// store it as the only entry in one. (But let's say Undefined means an
// empty array.)
@@ -889,6 +905,8 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath)
// path entry that's bad.
for (LLSD::Integer i = 0; i < path.size(); ++i)
{
+ LL_PROFILE_ZONE_NUM( i )
+
const LLSD& key{path[i]};
if (key.isString())
{
@@ -917,6 +935,8 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath)
LLSD drill(const LLSD& blob, const LLSD& path)
{
+ LL_PROFILE_ZONE_SCOPED
+
// non-const drill() does exactly what we want. Temporarily cast away
// const-ness and use that.
return drill(const_cast<LLSD&>(blob), path);
@@ -929,6 +949,8 @@ LLSD drill(const LLSD& blob, const LLSD& path)
// filter may be include to exclude/include keys in a map.
LLSD llsd_clone(LLSD value, LLSD filter)
{
+ LL_PROFILE_ZONE_SCOPED
+
LLSD clone;
bool has_filter(filter.isMap());
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 7c81d65a8b..10a8ecfedb 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -455,6 +455,7 @@ public:
static DERIVED_TYPE* getInstance()
{
+ LL_PROFILE_ZONE_SCOPED;
// We know the viewer has LLSingleton dependency circularities. If you
// feel strongly motivated to eliminate them, cheers and good luck.
// (At that point we could consider a much simpler locking mechanism.)
@@ -838,4 +839,30 @@ private: \
/* LLSINGLETON() is carefully implemented to permit exactly this */ \
LLSINGLETON_C11(DERIVED_CLASS) {}
+// Relatively unsafe singleton implementation that is much faster
+// and simpler than LLSingleton, but has no dependency tracking
+// or inherent thread safety and requires manual invocation of
+// createInstance before first use.
+template<class T>
+class LLSimpleton
+{
+public:
+ static T* sInstance;
+
+ static void createInstance()
+ {
+ llassert(sInstance == nullptr);
+ sInstance = new T();
+ }
+
+ static inline T* getInstance() { return sInstance; }
+ static inline T& instance() { return *getInstance(); }
+ static inline bool instanceExists() { return sInstance != nullptr; }
+
+ static void deleteSingleton() {
+ delete sInstance;
+ sInstance = nullptr;
+ }
+};
+
#endif
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 0290eea143..f6f9f97809 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -37,9 +37,6 @@
#include <winnls.h> // for WideCharToMultiByte
#endif
-LLTrace::BlockTimerStatHandle FT_STRING_FORMAT("String Format");
-
-
std::string ll_safe_string(const char* in)
{
if(in) return std::string(in);
@@ -1356,7 +1353,7 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
template<>
S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions)
{
- LL_RECORD_BLOCK_TIME(FT_STRING_FORMAT);
+ LL_PROFILE_ZONE_SCOPED;
S32 res = 0;
std::string output;
@@ -1429,7 +1426,7 @@ S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions)
template<>
S32 LLStringUtil::format(std::string& s, const LLSD& substitutions)
{
- LL_RECORD_BLOCK_TIME(FT_STRING_FORMAT);
+ LL_PROFILE_ZONE_SCOPED;
S32 res = 0;
if (!substitutions.isMap())
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 2ca15a31c6..18f4684b49 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -828,6 +828,7 @@ LLSD LLMemoryInfo::getStatsMap() const
LLMemoryInfo& LLMemoryInfo::refresh()
{
+ LL_PROFILE_ZONE_SCOPED
mStatsMap = loadStatsMap();
LL_DEBUGS("LLMemoryInfo") << "Populated mStatsMap:\n";
@@ -837,11 +838,9 @@ LLMemoryInfo& LLMemoryInfo::refresh()
return *this;
}
-static LLTrace::BlockTimerStatHandle FTM_MEMINFO_LOAD_STATS("MemInfo Load Stats");
-
LLSD LLMemoryInfo::loadStatsMap()
{
- LL_RECORD_BLOCK_TIME(FTM_MEMINFO_LOAD_STATS);
+ LL_PROFILE_ZONE_SCOPED;
// This implementation is derived from stream() code (as of 2011-06-29).
Stats stats;
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 6d531d842d..11f5a015f1 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -135,6 +135,8 @@ void LLThread::threadRun()
set_thread_name(-1, mName.c_str());
#endif
+ LL_PROFILER_SET_THREAD_NAME( mName.c_str() );
+
// this is the first point at which we're actually running in the new thread
mID = currentID();
@@ -331,6 +333,7 @@ bool LLThread::runCondition(void)
// Stop thread execution if requested until unpaused.
void LLThread::checkPause()
{
+ LL_PROFILE_ZONE_SCOPED
mDataLock->lock();
// This is in a while loop because the pthread API allows for spurious wakeups.
@@ -362,17 +365,20 @@ void LLThread::setQuitting()
// static
LLThread::id_t LLThread::currentID()
{
+ LL_PROFILE_ZONE_SCOPED
return std::this_thread::get_id();
}
// static
void LLThread::yield()
{
+ LL_PROFILE_ZONE_SCOPED
std::this_thread::yield();
}
void LLThread::wake()
{
+ LL_PROFILE_ZONE_SCOPED
mDataLock->lock();
if(!shouldSleep())
{
@@ -383,6 +389,7 @@ void LLThread::wake()
void LLThread::wakeLocked()
{
+ LL_PROFILE_ZONE_SCOPED
if(!shouldSleep())
{
mRunCondition->signal();
@@ -391,11 +398,13 @@ void LLThread::wakeLocked()
void LLThread::lockData()
{
+ LL_PROFILE_ZONE_SCOPED
mDataLock->lock();
}
void LLThread::unlockData()
{
+ LL_PROFILE_ZONE_SCOPED
mDataLock->unlock();
}
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 26e0d71d31..06e8d8f609 100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -1,6 +1,6 @@
/**
* @file llthreadsafequeue.h
- * @brief Base classes for thread, mutex and condition handling.
+ * @brief Queue protected with mutexes for cross-thread use
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -27,16 +27,19 @@
#ifndef LL_LLTHREADSAFEQUEUE_H
#define LL_LLTHREADSAFEQUEUE_H
-#include "llexception.h"
-#include <deque>
-#include <string>
-#include <chrono>
-#include "mutex.h"
#include "llcoros.h"
#include LLCOROS_MUTEX_HEADER
#include <boost/fiber/timed_mutex.hpp>
#include LLCOROS_CONDVAR_HEADER
+#include "llexception.h"
+#include "mutex.h"
+#include <chrono>
+#include <queue>
+#include <string>
+/*****************************************************************************
+* LLThreadSafeQueue
+*****************************************************************************/
//
// A general queue exception.
//
@@ -66,70 +69,111 @@ public:
}
};
-//
-// Implements a thread safe FIFO.
-//
-template<typename ElementT>
+/**
+ * Implements a thread safe FIFO.
+ */
+// Let the default std::queue default to underlying std::deque. Override if
+// desired.
+template<typename ElementT, typename QueueT=std::queue<ElementT>>
class LLThreadSafeQueue
{
public:
typedef ElementT value_type;
-
- // If the pool is set to NULL one will be allocated and managed by this
- // queue.
+
+ // Limiting the number of pending items prevents unbounded growth of the
+ // underlying queue.
LLThreadSafeQueue(U32 capacity = 1024);
-
- // Add an element to the front of queue (will block if the queue has
+ virtual ~LLThreadSafeQueue() {}
+
+ // Add an element to the queue (will block if the queue has
// reached capacity).
//
// This call will raise an interrupt error if the queue is closed while
// the caller is blocked.
- void pushFront(ElementT const & element);
-
- // Try to add an element to the front of queue without blocking. Returns
+ template <typename T>
+ void push(T&& element);
+ // legacy name
+ void pushFront(ElementT const & element) { return push(element); }
+
+ // Try to add an element to the queue without blocking. Returns
// true only if the element was actually added.
- bool tryPushFront(ElementT const & element);
+ template <typename T>
+ bool tryPush(T&& element);
+ // legacy name
+ bool tryPushFront(ElementT const & element) { return tryPush(element); }
- // Try to add an element to the front of queue, blocking if full but with
- // timeout. Returns true if the element was added.
+ // Try to add an element to the queue, blocking if full but with timeout
+ // after specified duration. Returns true if the element was added.
// There are potentially two different timeouts involved: how long to try
// to lock the mutex, versus how long to wait for the queue to stop being
// full. Careful settings for each timeout might be orders of magnitude
// apart. However, this method conflates them.
+ template <typename Rep, typename Period, typename T>
+ bool tryPushFor(const std::chrono::duration<Rep, Period>& timeout,
+ T&& element);
+ // legacy name
template <typename Rep, typename Period>
bool tryPushFrontFor(const std::chrono::duration<Rep, Period>& timeout,
- ElementT const & element);
+ ElementT const & element) { return tryPushFor(timeout, element); }
- // Pop the element at the end of the queue (will block if the queue is
+ // Try to add an element to the queue, blocking if full but with
+ // timeout at specified time_point. Returns true if the element was added.
+ template <typename Clock, typename Duration, typename T>
+ bool tryPushUntil(const std::chrono::time_point<Clock, Duration>& until,
+ T&& element);
+ // no legacy name because this is a newer method
+
+ // Pop the element at the head of the queue (will block if the queue is
// empty).
//
// This call will raise an interrupt error if the queue is closed while
// the caller is blocked.
- ElementT popBack(void);
-
- // Pop an element from the end of the queue if there is one available.
+ ElementT pop(void);
+ // legacy name
+ ElementT popBack(void) { return pop(); }
+
+ // Pop an element from the head of the queue if there is one available.
// Returns true only if an element was popped.
- bool tryPopBack(ElementT & element);
-
+ bool tryPop(ElementT & element);
+ // legacy name
+ bool tryPopBack(ElementT & element) { return tryPop(element); }
+
+ // Pop the element at the head of the queue, blocking if empty, with
+ // timeout after specified duration. Returns true if an element was popped.
+ template <typename Rep, typename Period>
+ bool tryPopFor(const std::chrono::duration<Rep, Period>& timeout, ElementT& element);
+ // no legacy name because this is a newer method
+
+ // Pop the element at the head of the queue, blocking if empty, with
+ // timeout at specified time_point. Returns true if an element was popped.
+ template <typename Clock, typename Duration>
+ bool tryPopUntil(const std::chrono::time_point<Clock, Duration>& until,
+ ElementT& element);
+ // no legacy name because this is a newer method
+
// Returns the size of the queue.
size_t size();
+ //Returns the capacity of the queue.
+ U32 capacity() { return mCapacity; }
+
// closes the queue:
- // - every subsequent pushFront() call will throw LLThreadSafeQueueInterrupt
- // - every subsequent tryPushFront() call will return false
- // - popBack() calls will return normally until the queue is drained, then
- // every subsequent popBack() will throw LLThreadSafeQueueInterrupt
- // - tryPopBack() calls will return normally until the queue is drained,
- // then every subsequent tryPopBack() call will return false
+ // - every subsequent push() call will throw LLThreadSafeQueueInterrupt
+ // - every subsequent tryPush() call will return false
+ // - pop() calls will return normally until the queue is drained, then
+ // every subsequent pop() will throw LLThreadSafeQueueInterrupt
+ // - tryPop() calls will return normally until the queue is drained,
+ // then every subsequent tryPop() call will return false
void close();
- // detect closed state
+ // producer end: are we prevented from pushing any additional items?
bool isClosed();
- // inverse of isClosed()
- explicit operator bool();
+ // consumer end: are we done, is the queue entirely drained?
+ bool done();
-private:
- std::deque< ElementT > mStorage;
+protected:
+ typedef QueueT queue_type;
+ QueueT mStorage;
U32 mCapacity;
bool mClosed;
@@ -137,37 +181,152 @@ private:
typedef std::unique_lock<decltype(mLock)> lock_t;
boost::fibers::condition_variable_any mCapacityCond;
boost::fibers::condition_variable_any mEmptyCond;
-};
-// LLThreadSafeQueue
-//-----------------------------------------------------------------------------
+ enum pop_result { EMPTY, DONE, WAITING, POPPED };
+ // implementation logic, suitable for passing to tryLockUntil()
+ template <typename Clock, typename Duration>
+ pop_result tryPopUntil_(lock_t& lock,
+ const std::chrono::time_point<Clock, Duration>& until,
+ ElementT& element);
+ // if we're able to lock immediately, do so and run the passed callable,
+ // which must accept lock_t& and return bool
+ template <typename CALLABLE>
+ bool tryLock(CALLABLE&& callable);
+ // if we're able to lock before the passed time_point, do so and run the
+ // passed callable, which must accept lock_t& and return bool
+ template <typename Clock, typename Duration, typename CALLABLE>
+ bool tryLockUntil(const std::chrono::time_point<Clock, Duration>& until,
+ CALLABLE&& callable);
+ // while lock is locked, really push the passed element, if we can
+ template <typename T>
+ bool push_(lock_t& lock, T&& element);
+ // while lock is locked, really pop the head element, if we can
+ pop_result pop_(lock_t& lock, ElementT& element);
+ // Is the current head element ready to pop? We say yes; subclass can
+ // override as needed.
+ virtual bool canPop(const ElementT& head) const { return true; }
+};
-template<typename ElementT>
-LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(U32 capacity) :
+/*****************************************************************************
+* PriorityQueueAdapter
+*****************************************************************************/
+namespace LL
+{
+ /**
+ * std::priority_queue's API is almost like std::queue, intentionally of
+ * course, but you must access the element about to pop() as top() rather
+ * than as front(). Make an adapter for use with LLThreadSafeQueue.
+ */
+ template <typename T, typename Container=std::vector<T>,
+ typename Compare=std::less<typename Container::value_type>>
+ class PriorityQueueAdapter
+ {
+ public:
+ // publish all the same types
+ typedef std::priority_queue<T, Container, Compare> queue_type;
+ typedef typename queue_type::container_type container_type;
+ typedef typename queue_type::value_compare value_compare;
+ typedef typename queue_type::value_type value_type;
+ typedef typename queue_type::size_type size_type;
+ typedef typename queue_type::reference reference;
+ typedef typename queue_type::const_reference const_reference;
+
+ // Although std::queue defines both const and non-const front()
+ // methods, std::priority_queue defines only const top().
+ const_reference front() const { return mQ.top(); }
+ // std::priority_queue has no equivalent to back(), so it's good that
+ // LLThreadSafeQueue doesn't use it.
+
+ // All the rest of these merely forward to the corresponding
+ // queue_type methods.
+ bool empty() const { return mQ.empty(); }
+ size_type size() const { return mQ.size(); }
+ void push(const value_type& value) { mQ.push(value); }
+ void push(value_type&& value) { mQ.push(std::move(value)); }
+ template <typename... Args>
+ void emplace(Args&&... args) { mQ.emplace(std::forward<Args>(args)...); }
+ void pop() { mQ.pop(); }
+
+ private:
+ queue_type mQ;
+ };
+} // namespace LL
+
+
+/*****************************************************************************
+* LLThreadSafeQueue implementation
+*****************************************************************************/
+template<typename ElementT, typename QueueT>
+LLThreadSafeQueue<ElementT, QueueT>::LLThreadSafeQueue(U32 capacity) :
mCapacity(capacity),
mClosed(false)
{
}
-template<typename ElementT>
-void LLThreadSafeQueue<ElementT>::pushFront(ElementT const & element)
+// if we're able to lock immediately, do so and run the passed callable, which
+// must accept lock_t& and return bool
+template <typename ElementT, typename QueueT>
+template <typename CALLABLE>
+bool LLThreadSafeQueue<ElementT, QueueT>::tryLock(CALLABLE&& callable)
+{
+ lock_t lock1(mLock, std::defer_lock);
+ if (!lock1.try_lock())
+ return false;
+
+ return std::forward<CALLABLE>(callable)(lock1);
+}
+
+
+// if we're able to lock before the passed time_point, do so and run the
+// passed callable, which must accept lock_t& and return bool
+template <typename ElementT, typename QueueT>
+template <typename Clock, typename Duration, typename CALLABLE>
+bool LLThreadSafeQueue<ElementT, QueueT>::tryLockUntil(
+ const std::chrono::time_point<Clock, Duration>& until,
+ CALLABLE&& callable)
+{
+ lock_t lock1(mLock, std::defer_lock);
+ if (!lock1.try_lock_until(until))
+ return false;
+
+ return std::forward<CALLABLE>(callable)(lock1);
+}
+
+
+// while lock is locked, really push the passed element, if we can
+template <typename ElementT, typename QueueT>
+template <typename T>
+bool LLThreadSafeQueue<ElementT, QueueT>::push_(lock_t& lock, T&& element)
+{
+ if (mStorage.size() >= mCapacity)
+ return false;
+
+ mStorage.push(std::forward<T>(element));
+ lock.unlock();
+ // now that we've pushed, if somebody's been waiting to pop, signal them
+ mEmptyCond.notify_one();
+ return true;
+}
+
+
+template <typename ElementT, typename QueueT>
+template<typename T>
+void LLThreadSafeQueue<ElementT, QueueT>::push(T&& element)
{
lock_t lock1(mLock);
while (true)
{
+ // On the producer side, it doesn't matter whether the queue has been
+ // drained or not: the moment either end calls close(), further push()
+ // operations will fail.
if (mClosed)
{
LLTHROW(LLThreadSafeQueueInterrupt());
}
- if (mStorage.size() < mCapacity)
- {
- mStorage.push_front(element);
- lock1.unlock();
- mEmptyCond.notify_one();
+ if (push_(lock1, std::forward<T>(element)))
return;
- }
// Storage Full. Wait for signal.
mCapacityCond.wait(lock1);
@@ -175,142 +334,225 @@ void LLThreadSafeQueue<ElementT>::pushFront(ElementT const & element)
}
-template <typename ElementT>
-template <typename Rep, typename Period>
-bool LLThreadSafeQueue<ElementT>::tryPushFrontFor(const std::chrono::duration<Rep, Period>& timeout,
- ElementT const & element)
+template<typename ElementT, typename QueueT>
+template<typename T>
+bool LLThreadSafeQueue<ElementT, QueueT>::tryPush(T&& element)
{
- // Convert duration to time_point: passing the same timeout duration to
- // each of multiple calls is wrong.
- auto endpoint = std::chrono::steady_clock::now() + timeout;
+ return tryLock(
+ [this, element=std::move(element)](lock_t& lock)
+ {
+ if (mClosed)
+ return false;
+ return push_(lock, std::move(element));
+ });
+}
- lock_t lock1(mLock, std::defer_lock);
- if (!lock1.try_lock_until(endpoint))
- return false;
- while (true)
- {
- if (mClosed)
- {
- return false;
- }
+template <typename ElementT, typename QueueT>
+template <typename Rep, typename Period, typename T>
+bool LLThreadSafeQueue<ElementT, QueueT>::tryPushFor(
+ const std::chrono::duration<Rep, Period>& timeout,
+ T&& element)
+{
+ // Convert duration to time_point: passing the same timeout duration to
+ // each of multiple calls is wrong.
+ return tryPushUntil(std::chrono::steady_clock::now() + timeout,
+ std::forward<T>(element));
+}
- if (mStorage.size() < mCapacity)
- {
- mStorage.push_front(element);
- lock1.unlock();
- mEmptyCond.notify_one();
- return true;
- }
- // Storage Full. Wait for signal.
- if (LLCoros::cv_status::timeout == mCapacityCond.wait_until(lock1, endpoint))
+template <typename ElementT, typename QueueT>
+template <typename Clock, typename Duration, typename T>
+bool LLThreadSafeQueue<ElementT, QueueT>::tryPushUntil(
+ const std::chrono::time_point<Clock, Duration>& until,
+ T&& element)
+{
+ return tryLockUntil(
+ until,
+ [this, until, element=std::move(element)](lock_t& lock)
{
- // timed out -- formally we might recheck both conditions above
- return false;
- }
- // If we didn't time out, we were notified for some reason. Loop back
- // to check.
- }
+ while (true)
+ {
+ if (mClosed)
+ {
+ return false;
+ }
+
+ if (push_(lock, std::move(element)))
+ return true;
+
+ // Storage Full. Wait for signal.
+ if (LLCoros::cv_status::timeout == mCapacityCond.wait_until(lock, until))
+ {
+ // timed out -- formally we might recheck both conditions above
+ return false;
+ }
+ // If we didn't time out, we were notified for some reason. Loop back
+ // to check.
+ }
+ });
}
-template<typename ElementT>
-bool LLThreadSafeQueue<ElementT>::tryPushFront(ElementT const & element)
+// while lock is locked, really pop the head element, if we can
+template <typename ElementT, typename QueueT>
+typename LLThreadSafeQueue<ElementT, QueueT>::pop_result
+LLThreadSafeQueue<ElementT, QueueT>::pop_(lock_t& lock, ElementT& element)
{
- lock_t lock1(mLock, std::defer_lock);
- if (!lock1.try_lock())
- return false;
-
- if (mClosed)
- return false;
+ // If mStorage is empty, there's no head element.
+ if (mStorage.empty())
+ return mClosed? DONE : EMPTY;
- if (mStorage.size() >= mCapacity)
- return false;
+ // If there's a head element, pass it to canPop() to see if it's ready to pop.
+ if (! canPop(mStorage.front()))
+ return WAITING;
- mStorage.push_front(element);
- lock1.unlock();
- mEmptyCond.notify_one();
- return true;
+ // std::queue::front() is the element about to pop()
+ element = mStorage.front();
+ mStorage.pop();
+ lock.unlock();
+ // now that we've popped, if somebody's been waiting to push, signal them
+ mCapacityCond.notify_one();
+ return POPPED;
}
-template<typename ElementT>
-ElementT LLThreadSafeQueue<ElementT>::popBack(void)
+template<typename ElementT, typename QueueT>
+ElementT LLThreadSafeQueue<ElementT, QueueT>::pop(void)
{
lock_t lock1(mLock);
+ ElementT value;
while (true)
{
- if (!mStorage.empty())
- {
- ElementT value = mStorage.back();
- mStorage.pop_back();
- lock1.unlock();
- mCapacityCond.notify_one();
- return value;
- }
-
- if (mClosed)
+ // On the consumer side, we always try to pop before checking mClosed
+ // so we can finish draining the queue.
+ pop_result popped = pop_(lock1, value);
+ if (popped == POPPED)
+ return std::move(value);
+
+ // Once the queue is DONE, there will never be any more coming.
+ if (popped == DONE)
{
LLTHROW(LLThreadSafeQueueInterrupt());
}
- // Storage empty. Wait for signal.
+ // If we didn't pop because WAITING, i.e. canPop() returned false,
+ // then even if the producer end has been closed, there's still at
+ // least one item to drain: wait for it. Or we might be EMPTY, with
+ // the queue still open. Either way, wait for signal.
mEmptyCond.wait(lock1);
}
}
-template<typename ElementT>
-bool LLThreadSafeQueue<ElementT>::tryPopBack(ElementT & element)
+template<typename ElementT, typename QueueT>
+bool LLThreadSafeQueue<ElementT, QueueT>::tryPop(ElementT & element)
{
- lock_t lock1(mLock, std::defer_lock);
- if (!lock1.try_lock())
- return false;
+ return tryLock(
+ [this, &element](lock_t& lock)
+ {
+ // conflate EMPTY, DONE, WAITING: tryPop() behavior when the queue
+ // is closed is implemented by simple inability to push any new
+ // elements
+ return pop_(lock, element) == POPPED;
+ });
+}
- // no need to check mClosed: tryPopBack() behavior when the queue is
- // closed is implemented by simple inability to push any new elements
- if (mStorage.empty())
- return false;
- element = mStorage.back();
- mStorage.pop_back();
- lock1.unlock();
- mCapacityCond.notify_one();
- return true;
+template <typename ElementT, typename QueueT>
+template <typename Rep, typename Period>
+bool LLThreadSafeQueue<ElementT, QueueT>::tryPopFor(
+ const std::chrono::duration<Rep, Period>& timeout,
+ ElementT& element)
+{
+ // Convert duration to time_point: passing the same timeout duration to
+ // each of multiple calls is wrong.
+ return tryPopUntil(std::chrono::steady_clock::now() + timeout, element);
+}
+
+
+template <typename ElementT, typename QueueT>
+template <typename Clock, typename Duration>
+bool LLThreadSafeQueue<ElementT, QueueT>::tryPopUntil(
+ const std::chrono::time_point<Clock, Duration>& until,
+ ElementT& element)
+{
+ return tryLockUntil(
+ until,
+ [this, until, &element](lock_t& lock)
+ {
+ // conflate EMPTY, DONE, WAITING
+ return tryPopUntil_(lock, until, element) == POPPED;
+ });
+}
+
+
+// body of tryPopUntil(), called once we have the lock
+template <typename ElementT, typename QueueT>
+template <typename Clock, typename Duration>
+typename LLThreadSafeQueue<ElementT, QueueT>::pop_result
+LLThreadSafeQueue<ElementT, QueueT>::tryPopUntil_(
+ lock_t& lock,
+ const std::chrono::time_point<Clock, Duration>& until,
+ ElementT& element)
+{
+ while (true)
+ {
+ pop_result popped = pop_(lock, element);
+ if (popped == POPPED || popped == DONE)
+ {
+ // If we succeeded, great! If we've drained the last item, so be
+ // it. Either way, break the loop and tell caller.
+ return popped;
+ }
+
+ // EMPTY or WAITING: wait for signal.
+ if (LLCoros::cv_status::timeout == mEmptyCond.wait_until(lock, until))
+ {
+ // timed out -- formally we might recheck
+ // as it is, break loop
+ return popped;
+ }
+ // If we didn't time out, we were notified for some reason. Loop back
+ // to check.
+ }
}
-template<typename ElementT>
-size_t LLThreadSafeQueue<ElementT>::size(void)
+template<typename ElementT, typename QueueT>
+size_t LLThreadSafeQueue<ElementT, QueueT>::size(void)
{
lock_t lock(mLock);
return mStorage.size();
}
-template<typename ElementT>
-void LLThreadSafeQueue<ElementT>::close()
+
+template<typename ElementT, typename QueueT>
+void LLThreadSafeQueue<ElementT, QueueT>::close()
{
lock_t lock(mLock);
mClosed = true;
lock.unlock();
- // wake up any blocked popBack() calls
+ // wake up any blocked pop() calls
mEmptyCond.notify_all();
- // wake up any blocked pushFront() calls
+ // wake up any blocked push() calls
mCapacityCond.notify_all();
}
-template<typename ElementT>
-bool LLThreadSafeQueue<ElementT>::isClosed()
+
+template<typename ElementT, typename QueueT>
+bool LLThreadSafeQueue<ElementT, QueueT>::isClosed()
{
lock_t lock(mLock);
- return mClosed && mStorage.size() == 0;
+ return mClosed;
}
-template<typename ElementT>
-LLThreadSafeQueue<ElementT>::operator bool()
+
+template<typename ElementT, typename QueueT>
+bool LLThreadSafeQueue<ElementT, QueueT>::done()
{
- return ! isClosed();
+ lock_t lock(mLock);
+ return mClosed && mStorage.empty();
}
#endif
diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp
index 54079a4689..f59b207ded 100644
--- a/indra/llcommon/lltrace.cpp
+++ b/indra/llcommon/lltrace.cpp
@@ -61,6 +61,7 @@ TimeBlockTreeNode::TimeBlockTreeNode()
void TimeBlockTreeNode::setParent( BlockTimerStatHandle* parent )
{
+ LL_PROFILE_ZONE_SCOPED;
llassert_always(parent != mBlock);
llassert_always(parent != NULL);
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 0d0cd6f581..4051c558a4 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -227,6 +227,7 @@ public:
void setName(const char* name)
{
+ LL_PROFILE_ZONE_SCOPED;
mName = name;
setKey(name);
}
@@ -234,12 +235,14 @@ public:
/*virtual*/ const char* getUnitLabel() const { return "KB"; }
StatType<MemAccumulator::AllocationFacet>& allocations()
- {
+ {
+ LL_PROFILE_ZONE_SCOPED;
return static_cast<StatType<MemAccumulator::AllocationFacet>&>(*(StatType<MemAccumulator>*)this);
}
StatType<MemAccumulator::DeallocationFacet>& deallocations()
- {
+ {
+ LL_PROFILE_ZONE_SCOPED;
return static_cast<StatType<MemAccumulator::DeallocationFacet>&>(*(StatType<MemAccumulator>*)this);
}
};
@@ -261,6 +264,7 @@ struct MeasureMem<T, typename T::mem_trackable_tag_t, IS_BYTES>
{
static size_t measureFootprint(const T& value)
{
+ LL_PROFILE_ZONE_SCOPED;
return sizeof(T) + value.getMemFootprint();
}
};
@@ -270,6 +274,7 @@ struct MeasureMem<T, IS_MEM_TRACKABLE, typename T::is_unit_t>
{
static size_t measureFootprint(const T& value)
{
+ LL_PROFILE_ZONE_SCOPED;
return U32Bytes(value).value();
}
};
@@ -279,6 +284,7 @@ struct MeasureMem<T*, IS_MEM_TRACKABLE, IS_BYTES>
{
static size_t measureFootprint(const T* value)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!value)
{
return 0;
@@ -323,6 +329,7 @@ struct MeasureMem<std::basic_string<T>, IS_MEM_TRACKABLE, IS_BYTES>
{
static size_t measureFootprint(const std::basic_string<T>& value)
{
+ LL_PROFILE_ZONE_SCOPED;
return value.capacity() * sizeof(T);
}
};
@@ -331,6 +338,7 @@ struct MeasureMem<std::basic_string<T>, IS_MEM_TRACKABLE, IS_BYTES>
template<typename T>
inline void claim_alloc(MemStatHandle& measurement, const T& value)
{
+ LL_PROFILE_ZONE_SCOPED;
#if LL_TRACE_ENABLED
S32 size = MeasureMem<T>::measureFootprint(value);
if(size == 0) return;
@@ -343,6 +351,7 @@ inline void claim_alloc(MemStatHandle& measurement, const T& value)
template<typename T>
inline void disclaim_alloc(MemStatHandle& measurement, const T& value)
{
+ LL_PROFILE_ZONE_SCOPED;
#if LL_TRACE_ENABLED
S32 size = MeasureMem<T>::measureFootprint(value);
if(size == 0) return;
@@ -352,141 +361,6 @@ inline void disclaim_alloc(MemStatHandle& measurement, const T& value)
#endif
}
-template<typename DERIVED, size_t ALIGNMENT = LL_DEFAULT_HEAP_ALIGN>
-class MemTrackableNonVirtual
-{
-public:
- typedef void mem_trackable_tag_t;
-
- MemTrackableNonVirtual(const char* name)
-#if LL_TRACE_ENABLED
- : mMemFootprint(0)
-#endif
- {
-#if LL_TRACE_ENABLED
- static bool name_initialized = false;
- if (!name_initialized)
- {
- name_initialized = true;
- sMemStat.setName(name);
- }
-#endif
- }
-
-#if LL_TRACE_ENABLED
- ~MemTrackableNonVirtual()
- {
- disclaimMem(mMemFootprint);
- }
-
- static MemStatHandle& getMemStatHandle()
- {
- return sMemStat;
- }
-
- S32 getMemFootprint() const { return mMemFootprint; }
-#endif
-
- void* operator new(size_t size)
- {
-#if LL_TRACE_ENABLED
- claim_alloc(sMemStat, size);
-#endif
- return ll_aligned_malloc<ALIGNMENT>(size);
- }
-
- template<int CUSTOM_ALIGNMENT>
- static void* aligned_new(size_t size)
- {
-#if LL_TRACE_ENABLED
- claim_alloc(sMemStat, size);
-#endif
- return ll_aligned_malloc<CUSTOM_ALIGNMENT>(size);
- }
-
- void operator delete(void* ptr, size_t size)
- {
-#if LL_TRACE_ENABLED
- disclaim_alloc(sMemStat, size);
-#endif
- ll_aligned_free<ALIGNMENT>(ptr);
- }
-
- template<int CUSTOM_ALIGNMENT>
- static void aligned_delete(void* ptr, size_t size)
- {
-#if LL_TRACE_ENABLED
- disclaim_alloc(sMemStat, size);
-#endif
- ll_aligned_free<CUSTOM_ALIGNMENT>(ptr);
- }
-
- void* operator new [](size_t size)
- {
-#if LL_TRACE_ENABLED
- claim_alloc(sMemStat, size);
-#endif
- return ll_aligned_malloc<ALIGNMENT>(size);
- }
-
- void operator delete[](void* ptr, size_t size)
- {
-#if LL_TRACE_ENABLED
- disclaim_alloc(sMemStat, size);
-#endif
- ll_aligned_free<ALIGNMENT>(ptr);
- }
-
- // claim memory associated with other objects/data as our own, adding to our calculated footprint
- template<typename CLAIM_T>
- void claimMem(const CLAIM_T& value) const
- {
-#if LL_TRACE_ENABLED
- S32 size = MeasureMem<CLAIM_T>::measureFootprint(value);
- claim_alloc(sMemStat, size);
- mMemFootprint += size;
-#endif
- }
-
- // remove memory we had claimed from our calculated footprint
- template<typename CLAIM_T>
- void disclaimMem(const CLAIM_T& value) const
- {
-#if LL_TRACE_ENABLED
- S32 size = MeasureMem<CLAIM_T>::measureFootprint(value);
- disclaim_alloc(sMemStat, size);
- mMemFootprint -= size;
-#endif
- }
-
-private:
-#if LL_TRACE_ENABLED
- // use signed values so that we can temporarily go negative
- // and reconcile in destructor
- // NB: this assumes that no single class is responsible for > 2GB of allocations
- mutable S32 mMemFootprint;
-
- static MemStatHandle sMemStat;
-#endif
-
-};
-
-#if LL_TRACE_ENABLED
-template<typename DERIVED, size_t ALIGNMENT>
-MemStatHandle MemTrackableNonVirtual<DERIVED, ALIGNMENT>::sMemStat(typeid(MemTrackableNonVirtual<DERIVED, ALIGNMENT>).name());
-#endif
-
-template<typename DERIVED, size_t ALIGNMENT = LL_DEFAULT_HEAP_ALIGN>
-class MemTrackable : public MemTrackableNonVirtual<DERIVED, ALIGNMENT>
-{
-public:
- MemTrackable(const char* name)
- : MemTrackableNonVirtual<DERIVED, ALIGNMENT>(name)
- {}
-
- virtual ~MemTrackable()
- {}
-};
}
#endif // LL_LLTRACE_H
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index b1c23c6fb7..8e9aaee0e6 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -41,6 +41,7 @@ extern MemStatHandle gTraceMemStat;
AccumulatorBufferGroup::AccumulatorBufferGroup()
{
+ LL_PROFILE_ZONE_SCOPED;
claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
@@ -55,6 +56,7 @@ AccumulatorBufferGroup::AccumulatorBufferGroup(const AccumulatorBufferGroup& oth
mStackTimers(other.mStackTimers),
mMemStats(other.mMemStats)
{
+ LL_PROFILE_ZONE_SCOPED;
claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
@@ -64,6 +66,7 @@ AccumulatorBufferGroup::AccumulatorBufferGroup(const AccumulatorBufferGroup& oth
AccumulatorBufferGroup::~AccumulatorBufferGroup()
{
+ LL_PROFILE_ZONE_SCOPED;
disclaim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
disclaim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
disclaim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
@@ -73,6 +76,7 @@ AccumulatorBufferGroup::~AccumulatorBufferGroup()
void AccumulatorBufferGroup::handOffTo(AccumulatorBufferGroup& other)
{
+ LL_PROFILE_ZONE_SCOPED;
other.mCounts.reset(&mCounts);
other.mSamples.reset(&mSamples);
other.mEvents.reset(&mEvents);
@@ -82,6 +86,7 @@ void AccumulatorBufferGroup::handOffTo(AccumulatorBufferGroup& other)
void AccumulatorBufferGroup::makeCurrent()
{
+ LL_PROFILE_ZONE_SCOPED;
mCounts.makeCurrent();
mSamples.makeCurrent();
mEvents.makeCurrent();
@@ -104,6 +109,7 @@ void AccumulatorBufferGroup::makeCurrent()
//static
void AccumulatorBufferGroup::clearCurrent()
{
+ LL_PROFILE_ZONE_SCOPED;
AccumulatorBuffer<CountAccumulator>::clearCurrent();
AccumulatorBuffer<SampleAccumulator>::clearCurrent();
AccumulatorBuffer<EventAccumulator>::clearCurrent();
@@ -118,6 +124,7 @@ bool AccumulatorBufferGroup::isCurrent() const
void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
{
+ LL_PROFILE_ZONE_SCOPED;
mCounts.addSamples(other.mCounts, SEQUENTIAL);
mSamples.addSamples(other.mSamples, SEQUENTIAL);
mEvents.addSamples(other.mEvents, SEQUENTIAL);
@@ -127,6 +134,7 @@ void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
void AccumulatorBufferGroup::merge( const AccumulatorBufferGroup& other)
{
+ LL_PROFILE_ZONE_SCOPED;
mCounts.addSamples(other.mCounts, NON_SEQUENTIAL);
mSamples.addSamples(other.mSamples, NON_SEQUENTIAL);
mEvents.addSamples(other.mEvents, NON_SEQUENTIAL);
@@ -137,6 +145,7 @@ void AccumulatorBufferGroup::merge( const AccumulatorBufferGroup& other)
void AccumulatorBufferGroup::reset(AccumulatorBufferGroup* other)
{
+ LL_PROFILE_ZONE_SCOPED;
mCounts.reset(other ? &other->mCounts : NULL);
mSamples.reset(other ? &other->mSamples : NULL);
mEvents.reset(other ? &other->mEvents : NULL);
@@ -146,6 +155,7 @@ void AccumulatorBufferGroup::reset(AccumulatorBufferGroup* other)
void AccumulatorBufferGroup::sync()
{
+ LL_PROFILE_ZONE_SCOPED;
if (isCurrent())
{
F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
@@ -190,7 +200,7 @@ F64 SampleAccumulator::mergeSumsOfSquares(const SampleAccumulator& a, const Samp
void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppendType append_type )
{
- if (append_type == NON_SEQUENTIAL)
+ if (append_type == NON_SEQUENTIAL)
{
return;
}
@@ -289,7 +299,7 @@ void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendT
void EventAccumulator::reset( const EventAccumulator* other )
{
- mNumSamples = 0;
+ mNumSamples = 0;
mSum = 0;
mMin = F32(NaN);
mMax = F32(NaN);
diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h
index 8eb5338a2a..b183fcd14a 100644
--- a/indra/llcommon/lltraceaccumulators.h
+++ b/indra/llcommon/lltraceaccumulators.h
@@ -66,6 +66,7 @@ namespace LLTrace
: mStorageSize(0),
mStorage(NULL)
{
+ LL_PROFILE_ZONE_SCOPED;
const AccumulatorBuffer& other = *getDefaultBuffer();
resize(sNextStorageSlot);
for (S32 i = 0; i < sNextStorageSlot; i++)
@@ -76,6 +77,7 @@ namespace LLTrace
~AccumulatorBuffer()
{
+ LL_PROFILE_ZONE_SCOPED;
if (isCurrent())
{
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
@@ -98,6 +100,7 @@ namespace LLTrace
: mStorageSize(0),
mStorage(NULL)
{
+ LL_PROFILE_ZONE_SCOPED;
resize(sNextStorageSlot);
for (S32 i = 0; i < sNextStorageSlot; i++)
{
@@ -107,6 +110,7 @@ namespace LLTrace
void addSamples(const AccumulatorBuffer<ACCUMULATOR>& other, EBufferAppendType append_type)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot);
for (size_t i = 0; i < sNextStorageSlot; i++)
{
@@ -116,6 +120,7 @@ namespace LLTrace
void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot);
for (size_t i = 0; i < sNextStorageSlot; i++)
{
@@ -125,6 +130,7 @@ namespace LLTrace
void reset(const AccumulatorBuffer<ACCUMULATOR>* other = NULL)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(mStorageSize >= sNextStorageSlot);
for (size_t i = 0; i < sNextStorageSlot; i++)
{
@@ -134,6 +140,7 @@ namespace LLTrace
void sync(F64SecondsImplicit time_stamp)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(mStorageSize >= sNextStorageSlot);
for (size_t i = 0; i < sNextStorageSlot; i++)
{
@@ -153,12 +160,13 @@ namespace LLTrace
static void clearCurrent()
{
- LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
+ LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
}
// NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned
size_t reserveSlot()
{
+ LL_PROFILE_ZONE_SCOPED;
size_t next_slot = sNextStorageSlot++;
if (next_slot >= mStorageSize)
{
@@ -172,6 +180,7 @@ namespace LLTrace
void resize(size_t new_size)
{
+ LL_PROFILE_ZONE_SCOPED;
if (new_size <= mStorageSize) return;
ACCUMULATOR* old_storage = mStorage;
@@ -212,6 +221,7 @@ namespace LLTrace
static self_t* getDefaultBuffer()
{
+ LL_PROFILE_ZONE_SCOPED;
static bool sInitialized = false;
if (!sInitialized)
{
@@ -326,6 +336,7 @@ namespace LLTrace
void sample(F64 value)
{
+ LL_PROFILE_ZONE_SCOPED;
F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
// store effect of last value
@@ -444,9 +455,9 @@ namespace LLTrace
S32 mNumSamples;
};
- class TimeBlockAccumulator
+ class alignas(32) TimeBlockAccumulator
{
- public:
+ public:
typedef F64Seconds value_t;
static F64Seconds getDefaultValue() { return F64Seconds(0); }
@@ -539,6 +550,7 @@ namespace LLTrace
void addSamples(const MemAccumulator& other, EBufferAppendType append_type)
{
+ LL_PROFILE_ZONE_SCOPED;
mAllocations.addSamples(other.mAllocations, append_type);
mDeallocations.addSamples(other.mDeallocations, append_type);
@@ -557,6 +569,7 @@ namespace LLTrace
void reset(const MemAccumulator* other)
{
+ LL_PROFILE_ZONE_SCOPED;
mSize.reset(other ? &other->mSize : NULL);
mAllocations.reset(other ? &other->mAllocations : NULL);
mDeallocations.reset(other ? &other->mDeallocations : NULL);
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 3094b627a2..5ce1b337fe 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -50,6 +50,7 @@ Recording::Recording(EPlayState state)
: mElapsedSeconds(0),
mActiveBuffers(NULL)
{
+ LL_PROFILE_ZONE_SCOPED;
claim_alloc(gTraceMemStat, this);
mBuffers = new AccumulatorBufferGroup();
claim_alloc(gTraceMemStat, mBuffers);
@@ -59,12 +60,14 @@ Recording::Recording(EPlayState state)
Recording::Recording( const Recording& other )
: mActiveBuffers(NULL)
{
+ LL_PROFILE_ZONE_SCOPED;
claim_alloc(gTraceMemStat, this);
*this = other;
}
Recording& Recording::operator = (const Recording& other)
{
+ LL_PROFILE_ZONE_SCOPED;
// this will allow us to seamlessly start without affecting any data we've acquired from other
setPlayState(PAUSED);
@@ -85,6 +88,7 @@ Recording& Recording::operator = (const Recording& other)
Recording::~Recording()
{
+ LL_PROFILE_ZONE_SCOPED;
disclaim_alloc(gTraceMemStat, this);
disclaim_alloc(gTraceMemStat, mBuffers);
@@ -103,6 +107,7 @@ void Recording::update()
#if LL_TRACE_ENABLED
if (isStarted())
{
+ LL_PROFILE_ZONE_SCOPED;
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
// must have
@@ -123,6 +128,7 @@ void Recording::update()
void Recording::handleReset()
{
+ LL_PROFILE_ZONE_SCOPED;
#if LL_TRACE_ENABLED
mBuffers.write()->reset();
@@ -133,6 +139,7 @@ void Recording::handleReset()
void Recording::handleStart()
{
+ LL_PROFILE_ZONE_SCOPED;
#if LL_TRACE_ENABLED
mSamplingTimer.reset();
mBuffers.setStayUnique(true);
@@ -144,6 +151,7 @@ void Recording::handleStart()
void Recording::handleStop()
{
+ LL_PROFILE_ZONE_SCOPED;
#if LL_TRACE_ENABLED
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
// must have thread recorder running on this thread
@@ -273,7 +281,7 @@ F64Kilobytes Recording::getMean(const StatType<MemAccumulator>& stat)
F64Kilobytes Recording::getMax(const StatType<MemAccumulator>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
return F64Bytes(llmax(accumulator.mSize.getMax(), active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.getMax() : F32_MIN));
@@ -281,7 +289,7 @@ F64Kilobytes Recording::getMax(const StatType<MemAccumulator>& stat)
F64Kilobytes Recording::getStandardDeviation(const StatType<MemAccumulator>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
if (active_accumulator && active_accumulator->hasValue())
@@ -297,7 +305,7 @@ F64Kilobytes Recording::getStandardDeviation(const StatType<MemAccumulator>& sta
F64Kilobytes Recording::getLastValue(const StatType<MemAccumulator>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
return F64Bytes(active_accumulator ? active_accumulator->mSize.getLastValue() : accumulator.mSize.getLastValue());
@@ -305,7 +313,7 @@ F64Kilobytes Recording::getLastValue(const StatType<MemAccumulator>& stat)
bool Recording::hasValue(const StatType<MemAccumulator::AllocationFacet>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
return accumulator.mAllocations.hasValue() || (active_accumulator ? active_accumulator->mAllocations.hasValue() : false);
@@ -313,7 +321,7 @@ bool Recording::hasValue(const StatType<MemAccumulator::AllocationFacet>& stat)
F64Kilobytes Recording::getSum(const StatType<MemAccumulator::AllocationFacet>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
return F64Bytes(accumulator.mAllocations.getSum() + (active_accumulator ? active_accumulator->mAllocations.getSum() : 0));
@@ -321,7 +329,7 @@ F64Kilobytes Recording::getSum(const StatType<MemAccumulator::AllocationFacet>&
F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::AllocationFacet>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
return F64Bytes((accumulator.mAllocations.getSum() + (active_accumulator ? active_accumulator->mAllocations.getSum() : 0)) / mElapsedSeconds.value());
@@ -329,7 +337,7 @@ F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::AllocationFacet
S32 Recording::getSampleCount(const StatType<MemAccumulator::AllocationFacet>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
return accumulator.mAllocations.getSampleCount() + (active_accumulator ? active_accumulator->mAllocations.getSampleCount() : 0);
@@ -337,7 +345,7 @@ S32 Recording::getSampleCount(const StatType<MemAccumulator::AllocationFacet>& s
bool Recording::hasValue(const StatType<MemAccumulator::DeallocationFacet>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
return accumulator.mDeallocations.hasValue() || (active_accumulator ? active_accumulator->mDeallocations.hasValue() : false);
@@ -346,7 +354,7 @@ bool Recording::hasValue(const StatType<MemAccumulator::DeallocationFacet>& stat
F64Kilobytes Recording::getSum(const StatType<MemAccumulator::DeallocationFacet>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
return F64Bytes(accumulator.mDeallocations.getSum() + (active_accumulator ? active_accumulator->mDeallocations.getSum() : 0));
@@ -354,7 +362,7 @@ F64Kilobytes Recording::getSum(const StatType<MemAccumulator::DeallocationFacet>
F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::DeallocationFacet>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
return F64Bytes((accumulator.mDeallocations.getSum() + (active_accumulator ? active_accumulator->mDeallocations.getSum() : 0)) / mElapsedSeconds.value());
@@ -362,7 +370,7 @@ F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::DeallocationFac
S32 Recording::getSampleCount(const StatType<MemAccumulator::DeallocationFacet>& stat)
{
- update();
+ update();
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
return accumulator.mDeallocations.getSampleCount() + (active_accumulator ? active_accumulator->mDeallocations.getSampleCount() : 0);
@@ -370,7 +378,7 @@ S32 Recording::getSampleCount(const StatType<MemAccumulator::DeallocationFacet>&
bool Recording::hasValue(const StatType<CountAccumulator>& stat)
{
- update();
+ update();
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
return accumulator.hasValue() || (active_accumulator ? active_accumulator->hasValue() : false);
@@ -378,7 +386,7 @@ bool Recording::hasValue(const StatType<CountAccumulator>& stat)
F64 Recording::getSum(const StatType<CountAccumulator>& stat)
{
- update();
+ update();
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
return accumulator.getSum() + (active_accumulator ? active_accumulator->getSum() : 0);
@@ -386,7 +394,7 @@ F64 Recording::getSum(const StatType<CountAccumulator>& stat)
F64 Recording::getPerSec( const StatType<CountAccumulator>& stat )
{
- update();
+ update();
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
F64 sum = accumulator.getSum() + (active_accumulator ? active_accumulator->getSum() : 0);
@@ -395,7 +403,7 @@ F64 Recording::getPerSec( const StatType<CountAccumulator>& stat )
S32 Recording::getSampleCount( const StatType<CountAccumulator>& stat )
{
- update();
+ update();
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
return accumulator.getSampleCount() + (active_accumulator ? active_accumulator->getSampleCount() : 0);
@@ -403,7 +411,7 @@ S32 Recording::getSampleCount( const StatType<CountAccumulator>& stat )
bool Recording::hasValue(const StatType<SampleAccumulator>& stat)
{
- update();
+ update();
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
return accumulator.hasValue() || (active_accumulator && active_accumulator->hasValue());
@@ -411,7 +419,7 @@ bool Recording::hasValue(const StatType<SampleAccumulator>& stat)
F64 Recording::getMin( const StatType<SampleAccumulator>& stat )
{
- update();
+ update();
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
return llmin(accumulator.getMin(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMin() : F32_MAX);
@@ -419,7 +427,7 @@ F64 Recording::getMin( const StatType<SampleAccumulator>& stat )
F64 Recording::getMax( const StatType<SampleAccumulator>& stat )
{
- update();
+ update();
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
return llmax(accumulator.getMax(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMax() : F32_MIN);
@@ -427,7 +435,7 @@ F64 Recording::getMax( const StatType<SampleAccumulator>& stat )
F64 Recording::getMean( const StatType<SampleAccumulator>& stat )
{
- update();
+ update();
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
if (active_accumulator && active_accumulator->hasValue())
@@ -448,7 +456,7 @@ F64 Recording::getMean( const StatType<SampleAccumulator>& stat )
F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat )
{
- update();
+ update();
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
@@ -465,7 +473,7 @@ F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat )
F64 Recording::getLastValue( const StatType<SampleAccumulator>& stat )
{
- update();
+ update();
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
return (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getLastValue() : accumulator.getLastValue());
@@ -473,7 +481,7 @@ F64 Recording::getLastValue( const StatType<SampleAccumulator>& stat )
S32 Recording::getSampleCount( const StatType<SampleAccumulator>& stat )
{
- update();
+ update();
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
return accumulator.getSampleCount() + (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getSampleCount() : 0);
@@ -481,7 +489,7 @@ S32 Recording::getSampleCount( const StatType<SampleAccumulator>& stat )
bool Recording::hasValue(const StatType<EventAccumulator>& stat)
{
- update();
+ update();
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
return accumulator.hasValue() || (active_accumulator && active_accumulator->hasValue());
@@ -489,7 +497,7 @@ bool Recording::hasValue(const StatType<EventAccumulator>& stat)
F64 Recording::getSum( const StatType<EventAccumulator>& stat)
{
- update();
+ update();
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
return (F64)(accumulator.getSum() + (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getSum() : 0));
@@ -497,7 +505,7 @@ F64 Recording::getSum( const StatType<EventAccumulator>& stat)
F64 Recording::getMin( const StatType<EventAccumulator>& stat )
{
- update();
+ update();
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
return llmin(accumulator.getMin(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMin() : F32_MAX);
@@ -505,7 +513,7 @@ F64 Recording::getMin( const StatType<EventAccumulator>& stat )
F64 Recording::getMax( const StatType<EventAccumulator>& stat )
{
- update();
+ update();
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
return llmax(accumulator.getMax(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMax() : F32_MIN);
@@ -513,7 +521,7 @@ F64 Recording::getMax( const StatType<EventAccumulator>& stat )
F64 Recording::getMean( const StatType<EventAccumulator>& stat )
{
- update();
+ update();
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
if (active_accumulator && active_accumulator->hasValue())
@@ -534,7 +542,7 @@ F64 Recording::getMean( const StatType<EventAccumulator>& stat )
F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat )
{
- update();
+ update();
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
@@ -551,7 +559,7 @@ F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat )
F64 Recording::getLastValue( const StatType<EventAccumulator>& stat )
{
- update();
+ update();
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
return active_accumulator ? active_accumulator->getLastValue() : accumulator.getLastValue();
@@ -559,7 +567,7 @@ F64 Recording::getLastValue( const StatType<EventAccumulator>& stat )
S32 Recording::getSampleCount( const StatType<EventAccumulator>& stat )
{
- update();
+ update();
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
return accumulator.getSampleCount() + (active_accumulator ? active_accumulator->getSampleCount() : 0);
@@ -575,17 +583,20 @@ PeriodicRecording::PeriodicRecording( S32 num_periods, EPlayState state)
mNumRecordedPeriods(0),
mRecordingPeriods(num_periods ? num_periods : 1)
{
+ LL_PROFILE_ZONE_SCOPED;
setPlayState(state);
claim_alloc(gTraceMemStat, this);
}
PeriodicRecording::~PeriodicRecording()
{
+ LL_PROFILE_ZONE_SCOPED;
disclaim_alloc(gTraceMemStat, this);
}
void PeriodicRecording::nextPeriod()
{
+ LL_PROFILE_ZONE_SCOPED;
if (mAutoResize)
{
mRecordingPeriods.push_back(Recording());
@@ -600,6 +611,7 @@ void PeriodicRecording::nextPeriod()
void PeriodicRecording::appendRecording(Recording& recording)
{
+ LL_PROFILE_ZONE_SCOPED;
getCurRecording().appendRecording(recording);
nextPeriod();
}
@@ -607,6 +619,7 @@ void PeriodicRecording::appendRecording(Recording& recording)
void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
{
+ LL_PROFILE_ZONE_SCOPED;
if (other.mRecordingPeriods.empty()) return;
getCurRecording().update();
@@ -680,6 +693,7 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
F64Seconds PeriodicRecording::getDuration() const
{
+ LL_PROFILE_ZONE_SCOPED;
F64Seconds duration;
S32 num_periods = mRecordingPeriods.size();
for (S32 i = 1; i <= num_periods; i++)
@@ -693,6 +707,7 @@ F64Seconds PeriodicRecording::getDuration() const
LLTrace::Recording PeriodicRecording::snapshotCurRecording() const
{
+ LL_PROFILE_ZONE_SCOPED;
Recording recording_copy(getCurRecording());
recording_copy.stop();
return recording_copy;
@@ -735,16 +750,19 @@ const Recording& PeriodicRecording::getPrevRecording( S32 offset ) const
void PeriodicRecording::handleStart()
{
+ LL_PROFILE_ZONE_SCOPED;
getCurRecording().start();
}
void PeriodicRecording::handleStop()
{
+ LL_PROFILE_ZONE_SCOPED;
getCurRecording().pause();
}
void PeriodicRecording::handleReset()
{
+ LL_PROFILE_ZONE_SCOPED;
getCurRecording().stop();
if (mAutoResize)
@@ -768,11 +786,13 @@ void PeriodicRecording::handleReset()
void PeriodicRecording::handleSplitTo(PeriodicRecording& other)
{
+ LL_PROFILE_ZONE_SCOPED;
getCurRecording().splitTo(other.getCurRecording());
}
F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
bool has_value = false;
@@ -794,6 +814,7 @@ F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, S32
F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
bool has_value = false;
@@ -816,6 +837,7 @@ F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, S32
// calculates means using aggregates per period
F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
F64 mean = 0;
@@ -836,9 +858,9 @@ F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, S3
: NaN;
}
-
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
F64 period_mean = getPeriodMean(stat, num_periods);
@@ -863,6 +885,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulat
F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
bool has_value = false;
@@ -884,6 +907,7 @@ F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, S3
F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/)
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
bool has_value = false;
@@ -906,6 +930,7 @@ F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, S32
F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
S32 valid_period_count = 0;
@@ -926,8 +951,35 @@ F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, S
: NaN;
}
+F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
+{
+ LL_PROFILE_ZONE_SCOPED;
+ num_periods = llmin(num_periods, getNumRecordedPeriods());
+
+ std::vector<F64> buf;
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ Recording& recording = getPrevRecording(i);
+ if (recording.getDuration() > (F32Seconds)0.f)
+ {
+ if (recording.hasValue(stat))
+ {
+ buf.push_back(recording.getMean(stat));
+ }
+ }
+ }
+ if (buf.size()==0)
+ {
+ return 0.0f;
+ }
+ std::sort(buf.begin(), buf.end());
+
+ return F64((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]);
+}
+
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
F64 period_mean = getPeriodMean(stat, num_periods);
@@ -953,6 +1005,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumula
F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
F64Kilobytes min_val(std::numeric_limits<F64>::max());
@@ -972,6 +1025,7 @@ F64Kilobytes PeriodicRecording::getPeriodMin(const MemStatHandle& stat, S32 num_
F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/)
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
F64Kilobytes max_val(0.0);
@@ -991,6 +1045,7 @@ F64Kilobytes PeriodicRecording::getPeriodMax(const MemStatHandle& stat, S32 num_
F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
F64Kilobytes mean(0);
@@ -1011,6 +1066,7 @@ F64Kilobytes PeriodicRecording::getPeriodMean(const MemStatHandle& stat, S32 num
F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/ )
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
F64Kilobytes period_mean = getPeriodMean(stat, num_periods);
@@ -1044,6 +1100,7 @@ F64Kilobytes PeriodicRecording::getPeriodStandardDeviation(const MemStatHandle&
void ExtendableRecording::extend()
{
+ LL_PROFILE_ZONE_SCOPED;
// push the data back to accepted recording
mAcceptedRecording.appendRecording(mPotentialRecording);
// flush data, so we can start from scratch
@@ -1052,22 +1109,26 @@ void ExtendableRecording::extend()
void ExtendableRecording::handleStart()
{
+ LL_PROFILE_ZONE_SCOPED;
mPotentialRecording.start();
}
void ExtendableRecording::handleStop()
{
+ LL_PROFILE_ZONE_SCOPED;
mPotentialRecording.pause();
}
void ExtendableRecording::handleReset()
{
+ LL_PROFILE_ZONE_SCOPED;
mAcceptedRecording.reset();
mPotentialRecording.reset();
}
void ExtendableRecording::handleSplitTo(ExtendableRecording& other)
{
+ LL_PROFILE_ZONE_SCOPED;
mPotentialRecording.splitTo(other.mPotentialRecording);
}
@@ -1084,6 +1145,7 @@ ExtendablePeriodicRecording::ExtendablePeriodicRecording()
void ExtendablePeriodicRecording::extend()
{
+ LL_PROFILE_ZONE_SCOPED;
// push the data back to accepted recording
mAcceptedRecording.appendPeriodicRecording(mPotentialRecording);
// flush data, so we can start from scratch
@@ -1093,22 +1155,26 @@ void ExtendablePeriodicRecording::extend()
void ExtendablePeriodicRecording::handleStart()
{
+ LL_PROFILE_ZONE_SCOPED;
mPotentialRecording.start();
}
void ExtendablePeriodicRecording::handleStop()
{
+ LL_PROFILE_ZONE_SCOPED;
mPotentialRecording.pause();
}
void ExtendablePeriodicRecording::handleReset()
{
+ LL_PROFILE_ZONE_SCOPED;
mAcceptedRecording.reset();
mPotentialRecording.reset();
}
void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& other)
{
+ LL_PROFILE_ZONE_SCOPED;
mPotentialRecording.splitTo(other.mPotentialRecording);
}
@@ -1123,6 +1189,7 @@ PeriodicRecording& get_frame_recording()
void LLStopWatchControlsMixinCommon::start()
{
+ LL_PROFILE_ZONE_SCOPED;
switch (mPlayState)
{
case STOPPED:
@@ -1144,6 +1211,7 @@ void LLStopWatchControlsMixinCommon::start()
void LLStopWatchControlsMixinCommon::stop()
{
+ LL_PROFILE_ZONE_SCOPED;
switch (mPlayState)
{
case STOPPED:
@@ -1163,6 +1231,7 @@ void LLStopWatchControlsMixinCommon::stop()
void LLStopWatchControlsMixinCommon::pause()
{
+ LL_PROFILE_ZONE_SCOPED;
switch (mPlayState)
{
case STOPPED:
@@ -1182,6 +1251,7 @@ void LLStopWatchControlsMixinCommon::pause()
void LLStopWatchControlsMixinCommon::unpause()
{
+ LL_PROFILE_ZONE_SCOPED;
switch (mPlayState)
{
case STOPPED:
@@ -1201,6 +1271,7 @@ void LLStopWatchControlsMixinCommon::unpause()
void LLStopWatchControlsMixinCommon::resume()
{
+ LL_PROFILE_ZONE_SCOPED;
switch (mPlayState)
{
case STOPPED:
@@ -1221,6 +1292,7 @@ void LLStopWatchControlsMixinCommon::resume()
void LLStopWatchControlsMixinCommon::restart()
{
+ LL_PROFILE_ZONE_SCOPED;
switch (mPlayState)
{
case STOPPED:
@@ -1244,11 +1316,13 @@ void LLStopWatchControlsMixinCommon::restart()
void LLStopWatchControlsMixinCommon::reset()
{
+ LL_PROFILE_ZONE_SCOPED;
handleReset();
}
void LLStopWatchControlsMixinCommon::setPlayState( EPlayState state )
{
+ LL_PROFILE_ZONE_SCOPED;
switch(state)
{
case STOPPED:
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index d0b4a842a6..1f3d37336a 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -355,6 +355,7 @@ namespace LLTrace
template <typename T>
S32 getSampleCount(const StatType<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
S32 num_samples = 0;
@@ -374,6 +375,7 @@ namespace LLTrace
template <typename T>
typename T::value_t getPeriodMin(const StatType<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
bool has_value = false;
@@ -396,6 +398,7 @@ namespace LLTrace
template<typename T>
T getPeriodMin(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return T(getPeriodMin(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
}
@@ -403,6 +406,7 @@ namespace LLTrace
template<typename T>
T getPeriodMin(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return T(getPeriodMin(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
}
@@ -410,6 +414,7 @@ namespace LLTrace
template<typename T>
T getPeriodMin(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return T(getPeriodMin(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
}
@@ -419,6 +424,7 @@ namespace LLTrace
template <typename T>
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
typename RelatedTypes<typename T::value_t>::fractional_t min_val(std::numeric_limits<F64>::max());
@@ -433,6 +439,7 @@ namespace LLTrace
template<typename T>
typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return typename RelatedTypes<T>::fractional_t(getPeriodMinPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
}
@@ -444,6 +451,7 @@ namespace LLTrace
template <typename T>
typename T::value_t getPeriodMax(const StatType<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
bool has_value = false;
@@ -466,6 +474,7 @@ namespace LLTrace
template<typename T>
T getPeriodMax(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return T(getPeriodMax(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
}
@@ -473,6 +482,7 @@ namespace LLTrace
template<typename T>
T getPeriodMax(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return T(getPeriodMax(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
}
@@ -480,6 +490,7 @@ namespace LLTrace
template<typename T>
T getPeriodMax(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return T(getPeriodMax(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
}
@@ -489,6 +500,7 @@ namespace LLTrace
template <typename T>
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
F64 max_val = std::numeric_limits<F64>::min();
@@ -503,6 +515,7 @@ namespace LLTrace
template<typename T>
typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return typename RelatedTypes<T>::fractional_t(getPeriodMaxPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
}
@@ -514,6 +527,7 @@ namespace LLTrace
template <typename T>
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
typename RelatedTypes<typename T::value_t>::fractional_t mean(0);
@@ -534,12 +548,14 @@ namespace LLTrace
template<typename T>
typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
}
F64 getPeriodMean(const StatType<SampleAccumulator>& stat, S32 num_periods = S32_MAX);
template<typename T>
typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
}
@@ -547,6 +563,7 @@ namespace LLTrace
template<typename T>
typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
}
@@ -556,6 +573,7 @@ namespace LLTrace
template <typename T>
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
num_periods = llmin(num_periods, getNumRecordedPeriods());
typename RelatedTypes<typename T::value_t>::fractional_t mean = 0;
@@ -577,9 +595,39 @@ namespace LLTrace
template<typename T>
typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return typename RelatedTypes<T>::fractional_t(getPeriodMeanPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
}
+ F64 getPeriodMedian( const StatType<SampleAccumulator>& stat, S32 num_periods = S32_MAX);
+
+ template <typename T>
+ typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMedianPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ num_periods = llmin(num_periods, getNumRecordedPeriods());
+
+ std::vector <typename RelatedTypes<typename T::value_t>::fractional_t> buf;
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ Recording& recording = getPrevRecording(i);
+ if (recording.getDuration() > (F32Seconds)0.f)
+ {
+ buf.push_back(recording.getPerSec(stat));
+ }
+ }
+ std::sort(buf.begin(), buf.end());
+
+ return typename RelatedTypes<T>::fractional_t((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]);
+ }
+
+ template<typename T>
+ typename RelatedTypes<T>::fractional_t getPeriodMedianPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ return typename RelatedTypes<T>::fractional_t(getPeriodMedianPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
+ }
+
//
// PERIODIC STANDARD DEVIATION
//
@@ -589,6 +637,7 @@ namespace LLTrace
template<typename T>
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
}
@@ -596,6 +645,7 @@ namespace LLTrace
template<typename T>
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX)
{
+ LL_PROFILE_ZONE_SCOPED;
return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
}
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 025dc57044..7ae1e72784 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -274,12 +274,10 @@ void ThreadRecorder::pushToParent()
}
-static LLTrace::BlockTimerStatHandle FTM_PULL_TRACE_DATA_FROM_CHILDREN("Pull child thread trace data");
-
void ThreadRecorder::pullFromChildren()
{
#if LL_TRACE_ENABLED
- LL_RECORD_BLOCK_TIME(FTM_PULL_TRACE_DATA_FROM_CHILDREN);
+ LL_PROFILE_ZONE_SCOPED;
if (mActiveRecordings.empty()) return;
{ LLMutexLock lock(&mChildListMutex);
diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h
index fe7482ba29..86a396ab06 100644
--- a/indra/llcommon/lluuid.h
+++ b/indra/llcommon/lluuid.h
@@ -184,6 +184,17 @@ struct boost::hash<LLUUID>
}
};
+// Adapt boost hash to std hash
+namespace std
+{
+ template<> struct hash<LLUUID>
+ {
+ std::size_t operator()(LLUUID const& s) const noexcept
+ {
+ return boost::hash<LLUUID>()(s);
+ }
+ };
+}
#endif
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index 9b89159625..5daa29adf4 100644
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -90,19 +90,19 @@ namespace tut
{
Keyed one("one");
ensure_equals(Keyed::instanceCount(), 1);
- Keyed* found = Keyed::getInstance("one");
- ensure("couldn't find stack Keyed", found);
- ensure_equals("found wrong Keyed instance", found, &one);
+ auto found = Keyed::getInstance("one");
+ ensure("couldn't find stack Keyed", bool(found));
+ ensure_equals("found wrong Keyed instance", found.get(), &one);
{
boost::scoped_ptr<Keyed> two(new Keyed("two"));
ensure_equals(Keyed::instanceCount(), 2);
- Keyed* found = Keyed::getInstance("two");
- ensure("couldn't find heap Keyed", found);
- ensure_equals("found wrong Keyed instance", found, two.get());
+ auto found = Keyed::getInstance("two");
+ ensure("couldn't find heap Keyed", bool(found));
+ ensure_equals("found wrong Keyed instance", found.get(), two.get());
}
ensure_equals(Keyed::instanceCount(), 1);
}
- Keyed* found = Keyed::getInstance("one");
+ auto found = Keyed::getInstance("one");
ensure("Keyed key lives too long", ! found);
ensure_equals(Keyed::instanceCount(), 0);
}
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index f0eafa8201..447c7f50f2 100644
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -356,14 +356,15 @@ namespace tut
// Create a script file in a temporary place.
NamedTempFile script("py",
+ "from __future__ import print_function" EOL
"import sys" EOL
"import time" EOL
EOL
"time.sleep(2)" EOL
- "print >>sys.stdout, 'stdout after wait'" EOL
+ "print('stdout after wait',file=sys.stdout)" EOL
"sys.stdout.flush()" EOL
"time.sleep(2)" EOL
- "print >>sys.stderr, 'stderr after wait'" EOL
+ "print('stderr after wait',file=sys.stderr)" EOL
"sys.stderr.flush()" EOL
);
@@ -568,12 +569,12 @@ namespace tut
{
set_test_name("arguments");
PythonProcessLauncher py(get_test_name(),
- "from __future__ import with_statement\n"
+ "from __future__ import with_statement, print_function\n"
"import sys\n"
// note nonstandard output-file arg!
"with open(sys.argv[3], 'w') as f:\n"
" for arg in sys.argv[1:]:\n"
- " print >>f, arg\n");
+ " print(arg,file=f)\n");
// We expect that PythonProcessLauncher has already appended
// its own NamedTempFile to mParams.args (sys.argv[0]).
py.mParams.args.add("first arg"); // sys.argv[1]
@@ -857,7 +858,8 @@ namespace tut
set_test_name("'bogus' test");
CaptureLog recorder;
PythonProcessLauncher py(get_test_name(),
- "print 'Hello world'\n");
+ "from __future__ import print_function\n"
+ "print('Hello world')\n");
py.mParams.files.add(LLProcess::FileParam("bogus"));
py.mPy = LLProcess::create(py.mParams);
ensure("should have rejected 'bogus'", ! py.mPy);
@@ -872,7 +874,8 @@ namespace tut
// Replace this test with one or more real 'file' tests when we
// implement 'file' support
PythonProcessLauncher py(get_test_name(),
- "print 'Hello world'\n");
+ "from __future__ import print_function\n"
+ "print('Hello world')\n");
py.mParams.files.add(LLProcess::FileParam());
py.mParams.files.add(LLProcess::FileParam("file"));
py.mPy = LLProcess::create(py.mParams);
@@ -887,7 +890,8 @@ namespace tut
// implement 'tpipe' support
CaptureLog recorder;
PythonProcessLauncher py(get_test_name(),
- "print 'Hello world'\n");
+ "from __future__ import print_function\n"
+ "print('Hello world')\n");
py.mParams.files.add(LLProcess::FileParam());
py.mParams.files.add(LLProcess::FileParam("tpipe"));
py.mPy = LLProcess::create(py.mParams);
@@ -904,7 +908,8 @@ namespace tut
// implement 'npipe' support
CaptureLog recorder;
PythonProcessLauncher py(get_test_name(),
- "print 'Hello world'\n");
+ "from __future__ import print_function\n"
+ "print('Hello world')\n");
py.mParams.files.add(LLProcess::FileParam());
py.mParams.files.add(LLProcess::FileParam());
py.mParams.files.add(LLProcess::FileParam("npipe"));
@@ -980,7 +985,8 @@ namespace tut
{
set_test_name("get*Pipe() validation");
PythonProcessLauncher py(get_test_name(),
- "print 'this output is expected'\n");
+ "from __future__ import print_function\n"
+ "print('this output is expected')\n");
py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stdin
py.mParams.files.add(LLProcess::FileParam()); // inherit stdout
py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stderr
@@ -1000,14 +1006,15 @@ namespace tut
{
set_test_name("talk to stdin/stdout");
PythonProcessLauncher py(get_test_name(),
+ "from __future__ import print_function\n"
"import sys, time\n"
- "print 'ok'\n"
+ "print('ok')\n"
"sys.stdout.flush()\n"
"# wait for 'go' from test program\n"
"go = sys.stdin.readline()\n"
"if go != 'go\\n':\n"
" sys.exit('expected \"go\", saw %r' % go)\n"
- "print 'ack'\n");
+ "print('ack')\n");
py.mParams.files.add(LLProcess::FileParam("pipe")); // stdin
py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
py.launch();
@@ -1118,7 +1125,8 @@ namespace tut
{
set_test_name("ReadPipe \"eof\" event");
PythonProcessLauncher py(get_test_name(),
- "print 'Hello from Python!'\n");
+ "from __future__ import print_function\n"
+ "print('Hello from Python!')\n");
py.mParams.files.add(LLProcess::FileParam()); // stdin
py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
py.launch();
diff --git a/indra/llcommon/tests/threadsafeschedule_test.cpp b/indra/llcommon/tests/threadsafeschedule_test.cpp
new file mode 100644
index 0000000000..af67b9f492
--- /dev/null
+++ b/indra/llcommon/tests/threadsafeschedule_test.cpp
@@ -0,0 +1,69 @@
+/**
+ * @file threadsafeschedule_test.cpp
+ * @author Nat Goodspeed
+ * @date 2021-10-04
+ * @brief Test for threadsafeschedule.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "threadsafeschedule.h"
+// STL headers
+// std headers
+#include <chrono>
+// external library headers
+// other Linden headers
+#include "../test/lltut.h"
+
+using namespace std::literals::chrono_literals; // ms suffix
+using namespace std::literals::string_literals; // s suffix
+using Queue = LL::ThreadSafeSchedule<std::string>;
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct threadsafeschedule_data
+ {
+ Queue queue;
+ };
+ typedef test_group<threadsafeschedule_data> threadsafeschedule_group;
+ typedef threadsafeschedule_group::object object;
+ threadsafeschedule_group threadsafeschedulegrp("threadsafeschedule");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("push");
+ // Simply calling push() a few times might result in indeterminate
+ // delivery order if the resolution of steady_clock is coarser than
+ // the real time required for each push() call. Explicitly increment
+ // the timestamp for each one -- but since we're passing explicit
+ // timestamps, make the queue reorder them.
+ queue.push(Queue::TimeTuple(Queue::Clock::now() + 20ms, "ghi"));
+ // Given the various push() overloads, you have to match the type
+ // exactly: conversions are ambiguous.
+ queue.push("abc"s);
+ queue.push(Queue::Clock::now() + 10ms, "def");
+ queue.close();
+ auto entry = queue.pop();
+ ensure_equals("failed to pop first", std::get<0>(entry), "abc"s);
+ entry = queue.pop();
+ ensure_equals("failed to pop second", std::get<0>(entry), "def"s);
+ ensure("queue not closed", queue.isClosed());
+ ensure("queue prematurely done", ! queue.done());
+ std::string s;
+ bool popped = queue.tryPopFor(1s, s);
+ ensure("failed to pop third", popped);
+ ensure_equals("third is wrong", s, "ghi"s);
+ popped = queue.tryPop(s);
+ ensure("queue not empty", ! popped);
+ ensure("queue not done", queue.done());
+ }
+} // namespace tut
diff --git a/indra/llcommon/tests/tuple_test.cpp b/indra/llcommon/tests/tuple_test.cpp
new file mode 100644
index 0000000000..af94e2086c
--- /dev/null
+++ b/indra/llcommon/tests/tuple_test.cpp
@@ -0,0 +1,47 @@
+/**
+ * @file tuple_test.cpp
+ * @author Nat Goodspeed
+ * @date 2021-10-04
+ * @brief Test for tuple.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "tuple.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "../test/lltut.h"
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct tuple_data
+ {
+ };
+ typedef test_group<tuple_data> tuple_group;
+ typedef tuple_group::object object;
+ tuple_group tuplegrp("tuple");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("tuple");
+ std::tuple<std::string, int> tup{ "abc", 17 };
+ std::tuple<int, std::string, int> ptup{ tuple_cons(34, tup) };
+ std::tuple<std::string, int> tup2;
+ int i;
+ std::tie(i, tup2) = tuple_split(ptup);
+ ensure_equals("tuple_car() fail", i, 34);
+ ensure_equals("tuple_cdr() (0) fail", std::get<0>(tup2), "abc");
+ ensure_equals("tuple_cdr() (1) fail", std::get<1>(tup2), 17);
+ }
+} // namespace tut
diff --git a/indra/llcommon/tests/workqueue_test.cpp b/indra/llcommon/tests/workqueue_test.cpp
new file mode 100644
index 0000000000..d5405400fd
--- /dev/null
+++ b/indra/llcommon/tests/workqueue_test.cpp
@@ -0,0 +1,159 @@
+/**
+ * @file workqueue_test.cpp
+ * @author Nat Goodspeed
+ * @date 2021-10-07
+ * @brief Test for workqueue.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "workqueue.h"
+// STL headers
+// std headers
+#include <chrono>
+#include <deque>
+// external library headers
+// other Linden headers
+#include "../test/lltut.h"
+#include "llcond.h"
+#include "llstring.h"
+#include "stringize.h"
+
+using namespace LL;
+using namespace std::literals::chrono_literals; // ms suffix
+using namespace std::literals::string_literals; // s suffix
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct workqueue_data
+ {
+ WorkQueue queue{"queue"};
+ };
+ typedef test_group<workqueue_data> workqueue_group;
+ typedef workqueue_group::object object;
+ workqueue_group workqueuegrp("workqueue");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("name");
+ ensure_equals("didn't capture name", queue.getKey(), "queue");
+ ensure("not findable", WorkQueue::getInstance("queue") == queue.getWeak().lock());
+ WorkQueue q2;
+ ensure("has no name", LLStringUtil::startsWith(q2.getKey(), "WorkQueue"));
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ set_test_name("post");
+ bool wasRun{ false };
+ // We only get away with binding a simple bool because we're running
+ // the work on the same thread.
+ queue.post([&wasRun](){ wasRun = true; });
+ queue.close();
+ ensure("ran too soon", ! wasRun);
+ queue.runUntilClose();
+ ensure("didn't run", wasRun);
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ set_test_name("postEvery");
+ // record of runs
+ using Shared = std::deque<WorkQueue::TimePoint>;
+ // This is an example of how to share data between the originator of
+ // postEvery(work) and the work item itself, since usually a WorkQueue
+ // is used to dispatch work to a different thread. Neither of them
+ // should call any of LLCond's wait methods: you don't want to stall
+ // either the worker thread or the originating thread (conventionally
+ // main). Use LLCond or a subclass even if all you want to do is
+ // signal the work item that it can quit; consider LLOneShotCond.
+ LLCond<Shared> data;
+ auto start = WorkQueue::TimePoint::clock::now();
+ auto interval = 100ms;
+ queue.postEvery(
+ interval,
+ [&data, count = 0]
+ () mutable
+ {
+ // record the timestamp at which this instance is running
+ data.update_one(
+ [](Shared& data)
+ {
+ data.push_back(WorkQueue::TimePoint::clock::now());
+ });
+ // by the 3rd call, return false to stop
+ return (++count < 3);
+ });
+ // no convenient way to close() our queue while we've got a
+ // postEvery() running, so run until we think we should have exhausted
+ // the iterations
+ queue.runFor(10*interval);
+ // Take a copy of the captured deque.
+ Shared result = data.get();
+ ensure_equals("called wrong number of times", result.size(), 3);
+ // postEvery() assumes you want the first call to happen right away.
+ // Pretend our start time was (interval) earlier than that, to make
+ // our too early/too late tests uniform for all entries.
+ start -= interval;
+ for (size_t i = 0; i < result.size(); ++i)
+ {
+ auto diff = result[i] - start;
+ start += interval;
+ try
+ {
+ ensure(STRINGIZE("call " << i << " too soon"), diff >= interval);
+ ensure(STRINGIZE("call " << i << " too late"), diff < interval*1.5);
+ }
+ catch (const tut::failure&)
+ {
+ auto interval_ms = interval / 1ms;
+ auto diff_ms = diff / 1ms;
+ std::cerr << "interval " << interval_ms
+ << "ms; diff " << diff_ms << "ms" << std::endl;
+ throw;
+ }
+ }
+ }
+
+ template<> template<>
+ void object::test<4>()
+ {
+ set_test_name("postTo");
+ WorkQueue main("main");
+ auto qptr = WorkQueue::getInstance("queue");
+ int result = 0;
+ main.postTo(
+ qptr,
+ [](){ return 17; },
+ // Note that a postTo() *callback* can safely bind a reference to
+ // a variable on the invoking thread, because the callback is run
+ // on the invoking thread.
+ [&result](int i){ result = i; });
+ // this should post the callback to main
+ qptr->runOne();
+ // this should run the callback
+ main.runOne();
+ ensure_equals("failed to run int callback", result, 17);
+
+ std::string alpha;
+ // postTo() handles arbitrary return types
+ main.postTo(
+ qptr,
+ [](){ return "abc"s; },
+ [&alpha](const std::string& s){ alpha = s; });
+ qptr->runPending();
+ main.runPending();
+ ensure_equals("failed to run string callback", alpha, "abc");
+ }
+} // namespace tut
diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h
new file mode 100644
index 0000000000..c8ad23532b
--- /dev/null
+++ b/indra/llcommon/threadsafeschedule.h
@@ -0,0 +1,373 @@
+/**
+ * @file threadsafeschedule.h
+ * @author Nat Goodspeed
+ * @date 2021-10-02
+ * @brief ThreadSafeSchedule is an ordered queue in which every item has an
+ * associated timestamp.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_THREADSAFESCHEDULE_H)
+#define LL_THREADSAFESCHEDULE_H
+
+#include "chrono.h"
+#include "llexception.h"
+#include "llthreadsafequeue.h"
+#include "tuple.h"
+#include <chrono>
+#include <tuple>
+
+namespace LL
+{
+ namespace ThreadSafeSchedulePrivate
+ {
+ using TimePoint = std::chrono::steady_clock::time_point;
+ // Bundle consumer's data with a TimePoint to order items by timestamp.
+ template <typename... Args>
+ using TimestampedTuple = std::tuple<TimePoint, Args...>;
+
+ // comparison functor for TimedTuples -- see TimedQueue comments
+ struct ReverseTupleOrder
+ {
+ template <typename Tuple>
+ bool operator()(const Tuple& left, const Tuple& right) const
+ {
+ return std::get<0>(left) > std::get<0>(right);
+ }
+ };
+
+ template <typename... Args>
+ using TimedQueue = PriorityQueueAdapter<
+ TimestampedTuple<Args...>,
+ // std::vector is the default storage for std::priority_queue,
+ // have to restate to specify comparison template parameter
+ std::vector<TimestampedTuple<Args...>>,
+ // std::priority_queue uses a counterintuitive comparison
+ // behavior: the default std::less comparator is used to present
+ // the *highest* value as top(). So to sort by earliest timestamp,
+ // we must invert by using >.
+ ReverseTupleOrder>;
+ } // namespace ThreadSafeSchedulePrivate
+
+ /**
+ * ThreadSafeSchedule is an ordered LLThreadSafeQueue in which every item
+ * is given an associated timestamp. That is, TimePoint is implicitly
+ * prepended to the std::tuple with the specified types.
+ *
+ * Items are popped in increasing chronological order. Moreover, any item
+ * with a timestamp in the future is held back until
+ * std::chrono::steady_clock reaches that timestamp.
+ */
+ template <typename... Args>
+ class ThreadSafeSchedule:
+ public LLThreadSafeQueue<ThreadSafeSchedulePrivate::TimestampedTuple<Args...>,
+ ThreadSafeSchedulePrivate::TimedQueue<Args...>>
+ {
+ public:
+ using DataTuple = std::tuple<Args...>;
+ using TimeTuple = ThreadSafeSchedulePrivate::TimestampedTuple<Args...>;
+
+ private:
+ using super = LLThreadSafeQueue<TimeTuple, ThreadSafeSchedulePrivate::TimedQueue<Args...>>;
+ using lock_t = typename super::lock_t;
+ // VS 2017 needs this due to a bug:
+ // https://developercommunity.visualstudio.com/t/cannot-access-protected-enumerator-of-enclosing-cl/203430
+ enum pop_result { EMPTY=super::EMPTY, DONE=super::DONE, WAITING=super::WAITING, POPPED=super::POPPED };
+
+ public:
+ using Closed = LLThreadSafeQueueInterrupt;
+ using TimePoint = ThreadSafeSchedulePrivate::TimePoint;
+ using Clock = TimePoint::clock;
+
+ ThreadSafeSchedule(U32 capacity=1024):
+ super(capacity)
+ {}
+
+ /*----------------------------- push() -----------------------------*/
+ /// explicitly pass TimeTuple
+ using super::push;
+
+ /// pass DataTuple with implicit now
+ // This could be ambiguous for Args with a single type. Unfortunately
+ // we can't enable_if an individual method with a condition based on
+ // the *class* template arguments, only on that method's template
+ // arguments. We could specialize this class for the single-Args case;
+ // we could minimize redundancy by breaking out a common base class...
+ void push(const DataTuple& tuple)
+ {
+ push(tuple_cons(Clock::now(), tuple));
+ }
+
+ /// individually pass each component of the TimeTuple
+ void push(const TimePoint& time, Args&&... args)
+ {
+ push(TimeTuple(time, std::forward<Args>(args)...));
+ }
+
+ /// individually pass every component except the TimePoint (implies now)
+ // This could be ambiguous if the first specified template parameter
+ // type is also TimePoint. We could try to disambiguate, but a simpler
+ // approach would be for the caller to explicitly construct DataTuple
+ // and call that overload.
+ void push(Args&&... args)
+ {
+ push(Clock::now(), std::forward<Args>(args)...);
+ }
+
+ /*--------------------------- tryPush() ----------------------------*/
+ /// explicit TimeTuple
+ using super::tryPush;
+
+ /// DataTuple with implicit now
+ bool tryPush(const DataTuple& tuple)
+ {
+ return tryPush(tuple_cons(Clock::now(), tuple));
+ }
+
+ /// individually pass components
+ bool tryPush(const TimePoint& time, Args&&... args)
+ {
+ return tryPush(TimeTuple(time, std::forward<Args>(args)...));
+ }
+
+ /// individually pass components with implicit now
+ bool tryPush(Args&&... args)
+ {
+ return tryPush(Clock::now(), std::forward<Args>(args)...);
+ }
+
+ /*-------------------------- tryPushFor() --------------------------*/
+ /// explicit TimeTuple
+ using super::tryPushFor;
+
+ /// DataTuple with implicit now
+ template <typename Rep, typename Period>
+ bool tryPushFor(const std::chrono::duration<Rep, Period>& timeout,
+ const DataTuple& tuple)
+ {
+ return tryPushFor(timeout, tuple_cons(Clock::now(), tuple));
+ }
+
+ /// individually pass components
+ template <typename Rep, typename Period>
+ bool tryPushFor(const std::chrono::duration<Rep, Period>& timeout,
+ const TimePoint& time, Args&&... args)
+ {
+ return tryPushFor(TimeTuple(time, std::forward<Args>(args)...));
+ }
+
+ /// individually pass components with implicit now
+ template <typename Rep, typename Period>
+ bool tryPushFor(const std::chrono::duration<Rep, Period>& timeout,
+ Args&&... args)
+ {
+ return tryPushFor(Clock::now(), std::forward<Args>(args)...);
+ }
+
+ /*------------------------- tryPushUntil() -------------------------*/
+ /// explicit TimeTuple
+ using super::tryPushUntil;
+
+ /// DataTuple with implicit now
+ template <typename Clock, typename Duration>
+ bool tryPushUntil(const std::chrono::time_point<Clock, Duration>& until,
+ const DataTuple& tuple)
+ {
+ return tryPushUntil(until, tuple_cons(Clock::now(), tuple));
+ }
+
+ /// individually pass components
+ template <typename Clock, typename Duration>
+ bool tryPushUntil(const std::chrono::time_point<Clock, Duration>& until,
+ const TimePoint& time, Args&&... args)
+ {
+ return tryPushUntil(until, TimeTuple(time, std::forward<Args>(args)...));
+ }
+
+ /// individually pass components with implicit now
+ template <typename Clock, typename Duration>
+ bool tryPushUntil(const std::chrono::time_point<Clock, Duration>& until,
+ Args&&... args)
+ {
+ return tryPushUntil(until, Clock::now(), std::forward<Args>(args)...);
+ }
+
+ /*----------------------------- pop() ------------------------------*/
+ // Our consumer may or may not care about the timestamp associated
+ // with each popped item, so we allow retrieving either DataTuple or
+ // TimeTuple. One potential use would be to observe, and possibly
+ // adjust for, the time lag between the item time and the actual
+ // current time.
+
+ /// pop DataTuple by value
+ // It would be great to notice when sizeof...(Args) == 1 and directly
+ // return the first (only) value, instead of making pop()'s caller
+ // call std::get<0>(value). See push(DataTuple) remarks for why we
+ // haven't yet jumped through those hoops.
+ DataTuple pop()
+ {
+ return tuple_cdr(popWithTime());
+ }
+
+ /// pop TimeTuple by value
+ TimeTuple popWithTime()
+ {
+ lock_t lock(super::mLock);
+ // We can't just sit around waiting forever, given that there may
+ // be items in the queue that are not yet ready but will *become*
+ // ready in the near future. So in fact, with this class, every
+ // pop() becomes a tryPopUntil(), constrained to the timestamp of
+ // the head item. It almost doesn't matter what we specify for the
+ // caller's time constraint -- all we really care about is the
+ // head item's timestamp. Since pop() and popWithTime() are
+ // defined to wait until either an item becomes available or the
+ // queue is closed, loop until one of those things happens. The
+ // constraint we pass just determines how often we'll loop while
+ // waiting.
+ TimeTuple tt;
+ while (true)
+ {
+ // Pick a point suitably far into the future.
+ TimePoint until = TimePoint::clock::now() + std::chrono::hours(24);
+ pop_result popped = tryPopUntil_(lock, until, tt);
+ if (popped == POPPED)
+ return std::move(tt);
+
+ // DONE: throw, just as super::pop() does
+ if (popped == DONE)
+ {
+ LLTHROW(LLThreadSafeQueueInterrupt());
+ }
+ // WAITING: we've still got items to drain.
+ // EMPTY: not closed, so it's worth waiting for more items.
+ // Either way, loop back to wait.
+ }
+ }
+
+ // We can use tryPop(TimeTuple&) just as it stands; the only behavior
+ // difference is in our canPop() override method.
+ using super::tryPop;
+
+ /// tryPop(DataTuple&)
+ bool tryPop(DataTuple& tuple)
+ {
+ TimeTuple tt;
+ if (! super::tryPop(tt))
+ return false;
+ tuple = tuple_cdr(std::move(tt));
+ return true;
+ }
+
+ /// for when Args has exactly one type
+ bool tryPop(typename std::tuple_element<1, TimeTuple>::type& value)
+ {
+ TimeTuple tt;
+ if (! super::tryPop(tt))
+ return false;
+ value = std::get<1>(std::move(tt));
+ return true;
+ }
+
+ /// tryPopFor()
+ template <typename Rep, typename Period, typename Tuple>
+ bool tryPopFor(const std::chrono::duration<Rep, Period>& timeout, Tuple& tuple)
+ {
+ // It's important to use OUR tryPopUntil() implementation, rather
+ // than delegating immediately to our base class.
+ return tryPopUntil(Clock::now() + timeout, tuple);
+ }
+
+ /// tryPopUntil(TimeTuple&)
+ template <typename Clock, typename Duration>
+ bool tryPopUntil(const std::chrono::time_point<Clock, Duration>& until,
+ TimeTuple& tuple)
+ {
+ // super::tryPopUntil() wakes up when an item becomes available or
+ // we hit 'until', whichever comes first. Thing is, the current
+ // head of the queue could become ready sooner than either of
+ // those events, and we need to deliver it as soon as it does.
+ // Don't wait past the TimePoint of the head item.
+ // Naturally, lock the queue before peeking at mStorage.
+ return super::tryLockUntil(
+ until,
+ [this, until, &tuple](lock_t& lock)
+ {
+ // Use our time_point_cast to allow for 'until' that's a
+ // time_point type other than TimePoint.
+ return POPPED ==
+ tryPopUntil_(lock, LL::time_point_cast<TimePoint>(until), tuple);
+ });
+ }
+
+ pop_result tryPopUntil_(lock_t& lock, const TimePoint& until, TimeTuple& tuple)
+ {
+ TimePoint adjusted = until;
+ if (! super::mStorage.empty())
+ {
+ // use whichever is earlier: the head item's timestamp, or
+ // the caller's limit
+ adjusted = min(std::get<0>(super::mStorage.front()), adjusted);
+ }
+ // now delegate to base-class tryPopUntil_()
+ pop_result popped;
+ while ((popped = pop_result(super::tryPopUntil_(lock, adjusted, tuple))) == WAITING)
+ {
+ // If super::tryPopUntil_() returns WAITING, it means there's
+ // a head item, but it's not yet time. But it's worth looping
+ // back to recheck.
+ }
+ return popped;
+ }
+
+ /// tryPopUntil(DataTuple&)
+ template <typename Clock, typename Duration>
+ bool tryPopUntil(const std::chrono::time_point<Clock, Duration>& until,
+ DataTuple& tuple)
+ {
+ TimeTuple tt;
+ if (! tryPopUntil(until, tt))
+ return false;
+ tuple = tuple_cdr(std::move(tt));
+ return true;
+ }
+
+ /// for when Args has exactly one type
+ template <typename Clock, typename Duration>
+ bool tryPopUntil(const std::chrono::time_point<Clock, Duration>& until,
+ typename std::tuple_element<1, TimeTuple>::type& value)
+ {
+ TimeTuple tt;
+ if (! tryPopUntil(until, tt))
+ return false;
+ value = std::get<1>(std::move(tt));
+ return true;
+ }
+
+ /*------------------------------ etc. ------------------------------*/
+ // We can't hide items that aren't yet ready because we can't traverse
+ // the underlying priority_queue: it has no iterators, only top(). So
+ // a consumer could observe size() > 0 and yet tryPop() returns false.
+ // Shrug, in a multi-consumer scenario that would be expected behavior.
+ using super::size;
+ // open/closed state
+ using super::close;
+ using super::isClosed;
+ using super::done;
+
+ private:
+ // this method is called by base class pop_() every time we're
+ // considering whether to deliver the current head element
+ bool canPop(const TimeTuple& head) const override
+ {
+ // an item with a future timestamp isn't yet ready to pop
+ // (should we add some slop for overhead?)
+ return std::get<0>(head) <= Clock::now();
+ }
+ };
+
+} // namespace LL
+
+#endif /* ! defined(LL_THREADSAFESCHEDULE_H) */
diff --git a/indra/llcommon/tuple.h b/indra/llcommon/tuple.h
new file mode 100644
index 0000000000..bfe7e3c2ba
--- /dev/null
+++ b/indra/llcommon/tuple.h
@@ -0,0 +1,84 @@
+/**
+ * @file tuple.h
+ * @author Nat Goodspeed
+ * @date 2021-10-04
+ * @brief A couple tuple utilities
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_TUPLE_H)
+#define LL_TUPLE_H
+
+#include <tuple>
+#include <type_traits> // std::remove_reference
+#include <utility> // std::pair
+
+/**
+ * tuple_cons() behaves like LISP cons: it uses std::tuple_cat() to prepend a
+ * new item of arbitrary type to an existing std::tuple.
+ */
+template <typename First, typename... Rest, typename Tuple_=std::tuple<Rest...>>
+auto tuple_cons(First&& first, Tuple_&& rest)
+{
+ // All we need to do is make a tuple containing 'first', and let
+ // tuple_cat() do the hard part.
+ return std::tuple_cat(std::tuple<First>(std::forward<First>(first)),
+ std::forward<Tuple_>(rest));
+}
+
+/**
+ * tuple_car() behaves like LISP car: it extracts the first item from a
+ * std::tuple.
+ */
+template <typename... Args, typename Tuple_=std::tuple<Args...>>
+auto tuple_car(Tuple_&& tuple)
+{
+ return std::get<0>(std::forward<Tuple_>(tuple));
+}
+
+/**
+ * tuple_cdr() behaves like LISP cdr: it returns a new tuple containing
+ * everything BUT the first item.
+ */
+// derived from https://stackoverflow.com/a/24046437
+template <typename Tuple, std::size_t... Indices>
+auto tuple_cdr_(Tuple&& tuple, const std::index_sequence<Indices...>)
+{
+ // Given an index sequence from [0..N-1), extract tuple items [1..N)
+ return std::make_tuple(std::get<Indices+1u>(std::forward<Tuple>(tuple))...);
+}
+
+template <typename Tuple>
+auto tuple_cdr(Tuple&& tuple)
+{
+ return tuple_cdr_(
+ std::forward<Tuple>(tuple),
+ // Pass helper function an index sequence one item shorter than tuple
+ std::make_index_sequence<
+ std::tuple_size<
+ // tuple_size doesn't like reference types
+ typename std::remove_reference<Tuple>::type
+ >::value - 1u>
+ ());
+}
+
+/**
+ * tuple_split(), the opposite of tuple_cons(), has no direct analog in LISP.
+ * It returns a std::pair of tuple_car(), tuple_cdr(). We could call this
+ * function tuple_car_cdr(), or tuple_slice() or some such. But tuple_split()
+ * feels more descriptive.
+ */
+template <typename... Args, typename Tuple_=std::tuple<Args...>>
+auto tuple_split(Tuple_&& tuple)
+{
+ // We're not really worried about forwarding multiple times a tuple that
+ // might contain move-only items, because the implementation above only
+ // applies std::get() exactly once to each item.
+ return std::make_pair(tuple_car(std::forward<Tuple_>(tuple)),
+ tuple_cdr(std::forward<Tuple_>(tuple)));
+}
+
+#endif /* ! defined(LL_TUPLE_H) */
diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp
new file mode 100644
index 0000000000..b32357e832
--- /dev/null
+++ b/indra/llcommon/workqueue.cpp
@@ -0,0 +1,130 @@
+/**
+ * @file workqueue.cpp
+ * @author Nat Goodspeed
+ * @date 2021-10-06
+ * @brief Implementation for WorkQueue.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "workqueue.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llcoros.h"
+#include LLCOROS_MUTEX_HEADER
+#include "llerror.h"
+#include "llexception.h"
+#include "stringize.h"
+
+using Mutex = LLCoros::Mutex;
+using Lock = LLCoros::LockType;
+
+LL::WorkQueue::WorkQueue(const std::string& name):
+ super(makeName(name))
+{
+ // TODO: register for "LLApp" events so we can implicitly close() on
+ // viewer shutdown.
+}
+
+void LL::WorkQueue::close()
+{
+ mQueue.close();
+}
+
+void LL::WorkQueue::runUntilClose()
+{
+ try
+ {
+ for (;;)
+ {
+ callWork(mQueue.pop());
+ }
+ }
+ catch (const Queue::Closed&)
+ {
+ }
+}
+
+bool LL::WorkQueue::runPending()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ for (Work work; mQueue.tryPop(work); )
+ {
+ callWork(work);
+ }
+ return ! mQueue.done();
+}
+
+bool LL::WorkQueue::runOne()
+{
+ Work work;
+ if (mQueue.tryPop(work))
+ {
+ callWork(work);
+ }
+ return ! mQueue.done();
+}
+
+bool LL::WorkQueue::runUntil(const TimePoint& until)
+{
+ // Should we subtract some slop to allow for typical Work execution time?
+ // How much slop?
+ Work work;
+ while (TimePoint::clock::now() < until && mQueue.tryPopUntil(until, work))
+ {
+ callWork(work);
+ }
+ return ! mQueue.done();
+}
+
+std::string LL::WorkQueue::makeName(const std::string& name)
+{
+ if (! name.empty())
+ return name;
+
+ static U32 discriminator = 0;
+ static Mutex mutex;
+ U32 num;
+ {
+ // Protect discriminator from concurrent access by different threads.
+ // It can't be thread_local, else two racing threads will come up with
+ // the same name.
+ Lock lk(mutex);
+ num = discriminator++;
+ }
+ return STRINGIZE("WorkQueue" << num);
+}
+
+void LL::WorkQueue::callWork(const Queue::DataTuple& work)
+{
+ // ThreadSafeSchedule::pop() always delivers a tuple, even when
+ // there's only one data field per item, as for us.
+ callWork(std::get<0>(work));
+}
+
+void LL::WorkQueue::callWork(const Work& work)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ try
+ {
+ work();
+ }
+ catch (...)
+ {
+ // No matter what goes wrong with any individual work item, the worker
+ // thread must go on! Log our own instance name with the exception.
+ LOG_UNHANDLED_EXCEPTION(getKey());
+ }
+}
+
+void LL::WorkQueue::error(const std::string& msg)
+{
+ LL_ERRS("WorkQueue") << msg << LL_ENDL;
+}
diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h
new file mode 100644
index 0000000000..5ec790da79
--- /dev/null
+++ b/indra/llcommon/workqueue.h
@@ -0,0 +1,335 @@
+/**
+ * @file workqueue.h
+ * @author Nat Goodspeed
+ * @date 2021-09-30
+ * @brief Queue used for inter-thread work passing.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_WORKQUEUE_H)
+#define LL_WORKQUEUE_H
+
+#include "llinstancetracker.h"
+#include "threadsafeschedule.h"
+#include <chrono>
+#include <functional> // std::function
+#include <queue>
+#include <string>
+#include <utility> // std::pair
+#include <vector>
+
+namespace LL
+{
+ /**
+ * A typical WorkQueue has a string name that can be used to find it.
+ */
+ class WorkQueue: public LLInstanceTracker<WorkQueue, std::string>
+ {
+ private:
+ using super = LLInstanceTracker<WorkQueue, std::string>;
+
+ public:
+ using Work = std::function<void()>;
+
+ private:
+ using Queue = ThreadSafeSchedule<Work>;
+ // helper for postEvery()
+ template <typename Rep, typename Period, typename CALLABLE>
+ class BackJack;
+
+ public:
+ using TimePoint = Queue::TimePoint;
+ using TimedWork = Queue::TimeTuple;
+ using Closed = Queue::Closed;
+
+ /**
+ * You may omit the WorkQueue name, in which case a unique name is
+ * synthesized; for practical purposes that makes it anonymous.
+ */
+ WorkQueue(const std::string& name = std::string());
+
+ /**
+ * Since the point of WorkQueue is to pass work to some other worker
+ * thread(s) asynchronously, it's important that the WorkQueue continue
+ * to exist until the worker thread(s) have drained it. To communicate
+ * that it's time for them to quit, close() the queue.
+ */
+ void close();
+
+ /*---------------------- fire and forget API -----------------------*/
+
+ /// fire-and-forget, but at a particular (future?) time
+ template <typename CALLABLE>
+ void post(const TimePoint& time, CALLABLE&& callable)
+ {
+ // Defer reifying an arbitrary CALLABLE until we hit this method.
+ // All other methods should accept CALLABLEs of arbitrary type to
+ // avoid multiple levels of std::function indirection.
+ mQueue.push(TimedWork(time, std::move(callable)));
+ }
+
+ /// fire-and-forget
+ template <typename CALLABLE>
+ void post(CALLABLE&& callable)
+ {
+ // We use TimePoint::clock::now() instead of TimePoint's
+ // representation of the epoch because this WorkQueue may contain
+ // a mix of past-due TimedWork items and TimedWork items scheduled
+ // for the future. Sift this new item into the correct place.
+ post(TimePoint::clock::now(), std::move(callable));
+ }
+
+ /**
+ * Launch a callable returning bool that will trigger repeatedly at
+ * specified interval, until the callable returns false.
+ *
+ * If you need to signal that callable from outside, DO NOT bind a
+ * reference to a simple bool! That's not thread-safe. Instead, bind
+ * an LLCond variant, e.g. LLOneShotCond or LLBoolCond.
+ */
+ template <typename Rep, typename Period, typename CALLABLE>
+ void postEvery(const std::chrono::duration<Rep, Period>& interval,
+ CALLABLE&& callable);
+
+ template <typename CALLABLE>
+ bool tryPost(CALLABLE&& callable)
+ {
+ return mQueue.tryPush(TimedWork(TimePoint::clock::now(), std::move(callable)));
+ }
+
+ /*------------------------- handshake API --------------------------*/
+
+ /**
+ * Post work to another WorkQueue to be run at a specified time,
+ * requesting a specific callback to be run on this WorkQueue on
+ * completion.
+ *
+ * Returns true if able to post, false if the other WorkQueue is
+ * inaccessible.
+ */
+ // Apparently some Microsoft header file defines a macro CALLBACK? The
+ // natural template argument name CALLBACK produces very weird Visual
+ // Studio compile errors that seem utterly unrelated to this source
+ // code.
+ template <typename CALLABLE, typename FOLLOWUP>
+ bool postTo(WorkQueue::weak_t target,
+ const TimePoint& time, CALLABLE&& callable, FOLLOWUP&& callback)
+ {
+ // We're being asked to post to the WorkQueue at target.
+ // target is a weak_ptr: have to lock it to check it.
+ auto tptr = target.lock();
+ if (! tptr)
+ // can't post() if the target WorkQueue has been destroyed
+ return false;
+
+ // Here we believe target WorkQueue still exists. Post to it a
+ // lambda that packages our callable, our callback and a weak_ptr
+ // to this originating WorkQueue.
+ tptr->post(
+ time,
+ [reply = super::getWeak(),
+ callable = std::move(callable),
+ callback = std::move(callback)]
+ ()
+ {
+ // Call the callable in any case -- but to minimize
+ // copying the result, immediately bind it into a reply
+ // lambda. The reply lambda also binds the original
+ // callback, so that when we, the originating WorkQueue,
+ // finally receive and process the reply lambda, we'll
+ // call the bound callback with the bound result -- on the
+ // same thread that originally called postTo().
+ auto rlambda =
+ [result = callable(),
+ callback = std::move(callback)]
+ ()
+ { callback(std::move(result)); };
+ // Check if this originating WorkQueue still exists.
+ // Remember, the outer lambda is now running on a thread
+ // servicing the target WorkQueue, and real time has
+ // elapsed since postTo()'s tptr->post() call.
+ // reply is a weak_ptr: have to lock it to check it.
+ auto rptr = reply.lock();
+ if (rptr)
+ {
+ // Only post reply lambda if the originating WorkQueue
+ // still exists. If not -- who would we tell? Log it?
+ try
+ {
+ rptr->post(std::move(rlambda));
+ }
+ catch (const Closed&)
+ {
+ // Originating WorkQueue might still exist, but
+ // might be Closed. Same thing: just discard the
+ // callback.
+ }
+ }
+ });
+ // looks like we were able to post()
+ return true;
+ }
+
+ /**
+ * Post work to another WorkQueue, requesting a specific callback to
+ * be run on this WorkQueue on completion.
+ *
+ * Returns true if able to post, false if the other WorkQueue is
+ * inaccessible.
+ */
+ template <typename CALLABLE, typename FOLLOWUP>
+ bool postTo(WorkQueue::weak_t target,
+ CALLABLE&& callable, FOLLOWUP&& callback)
+ {
+ return postTo(target, TimePoint::clock::now(), std::move(callable), std::move(callback));
+ }
+
+ /*--------------------------- worker API ---------------------------*/
+
+ /**
+ * runUntilClose() pulls TimedWork items off this WorkQueue until the
+ * queue is closed, at which point it returns. This would be the
+ * typical entry point for a simple worker thread.
+ */
+ void runUntilClose();
+
+ /**
+ * runPending() runs all TimedWork items that are ready to run. It
+ * returns true if the queue remains open, false if the queue has been
+ * closed. This could be used by a thread whose primary purpose is to
+ * serve the queue, but also wants to do other things with its idle time.
+ */
+ bool runPending();
+
+ /**
+ * runOne() runs at most one ready TimedWork item -- zero if none are
+ * ready. It returns true if the queue remains open, false if the
+ * queue has been closed.
+ */
+ bool runOne();
+
+ /**
+ * runFor() runs a subset of ready TimedWork items, until the
+ * timeslice has been exceeded. It returns true if the queue remains
+ * open, false if the queue has been closed. This could be used by a
+ * busy main thread to lend a bounded few CPU cycles to this WorkQueue
+ * without risking the WorkQueue blowing out the length of any one
+ * frame.
+ */
+ template <typename Rep, typename Period>
+ bool runFor(const std::chrono::duration<Rep, Period>& timeslice)
+ {
+ return runUntil(TimePoint::clock::now() + timeslice);
+ }
+
+ /**
+ * runUntil() is just like runFor(), only with a specific end time
+ * instead of a timeslice duration.
+ */
+ bool runUntil(const TimePoint& until);
+
+ private:
+ static void error(const std::string& msg);
+ static std::string makeName(const std::string& name);
+ void callWork(const Queue::DataTuple& work);
+ void callWork(const Work& work);
+ Queue mQueue;
+ };
+
+ /**
+ * BackJack is, in effect, a hand-rolled lambda, binding a WorkQueue, a
+ * CALLABLE that returns bool, a TimePoint and an interval at which to
+ * relaunch it. As long as the callable continues returning true, BackJack
+ * keeps resubmitting it to the target WorkQueue.
+ */
+ // Why is BackJack a class and not a lambda? Because, unlike a lambda, a
+ // class method gets its own 'this' pointer -- which we need to resubmit
+ // the whole BackJack callable.
+ template <typename Rep, typename Period, typename CALLABLE>
+ class WorkQueue::BackJack
+ {
+ public:
+ // bind the desired data
+ BackJack(WorkQueue::weak_t target,
+ const WorkQueue::TimePoint& start,
+ const std::chrono::duration<Rep, Period>& interval,
+ CALLABLE&& callable):
+ mTarget(target),
+ mStart(start),
+ mInterval(interval),
+ mCallable(std::move(callable))
+ {}
+
+ // Call by target WorkQueue -- note that although WE require a
+ // callable returning bool, WorkQueue wants a void callable. We
+ // consume the bool.
+ void operator()()
+ {
+ // If mCallable() throws an exception, don't catch it here: if it
+ // throws once, it's likely to throw every time, so it's a waste
+ // of time to arrange to call it again.
+ if (mCallable())
+ {
+ // Modify mStart to the new start time we desire. If we simply
+ // added mInterval to now, we'd get actual timings of
+ // (mInterval + slop), where 'slop' is the latency between the
+ // previous mStart and the WorkQueue actually calling us.
+ // Instead, add mInterval to mStart so that at least we
+ // register our intent to fire at exact mIntervals.
+ mStart += mInterval;
+
+ // We're being called at this moment by the target WorkQueue.
+ // Assume it still exists, rather than checking the result of
+ // lock().
+ // Resubmit the whole *this callable: that's why we're a class
+ // rather than a lambda. Allow moving *this so we can carry a
+ // move-only callable; but naturally this statement must be
+ // the last time we reference this instance, which may become
+ // moved-from.
+ try
+ {
+ mTarget.lock()->post(mStart, std::move(*this));
+ }
+ catch (const Closed&)
+ {
+ // Once this queue is closed, oh well, just stop
+ }
+ }
+ }
+
+ private:
+ WorkQueue::weak_t mTarget;
+ WorkQueue::TimePoint mStart;
+ std::chrono::duration<Rep, Period> mInterval;
+ CALLABLE mCallable;
+ };
+
+ template <typename Rep, typename Period, typename CALLABLE>
+ void WorkQueue::postEvery(const std::chrono::duration<Rep, Period>& interval,
+ CALLABLE&& callable)
+ {
+ if (interval.count() <= 0)
+ {
+ // It's essential that postEvery() be called with a positive
+ // interval, since each call to BackJack posts another instance of
+ // itself at (start + interval) and we order by target time. A
+ // zero or negative interval would result in that BackJack
+ // instance going to the head of the queue every time, immediately
+ // ready to run. Effectively that would produce an infinite loop,
+ // a denial of service on this WorkQueue.
+ error("postEvery(interval) may not be 0");
+ }
+ // Instantiate and post a suitable BackJack, binding a weak_ptr to
+ // self, the current time, the desired interval and the desired
+ // callable.
+ post(
+ BackJack<Rep, Period, CALLABLE>(
+ getWeak(), TimePoint::clock::now(), interval, std::move(callable)));
+ }
+
+} // namespace LL
+
+#endif /* ! defined(LL_WORKQUEUE_H) */
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 983c7c2406..2bf5f5492e 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -623,8 +623,7 @@ void LLImage::setLastError(const std::string& message)
//---------------------------------------------------------------------------
LLImageBase::LLImageBase()
-: LLTrace::MemTrackable<LLImageBase>("LLImage"),
- mData(NULL),
+: mData(NULL),
mDataSize(0),
mWidth(0),
mHeight(0),
@@ -673,7 +672,6 @@ void LLImageBase::sanityCheck()
void LLImageBase::deleteData()
{
ll_aligned_free_16(mData);
- disclaimMem(mDataSize);
mDataSize = 0;
mData = NULL;
}
@@ -731,7 +729,6 @@ U8* LLImageBase::allocateData(S32 size)
}
}
mDataSize = size;
- claimMem(mDataSize);
return mData;
}
@@ -752,9 +749,7 @@ U8* LLImageBase::reallocateData(S32 size)
ll_aligned_free_16(mData) ;
}
mData = new_datap;
- disclaimMem(mDataSize);
mDataSize = size;
- claimMem(mDataSize);
mBadBufferAllocation = false;
return mData;
}
@@ -2263,9 +2258,7 @@ void LLImageBase::setDataAndSize(U8 *data, S32 size)
{
ll_assert_aligned(data, 16);
mData = data;
- disclaimMem(mDataSize);
mDataSize = size;
- claimMem(mDataSize);
}
//static
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index f66b1666d7..354926ee58 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -112,8 +112,7 @@ protected:
// Image base class
class LLImageBase
-: public LLThreadSafeRefCount,
- public LLTrace::MemTrackable<LLImageBase>
+: public LLThreadSafeRefCount
{
protected:
virtual ~LLImageBase();
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 4bff21610f..e1809dbe59 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -60,7 +60,6 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
mAreaUsedForDataSizeCalcs(0)
{
mImpl.reset(fallbackCreateLLImageJ2CImpl());
- claimMem(mImpl);
// Clear data size table
for( S32 i = 0; i <= MAX_DISCARD_LEVEL; i++)
diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp
index 62638fa16c..32a5472ec8 100644
--- a/indra/llimage/llimagejpeg.cpp
+++ b/indra/llimage/llimagejpeg.cpp
@@ -393,9 +393,7 @@ boolean LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo )
cinfo->dest->next_output_byte = self->mOutputBuffer + self->mOutputBufferSize;
cinfo->dest->free_in_buffer = self->mOutputBufferSize;
- self->disclaimMem(self->mOutputBufferSize);
self->mOutputBufferSize = new_buffer_size;
- self->claimMem(new_buffer_size);
return true;
}
@@ -501,13 +499,10 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
// Allocate a temporary buffer big enough to hold the entire compressed image (and then some)
// (Note: we make it bigger in emptyOutputBuffer() if we need to)
delete[] mOutputBuffer;
- disclaimMem(mOutputBufferSize);
mOutputBufferSize = getWidth() * getHeight() * getComponents() + 1024;
- claimMem(mOutputBufferSize);
mOutputBuffer = new(std::nothrow) U8[ mOutputBufferSize ];
if (mOutputBuffer == NULL)
{
- disclaimMem(mOutputBufferSize);
mOutputBufferSize = 0;
setLastError("Failed to allocate output buffer");
return false;
@@ -547,7 +542,6 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
jpeg_destroy_compress(&cinfo);
delete[] mOutputBuffer;
mOutputBuffer = NULL;
- disclaimMem(mOutputBufferSize);
mOutputBufferSize = 0;
return false;
}
@@ -650,7 +644,6 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
// After finish_compress, we can release the temp output buffer.
delete[] mOutputBuffer;
mOutputBuffer = NULL;
- disclaimMem(mOutputBufferSize);
mOutputBufferSize = 0;
////////////////////////////////////////
@@ -663,7 +656,6 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
jpeg_destroy_compress(&cinfo);
delete[] mOutputBuffer;
mOutputBuffer = NULL;
- disclaimMem(mOutputBufferSize);
mOutputBufferSize = 0;
return false;
}
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 5f42fba866..33f8dce6ee 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -48,6 +48,7 @@ LLImageDecodeThread::~LLImageDecodeThread()
// virtual
S32 LLImageDecodeThread::update(F32 max_time_ms)
{
+ LL_PROFILE_ZONE_SCOPED;
LLMutexLock lock(mCreationMutex);
for (creation_list_t::iterator iter = mCreationList.begin();
iter != mCreationList.end(); ++iter)
@@ -71,6 +72,7 @@ S32 LLImageDecodeThread::update(F32 max_time_ms)
LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
{
+ LL_PROFILE_ZONE_SCOPED;
LLMutexLock lock(mCreationMutex);
handle_t handle = generateHandle();
mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
@@ -118,6 +120,7 @@ LLImageDecodeThread::ImageRequest::~ImageRequest()
// Returns true when done, whether or not decode was successful.
bool LLImageDecodeThread::ImageRequest::processRequest()
{
+ LL_PROFILE_ZONE_SCOPED;
const F32 decode_time_slice = .1f;
bool done = true;
if (!mDecodedRaw && mFormattedImage.notNull())
@@ -164,6 +167,7 @@ bool LLImageDecodeThread::ImageRequest::processRequest()
void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
{
+ LL_PROFILE_ZONE_SCOPED;
if (mResponder.notNull())
{
bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp
index 51c5c63556..9011ac615c 100644
--- a/indra/llimage/tests/llimageworker_test.cpp
+++ b/indra/llimage/tests/llimageworker_test.cpp
@@ -45,8 +45,7 @@
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
LLImageBase::LLImageBase()
-: LLTrace::MemTrackable<LLImageBase>("LLImageBase"),
-mData(NULL),
+: mData(NULL),
mDataSize(0),
mWidth(0),
mHeight(0),
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 18bc1b5a91..81261f0767 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -74,20 +74,17 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid,
const LLUUID& parent_uuid,
LLAssetType::EType type,
const std::string& name)
-: LLTrace::MemTrackable<LLInventoryObject>("LLInventoryObject"),
- mUUID(uuid),
+: mUUID(uuid),
mParentUUID(parent_uuid),
mType(type),
mName(name),
mCreationDate(0)
{
- claimMem(mName);
correctInventoryName(mName);
}
LLInventoryObject::LLInventoryObject()
-: LLTrace::MemTrackable<LLInventoryObject>("LLInventoryObject"),
- mType(LLAssetType::AT_NONE),
+: mType(LLAssetType::AT_NONE),
mCreationDate(0)
{
}
@@ -101,9 +98,7 @@ void LLInventoryObject::copyObject(const LLInventoryObject* other)
mUUID = other->mUUID;
mParentUUID = other->mParentUUID;
mType = other->mType;
- disclaimMem(mName);
mName = other->mName;
- claimMem(mName);
}
const LLUUID& LLInventoryObject::getUUID() const
@@ -156,9 +151,7 @@ void LLInventoryObject::rename(const std::string& n)
correctInventoryName(new_name);
if( !new_name.empty() && new_name != mName )
{
- disclaimMem(mName);
mName = new_name;
- claimMem(mName);
}
}
@@ -311,7 +304,6 @@ LLInventoryItem::LLInventoryItem(const LLUUID& uuid,
LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
LLStringUtil::replaceChar(mDescription, '|', ' ');
- claimMem(mDescription);
mPermissions.initMasks(inv_type);
}
@@ -344,9 +336,7 @@ void LLInventoryItem::copyItem(const LLInventoryItem* other)
copyObject(other);
mPermissions = other->mPermissions;
mAssetUUID = other->mAssetUUID;
- disclaimMem(mDescription);
mDescription = other->mDescription;
- claimMem(mDescription);
mSaleInfo = other->mSaleInfo;
mInventoryType = other->mInventoryType;
mFlags = other->mFlags;
@@ -426,9 +416,7 @@ void LLInventoryItem::setDescription(const std::string& d)
LLInventoryItem::correctInventoryDescription(new_desc);
if( new_desc != mDescription )
{
- disclaimMem(mDescription);
mDescription = new_desc;
- claimMem(mDescription);
}
}
@@ -708,10 +696,8 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
valuestr[0] = '\000';
}
- disclaimMem(mDescription);
mDescription.assign(valuestr);
LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
- claimMem(mDescription);
/* TODO -- ask Ian about this code
const char *donkey = mDescription.c_str();
if (donkey[0] == '|')
@@ -840,11 +826,9 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const
sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate;
}
-LLTrace::BlockTimerStatHandle FTM_INVENTORY_SD_DESERIALIZE("Inventory SD Deserialize");
-
bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
{
- LL_RECORD_BLOCK_TIME(FTM_INVENTORY_SD_DESERIALIZE);
+ LL_PROFILE_ZONE_SCOPED;
if (is_new)
{
// If we're adding LLSD to an existing object, need avoid
@@ -961,10 +945,8 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
w = INV_DESC_LABEL;
if (sd.has(w))
{
- disclaimMem(mDescription);
mDescription = sd[w].asString();
LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
- claimMem(mDescription);
}
w = INV_CREATION_DATE_LABEL;
if (sd.has(w))
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 0f336a072f..7d9f9704f1 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -44,7 +44,7 @@ class LLMessageSystem;
// Base class for anything in the user's inventory. Handles the common code
// between items and categories.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInventoryObject : public LLRefCount, public LLTrace::MemTrackable<LLInventoryObject>
+class LLInventoryObject : public LLRefCount
{
public:
typedef std::list<LLPointer<LLInventoryObject> > object_list_t;
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp
index 8a8e2bb340..aed972b150 100644
--- a/indra/llinventory/llsettingsbase.cpp
+++ b/indra/llinventory/llsettingsbase.cpp
@@ -683,6 +683,7 @@ bool LLSettingsBase::Validator::verifyStringLength(LLSD &value, U32, S32 length)
//=========================================================================
void LLSettingsBlender::update(const LLSettingsBase::BlendFactor& blendf)
{
+ LL_PROFILE_ZONE_SCOPED;
F64 res = setBlendFactor(blendf);
llassert(res >= 0.0 && res <= 1.0);
(void)res;
@@ -713,6 +714,7 @@ F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_
void LLSettingsBlender::triggerComplete()
{
+ LL_PROFILE_ZONE_SCOPED;
if (mTarget)
mTarget->replaceSettings(mFinal->getSettings());
LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon
@@ -725,11 +727,13 @@ const LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::MIN_BLEND_DELTA(FL
LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const
{
+ LL_PROFILE_ZONE_SCOPED;
return LLSettingsBase::BlendFactor(fmod((F64)spanpos, (F64)spanlen) / (F64)spanlen);
}
bool LLSettingsBlenderTimeDelta::applyTimeDelta(const LLSettingsBase::Seconds& timedelta)
{
+ LL_PROFILE_ZONE_SCOPED;
mTimeSpent += timedelta;
if (mTimeSpent > mBlendSpan)
diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp
index 2bb03e8391..241826604f 100644
--- a/indra/llinventory/llsettingsdaycycle.cpp
+++ b/indra/llinventory/llsettingsdaycycle.cpp
@@ -41,9 +41,6 @@
//=========================================================================
namespace
{
- LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment Day");
- LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment Day");
-
template<typename T>
inline T get_wrapping_distance(T begin, T end)
{
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 1470edbf38..979a284744 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -66,11 +66,6 @@ namespace {
}
}
-static LLTrace::BlockTimerStatHandle FTM_BLEND_SKYVALUES("Blending Sky Environment");
-static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_SKYVALUES("Recalculate Sky");
-static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_BODIES("Recalculate Heavenly Bodies");
-static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_LIGHTING("Recalculate Lighting");
-
//=========================================================================
const std::string LLSettingsSky::SETTING_AMBIENT("ambient");
const std::string LLSettingsSky::SETTING_BLUE_DENSITY("blue_density");
@@ -444,6 +439,7 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother)
void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(getSettingsType() == end->getSettingsType());
LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast<LLSettingsSky>(end);
@@ -939,7 +935,7 @@ LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy)
void LLSettingsSky::updateSettings()
{
- LL_RECORD_BLOCK_TIME(FTM_RECALCULATE_SKYVALUES);
+ LL_PROFILE_ZONE_SCOPED;
// base class clears dirty flag so as to not trigger recursive update
LLSettingsBase::updateSettings();
@@ -1022,6 +1018,7 @@ LLColor3 LLSettingsSky::getLightDiffuse() const
LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default_value) const
{
+ LL_PROFILE_ZONE_SCOPED;
if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key))
{
return LLColor3(mSettings[SETTING_LEGACY_HAZE][key]);
@@ -1035,6 +1032,7 @@ LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default
F32 LLSettingsSky::getFloat(const std::string& key, F32 default_value) const
{
+ LL_PROFILE_ZONE_SCOPED;
if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key))
{
return mSettings[SETTING_LEGACY_HAZE][key].asReal();
@@ -1206,11 +1204,19 @@ LLColor3 LLSettingsSky::getLightTransmittance(F32 distance) const
return transmittance;
}
+// SL-16127: getTotalDensity() and getDensityMultiplier() call LLSettingsSky::getColor() and LLSettingsSky::getFloat() respectively which are S-L-O-W
+LLColor3 LLSettingsSky::getLightTransmittanceFast( const LLColor3& total_density, const F32 density_multiplier, const F32 distance ) const
+{
+ // Transparency (-> density) from Beer's law
+ LLColor3 transmittance = componentExp(total_density * -(density_multiplier * distance));
+ return transmittance;
+}
+
// performs soft scale clip and gamma correction ala the shader implementation
// scales colors down to 0 - 1 range preserving relative ratios
-LLColor3 LLSettingsSky::gammaCorrect(const LLColor3& in) const
+LLColor3 LLSettingsSky::gammaCorrect(const LLColor3& in,const F32 &gamma) const
{
- F32 gamma = getGamma();
+ //F32 gamma = getGamma(); // SL-16127: Use cached gamma from atmospheric vars
LLColor3 v(in);
// scale down to 0 to 1 range preserving relative ratio (aka homegenize)
diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h
index 4127911643..fa9326f006 100644
--- a/indra/llinventory/llsettingssky.h
+++ b/indra/llinventory/llsettingssky.h
@@ -252,8 +252,9 @@ public:
LLColor3 getLightAttenuation(F32 distance) const;
LLColor3 getLightTransmittance(F32 distance) const;
+ LLColor3 getLightTransmittanceFast(const LLColor3& total_density, const F32 density_multiplier, const F32 distance) const;
LLColor3 getTotalDensity() const;
- LLColor3 gammaCorrect(const LLColor3& in) const;
+ LLColor3 gammaCorrect(const LLColor3& in,const F32 &gamma) const;
LLColor3 getBlueDensity() const;
LLColor3 getBlueHorizon() const;
diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp
index 1ae8d78b22..90f99e8198 100644
--- a/indra/llinventory/llsettingswater.cpp
+++ b/indra/llinventory/llsettingswater.cpp
@@ -33,14 +33,6 @@
#include "v3colorutil.h"
#include "indra_constants.h"
-//=========================================================================
-namespace
-{
- LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment");
- LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment");
-}
-
-//=========================================================================
const std::string LLSettingsWater::SETTING_BLUR_MULTIPLIER("blur_multiplier");
const std::string LLSettingsWater::SETTING_FOG_COLOR("water_fog_color");
const std::string LLSettingsWater::SETTING_FOG_DENSITY("water_fog_density");
diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp
index ee7b14be85..16213b7f45 100644
--- a/indra/llkdu/tests/llimagej2ckdu_test.cpp
+++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp
@@ -63,8 +63,7 @@ U8* LLImageRaw::reallocateData(S32 ) { return NULL; }
bool LLImageRaw::resize(U16, U16, S8) { return true; } // this method always returns true...
LLImageBase::LLImageBase()
-: LLTrace::MemTrackable<LLImageBase>("LLImageBase"),
-mData(NULL),
+: mData(NULL),
mDataSize(0),
mWidth(0),
mHeight(0),
diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h
index 7ba347062f..5291a05607 100644
--- a/indra/llmath/llmatrix4a.h
+++ b/indra/llmath/llmatrix4a.h
@@ -36,6 +36,26 @@ class LLMatrix4a
public:
LL_ALIGN_16(LLVector4a mMatrix[4]);
+ LLMatrix4a()
+ {
+
+ }
+
+ explicit LLMatrix4a(const LLMatrix4& val)
+ {
+ loadu(val);
+ }
+
+ inline F32* getF32ptr()
+ {
+ return (F32*) &mMatrix;
+ }
+
+ inline const F32* getF32ptr() const
+ {
+ return (F32*)&mMatrix;
+ }
+
inline void clear()
{
mMatrix[0].clear();
@@ -44,6 +64,14 @@ public:
mMatrix[3].clear();
}
+ inline void setIdentity()
+ {
+ mMatrix[0].set(1.f, 0.f, 0.f, 0.f);
+ mMatrix[1].set(0.f, 1.f, 0.f, 0.f);
+ mMatrix[2].set(0.f, 0.f, 1.f, 0.f);
+ mMatrix[3].set(0.f, 0.f, 0.f, 1.f);
+ }
+
inline void loadu(const LLMatrix4& src)
{
mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]);
@@ -105,7 +133,7 @@ public:
mMatrix[3].setAdd(a.mMatrix[3],d3);
}
- inline void rotate(const LLVector4a& v, LLVector4a& res)
+ inline void rotate(const LLVector4a& v, LLVector4a& res) const
{
LLVector4a y,z;
@@ -151,6 +179,8 @@ public:
{
affineTransformSSE(v,res);
}
+
+ const LLVector4a& getTranslation() const { return mMatrix[3]; }
};
inline LLVector4a rowMul(const LLVector4a &row, const LLMatrix4a &mat)
@@ -176,6 +206,15 @@ inline void matMul(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res)
res.mMatrix[3] = row3;
}
+//Faster version of matMul wehere res must not be a or b
+inline void matMulUnsafe(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res)
+{
+ res.mMatrix[0] = rowMul(a.mMatrix[0], b);
+ res.mMatrix[1] = rowMul(a.mMatrix[1], b);
+ res.mMatrix[2] = rowMul(a.mMatrix[2], b);
+ res.mMatrix[3] = rowMul(a.mMatrix[3], b);
+}
+
inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m)
{
s << "[" << m.mMatrix[0] << ", " << m.mMatrix[1] << ", " << m.mMatrix[2] << ", " << m.mMatrix[3] << "]";
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index 0e2f62f9db..8c4a1304b4 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -74,8 +74,9 @@ public:
};
template <class T>
-class LLOctreeNode : public LLTreeNode<T>
+class alignas(16) LLOctreeNode : public LLTreeNode<T>
{
+ LL_ALIGN_NEW
public:
typedef LLOctreeTraveler<T> oct_traveler;
@@ -91,16 +92,6 @@ public:
typedef LLOctreeNode<T> oct_node;
typedef LLOctreeListener<T> oct_listener;
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
LLOctreeNode( const LLVector4a& center,
const LLVector4a& size,
BaseType* parent,
diff --git a/indra/llmath/llrigginginfo.h b/indra/llmath/llrigginginfo.h
index b3d6bc2d19..059c6ae082 100644
--- a/indra/llmath/llrigginginfo.h
+++ b/indra/llmath/llrigginginfo.h
@@ -34,9 +34,9 @@
// Extents are in joint space
// isRiggedTo is based on the state of all currently associated rigged meshes
-LL_ALIGN_PREFIX(16)
-class LLJointRiggingInfo
+class alignas(16) LLJointRiggingInfo
{
+ LL_ALIGN_NEW
public:
LLJointRiggingInfo();
bool isRiggedTo() const;
@@ -45,31 +45,10 @@ public:
const LLVector4a *getRiggedExtents() const;
void merge(const LLJointRiggingInfo& other);
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
- void* operator new[](size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete[](void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
-
private:
- LL_ALIGN_16(LLVector4a mRiggedExtents[2]);
+ LLVector4a mRiggedExtents[2];
bool mIsRiggedTo;
-} LL_ALIGN_POSTFIX(16);
+};
// For storing all the rigging info associated with a given avatar or
// object, keyed by joint_num.
diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h
index 27abf39537..53c8f604f6 100644
--- a/indra/llmath/llvector4a.h
+++ b/indra/llmath/llvector4a.h
@@ -46,11 +46,10 @@ class LLRotation;
// of this writing, July 08, 2010) about getting it implemented before you resort to
// LLVector3/LLVector4.
/////////////////////////////////
-struct LLVector4a;
-LL_ALIGN_PREFIX(16)
-struct LLVector4a
+class alignas(16) LLVector4a
{
+ LL_ALIGN_NEW
public:
///////////////////////////////////
@@ -138,10 +137,10 @@ public:
// BASIC GET/SET
////////////////////////////////////
- // Return a "this" as an F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon)
+ // Return a "this" as an F32 pointer.
inline F32* getF32ptr();
- // Return a "this" as a const F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon)
+ // Return a "this" as a const F32 pointer.
inline const F32* const getF32ptr() const;
// Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates
@@ -324,7 +323,7 @@ public:
private:
LLQuad mQ;
-} LL_ALIGN_POSTFIX(16);
+};
inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p)
{
diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl
index 69d3d01efe..8be1c1b114 100644
--- a/indra/llmath/llvector4a.inl
+++ b/indra/llmath/llvector4a.inl
@@ -58,13 +58,13 @@ inline void LLVector4a::store4a(F32* dst) const
// BASIC GET/SET
////////////////////////////////////
-// Return a "this" as an F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon)
+// Return a "this" as an F32 pointer.
F32* LLVector4a::getF32ptr()
{
return (F32*) &mQ;
}
-// Return a "this" as a const F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon)
+// Return a "this" as a const F32 pointer.
const F32* const LLVector4a::getF32ptr() const
{
return (const F32* const) &mQ;
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index e085fa6ada..130f30bedc 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -383,6 +383,7 @@ public:
virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
{ //this is a depth first traversal, so it's safe to assum all children have complete
//bounding data
+ LL_PROFILE_ZONE_SCOPED
LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0);
@@ -822,6 +823,8 @@ S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 de
BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split,
BOOL is_sculpted, S32 sculpt_size)
{
+ LL_PROFILE_ZONE_SCOPED
+
if ((!mDirty) && (!is_sculpted))
{
return FALSE;
@@ -1302,6 +1305,8 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff
void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
{
+ LL_PROFILE_ZONE_SCOPED
+
// Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane.
static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
@@ -1536,6 +1541,8 @@ S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail)
BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
BOOL is_sculpted, S32 sculpt_size)
{
+ LL_PROFILE_ZONE_SCOPED
+
if ((!mDirty) && (!is_sculpted))
{
return FALSE;
@@ -2112,6 +2119,8 @@ LLVolume::~LLVolume()
BOOL LLVolume::generate()
{
+ LL_PROFILE_ZONE_SCOPED
+
LL_CHECK_MEMORY
llassert_always(mProfilep);
@@ -2370,6 +2379,8 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs
bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
{
+ LL_PROFILE_ZONE_SCOPED
+
//input stream is now pointing at a zlib compressed block of LLSD
//decompress block
LLSD mdl;
@@ -2755,6 +2766,8 @@ S32 LLVolume::getNumFaces() const
void LLVolume::createVolumeFaces()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (mGenerateSingleFace)
{
// do nothing
@@ -3720,6 +3733,8 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
const LLMatrix3& norm_mat_in,
S32 face_mask)
{
+ LL_PROFILE_ZONE_SCOPED
+
LLMatrix4a mat;
mat.loadu(mat_in);
@@ -4846,6 +4861,8 @@ void LLVolumeFace::freeData()
BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
{
+ LL_PROFILE_ZONE_SCOPED
+
//tree for this face is no longer valid
delete mOctree;
mOctree = NULL;
@@ -5514,6 +5531,8 @@ bool LLVolumeFace::cacheOptimize()
void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (mOctree)
{
return;
@@ -6287,6 +6306,8 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
void LLVolumeFace::createTangents()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!mTangents)
{
allocateTangents(mNumVertices);
@@ -6482,6 +6503,8 @@ void LLVolumeFace::fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v,
BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
{
+ LL_PROFILE_ZONE_SCOPED
+
LL_CHECK_MEMORY
BOOL flat = mTypeMask & FLAT_MASK;
@@ -6974,6 +6997,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)
{
+ LL_PROFILE_ZONE_SCOPED
+
//LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
// new(tan1) LLVector4a;
diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h
index 13150028d8..b2bc440368 100644
--- a/indra/llmath/llvolumeoctree.h
+++ b/indra/llmath/llvolumeoctree.h
@@ -34,19 +34,10 @@
#include "llvolume.h"
#include "llvector4a.h"
-class LLVolumeTriangle : public LLRefCount
+class alignas(16) LLVolumeTriangle : public LLRefCount
{
+ LL_ALIGN_NEW
public:
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
LLVolumeTriangle()
{
mBinIndex = -1;
@@ -86,20 +77,10 @@ public:
};
-class LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
+class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
{
+ LL_ALIGN_NEW
public:
-
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node);
~LLVolumeOctreeListener();
diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp
index 3baf1bad18..6e40dae30b 100644
--- a/indra/llmath/m4math.cpp
+++ b/indra/llmath/m4math.cpp
@@ -32,8 +32,7 @@
#include "m4math.h"
#include "m3math.h"
#include "llquaternion.h"
-
-
+#include "llmatrix4a.h"
// LLMatrix4
@@ -115,6 +114,12 @@ LLMatrix4::LLMatrix4(const LLQuaternion &q)
*this = initRotation(q);
}
+LLMatrix4::LLMatrix4(const LLMatrix4a& mat)
+ : LLMatrix4(mat.getF32ptr())
+{
+
+}
+
LLMatrix4::LLMatrix4(const LLQuaternion &q, const LLVector4 &pos)
{
*this = initRotTrans(q, pos);
diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h
index bf60adb9b6..b9da970cde 100644
--- a/indra/llmath/m4math.h
+++ b/indra/llmath/m4math.h
@@ -32,6 +32,7 @@
class LLVector4;
class LLMatrix3;
class LLQuaternion;
+class LLMatrix4a;
// NOTA BENE: Currently assuming a right-handed, x-forward, y-left, z-up universe
@@ -104,6 +105,7 @@ public:
explicit LLMatrix4(const F32 *mat); // Initializes Matrix to values in mat
explicit LLMatrix4(const LLMatrix3 &mat); // Initializes Matrix to values in mat and sets position to (0,0,0)
explicit LLMatrix4(const LLQuaternion &q); // Initializes Matrix with rotation q and sets position to (0,0,0)
+ explicit LLMatrix4(const LLMatrix4a& mat);
LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos); // Initializes Matrix to values in mat and pos
diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp
index b04c67d926..93010d2250 100644
--- a/indra/llmath/v3math.cpp
+++ b/indra/llmath/v3math.cpp
@@ -316,6 +316,12 @@ LLVector3::LLVector3(const LLVector4 &vec)
mV[VZ] = (F32)vec.mV[VZ];
}
+LLVector3::LLVector3(const LLVector4a& vec)
+ : LLVector3(vec.getF32ptr())
+{
+
+}
+
LLVector3::LLVector3(const LLSD& sd)
{
setValue(sd);
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index 6f857d7061..068f489020 100644
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -33,6 +33,7 @@
#include "llsd.h"
class LLVector2;
class LLVector4;
+class LLVector4a;
class LLMatrix3;
class LLMatrix4;
class LLVector3d;
@@ -62,7 +63,9 @@ class LLVector3
explicit LLVector3(const LLVector2 &vec); // Initializes LLVector3 to (vec[0]. vec[1], 0)
explicit LLVector3(const LLVector3d &vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2])
explicit LLVector3(const LLVector4 &vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2])
- explicit LLVector3(const LLSD& sd);
+ explicit LLVector3(const LLVector4a& vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2])
+ explicit LLVector3(const LLSD& sd);
+
LLSD getValue() const;
diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp
index d3e195789b..0abdafbdfc 100644
--- a/indra/llmessage/llfiltersd2xmlrpc.cpp
+++ b/indra/llmessage/llfiltersd2xmlrpc.cpp
@@ -309,7 +309,6 @@ LLFilterSD2XMLRPCResponse::~LLFilterSD2XMLRPCResponse()
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_SD2XMLRPC_RESPONSE("SD2XMLRPC Response");
// virtual
LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl(
const LLChannelDescriptors& channels,
@@ -318,7 +317,7 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_SD2XMLRPC_RESPONSE);
+ LL_PROFILE_ZONE_SCOPED;
PUMP_DEBUG;
// This pipe does not work if it does not have everyting. This
@@ -386,8 +385,6 @@ LLFilterSD2XMLRPCRequest::~LLFilterSD2XMLRPCRequest()
{
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_SD2XMLRPC_REQUEST("S22XMLRPC Request");
-
// virtual
LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl(
const LLChannelDescriptors& channels,
@@ -396,7 +393,7 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_SD2XMLRPC_REQUEST);
+ LL_PROFILE_ZONE_SCOPED;
// This pipe does not work if it does not have everyting. This
// could be addressed by making a stream parser for llsd which
// handled partial information.
@@ -593,8 +590,6 @@ LLFilterXMLRPCResponse2LLSD::~LLFilterXMLRPCResponse2LLSD()
{
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_XMLRPC2LLSD_RESPONSE("XMLRPC2LLSD Response");
-
LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
@@ -602,7 +597,7 @@ LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_XMLRPC2LLSD_RESPONSE);
+ LL_PROFILE_ZONE_SCOPED;
PUMP_DEBUG;
if(!eos) return STATUS_BREAK;
@@ -679,7 +674,6 @@ LLFilterXMLRPCRequest2LLSD::~LLFilterXMLRPCRequest2LLSD()
{
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_XMLRPC2LLSD_REQUEST("XMLRPC2LLSD Request");
LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
@@ -687,7 +681,7 @@ LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_XMLRPC2LLSD_REQUEST);
+ LL_PROFILE_ZONE_SCOPED;
PUMP_DEBUG;
if(!eos) return STATUS_BREAK;
if(!buffer) return STATUS_ERROR;
diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp
index 6fd17c9154..6e9598a0a3 100644
--- a/indra/llmessage/llhttpnode.cpp
+++ b/indra/llmessage/llhttpnode.cpp
@@ -121,6 +121,7 @@ LLSD LLHTTPNode::simplePost(const LLSD& input) const
// virtual
void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) const
{
+ LL_PROFILE_ZONE_SCOPED;
try
{
response->result(simpleGet());
@@ -134,6 +135,7 @@ void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) cons
// virtual
void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, const LLSD& input) const
{
+ LL_PROFILE_ZONE_SCOPED;
try
{
response->result(simplePut(input));
@@ -147,6 +149,7 @@ void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, cons
// virtual
void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, const LLSD& input) const
{
+ LL_PROFILE_ZONE_SCOPED;
try
{
response->result(simplePost(input));
@@ -160,6 +163,7 @@ void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, con
// virtual
void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) const
{
+ LL_PROFILE_ZONE_SCOPED;
try
{
response->result(simpleDel(context));
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index d9042fa8b0..c707c7ad09 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -132,12 +132,6 @@ private:
LLSD mHeaders;
};
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_PIPE("HTTP Pipe");
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_GET("HTTP Get");
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_PUT("HTTP Put");
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_POST("HTTP Post");
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_DELETE("HTTP Delete");
-
LLIOPipe::EStatus LLHTTPPipe::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
@@ -145,7 +139,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_PIPE);
+ LL_PROFILE_ZONE_SCOPED;
PUMP_DEBUG;
LL_DEBUGS() << "LLSDHTTPServer::process_impl" << LL_ENDL;
@@ -174,12 +168,10 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB];
if(verb == HTTP_VERB_GET)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_GET);
mNode.get(LLHTTPNode::ResponsePtr(mResponse), context);
}
else if(verb == HTTP_VERB_PUT)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_PUT);
LLSD input;
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
{
@@ -195,7 +187,6 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
}
else if(verb == HTTP_VERB_POST)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_POST);
LLSD input;
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
{
@@ -211,7 +202,6 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
}
else if(verb == HTTP_VERB_DELETE)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_DELETE);
mNode.del(LLHTTPNode::ResponsePtr(mResponse), context);
}
else if(verb == HTTP_VERB_OPTIONS)
@@ -455,8 +445,6 @@ protected:
* LLHTTPResponseHeader
*/
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_HEADER("HTTP Header");
-
// virtual
LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
const LLChannelDescriptors& channels,
@@ -465,7 +453,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_HEADER);
+ LL_PROFILE_ZONE_SCOPED;
PUMP_DEBUG;
if(eos)
{
@@ -655,8 +643,6 @@ void LLHTTPResponder::markBad(
<< "</body>\n</html>\n";
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_RESPONDER("HTTP Responder");
-
// virtual
LLIOPipe::EStatus LLHTTPResponder::process_impl(
const LLChannelDescriptors& channels,
@@ -665,7 +651,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_RESPONDER);
+ LL_PROFILE_ZONE_SCOPED;
PUMP_DEBUG;
LLIOPipe::EStatus status = STATUS_OK;
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index a9cc71c365..321d7286eb 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -300,8 +300,6 @@ LLIOSocketReader::~LLIOSocketReader()
//LL_DEBUGS() << "Destroying LLIOSocketReader" << LL_ENDL;
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_SOCKET_READER("Socket Reader");
-
// virtual
LLIOPipe::EStatus LLIOSocketReader::process_impl(
const LLChannelDescriptors& channels,
@@ -310,7 +308,7 @@ LLIOPipe::EStatus LLIOSocketReader::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_SOCKET_READER);
+ LL_PROFILE_ZONE_SCOPED;
PUMP_DEBUG;
if(!mSource) return STATUS_PRECONDITION_NOT_MET;
if(!mInitialized)
@@ -400,7 +398,6 @@ LLIOSocketWriter::~LLIOSocketWriter()
//LL_DEBUGS() << "Destroying LLIOSocketWriter" << LL_ENDL;
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_SOCKET_WRITER("Socket Writer");
// virtual
LLIOPipe::EStatus LLIOSocketWriter::process_impl(
const LLChannelDescriptors& channels,
@@ -409,7 +406,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_SOCKET_WRITER);
+ LL_PROFILE_ZONE_SCOPED;
PUMP_DEBUG;
if(!mDestination) return STATUS_PRECONDITION_NOT_MET;
if(!mInitialized)
@@ -556,7 +553,6 @@ void LLIOServerSocket::setResponseTimeout(F32 timeout_secs)
mResponseTimeout = timeout_secs;
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_SERVER_SOCKET("Server Socket");
// virtual
LLIOPipe::EStatus LLIOServerSocket::process_impl(
const LLChannelDescriptors& channels,
@@ -565,7 +561,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_SERVER_SOCKET);
+ LL_PROFILE_ZONE_SCOPED;
PUMP_DEBUG;
if(!pump)
{
diff --git a/indra/llmessage/llioutil.cpp b/indra/llmessage/llioutil.cpp
index b8443c0600..850bc2a616 100644
--- a/indra/llmessage/llioutil.cpp
+++ b/indra/llmessage/llioutil.cpp
@@ -45,7 +45,6 @@ LLIOPipe::EStatus LLIOFlush::process_impl(
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_SLEEP("IO Sleep");
/**
* @class LLIOSleep
*/
@@ -56,7 +55,7 @@ LLIOPipe::EStatus LLIOSleep::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_SLEEP);
+ LL_PROFILE_ZONE_SCOPED;
if(mSeconds > 0.0)
{
if(pump) pump->sleepChain(mSeconds);
@@ -66,7 +65,6 @@ LLIOPipe::EStatus LLIOSleep::process_impl(
return STATUS_DONE;
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_ADD_CHAIN("Add Chain");
/**
* @class LLIOAddChain
*/
@@ -77,7 +75,7 @@ LLIOPipe::EStatus LLIOAddChain::process_impl(
LLSD& context,
LLPumpIO* pump)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_ADD_CHAIN);
+ LL_PROFILE_ZONE_SCOPED;
pump->addChain(mChain, mTimeout);
return STATUS_DONE;
}
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index a2524e9804..35365665f6 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -416,9 +416,6 @@ void LLPumpIO::pump()
pump(DEFAULT_POLL_TIMEOUT);
}
-static LLTrace::BlockTimerStatHandle FTM_PUMP_IO("Pump IO");
-static LLTrace::BlockTimerStatHandle FTM_PUMP_POLL("Pump Poll");
-
LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain)
{
std::for_each(
@@ -431,7 +428,7 @@ LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t
//timeout is in microseconds
void LLPumpIO::pump(const S32& poll_timeout)
{
- LL_RECORD_BLOCK_TIME(FTM_PUMP_IO);
+ LL_PROFILE_ZONE_SCOPED;
//LL_INFOS() << "LLPumpIO::pump()" << LL_ENDL;
// Run any pending runners.
@@ -509,7 +506,7 @@ void LLPumpIO::pump(const S32& poll_timeout)
S32 count = 0;
S32 client_id = 0;
{
- LL_RECORD_BLOCK_TIME(FTM_PUMP_POLL);
+ LL_PROFILE_ZONE_SCOPED;
apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd);
}
PUMP_DEBUG;
@@ -737,10 +734,9 @@ bool LLPumpIO::respond(
return true;
}
-static LLTrace::BlockTimerStatHandle FTM_PUMP_CALLBACK_CHAIN("Chain");
-
void LLPumpIO::callback()
{
+ LL_PROFILE_ZONE_SCOPED;
//LL_INFOS() << "LLPumpIO::callback()" << LL_ENDL;
if(true)
{
@@ -756,7 +752,6 @@ void LLPumpIO::callback()
callbacks_t::iterator end = mCallbacks.end();
for(; it != end; ++it)
{
- LL_RECORD_BLOCK_TIME(FTM_PUMP_CALLBACK_CHAIN);
// it's always the first and last time for respone chains
(*it).mHead = (*it).mChainLinks.begin();
(*it).mInit = true;
diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp
index 6d5ad0ba08..32f79f0546 100644
--- a/indra/llmessage/lltemplatemessagereader.cpp
+++ b/indra/llmessage/lltemplatemessagereader.cpp
@@ -533,6 +533,8 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_MESSAGES("Process Messages");
// decode a given message
BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender )
{
+ LL_RECORD_BLOCK_TIME(FTM_PROCESS_MESSAGES);
+
llassert( mReceiveSize >= 0 );
llassert( mCurrentRMessageTemplate);
llassert( !mCurrentRMessageData );
@@ -707,12 +709,9 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender
decode_timer.reset();
}
+ if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) )
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_MESSAGES);
- if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) )
- {
- LL_WARNS() << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << LL_ENDL;
- }
+ LL_WARNS() << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << LL_ENDL;
}
if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index dfa29fb539..8343de0cbc 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -1173,17 +1173,19 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
LLMeshSkinInfo& skin_info = model->mSkinInfo;
+ LLMatrix4 mat;
for (int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
- skin_info.mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4];
+ mat.mMatrix[i][j] = dom_value[i + j*4];
}
}
- LLMatrix4 trans = normalized_transformation;
- trans *= skin_info.mBindShapeMatrix;
- skin_info.mBindShapeMatrix = trans;
+ skin_info.mBindShapeMatrix.loadu(mat);
+
+ LLMatrix4a trans(normalized_transformation);
+ matMul(trans, skin_info.mBindShapeMatrix, skin_info.mBindShapeMatrix);
}
@@ -1401,7 +1403,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
mat.mMatrix[i][j] = transform[k*16 + i + j*4];
}
}
- model->mSkinInfo.mInvBindMatrix.push_back(mat);
+ model->mSkinInfo.mInvBindMatrix.push_back(LLMatrix4a(mat));
}
}
}
@@ -1475,9 +1477,9 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
if (mJointMap.find(lookingForJoint) != mJointMap.end()
&& model->mSkinInfo.mInvBindMatrix.size() > i)
{
- LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i];
+ LLMatrix4 newInverse = LLMatrix4(model->mSkinInfo.mInvBindMatrix[i].getF32ptr());
newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() );
- model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse );
+ model->mSkinInfo.mAlternateBindMatrix.push_back( LLMatrix4a(newInverse) );
}
else
{
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 702a1b5238..a23b991f1d 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1396,7 +1396,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
}
}
- mInvBindMatrix.push_back(mat);
+ mInvBindMatrix.push_back(LLMatrix4a(mat));
}
if (mJointNames.size() != mInvBindMatrix.size())
@@ -1410,13 +1410,15 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
if (skin.has("bind_shape_matrix"))
{
+ LLMatrix4 mat;
for (U32 j = 0; j < 4; j++)
{
for (U32 k = 0; k < 4; k++)
{
- mBindShapeMatrix.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal();
+ mat.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal();
}
}
+ mBindShapeMatrix.loadu(mat);
}
if (skin.has("alt_inverse_bind_matrix"))
@@ -1432,7 +1434,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
}
}
- mAlternateBindMatrix.push_back(mat);
+ mAlternateBindMatrix.push_back(LLMatrix4a(mat));
}
}
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 51fa2f8079..cd2b6c6728 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -33,13 +33,17 @@
#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
{
+ LL_ALIGN_NEW
public:
LLMeshSkinInfo();
LLMeshSkinInfo(LLSD& data);
@@ -49,18 +53,21 @@ public:
LLUUID mMeshID;
std::vector<std::string> mJointNames;
mutable std::vector<S32> mJointNums;
- std::vector<LLMatrix4> mInvBindMatrix;
- std::vector<LLMatrix4> mAlternateBindMatrix;
+ typedef std::vector<LLMatrix4a, boost::alignment::aligned_allocator<LLMatrix4a, 16>> matrix_list_t;
+ matrix_list_t mInvBindMatrix;
+ matrix_list_t mAlternateBindMatrix;
- LLMatrix4 mBindShapeMatrix;
+ LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);
float mPelvisOffset;
bool mLockScaleIfJointPosition;
bool mInvalidJointsScrubbed;
bool mJointNumsInitialized;
-};
+} LL_ALIGN_POSTFIX(16);
+LL_ALIGN_PREFIX(16)
class LLModel : public LLVolume
{
+ LL_ALIGN_NEW
public:
enum
@@ -282,7 +289,7 @@ public:
EModelStatus mStatus ;
int mSubmodelID;
-};
+} LL_ALIGN_POSTFIX(16);
typedef std::vector<LLPointer<LLModel> > model_list;
typedef std::queue<LLPointer<LLModel> > model_queue;
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 5947bca670..d7f7b2f58e 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -150,6 +150,7 @@ void LLCubeMap::initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages
void LLCubeMap::initGLData()
{
+ LL_PROFILE_ZONE_SCOPED;
for (int i = 0; i < 6; i++)
{
mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION);
@@ -453,6 +454,7 @@ BOOL LLCubeMap::project(F32& v_min, F32& v_max, F32& h_min, F32& h_max,
void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col)
{
+ LL_PROFILE_ZONE_SCOPED;
F32 v_min, v_max, h_min, h_max;
LLVector3 center = dir[0] + dir[1] + dir[2] + dir[3];
center.normVec();
diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp
index f128636ab2..c71e24c83a 100644
--- a/indra/llrender/llfontbitmapcache.cpp
+++ b/indra/llrender/llfontbitmapcache.cpp
@@ -30,8 +30,7 @@
#include "llfontbitmapcache.h"
LLFontBitmapCache::LLFontBitmapCache()
-: LLTrace::MemTrackable<LLFontBitmapCache>("LLFontBitmapCache"),
- mNumComponents(0),
+: mNumComponents(0),
mBitmapWidth(0),
mBitmapHeight(0),
mBitmapNum(-1),
@@ -124,9 +123,6 @@ BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32 &pos_x, S32 &pos_y, S32& bitm
image_gl->createGLTexture(0, image_raw);
gGL.getTexUnit(0)->bind(image_gl);
image_gl->setFilteringOption(LLTexUnit::TFO_POINT); // was setMipFilterNearest(TRUE, TRUE);
-
- claimMem(image_raw);
- claimMem(image_gl);
}
else
{
@@ -156,20 +152,8 @@ void LLFontBitmapCache::destroyGL()
void LLFontBitmapCache::reset()
{
- for (std::vector<LLPointer<LLImageRaw> >::iterator it = mImageRawVec.begin(), end_it = mImageRawVec.end();
- it != end_it;
- ++it)
- {
- disclaimMem(**it);
- }
mImageRawVec.clear();
- for (std::vector<LLPointer<LLImageGL> >::iterator it = mImageGLVec.begin(), end_it = mImageGLVec.end();
- it != end_it;
- ++it)
- {
- disclaimMem(**it);
- }
mImageGLVec.clear();
mBitmapWidth = 0;
diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h
index 75df3a94a7..7de3a6b56f 100644
--- a/indra/llrender/llfontbitmapcache.h
+++ b/indra/llrender/llfontbitmapcache.h
@@ -32,7 +32,7 @@
// Maintain a collection of bitmaps containing rendered glyphs.
// Generalizes the single-bitmap logic from LLFontFreetype and LLFontGL.
-class LLFontBitmapCache : public LLTrace::MemTrackable<LLFontBitmapCache>
+class LLFontBitmapCache
{
public:
LLFontBitmapCache();
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index c41730ebaa..e964d1586f 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -104,8 +104,7 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
}
LLFontFreetype::LLFontFreetype()
-: LLTrace::MemTrackable<LLFontFreetype>("LLFontFreetype"),
- mFontBitmapCachep(new LLFontBitmapCache),
+: mFontBitmapCachep(new LLFontBitmapCache),
mAscender(0.f),
mDescender(0.f),
mLineHeight(0.f),
@@ -222,8 +221,6 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
S32 max_char_height = ll_round(0.5f + (y_max - y_min));
mFontBitmapCachep->init(components, max_char_width, max_char_height);
- claimMem(mFontBitmapCachep);
-
if (!mFTFace->charmap)
{
@@ -238,7 +235,6 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
}
mName = filename;
- claimMem(mName);
mPointSize = point_size;
mStyle = LLFontGL::NORMAL;
@@ -460,6 +456,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch) const
LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const
{
+ LL_PROFILE_ZONE_SCOPED;
if (mFTFace == NULL)
return NULL;
@@ -585,7 +582,6 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
}
else
{
- claimMem(gi);
mCharGlyphInfoMap[wch] = gi;
}
}
@@ -631,11 +627,9 @@ void LLFontFreetype::resetBitmapCache()
it != end_it;
++it)
{
- disclaimMem(it->second);
delete it->second;
}
mCharGlyphInfoMap.clear();
- disclaimMem(mFontBitmapCachep);
mFontBitmapCachep->reset();
// Adding default glyph is skipped for fallback fonts here as well as in loadFace().
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index 1afe84e770..f61f169987 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -76,7 +76,7 @@ struct LLFontGlyphInfo
extern LLFontManager *gFontManagerp;
-class LLFontFreetype : public LLRefCount, public LLTrace::MemTrackable<LLFontFreetype>
+class LLFontFreetype : public LLRefCount
{
public:
LLFontFreetype();
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 86a4c35e6d..7f734e41f3 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -109,8 +109,6 @@ S32 LLFontGL::getNumFaces(const std::string& filename)
return mFontFreetype->getNumFaces(filename);
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts");
-
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses) const
{
@@ -147,7 +145,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rec
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_FONTS);
+ LL_PROFILE_ZONE_SCOPED;
if(!sDisplayFont) //do not display texts
{
@@ -547,9 +545,19 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
return cur_x / sScaleX;
}
+void LLFontGL::generateASCIIglyphs()
+{
+ LL_PROFILE_ZONE_SCOPED
+ for (U32 i = 32; (i < 127); i++)
+ {
+ mFontFreetype->getGlyphInfo(i);
+ }
+}
+
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, EWordWrapStyle end_on_word_boundary) const
{
+ LL_PROFILE_ZONE_SCOPED
if (!wchars || !wchars[0] || max_chars == 0)
{
return 0;
@@ -829,6 +837,8 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st
{
sFontRegistry->reset();
}
+
+ LLFontGL::loadDefaultFonts();
}
// Force standard fonts to get generated up front.
@@ -838,6 +848,7 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st
// static
bool LLFontGL::loadDefaultFonts()
{
+ LL_PROFILE_ZONE_SCOPED
bool succ = true;
succ &= (NULL != getFontSansSerifSmall());
succ &= (NULL != getFontSansSerif());
@@ -845,10 +856,18 @@ bool LLFontGL::loadDefaultFonts()
succ &= (NULL != getFontSansSerifHuge());
succ &= (NULL != getFontSansSerifBold());
succ &= (NULL != getFontMonospace());
- succ &= (NULL != getFontExtChar());
return succ;
}
+void LLFontGL::loadCommonFonts()
+{
+ LL_PROFILE_ZONE_SCOPED
+ getFont(LLFontDescriptor("SansSerif", "Small", BOLD));
+ getFont(LLFontDescriptor("SansSerif", "Large", BOLD));
+ getFont(LLFontDescriptor("SansSerif", "Huge", BOLD));
+ getFont(LLFontDescriptor("Monospace", "Medium", 0));
+}
+
// static
void LLFontGL::destroyDefaultFonts()
{
@@ -1015,7 +1034,7 @@ LLFontGL* LLFontGL::getFontSansSerifBig()
//static
LLFontGL* LLFontGL::getFontSansSerifHuge()
{
- static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Large",0));
+ static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Huge",0));
return fontp;
}
@@ -1026,12 +1045,6 @@ LLFontGL* LLFontGL::getFontSansSerifBold()
return fontp;
}
-//static
-LLFontGL* LLFontGL::getFontExtChar()
-{
- return getFontSansSerif();
-}
-
//static
LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc)
{
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 10891faed9..3b58a37d33 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -160,12 +160,15 @@ public:
const LLFontDescriptor& getFontDesc() const;
+ void generateASCIIglyphs();
+
static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true);
// Load sans-serif, sans-serif-small, etc.
// Slow, requires multiple seconds to load fonts.
static bool loadDefaultFonts();
+ static void loadCommonFonts();
static void destroyDefaultFonts();
static void destroyAllGL();
@@ -190,7 +193,6 @@ public:
static LLFontGL* getFontSansSerifBig();
static LLFontGL* getFontSansSerifHuge();
static LLFontGL* getFontSansSerifBold();
- static LLFontGL* getFontExtChar();
static LLFontGL* getFont(const LLFontDescriptor& desc);
// Use with legacy names like "SANSSERIF_SMALL" or "OCRA"
static LLFontGL* getFontByName(const std::string& name);
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 33a33af160..bc1a2f8887 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -597,6 +597,11 @@ LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& desc)
<<" style=[" << ((S32) desc.getStyle()) << "]"
<< " size=[" << desc.getSize() << "]" << LL_ENDL;
}
+ else
+ {
+ //generate glyphs for ASCII chars to avoid stalls later
+ fontp->generateASCIIglyphs();
+ }
return fontp;
}
}
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 43fedeca64..c7f85aec21 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -62,6 +62,7 @@
BOOL gDebugSession = FALSE;
BOOL gClothRipple = FALSE;
BOOL gHeadlessClient = FALSE;
+BOOL gNonInteractive = FALSE;
BOOL gGLActive = FALSE;
BOOL gGLDebugLoggingEnabled = TRUE;
@@ -434,9 +435,6 @@ LLGLManager::LLGLManager() :
mHasMapBufferRange(FALSE),
mHasFlushBufferRange(FALSE),
mHasPBuffer(FALSE),
- mHasShaderObjects(FALSE),
- mHasVertexShader(FALSE),
- mHasFragmentShader(FALSE),
mNumTextureImageUnits(0),
mHasOcclusionQuery(FALSE),
mHasTimerQuery(FALSE),
@@ -559,7 +557,7 @@ bool LLGLManager::initGL()
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
for (GLint i = 0; i < count; ++i)
{
- std::string ext((const char*) glGetStringi(GL_EXTENSIONS, i));
+ std::string ext = ll_safe_string((const char*) glGetStringi(GL_EXTENSIONS, i));
str << ext << " ";
LL_DEBUGS("GLExtensions") << ext << LL_ENDL;
}
@@ -775,14 +773,9 @@ bool LLGLManager::initGL()
stop_glerror();
- stop_glerror();
-
- if (mHasFragmentShader)
- {
- GLint num_tex_image_units;
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
- mNumTextureImageUnits = llmin(num_tex_image_units, 32);
- }
+ GLint num_tex_image_units;
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
+ mNumTextureImageUnits = llmin(num_tex_image_units, 32);
if (LLRender::sGLCoreProfile)
{
@@ -975,9 +968,9 @@ void LLGLManager::asLLSD(LLSD& info)
info["has_map_buffer_range"] = mHasMapBufferRange;
info["has_flush_buffer_range"] = mHasFlushBufferRange;
info["has_pbuffer"] = mHasPBuffer;
- info["has_shader_objects"] = mHasShaderObjects;
- info["has_vertex_shader"] = mHasVertexShader;
- info["has_fragment_shader"] = mHasFragmentShader;
+ info["has_shader_objects"] = std::string("Assumed TRUE"); // was mHasShaderObjects;
+ info["has_vertex_shader"] = std::string("Assumed TRUE"); // was mHasVertexShader;
+ info["has_fragment_shader"] = std::string("Assumed TRUE"); // was mHasFragmentShader;
info["num_texture_image_units"] = mNumTextureImageUnits;
info["has_occlusion_query"] = mHasOcclusionQuery;
info["has_timer_query"] = mHasTimerQuery;
@@ -1083,9 +1076,6 @@ void LLGLManager::initExtensions()
mHasCubeMap = FALSE;
mHasOcclusionQuery = FALSE;
mHasPointParameters = FALSE;
- mHasShaderObjects = FALSE;
- mHasVertexShader = FALSE;
- mHasFragmentShader = FALSE;
mHasTextureRectangle = FALSE;
#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
@@ -1143,10 +1133,6 @@ void LLGLManager::initExtensions()
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
#endif
- mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
- mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
- && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
- mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
#endif
#if LL_LINUX
@@ -1169,9 +1155,6 @@ void LLGLManager::initExtensions()
mHasCubeMap = FALSE;
mHasOcclusionQuery = FALSE;
mHasPointParameters = FALSE;
- mHasShaderObjects = FALSE;
- mHasVertexShader = FALSE;
- mHasFragmentShader = FALSE;
LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL;
}
else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */
@@ -1184,9 +1167,6 @@ void LLGLManager::initExtensions()
mHasAnisotropic = FALSE;
//mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar
//mHasOcclusionQuery = FALSE; // source of many ATI system hangs
- mHasShaderObjects = FALSE;
- mHasVertexShader = FALSE;
- mHasFragmentShader = FALSE;
mHasBlendFuncSeparate = FALSE;
LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL;
}
@@ -1208,9 +1188,6 @@ void LLGLManager::initExtensions()
if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S
// if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S
if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE;
- if (strchr(blacklist,'m')) mHasShaderObjects = FALSE;//S
- if (strchr(blacklist,'n')) mHasVertexShader = FALSE;//S
- if (strchr(blacklist,'o')) mHasFragmentShader = FALSE;//S
if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S
if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S
if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S
@@ -1257,18 +1234,6 @@ void LLGLManager::initExtensions()
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL;
}
- if (!mHasShaderObjects)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_shader_objects" << LL_ENDL;
- }
- if (!mHasVertexShader)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_vertex_shader" << LL_ENDL;
- }
- if (!mHasFragmentShader)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL;
- }
if (!mHasBlendFuncSeparate)
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL;
@@ -1436,134 +1401,132 @@ void LLGLManager::initExtensions()
glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfARB");
glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfvARB");
}
- if (mHasShaderObjects)
- {
- glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteObjectARB");
- glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetHandleARB");
- glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDetachObjectARB");
- glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateShaderObjectARB");
- glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glShaderSourceARB");
- glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCompileShaderARB");
- glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateProgramObjectARB");
- glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glAttachObjectARB");
- glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glLinkProgramARB");
- glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUseProgramObjectARB");
- glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glValidateProgramARB");
- glUniform1fARB = (PFNGLUNIFORM1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fARB");
- glUniform2fARB = (PFNGLUNIFORM2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fARB");
- glUniform3fARB = (PFNGLUNIFORM3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fARB");
- glUniform4fARB = (PFNGLUNIFORM4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fARB");
- glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1iARB");
- glUniform2iARB = (PFNGLUNIFORM2IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2iARB");
- glUniform3iARB = (PFNGLUNIFORM3IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3iARB");
- glUniform4iARB = (PFNGLUNIFORM4IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4iARB");
- glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fvARB");
- glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fvARB");
- glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fvARB");
- glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fvARB");
- glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1ivARB");
- glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2ivARB");
- glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3ivARB");
- glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB");
- glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB");
- glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB");
- glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4fv");
- glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB");
- glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB");
- glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB");
- glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInfoLogARB");
- glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttachedObjectsARB");
- glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocationARB");
- glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformARB");
- glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformfvARB");
- glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformivARB");
- glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetShaderSourceARB");
- }
- if (mHasVertexShader)
- {
- LL_INFOS() << "initExtensions() VertexShader-related procs..." << LL_ENDL;
-
- // nSight doesn't support use of ARB funcs that have been normalized in the API
- if (!LLRender::sNsightDebugSupport)
- {
- glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
- glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
- }
- else
- {
- glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocation");
- glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocation");
- }
-
- glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttribARB");
- glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB");
- glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB");
- glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fARB");
- glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvARB");
- glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sARB");
- glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svARB");
- glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dARB");
- glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvARB");
- glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fARB");
- glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvARB");
- glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sARB");
- glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svARB");
- glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dARB");
- glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvARB");
- glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fARB");
- glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvARB");
- glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sARB");
- glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svARB");
- glVertexAttrib4nbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nbvARB");
- glVertexAttrib4nivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nivARB");
- glVertexAttrib4nsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nsvARB");
- glVertexAttrib4nubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubARB");
- glVertexAttrib4nubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubvARB");
- glVertexAttrib4nuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nuivARB");
- glVertexAttrib4nusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nusvARB");
- glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bvARB");
- glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dARB");
- glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvARB");
- glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fARB");
- glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvARB");
- glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ivARB");
- glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sARB");
- glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svARB");
- glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvARB");
- glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");
- glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");
- glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB");
- glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer");
- glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");
- glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");
- glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
- glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB");
- glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB");
- glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB");
- glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB");
- glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB");
- glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB");
- glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB");
- glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB");
- glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB");
- glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB");
- glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB");
- glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB");
- glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB");
- glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterdvARB");
- glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterfvARB");
- glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramivARB");
- glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB");
- glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvARB");
- glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvARB");
- glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivARB");
- glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glgetVertexAttribPointervARB");
- glIsProgramARB = (PFNGLISPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB");
- }
- LL_DEBUGS("RenderInit") << "GL Probe: Got symbols" << LL_ENDL;
+
+ // Assume shader capabilities
+ glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteObjectARB");
+ glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetHandleARB");
+ glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDetachObjectARB");
+ glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateShaderObjectARB");
+ glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glShaderSourceARB");
+ glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCompileShaderARB");
+ glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateProgramObjectARB");
+ glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glAttachObjectARB");
+ glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glLinkProgramARB");
+ glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUseProgramObjectARB");
+ glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glValidateProgramARB");
+ glUniform1fARB = (PFNGLUNIFORM1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fARB");
+ glUniform2fARB = (PFNGLUNIFORM2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fARB");
+ glUniform3fARB = (PFNGLUNIFORM3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fARB");
+ glUniform4fARB = (PFNGLUNIFORM4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fARB");
+ glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1iARB");
+ glUniform2iARB = (PFNGLUNIFORM2IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2iARB");
+ glUniform3iARB = (PFNGLUNIFORM3IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3iARB");
+ glUniform4iARB = (PFNGLUNIFORM4IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4iARB");
+ glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fvARB");
+ glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fvARB");
+ glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fvARB");
+ glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fvARB");
+ glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1ivARB");
+ glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2ivARB");
+ glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3ivARB");
+ glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB");
+ glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB");
+ glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB");
+ glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4fv");
+ glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB");
+ glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB");
+ glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB");
+ glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInfoLogARB");
+ glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttachedObjectsARB");
+ glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocationARB");
+ glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformARB");
+ glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformfvARB");
+ glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformivARB");
+ glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetShaderSourceARB");
+
+ LL_INFOS() << "initExtensions() VertexShader-related procs..." << LL_ENDL;
+
+ // nSight doesn't support use of ARB funcs that have been normalized in the API
+ if (!LLRender::sNsightDebugSupport)
+ {
+ glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
+ glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
+ }
+ else
+ {
+ glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocation");
+ glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocation");
+ }
+
+ glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttribARB");
+ glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB");
+ glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB");
+ glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fARB");
+ glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvARB");
+ glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sARB");
+ glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svARB");
+ glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dARB");
+ glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvARB");
+ glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fARB");
+ glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvARB");
+ glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sARB");
+ glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svARB");
+ glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dARB");
+ glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvARB");
+ glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fARB");
+ glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvARB");
+ glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sARB");
+ glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svARB");
+ glVertexAttrib4nbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nbvARB");
+ glVertexAttrib4nivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nivARB");
+ glVertexAttrib4nsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nsvARB");
+ glVertexAttrib4nubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubARB");
+ glVertexAttrib4nubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubvARB");
+ glVertexAttrib4nuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nuivARB");
+ glVertexAttrib4nusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nusvARB");
+ glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bvARB");
+ glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dARB");
+ glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvARB");
+ glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fARB");
+ glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvARB");
+ glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ivARB");
+ glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sARB");
+ glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svARB");
+ glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvARB");
+ glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");
+ glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");
+ glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB");
+ glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer");
+ glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");
+ glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");
+ glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
+ glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB");
+ glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB");
+ glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB");
+ glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB");
+ glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB");
+ glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB");
+ glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB");
+ glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB");
+ glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB");
+ glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB");
+ glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB");
+ glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB");
+ glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB");
+ glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterdvARB");
+ glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterfvARB");
+ glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramivARB");
+ glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB");
+ glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvARB");
+ glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvARB");
+ glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivARB");
+ glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glgetVertexAttribPointervARB");
+ glIsProgramARB = (PFNGLISPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB");
+
+ LL_DEBUGS("RenderInit") << "GL Probe: Got symbols" << LL_ENDL;
#endif
- mInited = TRUE;
+ mInited = TRUE;
}
void rotate_quat(LLQuaternion& rotation)
@@ -2116,7 +2079,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
glClientActiveTextureARB(GL_TEXTURE0_ARB);
gGL.getTexUnit(0)->activate();
- if (gGLManager.mHasVertexShader && LLGLSLShader::sNoFixedFunction)
+ if (LLGLSLShader::sNoFixedFunction)
{ //make sure vertex attribs are all disabled
GLint count;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &count);
@@ -2154,6 +2117,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
LLGLState::LLGLState(LLGLenum state, S32 enabled) :
mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
{
+ LL_PROFILE_ZONE_SCOPED;
if (LLGLSLShader::sNoFixedFunction)
{ //always ignore state that's deprecated post GL 3.0
switch (state)
@@ -2212,6 +2176,7 @@ void LLGLState::setEnabled(S32 enabled)
LLGLState::~LLGLState()
{
+ LL_PROFILE_ZONE_SCOPED;
stop_glerror();
if (mState)
{
@@ -2469,6 +2434,7 @@ void LLGLNamePool::cleanup()
GLuint LLGLNamePool::allocate()
{
+ LL_PROFILE_ZONE_SCOPED;
#if LL_GL_NAME_POOLING
for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
{
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index a07e2d9bb0..6e1f5e6deb 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -94,9 +94,6 @@ public:
BOOL mHasMapBufferRange;
BOOL mHasFlushBufferRange;
BOOL mHasPBuffer;
- BOOL mHasShaderObjects;
- BOOL mHasVertexShader;
- BOOL mHasFragmentShader;
S32 mNumTextureImageUnits;
BOOL mHasOcclusionQuery;
BOOL mHasTimerQuery;
@@ -488,6 +485,7 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
extern BOOL gClothRipple;
extern BOOL gHeadlessClient;
+extern BOOL gNonInteractive;
extern BOOL gGLActive;
// Deal with changing glext.h definitions for newer SDK versions, specifically
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 6bca3623e0..3d93cc0762 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -812,4 +812,23 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
#endif
+#if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL
+ // Tracy uses the following:
+ // glGenQueries
+ // glGetQueryiv
+ // glGetQueryObjectiv
+ #define glGenQueries glGenQueriesARB
+ #define glGetQueryiv glGetQueryivARB
+ #define glGetQueryObjectiv glGetQueryObjectivARB
+ #include <tracy/TracyOpenGL.hpp>
+
+ #define LL_PROFILER_GPU_ZONEC(name,color) TracyGpuZoneC(name,color);
+ #define LL_PROFILER_GPU_COLLECT TracyGpuCollect
+ #define LL_PROFILER_GPU_CONTEXT TracyGpuContext
+#else
+ #define LL_PROFILER_GPU_ZONEC(name,color) (void)name;(void)color;
+ #define LL_PROFILER_GPU_COLLECT
+ #define LL_PROFILER_GPU_CONTEXT
+#endif
+
#endif // LL_LLGLHEADERS_H
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 4351f6e2c8..08c9dd8769 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -208,6 +208,7 @@ void LLGLSLShader::dumpStats()
//static
void LLGLSLShader::startProfile()
{
+ LL_PROFILE_ZONE_SCOPED;
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->placeProfileQuery();
@@ -218,6 +219,7 @@ void LLGLSLShader::startProfile()
//static
void LLGLSLShader::stopProfile(U32 count, U32 mode)
{
+ LL_PROFILE_ZONE_SCOPED;
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->readProfileQuery(count, mode);
@@ -384,6 +386,8 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
U32 varying_count,
const char** varyings)
{
+ LL_PROFILE_ZONE_SCOPED;
+
unloadInternal();
sInstances.insert(this);
@@ -588,6 +592,8 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes)
{
+ LL_PROFILE_ZONE_SCOPED;
+
//before linking, make sure reserved attributes always have consistent locations
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
{
@@ -649,6 +655,8 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * uniforms)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (index == -1)
{
return;
@@ -770,6 +778,8 @@ void LLGLSLShader::removePermutation(std::string name)
GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||
type == GL_SAMPLER_2D_MULTISAMPLE)
{ //this here is a texture
@@ -782,7 +792,9 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
{
- BOOL res = TRUE;
+ LL_PROFILE_ZONE_SCOPED;
+
+ BOOL res = TRUE;
mTotalUniformSize = 0;
mActiveTextureChannels = 0;
@@ -925,6 +937,8 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
BOOL LLGLSLShader::link(BOOL suppress_errors)
{
+ LL_PROFILE_ZONE_SCOPED;
+
BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
if (!success && !suppress_errors)
@@ -937,56 +951,52 @@ BOOL LLGLSLShader::link(BOOL suppress_errors)
void LLGLSLShader::bind()
{
+ LL_PROFILE_ZONE_SCOPED;
+
gGL.flush();
- if (gGLManager.mHasShaderObjects)
+
+ if (sCurBoundShader != mProgramObject) // Don't re-bind current shader
{
LLVertexBuffer::unbind();
glUseProgramObjectARB(mProgramObject);
sCurBoundShader = mProgramObject;
sCurBoundShaderPtr = this;
- if (mUniformsDirty)
- {
- LLShaderMgr::instance()->updateShaderUniforms(this);
- mUniformsDirty = FALSE;
- }
+ }
+
+ if (mUniformsDirty)
+ {
+ LLShaderMgr::instance()->updateShaderUniforms(this);
+ mUniformsDirty = FALSE;
}
}
void LLGLSLShader::unbind()
{
+ LL_PROFILE_ZONE_SCOPED;
+
gGL.flush();
- if (gGLManager.mHasShaderObjects)
- {
- stop_glerror();
- if (gGLManager.mIsNVIDIA)
- {
- for (U32 i = 0; i < mAttribute.size(); ++i)
- {
- vertexAttrib4f(i, 0,0,0,1);
- stop_glerror();
- }
- }
- LLVertexBuffer::unbind();
- glUseProgramObjectARB(0);
- sCurBoundShader = 0;
- sCurBoundShaderPtr = NULL;
- stop_glerror();
- }
+ stop_glerror();
+ LLVertexBuffer::unbind();
+ glUseProgramObjectARB(0);
+ sCurBoundShader = 0;
+ sCurBoundShaderPtr = NULL;
+ stop_glerror();
}
void LLGLSLShader::bindNoShader(void)
{
+ LL_PROFILE_ZONE_SCOPED;
+
LLVertexBuffer::unbind();
- if (gGLManager.mHasShaderObjects)
- {
- glUseProgramObjectARB(0);
- sCurBoundShader = 0;
- sCurBoundShaderPtr = NULL;
- }
+ glUseProgramObjectARB(0);
+ sCurBoundShader = 0;
+ sCurBoundShaderPtr = NULL;
}
S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
{
+ LL_PROFILE_ZONE_SCOPED;
+
S32 channel = 0;
channel = getUniformLocation(uniform);
@@ -995,6 +1005,8 @@ S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LL
S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
@@ -1005,7 +1017,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu
if (uniform > -1)
{
- gGL.getTexUnit(uniform)->bind(texture, mode);
+ gGL.getTexUnit(uniform)->bindFast(texture);
gGL.getTexUnit(uniform)->setTextureColorSpace(colorspace);
}
@@ -1014,6 +1026,8 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu
S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode)
{
+ LL_PROFILE_ZONE_SCOPED;
+
S32 channel = 0;
channel = getUniformLocation(uniform);
@@ -1022,6 +1036,8 @@ S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureT
S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
@@ -1032,7 +1048,7 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
if (uniform > -1)
{
- gGL.getTexUnit(uniform)->unbind(mode);
+ gGL.getTexUnit(uniform)->unbindFast(mode);
}
return uniform;
@@ -1040,6 +1056,8 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
@@ -1057,6 +1075,8 @@ S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTex
S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
@@ -1084,6 +1104,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTe
void LLGLSLShader::uniform1i(U32 index, GLint x)
{
+ LL_PROFILE_ZONE_SCOPED
if (mProgramObject)
{
if (mUniform.size() <= index)
@@ -1094,7 +1115,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
if (iter == mValue.end() || iter->second.mV[0] != x)
{
glUniform1iARB(mUniform[index], x);
@@ -1106,6 +1127,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
void LLGLSLShader::uniform1f(U32 index, GLfloat x)
{
+ LL_PROFILE_ZONE_SCOPED
if (mProgramObject)
{
if (mUniform.size() <= index)
@@ -1116,7 +1138,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
if (iter == mValue.end() || iter->second.mV[0] != x)
{
glUniform1fARB(mUniform[index], x);
@@ -1138,7 +1160,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(x,y,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1161,7 +1183,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(x,y,z,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1184,7 +1206,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(x,y,z,w);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1207,7 +1229,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0],0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1230,7 +1252,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0],0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1253,7 +1275,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0],v[1],0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1276,7 +1298,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0],v[1],v[2],0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1299,10 +1321,11 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0],v[1],v[2],v[3]);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
+ LL_PROFILE_ZONE_SCOPED;
glUniform4fvARB(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
@@ -1346,6 +1369,8 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c
void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (mProgramObject)
{
if (mUniform.size() <= index)
@@ -1380,6 +1405,8 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
{
+ LL_PROFILE_ZONE_SCOPED;
+
GLint ret = -1;
if (mProgramObject)
{
@@ -1404,10 +1431,16 @@ GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
GLint LLGLSLShader::getUniformLocation(U32 index)
{
+ LL_PROFILE_ZONE_SCOPED;
+
GLint ret = -1;
if (mProgramObject)
{
- llassert(index < mUniform.size());
+ if (index >= mUniform.size())
+ {
+ LL_WARNS_ONCE("Shader") << "Uniform index " << index << " out of bounds " << (S32)mUniform.size() << LL_ENDL;
+ return ret;
+ }
return mUniform[index];
}
@@ -1416,6 +1449,8 @@ GLint LLGLSLShader::getUniformLocation(U32 index)
GLint LLGLSLShader::getAttribLocation(U32 attrib)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (attrib < mAttribute.size())
{
return mAttribute[attrib];
@@ -1432,7 +1467,7 @@ void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(v,0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1448,7 +1483,7 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(i,j,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1465,7 +1500,7 @@ void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(v,0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1481,7 +1516,7 @@ void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLf
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(x,y,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1498,7 +1533,7 @@ void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLf
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(x,y,z,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1514,7 +1549,7 @@ void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(v[0],0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1530,7 +1565,7 @@ void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(v[0],v[1],0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1546,7 +1581,7 @@ void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(v[0],v[1],v[2],0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1563,12 +1598,11 @@ void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
LLVector4 vec(v);
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
- stop_glerror();
+ LL_PROFILE_ZONE_SCOPED;
glUniform4fvARB(location, count, v);
- stop_glerror();
mValue[location] = vec;
}
}
@@ -1608,3 +1642,27 @@ void LLGLSLShader::setMinimumAlpha(F32 minimum)
gGL.flush();
uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum);
}
+
+void LLShaderUniforms::apply(LLGLSLShader* shader)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ for (auto& uniform : mIntegers)
+ {
+ shader->uniform1i(uniform.mUniform, uniform.mValue);
+ }
+
+ for (auto& uniform : mFloats)
+ {
+ shader->uniform1f(uniform.mUniform, uniform.mValue);
+ }
+
+ for (auto& uniform : mVectors)
+ {
+ shader->uniform4fv(uniform.mUniform, 1, uniform.mValue.mV);
+ }
+
+ for (auto& uniform : mVector3s)
+ {
+ shader->uniform3fv(uniform.mUniform, 1, uniform.mValue.mV);
+ }
+}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 7cf6d3c941..3b23cf1b28 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -30,6 +30,7 @@
#include "llgl.h"
#include "llrender.h"
#include "llstaticstringtable.h"
+#include <unordered_map>
class LLShaderFeatures
{
@@ -64,16 +65,79 @@ public:
LLShaderFeatures();
};
+// ============= Structure for caching shader uniforms ===============
+class LLGLSLShader;
+
+class LLShaderUniforms
+{
+public:
+
+ template<typename T>
+ struct UniformSetting
+ {
+ S32 mUniform;
+ T mValue;
+ };
+
+ typedef UniformSetting<S32> IntSetting;
+ typedef UniformSetting<F32> FloatSetting;
+ typedef UniformSetting<LLVector4> VectorSetting;
+ typedef UniformSetting<LLVector3> Vector3Setting;
+
+ void clear()
+ {
+ mIntegers.resize(0);
+ mFloats.resize(0);
+ mVectors.resize(0);
+ mVector3s.resize(0);
+ }
+
+ void uniform1i(S32 index, S32 value)
+ {
+ mIntegers.push_back({ index, value });
+ }
+
+ void uniform1f(S32 index, F32 value)
+ {
+ mFloats.push_back({ index, value });
+ }
+
+ void uniform4fv(S32 index, const LLVector4& value)
+ {
+ mVectors.push_back({ index, value });
+ }
+
+ void uniform4fv(S32 index, const F32* value)
+ {
+ mVectors.push_back({ index, LLVector4(value) });
+ }
+
+ void uniform3fv(S32 index, const LLVector3& value)
+ {
+ mVector3s.push_back({ index, value });
+ }
+
+ void apply(LLGLSLShader* shader);
+
+
+ std::vector<IntSetting> mIntegers;
+ std::vector<FloatSetting> mFloats;
+ std::vector<VectorSetting> mVectors;
+ std::vector<Vector3Setting> mVector3s;
+};
class LLGLSLShader
{
public:
- enum
+ // enum primarily used to control application sky settings uniforms
+ typedef enum
{
- SG_DEFAULT = 0,
- SG_SKY,
- SG_WATER
- };
+ SG_DEFAULT = 0, // not sky or water specific
+ SG_SKY, //
+ SG_WATER,
+ SG_ANY,
+ SG_COUNT
+ } eGroup;
static std::set<LLGLSLShader*> sInstances;
static bool sProfileEnabled;
@@ -190,13 +254,15 @@ public:
U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
- std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name
- std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
+ typedef std::unordered_map<GLint, std::string> uniform_name_map_t;
+ typedef std::unordered_map<GLint, LLVector4> uniform_value_map_t;
+ uniform_name_map_t mUniformNameMap; //lookup map of uniform location to uniform name
+ uniform_value_map_t mValue; //lookup map of uniform location to last known value
std::vector<GLint> mTexture;
S32 mTotalUniformSize;
S32 mActiveTextureChannels;
S32 mShaderLevel;
- S32 mShaderGroup;
+ S32 mShaderGroup; // see LLGLSLShader::eGroup
BOOL mUniformsDirty;
LLShaderFeatures mFeatures;
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index ad501687ed..a279e85bae 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -262,6 +262,7 @@ LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(mGLTexturep.notNull()) ;
return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
@@ -269,6 +270,7 @@ BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos,
BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(mGLTexturep.notNull()) ;
return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index 071912c2c2..028457c510 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -176,7 +176,7 @@ private:
protected:
void setTexelsPerImage();
- //note: do not make this function public.
+public:
/*virtual*/ LLImageGL* getGLTexture() const ;
protected:
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 0151d20128..cbc5392882 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -39,6 +39,7 @@
#include "llgl.h"
#include "llglslshader.h"
#include "llrender.h"
+#include "llwindow.h"
//----------------------------------------------------------------------------
const F32 MIN_TEXTURE_LIFETIME = 10.f;
@@ -170,15 +171,32 @@ BOOL is_little_endian()
return (*c == 0x78) ;
}
+
+LLImageGLThread* LLImageGLThread::sInstance = nullptr;
+
//static
-void LLImageGL::initClass(S32 num_catagories, BOOL skip_analyze_alpha /* = false */)
+void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha /* = false */)
{
+ LL_PROFILE_ZONE_SCOPED;
sSkipAnalyzeAlpha = skip_analyze_alpha;
+ LLImageGLThread::sInstance = new LLImageGLThread(window);
+ LLImageGLThread::sInstance->start();
+}
+
+//static
+void LLImageGL::updateClass()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ LLImageGLThread::sInstance->executeCallbacks();
}
//static
void LLImageGL::cleanupClass()
-{
+{
+ LL_PROFILE_ZONE_SCOPED;
+ LLImageGLThread::sInstance->mFunctionQueue.close();
+ delete LLImageGLThread::sInstance;
+ LLImageGLThread::sInstance = nullptr;
}
//static
@@ -258,11 +276,10 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
//----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_STATS("Image Stats");
// static
void LLImageGL::updateStats(F32 current_time)
{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_STATS);
+ LL_PROFILE_ZONE_SCOPED;
sLastFrameTime = current_time;
sBoundTextureMemory = sCurBoundTextureMemory;
sCurBoundTextureMemory = S32Bytes(0);
@@ -295,10 +312,8 @@ void LLImageGL::destroyGL(BOOL save_state)
if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
{
glimage->mSaveData = new LLImageRaw;
- glimage->claimMem(glimage->mSaveData);
if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
{
- glimage->disclaimMem(glimage->mSaveData);
glimage->mSaveData = NULL ;
}
}
@@ -372,8 +387,7 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, B
//----------------------------------------------------------------------------
LLImageGL::LLImageGL(BOOL usemipmaps)
-: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0), mExternalTexture(FALSE)
+: mSaveData(0), mExternalTexture(FALSE)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -382,8 +396,7 @@ LLImageGL::LLImageGL(BOOL usemipmaps)
}
LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
-: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0), mExternalTexture(FALSE)
+: mSaveData(0), mExternalTexture(FALSE)
{
llassert( components <= 4 );
init(usemipmaps);
@@ -393,8 +406,7 @@ LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
}
LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps)
-: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0), mExternalTexture(FALSE)
+: mSaveData(0), mExternalTexture(FALSE)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -412,7 +424,6 @@ LLImageGL::LLImageGL(
LLGLenum formatPrimary,
LLGLenum formatType,
LLTexUnit::eTextureAddressMode addressMode)
- : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), mSaveData(0), mExternalTexture(TRUE)
{
init(false);
mTexName = texName;
@@ -656,6 +667,7 @@ void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_for
void LLImageGL::setImage(const LLImageRaw* imageraw)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert((imageraw->getWidth() == getWidth(mCurrentDiscardLevel)) &&
(imageraw->getHeight() == getHeight(mCurrentDiscardLevel)) &&
(imageraw->getComponents() == getComponents()));
@@ -663,10 +675,9 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
setImage(rawdata, FALSE);
}
-static LLTrace::BlockTimerStatHandle FTM_SET_IMAGE("setImage");
-BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
+BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips, S32 usename)
{
- LL_RECORD_BLOCK_TIME(FTM_SET_IMAGE);
+ LL_PROFILE_ZONE_SCOPED;
bool is_compressed = false;
switch (mFormatPrimary)
@@ -683,12 +694,11 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
break;
}
-
-
if (mUseMipMaps)
{
//set has mip maps to true before binding image so tex parameters get set properly
- gGL.getTexUnit(0)->unbind(mBindTarget);
+ gGL.getTexUnit(0)->unbind(mBindTarget);
+
mHasMipMaps = true;
mTexOptionsDirty = true;
setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
@@ -698,10 +708,10 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
mHasMipMaps = false;
}
- llverify(gGL.getTexUnit(0)->bind(this));
-
-
- if (mUseMipMaps)
+ gGL.getTexUnit(0)->bind(this, false, false, usename);
+
+
+ if (mUseMipMaps)
{
if (data_hasmips)
{
@@ -728,8 +738,6 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
else
{
-// LL_RECORD_BLOCK_TIME(FTM_TEMP4);
-
if(mFormatSwapBytes)
{
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
@@ -760,8 +768,6 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
stop_glerror();
{
-// LL_RECORD_BLOCK_TIME(FTM_TEMP4);
-
if(mFormatSwapBytes)
{
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
@@ -781,7 +787,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
}
- LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
+ LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
data_in, mAllowCompression);
@@ -871,14 +877,13 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
llassert(w > 0 && h > 0 && cur_mip_data);
(void)cur_mip_data;
{
-// LL_RECORD_BLOCK_TIME(FTM_TEMP4);
if(mFormatSwapBytes)
{
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
stop_glerror();
}
- LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
+ LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
if (m == 0)
{
analyzeAlpha(data_in, w, h);
@@ -1067,6 +1072,7 @@ void LLImageGL::postAddToAtlas()
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!width || !height)
{
return TRUE;
@@ -1163,6 +1169,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
{
+ LL_PROFILE_ZONE_SCOPED;
return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update);
}
@@ -1183,15 +1190,14 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
}
// static
-static LLTrace::BlockTimerStatHandle FTM_GENERATE_TEXTURES("generate textures");
void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
{
- LL_RECORD_BLOCK_TIME(FTM_GENERATE_TEXTURES);
+ LL_PROFILE_ZONE_SCOPED;
glGenTextures(numTextures, textures);
}
// static
-void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
+void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures)
{
if (gGLManager.mInited)
{
@@ -1200,125 +1206,126 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
}
// static
-static LLTrace::BlockTimerStatHandle FTM_SET_MANUAL_IMAGE("setManualImage");
-void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
+void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void* pixels, bool allow_compression)
{
- LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE);
- bool use_scratch = false;
- U32* scratch = NULL;
- if (LLRender::sGLCoreProfile)
- {
- if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE)
- { //GL_ALPHA is deprecated, convert to RGBA
- use_scratch = true;
- scratch = new U32[width*height];
+ LL_PROFILE_ZONE_SCOPED;
+ bool use_scratch = false;
+ U32* scratch = NULL;
+ if (LLRender::sGLCoreProfile)
+ {
+ if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE)
+ { //GL_ALPHA is deprecated, convert to RGBA
+ use_scratch = true;
+ scratch = new U32[width * height];
- U32 pixel_count = (U32) (width*height);
- for (U32 i = 0; i < pixel_count; i++)
- {
- U8* pix = (U8*) &scratch[i];
- pix[0] = pix[1] = pix[2] = 0;
- pix[3] = ((U8*) pixels)[i];
- }
-
- pixformat = GL_RGBA;
- intformat = GL_RGBA8;
- }
+ U32 pixel_count = (U32)(width * height);
+ for (U32 i = 0; i < pixel_count; i++)
+ {
+ U8* pix = (U8*)&scratch[i];
+ pix[0] = pix[1] = pix[2] = 0;
+ pix[3] = ((U8*)pixels)[i];
+ }
- if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE)
- { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA
- use_scratch = true;
- scratch = new U32[width*height];
+ pixformat = GL_RGBA;
+ intformat = GL_RGBA8;
+ }
- U32 pixel_count = (U32) (width*height);
- for (U32 i = 0; i < pixel_count; i++)
- {
- U8 lum = ((U8*) pixels)[i*2+0];
- U8 alpha = ((U8*) pixels)[i*2+1];
+ if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE)
+ { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA
+ use_scratch = true;
+ scratch = new U32[width * height];
- U8* pix = (U8*) &scratch[i];
- pix[0] = pix[1] = pix[2] = lum;
- pix[3] = alpha;
- }
-
- pixformat = GL_RGBA;
- intformat = GL_RGBA8;
- }
+ U32 pixel_count = (U32)(width * height);
+ for (U32 i = 0; i < pixel_count; i++)
+ {
+ U8 lum = ((U8*)pixels)[i * 2 + 0];
+ U8 alpha = ((U8*)pixels)[i * 2 + 1];
- if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE)
- { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
- use_scratch = true;
- scratch = new U32[width*height];
+ U8* pix = (U8*)&scratch[i];
+ pix[0] = pix[1] = pix[2] = lum;
+ pix[3] = alpha;
+ }
- U32 pixel_count = (U32) (width*height);
- for (U32 i = 0; i < pixel_count; i++)
- {
- U8 lum = ((U8*) pixels)[i];
-
- U8* pix = (U8*) &scratch[i];
- pix[0] = pix[1] = pix[2] = lum;
- pix[3] = 255;
- }
-
- pixformat = GL_RGBA;
- intformat = GL_RGB8;
- }
- }
+ pixformat = GL_RGBA;
+ intformat = GL_RGBA8;
+ }
- if (LLImageGL::sCompressTextures && allow_compression)
- {
- switch (intformat)
- {
- case GL_RGB:
- case GL_RGB8:
- intformat = GL_COMPRESSED_RGB;
- break;
- case GL_SRGB:
- case GL_SRGB8:
- intformat = GL_COMPRESSED_SRGB;
- break;
- case GL_RGBA:
- case GL_RGBA8:
- intformat = GL_COMPRESSED_RGBA;
- break;
- case GL_SRGB_ALPHA:
- case GL_SRGB8_ALPHA8:
- intformat = GL_COMPRESSED_SRGB_ALPHA;
- break;
- case GL_LUMINANCE:
- case GL_LUMINANCE8:
- intformat = GL_COMPRESSED_LUMINANCE;
- break;
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE8_ALPHA8:
- intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
- break;
- case GL_ALPHA:
- case GL_ALPHA8:
- intformat = GL_COMPRESSED_ALPHA;
- break;
- default:
- LL_WARNS() << "Could not compress format: " << std::hex << intformat << LL_ENDL;
- break;
- }
- }
+ if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE)
+ { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
+ use_scratch = true;
+ scratch = new U32[width * height];
- stop_glerror();
- glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
- stop_glerror();
+ U32 pixel_count = (U32)(width * height);
+ for (U32 i = 0; i < pixel_count; i++)
+ {
+ U8 lum = ((U8*)pixels)[i];
- if (use_scratch)
- {
- delete [] scratch;
- }
+ U8* pix = (U8*)&scratch[i];
+ pix[0] = pix[1] = pix[2] = lum;
+ pix[3] = 255;
+ }
+
+ pixformat = GL_RGBA;
+ intformat = GL_RGB8;
+ }
+ }
+
+ if (LLImageGL::sCompressTextures && allow_compression)
+ {
+ switch (intformat)
+ {
+ case GL_RGB:
+ case GL_RGB8:
+ intformat = GL_COMPRESSED_RGB;
+ break;
+ case GL_SRGB:
+ case GL_SRGB8:
+ intformat = GL_COMPRESSED_SRGB;
+ break;
+ case GL_RGBA:
+ case GL_RGBA8:
+ intformat = GL_COMPRESSED_RGBA;
+ break;
+ case GL_SRGB_ALPHA:
+ case GL_SRGB8_ALPHA8:
+ intformat = GL_COMPRESSED_SRGB_ALPHA;
+ break;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE8:
+ intformat = GL_COMPRESSED_LUMINANCE;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE8_ALPHA8:
+ intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
+ break;
+ case GL_ALPHA:
+ case GL_ALPHA8:
+ intformat = GL_COMPRESSED_ALPHA;
+ break;
+ default:
+ LL_WARNS() << "Could not compress format: " << std::hex << intformat << LL_ENDL;
+ break;
+ }
+ }
+
+ stop_glerror();
+ {
+ LL_PROFILE_ZONE_NAMED("glTexImage2D");
+ glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
+ }
+ stop_glerror();
+
+ if (use_scratch)
+ {
+ delete[] scratch;
+ }
}
//create an empty GL texture: just create a texture name
//the texture is assiciate with some image by calling glTexImage outside LLImageGL
-static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE1("createGLTexture()");
BOOL LLImageGL::createGLTexture()
{
- LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE1);
+ LL_PROFILE_ZONE_SCOPED;
if (gGLManager.mIsDisabled)
{
LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
@@ -1333,6 +1340,7 @@ BOOL LLImageGL::createGLTexture()
if(mTexName)
{
LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+ mTexName = 0;
}
@@ -1347,23 +1355,22 @@ BOOL LLImageGL::createGLTexture()
return TRUE ;
}
-static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE2("createGLTexture(raw)");
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
{
- LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE2);
+ LL_PROFILE_ZONE_SCOPED;
if (gGLManager.mIsDisabled)
{
LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
return FALSE;
}
- mGLTextureCreated = false ;
llassert(gGLManager.mInited);
stop_glerror();
if (!imageraw || imageraw->isBufferInvalid())
{
LL_WARNS() << "Trying to create a texture from invalid image data" << LL_ENDL;
+ mGLTextureCreated = false;
return FALSE;
}
@@ -1383,6 +1390,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
if (!setSize(w, h, imageraw->getComponents(), discard_level))
{
LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
+ mGLTextureCreated = false;
return FALSE;
}
@@ -1451,6 +1459,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
destroyGLTexture();
mCurrentDiscardLevel = discard_level;
mLastBindTime = sLastFrameTime;
+ mGLTextureCreated = false;
return TRUE ;
}
@@ -1459,107 +1468,123 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
return createGLTexture(discard_level, rawdata, FALSE, usename);
}
-static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE3("createGLTexture3(data)");
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
{
- LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE3);
- llassert(data_in);
- stop_glerror();
+ LL_PROFILE_ZONE_SCOPED;
+ llassert(data_in);
+ stop_glerror();
- if (discard_level < 0)
- {
- llassert(mCurrentDiscardLevel >= 0);
- discard_level = mCurrentDiscardLevel;
- }
- discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
-
- if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
- {
- // This will only be true if the size has not changed
- return setImage(data_in, data_hasmips);
- }
-
- U32 old_name = mTexName;
-// S32 old_discard = mCurrentDiscardLevel;
-
- if (usename != 0)
- {
- mTexName = usename;
- }
- else
- {
- LLImageGL::generateTextures(1, &mTexName);
- stop_glerror();
- {
- llverify(gGL.getTexUnit(0)->bind(this));
- stop_glerror();
- glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
- stop_glerror();
- glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level);
- stop_glerror();
- }
- }
- if (!mTexName)
- {
- if (old_name)
- {
- sGlobalTextureMemory -= mTextureMemory;
- LLImageGL::deleteTextures(1, &old_name);
- disclaimMem(mTextureMemory);
- stop_glerror();
- }
+ if (discard_level < 0)
+ {
+ llassert(mCurrentDiscardLevel >= 0);
+ discard_level = mCurrentDiscardLevel;
+ }
+ discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
- LL_WARNS() << "LLImageGL::createGLTexture failed to make texture" << LL_ENDL;
- return FALSE;
- }
+ if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
+ {
+ // This will only be true if the size has not changed
+ return setImage(data_in, data_hasmips);
+ }
- if (mUseMipMaps)
- {
- mAutoGenMips = gGLManager.mHasMipMapGeneration;
+ GLuint old_texname = mTexName;
+
+ if (usename != 0)
+ {
+ mNewTexName = usename;
+ }
+ else
+ {
+ LLImageGL::generateTextures(1, &mNewTexName);
+ {
+ gGL.getTexUnit(0)->bind(this, false, false, mNewTexName);
+ glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel - discard_level);
+ }
+ }
+
+ if (mUseMipMaps)
+ {
+ mAutoGenMips = gGLManager.mHasMipMapGeneration;
#if LL_DARWIN
- // On the Mac GF2 and GF4MX drivers, auto mipmap generation doesn't work right with alpha-only textures.
- if(gGLManager.mIsGF2or4MX && (mFormatInternal == GL_ALPHA8) && (mFormatPrimary == GL_ALPHA))
- {
- mAutoGenMips = FALSE;
- }
+ // On the Mac GF2 and GF4MX drivers, auto mipmap generation doesn't work right with alpha-only textures.
+ if (gGLManager.mIsGF2or4MX && (mFormatInternal == GL_ALPHA8) && (mFormatPrimary == GL_ALPHA))
+ {
+ mAutoGenMips = FALSE;
+ }
#endif
- }
+ }
- mCurrentDiscardLevel = discard_level;
+ mCurrentDiscardLevel = discard_level;
- if (!setImage(data_in, data_hasmips))
- {
- stop_glerror();
- return FALSE;
- }
+ if (!setImage(data_in, data_hasmips, mNewTexName))
+ {
+ return FALSE;
+ }
- // Set texture options to our defaults.
- gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
- gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
- gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
+ // Set texture options to our defaults.
+ gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
+ gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
+ gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
- // things will break if we don't unbind after creation
- gGL.getTexUnit(0)->unbind(mBindTarget);
- stop_glerror();
+ // things will break if we don't unbind after creation
+ gGL.getTexUnit(0)->unbind(mBindTarget);
- if (old_name != 0)
- {
- sGlobalTextureMemory -= mTextureMemory;
+ if (old_texname != 0)
+ {
+ sGlobalTextureMemory -= mTextureMemory;
+ }
- LLImageGL::deleteTextures(1, &old_name);
+ //if we're on the image loading thread, be sure to delete old_texname and update mTexName on the main thread
+ if (LLImageGLThread::sInstance != nullptr &&
+ LLThread::currentID() == LLImageGLThread::sInstance->getID())
+ {
+ {
+ LL_PROFILE_ZONE_NAMED("cglt - sync");
+ if (gGLManager.mHasSync)
+ {
+ auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ glClientWaitSync(sync, 0, 0);
+ glDeleteSync(sync);
+ }
+ else
+ {
+ glFinish();
+ }
+ }
- stop_glerror();
- }
+ ref();
+ LLImageGLThread::sInstance->postCallback([=]()
+ {
+ LL_PROFILE_ZONE_NAMED("cglt - delete callback");
+ if (old_texname != 0)
+ {
+ LLImageGL::deleteTextures(1, &old_texname);
+ }
+ mTexName = mNewTexName;
+ mNewTexName = 0;
+ unref();
+ });
+ }
+ else
+ {
+ //not on background thread, immediately set mTexName
+ if (old_texname != 0)
+ {
+ LLImageGL::deleteTextures(1, &old_texname);
+ }
+ mTexName = mNewTexName;
+ mNewTexName = 0;
+ }
+
+ mTextureMemory = (S32Bytes)getMipBytes(mCurrentDiscardLevel);
+ sGlobalTextureMemory += mTextureMemory;
+ mTexelsInGLTexture = getWidth() * getHeight();
- disclaimMem(mTextureMemory);
- mTextureMemory = (S32Bytes)getMipBytes(discard_level);
- claimMem(mTextureMemory);
- sGlobalTextureMemory += mTextureMemory;
- mTexelsInGLTexture = getWidth() * getHeight() ;
+ // mark this as bound at this point, so we don't throw it out immediately
+ mLastBindTime = sLastFrameTime;
- // mark this as bound at this point, so we don't throw it out immediately
- mLastBindTime = sLastFrameTime;
- return TRUE;
+ return TRUE;
}
BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
@@ -1690,11 +1715,10 @@ void LLImageGL::destroyGLTexture()
if(mTextureMemory != S32Bytes(0))
{
sGlobalTextureMemory -= mTextureMemory;
- disclaimMem(mTextureMemory);
mTextureMemory = (S32Bytes)0;
}
- LLImageGL::deleteTextures(1, &mTexName);
+ LLImageGL::deleteTextures(1, &mTexName);
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mTexName = 0;
mGLTextureCreated = FALSE ;
@@ -2043,7 +2067,6 @@ U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
U32 size = pick_width * pick_height;
size = (size + 7) / 8; // pixelcount-to-bits
mPickMask = new U8[size];
- claimMem(size);
mPickMaskWidth = pick_width - 1;
mPickMaskHeight = pick_height - 1;
@@ -2058,7 +2081,6 @@ void LLImageGL::freePickMask()
// pickmask validity depends on old image size, delete it
if (mPickMask != NULL)
{
- disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8);
delete [] mPickMask;
}
mPickMask = NULL;
@@ -2235,3 +2257,75 @@ void LLImageGL::resetCurTexSizebar()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips);
*/
+
+LLImageGLThread::LLImageGLThread(LLWindow* window)
+ : LLThread("LLImageGL"), mWindow(window)
+{
+ mFinished = false;
+
+ mContext = mWindow->createSharedContext();
+}
+
+// post a function to be executed on the LLImageGL background thread
+
+bool LLImageGLThread::post(const std::function<void()>& func)
+{
+ try
+ {
+ mFunctionQueue.post(func);
+ }
+ catch (LLThreadSafeQueueInterrupt e)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//post a callback to be executed on the main thread
+
+bool LLImageGLThread::postCallback(const std::function<void()>& callback)
+{
+ try
+ {
+ if (!mCallbackQueue.tryPost(callback))
+ {
+ mPendingCallbackQ.push(callback);
+ }
+ }
+ catch (LLThreadSafeQueueInterrupt e)
+ {
+ //thread is closing, drop request
+ return false;
+ }
+
+ return true;
+}
+
+void LLImageGLThread::executeCallbacks()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ //executed from main thread
+ mCallbackQueue.runPending();
+
+ while (!mPendingCallbackQ.empty())
+ {
+ if (mCallbackQueue.tryPost(mPendingCallbackQ.front()))
+ {
+ mPendingCallbackQ.pop();
+ }
+ else
+ {
+ break;
+ }
+ }
+}
+
+void LLImageGLThread::run()
+{
+ mWindow->makeContextCurrent(mContext);
+ gGL.init();
+ mFunctionQueue.runUntilClose();
+ gGL.shutdown();
+ mWindow->destroySharedContext(mContext);
+}
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 61ddc8d59b..8264e4a5f2 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -35,20 +35,24 @@
#include "llrefcount.h"
#include "v2math.h"
#include "llunits.h"
-
+#include "llthreadsafequeue.h"
#include "llrender.h"
+#include "workqueue.h"
+
class LLTextureAtlas ;
+class LLWindow;
+
#define BYTES_TO_MEGA_BYTES(x) ((x) >> 20)
#define MEGA_BYTES_TO_BYTES(x) ((x) << 20)
//============================================================================
-class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL>
+class LLImageGL : public LLRefCount
{
friend class LLTexUnit;
public:
// These 2 functions replace glGenTextures() and glDeleteTextures()
static void generateTextures(S32 numTextures, U32 *textures);
- static void deleteTextures(S32 numTextures, U32 *textures);
+ static void deleteTextures(S32 numTextures, const U32 *textures);
static void deleteDeadTextures();
// Size calculation
@@ -102,13 +106,13 @@ public:
void setAllowCompression(bool allow) { mAllowCompression = allow; }
static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
-
+
BOOL createGLTexture() ;
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
S32 category = sMaxCategories-1);
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
void setImage(const LLImageRaw* imageraw);
- BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE);
+ BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0);
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
@@ -208,8 +212,9 @@ private:
bool mGLTextureCreated ;
LLGLuint mTexName;
+ LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread
U16 mWidth;
- U16 mHeight;
+ U16 mHeight;
S8 mCurrentDiscardLevel;
S8 mDiscardLevelInAtlas;
@@ -265,7 +270,8 @@ public:
#endif
public:
- static void initClass(S32 num_catagories, BOOL skip_analyze_alpha = false);
+ static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false);
+ static void updateClass();
static void cleanupClass() ;
private:
@@ -301,4 +307,35 @@ public:
};
+class LLImageGLThread : public LLThread
+{
+public:
+ LLImageGLThread(LLWindow* window);
+
+ // post a function to be executed on the LLImageGL background thread
+ bool post(const std::function<void()>& func);
+
+ //post a callback to be executed on the main thread
+ bool postCallback(const std::function<void()>& callback);
+
+ void executeCallbacks();
+
+ void run() override;
+
+ // Work Queue for background thread
+ LL::WorkQueue mFunctionQueue;
+
+ // Work Queue for main thread (run from updateClass)
+ LL::WorkQueue mCallbackQueue;
+
+ LLWindow* mWindow;
+ void* mContext;
+ LLAtomicBool mFinished;
+
+ std::queue<std::function<void()>> mPendingCallbackQ;
+
+ static LLImageGLThread* sInstance;
+};
+
+
#endif // LL_LLIMAGEGL_H
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 03b6aac20c..aad04beea2 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -36,7 +36,7 @@
#include "lltexture.h"
#include "llshadermgr.h"
-LLRender gGL;
+thread_local LLRender gGL;
// Handy copies of last good GL matrices
F32 gGLModelView[16];
@@ -229,8 +229,24 @@ void LLTexUnit::disable(void)
}
}
+void LLTexUnit::bindFast(LLTexture* texture)
+{
+ LLImageGL* gl_tex = texture->getGLTexture();
+
+ glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
+ gGL.mCurrTextureUnitIndex = mIndex;
+ mCurrTexture = gl_tex->getTexName();
+ if (!mCurrTexture)
+ {
+ mCurrTexture = LLImageGL::sDefaultGLTexture->getTexName();
+ }
+ glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
+ mHasMipMaps = gl_tex->mHasMipMaps;
+}
+
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
{
+ LL_PROFILE_ZONE_SCOPED;
stop_glerror();
if (mIndex >= 0)
{
@@ -294,18 +310,20 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
return true;
}
-bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
+bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32 usename)
{
stop_glerror();
if (mIndex < 0) return false;
+ U32 texname = usename ? usename : texture->getTexName();
+
if(!texture)
{
LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
return false;
}
- if(!texture->getTexName())
+ if(!texname)
{
if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName())
{
@@ -315,7 +333,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
return false ;
}
- if ((mCurrTexture != texture->getTexName()) || forceBind)
+ if ((mCurrTexture != texname) || forceBind)
{
gGL.flush();
stop_glerror();
@@ -323,7 +341,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
stop_glerror();
enable(texture->getTarget());
stop_glerror();
- mCurrTexture = texture->getTexName();
+ mCurrTexture = texname;
glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
stop_glerror();
texture->updateBindStats(texture->mTextureMemory);
@@ -459,6 +477,28 @@ void LLTexUnit::unbind(eTextureType type)
}
}
+void LLTexUnit::unbindFast(eTextureType type)
+{
+ activate();
+
+ // Disabled caching of binding state.
+ if (mCurrTexType == type)
+ {
+ mCurrTexture = 0;
+
+ // Always make sure our texture color space is reset to linear. SRGB sampling should be opt-in in the vast majority of cases. Also prevents color space "popping".
+ mTexColorSpace = TCS_LINEAR;
+ if (type == LLTexUnit::TT_TEXTURE)
+ {
+ glBindTexture(sGLTextureType[type], sWhiteTexture);
+ }
+ else
+ {
+ glBindTexture(sGLTextureType[type], 0);
+ }
+ }
+}
+
void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
{
if (mIndex < 0 || mCurrTexture == 0) return;
@@ -1243,8 +1283,6 @@ void LLRender::syncLightState()
void LLRender::syncMatrices()
{
- stop_glerror();
-
static const U32 name[] =
{
LLShaderMgr::MODELVIEW_MATRIX,
@@ -1415,8 +1453,6 @@ void LLRender::syncMatrices()
}
}
}
-
- stop_glerror();
}
void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
@@ -1848,6 +1884,7 @@ LLLightState* LLRender::getLight(U32 index)
void LLRender::setAmbientLightColor(const LLColor4& color)
{
+ LL_PROFILE_ZONE_SCOPED
if (color != mAmbientLightColor)
{
++mLightHash;
@@ -1926,6 +1963,7 @@ void LLRender::flush()
{
if (mCount > 0)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!mUIOffset.empty())
{
sUICalls++;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index af8568f8a3..7f19a45410 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -158,9 +158,20 @@ public:
// Binds the LLImageGL to this texture unit
// (automatically enables the unit for the LLImageGL's texture type)
- bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false);
+ bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false, S32 usename = 0);
bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false);
+ // bind implementation for inner loops
+ // makes the following assumptions:
+ // - No need for gGL.flush()
+ // - texture is not null
+ // - gl_tex->getTexName() is not zero
+ // - This texture is not being bound redundantly
+ // - USE_SRGB_DECODE is disabled
+ // - mTexOptionsDirty is false
+ // -
+ void bindFast(LLTexture* texture);
+
// Binds a cubemap to this texture unit
// (automatically enables the texture unit for cubemaps)
bool bind(LLCubeMap* cubeMap);
@@ -177,6 +188,9 @@ public:
// (only if there's a texture of the given type currently bound)
void unbind(eTextureType type);
+ // Fast but unsafe version of unbind
+ void unbindFast(eTextureType type);
+
// Sets the addressing mode used to sample the texture
// Warning: this stays set for the bound texture forever,
// make sure you want to permanently change the address mode for the bound texture.
@@ -511,7 +525,7 @@ extern F32 gGLLastProjection[16];
extern F32 gGLProjection[16];
extern S32 gGLViewport[4];
-extern LLRender gGL;
+extern thread_local LLRender gGL;
// This rotation matrix moves the default OpenGL reference frame
// (-Z at, Y up) to Cory's favorite reference frame (X at, Z up)
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index dd34f3e383..5a942996be 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -1083,8 +1083,6 @@ void gl_rect_2d_simple( S32 width, S32 height )
gGL.end();
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_SEGMENTED_RECT ("Render segmented rectangle");
-
void gl_segmented_rect_2d_tex(const S32 left,
const S32 top,
const S32 right,
@@ -1094,7 +1092,7 @@ void gl_segmented_rect_2d_tex(const S32 left,
const S32 border_size,
const U32 edges)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SEGMENTED_RECT);
+ LL_PROFILE_ZONE_SCOPED;
S32 width = llabs(right - left);
S32 height = llabs(top - bottom);
@@ -1253,7 +1251,7 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
const F32 end_fragment,
const U32 edges)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SEGMENTED_RECT);
+ LL_PROFILE_ZONE_SCOPED;
const S32 left = rect.mLeft;
const S32 right = rect.mRight;
const S32 top = rect.mTop;
@@ -1440,7 +1438,7 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,
const LLVector3& width_vec, const LLVector3& height_vec)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SEGMENTED_RECT);
+ LL_PROFILE_ZONE_SCOPED;
gGL.begin(LLRender::QUADS);
{
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index e3c0255290..401085a00b 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -437,11 +437,13 @@ void LLRenderTarget::bindTarget()
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3};
+ LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x4000FF )
glDrawBuffersARB(mTex.size(), drawbuffers);
}
if (mTex.empty())
{ //no color buffer to draw to
+ LL_PROFILER_GPU_ZONEC( "gl.DrawBuffer", 0x0000FF )
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
}
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index 41481fb8a7..e890a5a30b 100644
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -42,7 +42,7 @@ class LLFontGL ;
//
//this is an abstract class as the parent for the class LLGLTexture
//
-class LLTexture : public virtual LLRefCount, public LLTrace::MemTrackable<LLTexture>
+class LLTexture : public virtual LLRefCount
{
friend class LLTexUnit ;
friend class LLFontGL ;
@@ -52,7 +52,6 @@ protected:
public:
LLTexture()
- : LLTrace::MemTrackable<LLTexture>("LLTexture")
{}
//
@@ -67,11 +66,9 @@ public:
virtual S32 getWidth(S32 discard_level = -1) const;
virtual S32 getHeight(S32 discard_level = -1) const;
virtual bool isActiveFetching();
+ virtual LLImageGL* getGLTexture() const;
private:
- //note: do not make this function public.
- virtual LLImageGL* getGLTexture() const;
-
virtual void updateBindStatsForTester();
};
#endif
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 7d2b09ca4a..5ea07ddcb1 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -91,6 +91,8 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_
U32 LLVBOPool::sBytesPooled = 0;
U32 LLVBOPool::sIndexBytesPooled = 0;
+U32 LLVBOPool::sNameIdx = 0;
+U32 LLVBOPool::sNamePool[1024];
std::list<U32> LLVertexBuffer::sAvailableVAOName;
U32 LLVertexBuffer::sCurVAOName = 1;
@@ -121,15 +123,20 @@ bool LLVertexBuffer::sPreferStreamDraw = false;
U32 LLVBOPool::genBuffer()
{
- U32 ret = 0;
+ LL_PROFILE_ZONE_SCOPED
- glGenBuffersARB(1, &ret);
-
- return ret;
+ if (sNameIdx == 0)
+ {
+ glGenBuffersARB(1024, sNamePool);
+ sNameIdx = 1024;
+ }
+
+ return sNamePool[--sNameIdx];
}
void LLVBOPool::deleteBuffer(U32 name)
{
+ LL_PROFILE_ZONE_SCOPED
if (gGLManager.mInited)
{
LLVertexBuffer::unbind();
@@ -152,6 +159,7 @@ LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
{
+ LL_PROFILE_ZONE_SCOPED
llassert(vbo_block_size(size) == size);
volatile U8* ret = NULL;
@@ -267,10 +275,12 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
void LLVBOPool::seedPool()
{
+ LL_PROFILE_ZONE_SCOPED
U32 dummy_name = 0;
if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
{
+ LL_PROFILE_ZONE_NAMED("VBOPool Resize");
mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
}
@@ -411,6 +421,7 @@ void LLVertexBuffer::releaseVAOName(U32 name)
//static
void LLVertexBuffer::seedPools()
{
+ LL_PROFILE_ZONE_SCOPED
sStreamVBOPool.seedPool();
sDynamicVBOPool.seedPool();
sDynamicCopyVBOPool.seedPool();
@@ -566,62 +577,22 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
//static
-static LLTrace::BlockTimerStatHandle FTM_VB_DRAW_ARRAYS("drawArrays");
-void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
+void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos)
{
- LL_RECORD_BLOCK_TIME(FTM_VB_DRAW_ARRAYS);
- llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
- gGL.syncMatrices();
-
- U32 count = pos.size();
-
- llassert(norm.size() >= pos.size());
- llassert(count > 0);
-
- if( count == 0 )
- {
- LL_WARNS() << "Called drawArrays with 0 vertices" << LL_ENDL;
- return;
- }
-
- if( norm.size() < pos.size() )
- {
- LL_WARNS() << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << LL_ENDL;
- return;
- }
-
- unbind();
-
- setupClientArrays(MAP_VERTEX | MAP_NORMAL);
-
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
-
- if (shader)
- {
- S32 loc = LLVertexBuffer::TYPE_VERTEX;
- if (loc > -1)
- {
- glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV);
- }
- loc = LLVertexBuffer::TYPE_NORMAL;
- if (loc > -1)
- {
- glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV);
- }
- }
- else
- {
- glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
- glNormalPointer(GL_FLOAT, 0, norm[0].mV);
- }
- LLGLSLShader::startProfile();
- glDrawArrays(sGLMode[mode], 0, count);
- LLGLSLShader::stopProfile(count, mode);
+ LL_PROFILE_ZONE_SCOPED;
+ gGL.begin(mode);
+ for (auto& v : pos)
+ {
+ gGL.vertex3fv(v.mV);
+ }
+ gGL.end();
+ gGL.flush();
}
//static
void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
gGL.syncMatrices();
@@ -634,28 +605,27 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
unbind();
- setupClientArrays(mask);
-
- if (LLGLSLShader::sNoFixedFunction)
- {
- S32 loc = LLVertexBuffer::TYPE_VERTEX;
- glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos);
-
- if (tc)
- {
- loc = LLVertexBuffer::TYPE_TEXCOORD0;
- glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc);
- }
- }
- else
- {
- glTexCoordPointer(2, GL_FLOAT, 0, tc);
- glVertexPointer(3, GL_FLOAT, 16, pos);
- }
-
- LLGLSLShader::startProfile();
- glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp);
- LLGLSLShader::stopProfile(num_indices, mode);
+ gGL.begin(mode);
+
+ if (tc != nullptr)
+ {
+ for (int i = 0; i < num_indices; ++i)
+ {
+ U16 idx = indicesp[i];
+ gGL.texCoord2fv(tc[idx].mV);
+ gGL.vertex3fv(pos[idx].getF32ptr());
+ }
+ }
+ else
+ {
+ for (int i = 0; i < num_indices; ++i)
+ {
+ U16 idx = indicesp[i];
+ gGL.vertex3fv(pos[idx].getF32ptr());
+ }
+ }
+ gGL.end();
+ gGL.flush();
}
void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
@@ -763,6 +733,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
stop_glerror();
LLGLSLShader::startProfile();
+ LL_PROFILER_GPU_ZONEC( "gl.DrawRangeElements", 0xFFFF00 )
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
LLGLSLShader::stopProfile(count, mode);
@@ -773,6 +744,18 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
placeFence();
}
+void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
+{
+ mMappable = false;
+ gGL.syncMatrices();
+
+ U16* idx = ((U16*)(U8*)mAlignedIndexOffset) + indices_offset;
+
+ LL_PROFILER_GPU_ZONEC("gl.DrawRangeElements", 0xFFFF00)
+ glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
+ idx);
+}
+
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
@@ -814,6 +797,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
stop_glerror();
LLGLSLShader::startProfile();
+ LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0xA0FFA0 )
glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
((U16*) getIndicesPointer()) + indices_offset);
LLGLSLShader::stopProfile(count, mode);
@@ -821,53 +805,51 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
placeFence();
}
-static LLTrace::BlockTimerStatHandle FTM_GL_DRAW_ARRAYS("GL draw arrays");
+
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
- llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
- mMappable = false;
- gGL.syncMatrices();
-
- llassert(mNumVerts >= 0);
- if (first >= (U32) mNumVerts ||
- first + count > (U32) mNumVerts)
- {
- LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << LL_ENDL;
- }
-
- if (mGLArray)
- {
- if (mGLArray != sGLRenderArray)
- {
- LL_ERRS() << "Wrong vertex array bound." << LL_ENDL;
- }
- }
- else
- {
- if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
- {
- LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL;
- }
- }
-
- if (mode >= LLRender::NUM_MODES)
- {
- LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL;
- return;
- }
+ LL_PROFILE_ZONE_SCOPED;
+ llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+ mMappable = false;
+ gGL.syncMatrices();
+
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ llassert(mNumVerts >= 0);
+ if (first >= (U32)mNumVerts ||
+ first + count > (U32)mNumVerts)
+ {
+ LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first + count << "]" << LL_ENDL;
+ }
+
+ if (mGLArray)
+ {
+ if (mGLArray != sGLRenderArray)
+ {
+ LL_ERRS() << "Wrong vertex array bound." << LL_ENDL;
+ }
+ }
+ else
+ {
+ if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
+ {
+ LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL;
+ }
+ }
+
+ if (mode >= LLRender::NUM_MODES)
+ {
+ LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL;
+ return;
+ }
+#endif
- {
- LL_RECORD_BLOCK_TIME(FTM_GL_DRAW_ARRAYS);
- stop_glerror();
- LLGLSLShader::startProfile();
- stop_glerror();
- glDrawArrays(sGLMode[mode], first, count);
- stop_glerror();
- LLGLSLShader::stopProfile(count, mode);
- }
+ {
+ LL_PROFILER_GPU_ZONEC("gl.DrawArrays", 0xFF4040)
+ glDrawArrays(sGLMode[mode], first, count);
+ }
- stop_glerror();
- placeFence();
+ stop_glerror();
+ placeFence();
}
//static
@@ -964,8 +946,7 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
}
LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage)
-: LLTrace::MemTrackable<LLVertexBuffer>("LLVertexBuffer"),
- LLRefCount(),
+: LLRefCount(),
mNumVerts(0),
mNumIndices(0),
@@ -1110,9 +1091,7 @@ void LLVertexBuffer::waitFence() const
void LLVertexBuffer::genBuffer(U32 size)
{
- disclaimMem(mSize);
mSize = vbo_block_size(size);
- claimMem(mSize);
if (mUsage == GL_STREAM_DRAW_ARB)
{
@@ -1208,9 +1187,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
static int gl_buffer_idx = 0;
mGLBuffer = ++gl_buffer_idx;
mMappedData = (U8*)ll_aligned_malloc_16(size);
- disclaimMem(mSize);
mSize = size;
- claimMem(mSize);
}
if (!mMappedData)
@@ -1380,8 +1357,6 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
return success;
}
-static LLTrace::BlockTimerStatHandle FTM_SETUP_VERTEX_ARRAY("Setup VAO");
-
void LLVertexBuffer::setupVertexArray()
{
if (!mGLArray)
@@ -1389,7 +1364,7 @@ void LLVertexBuffer::setupVertexArray()
return;
}
- LL_RECORD_BLOCK_TIME(FTM_SETUP_VERTEX_ARRAY);
+ LL_PROFILE_ZONE_SCOPED;
#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
#endif
@@ -1562,12 +1537,11 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
return true;
}
-static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_BUFFER_RANGE("VBO Map Range");
-static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_BUFFER("VBO Map");
// Map for data access
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
{
+ LL_PROFILE_ZONE_SCOPED;
bindGLBuffer(true);
if (mFinal)
{
@@ -1634,7 +1608,6 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
- LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_BUFFER_RANGE);
S32 offset = mOffsets[type] + sTypeSize[type]*index;
S32 length = (sTypeSize[type]*count+0xF) & ~0xF;
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length,
@@ -1658,7 +1631,6 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
}
}
- LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_BUFFER);
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1744,11 +1716,9 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
}
-static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_INDEX_RANGE("IBO Map Range");
-static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_INDEX("IBO Map");
-
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
+ LL_PROFILE_ZONE_SCOPED;
bindGLIndices(true);
if (mFinal)
{
@@ -1823,7 +1793,6 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
- LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX_RANGE);
S32 offset = sizeof(U16)*index;
S32 length = sizeof(U16)*count;
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length,
@@ -1835,7 +1804,6 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
else
{
#ifdef GL_ARB_map_buffer_range
- LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX);
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1859,7 +1827,6 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
}
else
{
- LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX);
map_range = false;
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
@@ -1910,13 +1877,6 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
}
}
-static LLTrace::BlockTimerStatHandle FTM_VBO_UNMAP("VBO Unmap");
-static LLTrace::BlockTimerStatHandle FTM_VBO_FLUSH_RANGE("Flush VBO Range");
-
-
-static LLTrace::BlockTimerStatHandle FTM_IBO_UNMAP("IBO Unmap");
-static LLTrace::BlockTimerStatHandle FTM_IBO_FLUSH_RANGE("Flush IBO Range");
-
void LLVertexBuffer::unmapBuffer()
{
if (!useVBOs())
@@ -1925,10 +1885,10 @@ void LLVertexBuffer::unmapBuffer()
}
bool updated_all = false;
-
+ LL_PROFILE_ZONE_SCOPED;
if (mMappedData && mVertexLocked)
{
- LL_RECORD_BLOCK_TIME(FTM_VBO_UNMAP);
+ LL_PROFILE_ZONE_NAMED("unmapBuffer - vertex");
bindGLBuffer(true);
updated_all = mIndexLocked; //both vertex and index buffers done updating
@@ -1975,7 +1935,7 @@ void LLVertexBuffer::unmapBuffer()
{
if (!mMappedVertexRegions.empty())
{
- stop_glerror();
+ LL_PROFILE_ZONE_NAMED("unmapBuffer - flush vertex");
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
const MappedRegion& region = mMappedVertexRegions[i];
@@ -1983,18 +1943,16 @@ void LLVertexBuffer::unmapBuffer()
S32 length = sTypeSize[region.mType]*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
- LL_RECORD_BLOCK_TIME(FTM_VBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
#endif
}
else if (gGLManager.mHasFlushBufferRange)
- {
+ {
#ifndef LL_MESA_HEADLESS
glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length);
#endif
}
- stop_glerror();
}
mMappedVertexRegions.clear();
@@ -2013,7 +1971,7 @@ void LLVertexBuffer::unmapBuffer()
if (mMappedIndexData && mIndexLocked)
{
- LL_RECORD_BLOCK_TIME(FTM_IBO_UNMAP);
+ LL_PROFILE_ZONE_NAMED("unmapBuffer - index");
bindGLIndices();
if(!mMappable)
{
@@ -2059,12 +2017,12 @@ void LLVertexBuffer::unmapBuffer()
{
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
+ LL_PROFILE_ZONE_NAMED("unmapBuffer - flush index");
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
- LL_RECORD_BLOCK_TIME(FTM_IBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
#endif
@@ -2083,9 +2041,8 @@ void LLVertexBuffer::unmapBuffer()
mMappedIndexRegions.clear();
}
}
- stop_glerror();
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
- stop_glerror();
+
+ glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
mMappedIndexData = NULL;
}
@@ -2208,13 +2165,12 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in
//----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_BIND_GL_ARRAY("Bind Array");
bool LLVertexBuffer::bindGLArray()
{
if (mGLArray && sGLRenderArray != mGLArray)
{
{
- LL_RECORD_BLOCK_TIME(FTM_BIND_GL_ARRAY);
+ LL_PROFILE_ZONE_SCOPED;
#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
#endif
@@ -2231,8 +2187,6 @@ bool LLVertexBuffer::bindGLArray()
return false;
}
-static LLTrace::BlockTimerStatHandle FTM_BIND_GL_BUFFER("Bind Buffer");
-
bool LLVertexBuffer::bindGLBuffer(bool force_bind)
{
bindGLArray();
@@ -2241,8 +2195,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
{
- //LL_RECORD_BLOCK_TIME(FTM_BIND_GL_BUFFER);
-
+ LL_PROFILE_ZONE_SCOPED;
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
sBindCount++;
@@ -2256,16 +2209,29 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
return ret;
}
-static LLTrace::BlockTimerStatHandle FTM_BIND_GL_INDICES("Bind Indices");
+bool LLVertexBuffer::bindGLBufferFast()
+{
+ if (mGLBuffer != sGLRenderBuffer || !sVBOActive)
+ {
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
+ sGLRenderBuffer = mGLBuffer;
+ sBindCount++;
+ sVBOActive = true;
+
+ return true;
+ }
+
+ return false;
+}
bool LLVertexBuffer::bindGLIndices(bool force_bind)
{
+ LL_PROFILE_ZONE_SCOPED;
bindGLArray();
bool ret = false;
if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))))
{
- LL_RECORD_BLOCK_TIME(FTM_BIND_GL_INDICES);
/*if (sMapped)
{
LL_ERRS() << "VBO bound while another VBO mapped!" << LL_ENDL;
@@ -2281,6 +2247,21 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)
return ret;
}
+bool LLVertexBuffer::bindGLIndicesFast()
+{
+ if (mGLIndices != sGLRenderIndices || !sIBOActive)
+ {
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
+ sGLRenderIndices = mGLIndices;
+ sBindCount++;
+ sIBOActive = true;
+
+ return true;
+ }
+
+ return false;
+}
+
void LLVertexBuffer::flush()
{
if (useVBOs())
@@ -2471,6 +2452,26 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
}
}
+void LLVertexBuffer::setBufferFast(U32 data_mask)
+{
+ //set up pointers if the data mask is different ...
+ bool setup = (sLastMask != data_mask);
+
+
+ const bool bindBuffer = bindGLBufferFast();
+ const bool bindIndices = bindGLIndicesFast();
+
+ setup = setup || bindBuffer || bindIndices;
+
+ setupClientArrays(data_mask);
+
+ if (data_mask && setup)
+ {
+ setupVertexBufferFast(data_mask);
+ sSetCount++;
+ }
+}
+
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
@@ -2628,6 +2629,99 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
llglassertok();
}
+void LLVertexBuffer::setupVertexBufferFast(U32 data_mask)
+{
+ U8* base = (U8*)mAlignedOffset;
+
+ if (data_mask & MAP_NORMAL)
+ {
+ S32 loc = TYPE_NORMAL;
+ void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]);
+ glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD3)
+ {
+ S32 loc = TYPE_TEXCOORD3;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
+ glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD2)
+ {
+ S32 loc = TYPE_TEXCOORD2;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
+ glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD1)
+ {
+ S32 loc = TYPE_TEXCOORD1;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
+ glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
+ }
+ if (data_mask & MAP_TANGENT)
+ {
+ S32 loc = TYPE_TANGENT;
+ void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD0)
+ {
+ S32 loc = TYPE_TEXCOORD0;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
+ glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
+ }
+ if (data_mask & MAP_COLOR)
+ {
+ S32 loc = TYPE_COLOR;
+ //bind emissive instead of color pointer if emissive is present
+ void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
+ }
+ if (data_mask & MAP_EMISSIVE)
+ {
+ S32 loc = TYPE_EMISSIVE;
+ void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+
+ if (!(data_mask & MAP_COLOR))
+ { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
+ loc = TYPE_COLOR;
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ }
+ }
+ if (data_mask & MAP_WEIGHT)
+ {
+ S32 loc = TYPE_WEIGHT;
+ void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
+ glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
+ }
+ if (data_mask & MAP_WEIGHT4)
+ {
+ S32 loc = TYPE_WEIGHT4;
+ void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
+ }
+ if (data_mask & MAP_CLOTHWEIGHT)
+ {
+ S32 loc = TYPE_CLOTHWEIGHT;
+ void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
+ }
+ if (data_mask & MAP_TEXTURE_INDEX)
+ {
+#if !LL_DARWIN
+ S32 loc = TYPE_TEXTURE_INDEX;
+ void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12);
+ glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+#endif
+ }
+ if (data_mask & MAP_VERTEX)
+ {
+ S32 loc = TYPE_VERTEX;
+ void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
+ glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+ }
+}
+
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
{
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index dbe1a3687f..1b400b3aad 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -89,13 +89,16 @@ public:
std::vector<record_list_t> mFreeList;
std::vector<U32> mMissCount;
+ //used to avoid calling glGenBuffers for every VBO creation
+ static U32 sNamePool[1024];
+ static U32 sNameIdx;
};
//============================================================================
// base class
class LLPrivateMemoryPool;
-class LLVertexBuffer : public LLRefCount, public LLTrace::MemTrackable<LLVertexBuffer>
+class LLVertexBuffer : public LLRefCount
{
public:
class MappedRegion
@@ -110,8 +113,7 @@ public:
};
LLVertexBuffer(const LLVertexBuffer& rhs)
- : LLTrace::MemTrackable<LLVertexBuffer>("LLVertexBuffer"),
- mUsage(rhs.mUsage)
+ : mUsage(rhs.mUsage)
{
*this = rhs;
}
@@ -127,7 +129,7 @@ public:
static LLVBOPool sDynamicCopyVBOPool;
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
-
+
static std::list<U32> sAvailableVAOName;
static U32 sCurVAOName;
@@ -143,8 +145,7 @@ public:
static void initClass(bool use_vbo, bool no_vbo_mapping);
static void cleanupClass();
static void setupClientArrays(U32 data_mask);
- static void pushPositions(U32 mode, const LLVector4a* pos, U32 count);
- static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
+ static void drawArrays(U32 mode, const std::vector<LLVector3>& pos);
static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
static void unbind(); //unbind any bound vertex buffer
@@ -207,13 +208,17 @@ protected:
virtual ~LLVertexBuffer(); // use unref()
- virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer()
+ virtual void setupVertexBuffer(U32 data_mask);
+ void setupVertexBufferFast(U32 data_mask);
+
void setupVertexArray();
void genBuffer(U32 size);
void genIndices(U32 size);
bool bindGLBuffer(bool force_bind = false);
+ bool bindGLBufferFast();
bool bindGLIndices(bool force_bind = false);
+ bool bindGLIndicesFast();
bool bindGLArray();
void releaseBuffer();
void releaseIndices();
@@ -236,6 +241,8 @@ public:
// set for rendering
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
+ void setBufferFast(U32 data_mask); // calls setupVertexBufferFast(), assumes data_mask is not 0 among other assumptions
+
void flush(); //flush pending data to GL memory
// allocate buffer
bool allocateBuffer(S32 nverts, S32 nindices, bool create);
@@ -287,6 +294,9 @@ public:
void drawArrays(U32 mode, U32 offset, U32 count) const;
void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
+ //implementation for inner loops that does no safety checking
+ void drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
+
//for debugging, validate data in given range is valid
void validateRange(U32 start, U32 end, U32 count, U32 offset) const;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 0e42922543..03efd09689 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -3268,11 +3268,9 @@ boost::signals2::connection LLFloater::setCloseCallback( const commit_signal_t::
return mCloseSignal.connect(cb);
}
-LLTrace::BlockTimerStatHandle POST_BUILD("Floater Post Build");
-static LLTrace::BlockTimerStatHandle FTM_EXTERNAL_FLOATER_LOAD("Load Extern Floater Reference");
-
bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node)
{
+ LL_PROFILE_ZONE_SCOPED;
Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>());
Params params(default_params);
@@ -3299,7 +3297,6 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
LLUICtrlFactory::instance().pushFileName(xml_filename);
- LL_RECORD_BLOCK_TIME(FTM_EXTERNAL_FLOATER_LOAD);
if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml))
{
LL_WARNS() << "Couldn't parse panel from: " << xml_filename << LL_ENDL;
@@ -3375,12 +3372,8 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
}
BOOL result;
- {
- LL_RECORD_BLOCK_TIME(POST_BUILD);
-
- result = postBuild();
- }
-
+ result = postBuild();
+
if (!result)
{
LL_ERRS() << "Failed to construct floater " << getName() << LL_ENDL;
@@ -3424,11 +3417,9 @@ bool LLFloater::isVisible(const LLFloater* floater)
return floater && floater->getVisible();
}
-static LLTrace::BlockTimerStatHandle FTM_BUILD_FLOATERS("Build Floaters");
-
bool LLFloater::buildFromFile(const std::string& filename)
{
- LL_RECORD_BLOCK_TIME(FTM_BUILD_FLOATERS);
+ LL_PROFILE_ZONE_SCOPED;
LLXMLNodePtr root;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 2672d600c6..306760b7fb 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -346,6 +346,8 @@ public:
// handle refocusing.
static void closeFrontmostFloater();
+ static bool isQuitRequested() { return sQuitting; }
+
// LLNotification::Params contextualNotification(const std::string& name)
// {
// return LLNotification::Params(name).context(mNotificationContext);
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 622c9edba7..0996e82bf7 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -189,7 +189,6 @@ LLFolderView::LLFolderView(const Params& p)
mViewModel(p.view_model),
mGroupedItemModel(p.grouped_item_model)
{
- claimMem(mViewModel);
LLPanel* panel = p.parent_panel;
mParentPanel = panel->getHandle();
mViewModel->setFolderView(this);
@@ -337,11 +336,9 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height )
return ll_round(mTargetHeight);
}
-static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View");
-
void LLFolderView::filter( LLFolderViewFilter& filter )
{
- LL_RECORD_BLOCK_TIME(FTM_FILTER);
+ LL_PROFILE_ZONE_SCOPED;
static LLCachedControl<S32> time_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
static LLCachedControl<S32> time_invisible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
filter.resetTime(llclamp((mParentPanel.get()->getVisible() ? time_visible() : time_invisible()), 1, 100));
@@ -503,10 +500,9 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
return rv;
}
-static LLTrace::BlockTimerStatHandle FTM_SANITIZE_SELECTION("Sanitize Selection");
void LLFolderView::sanitizeSelection()
{
- LL_RECORD_BLOCK_TIME(FTM_SANITIZE_SELECTION);
+ LL_PROFILE_ZONE_SCOPED;
// store off current item in case it is automatically deselected
// and we want to preserve context
LLFolderViewItem* original_selected_item = getCurSelectedItem();
@@ -1621,7 +1617,6 @@ void LLFolderView::setShowSingleSelection(bool show)
}
}
-static LLTrace::BlockTimerStatHandle FTM_AUTO_SELECT("Open and Select");
static LLTrace::BlockTimerStatHandle FTM_INVENTORY("Inventory");
// Main idle routine
@@ -1657,7 +1652,6 @@ void LLFolderView::update()
// automatically show matching items, and select first one if we had a selection
if (mNeedsAutoSelect)
{
- LL_RECORD_BLOCK_TIME(FTM_AUTO_SELECT);
// select new item only if a filtered item not currently selected and there was a selection
LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
if (!mAutoSelectOverride && selected_itemp && !selected_itemp->getViewModelItem()->potentiallyVisible())
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index e62b2779dd..093e213be3 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -108,11 +108,10 @@ public:
virtual S32 getFirstRequiredGeneration() const = 0;
};
-class LLFolderViewModelInterface : public LLTrace::MemTrackable<LLFolderViewModelInterface>
+class LLFolderViewModelInterface
{
public:
LLFolderViewModelInterface()
- : LLTrace::MemTrackable<LLFolderViewModelInterface>("LLFolderViewModelInterface")
{}
virtual ~LLFolderViewModelInterface() {}
@@ -133,11 +132,10 @@ public:
// This is an abstract base class that users of the folderview classes
// would use to bridge the folder view with the underlying data
-class LLFolderViewModelItem : public LLRefCount, public LLTrace::MemTrackable<LLFolderViewModelItem>
+class LLFolderViewModelItem : public LLRefCount
{
public:
LLFolderViewModelItem()
- : LLTrace::MemTrackable<LLFolderViewModelItem>("LLFolderViewModelItem")
{}
virtual ~LLFolderViewModelItem() { }
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 29a156e933..528d2e70ad 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -340,8 +340,6 @@ void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed)
mNeedsLayout = true;
}
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_LAYOUT("Update LayoutStacks");
-
class LLImagePanel : public LLPanel
{
public:
@@ -369,7 +367,7 @@ private:
void LLLayoutStack::updateLayout()
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_LAYOUT);
+ LL_PROFILE_ZONE_SCOPED;
if (!mNeedsLayout) return;
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index b791a19c2b..88eda1c172 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1387,7 +1387,7 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)
LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName)
{
- return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName));
+ return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName).get());
}
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 00da0f5fec..f770920c4a 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -800,14 +800,12 @@ boost::signals2::connection LLPanel::setVisibleCallback( const commit_signal_t::
return mVisibleSignal->connect(cb);
}
-static LLTrace::BlockTimerStatHandle FTM_BUILD_PANELS("Build Panels");
-
//-----------------------------------------------------------------------------
// buildPanel()
//-----------------------------------------------------------------------------
BOOL LLPanel::buildFromFile(const std::string& filename, const LLPanel::Params& default_params)
{
- LL_RECORD_BLOCK_TIME(FTM_BUILD_PANELS);
+ LL_PROFILE_ZONE_SCOPED;
BOOL didPost = FALSE;
LLXMLNodePtr root;
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index de644185fd..c70085b72f 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -3045,10 +3045,9 @@ LLScrollListColumn* LLScrollListCtrl::getColumn(const std::string& name)
return NULL;
}
-LLTrace::BlockTimerStatHandle FTM_ADD_SCROLLLIST_ELEMENT("Add Scroll List Item");
LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata)
{
- LL_RECORD_BLOCK_TIME(FTM_ADD_SCROLLLIST_ELEMENT);
+ LL_PROFILE_ZONE_SCOPED;
LLScrollListItem::Params item_params;
LLParamSDParser parser;
parser.readSD(element, item_params);
@@ -3058,14 +3057,14 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& element, EAddPosition
LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_p, EAddPosition pos)
{
- LL_RECORD_BLOCK_TIME(FTM_ADD_SCROLLLIST_ELEMENT);
+ LL_PROFILE_ZONE_SCOPED;
LLScrollListItem *new_item = new LLScrollListItem(item_p);
return addRow(new_item, item_p, pos);
}
LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLScrollListItem::Params& item_p, EAddPosition pos)
{
- LL_RECORD_BLOCK_TIME(FTM_ADD_SCROLLLIST_ELEMENT);
+ LL_PROFILE_ZONE_SCOPED;
if (!item_p.validateBlock() || !new_item) return NULL;
new_item->setNumColumns(mColumns.size());
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index 6c8e63442b..2449100952 100644
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -160,6 +160,7 @@ LLStatBar::Params::Params()
tick_spacing("tick_spacing", 0.f),
decimal_digits("decimal_digits", 3),
show_bar("show_bar", false),
+ show_median("show_median", false),
show_history("show_history", false),
scale_range("scale_range", true),
num_frames("num_frames", 200),
@@ -186,6 +187,7 @@ LLStatBar::LLStatBar(const Params& p)
mNumShortHistoryFrames(p.num_frames_short),
mMaxHeight(p.max_height),
mDisplayBar(p.show_bar),
+ mShowMedian(p.show_median),
mDisplayHistory(p.show_history),
mOrientation(p.orientation),
mAutoScaleMax(!p.bar_max.isProvided()),
@@ -318,7 +320,14 @@ void LLStatBar::draw()
min = frame_recording.getPeriodMinPerSec(count_stat, num_frames);
max = frame_recording.getPeriodMaxPerSec(count_stat, num_frames);
mean = frame_recording.getPeriodMeanPerSec(count_stat, num_frames);
- display_value = mean;
+ if (mShowMedian)
+ {
+ display_value = frame_recording.getPeriodMedianPerSec(count_stat, num_frames);
+ }
+ else
+ {
+ display_value = mean;
+ }
}
break;
case STAT_EVENT:
@@ -344,7 +353,11 @@ void LLStatBar::draw()
mean = frame_recording.getPeriodMean(sample_stat, num_frames);
num_rapid_changes = calc_num_rapid_changes(frame_recording, sample_stat, RAPID_CHANGE_WINDOW);
- if (num_rapid_changes / RAPID_CHANGE_WINDOW.value() > MAX_RAPID_CHANGES_PER_SEC)
+ if (mShowMedian)
+ {
+ display_value = frame_recording.getPeriodMedian(sample_stat, num_frames);
+ }
+ else if (num_rapid_changes / RAPID_CHANGE_WINDOW.value() > MAX_RAPID_CHANGES_PER_SEC)
{
display_value = mean;
}
@@ -554,29 +567,25 @@ void LLStatBar::draw()
void LLStatBar::setStat(const std::string& stat_name)
{
using namespace LLTrace;
- const StatType<CountAccumulator>* count_stat;
- const StatType<EventAccumulator>* event_stat;
- const StatType<SampleAccumulator>* sample_stat;
- const StatType<MemAccumulator>* mem_stat;
- if ((count_stat = StatType<CountAccumulator>::getInstance(stat_name)))
+ if (auto count_stat = StatType<CountAccumulator>::getInstance(stat_name))
{
- mStat.countStatp = count_stat;
+ mStat.countStatp = count_stat.get();
mStatType = STAT_COUNT;
}
- else if ((event_stat = StatType<EventAccumulator>::getInstance(stat_name)))
+ else if (auto event_stat = StatType<EventAccumulator>::getInstance(stat_name))
{
- mStat.eventStatp = event_stat;
+ mStat.eventStatp = event_stat.get();
mStatType = STAT_EVENT;
}
- else if ((sample_stat = StatType<SampleAccumulator>::getInstance(stat_name)))
+ else if (auto sample_stat = StatType<SampleAccumulator>::getInstance(stat_name))
{
- mStat.sampleStatp = sample_stat;
+ mStat.sampleStatp = sample_stat.get();
mStatType = STAT_SAMPLE;
}
- else if ((mem_stat = StatType<MemAccumulator>::getInstance(stat_name)))
+ else if (auto mem_stat = StatType<MemAccumulator>::getInstance(stat_name))
{
- mStat.memStatp = mem_stat;
+ mStat.memStatp = mem_stat.get();
mStatType = STAT_MEM;
}
}
diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h
index 1ff4c67fc5..6b481ca68f 100644
--- a/indra/llui/llstatbar.h
+++ b/indra/llui/llstatbar.h
@@ -44,9 +44,10 @@ public:
bar_max,
tick_spacing;
- Optional<bool> show_bar,
+ Optional<bool> show_bar,
show_history,
- scale_range;
+ scale_range,
+ show_median; // default is mean
Optional<S32> decimal_digits,
num_frames,
@@ -112,6 +113,7 @@ private:
bool mDisplayBar, // Display the bar graph.
mDisplayHistory,
+ mShowMedian,
mAutoScaleMax,
mAutoScaleMin;
};
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 05788f1b6c..3b0789892f 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1490,11 +1490,9 @@ S32 LLTextBase::getLeftOffset(S32 width)
}
}
-
-static LLTrace::BlockTimerStatHandle FTM_TEXT_REFLOW ("Text Reflow");
void LLTextBase::reflow()
{
- LL_RECORD_BLOCK_TIME(FTM_TEXT_REFLOW);
+ LL_PROFILE_ZONE_SCOPED;
updateSegments();
@@ -1839,10 +1837,9 @@ void LLTextBase::removeDocumentChild(LLView* view)
}
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_TEXT_SEGMENTS("Update Text Segments");
void LLTextBase::updateSegments()
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_TEXT_SEGMENTS);
+ LL_PROFILE_ZONE_SCOPED;
createDefaultSegment();
}
@@ -2102,19 +2099,16 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name)
}
}
-static LLTrace::BlockTimerStatHandle FTM_PARSE_HTML("Parse HTML");
-
-
void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params)
{
+ LL_PROFILE_ZONE_SCOPED;
LLStyle::Params style_params(input_params);
style_params.fillFrom(getStyleParams());
S32 part = (S32)LLTextParser::WHOLE;
if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358).
{
- LL_RECORD_BLOCK_TIME(FTM_PARSE_HTML);
S32 start=0,end=0;
LLUrlMatch match;
std::string text = new_text;
@@ -2208,11 +2202,9 @@ void LLTextBase::setLastSegmentToolTip(const std::string &tooltip)
}
}
-static LLTrace::BlockTimerStatHandle FTM_APPEND_TEXT("Append Text");
-
void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
{
- LL_RECORD_BLOCK_TIME(FTM_APPEND_TEXT);
+ LL_PROFILE_ZONE_SCOPED;
if (new_text.empty())
return;
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 5924542a19..51391bb5e8 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -121,7 +121,6 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
mDoubleClickSignal(NULL),
mTransparencyType(TT_DEFAULT)
{
- claimMem(viewmodel.get());
}
void LLUICtrl::initFromParams(const Params& p)
@@ -476,6 +475,7 @@ LLViewModel* LLUICtrl::getViewModel() const
//virtual
BOOL LLUICtrl::postBuild()
{
+ LL_PROFILE_ZONE_SCOPED;
//
// Find all of the children that want to be in front and move them to the front
//
@@ -781,12 +781,9 @@ BOOL LLUICtrl::getIsChrome() const
}
-
-LLTrace::BlockTimerStatHandle FTM_FOCUS_FIRST_ITEM("Focus First Item");
-
BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash)
{
- LL_RECORD_BLOCK_TIME(FTM_FOCUS_FIRST_ITEM);
+ LL_PROFILE_ZONE_SCOPED;
// try to select default tab group child
LLViewQuery query = getTabOrderQuery();
child_list_t result = query(this);
@@ -1005,7 +1002,6 @@ boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (L
boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb )
{
if (!mValidateSignal) mValidateSignal = new enable_signal_t();
- claimMem(mValidateSignal);
return mValidateSignal->connect(boost::bind(cb, _2));
}
@@ -1070,7 +1066,6 @@ boost::signals2::connection LLUICtrl::setValidateCallback(const EnableCallbackPa
boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb )
{
if (!mCommitSignal) mCommitSignal = new commit_signal_t();
- claimMem(mCommitSignal);
return mCommitSignal->connect(cb);
}
@@ -1078,7 +1073,6 @@ boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::
boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t::slot_type& cb )
{
if (!mValidateSignal) mValidateSignal = new enable_signal_t();
- claimMem(mValidateSignal);
return mValidateSignal->connect(cb);
}
@@ -1086,7 +1080,6 @@ boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t
boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal_t::slot_type& cb )
{
if (!mMouseEnterSignal) mMouseEnterSignal = new commit_signal_t();
- claimMem(mMouseEnterSignal);
return mMouseEnterSignal->connect(cb);
}
@@ -1094,7 +1087,6 @@ boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal
boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal_t::slot_type& cb )
{
if (!mMouseLeaveSignal) mMouseLeaveSignal = new commit_signal_t();
- claimMem(mMouseLeaveSignal);
return mMouseLeaveSignal->connect(cb);
}
@@ -1102,7 +1094,6 @@ boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal
boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t::slot_type& cb )
{
if (!mMouseDownSignal) mMouseDownSignal = new mouse_signal_t();
- claimMem(mMouseDownSignal);
return mMouseDownSignal->connect(cb);
}
@@ -1110,7 +1101,6 @@ boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t
boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t::slot_type& cb )
{
if (!mMouseUpSignal) mMouseUpSignal = new mouse_signal_t();
- claimMem(mMouseUpSignal);
return mMouseUpSignal->connect(cb);
}
@@ -1118,7 +1108,6 @@ boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t::
boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_signal_t::slot_type& cb )
{
if (!mRightMouseDownSignal) mRightMouseDownSignal = new mouse_signal_t();
- claimMem(mRightMouseDownSignal);
return mRightMouseDownSignal->connect(cb);
}
@@ -1126,7 +1115,6 @@ boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_sig
boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signal_t::slot_type& cb )
{
if (!mRightMouseUpSignal) mRightMouseUpSignal = new mouse_signal_t();
- claimMem(mRightMouseUpSignal);
return mRightMouseUpSignal->connect(cb);
}
@@ -1134,7 +1122,6 @@ boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signa
boost::signals2::connection LLUICtrl::setDoubleClickCallback( const mouse_signal_t::slot_type& cb )
{
if (!mDoubleClickSignal) mDoubleClickSignal = new mouse_signal_t();
- claimMem(mDoubleClickSignal);
return mDoubleClickSignal->connect(cb);
}
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index fdefae01b1..2d0c0ea8aa 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -44,10 +44,6 @@
// this library includes
#include "llpanel.h"
-LLTrace::BlockTimerStatHandle FTM_WIDGET_CONSTRUCTION("Widget Construction");
-LLTrace::BlockTimerStatHandle FTM_INIT_FROM_PARAMS("Widget InitFromParams");
-LLTrace::BlockTimerStatHandle FTM_WIDGET_SETUP("Widget Setup");
-
//-----------------------------------------------------------------------------
// UI Ctrl class for padding
@@ -117,12 +113,10 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa
}
}
-static LLTrace::BlockTimerStatHandle FTM_CREATE_CHILDREN("Create XUI Children");
-
//static
void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t& registry, LLXMLNodePtr output_node)
{
- LL_RECORD_BLOCK_TIME(FTM_CREATE_CHILDREN);
+ LL_PROFILE_ZONE_SCOPED;
if (node.isNull()) return;
for (LLXMLNodePtr child_node = node->getFirstChild(); child_node.notNull(); child_node = child_node->getNextSibling())
@@ -159,14 +153,13 @@ void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const wid
}
-static LLTrace::BlockTimerStatHandle FTM_XML_PARSE("XML Reading/Parsing");
//-----------------------------------------------------------------------------
// getLayeredXMLNode()
//-----------------------------------------------------------------------------
bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root,
LLDir::ESkinConstraint constraint)
{
- LL_RECORD_BLOCK_TIME(FTM_XML_PARSE);
+ LL_PROFILE_ZONE_SCOPED;
std::vector<std::string> paths =
gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename, constraint);
@@ -191,11 +184,9 @@ S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_CREATE_FROM_XML("Create child widget");
-
LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t& registry, LLXMLNodePtr output_node)
{
- LL_RECORD_BLOCK_TIME(FTM_CREATE_FROM_XML);
+ LL_PROFILE_ZONE_SCOPED;
std::string ctrl_type = node->getName()->mString;
LLStringUtil::toLower(ctrl_type);
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 135ed57a4f..3f24a3f1a5 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -79,10 +79,6 @@ class LLWidgetNameRegistry
// LLSINGLETON(LLDefaultParamBlockRegistry);
//};
-extern LLTrace::BlockTimerStatHandle FTM_WIDGET_SETUP;
-extern LLTrace::BlockTimerStatHandle FTM_WIDGET_CONSTRUCTION;
-extern LLTrace::BlockTimerStatHandle FTM_INIT_FROM_PARAMS;
-
// Build time optimization, generate this once in .cpp file
#ifndef LLUICTRLFACTORY_CPP
extern template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getInstance();
@@ -213,6 +209,7 @@ private:
template<typename T>
static T* createWidgetImpl(const typename T::Params& params, LLView* parent = NULL)
{
+ LL_PROFILE_ZONE_SCOPED;
T* widget = NULL;
if (!params.validateBlock())
@@ -221,12 +218,9 @@ private:
//return NULL;
}
- { LL_RECORD_BLOCK_TIME(FTM_WIDGET_CONSTRUCTION);
- widget = new T(params);
- }
- { LL_RECORD_BLOCK_TIME(FTM_INIT_FROM_PARAMS);
- widget->initFromParams(params);
- }
+ widget = new T(params);
+
+ widget->initFromParams(params);
if (parent)
{
@@ -239,7 +233,7 @@ private:
template<typename T>
static T* defaultBuilder(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
{
- LL_RECORD_BLOCK_TIME(FTM_WIDGET_SETUP);
+ LL_PROFILE_ZONE_SCOPED;
typename T::Params params(getDefaultParams<T>());
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index b942be2a4a..bd0b9d3db2 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -140,8 +140,7 @@ LLView::Params::Params()
}
LLView::LLView(const LLView::Params& p)
-: LLTrace::MemTrackable<LLView>("LLView"),
- mVisible(p.visible),
+: mVisible(p.visible),
mInDraw(false),
mName(p.name),
mParentView(NULL),
@@ -1597,15 +1596,11 @@ LLView* LLView::getChildView(const std::string& name, BOOL recurse) const
return getChild<LLView>(name, recurse);
}
-static LLTrace::BlockTimerStatHandle FTM_FIND_VIEWS("Find Widgets");
-
LLView* LLView::findChildView(const std::string& name, BOOL recurse) const
{
- LL_RECORD_BLOCK_TIME(FTM_FIND_VIEWS);
- //richard: should we allow empty names?
- //if(name.empty())
- // return NULL;
- // Look for direct children *first*
+ LL_PROFILE_ZONE_SCOPED;
+
+ // Look for direct children *first*
BOOST_FOREACH(LLView* childp, mChildList)
{
llassert(childp);
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index c60dcf3344..bec45df78a 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -100,8 +100,7 @@ class LLView
: public LLMouseHandler, // handles mouse events
public LLFocusableElement, // handles keyboard events
public LLMortician, // lazy deletion
- public LLHandleProvider<LLView>, // passes out weak references to self
- public LLTrace::MemTrackable<LLView> // track memory usage
+ public LLHandleProvider<LLView> // passes out weak references to self
{
public:
diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp
index cb000aef74..5a44ec947a 100644
--- a/indra/llui/llviewereventrecorder.cpp
+++ b/indra/llui/llviewereventrecorder.cpp
@@ -28,6 +28,8 @@
#include "llui.h"
#include "llleap.h"
+LLViewerEventRecorder* LLSimpleton<LLViewerEventRecorder>::sInstance = nullptr;
+
LLViewerEventRecorder::LLViewerEventRecorder() {
clear(UNDEFINED);
diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h
index d1059d55de..d2c0780361 100644
--- a/indra/llui/llviewereventrecorder.h
+++ b/indra/llui/llviewereventrecorder.h
@@ -42,12 +42,12 @@
#include "llsingleton.h" // includes llerror which we need here so we can skip the include here
-class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder>
+class LLViewerEventRecorder : public LLSimpleton<LLViewerEventRecorder>
{
- LLSINGLETON(LLViewerEventRecorder);
- ~LLViewerEventRecorder();
-
- public:
+public:
+ LLViewerEventRecorder();
+ ~LLViewerEventRecorder();
+
void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y, std::string mName);
void setMouseLocalCoords(S32 x,S32 y);
void setMouseGlobalCoords(S32 x,S32 y);
diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp
index 282addf692..a400eb70c0 100644
--- a/indra/llui/llviewmodel.cpp
+++ b/indra/llui/llviewmodel.cpp
@@ -37,15 +37,13 @@
///
LLViewModel::LLViewModel()
-: LLTrace::MemTrackable<LLViewModel>("LLViewModel"),
- mDirty(false)
+: mDirty(false)
{
}
/// Instantiate an LLViewModel with an existing data value
LLViewModel::LLViewModel(const LLSD& value)
-: LLTrace::MemTrackable<LLViewModel>("LLViewModel"),
- mDirty(false)
+: mDirty(false)
{
setValue(value);
}
@@ -82,15 +80,9 @@ LLTextViewModel::LLTextViewModel(const LLSD& value)
void LLTextViewModel::setValue(const LLSD& value)
{
// approximate LLSD storage usage
- disclaimMem(mDisplay.size());
LLViewModel::setValue(value);
- disclaimMem(mDisplay);
mDisplay = utf8str_to_wstring(value.asString());
- claimMem(mDisplay);
- // approximate LLSD storage usage
- claimMem(mDisplay.size());
-
// mDisplay and mValue agree
mUpdateFromDisplay = false;
}
@@ -101,12 +93,8 @@ void LLTextViewModel::setDisplay(const LLWString& value)
// and do the utf8str_to_wstring() to get the corresponding mDisplay
// value. But a text editor might want to edit the display string
// directly, then convert back to UTF8 on commit.
- disclaimMem(mDisplay.size());
- disclaimMem(mDisplay);
- mDisplay = value;
- claimMem(mDisplay);
- claimMem(mDisplay.size());
- mDirty = true;
+ mDisplay = value;
+ mDirty = true;
// Don't immediately convert to UTF8 -- do it lazily -- we expect many
// more setDisplay() calls than getValue() calls. Just flag that it needs
// doing.
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
index 49d7c322a3..e7dceb6c31 100644
--- a/indra/llui/llviewmodel.h
+++ b/indra/llui/llviewmodel.h
@@ -62,8 +62,7 @@ typedef LLPointer<LLListViewModel> LLListViewModelPtr;
* last referencing widget is destroyed.
*/
class LLViewModel
-: public LLRefCount,
- public LLTrace::MemTrackable<LLViewModel>
+: public LLRefCount
{
public:
LLViewModel();
diff --git a/indra/llwindow/GL/glh_extensions.h b/indra/llwindow/GL/glh_extensions.h
deleted file mode 100644
index 554cb1731f..0000000000
--- a/indra/llwindow/GL/glh_extensions.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * glh_extensions.h
- * $LicenseInfo:firstyear=2006&license=mit$ (mit used here to satisfy validity checker)
- * Copyright (C) 2006, NVIDIA
- * From nVidia Corporation, downloaded 2006-12-18 from:
- * http://developer.nvidia.com/attach/8196
- * ("NVParse Library with Source (.zip) (2390 KB)")
- *
- * License (quoted from license_info.txt in aforementioned file):
- * "The files bison.exe, bison.simple, and flex.exe are covered by
- * the GPL. All other files in this distribution can be used however
- * you want."
- * $/LicenseInfo$
-
- */
-
-#ifndef GLH_EXTENSIONS
-#define GLH_EXTENSIONS
-
-#include <string.h>
-#include <stdio.h>
-
-#ifdef _WIN32
-# include <windows.h>
-#endif
-
-#ifndef __APPLE__
-#include <GL/gl.h>
-#endif
-
-#ifdef _WIN32
-# include "GL/wglext.h"
-#endif
-
-#define CHECK_MEMORY(ptr) \
- if (NULL == ptr) { \
- printf("Error allocating memory in file %s, line %d\n", __FILE__, __LINE__); \
- exit(-1); \
- }
-
-#ifdef GLH_EXT_SINGLE_FILE
-# define GLH_EXTENSIONS_SINGLE_FILE // have to do this because glh_genext.h unsets GLH_EXT_SINGLE_FILE
-#endif
-
-#include "glh_genext.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef GLH_EXTENSIONS_SINGLE_FILE
-
-class GLHExts
-{
-public:
- GLHExts()
- {
- mSysExts = NULL;
-// mUnsupportedExts = NULL;
- }
- ~GLHExts()
- {
- if (mSysExts)
- {
- free(mSysExts);
- }
-// if (mUnsupportedExts)
-// {
-// free(mUnsupportedExts);
-// }
- }
- char *mSysExts;
-// char *mUnsupportedExts;
-};
-
-GLHExts gGLHExts;
-
-static int ExtensionExists(const char* extName, const char* sysExts)
-{
- char *padExtName = (char*)malloc(strlen(extName) + 2);
- strcat(strcpy(padExtName, extName), " ");
-
- if (0 == strcmp(extName, "GL_VERSION_1_2")) {
- const char *version = (const char*)glGetString(GL_VERSION);
- if (strstr(version, "1.0") == version || strstr(version, "1.1") == version) {
- return FALSE;
- } else {
- return TRUE;
- }
- }
- if (strstr(sysExts, padExtName)) {
- free(padExtName);
- return TRUE;
- } else {
- free(padExtName);
- return FALSE;
- }
-}
-
-static const char* EatWhiteSpace(const char *str)
-{
- for (; *str && (' ' == *str || '\t' == *str || '\n' == *str); str++);
- return str;
-}
-
-static const char* EatNonWhiteSpace(const char *str)
-{
- for (; *str && (' ' != *str && '\t' != *str && '\n' != *str); str++);
- return str;
-}
-
-
-int glh_init_extensions(const char *origReqExts)
-{
- // Length of requested extensions string
- //unsigned reqExtsLen;
- char *reqExts;
- // Ptr for individual extensions within reqExts
- char *reqExt;
- int success = TRUE;
-
- // build space-padded extension string
- if (NULL == gGLHExts.mSysExts) {
- const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
- int sysExtsLen = (int)strlen(extensions);
- const char *winsys_extensions = 0;
- int winsysExtsLen = 0;
-#ifdef _WIN32
- {
- PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
- wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
- if(wglGetExtensionsStringARB)
- {
- winsys_extensions = wglGetExtensionsStringARB(wglGetCurrentDC());
- winsysExtsLen = (S32)strlen(winsys_extensions);
- }
- }
-#endif
- // Add 2 bytes, one for padding space, one for terminating NULL
- gGLHExts.mSysExts = (char*)malloc(sysExtsLen + winsysExtsLen + 3);
- CHECK_MEMORY(gGLHExts.mSysExts);
- strcpy(gGLHExts.mSysExts, extensions);
- gGLHExts.mSysExts[sysExtsLen] = ' ';
- gGLHExts.mSysExts[sysExtsLen + 1] = 0;
- if (winsysExtsLen)
- {
- strcat(gGLHExts.mSysExts, winsys_extensions);
- }
- gGLHExts.mSysExts[sysExtsLen + 1 + winsysExtsLen] = ' ';
- gGLHExts.mSysExts[sysExtsLen + 1 + winsysExtsLen + 1] = 0;
- }
-
- if (NULL == origReqExts)
- {
- return TRUE;
- }
- reqExts = strdup(origReqExts);
- /*
- reqExtsLen = (S32)strlen(reqExts);
- if (NULL == gGLHExts.mUnsupportedExts)
- {
- gGLHExts.mUnsupportedExts = (char*)malloc(reqExtsLen + 1);
- }
- else if (reqExtsLen > strlen(gGLHExts.mUnsupportedExts))
- {
- gGLHExts.mUnsupportedExts = (char*)realloc(gGLHExts.mUnsupportedExts, reqExtsLen + 1);
- }
- CHECK_MEMORY(gGLHExts.mUnsupportedExts);
- *gGLHExts.mUnsupportedExts = 0;
- */
-
- // Parse requested extension list
- for (reqExt = reqExts;
- (reqExt = (char*)EatWhiteSpace(reqExt)) && *reqExt;
- reqExt = (char*)EatNonWhiteSpace(reqExt))
- {
- char *extEnd = (char*)EatNonWhiteSpace(reqExt);
- char saveChar = *extEnd;
- *extEnd = (char)0;
-
- if (!ExtensionExists(reqExt, gGLHExts.mSysExts) ||
- !glh_init_extension(reqExt)) {
- /*
- // add reqExt to end of unsupportedExts
- strcat(gGLHExts.mUnsupportedExts, reqExt);
- strcat(gGLHExts.mUnsupportedExts, " ");
- */
- success = FALSE;
- }
- *extEnd = saveChar;
- }
- free(reqExts);
- return success;
-}
-
-const char* glh_get_unsupported_extensions()
-{
- return "";
-// return (const char*)gGLHExts.mUnsupportedExts;
-}
-
-#else
-int glh_init_extensions(const char *origReqExts);
-const char* glh_get_unsupported_extensions();
-#endif /* GLH_EXT_SINGLE_FILE */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GLH_EXTENSIONS */
diff --git a/indra/llwindow/GL/glh_genext.h b/indra/llwindow/GL/glh_genext.h
deleted file mode 100644
index cd5d1604a8..0000000000
--- a/indra/llwindow/GL/glh_genext.h
+++ /dev/null
@@ -1,1674 +0,0 @@
-/*
- * glh_genext.h
- * $LicenseInfo:firstyear=2008&license=mit$ (mit used here to satisfy validity checker)
- * Copyright (C) 2008, NVIDIA
- * From nVidia Corporation, downloaded 2006-12-18 from:
- * http://developer.nvidia.com/attach/8196
- * ("NVParse Library with Source (.zip) (2390 KB)")
- *
- * License (quoted from license_info.txt in aforementioned file):
- * "The files bison.exe, bison.simple, and flex.exe are covered by
- * the GPL. All other files in this distribution can be used however
- * you want."
- * $/LicenseInfo$
- */
-
-/* File generated by extgen.cpp -- do not modify */
-#ifndef GLH_GENEXT_H
-#define GLH_GENEXT_H
-
-// MBW -- None of this is necessary on Mac OS.
-#ifndef __APPLE__
-
-#include <GL/gl.h>
-#include <GL/glext.h>
-
-#ifdef _WIN32 /* supports windows, x -- need to generalize */
-# include <GL/wglext.h>
-# define GLH_EXT_GET_PROC_ADDRESS(p) wglGetProcAddress(p)
-#else if GLX_VERSION_1_3
-# include <GL/glxext.h>
-# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddressARB(p)
-#endif
-
-#ifdef GLH_EXT_SINGLE_FILE
- #define GLH_EXTERN
- #define GLH_INITIALIZER = 0
-#else
- #define GLH_EXTERN extern
- #define GLH_INITIALIZER
-#endif
-
-#define GLH__PREPROCESSOR_GYMNASTICS2(a,b) a##b
-#define GLH__PREPROCESSOR_GYMNASTICS(a,b) GLH__PREPROCESSOR_GYMNASTICS2(a,b)
-
-#ifndef GLH_EXT_PREFIX
-# define GLH_EXT_NAME(a) a
-#else
-# define GLH_EXT_NAME(a) GLH__PREPROCESSOR_GYMNASTICS(GLH_EXT_PREFIX,a)
-#endif
-
-#ifndef _WIN32
-# ifndef GLH_CORE_1_2_PREFIX
-# define GLH_CORE_1_2_PREFIX _
-# endif
-#endif
-
-#ifndef GLH_CORE_1_2_PREFIX
-# define GLH_CORE_1_2_NAME(a) a
-#else
-# define GLH_CORE_1_2_NAME(a) GLH__PREPROCESSOR_GYMNASTICS(GLH_CORE_1_2_PREFIX,a)
-#endif
-
-#ifdef GL_ARB_multitexture
- GLH_EXTERN PFNGLMULTITEXCOORD1DARBPROC GLH_EXT_NAME(glMultiTexCoord1dARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD1DVARBPROC GLH_EXT_NAME(glMultiTexCoord1dvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD1FARBPROC GLH_EXT_NAME(glMultiTexCoord1fARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD1FVARBPROC GLH_EXT_NAME(glMultiTexCoord1fvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD1IARBPROC GLH_EXT_NAME(glMultiTexCoord1iARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD1IVARBPROC GLH_EXT_NAME(glMultiTexCoord1ivARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD1SARBPROC GLH_EXT_NAME(glMultiTexCoord1sARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD1SVARBPROC GLH_EXT_NAME(glMultiTexCoord1svARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD2DARBPROC GLH_EXT_NAME(glMultiTexCoord2dARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD2DVARBPROC GLH_EXT_NAME(glMultiTexCoord2dvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD2FARBPROC GLH_EXT_NAME(glMultiTexCoord2fARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD2FVARBPROC GLH_EXT_NAME(glMultiTexCoord2fvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD2IARBPROC GLH_EXT_NAME(glMultiTexCoord2iARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD2IVARBPROC GLH_EXT_NAME(glMultiTexCoord2ivARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD2SARBPROC GLH_EXT_NAME(glMultiTexCoord2sARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD2SVARBPROC GLH_EXT_NAME(glMultiTexCoord2svARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD3DARBPROC GLH_EXT_NAME(glMultiTexCoord3dARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD3DVARBPROC GLH_EXT_NAME(glMultiTexCoord3dvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD3FARBPROC GLH_EXT_NAME(glMultiTexCoord3fARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD3FVARBPROC GLH_EXT_NAME(glMultiTexCoord3fvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD3IARBPROC GLH_EXT_NAME(glMultiTexCoord3iARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD3IVARBPROC GLH_EXT_NAME(glMultiTexCoord3ivARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD3SARBPROC GLH_EXT_NAME(glMultiTexCoord3sARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD3SVARBPROC GLH_EXT_NAME(glMultiTexCoord3svARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD4DARBPROC GLH_EXT_NAME(glMultiTexCoord4dARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD4DVARBPROC GLH_EXT_NAME(glMultiTexCoord4dvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD4FARBPROC GLH_EXT_NAME(glMultiTexCoord4fARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD4FVARBPROC GLH_EXT_NAME(glMultiTexCoord4fvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD4IARBPROC GLH_EXT_NAME(glMultiTexCoord4iARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD4IVARBPROC GLH_EXT_NAME(glMultiTexCoord4ivARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD4SARBPROC GLH_EXT_NAME(glMultiTexCoord4sARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTITEXCOORD4SVARBPROC GLH_EXT_NAME(glMultiTexCoord4svARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLACTIVETEXTUREARBPROC GLH_EXT_NAME(glActiveTextureARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCLIENTACTIVETEXTUREARBPROC GLH_EXT_NAME(glClientActiveTextureARB) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_ARB_texture_border_clamp
-#endif
-
-#ifdef GL_ARB_texture_compression
- GLH_EXTERN PFNGLCOMPRESSEDTEXIMAGE3DARBPROC GLH_EXT_NAME(glCompressedTexImage3DARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOMPRESSEDTEXIMAGE2DARBPROC GLH_EXT_NAME(glCompressedTexImage2DARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOMPRESSEDTEXIMAGE1DARBPROC GLH_EXT_NAME(glCompressedTexImage1DARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC GLH_EXT_NAME(glCompressedTexSubImage3DARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC GLH_EXT_NAME(glCompressedTexSubImage2DARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC GLH_EXT_NAME(glCompressedTexSubImage1DARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOMPRESSEDTEXIMAGEARBPROC GLH_EXT_NAME(glGetCompressedTexImageARB) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_ARB_texture_cube_map
-#endif
-
-#ifdef GL_ARB_transpose_matrix
- GLH_EXTERN PFNGLLOADTRANSPOSEMATRIXFARBPROC GLH_EXT_NAME(glLoadTransposeMatrixfARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLLOADTRANSPOSEMATRIXDARBPROC GLH_EXT_NAME(glLoadTransposeMatrixdARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTTRANSPOSEMATRIXFARBPROC GLH_EXT_NAME(glMultTransposeMatrixfARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMULTTRANSPOSEMATRIXDARBPROC GLH_EXT_NAME(glMultTransposeMatrixdARB) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_ARB_vertex_program
- GLH_EXTERN PFNGLVERTEXATTRIB1SARBPROC GLH_EXT_NAME(glVertexAttrib1sARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1FARBPROC GLH_EXT_NAME(glVertexAttrib1fARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1DARBPROC GLH_EXT_NAME(glVertexAttrib1dARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2SARBPROC GLH_EXT_NAME(glVertexAttrib2sARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2FARBPROC GLH_EXT_NAME(glVertexAttrib2fARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2DARBPROC GLH_EXT_NAME(glVertexAttrib2dARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3SARBPROC GLH_EXT_NAME(glVertexAttrib3sARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3FARBPROC GLH_EXT_NAME(glVertexAttrib3fARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3DARBPROC GLH_EXT_NAME(glVertexAttrib3dARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4SARBPROC GLH_EXT_NAME(glVertexAttrib4sARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4FARBPROC GLH_EXT_NAME(glVertexAttrib4fARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4DARBPROC GLH_EXT_NAME(glVertexAttrib4dARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4NUBARBPROC GLH_EXT_NAME(glVertexAttrib4NubARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1SVARBPROC GLH_EXT_NAME(glVertexAttrib1svARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1FVARBPROC GLH_EXT_NAME(glVertexAttrib1fvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1DVARBPROC GLH_EXT_NAME(glVertexAttrib1dvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2SVARBPROC GLH_EXT_NAME(glVertexAttrib2svARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2FVARBPROC GLH_EXT_NAME(glVertexAttrib2fvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2DVARBPROC GLH_EXT_NAME(glVertexAttrib2dvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3SVARBPROC GLH_EXT_NAME(glVertexAttrib3svARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3FVARBPROC GLH_EXT_NAME(glVertexAttrib3fvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3DVARBPROC GLH_EXT_NAME(glVertexAttrib3dvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4BVARBPROC GLH_EXT_NAME(glVertexAttrib4bvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4SVARBPROC GLH_EXT_NAME(glVertexAttrib4svARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4IVARBPROC GLH_EXT_NAME(glVertexAttrib4ivARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4UBVARBPROC GLH_EXT_NAME(glVertexAttrib4ubvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4USVARBPROC GLH_EXT_NAME(glVertexAttrib4usvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4UIVARBPROC GLH_EXT_NAME(glVertexAttrib4uivARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4FVARBPROC GLH_EXT_NAME(glVertexAttrib4fvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4DVARBPROC GLH_EXT_NAME(glVertexAttrib4dvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4NBVARBPROC GLH_EXT_NAME(glVertexAttrib4NbvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4NSVARBPROC GLH_EXT_NAME(glVertexAttrib4NsvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4NIVARBPROC GLH_EXT_NAME(glVertexAttrib4NivARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4NUBVARBPROC GLH_EXT_NAME(glVertexAttrib4NubvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4NUSVARBPROC GLH_EXT_NAME(glVertexAttrib4NusvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4NUIVARBPROC GLH_EXT_NAME(glVertexAttrib4NuivARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBPOINTERARBPROC GLH_EXT_NAME(glVertexAttribPointerARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLENABLEVERTEXATTRIBARRAYARBPROC GLH_EXT_NAME(glEnableVertexAttribArrayARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLDISABLEVERTEXATTRIBARRAYARBPROC GLH_EXT_NAME(glDisableVertexAttribArrayARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMSTRINGARBPROC GLH_EXT_NAME(glProgramStringARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLBINDPROGRAMARBPROC GLH_EXT_NAME(glBindProgramARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLDELETEPROGRAMSARBPROC GLH_EXT_NAME(glDeleteProgramsARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGENPROGRAMSARBPROC GLH_EXT_NAME(glGenProgramsARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMENVPARAMETER4DARBPROC GLH_EXT_NAME(glProgramEnvParameter4dARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMENVPARAMETER4DVARBPROC GLH_EXT_NAME(glProgramEnvParameter4dvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMENVPARAMETER4FARBPROC GLH_EXT_NAME(glProgramEnvParameter4fARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMENVPARAMETER4FVARBPROC GLH_EXT_NAME(glProgramEnvParameter4fvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMLOCALPARAMETER4DARBPROC GLH_EXT_NAME(glProgramLocalParameter4dARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMLOCALPARAMETER4DVARBPROC GLH_EXT_NAME(glProgramLocalParameter4dvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMLOCALPARAMETER4FARBPROC GLH_EXT_NAME(glProgramLocalParameter4fARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMLOCALPARAMETER4FVARBPROC GLH_EXT_NAME(glProgramLocalParameter4fvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPROGRAMENVPARAMETERDVARBPROC GLH_EXT_NAME(glGetProgramEnvParameterdvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPROGRAMENVPARAMETERFVARBPROC GLH_EXT_NAME(glGetProgramEnvParameterfvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC GLH_EXT_NAME(glGetProgramLocalParameterdvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC GLH_EXT_NAME(glGetProgramLocalParameterfvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPROGRAMIVARBPROC GLH_EXT_NAME(glGetProgramivARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPROGRAMSTRINGARBPROC GLH_EXT_NAME(glGetProgramStringARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETVERTEXATTRIBDVARBPROC GLH_EXT_NAME(glGetVertexAttribdvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETVERTEXATTRIBFVARBPROC GLH_EXT_NAME(glGetVertexAttribfvARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETVERTEXATTRIBIVARBPROC GLH_EXT_NAME(glGetVertexAttribivARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETVERTEXATTRIBPOINTERVARBPROC GLH_EXT_NAME(glGetVertexAttribPointervARB) GLH_INITIALIZER;
- GLH_EXTERN PFNGLISPROGRAMARBPROC GLH_EXT_NAME(glIsProgramARB) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_abgr
-#endif
-
-#ifdef GL_EXT_bgra
-#endif
-
-#ifdef GL_EXT_blend_color
- GLH_EXTERN PFNGLBLENDCOLOREXTPROC GLH_EXT_NAME(glBlendColorEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_blend_minmax
- GLH_EXTERN PFNGLBLENDEQUATIONEXTPROC GLH_EXT_NAME(glBlendEquationEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_blend_subtract
-#endif
-
-#ifdef GL_EXT_compiled_vertex_array
- GLH_EXTERN PFNGLLOCKARRAYSEXTPROC GLH_EXT_NAME(glLockArraysEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLUNLOCKARRAYSEXTPROC GLH_EXT_NAME(glUnlockArraysEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_fog_coord
- GLH_EXTERN PFNGLFOGCOORDDEXTPROC GLH_EXT_NAME(glFogCoorddEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLFOGCOORDDVEXTPROC GLH_EXT_NAME(glFogCoorddvEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLFOGCOORDFEXTPROC GLH_EXT_NAME(glFogCoordfEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLFOGCOORDFVEXTPROC GLH_EXT_NAME(glFogCoordfvEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLFOGCOORDPOINTEREXTPROC GLH_EXT_NAME(glFogCoordPointerEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_light_max_exponent
-#endif
-
-#ifdef GL_EXT_packed_pixels
-#endif
-
-#ifdef GL_EXT_paletted_texture
- GLH_EXTERN PFNGLCOLORSUBTABLEEXTPROC GLH_EXT_NAME(glColorSubTableEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOLORTABLEEXTPROC GLH_EXT_NAME(glColorTableEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOLORTABLEEXTPROC GLH_EXT_NAME(glGetColorTableEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOLORTABLEPARAMETERFVEXTPROC GLH_EXT_NAME(glGetColorTableParameterfvEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOLORTABLEPARAMETERIVEXTPROC GLH_EXT_NAME(glGetColorTableParameterivEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_point_parameters
- GLH_EXTERN PFNGLPOINTPARAMETERFEXTPROC GLH_EXT_NAME(glPointParameterfEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPOINTPARAMETERFVEXTPROC GLH_EXT_NAME(glPointParameterfvEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_rescale_normal
-#endif
-
-#ifdef GL_EXT_secondary_color
- GLH_EXTERN PFNGLSECONDARYCOLOR3BEXTPROC GLH_EXT_NAME(glSecondaryColor3bEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3BVEXTPROC GLH_EXT_NAME(glSecondaryColor3bvEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3DEXTPROC GLH_EXT_NAME(glSecondaryColor3dEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3DVEXTPROC GLH_EXT_NAME(glSecondaryColor3dvEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3FEXTPROC GLH_EXT_NAME(glSecondaryColor3fEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3FVEXTPROC GLH_EXT_NAME(glSecondaryColor3fvEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3IEXTPROC GLH_EXT_NAME(glSecondaryColor3iEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3IVEXTPROC GLH_EXT_NAME(glSecondaryColor3ivEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3SEXTPROC GLH_EXT_NAME(glSecondaryColor3sEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3SVEXTPROC GLH_EXT_NAME(glSecondaryColor3svEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3UBEXTPROC GLH_EXT_NAME(glSecondaryColor3ubEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3UBVEXTPROC GLH_EXT_NAME(glSecondaryColor3ubvEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3UIEXTPROC GLH_EXT_NAME(glSecondaryColor3uiEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3UIVEXTPROC GLH_EXT_NAME(glSecondaryColor3uivEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3USEXTPROC GLH_EXT_NAME(glSecondaryColor3usEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLOR3USVEXTPROC GLH_EXT_NAME(glSecondaryColor3usvEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSECONDARYCOLORPOINTEREXTPROC GLH_EXT_NAME(glSecondaryColorPointerEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_separate_specular_color
-#endif
-
-#ifdef GL_EXT_shared_texture_palette
-#endif
-
-#ifdef GL_EXT_stencil_wrap
-#endif
-
-#ifdef GL_EXT_texture_compression_s3tc
-#endif
-
-#ifdef GL_EXT_texture_cube_map
-#endif
-
-#ifdef GL_EXT_texture_edge_clamp
-#endif
-
-#ifdef GL_EXT_texture_env_add
-#endif
-
-#ifdef GL_EXT_texture_env_combine
-#endif
-
-#ifdef GL_EXT_texture_filter_anisotropic
-#endif
-
-#ifdef GL_EXT_texture_lod_bias
-#endif
-
-#ifdef GL_EXT_texture_object
- GLH_EXTERN PFNGLARETEXTURESRESIDENTEXTPROC GLH_EXT_NAME(glAreTexturesResidentEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLBINDTEXTUREEXTPROC GLH_EXT_NAME(glBindTextureEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLDELETETEXTURESEXTPROC GLH_EXT_NAME(glDeleteTexturesEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGENTEXTURESEXTPROC GLH_EXT_NAME(glGenTexturesEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLISTEXTUREEXTPROC GLH_EXT_NAME(glIsTextureEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPRIORITIZETEXTURESEXTPROC GLH_EXT_NAME(glPrioritizeTexturesEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_texture3D
- GLH_EXTERN PFNGLTEXIMAGE3DEXTPROC GLH_EXT_NAME(glTexImage3DEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_vertex_array
- GLH_EXTERN PFNGLARRAYELEMENTEXTPROC GLH_EXT_NAME(glArrayElementEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOLORPOINTEREXTPROC GLH_EXT_NAME(glColorPointerEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLEDGEFLAGPOINTEREXTPROC GLH_EXT_NAME(glEdgeFlagPointerEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPOINTERVEXTPROC GLH_EXT_NAME(glGetPointervEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLINDEXPOINTEREXTPROC GLH_EXT_NAME(glIndexPointerEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLNORMALPOINTEREXTPROC GLH_EXT_NAME(glNormalPointerEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLTEXCOORDPOINTEREXTPROC GLH_EXT_NAME(glTexCoordPointerEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXPOINTEREXTPROC GLH_EXT_NAME(glVertexPointerEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLDRAWARRAYSEXTPROC GLH_EXT_NAME(glDrawArraysEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_EXT_vertex_weighting
- GLH_EXTERN PFNGLVERTEXWEIGHTFEXTPROC GLH_EXT_NAME(glVertexWeightfEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXWEIGHTFVEXTPROC GLH_EXT_NAME(glVertexWeightfvEXT) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXWEIGHTPOINTEREXTPROC GLH_EXT_NAME(glVertexWeightPointerEXT) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_NV_blend_square
-#endif
-
-#ifdef GL_NV_evaluators
- GLH_EXTERN PFNGLMAPCONTROLPOINTSNVPROC GLH_EXT_NAME(glMapControlPointsNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMAPPARAMETERIVNVPROC GLH_EXT_NAME(glMapParameterivNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLMAPPARAMETERFVNVPROC GLH_EXT_NAME(glMapParameterfvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETMAPCONTROLPOINTSNVPROC GLH_EXT_NAME(glGetMapControlPointsNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETMAPPARAMETERIVNVPROC GLH_EXT_NAME(glGetMapParameterivNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETMAPPARAMETERFVNVPROC GLH_EXT_NAME(glGetMapParameterfvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETMAPATTRIBPARAMETERIVNVPROC GLH_EXT_NAME(glGetMapAttribParameterivNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETMAPATTRIBPARAMETERFVNVPROC GLH_EXT_NAME(glGetMapAttribParameterfvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLEVALMAPSNVPROC GLH_EXT_NAME(glEvalMapsNV) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_NV_fence
- GLH_EXTERN PFNGLGENFENCESNVPROC GLH_EXT_NAME(glGenFencesNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLDELETEFENCESNVPROC GLH_EXT_NAME(glDeleteFencesNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLSETFENCENVPROC GLH_EXT_NAME(glSetFenceNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLTESTFENCENVPROC GLH_EXT_NAME(glTestFenceNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLFINISHFENCENVPROC GLH_EXT_NAME(glFinishFenceNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLISFENCENVPROC GLH_EXT_NAME(glIsFenceNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETFENCEIVNVPROC GLH_EXT_NAME(glGetFenceivNV) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_NV_fog_distance
-#endif
-
-#ifdef GL_NV_packed_depth_stencil
-#endif
-
-#ifdef GL_NV_register_combiners
- GLH_EXTERN PFNGLCOMBINERPARAMETERFVNVPROC GLH_EXT_NAME(glCombinerParameterfvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOMBINERPARAMETERFNVPROC GLH_EXT_NAME(glCombinerParameterfNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOMBINERPARAMETERIVNVPROC GLH_EXT_NAME(glCombinerParameterivNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOMBINERPARAMETERINVPROC GLH_EXT_NAME(glCombinerParameteriNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOMBINERINPUTNVPROC GLH_EXT_NAME(glCombinerInputNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOMBINEROUTPUTNVPROC GLH_EXT_NAME(glCombinerOutputNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLFINALCOMBINERINPUTNVPROC GLH_EXT_NAME(glFinalCombinerInputNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC GLH_EXT_NAME(glGetCombinerInputParameterfvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC GLH_EXT_NAME(glGetCombinerInputParameterivNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC GLH_EXT_NAME(glGetCombinerOutputParameterfvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC GLH_EXT_NAME(glGetCombinerOutputParameterivNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC GLH_EXT_NAME(glGetFinalCombinerInputParameterfvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC GLH_EXT_NAME(glGetFinalCombinerInputParameterivNV) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_NV_register_combiners2
- GLH_EXTERN PFNGLCOMBINERSTAGEPARAMETERFVNVPROC GLH_EXT_NAME(glCombinerStageParameterfvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC GLH_EXT_NAME(glGetCombinerStageParameterfvNV) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_NV_texgen_reflection
-#endif
-
-#ifdef GL_NV_texture_env_combine4
-#endif
-
-#ifdef GL_NV_texture_rectangle
-#endif
-
-#ifdef GL_NV_texture_shader
-#endif
-
-#ifdef GL_NV_vertex_array_range
- GLH_EXTERN PFNGLFLUSHVERTEXARRAYRANGENVPROC GLH_EXT_NAME(glFlushVertexArrayRangeNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXARRAYRANGENVPROC GLH_EXT_NAME(glVertexArrayRangeNV) GLH_INITIALIZER;
-# ifdef _WIN32
- GLH_EXTERN PFNWGLALLOCATEMEMORYNVPROC GLH_EXT_NAME(wglAllocateMemoryNV) GLH_INITIALIZER;
-# endif
-# ifdef GLX_VERSION_1_3
- GLH_EXTERN PFNGLXALLOCATEMEMORYNVPROC GLH_EXT_NAME(glXAllocateMemoryNV) GLH_INITIALIZER;
-# endif
-# ifdef _WIN32
- GLH_EXTERN PFNWGLFREEMEMORYNVPROC GLH_EXT_NAME(wglFreeMemoryNV) GLH_INITIALIZER;
-# endif
-# ifdef GLX_VERSION_1_3
- GLH_EXTERN PFNGLXFREEMEMORYNVPROC GLH_EXT_NAME(glXFreeMemoryNV) GLH_INITIALIZER;
-# endif
-#endif
-
-#ifdef GL_NV_vertex_program
- GLH_EXTERN PFNGLAREPROGRAMSRESIDENTNVPROC GLH_EXT_NAME(glAreProgramsResidentNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLBINDPROGRAMNVPROC GLH_EXT_NAME(glBindProgramNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLDELETEPROGRAMSNVPROC GLH_EXT_NAME(glDeleteProgramsNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLEXECUTEPROGRAMNVPROC GLH_EXT_NAME(glExecuteProgramNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGENPROGRAMSNVPROC GLH_EXT_NAME(glGenProgramsNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPROGRAMPARAMETERDVNVPROC GLH_EXT_NAME(glGetProgramParameterdvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPROGRAMPARAMETERFVNVPROC GLH_EXT_NAME(glGetProgramParameterfvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPROGRAMIVNVPROC GLH_EXT_NAME(glGetProgramivNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETPROGRAMSTRINGNVPROC GLH_EXT_NAME(glGetProgramStringNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETTRACKMATRIXIVNVPROC GLH_EXT_NAME(glGetTrackMatrixivNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETVERTEXATTRIBDVNVPROC GLH_EXT_NAME(glGetVertexAttribdvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETVERTEXATTRIBFVNVPROC GLH_EXT_NAME(glGetVertexAttribfvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETVERTEXATTRIBIVNVPROC GLH_EXT_NAME(glGetVertexAttribivNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETVERTEXATTRIBPOINTERVNVPROC GLH_EXT_NAME(glGetVertexAttribPointervNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLISPROGRAMNVPROC GLH_EXT_NAME(glIsProgramNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLLOADPROGRAMNVPROC GLH_EXT_NAME(glLoadProgramNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMPARAMETER4DNVPROC GLH_EXT_NAME(glProgramParameter4dNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMPARAMETER4DVNVPROC GLH_EXT_NAME(glProgramParameter4dvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMPARAMETER4FNVPROC GLH_EXT_NAME(glProgramParameter4fNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMPARAMETER4FVNVPROC GLH_EXT_NAME(glProgramParameter4fvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMPARAMETERS4DVNVPROC GLH_EXT_NAME(glProgramParameters4dvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLPROGRAMPARAMETERS4FVNVPROC GLH_EXT_NAME(glProgramParameters4fvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLREQUESTRESIDENTPROGRAMSNVPROC GLH_EXT_NAME(glRequestResidentProgramsNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLTRACKMATRIXNVPROC GLH_EXT_NAME(glTrackMatrixNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBPOINTERNVPROC GLH_EXT_NAME(glVertexAttribPointerNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1DNVPROC GLH_EXT_NAME(glVertexAttrib1dNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1DVNVPROC GLH_EXT_NAME(glVertexAttrib1dvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1FNVPROC GLH_EXT_NAME(glVertexAttrib1fNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1FVNVPROC GLH_EXT_NAME(glVertexAttrib1fvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1SNVPROC GLH_EXT_NAME(glVertexAttrib1sNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB1SVNVPROC GLH_EXT_NAME(glVertexAttrib1svNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2DNVPROC GLH_EXT_NAME(glVertexAttrib2dNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2DVNVPROC GLH_EXT_NAME(glVertexAttrib2dvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2FNVPROC GLH_EXT_NAME(glVertexAttrib2fNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2FVNVPROC GLH_EXT_NAME(glVertexAttrib2fvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2SNVPROC GLH_EXT_NAME(glVertexAttrib2sNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB2SVNVPROC GLH_EXT_NAME(glVertexAttrib2svNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3DNVPROC GLH_EXT_NAME(glVertexAttrib3dNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3DVNVPROC GLH_EXT_NAME(glVertexAttrib3dvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3FNVPROC GLH_EXT_NAME(glVertexAttrib3fNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3FVNVPROC GLH_EXT_NAME(glVertexAttrib3fvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3SNVPROC GLH_EXT_NAME(glVertexAttrib3sNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB3SVNVPROC GLH_EXT_NAME(glVertexAttrib3svNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4DNVPROC GLH_EXT_NAME(glVertexAttrib4dNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4DVNVPROC GLH_EXT_NAME(glVertexAttrib4dvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4FNVPROC GLH_EXT_NAME(glVertexAttrib4fNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4FVNVPROC GLH_EXT_NAME(glVertexAttrib4fvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4SNVPROC GLH_EXT_NAME(glVertexAttrib4sNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4SVNVPROC GLH_EXT_NAME(glVertexAttrib4svNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIB4UBVNVPROC GLH_EXT_NAME(glVertexAttrib4ubvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS1DVNVPROC GLH_EXT_NAME(glVertexAttribs1dvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS1FVNVPROC GLH_EXT_NAME(glVertexAttribs1fvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS1SVNVPROC GLH_EXT_NAME(glVertexAttribs1svNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS2DVNVPROC GLH_EXT_NAME(glVertexAttribs2dvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS2FVNVPROC GLH_EXT_NAME(glVertexAttribs2fvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS2SVNVPROC GLH_EXT_NAME(glVertexAttribs2svNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS3DVNVPROC GLH_EXT_NAME(glVertexAttribs3dvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS3FVNVPROC GLH_EXT_NAME(glVertexAttribs3fvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS3SVNVPROC GLH_EXT_NAME(glVertexAttribs3svNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS4DVNVPROC GLH_EXT_NAME(glVertexAttribs4dvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS4FVNVPROC GLH_EXT_NAME(glVertexAttribs4fvNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS4SVNVPROC GLH_EXT_NAME(glVertexAttribs4svNV) GLH_INITIALIZER;
- GLH_EXTERN PFNGLVERTEXATTRIBS4UBVNVPROC GLH_EXT_NAME(glVertexAttribs4ubvNV) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_SGIS_generate_mipmap
-#endif
-
-#ifdef GL_SGIS_texture_lod
-#endif
-
-#ifdef GL_SGIX_depth_texture
-#endif
-
-#ifdef GL_SGIX_shadow
-#endif
-
-#ifdef GL_VERSION_1_2
- /* These routines are prefixed by the preprocessor constant
- GLH_CORE_1_2_PREFIX to avoid colliding with the OpenGL 1.2 namespace. */
- GLH_EXTERN PFNGLBLENDCOLORPROC GLH_CORE_1_2_NAME(glBlendColor) GLH_INITIALIZER;
- GLH_EXTERN PFNGLBLENDEQUATIONPROC GLH_CORE_1_2_NAME(glBlendEquation) GLH_INITIALIZER;
- GLH_EXTERN PFNGLDRAWRANGEELEMENTSPROC GLH_CORE_1_2_NAME(glDrawRangeElements) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOLORTABLEPROC GLH_CORE_1_2_NAME(glColorTable) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOLORTABLEPARAMETERFVPROC GLH_CORE_1_2_NAME(glColorTableParameterfv) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOLORTABLEPARAMETERIVPROC GLH_CORE_1_2_NAME(glColorTableParameteriv) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOPYCOLORTABLEPROC GLH_CORE_1_2_NAME(glCopyColorTable) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOLORTABLEPROC GLH_CORE_1_2_NAME(glGetColorTable) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOLORTABLEPARAMETERFVPROC GLH_CORE_1_2_NAME(glGetColorTableParameterfv) GLH_INITIALIZER;
- GLH_EXTERN PFNGLGETCOLORTABLEPARAMETERIVPROC GLH_CORE_1_2_NAME(glGetColorTableParameteriv) GLH_INITIALIZER;
- GLH_EXTERN PFNGLTEXIMAGE3DPROC GLH_CORE_1_2_NAME(glTexImage3D) GLH_INITIALIZER;
- GLH_EXTERN PFNGLTEXSUBIMAGE3DPROC GLH_CORE_1_2_NAME(glTexSubImage3D) GLH_INITIALIZER;
- GLH_EXTERN PFNGLCOPYTEXSUBIMAGE3DPROC GLH_CORE_1_2_NAME(glCopyTexSubImage3D) GLH_INITIALIZER;
-#endif
-
-#ifdef GL_WIN_swap_hint
- GLH_EXTERN PFNGLADDSWAPHINTRECTWINPROC GLH_EXT_NAME(glAddSwapHintRectWIN) GLH_INITIALIZER;
-#endif
-
-#ifdef WGL_ARB_pbuffer
-# ifdef _WIN32
- GLH_EXTERN PFNWGLCREATEPBUFFERARBPROC GLH_EXT_NAME(wglCreatePbufferARB) GLH_INITIALIZER;
-# endif
-# ifdef _WIN32
- GLH_EXTERN PFNWGLGETPBUFFERDCARBPROC GLH_EXT_NAME(wglGetPbufferDCARB) GLH_INITIALIZER;
-# endif
-# ifdef _WIN32
- GLH_EXTERN PFNWGLRELEASEPBUFFERDCARBPROC GLH_EXT_NAME(wglReleasePbufferDCARB) GLH_INITIALIZER;
-# endif
-# ifdef _WIN32
- GLH_EXTERN PFNWGLDESTROYPBUFFERARBPROC GLH_EXT_NAME(wglDestroyPbufferARB) GLH_INITIALIZER;
-# endif
-# ifdef _WIN32
- GLH_EXTERN PFNWGLQUERYPBUFFERARBPROC GLH_EXT_NAME(wglQueryPbufferARB) GLH_INITIALIZER;
-# endif
-#endif
-
-#ifdef WGL_ARB_render_texture
-# ifdef _WIN32
- GLH_EXTERN PFNWGLBINDTEXIMAGEARBPROC GLH_EXT_NAME(wglBindTexImageARB) GLH_INITIALIZER;
-# endif
-# ifdef _WIN32
- GLH_EXTERN PFNWGLRELEASETEXIMAGEARBPROC GLH_EXT_NAME(wglReleaseTexImageARB) GLH_INITIALIZER;
-# endif
-# ifdef _WIN32
- GLH_EXTERN PFNWGLSETPBUFFERATTRIBARBPROC GLH_EXT_NAME(wglSetPbufferAttribARB) GLH_INITIALIZER;
-# endif
-#endif
-
-#ifdef WGL_ARB_pixel_format
-# ifdef _WIN32
- GLH_EXTERN PFNWGLGETPIXELFORMATATTRIBIVARBPROC GLH_EXT_NAME(wglGetPixelFormatAttribivARB) GLH_INITIALIZER;
-# endif
-# ifdef _WIN32
- GLH_EXTERN PFNWGLGETPIXELFORMATATTRIBFVARBPROC GLH_EXT_NAME(wglGetPixelFormatAttribfvARB) GLH_INITIALIZER;
-# endif
-# ifdef _WIN32
- GLH_EXTERN PFNWGLCHOOSEPIXELFORMATARBPROC GLH_EXT_NAME(wglChoosePixelFormatARB) GLH_INITIALIZER;
-# endif
-#endif
-
-
-#ifdef GLH_EXT_SINGLE_FILE
-
-int glh_init_extension(const char* extension)
-{
- if (NULL == extension) {
- return FALSE;
-#ifdef GL_ARB_multitexture
- } else if (0 == strcmp(extension, "GL_ARB_multitexture")) {
- GLH_EXT_NAME(glMultiTexCoord1dARB) = (PFNGLMULTITEXCOORD1DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1dARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord1dARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord1dvARB) = (PFNGLMULTITEXCOORD1DVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1dvARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord1dvARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord1fARB) = (PFNGLMULTITEXCOORD1FARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1fARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord1fARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord1fvARB) = (PFNGLMULTITEXCOORD1FVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1fvARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord1fvARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord1iARB) = (PFNGLMULTITEXCOORD1IARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1iARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord1iARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord1ivARB) = (PFNGLMULTITEXCOORD1IVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1ivARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord1ivARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord1sARB) = (PFNGLMULTITEXCOORD1SARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1sARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord1sARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord1svARB) = (PFNGLMULTITEXCOORD1SVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1svARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord1svARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord2dARB) = (PFNGLMULTITEXCOORD2DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2dARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord2dARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord2dvARB) = (PFNGLMULTITEXCOORD2DVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2dvARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord2dvARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord2fARB) = (PFNGLMULTITEXCOORD2FARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2fARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord2fARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord2fvARB) = (PFNGLMULTITEXCOORD2FVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2fvARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord2fvARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord2iARB) = (PFNGLMULTITEXCOORD2IARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2iARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord2iARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord2ivARB) = (PFNGLMULTITEXCOORD2IVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2ivARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord2ivARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord2sARB) = (PFNGLMULTITEXCOORD2SARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2sARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord2sARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord2svARB) = (PFNGLMULTITEXCOORD2SVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2svARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord2svARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord3dARB) = (PFNGLMULTITEXCOORD3DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3dARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord3dARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord3dvARB) = (PFNGLMULTITEXCOORD3DVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3dvARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord3dvARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord3fARB) = (PFNGLMULTITEXCOORD3FARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3fARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord3fARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord3fvARB) = (PFNGLMULTITEXCOORD3FVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3fvARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord3fvARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord3iARB) = (PFNGLMULTITEXCOORD3IARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3iARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord3iARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord3ivARB) = (PFNGLMULTITEXCOORD3IVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3ivARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord3ivARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord3sARB) = (PFNGLMULTITEXCOORD3SARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3sARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord3sARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord3svARB) = (PFNGLMULTITEXCOORD3SVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3svARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord3svARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord4dARB) = (PFNGLMULTITEXCOORD4DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4dARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord4dARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord4dvARB) = (PFNGLMULTITEXCOORD4DVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4dvARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord4dvARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord4fARB) = (PFNGLMULTITEXCOORD4FARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4fARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord4fARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord4fvARB) = (PFNGLMULTITEXCOORD4FVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4fvARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord4fvARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord4iARB) = (PFNGLMULTITEXCOORD4IARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4iARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord4iARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord4ivARB) = (PFNGLMULTITEXCOORD4IVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4ivARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord4ivARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord4sARB) = (PFNGLMULTITEXCOORD4SARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4sARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord4sARB))
- return FALSE;
- GLH_EXT_NAME(glMultiTexCoord4svARB) = (PFNGLMULTITEXCOORD4SVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4svARB");
- if (NULL == GLH_EXT_NAME(glMultiTexCoord4svARB))
- return FALSE;
- GLH_EXT_NAME(glActiveTextureARB) = (PFNGLACTIVETEXTUREARBPROC)GLH_EXT_GET_PROC_ADDRESS("glActiveTextureARB");
- if (NULL == GLH_EXT_NAME(glActiveTextureARB))
- return FALSE;
- GLH_EXT_NAME(glClientActiveTextureARB) = (PFNGLCLIENTACTIVETEXTUREARBPROC)GLH_EXT_GET_PROC_ADDRESS("glClientActiveTextureARB");
- if (NULL == GLH_EXT_NAME(glClientActiveTextureARB))
- return FALSE;
-#endif
-
-#ifdef GL_ARB_texture_border_clamp
- } else if (0 == strcmp(extension, "GL_ARB_texture_border_clamp")) {
-#endif
-
-#ifdef GL_ARB_texture_compression
- } else if (0 == strcmp(extension, "GL_ARB_texture_compression")) {
- GLH_EXT_NAME(glCompressedTexImage3DARB) = (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexImage3DARB");
- if (NULL == GLH_EXT_NAME(glCompressedTexImage3DARB))
- return FALSE;
- GLH_EXT_NAME(glCompressedTexImage2DARB) = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexImage2DARB");
- if (NULL == GLH_EXT_NAME(glCompressedTexImage2DARB))
- return FALSE;
- GLH_EXT_NAME(glCompressedTexImage1DARB) = (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexImage1DARB");
- if (NULL == GLH_EXT_NAME(glCompressedTexImage1DARB))
- return FALSE;
- GLH_EXT_NAME(glCompressedTexSubImage3DARB) = (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexSubImage3DARB");
- if (NULL == GLH_EXT_NAME(glCompressedTexSubImage3DARB))
- return FALSE;
- GLH_EXT_NAME(glCompressedTexSubImage2DARB) = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexSubImage2DARB");
- if (NULL == GLH_EXT_NAME(glCompressedTexSubImage2DARB))
- return FALSE;
- GLH_EXT_NAME(glCompressedTexSubImage1DARB) = (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexSubImage1DARB");
- if (NULL == GLH_EXT_NAME(glCompressedTexSubImage1DARB))
- return FALSE;
- GLH_EXT_NAME(glGetCompressedTexImageARB) = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCompressedTexImageARB");
- if (NULL == GLH_EXT_NAME(glGetCompressedTexImageARB))
- return FALSE;
-#endif
-
-#ifdef GL_ARB_texture_cube_map
- } else if (0 == strcmp(extension, "GL_ARB_texture_cube_map")) {
-#endif
-
-#ifdef GL_ARB_transpose_matrix
- } else if (0 == strcmp(extension, "GL_ARB_transpose_matrix")) {
- GLH_EXT_NAME(glLoadTransposeMatrixfARB) = (PFNGLLOADTRANSPOSEMATRIXFARBPROC)GLH_EXT_GET_PROC_ADDRESS("glLoadTransposeMatrixfARB");
- if (NULL == GLH_EXT_NAME(glLoadTransposeMatrixfARB))
- return FALSE;
- GLH_EXT_NAME(glLoadTransposeMatrixdARB) = (PFNGLLOADTRANSPOSEMATRIXDARBPROC)GLH_EXT_GET_PROC_ADDRESS("glLoadTransposeMatrixdARB");
- if (NULL == GLH_EXT_NAME(glLoadTransposeMatrixdARB))
- return FALSE;
- GLH_EXT_NAME(glMultTransposeMatrixfARB) = (PFNGLMULTTRANSPOSEMATRIXFARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultTransposeMatrixfARB");
- if (NULL == GLH_EXT_NAME(glMultTransposeMatrixfARB))
- return FALSE;
- GLH_EXT_NAME(glMultTransposeMatrixdARB) = (PFNGLMULTTRANSPOSEMATRIXDARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMultTransposeMatrixdARB");
- if (NULL == GLH_EXT_NAME(glMultTransposeMatrixdARB))
- return FALSE;
-#endif
-
-#ifdef GL_ARB_vertex_program
- } else if (0 == strcmp(extension, "GL_ARB_vertex_program")) {
- GLH_EXT_NAME(glVertexAttrib1sARB) = (PFNGLVERTEXATTRIB1SARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1sARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib1fARB) = (PFNGLVERTEXATTRIB1FARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1fARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib1dARB) = (PFNGLVERTEXATTRIB1DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1dARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib2sARB) = (PFNGLVERTEXATTRIB2SARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2sARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib2fARB) = (PFNGLVERTEXATTRIB2FARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2fARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib2dARB) = (PFNGLVERTEXATTRIB2DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2dARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib3sARB) = (PFNGLVERTEXATTRIB3SARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3sARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib3fARB) = (PFNGLVERTEXATTRIB3FARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3fARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib3dARB) = (PFNGLVERTEXATTRIB3DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3dARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4sARB) = (PFNGLVERTEXATTRIB4SARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4sARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4fARB) = (PFNGLVERTEXATTRIB4FARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4fARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4dARB) = (PFNGLVERTEXATTRIB4DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4dARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4NubARB) = (PFNGLVERTEXATTRIB4NUBARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4NubARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4NubARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib1svARB) = (PFNGLVERTEXATTRIB1SVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1svARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib1fvARB) = (PFNGLVERTEXATTRIB1FVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1fvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib1dvARB) = (PFNGLVERTEXATTRIB1DVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1dvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib2svARB) = (PFNGLVERTEXATTRIB2SVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2svARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib2fvARB) = (PFNGLVERTEXATTRIB2FVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2fvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib2dvARB) = (PFNGLVERTEXATTRIB2DVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2dvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib3svARB) = (PFNGLVERTEXATTRIB3SVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3svARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib3fvARB) = (PFNGLVERTEXATTRIB3FVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3fvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib3dvARB) = (PFNGLVERTEXATTRIB3DVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3dvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4bvARB) = (PFNGLVERTEXATTRIB4BVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4bvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4svARB) = (PFNGLVERTEXATTRIB4SVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4svARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4ivARB) = (PFNGLVERTEXATTRIB4IVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ivARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4ivARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4ubvARB) = (PFNGLVERTEXATTRIB4UBVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4ubvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4usvARB) = (PFNGLVERTEXATTRIB4USVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4usvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4uivARB) = (PFNGLVERTEXATTRIB4UIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4uivARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4fvARB) = (PFNGLVERTEXATTRIB4FVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4fvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4dvARB) = (PFNGLVERTEXATTRIB4DVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4dvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4NbvARB) = (PFNGLVERTEXATTRIB4NBVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4NbvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4NbvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4NsvARB) = (PFNGLVERTEXATTRIB4NSVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4NsvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4NsvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4NivARB) = (PFNGLVERTEXATTRIB4NIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4NivARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4NivARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4NubvARB) = (PFNGLVERTEXATTRIB4NUBVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4NubvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4NubvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4NusvARB) = (PFNGLVERTEXATTRIB4NUSVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4NusvARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4NusvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttrib4NuivARB) = (PFNGLVERTEXATTRIB4NUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4NuivARB");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4NuivARB))
- return GL_FALSE;
- GLH_EXT_NAME(glVertexAttribPointerARB) = (PFNGLVERTEXATTRIBPOINTERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB");
- if (NULL == GLH_EXT_NAME(glVertexAttribPointerARB))
- return GL_FALSE;
- GLH_EXT_NAME(glEnableVertexAttribArrayARB) = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");
- if (NULL == GLH_EXT_NAME(glEnableVertexAttribArrayARB))
- return GL_FALSE;
- GLH_EXT_NAME(glDisableVertexAttribArrayARB) = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");
- if (NULL == GLH_EXT_NAME(glDisableVertexAttribArrayARB))
- return GL_FALSE;
- GLH_EXT_NAME(glProgramStringARB) = (PFNGLPROGRAMSTRINGARBPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
- if (NULL == GLH_EXT_NAME(glProgramStringARB))
- return GL_FALSE;
- GLH_EXT_NAME(glBindProgramARB) = (PFNGLBINDPROGRAMARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB");
- if (NULL == GLH_EXT_NAME(glBindProgramARB))
- return GL_FALSE;
- GLH_EXT_NAME(glDeleteProgramsARB) = (PFNGLDELETEPROGRAMSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB");
- if (NULL == GLH_EXT_NAME(glDeleteProgramsARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGenProgramsARB) = (PFNGLGENPROGRAMSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB");
- if (NULL == GLH_EXT_NAME(glGenProgramsARB))
- return GL_FALSE;
- GLH_EXT_NAME(glProgramEnvParameter4dARB) = (PFNGLPROGRAMENVPARAMETER4DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB");
- if (NULL == GLH_EXT_NAME(glProgramEnvParameter4dARB))
- return GL_FALSE;
- GLH_EXT_NAME(glProgramEnvParameter4dvARB) = (PFNGLPROGRAMENVPARAMETER4DVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB");
- if (NULL == GLH_EXT_NAME(glProgramEnvParameter4dvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glProgramEnvParameter4fARB) = (PFNGLPROGRAMENVPARAMETER4FARBPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB");
- if (NULL == GLH_EXT_NAME(glProgramEnvParameter4fARB))
- return GL_FALSE;
- GLH_EXT_NAME(glProgramEnvParameter4fvARB) = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB");
- if (NULL == GLH_EXT_NAME(glProgramEnvParameter4fvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glProgramLocalParameter4dARB) = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB");
- if (NULL == GLH_EXT_NAME(glProgramLocalParameter4dARB))
- return GL_FALSE;
- GLH_EXT_NAME(glProgramLocalParameter4dvARB) = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB");
- if (NULL == GLH_EXT_NAME(glProgramLocalParameter4dvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glProgramLocalParameter4fARB) = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB");
- if (NULL == GLH_EXT_NAME(glProgramLocalParameter4fARB))
- return GL_FALSE;
- GLH_EXT_NAME(glProgramLocalParameter4fvARB) = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB");
- if (NULL == GLH_EXT_NAME(glProgramLocalParameter4fvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGetProgramEnvParameterdvARB) = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB");
- if (NULL == GLH_EXT_NAME(glGetProgramEnvParameterdvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGetProgramEnvParameterfvARB) = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB");
- if (NULL == GLH_EXT_NAME(glGetProgramEnvParameterfvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGetProgramLocalParameterdvARB) = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterdvARB");
- if (NULL == GLH_EXT_NAME(glGetProgramLocalParameterdvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGetProgramLocalParameterfvARB) = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterfvARB");
- if (NULL == GLH_EXT_NAME(glGetProgramLocalParameterfvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGetProgramivARB) = (PFNGLGETPROGRAMIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramivARB");
- if (NULL == GLH_EXT_NAME(glGetProgramivARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGetProgramStringARB) = (PFNGLGETPROGRAMSTRINGARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB");
- if (NULL == GLH_EXT_NAME(glGetProgramStringARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGetVertexAttribdvARB) = (PFNGLGETVERTEXATTRIBDVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvARB");
- if (NULL == GLH_EXT_NAME(glGetVertexAttribdvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGetVertexAttribfvARB) = (PFNGLGETVERTEXATTRIBFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvARB");
- if (NULL == GLH_EXT_NAME(glGetVertexAttribfvARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGetVertexAttribivARB) = (PFNGLGETVERTEXATTRIBIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivARB");
- if (NULL == GLH_EXT_NAME(glGetVertexAttribivARB))
- return GL_FALSE;
- GLH_EXT_NAME(glGetVertexAttribPointervARB) = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribPointervARB");
- if (NULL == GLH_EXT_NAME(glGetVertexAttribPointervARB))
- return GL_FALSE;
- GLH_EXT_NAME(glIsProgramARB) = (PFNGLISPROGRAMARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB");
- if (NULL == GLH_EXT_NAME(glIsProgramARB))
- return GL_FALSE;
-#endif
-
-#ifdef GL_EXT_abgr
- } else if (0 == strcmp(extension, "GL_EXT_abgr")) {
-#endif
-
-#ifdef GL_EXT_bgra
- } else if (0 == strcmp(extension, "GL_EXT_bgra")) {
-#endif
-
-#ifdef GL_EXT_blend_color
- } else if (0 == strcmp(extension, "GL_EXT_blend_color")) {
- GLH_EXT_NAME(glBlendColorEXT) = (PFNGLBLENDCOLOREXTPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendColorEXT");
- if (NULL == GLH_EXT_NAME(glBlendColorEXT))
- return FALSE;
-#endif
-
-#ifdef GL_EXT_blend_minmax
- } else if (0 == strcmp(extension, "GL_EXT_blend_minmax")) {
- GLH_EXT_NAME(glBlendEquationEXT) = (PFNGLBLENDEQUATIONEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendEquationEXT");
- if (NULL == GLH_EXT_NAME(glBlendEquationEXT))
- return FALSE;
-#endif
-
-#ifdef GL_EXT_blend_subtract
- } else if (0 == strcmp(extension, "GL_EXT_blend_subtract")) {
-#endif
-
-#ifdef GL_EXT_compiled_vertex_array
- } else if (0 == strcmp(extension, "GL_EXT_compiled_vertex_array")) {
- GLH_EXT_NAME(glLockArraysEXT) = (PFNGLLOCKARRAYSEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glLockArraysEXT");
- if (NULL == GLH_EXT_NAME(glLockArraysEXT))
- return FALSE;
- GLH_EXT_NAME(glUnlockArraysEXT) = (PFNGLUNLOCKARRAYSEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glUnlockArraysEXT");
- if (NULL == GLH_EXT_NAME(glUnlockArraysEXT))
- return FALSE;
-#endif
-
-#ifdef GL_EXT_fog_coord
- } else if (0 == strcmp(extension, "GL_EXT_fog_coord")) {
- GLH_EXT_NAME(glFogCoorddEXT) = (PFNGLFOGCOORDDEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoorddEXT");
- if (NULL == GLH_EXT_NAME(glFogCoorddEXT))
- return FALSE;
- GLH_EXT_NAME(glFogCoorddvEXT) = (PFNGLFOGCOORDDVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoorddvEXT");
- if (NULL == GLH_EXT_NAME(glFogCoorddvEXT))
- return FALSE;
- GLH_EXT_NAME(glFogCoordfEXT) = (PFNGLFOGCOORDFEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordfEXT");
- if (NULL == GLH_EXT_NAME(glFogCoordfEXT))
- return FALSE;
- GLH_EXT_NAME(glFogCoordfvEXT) = (PFNGLFOGCOORDFVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordfvEXT");
- if (NULL == GLH_EXT_NAME(glFogCoordfvEXT))
- return FALSE;
- GLH_EXT_NAME(glFogCoordPointerEXT) = (PFNGLFOGCOORDPOINTEREXTPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordPointerEXT");
- if (NULL == GLH_EXT_NAME(glFogCoordPointerEXT))
- return FALSE;
-#endif
-
-#ifdef GL_EXT_light_max_exponent
- } else if (0 == strcmp(extension, "GL_EXT_light_max_exponent")) {
-#endif
-
-#ifdef GL_EXT_packed_pixels
- } else if (0 == strcmp(extension, "GL_EXT_packed_pixels")) {
-#endif
-
-#ifdef GL_EXT_paletted_texture
- } else if (0 == strcmp(extension, "GL_EXT_paletted_texture")) {
- GLH_EXT_NAME(glColorSubTableEXT) = (PFNGLCOLORSUBTABLEEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glColorSubTableEXT");
- if (NULL == GLH_EXT_NAME(glColorSubTableEXT))
- return FALSE;
- GLH_EXT_NAME(glColorTableEXT) = (PFNGLCOLORTABLEEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glColorTableEXT");
- if (NULL == GLH_EXT_NAME(glColorTableEXT))
- return FALSE;
- GLH_EXT_NAME(glGetColorTableEXT) = (PFNGLGETCOLORTABLEEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glGetColorTableEXT");
- if (NULL == GLH_EXT_NAME(glGetColorTableEXT))
- return FALSE;
- GLH_EXT_NAME(glGetColorTableParameterfvEXT) = (PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glGetColorTableParameterfvEXT");
- if (NULL == GLH_EXT_NAME(glGetColorTableParameterfvEXT))
- return FALSE;
- GLH_EXT_NAME(glGetColorTableParameterivEXT) = (PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glGetColorTableParameterivEXT");
- if (NULL == GLH_EXT_NAME(glGetColorTableParameterivEXT))
- return FALSE;
-#endif
-
-#ifdef GL_EXT_point_parameters
- } else if (0 == strcmp(extension, "GL_EXT_point_parameters")) {
- GLH_EXT_NAME(glPointParameterfEXT) = (PFNGLPOINTPARAMETERFEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfEXT");
- if (NULL == GLH_EXT_NAME(glPointParameterfEXT))
- return FALSE;
- GLH_EXT_NAME(glPointParameterfvEXT) = (PFNGLPOINTPARAMETERFVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfvEXT");
- if (NULL == GLH_EXT_NAME(glPointParameterfvEXT))
- return FALSE;
-#endif
-
-#ifdef GL_EXT_rescale_normal
- } else if (0 == strcmp(extension, "GL_EXT_rescale_normal")) {
-#endif
-
-#ifdef GL_EXT_secondary_color
- } else if (0 == strcmp(extension, "GL_EXT_secondary_color")) {
- GLH_EXT_NAME(glSecondaryColor3bEXT) = (PFNGLSECONDARYCOLOR3BEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3bEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3bEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3bvEXT) = (PFNGLSECONDARYCOLOR3BVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3bvEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3bvEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3dEXT) = (PFNGLSECONDARYCOLOR3DEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3dEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3dEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3dvEXT) = (PFNGLSECONDARYCOLOR3DVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3dvEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3dvEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3fEXT) = (PFNGLSECONDARYCOLOR3FEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3fEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3fEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3fvEXT) = (PFNGLSECONDARYCOLOR3FVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3fvEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3fvEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3iEXT) = (PFNGLSECONDARYCOLOR3IEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3iEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3iEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3ivEXT) = (PFNGLSECONDARYCOLOR3IVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3ivEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3ivEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3sEXT) = (PFNGLSECONDARYCOLOR3SEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3sEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3sEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3svEXT) = (PFNGLSECONDARYCOLOR3SVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3svEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3svEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3ubEXT) = (PFNGLSECONDARYCOLOR3UBEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3ubEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3ubEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3ubvEXT) = (PFNGLSECONDARYCOLOR3UBVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3ubvEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3ubvEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3uiEXT) = (PFNGLSECONDARYCOLOR3UIEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3uiEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3uiEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3uivEXT) = (PFNGLSECONDARYCOLOR3UIVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3uivEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3uivEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3usEXT) = (PFNGLSECONDARYCOLOR3USEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3usEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3usEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColor3usvEXT) = (PFNGLSECONDARYCOLOR3USVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3usvEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColor3usvEXT))
- return FALSE;
- GLH_EXT_NAME(glSecondaryColorPointerEXT) = (PFNGLSECONDARYCOLORPOINTEREXTPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColorPointerEXT");
- if (NULL == GLH_EXT_NAME(glSecondaryColorPointerEXT))
- return FALSE;
-#endif
-
-#ifdef GL_EXT_separate_specular_color
- } else if (0 == strcmp(extension, "GL_EXT_separate_specular_color")) {
-#endif
-
-#ifdef GL_EXT_shared_texture_palette
- } else if (0 == strcmp(extension, "GL_EXT_shared_texture_palette")) {
-#endif
-
-#ifdef GL_EXT_stencil_wrap
- } else if (0 == strcmp(extension, "GL_EXT_stencil_wrap")) {
-#endif
-
-#ifdef GL_EXT_texture_compression_s3tc
- } else if (0 == strcmp(extension, "GL_EXT_texture_compression_s3tc")) {
-#endif
-
-#ifdef GL_EXT_texture_cube_map
- } else if (0 == strcmp(extension, "GL_EXT_texture_cube_map")) {
-#endif
-
-#ifdef GL_EXT_texture_edge_clamp
- } else if (0 == strcmp(extension, "GL_EXT_texture_edge_clamp")) {
-#endif
-
-#ifdef GL_EXT_texture_env_add
- } else if (0 == strcmp(extension, "GL_EXT_texture_env_add")) {
-#endif
-
-#ifdef GL_EXT_texture_env_combine
- } else if (0 == strcmp(extension, "GL_EXT_texture_env_combine")) {
-#endif
-
-#ifdef GL_EXT_texture_filter_anisotropic
- } else if (0 == strcmp(extension, "GL_EXT_texture_filter_anisotropic")) {
-#endif
-
-#ifdef GL_EXT_texture_lod_bias
- } else if (0 == strcmp(extension, "GL_EXT_texture_lod_bias")) {
-#endif
-
-#ifdef GL_EXT_texture_object
- } else if (0 == strcmp(extension, "GL_EXT_texture_object")) {
- GLH_EXT_NAME(glAreTexturesResidentEXT) = (PFNGLARETEXTURESRESIDENTEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glAreTexturesResidentEXT");
- if (NULL == GLH_EXT_NAME(glAreTexturesResidentEXT))
- return FALSE;
- GLH_EXT_NAME(glBindTextureEXT) = (PFNGLBINDTEXTUREEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glBindTextureEXT");
- if (NULL == GLH_EXT_NAME(glBindTextureEXT))
- return FALSE;
- GLH_EXT_NAME(glDeleteTexturesEXT) = (PFNGLDELETETEXTURESEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteTexturesEXT");
- if (NULL == GLH_EXT_NAME(glDeleteTexturesEXT))
- return FALSE;
- GLH_EXT_NAME(glGenTexturesEXT) = (PFNGLGENTEXTURESEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glGenTexturesEXT");
- if (NULL == GLH_EXT_NAME(glGenTexturesEXT))
- return FALSE;
- GLH_EXT_NAME(glIsTextureEXT) = (PFNGLISTEXTUREEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glIsTextureEXT");
- if (NULL == GLH_EXT_NAME(glIsTextureEXT))
- return FALSE;
- GLH_EXT_NAME(glPrioritizeTexturesEXT) = (PFNGLPRIORITIZETEXTURESEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glPrioritizeTexturesEXT");
- if (NULL == GLH_EXT_NAME(glPrioritizeTexturesEXT))
- return FALSE;
-#endif
-
-#ifdef GL_EXT_texture3D
- } else if (0 == strcmp(extension, "GL_EXT_texture3D")) {
- GLH_EXT_NAME(glTexImage3DEXT) = (PFNGLTEXIMAGE3DEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glTexImage3DEXT");
- if (NULL == GLH_EXT_NAME(glTexImage3DEXT))
- return FALSE;
-#endif
-
-#ifdef GL_EXT_vertex_array
- } else if (0 == strcmp(extension, "GL_EXT_vertex_array")) {
- GLH_EXT_NAME(glArrayElementEXT) = (PFNGLARRAYELEMENTEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glArrayElementEXT");
- if (NULL == GLH_EXT_NAME(glArrayElementEXT))
- return FALSE;
- GLH_EXT_NAME(glColorPointerEXT) = (PFNGLCOLORPOINTEREXTPROC)GLH_EXT_GET_PROC_ADDRESS("glColorPointerEXT");
- if (NULL == GLH_EXT_NAME(glColorPointerEXT))
- return FALSE;
- GLH_EXT_NAME(glEdgeFlagPointerEXT) = (PFNGLEDGEFLAGPOINTEREXTPROC)GLH_EXT_GET_PROC_ADDRESS("glEdgeFlagPointerEXT");
- if (NULL == GLH_EXT_NAME(glEdgeFlagPointerEXT))
- return FALSE;
- GLH_EXT_NAME(glGetPointervEXT) = (PFNGLGETPOINTERVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glGetPointervEXT");
- if (NULL == GLH_EXT_NAME(glGetPointervEXT))
- return FALSE;
- GLH_EXT_NAME(glIndexPointerEXT) = (PFNGLINDEXPOINTEREXTPROC)GLH_EXT_GET_PROC_ADDRESS("glIndexPointerEXT");
- if (NULL == GLH_EXT_NAME(glIndexPointerEXT))
- return FALSE;
- GLH_EXT_NAME(glNormalPointerEXT) = (PFNGLNORMALPOINTEREXTPROC)GLH_EXT_GET_PROC_ADDRESS("glNormalPointerEXT");
- if (NULL == GLH_EXT_NAME(glNormalPointerEXT))
- return FALSE;
- GLH_EXT_NAME(glTexCoordPointerEXT) = (PFNGLTEXCOORDPOINTEREXTPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordPointerEXT");
- if (NULL == GLH_EXT_NAME(glTexCoordPointerEXT))
- return FALSE;
- GLH_EXT_NAME(glVertexPointerEXT) = (PFNGLVERTEXPOINTEREXTPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexPointerEXT");
- if (NULL == GLH_EXT_NAME(glVertexPointerEXT))
- return FALSE;
- GLH_EXT_NAME(glDrawArraysEXT) = (PFNGLDRAWARRAYSEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawArraysEXT");
- if (NULL == GLH_EXT_NAME(glDrawArraysEXT))
- return FALSE;
-#endif
-
-#ifdef GL_EXT_vertex_weighting
- } else if (0 == strcmp(extension, "GL_EXT_vertex_weighting")) {
- GLH_EXT_NAME(glVertexWeightfEXT) = (PFNGLVERTEXWEIGHTFEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexWeightfEXT");
- if (NULL == GLH_EXT_NAME(glVertexWeightfEXT))
- return FALSE;
- GLH_EXT_NAME(glVertexWeightfvEXT) = (PFNGLVERTEXWEIGHTFVEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexWeightfvEXT");
- if (NULL == GLH_EXT_NAME(glVertexWeightfvEXT))
- return FALSE;
- GLH_EXT_NAME(glVertexWeightPointerEXT) = (PFNGLVERTEXWEIGHTPOINTEREXTPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexWeightPointerEXT");
- if (NULL == GLH_EXT_NAME(glVertexWeightPointerEXT))
- return FALSE;
-#endif
-
-#ifdef GL_NV_blend_square
- } else if (0 == strcmp(extension, "GL_NV_blend_square")) {
-#endif
-
-#ifdef GL_NV_evaluators
- } else if (0 == strcmp(extension, "GL_NV_evaluators")) {
- GLH_EXT_NAME(glMapControlPointsNV) = (PFNGLMAPCONTROLPOINTSNVPROC)GLH_EXT_GET_PROC_ADDRESS("glMapControlPointsNV");
- if (NULL == GLH_EXT_NAME(glMapControlPointsNV))
- return FALSE;
- GLH_EXT_NAME(glMapParameterivNV) = (PFNGLMAPPARAMETERIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glMapParameterivNV");
- if (NULL == GLH_EXT_NAME(glMapParameterivNV))
- return FALSE;
- GLH_EXT_NAME(glMapParameterfvNV) = (PFNGLMAPPARAMETERFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glMapParameterfvNV");
- if (NULL == GLH_EXT_NAME(glMapParameterfvNV))
- return FALSE;
- GLH_EXT_NAME(glGetMapControlPointsNV) = (PFNGLGETMAPCONTROLPOINTSNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetMapControlPointsNV");
- if (NULL == GLH_EXT_NAME(glGetMapControlPointsNV))
- return FALSE;
- GLH_EXT_NAME(glGetMapParameterivNV) = (PFNGLGETMAPPARAMETERIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetMapParameterivNV");
- if (NULL == GLH_EXT_NAME(glGetMapParameterivNV))
- return FALSE;
- GLH_EXT_NAME(glGetMapParameterfvNV) = (PFNGLGETMAPPARAMETERFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetMapParameterfvNV");
- if (NULL == GLH_EXT_NAME(glGetMapParameterfvNV))
- return FALSE;
- GLH_EXT_NAME(glGetMapAttribParameterivNV) = (PFNGLGETMAPATTRIBPARAMETERIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetMapAttribParameterivNV");
- if (NULL == GLH_EXT_NAME(glGetMapAttribParameterivNV))
- return FALSE;
- GLH_EXT_NAME(glGetMapAttribParameterfvNV) = (PFNGLGETMAPATTRIBPARAMETERFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetMapAttribParameterfvNV");
- if (NULL == GLH_EXT_NAME(glGetMapAttribParameterfvNV))
- return FALSE;
- GLH_EXT_NAME(glEvalMapsNV) = (PFNGLEVALMAPSNVPROC)GLH_EXT_GET_PROC_ADDRESS("glEvalMapsNV");
- if (NULL == GLH_EXT_NAME(glEvalMapsNV))
- return FALSE;
-#endif
-
-#ifdef GL_NV_fence
- } else if (0 == strcmp(extension, "GL_NV_fence")) {
- GLH_EXT_NAME(glGenFencesNV) = (PFNGLGENFENCESNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGenFencesNV");
- if (NULL == GLH_EXT_NAME(glGenFencesNV))
- return FALSE;
- GLH_EXT_NAME(glDeleteFencesNV) = (PFNGLDELETEFENCESNVPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteFencesNV");
- if (NULL == GLH_EXT_NAME(glDeleteFencesNV))
- return FALSE;
- GLH_EXT_NAME(glSetFenceNV) = (PFNGLSETFENCENVPROC)GLH_EXT_GET_PROC_ADDRESS("glSetFenceNV");
- if (NULL == GLH_EXT_NAME(glSetFenceNV))
- return FALSE;
- GLH_EXT_NAME(glTestFenceNV) = (PFNGLTESTFENCENVPROC)GLH_EXT_GET_PROC_ADDRESS("glTestFenceNV");
- if (NULL == GLH_EXT_NAME(glTestFenceNV))
- return FALSE;
- GLH_EXT_NAME(glFinishFenceNV) = (PFNGLFINISHFENCENVPROC)GLH_EXT_GET_PROC_ADDRESS("glFinishFenceNV");
- if (NULL == GLH_EXT_NAME(glFinishFenceNV))
- return FALSE;
- GLH_EXT_NAME(glIsFenceNV) = (PFNGLISFENCENVPROC)GLH_EXT_GET_PROC_ADDRESS("glIsFenceNV");
- if (NULL == GLH_EXT_NAME(glIsFenceNV))
- return FALSE;
- GLH_EXT_NAME(glGetFenceivNV) = (PFNGLGETFENCEIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFenceivNV");
- if (NULL == GLH_EXT_NAME(glGetFenceivNV))
- return FALSE;
-#endif
-
-#ifdef GL_NV_fog_distance
- } else if (0 == strcmp(extension, "GL_NV_fog_distance")) {
-#endif
-
-#ifdef GL_NV_packed_depth_stencil
- } else if (0 == strcmp(extension, "GL_NV_packed_depth_stencil")) {
-#endif
-
-#ifdef GL_NV_register_combiners
- } else if (0 == strcmp(extension, "GL_NV_register_combiners")) {
- GLH_EXT_NAME(glCombinerParameterfvNV) = (PFNGLCOMBINERPARAMETERFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glCombinerParameterfvNV");
- if (NULL == GLH_EXT_NAME(glCombinerParameterfvNV))
- return FALSE;
- GLH_EXT_NAME(glCombinerParameterfNV) = (PFNGLCOMBINERPARAMETERFNVPROC)GLH_EXT_GET_PROC_ADDRESS("glCombinerParameterfNV");
- if (NULL == GLH_EXT_NAME(glCombinerParameterfNV))
- return FALSE;
- GLH_EXT_NAME(glCombinerParameterivNV) = (PFNGLCOMBINERPARAMETERIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glCombinerParameterivNV");
- if (NULL == GLH_EXT_NAME(glCombinerParameterivNV))
- return FALSE;
- GLH_EXT_NAME(glCombinerParameteriNV) = (PFNGLCOMBINERPARAMETERINVPROC)GLH_EXT_GET_PROC_ADDRESS("glCombinerParameteriNV");
- if (NULL == GLH_EXT_NAME(glCombinerParameteriNV))
- return FALSE;
- GLH_EXT_NAME(glCombinerInputNV) = (PFNGLCOMBINERINPUTNVPROC)GLH_EXT_GET_PROC_ADDRESS("glCombinerInputNV");
- if (NULL == GLH_EXT_NAME(glCombinerInputNV))
- return FALSE;
- GLH_EXT_NAME(glCombinerOutputNV) = (PFNGLCOMBINEROUTPUTNVPROC)GLH_EXT_GET_PROC_ADDRESS("glCombinerOutputNV");
- if (NULL == GLH_EXT_NAME(glCombinerOutputNV))
- return FALSE;
- GLH_EXT_NAME(glFinalCombinerInputNV) = (PFNGLFINALCOMBINERINPUTNVPROC)GLH_EXT_GET_PROC_ADDRESS("glFinalCombinerInputNV");
- if (NULL == GLH_EXT_NAME(glFinalCombinerInputNV))
- return FALSE;
- GLH_EXT_NAME(glGetCombinerInputParameterfvNV) = (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCombinerInputParameterfvNV");
- if (NULL == GLH_EXT_NAME(glGetCombinerInputParameterfvNV))
- return FALSE;
- GLH_EXT_NAME(glGetCombinerInputParameterivNV) = (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCombinerInputParameterivNV");
- if (NULL == GLH_EXT_NAME(glGetCombinerInputParameterivNV))
- return FALSE;
- GLH_EXT_NAME(glGetCombinerOutputParameterfvNV) = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCombinerOutputParameterfvNV");
- if (NULL == GLH_EXT_NAME(glGetCombinerOutputParameterfvNV))
- return FALSE;
- GLH_EXT_NAME(glGetCombinerOutputParameterivNV) = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCombinerOutputParameterivNV");
- if (NULL == GLH_EXT_NAME(glGetCombinerOutputParameterivNV))
- return FALSE;
- GLH_EXT_NAME(glGetFinalCombinerInputParameterfvNV) = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFinalCombinerInputParameterfvNV");
- if (NULL == GLH_EXT_NAME(glGetFinalCombinerInputParameterfvNV))
- return FALSE;
- GLH_EXT_NAME(glGetFinalCombinerInputParameterivNV) = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFinalCombinerInputParameterivNV");
- if (NULL == GLH_EXT_NAME(glGetFinalCombinerInputParameterivNV))
- return FALSE;
-#endif
-
-#ifdef GL_NV_register_combiners2
- } else if (0 == strcmp(extension, "GL_NV_register_combiners2")) {
- GLH_EXT_NAME(glCombinerStageParameterfvNV) = (PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glCombinerStageParameterfvNV");
- if (NULL == GLH_EXT_NAME(glCombinerStageParameterfvNV))
- return FALSE;
- GLH_EXT_NAME(glGetCombinerStageParameterfvNV) = (PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCombinerStageParameterfvNV");
- if (NULL == GLH_EXT_NAME(glGetCombinerStageParameterfvNV))
- return FALSE;
-#endif
-
-#ifdef GL_NV_texgen_reflection
- } else if (0 == strcmp(extension, "GL_NV_texgen_reflection")) {
-#endif
-
-#ifdef GL_NV_texture_env_combine4
- } else if (0 == strcmp(extension, "GL_NV_texture_env_combine4")) {
-#endif
-
-#ifdef GL_NV_texture_rectangle
- } else if (0 == strcmp(extension, "GL_NV_texture_rectangle")) {
-#endif
-
-#ifdef GL_NV_texture_shader
- } else if (0 == strcmp(extension, "GL_NV_texture_shader")) {
-#endif
-
-#ifdef GL_NV_vertex_array_range
- } else if (0 == strcmp(extension, "GL_NV_vertex_array_range")) {
- GLH_EXT_NAME(glFlushVertexArrayRangeNV) = (PFNGLFLUSHVERTEXARRAYRANGENVPROC)GLH_EXT_GET_PROC_ADDRESS("glFlushVertexArrayRangeNV");
- if (NULL == GLH_EXT_NAME(glFlushVertexArrayRangeNV))
- return FALSE;
- GLH_EXT_NAME(glVertexArrayRangeNV) = (PFNGLVERTEXARRAYRANGENVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayRangeNV");
- if (NULL == GLH_EXT_NAME(glVertexArrayRangeNV))
- return FALSE;
-# ifdef _WIN32
- GLH_EXT_NAME(wglAllocateMemoryNV) = (PFNWGLALLOCATEMEMORYNVPROC)GLH_EXT_GET_PROC_ADDRESS("wglAllocateMemoryNV");
- if (NULL == GLH_EXT_NAME(wglAllocateMemoryNV))
- return FALSE;
-# endif
-# ifdef GLX_VERSION_1_3
- GLH_EXT_NAME(glXAllocateMemoryNV) = (PFNGLXALLOCATEMEMORYNVPROC)GLH_EXT_GET_PROC_ADDRESS("glXAllocateMemoryNV");
- if (NULL == GLH_EXT_NAME(glXAllocateMemoryNV))
- return FALSE;
-# endif
-# ifdef _WIN32
- GLH_EXT_NAME(wglFreeMemoryNV) = (PFNWGLFREEMEMORYNVPROC)GLH_EXT_GET_PROC_ADDRESS("wglFreeMemoryNV");
- if (NULL == GLH_EXT_NAME(wglFreeMemoryNV))
- return FALSE;
-# endif
-# ifdef GLX_VERSION_1_3
- GLH_EXT_NAME(glXFreeMemoryNV) = (PFNGLXFREEMEMORYNVPROC)GLH_EXT_GET_PROC_ADDRESS("glXFreeMemoryNV");
- if (NULL == GLH_EXT_NAME(glXFreeMemoryNV))
- return FALSE;
-# endif
-#endif
-
-#ifdef GL_NV_vertex_program
- } else if (0 == strcmp(extension, "GL_NV_vertex_program")) {
- GLH_EXT_NAME(glAreProgramsResidentNV) = (PFNGLAREPROGRAMSRESIDENTNVPROC)GLH_EXT_GET_PROC_ADDRESS("glAreProgramsResidentNV");
- if (NULL == GLH_EXT_NAME(glAreProgramsResidentNV))
- return FALSE;
- GLH_EXT_NAME(glBindProgramNV) = (PFNGLBINDPROGRAMNVPROC)GLH_EXT_GET_PROC_ADDRESS("glBindProgramNV");
- if (NULL == GLH_EXT_NAME(glBindProgramNV))
- return FALSE;
- GLH_EXT_NAME(glDeleteProgramsNV) = (PFNGLDELETEPROGRAMSNVPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsNV");
- if (NULL == GLH_EXT_NAME(glDeleteProgramsNV))
- return FALSE;
- GLH_EXT_NAME(glExecuteProgramNV) = (PFNGLEXECUTEPROGRAMNVPROC)GLH_EXT_GET_PROC_ADDRESS("glExecuteProgramNV");
- if (NULL == GLH_EXT_NAME(glExecuteProgramNV))
- return FALSE;
- GLH_EXT_NAME(glGenProgramsNV) = (PFNGLGENPROGRAMSNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGenProgramsNV");
- if (NULL == GLH_EXT_NAME(glGenProgramsNV))
- return FALSE;
- GLH_EXT_NAME(glGetProgramParameterdvNV) = (PFNGLGETPROGRAMPARAMETERDVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramParameterdvNV");
- if (NULL == GLH_EXT_NAME(glGetProgramParameterdvNV))
- return FALSE;
- GLH_EXT_NAME(glGetProgramParameterfvNV) = (PFNGLGETPROGRAMPARAMETERFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramParameterfvNV");
- if (NULL == GLH_EXT_NAME(glGetProgramParameterfvNV))
- return FALSE;
- GLH_EXT_NAME(glGetProgramivNV) = (PFNGLGETPROGRAMIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramivNV");
- if (NULL == GLH_EXT_NAME(glGetProgramivNV))
- return FALSE;
- GLH_EXT_NAME(glGetProgramStringNV) = (PFNGLGETPROGRAMSTRINGNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringNV");
- if (NULL == GLH_EXT_NAME(glGetProgramStringNV))
- return FALSE;
- GLH_EXT_NAME(glGetTrackMatrixivNV) = (PFNGLGETTRACKMATRIXIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTrackMatrixivNV");
- if (NULL == GLH_EXT_NAME(glGetTrackMatrixivNV))
- return FALSE;
- GLH_EXT_NAME(glGetVertexAttribdvNV) = (PFNGLGETVERTEXATTRIBDVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvNV");
- if (NULL == GLH_EXT_NAME(glGetVertexAttribdvNV))
- return FALSE;
- GLH_EXT_NAME(glGetVertexAttribfvNV) = (PFNGLGETVERTEXATTRIBFVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvNV");
- if (NULL == GLH_EXT_NAME(glGetVertexAttribfvNV))
- return FALSE;
- GLH_EXT_NAME(glGetVertexAttribivNV) = (PFNGLGETVERTEXATTRIBIVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivNV");
- if (NULL == GLH_EXT_NAME(glGetVertexAttribivNV))
- return FALSE;
- GLH_EXT_NAME(glGetVertexAttribPointervNV) = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribPointervNV");
- if (NULL == GLH_EXT_NAME(glGetVertexAttribPointervNV))
- return FALSE;
- GLH_EXT_NAME(glIsProgramNV) = (PFNGLISPROGRAMNVPROC)GLH_EXT_GET_PROC_ADDRESS("glIsProgramNV");
- if (NULL == GLH_EXT_NAME(glIsProgramNV))
- return FALSE;
- GLH_EXT_NAME(glLoadProgramNV) = (PFNGLLOADPROGRAMNVPROC)GLH_EXT_GET_PROC_ADDRESS("glLoadProgramNV");
- if (NULL == GLH_EXT_NAME(glLoadProgramNV))
- return FALSE;
- GLH_EXT_NAME(glProgramParameter4dNV) = (PFNGLPROGRAMPARAMETER4DNVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramParameter4dNV");
- if (NULL == GLH_EXT_NAME(glProgramParameter4dNV))
- return FALSE;
- GLH_EXT_NAME(glProgramParameter4dvNV) = (PFNGLPROGRAMPARAMETER4DVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramParameter4dvNV");
- if (NULL == GLH_EXT_NAME(glProgramParameter4dvNV))
- return FALSE;
- GLH_EXT_NAME(glProgramParameter4fNV) = (PFNGLPROGRAMPARAMETER4FNVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramParameter4fNV");
- if (NULL == GLH_EXT_NAME(glProgramParameter4fNV))
- return FALSE;
- GLH_EXT_NAME(glProgramParameter4fvNV) = (PFNGLPROGRAMPARAMETER4FVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramParameter4fvNV");
- if (NULL == GLH_EXT_NAME(glProgramParameter4fvNV))
- return FALSE;
- GLH_EXT_NAME(glProgramParameters4dvNV) = (PFNGLPROGRAMPARAMETERS4DVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramParameters4dvNV");
- if (NULL == GLH_EXT_NAME(glProgramParameters4dvNV))
- return FALSE;
- GLH_EXT_NAME(glProgramParameters4fvNV) = (PFNGLPROGRAMPARAMETERS4FVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramParameters4fvNV");
- if (NULL == GLH_EXT_NAME(glProgramParameters4fvNV))
- return FALSE;
- GLH_EXT_NAME(glRequestResidentProgramsNV) = (PFNGLREQUESTRESIDENTPROGRAMSNVPROC)GLH_EXT_GET_PROC_ADDRESS("glRequestResidentProgramsNV");
- if (NULL == GLH_EXT_NAME(glRequestResidentProgramsNV))
- return FALSE;
- GLH_EXT_NAME(glTrackMatrixNV) = (PFNGLTRACKMATRIXNVPROC)GLH_EXT_GET_PROC_ADDRESS("glTrackMatrixNV");
- if (NULL == GLH_EXT_NAME(glTrackMatrixNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribPointerNV) = (PFNGLVERTEXATTRIBPOINTERNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribPointerNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib1dNV) = (PFNGLVERTEXATTRIB1DNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1dNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib1dvNV) = (PFNGLVERTEXATTRIB1DVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1dvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib1fNV) = (PFNGLVERTEXATTRIB1FNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1fNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib1fvNV) = (PFNGLVERTEXATTRIB1FVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1fvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib1sNV) = (PFNGLVERTEXATTRIB1SNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1sNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib1svNV) = (PFNGLVERTEXATTRIB1SVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib1svNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib2dNV) = (PFNGLVERTEXATTRIB2DNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2dNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib2dvNV) = (PFNGLVERTEXATTRIB2DVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2dvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib2fNV) = (PFNGLVERTEXATTRIB2FNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2fNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib2fvNV) = (PFNGLVERTEXATTRIB2FVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2fvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib2sNV) = (PFNGLVERTEXATTRIB2SNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2sNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib2svNV) = (PFNGLVERTEXATTRIB2SVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib2svNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib3dNV) = (PFNGLVERTEXATTRIB3DNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3dNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib3dvNV) = (PFNGLVERTEXATTRIB3DVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3dvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib3fNV) = (PFNGLVERTEXATTRIB3FNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3fNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib3fvNV) = (PFNGLVERTEXATTRIB3FVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3fvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib3sNV) = (PFNGLVERTEXATTRIB3SNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3sNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib3svNV) = (PFNGLVERTEXATTRIB3SVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib3svNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib4dNV) = (PFNGLVERTEXATTRIB4DNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4dNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib4dvNV) = (PFNGLVERTEXATTRIB4DVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4dvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib4fNV) = (PFNGLVERTEXATTRIB4FNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4fNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib4fvNV) = (PFNGLVERTEXATTRIB4FVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4fvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib4sNV) = (PFNGLVERTEXATTRIB4SNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4sNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib4svNV) = (PFNGLVERTEXATTRIB4SVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4svNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttrib4ubvNV) = (PFNGLVERTEXATTRIB4UBVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttrib4ubvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs1dvNV) = (PFNGLVERTEXATTRIBS1DVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs1dvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs1dvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs1fvNV) = (PFNGLVERTEXATTRIBS1FVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs1fvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs1fvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs1svNV) = (PFNGLVERTEXATTRIBS1SVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs1svNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs1svNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs2dvNV) = (PFNGLVERTEXATTRIBS2DVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs2dvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs2dvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs2fvNV) = (PFNGLVERTEXATTRIBS2FVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs2fvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs2fvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs2svNV) = (PFNGLVERTEXATTRIBS2SVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs2svNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs2svNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs3dvNV) = (PFNGLVERTEXATTRIBS3DVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs3dvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs3dvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs3fvNV) = (PFNGLVERTEXATTRIBS3FVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs3fvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs3fvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs3svNV) = (PFNGLVERTEXATTRIBS3SVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs3svNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs3svNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs4dvNV) = (PFNGLVERTEXATTRIBS4DVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs4dvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs4dvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs4fvNV) = (PFNGLVERTEXATTRIBS4FVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs4fvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs4fvNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs4svNV) = (PFNGLVERTEXATTRIBS4SVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs4svNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs4svNV))
- return FALSE;
- GLH_EXT_NAME(glVertexAttribs4ubvNV) = (PFNGLVERTEXATTRIBS4UBVNVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribs4ubvNV");
- if (NULL == GLH_EXT_NAME(glVertexAttribs4ubvNV))
- return FALSE;
-#endif
-
-#ifdef GL_SGIS_generate_mipmap
- } else if (0 == strcmp(extension, "GL_SGIS_generate_mipmap")) {
-#endif
-
-#ifdef GL_SGIS_texture_lod
- } else if (0 == strcmp(extension, "GL_SGIS_texture_lod")) {
-#endif
-
-#ifdef GL_SGIX_depth_texture
- } else if (0 == strcmp(extension, "GL_SGIX_depth_texture")) {
-#endif
-
-#ifdef GL_SGIX_shadow
- } else if (0 == strcmp(extension, "GL_SGIX_shadow")) {
-#endif
-
-#ifdef GL_VERSION_1_2
- } else if (0 == strcmp(extension, "GL_VERSION_1_2")) {
- GLH_CORE_1_2_NAME(glBlendColor) = (PFNGLBLENDCOLORPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendColor");
- if (NULL == GLH_CORE_1_2_NAME(glBlendColor))
- return FALSE;
- GLH_CORE_1_2_NAME(glBlendEquation) = (PFNGLBLENDEQUATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendEquation");
- if (NULL == GLH_CORE_1_2_NAME(glBlendEquation))
- return FALSE;
- GLH_CORE_1_2_NAME(glDrawRangeElements) = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
- if (NULL == GLH_CORE_1_2_NAME(glDrawRangeElements))
- return FALSE;
- GLH_CORE_1_2_NAME(glColorTable) = (PFNGLCOLORTABLEPROC)GLH_EXT_GET_PROC_ADDRESS("glColorTable");
- if (NULL == GLH_CORE_1_2_NAME(glColorTable))
- return FALSE;
- GLH_CORE_1_2_NAME(glColorTableParameterfv) = (PFNGLCOLORTABLEPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glColorTableParameterfv");
- if (NULL == GLH_CORE_1_2_NAME(glColorTableParameterfv))
- return FALSE;
- GLH_CORE_1_2_NAME(glColorTableParameteriv) = (PFNGLCOLORTABLEPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glColorTableParameteriv");
- if (NULL == GLH_CORE_1_2_NAME(glColorTableParameteriv))
- return FALSE;
- GLH_CORE_1_2_NAME(glCopyColorTable) = (PFNGLCOPYCOLORTABLEPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyColorTable");
- if (NULL == GLH_CORE_1_2_NAME(glCopyColorTable))
- return FALSE;
- GLH_CORE_1_2_NAME(glGetColorTable) = (PFNGLGETCOLORTABLEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetColorTable");
- if (NULL == GLH_CORE_1_2_NAME(glGetColorTable))
- return FALSE;
- GLH_CORE_1_2_NAME(glGetColorTableParameterfv) = (PFNGLGETCOLORTABLEPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetColorTableParameterfv");
- if (NULL == GLH_CORE_1_2_NAME(glGetColorTableParameterfv))
- return FALSE;
- GLH_CORE_1_2_NAME(glGetColorTableParameteriv) = (PFNGLGETCOLORTABLEPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetColorTableParameteriv");
- if (NULL == GLH_CORE_1_2_NAME(glGetColorTableParameteriv))
- return FALSE;
- GLH_CORE_1_2_NAME(glTexImage3D) = (PFNGLTEXIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexImage3D");
- if (NULL == GLH_CORE_1_2_NAME(glTexImage3D))
- return FALSE;
- GLH_CORE_1_2_NAME(glTexSubImage3D) = (PFNGLTEXSUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexSubImage3D");
- if (NULL == GLH_CORE_1_2_NAME(glTexSubImage3D))
- return FALSE;
- GLH_CORE_1_2_NAME(glCopyTexSubImage3D) = (PFNGLCOPYTEXSUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyTexSubImage3D");
- if (NULL == GLH_CORE_1_2_NAME(glCopyTexSubImage3D))
- return FALSE;
-#endif
-
-#ifdef GL_WIN_swap_hint
- } else if (0 == strcmp(extension, "GL_WIN_swap_hint")) {
- GLH_EXT_NAME(glAddSwapHintRectWIN) = (PFNGLADDSWAPHINTRECTWINPROC)GLH_EXT_GET_PROC_ADDRESS("glAddSwapHintRectWIN");
- if (NULL == GLH_EXT_NAME(glAddSwapHintRectWIN))
- return FALSE;
-#endif
-
-#ifdef WGL_ARB_pbuffer
- } else if (0 == strcmp(extension, "WGL_ARB_pbuffer")) {
-# ifdef _WIN32
- GLH_EXT_NAME(wglCreatePbufferARB) = (PFNWGLCREATEPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreatePbufferARB");
- if (NULL == GLH_EXT_NAME(wglCreatePbufferARB))
- return FALSE;
-# endif
-# ifdef _WIN32
- GLH_EXT_NAME(wglGetPbufferDCARB) = (PFNWGLGETPBUFFERDCARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetPbufferDCARB");
- if (NULL == GLH_EXT_NAME(wglGetPbufferDCARB))
- return FALSE;
-# endif
-# ifdef _WIN32
- GLH_EXT_NAME(wglReleasePbufferDCARB) = (PFNWGLRELEASEPBUFFERDCARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglReleasePbufferDCARB");
- if (NULL == GLH_EXT_NAME(wglReleasePbufferDCARB))
- return FALSE;
-# endif
-# ifdef _WIN32
- GLH_EXT_NAME(wglDestroyPbufferARB) = (PFNWGLDESTROYPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglDestroyPbufferARB");
- if (NULL == GLH_EXT_NAME(wglDestroyPbufferARB))
- return FALSE;
-# endif
-# ifdef _WIN32
- GLH_EXT_NAME(wglQueryPbufferARB) = (PFNWGLQUERYPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglQueryPbufferARB");
- if (NULL == GLH_EXT_NAME(wglQueryPbufferARB))
- return FALSE;
-# endif
-#endif
-
-#ifdef WGL_ARB_render_texture
-# ifdef _WIN32
- GLH_EXT_NAME(wglBindTexImageARB) = (PFNWGLBINDTEXIMAGEARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglBindTexImageARB");
- if (NULL == GLH_EXT_NAME(wglBindTexImageARB))
- return FALSE;
-# endif
-# ifdef _WIN32
- GLH_EXT_NAME(wglReleaseTexImageARB) = (PFNWGLRELEASETEXIMAGEARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglReleaseTexImageARB");
- if (NULL == GLH_EXT_NAME(wglReleaseTexImageARB))
- return FALSE;
-# endif
-# ifdef _WIN32
- GLH_EXT_NAME(wglSetPbufferAttribARB) = (PFNWGLSETPBUFFERATTRIBARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglSetPbufferAttribARB");
- if (NULL == GLH_EXT_NAME(wglSetPbufferAttribARB))
- return FALSE;
-# endif
-#endif
-
-#ifdef WGL_ARB_pixel_format
- } else if (0 == strcmp(extension, "WGL_ARB_pixel_format")) {
-# ifdef _WIN32
- GLH_EXT_NAME(wglGetPixelFormatAttribivARB) = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetPixelFormatAttribivARB");
- if (NULL == GLH_EXT_NAME(wglGetPixelFormatAttribivARB))
- return FALSE;
-# endif
-# ifdef _WIN32
- GLH_EXT_NAME(wglGetPixelFormatAttribfvARB) = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetPixelFormatAttribfvARB");
- if (NULL == GLH_EXT_NAME(wglGetPixelFormatAttribfvARB))
- return FALSE;
-# endif
-# ifdef _WIN32
- GLH_EXT_NAME(wglChoosePixelFormatARB) = (PFNWGLCHOOSEPIXELFORMATARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglChoosePixelFormatARB");
- if (NULL == GLH_EXT_NAME(wglChoosePixelFormatARB))
- return FALSE;
-# endif
-#endif
-
- } else {
- return FALSE;
- }
- return TRUE;
-}
-#endif
-
-#else // defined(__APPLE__)
-
-#ifdef GLH_EXT_SINGLE_FILE
-
-int glh_init_extension(const char* extension)
-{
- // MBW -- XXX -- Should this check for extension availability?
- return TRUE;
-}
-#endif // GLH_EXT_SINGLE_FILE
-
-#endif // defined(__APPLE__)
-
-#undef GLH_EXT_SINGLE_FILE
-
-#endif /* GLH_GENEXT_H */
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index f9b387b00b..fd20f2ad15 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -288,7 +288,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
if (vsync)
{
- [glContext setValues:(const GLint*)1 forParameter:NSOpenGLCPSwapInterval];
+ GLint value = 1;
+ [glContext setValues:&value forParameter:NSOpenGLCPSwapInterval];
} else {
// supress this error after move to Xcode 7:
// error: null passed to a callee that requires a non-null argument [-Werror,-Wnonnull]
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index 30bc743e72..f4678a70c5 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -137,6 +137,12 @@ BOOL LLWindow::canDelete()
return TRUE;
}
+//virtual
+void LLWindow::setTitle(const std::string title)
+{
+ // the action happens in the platform specific impl
+}
+
// virtual
void LLWindow::incBusyCount()
{
@@ -397,7 +403,7 @@ LLWindow* LLWindowManager::createWindow(
const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags,
BOOL fullscreen,
BOOL clearBg,
- BOOL disable_vsync,
+ BOOL enable_vsync,
BOOL use_gl,
BOOL ignore_pixel_depth,
U32 fsaa_samples)
@@ -409,26 +415,26 @@ LLWindow* LLWindowManager::createWindow(
#if LL_MESA_HEADLESS
new_window = new LLWindowMesaHeadless(callbacks,
title, name, x, y, width, height, flags,
- fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
+ fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth);
#elif LL_SDL
new_window = new LLWindowSDL(callbacks,
title, x, y, width, height, flags,
- fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
+ fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
#elif LL_WINDOWS
new_window = new LLWindowWin32(callbacks,
title, name, x, y, width, height, flags,
- fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
+ fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
#elif LL_DARWIN
new_window = new LLWindowMacOSX(callbacks,
title, name, x, y, width, height, flags,
- fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
+ fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
#endif
}
else
{
new_window = new LLWindowHeadless(callbacks,
title, name, x, y, width, height, flags,
- fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
+ fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth);
}
if (FALSE == new_window->isValid())
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index d4d5b76937..43d81e4d59 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -77,15 +77,37 @@ public:
BOOL setSize(LLCoordScreen size);
BOOL setSize(LLCoordWindow size);
virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true);
- virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) = 0;
- virtual BOOL setCursorPosition(LLCoordWindow position) = 0;
+ virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) = 0;
+
+ //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread
+ // returns a pointer to be handed back to destroySharedConext/makeContextCurrent
+ virtual void* createSharedContext() = 0;
+ //make the given context current on the current thread
+ virtual void makeContextCurrent(void* context) = 0;
+ //destroy the given context that was retrieved by createSharedContext()
+ //Must be called on the same thread that called createSharedContext()
+ virtual void destroySharedContext(void* context) = 0;
+
+
+ virtual BOOL setCursorPosition(LLCoordWindow position) = 0;
virtual BOOL getCursorPosition(LLCoordWindow *position) = 0;
+#if LL_WINDOWS
+ virtual void toggleVSync(bool enable_vsync) = 0;
+ virtual BOOL getCursorDelta(LLCoordCommon* delta) = 0;
+#endif
virtual void showCursor() = 0;
virtual void hideCursor() = 0;
virtual BOOL isCursorHidden() = 0;
virtual void showCursorFromMouseMove() = 0;
virtual void hideCursorUntilMouseMove() = 0;
+ // Provide a way to set the Viewer window title after the
+ // windows has been created. The initial use case for this
+ // is described in SL-16102 (update window title with agent
+ // name, location etc. for non-interactive viewer) but it
+ // may also be useful in other cases.
+ virtual void setTitle(const std::string title);
+
// These two functions create a way to make a busy cursor instead
// of an arrow when someone's busy doing something. Draw an
// arrow/hour if busycount > 0.
@@ -274,7 +296,7 @@ public:
U32 flags = 0,
BOOL fullscreen = FALSE,
BOOL clearBg = FALSE,
- BOOL disable_vsync = TRUE,
+ BOOL enable_vsync = FALSE,
BOOL use_gl = TRUE,
BOOL ignore_pixel_depth = FALSE,
U32 fsaa_samples = 0);
diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp
index 70f473281b..c3738af6ca 100644
--- a/indra/llwindow/llwindowheadless.cpp
+++ b/indra/llwindow/llwindowheadless.cpp
@@ -35,7 +35,7 @@
//
LLWindowHeadless::LLWindowHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
U32 flags, BOOL fullscreen, BOOL clear_background,
- BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth)
+ BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth)
: LLWindow(callbacks, fullscreen, flags)
{
// Initialize a headless keyboard.
diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h
index c692666df1..78c5e4bae4 100644
--- a/indra/llwindow/llwindowheadless.h
+++ b/indra/llwindow/llwindowheadless.h
@@ -48,9 +48,16 @@ public:
/*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;};
/*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;};
/*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;};
- /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;};
+ /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;};
+ void* createSharedContext() { return nullptr; }
+ void makeContextCurrent(void*) {}
+ void destroySharedContext(void*) {}
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;};
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;};
+#if LL_WINDOWS
+ /*virtual*/ virtual void toggleVSync(bool enable_vsync) { }
+ /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) { return FALSE; }
+#endif
/*virtual*/ void showCursor() {};
/*virtual*/ void hideCursor() {};
/*virtual*/ void showCursorFromMouseMove() {};
@@ -97,7 +104,7 @@ public:
S32 x, S32 y,
S32 width, S32 height,
U32 flags, BOOL fullscreen, BOOL clear_background,
- BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth);
+ BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth);
virtual ~LLWindowHeadless();
private:
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index dfdfe4aa33..dac84690db 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -111,7 +111,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
S32 height, U32 flags,
BOOL fullscreen, BOOL clearBg,
- BOOL disable_vsync, BOOL use_gl,
+ BOOL enable_vsync, BOOL use_gl,
BOOL ignore_pixel_depth,
U32 fsaa_samples)
: LLWindow(NULL, fullscreen, flags)
@@ -165,7 +165,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
// Stash an object pointer for OSMessageBox()
gWindowImplementation = this;
// 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))
{
if(mWindow != NULL)
{
@@ -619,7 +619,7 @@ void LLWindowMacOSX::getMouseDeltas(float* delta)
delta[1] = mCursorLastEventDeltaY;
}
-BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync)
+BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync)
{
BOOL glNeedsInit = FALSE;
@@ -634,7 +634,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
{
// Our OpenGL view is already defined within SecondLife.xib.
// Get the view instead.
- mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync);
+ mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync);
mContext = getCGLContextObj(mGLView);
// Since we just created the context, it needs to be set up.
@@ -662,7 +662,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
// Disable vertical sync for swap
GLint frames_per_swap = 0;
- if (disable_vsync)
+ if (!enable_vsync)
{
frames_per_swap = 0;
}
@@ -698,7 +698,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
// We only support OS X 10.7's fullscreen app mode which is literally a full screen window that fills a virtual desktop.
// This makes this method obsolete.
-BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp)
+BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp)
{
return FALSE;
}
@@ -1916,6 +1916,34 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
allowDirectMarkedTextInput(b, mGLView); // mLanguageTextInputAllowed and mMarkedTextAllowed should be updated at once (by Pell Smit
}
+class sharedContext
+{
+public:
+ CGLContextObj mContext;
+};
+
+void* LLWindowMacOSX::createSharedContext()
+{
+ sharedContext* sc = new sharedContext();
+ CGLCreateContext(mPixelFormat, mContext, &(sc->mContext));
+
+ return (void *)sc;
+}
+
+void LLWindowMacOSX::makeContextCurrent(void* context)
+{
+ CGLSetCurrentContext(((sharedContext*)context)->mContext);
+}
+
+void LLWindowMacOSX::destroySharedContext(void* context)
+{
+ sharedContext* sc = (sharedContext*)context;
+
+ CGLDestroyContext(sc->mContext);
+
+ delete sc;
+}
+
void LLWindowMacOSX::interruptLanguageTextInput()
{
commitCurrentPreedit(mGLView);
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index bf45238c8d..18fa86930f 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -41,85 +41,84 @@
#undef verify
#undef require
-
class LLWindowMacOSX : 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*/ void showCursor();
- /*virtual*/ void hideCursor();
- /*virtual*/ void showCursorFromMouseMove();
- /*virtual*/ void hideCursorUntilMouseMove();
- /*virtual*/ BOOL isCursorHidden();
- /*virtual*/ void updateCursor();
- /*virtual*/ ECursorType getCursor() const;
- /*virtual*/ void captureMouse();
- /*virtual*/ void releaseMouse();
- /*virtual*/ void setMouseClipping( BOOL b );
- /*virtual*/ BOOL isClipboardTextAvailable();
- /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst);
- /*virtual*/ BOOL copyTextToClipboard(const LLWString & src);
- /*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 fsaa_samples);
- /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma)
- /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; }
- /*virtual*/ void gatherInput();
- /*virtual*/ void delayInputProcessing() {};
- /*virtual*/ void swapBuffers();
+ void show() override;
+ void hide() override;
+ void close() override;
+ BOOL getVisible() override;
+ BOOL getMinimized() override;
+ BOOL getMaximized() override;
+ BOOL maximize() override;
+ void minimize() override;
+ void restore() override;
+ BOOL getFullscreen();
+ 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;
+ BOOL getCursorPosition(LLCoordWindow *position) override;
+ void showCursor() override;
+ void hideCursor() override;
+ void showCursorFromMouseMove() override;
+ void hideCursorUntilMouseMove() override;
+ BOOL isCursorHidden() override;
+ void updateCursor() override;
+ ECursorType getCursor() const override;
+ void captureMouse() override;
+ void releaseMouse() override;
+ void setMouseClipping( BOOL b ) override;
+ BOOL isClipboardTextAvailable() override;
+ BOOL pasteTextFromClipboard(LLWString &dst) override;
+ BOOL copyTextToClipboard(const LLWString & src) override;
+ void flashIcon(F32 seconds) override;
+ F32 getGamma() override;
+ BOOL setGamma(const F32 gamma) override; // Set the gamma
+ U32 getFSAASamples() override;
+ void setFSAASamples(const U32 fsaa_samples) override;
+ BOOL restoreGamma() override; // Restore original gamma table (before updating gamma)
+ ESwapMethod getSwapMethod() override { return mSwapMethod; }
+ void gatherInput() override;
+ void delayInputProcessing() override {};
+ void swapBuffers() 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;
- /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions);
- /*virtual*/ F32 getNativeAspectRatio();
- /*virtual*/ F32 getPixelAspectRatio();
- /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; }
+ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override;
+ 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;
+ void bringToFront() override {};
- /*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
- /*virtual*/ void interruptLanguageTextInput();
- /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
- /*virtual*/ F32 getSystemUISize();
+ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) override;
+ void interruptLanguageTextInput() override;
+ void spawnWebBrowser(const std::string& escaped_url, bool async) override;
+ F32 getSystemUISize() override;
static std::vector<std::string> getDisplaysResolutionList();
static std::vector<std::string> getDynamicFallbackFontList();
// Provide native key event data
- /*virtual*/ LLSD getNativeKeyData();
+ LLSD getNativeKeyData() override;
void* getWindow() { return mWindow; }
LLWindowCallbacks* getCallbacks() { return mCallbacks; }
@@ -132,16 +131,25 @@ public:
bool allowsLanguageInput() { return mLanguageTextInputAllowed; }
+ //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread
+ // returns a pointer to be handed back to destroySharedConext/makeContextCurrent
+ void* createSharedContext() override;
+ //make the given context current on the current thread
+ void makeContextCurrent(void* context) override;
+ //destroy the given context that was retrieved by createSharedContext()
+ //Must be called on the same thread that called createSharedContext()
+ void destroySharedContext(void* context) override;
+
protected:
LLWindowMacOSX(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 disable_vsync, BOOL use_gl,
+ BOOL fullscreen, BOOL clearBg, BOOL enable_vsync, BOOL use_gl,
BOOL ignore_pixel_depth,
U32 fsaa_samples);
~LLWindowMacOSX();
void initCursors();
- BOOL isValid();
+ BOOL isValid() override;
void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size);
@@ -157,7 +165,7 @@ protected:
BOOL shouldPostQuit() { return mPostQuit; }
//Satisfy MAINT-3135 and MAINT-3288 with a flag.
- /*virtual */ void setOldResize(bool oldresize) {setResizeMode(oldresize, mGLView); }
+ /*virtual */ void setOldResize(bool oldresize) override {setResizeMode(oldresize, mGLView); }
private:
void restoreGLContext();
@@ -168,7 +176,7 @@ 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 adjustCursorDecouple(bool warpingMouse = false);
@@ -231,9 +239,9 @@ public:
LLSplashScreenMacOSX();
virtual ~LLSplashScreenMacOSX();
- /*virtual*/ void showImpl();
- /*virtual*/ void updateImpl(const std::string& mesg);
- /*virtual*/ void hideImpl();
+ void showImpl();
+ void updateImpl(const std::string& mesg);
+ void hideImpl();
private:
WindowRef mWindow;
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index b2b123f0da..e52624d66a 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -45,6 +45,7 @@
#include "lldir.h"
#include "llsdutil.h"
#include "llglslshader.h"
+#include "llthreadsafequeue.h"
// System includes
#include <commdlg.h>
@@ -79,6 +80,18 @@ const F32 ICON_FLASH_TIME = 0.5f;
extern BOOL gDebugWindowProc;
+static std::thread::id sWindowThreadId;
+static std::thread::id sMainThreadId;
+
+#if 1 // flip to zero to enable assertions for functions being called from wrong thread
+#define ASSERT_MAIN_THREAD()
+#define ASSERT_WINDOW_THREAD()
+#else
+#define ASSERT_MAIN_THREAD() llassert(LLThread::currentID() == sMainThreadId)
+#define ASSERT_WINDOW_THREAD() llassert(LLThread::currentID() == sWindowThreadId)
+#endif
+
+
LPWSTR gIconResource = IDI_APPLICATION;
LPDIRECTINPUT8 gDirectInput8;
@@ -294,7 +307,7 @@ LLWinImm::LLWinImm() : mHImmDll(NULL)
// static
-BOOL LLWinImm::isIME(HKL hkl)
+BOOL LLWinImm::isIME(HKL hkl)
{
if ( sTheInstance.mImmIsIME )
return sTheInstance.mImmIsIME(hkl);
@@ -326,7 +339,7 @@ BOOL LLWinImm::getOpenStatus(HIMC himc)
}
// static
-BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status)
+BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status)
{
if ( sTheInstance.mImmSetOpenStatus )
return sTheInstance.mImmSetOpenStatus(himc, status);
@@ -454,16 +467,20 @@ private:
static LLMonitorInfo sMonitorInfo;
+
+
LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
S32 height, U32 flags,
BOOL fullscreen, BOOL clearBg,
- BOOL disable_vsync, BOOL use_gl,
+ BOOL enable_vsync, BOOL use_gl,
BOOL ignore_pixel_depth,
U32 fsaa_samples)
: LLWindow(callbacks, fullscreen, flags)
{
-
+ sMainThreadId = LLThread::currentID();
+ mWindowThread = new LLWindowWin32Thread(this);
+ mWindowThread->start();
//MAINT-516 -- force a load of opengl32.dll just in case windows went sideways
LoadLibrary(L"opengl32.dll");
@@ -471,7 +488,6 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
mIconResource = gIconResource;
mOverrideAspectRatio = 0.f;
mNativeAspectRatio = 0.f;
- mMousePositionModified = FALSE;
mInputProcessingPaused = FALSE;
mPreeditor = NULL;
mKeyCharCode = 0;
@@ -784,7 +800,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
LLCoordScreen windowPos(x,y);
LLCoordScreen windowSize(window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top);
- if (!switchContext(mFullscreen, windowSize, TRUE, &windowPos))
+ if (!switchContext(mFullscreen, windowSize, enable_vsync, &windowPos))
{
return;
}
@@ -793,6 +809,13 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
initCursors();
setCursor( UI_CURSOR_ARROW );
+ mRawMouse.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
+ mRawMouse.usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE
+ mRawMouse.dwFlags = 0; // adds mouse and also ignores legacy mouse messages
+ mRawMouse.hwndTarget = 0;
+
+ RegisterRawInputDevices(&mRawMouse, 1, sizeof(mRawMouse));
+
// Initialize (boot strap) the Language text input management,
// based on the system's (or user's) default settings.
allowLanguageTextInput(NULL, FALSE);
@@ -811,6 +834,8 @@ LLWindowWin32::~LLWindowWin32()
delete [] mWindowClassName;
mWindowClassName = NULL;
+
+ delete mWindowThread;
}
void LLWindowWin32::show()
@@ -930,26 +955,37 @@ void LLWindowWin32::close()
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
- if (IsWindow(mWindowHandle))
- {
- // Make sure we don't leave a blank toolbar button.
- ShowWindow(mWindowHandle, SW_HIDE);
-
- // This causes WM_DESTROY to be sent *immediately*
- if (!destroy_window_handler(mWindowHandle))
+ mWindowThread->post([=]()
{
- OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
- mCallbacks->translateString("MBShutdownErr"),
- OSMB_OK);
- }
- }
- else
+ if (IsWindow(mWindowHandle))
+ {
+ // Make sure we don't leave a blank toolbar button.
+ ShowWindow(mWindowHandle, SW_HIDE);
+
+ // This causes WM_DESTROY to be sent *immediately*
+ if (!destroy_window_handler(mWindowHandle))
+ {
+ OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
+ mCallbacks->translateString("MBShutdownErr"),
+ OSMB_OK);
+ }
+ }
+ else
+ {
+ // Something killed the window while we were busy destroying gl or handle somehow got broken
+ LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL;
+ }
+ mWindowHandle = NULL;
+
+ mWindowThread->mFinished = true;
+ });
+
+ while (!mWindowThread->isStopped())
{
- // Something killed the window while we were busy destroying gl or handle somehow got broken
- LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL;
+ //nudge window thread
+ PostMessage(mWindowHandle, WM_USER + 0x0017, 0xB0B0, 0x1337);
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
-
- mWindowHandle = NULL;
}
BOOL LLWindowWin32::isValid()
@@ -1090,171 +1126,203 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordWindow size)
}
// changing fullscreen resolution
-BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp)
+BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BOOL enable_vsync, const LLCoordScreen* const posp)
{
- GLuint pixel_format;
- DEVMODE dev_mode;
- ::ZeroMemory(&dev_mode, sizeof(DEVMODE));
- dev_mode.dmSize = sizeof(DEVMODE);
- DWORD current_refresh;
- DWORD dw_ex_style;
- DWORD dw_style;
- RECT window_rect = {0, 0, 0, 0};
- S32 width = size.mX;
- S32 height = size.mY;
- BOOL auto_show = FALSE;
-
- if (mhRC)
- {
- auto_show = TRUE;
- resetDisplayResolution();
- }
-
- if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode))
- {
- current_refresh = dev_mode.dmDisplayFrequency;
- }
- else
- {
- current_refresh = 60;
- }
-
- gGLManager.shutdownGL();
- //destroy gl context
- if (mhRC)
- {
- if (!wglMakeCurrent(NULL, NULL))
- {
- LL_WARNS("Window") << "Release of DC and RC failed" << LL_ENDL;
- }
+ //called from main thread
+ GLuint pixel_format;
+ DEVMODE dev_mode;
+ ::ZeroMemory(&dev_mode, sizeof(DEVMODE));
+ dev_mode.dmSize = sizeof(DEVMODE);
+ DWORD current_refresh;
+ DWORD dw_ex_style;
+ DWORD dw_style;
+ RECT window_rect = { 0, 0, 0, 0 };
+ S32 width = size.mX;
+ S32 height = size.mY;
+ BOOL auto_show = FALSE;
+
+ if (mhRC)
+ {
+ auto_show = TRUE;
+ resetDisplayResolution();
+ }
- if (!wglDeleteContext(mhRC))
- {
- LL_WARNS("Window") << "Release of rendering context failed" << LL_ENDL;
- }
+ if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode))
+ {
+ current_refresh = dev_mode.dmDisplayFrequency;
+ }
+ else
+ {
+ current_refresh = 60;
+ }
- mhRC = NULL;
- }
+ gGLManager.shutdownGL();
+ //destroy gl context
+ if (mhRC)
+ {
+ if (!wglMakeCurrent(NULL, NULL))
+ {
+ LL_WARNS("Window") << "Release of DC and RC failed" << LL_ENDL;
+ }
- if (fullscreen)
- {
- mFullscreen = TRUE;
- BOOL success = FALSE;
- DWORD closest_refresh = 0;
+ if (!wglDeleteContext(mhRC))
+ {
+ LL_WARNS("Window") << "Release of rendering context failed" << LL_ENDL;
+ }
- for (S32 mode_num = 0;; mode_num++)
- {
- if (!EnumDisplaySettings(NULL, mode_num, &dev_mode))
- {
- break;
- }
+ mhRC = NULL;
+ }
- if (dev_mode.dmPelsWidth == width &&
- dev_mode.dmPelsHeight == height &&
- dev_mode.dmBitsPerPel == BITS_PER_PIXEL)
- {
- success = TRUE;
- if ((dev_mode.dmDisplayFrequency - current_refresh)
- < (closest_refresh - current_refresh))
- {
- closest_refresh = dev_mode.dmDisplayFrequency;
- }
- }
- }
+ if (fullscreen)
+ {
+ mFullscreen = TRUE;
+ BOOL success = FALSE;
+ DWORD closest_refresh = 0;
- if (closest_refresh == 0)
- {
- LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL;
- return FALSE;
- }
+ for (S32 mode_num = 0;; mode_num++)
+ {
+ if (!EnumDisplaySettings(NULL, mode_num, &dev_mode))
+ {
+ break;
+ }
- // If we found a good resolution, use it.
- if (success)
- {
- success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh);
- }
+ if (dev_mode.dmPelsWidth == width &&
+ dev_mode.dmPelsHeight == height &&
+ dev_mode.dmBitsPerPel == BITS_PER_PIXEL)
+ {
+ success = TRUE;
+ if ((dev_mode.dmDisplayFrequency - current_refresh)
+ < (closest_refresh - current_refresh))
+ {
+ closest_refresh = dev_mode.dmDisplayFrequency;
+ }
+ }
+ }
- // Keep a copy of the actual current device mode in case we minimize
- // and change the screen resolution. JC
- EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode);
+ if (closest_refresh == 0)
+ {
+ LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL;
+ return FALSE;
+ }
- if (success)
- {
- mFullscreen = TRUE;
- mFullscreenWidth = dev_mode.dmPelsWidth;
- mFullscreenHeight = dev_mode.dmPelsHeight;
- mFullscreenBits = dev_mode.dmBitsPerPel;
- mFullscreenRefresh = dev_mode.dmDisplayFrequency;
+ // If we found a good resolution, use it.
+ if (success)
+ {
+ success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh);
+ }
- LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth
- << "x" << dev_mode.dmPelsHeight
- << "x" << dev_mode.dmBitsPerPel
- << " @ " << dev_mode.dmDisplayFrequency
- << LL_ENDL;
+ // Keep a copy of the actual current device mode in case we minimize
+ // and change the screen resolution. JC
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode);
- window_rect.left = (long) 0;
- window_rect.right = (long) width; // Windows GDI rects don't include rightmost pixel
- window_rect.top = (long) 0;
- window_rect.bottom = (long) height;
- dw_ex_style = WS_EX_APPWINDOW;
- dw_style = WS_POPUP;
+ if (success)
+ {
+ mFullscreen = TRUE;
+ mFullscreenWidth = dev_mode.dmPelsWidth;
+ mFullscreenHeight = dev_mode.dmPelsHeight;
+ mFullscreenBits = dev_mode.dmBitsPerPel;
+ mFullscreenRefresh = dev_mode.dmDisplayFrequency;
+
+ LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth
+ << "x" << dev_mode.dmPelsHeight
+ << "x" << dev_mode.dmBitsPerPel
+ << " @ " << dev_mode.dmDisplayFrequency
+ << LL_ENDL;
+
+ window_rect.left = (long)0;
+ window_rect.right = (long)width; // Windows GDI rects don't include rightmost pixel
+ window_rect.top = (long)0;
+ window_rect.bottom = (long)height;
+ dw_ex_style = WS_EX_APPWINDOW;
+ dw_style = WS_POPUP;
+
+ // Move window borders out not to cover window contents.
+ // This converts client rect to window rect, i.e. expands it by the window border size.
+ AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style);
+ }
+ // If it failed, we don't want to run fullscreen
+ else
+ {
+ mFullscreen = FALSE;
+ mFullscreenWidth = -1;
+ mFullscreenHeight = -1;
+ mFullscreenBits = -1;
+ mFullscreenRefresh = -1;
- // Move window borders out not to cover window contents.
- // This converts client rect to window rect, i.e. expands it by the window border size.
- AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style);
- }
- // If it failed, we don't want to run fullscreen
- else
- {
- mFullscreen = FALSE;
- mFullscreenWidth = -1;
- mFullscreenHeight = -1;
- mFullscreenBits = -1;
- mFullscreenRefresh = -1;
+ LL_INFOS("Window") << "Unable to run fullscreen at " << width << "x" << height << LL_ENDL;
+ return FALSE;
+ }
+ }
+ else
+ {
+ mFullscreen = FALSE;
+ window_rect.left = (long)(posp ? posp->mX : 0);
+ window_rect.right = (long)width + window_rect.left; // Windows GDI rects don't include rightmost pixel
+ window_rect.top = (long)(posp ? posp->mY : 0);
+ window_rect.bottom = (long)height + window_rect.top;
+ // Window with an edge
+ dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
+ dw_style = WS_OVERLAPPEDWINDOW;
+ }
- LL_INFOS("Window") << "Unable to run fullscreen at " << width << "x" << height << LL_ENDL;
- return FALSE;
- }
- }
- else
- {
- mFullscreen = FALSE;
- window_rect.left = (long) (posp ? posp->mX : 0);
- window_rect.right = (long) width + window_rect.left; // Windows GDI rects don't include rightmost pixel
- window_rect.top = (long) (posp ? posp->mY : 0);
- window_rect.bottom = (long) height + window_rect.top;
- // Window with an edge
- dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
- dw_style = WS_OVERLAPPEDWINDOW;
- }
+ // don't post quit messages when destroying old windows
+ mPostQuit = FALSE;
- // don't post quit messages when destroying old windows
- mPostQuit = FALSE;
- // create window
+ // create window
LL_DEBUGS("Window") << "Creating window with X: " << window_rect.left
<< " Y: " << window_rect.top
<< " Width: " << (window_rect.right - window_rect.left)
<< " Height: " << (window_rect.bottom - window_rect.top)
<< " Fullscreen: " << mFullscreen
<< LL_ENDL;
- if (mWindowHandle && !destroy_window_handler(mWindowHandle))
+
+ auto oldHandle = mWindowHandle;
+
+ //zero out mWindowHandle and mhDC before destroying window so window thread falls back to peekmessage
+ mWindowHandle = 0;
+ mhDC = 0;
+
+ if (oldHandle && !destroy_window_handler(oldHandle))
{
LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL;
- }
- mWindowHandle = CreateWindowEx(dw_ex_style,
- mWindowClassName,
- mWindowTitle,
- WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style,
- window_rect.left, // x pos
- window_rect.top, // y pos
- window_rect.right - window_rect.left, // width
- window_rect.bottom - window_rect.top, // height
- NULL,
- NULL,
- mhInstance,
- NULL);
+ }
+
+ mWindowHandle = NULL;
+ mhDC = 0;
+
+ mWindowThread->post(
+ [this, window_rect, dw_ex_style, dw_style]()
+ {
+ mWindowHandle = CreateWindowEx(dw_ex_style,
+ mWindowClassName,
+ mWindowTitle,
+ WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style,
+ window_rect.left, // x pos
+ window_rect.top, // y pos
+ window_rect.right - window_rect.left, // width
+ window_rect.bottom - window_rect.top, // height
+ NULL,
+ NULL,
+ mhInstance,
+ NULL);
+
+ if (mWindowHandle)
+ {
+ mhDC = GetDC(mWindowHandle);
+ }
+ }
+ );
+
+ // HACK wait for above handle to become populated
+ // TODO: use a future
+ int count = 1024;
+ while (!mhDC && count > 0)
+ {
+ Sleep(10);
+ --count;
+ }
if (mWindowHandle)
{
@@ -1288,7 +1356,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
0, 0, 0
};
- if (!(mhDC = GetDC(mWindowHandle)))
+ if (!mhDC)
{
close();
OSMessageBox(mCallbacks->translateString("MBDevContextErr"),
@@ -1582,25 +1650,48 @@ const S32 max_format = (S32)num_formats - 1;
mhDC = 0; // Zero The Device Context
}
+ auto oldHandle = mWindowHandle;
+ mWindowHandle = NULL;
+ mhDC = 0;
+
// Destroy The Window
- if (mWindowHandle && !destroy_window_handler(mWindowHandle))
+ if (oldHandle && !destroy_window_handler(oldHandle))
{
LL_WARNS("Window") << "Failed to properly close window!" << LL_ENDL;
}
- mWindowHandle = CreateWindowEx(dw_ex_style,
- mWindowClassName,
- mWindowTitle,
- WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style,
- window_rect.left, // x pos
- window_rect.top, // y pos
- window_rect.right - window_rect.left, // width
- window_rect.bottom - window_rect.top, // height
- NULL,
- NULL,
- mhInstance,
- NULL);
+ mWindowThread->post(
+ [this, window_rect, dw_ex_style, dw_style]()
+ {
+ mWindowHandle = CreateWindowEx(dw_ex_style,
+ mWindowClassName,
+ mWindowTitle,
+ WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style,
+ window_rect.left, // x pos
+ window_rect.top, // y pos
+ window_rect.right - window_rect.left, // width
+ window_rect.bottom - window_rect.top, // height
+ NULL,
+ NULL,
+ mhInstance,
+ NULL);
+
+ if (mWindowHandle)
+ {
+ mhDC = GetDC(mWindowHandle);
+ }
+ }
+ );
+ // HACK wait for above handle to become populated
+ // TODO: use a future
+ int count = 1024;
+ while (!mhDC && count > 0)
+ {
+ PostMessage(oldHandle, WM_USER + 8, 0x1717, 0x3b3b);
+ Sleep(10);
+ --count;
+ }
if (mWindowHandle)
{
@@ -1612,7 +1703,7 @@ const S32 max_format = (S32)num_formats - 1;
LL_WARNS("Window") << "Window recreation failed, code: " << GetLastError() << LL_ENDL;
}
- if (!(mhDC = GetDC(mWindowHandle)))
+ if (!mhDC)
{
close();
OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
@@ -1687,58 +1778,11 @@ const S32 max_format = (S32)num_formats - 1;
mhRC = 0;
if (wglCreateContextAttribsARB)
{ //attempt to create a specific versioned context
- S32 attribs[] =
- { //start at 4.2
- WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
- WGL_CONTEXT_MINOR_VERSION_ARB, 2,
- WGL_CONTEXT_PROFILE_MASK_ARB, LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
- WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
- 0
- };
-
- bool done = false;
- while (!done)
- {
- mhRC = wglCreateContextAttribsARB(mhDC, mhRC, attribs);
-
- if (!mhRC)
- {
- if (attribs[3] > 0)
- { //decrement minor version
- attribs[3]--;
- }
- else if (attribs[1] > 3)
- { //decrement major version and start minor version over at 3
- attribs[1]--;
- attribs[3] = 3;
- }
- else
- { //we reached 3.0 and still failed, bail out
- done = true;
- }
- }
- else
- {
- LL_INFOS() << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) <<
- (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << LL_ENDL;
- done = true;
-
- // force sNoFixedFunction iff we're trying to use nsight debugging which does not support many legacy API uses
-
- // nSight doesn't support use of legacy API funcs in the fixed function pipe
- if (LLRender::sGLCoreProfile || LLRender::sNsightDebugSupport)
- {
- LLGLSLShader::sNoFixedFunction = true;
- }
- }
- }
- }
-
- if (!mhRC && !(mhRC = wglCreateContext(mhDC)))
- {
- close();
- OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
- return FALSE;
+ mhRC = (HGLRC) createSharedContext();
+ if (!mhRC)
+ {
+ return FALSE;
+ }
}
if (!wglMakeCurrent(mhDC, mhRC))
@@ -1748,6 +1792,8 @@ const S32 max_format = (S32)num_formats - 1;
return FALSE;
}
+ LL_PROFILER_GPU_CONTEXT
+
if (!gGLManager.initGL())
{
close();
@@ -1756,15 +1802,7 @@ const S32 max_format = (S32)num_formats - 1;
}
// Disable vertical sync for swap
- if (disable_vsync && wglSwapIntervalEXT)
- {
- LL_DEBUGS("Window") << "Disabling vertical sync" << LL_ENDL;
- wglSwapIntervalEXT(0);
- }
- else
- {
- LL_DEBUGS("Window") << "Keeping vertical sync" << LL_ENDL;
- }
+ toggleVSync(enable_vsync);
SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, (LONG_PTR)this);
@@ -1790,6 +1828,89 @@ const S32 max_format = (S32)num_formats - 1;
return TRUE;
}
+void* LLWindowWin32::createSharedContext()
+{
+ S32 attribs[] =
+ {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
+ WGL_CONTEXT_MINOR_VERSION_ARB, 2,
+ WGL_CONTEXT_PROFILE_MASK_ARB, LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+ WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
+ 0
+ };
+
+ HGLRC rc = wglCreateContextAttribsARB(mhDC, mhRC, attribs);
+
+ bool done = false;
+ while (!done)
+ {
+ rc = wglCreateContextAttribsARB(mhDC, mhRC, attribs);
+
+ if (!rc)
+ {
+ if (attribs[3] > 0)
+ { //decrement minor version
+ attribs[3]--;
+ }
+ else if (attribs[1] > 3)
+ { //decrement major version and start minor version over at 3
+ attribs[1]--;
+ attribs[3] = 3;
+ }
+ else
+ { //we reached 3.0 and still failed, bail out
+ done = true;
+ }
+ }
+ else
+ {
+ LL_INFOS() << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) <<
+ (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << LL_ENDL;
+ done = true;
+
+ // force sNoFixedFunction iff we're trying to use nsight debugging which does not support many legacy API uses
+
+ // nSight doesn't support use of legacy API funcs in the fixed function pipe
+ if (LLRender::sGLCoreProfile || LLRender::sNsightDebugSupport)
+ {
+ LLGLSLShader::sNoFixedFunction = true;
+ }
+ }
+ }
+
+ if (!rc && !(rc = wglCreateContext(mhDC)))
+ {
+ close();
+ OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
+ }
+
+ return rc;
+}
+
+void LLWindowWin32::makeContextCurrent(void* contextPtr)
+{
+ wglMakeCurrent(mhDC, (HGLRC) contextPtr);
+}
+
+void LLWindowWin32::destroySharedContext(void* contextPtr)
+{
+ wglDeleteContext((HGLRC)contextPtr);
+}
+
+void LLWindowWin32::toggleVSync(bool enable_vsync)
+{
+ if (!enable_vsync && wglSwapIntervalEXT)
+ {
+ LL_INFOS("Window") << "Disabling vertical sync" << LL_ENDL;
+ wglSwapIntervalEXT(0);
+ }
+ else
+ {
+ LL_INFOS("Window") << "Enabling vertical sync" << LL_ENDL;
+ wglSwapIntervalEXT(1);
+ }
+}
+
void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScreen& size )
{
if( mIsMouseClipping )
@@ -1811,63 +1932,97 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre
MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE);
}
+void LLWindowWin32::setTitle(const std::string title)
+{
+ // TODO: Do we need to use the wide string version of this call
+ // to support non-ascii usernames (and region names?)
+ SetWindowTextA(mWindowHandle, title.c_str());
+}
+
BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position)
{
- mMousePositionModified = TRUE;
- if (!mWindowHandle)
- {
- return FALSE;
- }
+ ASSERT_MAIN_THREAD();
+ if (!mWindowHandle)
+ {
+ return FALSE;
+ }
- // Inform the application of the new mouse position (needed for per-frame
- // hover/picking to function).
- mCallbacks->handleMouseMove(this, position.convert(), (MASK)0);
-
- // DEV-18951 VWR-8524 Camera moves wildly when alt-clicking.
- // Because we have preemptively notified the application of the new
- // mouse position via handleMouseMove() above, we need to clear out
- // any stale mouse move events. RN/JC
- MSG msg;
- while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
- { }
-
- LLCoordScreen screen_pos(position.convert());
- return ::SetCursorPos(screen_pos.mX, screen_pos.mY);
+ LLCoordScreen screen_pos(position.convert());
+
+ // instantly set the cursor position from the app's point of view
+ mCursorPosition = position;
+ mLastCursorPosition = position;
+
+ // Inform the application of the new mouse position (needed for per-frame
+ // hover/picking to function).
+ mCallbacks->handleMouseMove(this, position.convert(), (MASK)0);
+
+ // actually set the cursor position on the window thread
+ mWindowThread->post([=]()
+ {
+ // actually set the OS cursor position
+ SetCursorPos(screen_pos.mX, screen_pos.mY);
+ });
+
+ return TRUE;
}
BOOL LLWindowWin32::getCursorPosition(LLCoordWindow *position)
{
- POINT cursor_point;
-
- if (!mWindowHandle
- || !GetCursorPos(&cursor_point)
- || !position)
- {
- return FALSE;
- }
+ ASSERT_MAIN_THREAD();
+ if (!position)
+ {
+ return FALSE;
+ }
- *position = LLCoordScreen(cursor_point.x, cursor_point.y).convert();
+ *position = mCursorPosition;
return TRUE;
}
+BOOL LLWindowWin32::getCursorDelta(LLCoordCommon* delta)
+{
+ if (delta == nullptr)
+ {
+ return FALSE;
+ }
+
+ *delta = mMouseFrameDelta;
+
+ return TRUE;
+}
+
void LLWindowWin32::hideCursor()
{
- while (ShowCursor(FALSE) >= 0)
- {
- // nothing, wait for cursor to push down
- }
+ ASSERT_MAIN_THREAD();
+
+ mWindowThread->post([=]()
+ {
+ while (ShowCursor(FALSE) >= 0)
+ {
+ // nothing, wait for cursor to push down
+ }
+ });
+
mCursorHidden = TRUE;
mHideCursorPermanent = TRUE;
}
void LLWindowWin32::showCursor()
{
- // makes sure the cursor shows up
- while (ShowCursor(TRUE) < 0)
- {
- // do nothing, wait for cursor to pop out
- }
+ LL_PROFILE_ZONE_SCOPED;
+
+ ASSERT_MAIN_THREAD();
+
+ mWindowThread->post([=]()
+ {
+ // makes sure the cursor shows up
+ while (ShowCursor(TRUE) < 0)
+ {
+ // do nothing, wait for cursor to pop out
+ }
+ });
+
mCursorHidden = FALSE;
mHideCursorPermanent = FALSE;
}
@@ -1969,6 +2124,8 @@ void LLWindowWin32::initCursors()
void LLWindowWin32::updateCursor()
{
+ ASSERT_MAIN_THREAD();
+ LL_PROFILE_ZONE_SCOPED
if (mNextCursor == UI_CURSOR_ARROW
&& mBusyCount > 0)
{
@@ -1978,7 +2135,11 @@ void LLWindowWin32::updateCursor()
if( mCurrentCursor != mNextCursor )
{
mCurrentCursor = mNextCursor;
- SetCursor( mCursor[mNextCursor] );
+ auto nextCursor = mCursor[mNextCursor];
+ mWindowThread->post([=]()
+ {
+ SetCursor(nextCursor);
+ });
}
}
@@ -1994,13 +2155,8 @@ void LLWindowWin32::captureMouse()
void LLWindowWin32::releaseMouse()
{
- // *NOTE:Mani ReleaseCapture will spawn new windows messages...
- // which will in turn call our MainWindowProc. It therefore requires
- // pausing *and more importantly resumption* of the mainlooptimeout...
- // just like DispatchMessage below.
- mCallbacks->handlePauseWatchdog(this);
+ LL_PROFILE_ZONE_SCOPED;
ReleaseCapture();
- mCallbacks->handleResumeWatchdog(this);
}
@@ -2009,1003 +2165,997 @@ void LLWindowWin32::delayInputProcessing()
mInputProcessingPaused = TRUE;
}
+
void LLWindowWin32::gatherInput()
{
- MSG msg;
- int msg_count = 0;
+ ASSERT_MAIN_THREAD();
+ LL_PROFILE_ZONE_SCOPED
+ MSG msg;
- while ((msg_count < MAX_MESSAGE_PER_UPDATE) && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- mCallbacks->handlePingWatchdog(this, "Main:TranslateGatherInput");
- TranslateMessage(&msg);
+ {
+ LLMutexLock lock(&mRawMouseMutex);
+ mMouseFrameDelta = mRawMouseDelta;
- // turn watchdog off in here to not fail if windows is doing something wacky
- mCallbacks->handlePauseWatchdog(this);
- DispatchMessage(&msg);
- mCallbacks->handleResumeWatchdog(this);
- msg_count++;
+ mRawMouseDelta.mX = 0;
+ mRawMouseDelta.mY = 0;
+ }
- if ( mInputProcessingPaused )
- {
- break;
- }
- /* Attempted workaround for problem where typing fast and hitting
- return would result in only part of the text being sent. JC
- BOOL key_posted = TranslateMessage(&msg);
- DispatchMessage(&msg);
- msg_count++;
+ if (mWindowThread->mFunctionQueue.size() > 0)
+ {
+ LL_PROFILE_ZONE_NAMED("gi - PostMessage");
+ if (mWindowHandle)
+ { // post a nonsense user message to wake up the Window Thread in case any functions are pending
+ // and no windows events came through this frame
+ PostMessage(mWindowHandle, WM_USER + 0x0017, 0xB0B0, 0x1337);
+ }
+ }
+
+ while (mWindowThread->mMessageQueue.tryPopBack(msg))
+ {
+ LL_PROFILE_ZONE_NAMED("gi - message queue");
+ if (mInputProcessingPaused)
+ {
+ continue;
+ }
+
+ // For async host by name support. Really hacky.
+ if (gAsyncMsgCallback && (LL_WM_HOST_RESOLVED == msg.message))
+ {
+ LL_PROFILE_ZONE_NAMED("gi - callback");
+ gAsyncMsgCallback(msg);
+ }
+ }
- // If a key was translated, a WM_CHAR might have been posted to the end
- // of the event queue. We need it immediately.
- if (key_posted && msg.message == WM_KEYDOWN)
- {
- if (PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- msg_count++;
- }
- }
- */
- mCallbacks->handlePingWatchdog(this, "Main:AsyncCallbackGatherInput");
- // For async host by name support. Really hacky.
- if (gAsyncMsgCallback && (LL_WM_HOST_RESOLVED == msg.message))
- {
- gAsyncMsgCallback(msg);
- }
- }
+ {
+ LL_PROFILE_ZONE_NAMED("gi - PeekMessage");
+ S32 msg_count = 0;
+ while ((msg_count < MAX_MESSAGE_PER_UPDATE) && PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ msg_count++;
+ }
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED("gi - function queue");
+ //process any pending functions
+ std::function<void()> curFunc;
+ while (mFunctionQueue.tryPopBack(curFunc))
+ {
+ curFunc();
+ }
+ }
+
+ // send one and only one mouse move event per frame BEFORE handling mouse button presses
+ if (mLastCursorPosition != mCursorPosition)
+ {
+ LL_PROFILE_ZONE_NAMED("gi - mouse move");
+ mCallbacks->handleMouseMove(this, mCursorPosition.convert(), mMouseMask);
+ }
+
+ mLastCursorPosition = mCursorPosition;
+
+ {
+ LL_PROFILE_ZONE_NAMED("gi - mouse queue");
+ // handle mouse button presses AFTER updating mouse cursor position
+ std::function<void()> curFunc;
+ while (mMouseQueue.tryPopBack(curFunc))
+ {
+ curFunc();
+ }
+ }
mInputProcessingPaused = FALSE;
updateCursor();
-
- // clear this once we've processed all mouse messages that might have occurred after
- // we slammed the mouse position
- mMousePositionModified = FALSE;
}
static LLTrace::BlockTimerStatHandle FTM_KEYHANDLER("Handle Keyboard");
static LLTrace::BlockTimerStatHandle FTM_MOUSEHANDLER("Handle Mouse");
+#define WINDOW_IMP_POST(x) window_imp->post([=]() { x; })
+
LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param)
{
- // Ignore clicks not originated in the client area, i.e. mouse-up events not preceded with a WM_LBUTTONDOWN.
- // This helps prevent avatar walking after maximizing the window by double-clicking the title bar.
- static bool sHandleLeftMouseUp = true;
-
- // Ignore the double click received right after activating app.
- // This is to avoid triggering double click teleport after returning focus (see MAINT-3786).
- static bool sHandleDoubleClick = true;
-
- LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( h_wnd, GWLP_USERDATA );
-
- bool debug_window_proc = gDebugWindowProc || debugLoggingEnabled("Window");
-
-
- if (NULL != window_imp)
- {
- window_imp->mCallbacks->handleResumeWatchdog(window_imp);
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:StartWndProc");
- // Has user provided their own window callback?
- if (NULL != window_imp->mWndProc)
- {
- if (!window_imp->mWndProc(h_wnd, u_msg, w_param, l_param))
- {
- // user has handled window message
- return 0;
- }
- }
-
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:PreSwitchWndProc");
-
- // Juggle to make sure we can get negative positions for when
- // mouse is outside window.
- LLCoordWindow window_coord((S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param));
-
- // This doesn't work, as LOWORD returns unsigned short.
- //LLCoordWindow window_coord(LOWORD(l_param), HIWORD(l_param));
- LLCoordGL gl_coord;
-
- // pass along extended flag in mask
- MASK mask = (l_param>>16 & KF_EXTENDED) ? MASK_EXTENDED : 0x0;
- BOOL eat_keystroke = TRUE;
-
- switch(u_msg)
- {
- RECT update_rect;
- S32 update_width;
- S32 update_height;
-
- case WM_TIMER:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_TIMER");
- window_imp->mCallbacks->handleTimerEvent(window_imp);
- break;
-
- case WM_DEVICECHANGE:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_DEVICECHANGE");
- if (debug_window_proc)
- {
- LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param
- << "; lParam=" << l_param << LL_ENDL;
- }
- if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL)
- {
- if (window_imp->mCallbacks->handleDeviceChange(window_imp))
- {
- return 0;
- }
- }
- break;
-
- case WM_PAINT:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main: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;
- window_imp->mCallbacks->handlePaint(window_imp, update_rect.left, update_rect.top,
- update_width, update_height);
- break;
- case WM_PARENTNOTIFY:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_PARENTNOTIFY");
- u_msg = u_msg;
- break;
-
- case WM_SETCURSOR:
- // This message is sent whenever the cursor is moved in a window.
- // You need to set the appropriate cursor appearance.
-
- // Only take control of cursor over client region of window
- // This allows Windows(tm) to handle resize cursors, etc.
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETCURSOR");
- if (LOWORD(l_param) == HTCLIENT)
- {
- SetCursor(window_imp->mCursor[ window_imp->mCurrentCursor] );
- return 0;
- }
- break;
-
- case WM_ENTERMENULOOP:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ENTERMENULOOP");
- window_imp->mCallbacks->handleWindowBlock(window_imp);
- break;
-
- case WM_EXITMENULOOP:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_EXITMENULOOP");
- window_imp->mCallbacks->handleWindowUnblock(window_imp);
- break;
-
- case WM_ACTIVATEAPP:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ACTIVATEAPP");
- {
- // This message should be sent whenever the app gains or loses focus.
- BOOL activating = (BOOL) w_param;
- BOOL minimized = window_imp->getMinimized();
-
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "WINDOWPROC ActivateApp "
- << " activating " << S32(activating)
- << " minimized " << S32(minimized)
- << " fullscreen " << S32(window_imp->mFullscreen)
- << LL_ENDL;
- }
-
- if (window_imp->mFullscreen)
- {
- // When we run fullscreen, restoring or minimizing the app needs
- // to switch the screen resolution
- if (activating)
- {
- window_imp->setFullscreenResolution();
- window_imp->restore();
- }
- else
- {
- window_imp->minimize();
- window_imp->resetDisplayResolution();
- }
- }
-
- if (!activating)
- {
- sHandleDoubleClick = false;
- }
-
- window_imp->mCallbacks->handleActivateApp(window_imp, activating);
-
- break;
- }
-
- case WM_ACTIVATE:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ACTIVATE");
- {
- // Can be one of WA_ACTIVE, WA_CLICKACTIVE, or WA_INACTIVE
- BOOL activating = (LOWORD(w_param) != WA_INACTIVE);
-
- BOOL minimized = BOOL(HIWORD(w_param));
-
- if (!activating && LLWinImm::isAvailable() && window_imp->mPreeditor)
- {
- window_imp->interruptLanguageTextInput();
- }
-
- // JC - I'm not sure why, but if we don't report that we handled the
- // WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work
- // properly when we run fullscreen.
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "WINDOWPROC Activate "
- << " activating " << S32(activating)
- << " minimized " << S32(minimized)
- << LL_ENDL;
- }
-
- // Don't handle this.
- break;
- }
-
- case WM_QUERYOPEN:
- // TODO: use this to return a nice icon
- break;
+ ASSERT_WINDOW_THREAD();
+ LL_PROFILE_ZONE_SCOPED;
- case WM_SYSCOMMAND:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SYSCOMMAND");
- switch(w_param)
- {
- case SC_KEYMENU:
- // Disallow the ALT key from triggering the default system menu.
- return 0;
-
- case SC_SCREENSAVE:
- case SC_MONITORPOWER:
- // eat screen save messages and prevent them!
- return 0;
- }
- break;
+ // Ignore clicks not originated in the client area, i.e. mouse-up events not preceded with a WM_LBUTTONDOWN.
+ // This helps prevent avatar walking after maximizing the window by double-clicking the title bar.
+ static bool sHandleLeftMouseUp = true;
- case WM_CLOSE:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_CLOSE");
- // Will the app allow the window to close?
- if (window_imp->mCallbacks->handleCloseRequest(window_imp))
- {
- // Get the app to initiate cleanup.
- window_imp->mCallbacks->handleQuit(window_imp);
- // The app is responsible for calling destroyWindow when done with GL
- }
- return 0;
+ // Ignore the double click received right after activating app.
+ // This is to avoid triggering double click teleport after returning focus (see MAINT-3786).
+ static bool sHandleDoubleClick = true;
- case WM_DESTROY:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_DESTROY");
- if (window_imp->shouldPostQuit())
- {
- PostQuitMessage(0); // Posts WM_QUIT with an exit code of 0
- }
- return 0;
-
- case WM_COMMAND:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_COMMAND");
- if (!HIWORD(w_param)) // this message is from a menu
- {
- window_imp->mCallbacks->handleMenuSelect(window_imp, LOWORD(w_param));
- }
- break;
-
- case WM_SYSKEYDOWN:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SYSKEYDOWN");
- // allow system keys, such as ALT-F4 to be processed by Windows
- eat_keystroke = FALSE;
- case WM_KEYDOWN:
- window_imp->mKeyCharCode = 0; // don't know until wm_char comes in next
- window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff;
- window_imp->mKeyVirtualKey = w_param;
- window_imp->mRawMsg = u_msg;
- window_imp->mRawWParam = w_param;
- window_imp->mRawLParam = l_param;
-
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYDOWN");
- {
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN "
- << " key " << S32(w_param)
- << LL_ENDL;
- }
- if(gKeyboard->handleKeyDown(w_param, mask) && eat_keystroke)
- {
- return 0;
- }
- // pass on to windows if we didn't handle it
- break;
- }
- case WM_SYSKEYUP:
- eat_keystroke = FALSE;
- case WM_KEYUP:
- {
- window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff;
- window_imp->mKeyVirtualKey = w_param;
- window_imp->mRawMsg = u_msg;
- window_imp->mRawWParam = w_param;
- window_imp->mRawLParam = l_param;
+ LLWindowWin32* window_imp = (LLWindowWin32*)GetWindowLongPtr(h_wnd, GWLP_USERDATA);
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP");
- LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER);
+ bool debug_window_proc = false; // gDebugWindowProc || debugLoggingEnabled("Window");
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "Debug WindowProc WM_KEYUP "
- << " key " << S32(w_param)
- << LL_ENDL;
- }
- if (gKeyboard->handleKeyUp(w_param, mask) && eat_keystroke)
- {
- return 0;
- }
+ if (NULL != window_imp)
+ {
+ // Has user provided their own window callback?
+ if (NULL != window_imp->mWndProc)
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WndProc");
+ if (!window_imp->mWndProc(h_wnd, u_msg, w_param, l_param))
+ {
+ // user has handled window message
+ return 0;
+ }
+ }
- // pass on to windows
- break;
- }
- case WM_IME_SETCONTEXT:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_SETCONTEXT");
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL;
- }
- if (LLWinImm::isAvailable() && window_imp->mPreeditor)
- {
- l_param &= ~ISC_SHOWUICOMPOSITIONWINDOW;
- // Invoke DefWinProc with the modified LPARAM.
- }
- break;
+ // Juggle to make sure we can get negative positions for when
+ // mouse is outside window.
+ LLCoordWindow window_coord((S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param));
- case WM_IME_STARTCOMPOSITION:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_STARTCOMPOSITION");
- if (debug_window_proc)
- {
- LL_INFOS() << "WM_IME_STARTCOMPOSITION" << LL_ENDL;
- }
- if (LLWinImm::isAvailable() && window_imp->mPreeditor)
- {
- window_imp->handleStartCompositionMessage();
- return 0;
- }
- break;
+ // pass along extended flag in mask
+ MASK mask = (l_param >> 16 & KF_EXTENDED) ? MASK_EXTENDED : 0x0;
+ BOOL eat_keystroke = TRUE;
- case WM_IME_ENDCOMPOSITION:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_ENDCOMPOSITION");
- if (debug_window_proc)
- {
- LL_INFOS() << "WM_IME_ENDCOMPOSITION" << LL_ENDL;
- }
- if (LLWinImm::isAvailable() && window_imp->mPreeditor)
- {
- return 0;
- }
- break;
+ switch (u_msg)
+ {
+ RECT update_rect;
+ S32 update_width;
+ S32 update_height;
- case WM_IME_COMPOSITION:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_COMPOSITION");
- if (debug_window_proc)
- {
- LL_INFOS() << "WM_IME_COMPOSITION" << LL_ENDL;
- }
- if (LLWinImm::isAvailable() && window_imp->mPreeditor)
- {
- window_imp->handleCompositionMessage(l_param);
- return 0;
- }
- break;
+ case WM_TIMER:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_TIMER");
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleTimerEvent(window_imp));
+ break;
+ }
- case WM_IME_REQUEST:
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_REQUEST");
- if (debug_window_proc)
- {
- LL_INFOS() << "WM_IME_REQUEST" << LL_ENDL;
- }
- if (LLWinImm::isAvailable() && window_imp->mPreeditor)
- {
- LRESULT result = 0;
- if (window_imp->handleImeRequests(w_param, l_param, &result))
- {
- return result;
- }
- }
- break;
+ case WM_DEVICECHANGE:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_DEVICECHANGE");
+ if (debug_window_proc)
+ {
+ LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param
+ << "; lParam=" << l_param << LL_ENDL;
+ }
+ if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL)
+ {
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleDeviceChange(window_imp));
+
+ return TRUE;
+ }
+ break;
+ }
- case WM_CHAR:
- window_imp->mKeyCharCode = w_param;
- window_imp->mRawMsg = u_msg;
- window_imp->mRawWParam = w_param;
- window_imp->mRawLParam = l_param;
-
- // Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need
- // to figure out how that works. - Doug
- //
- // ... Well, I don't think so.
- // How it works is explained in Win32 API document, but WM_UNICHAR didn't work
- // as specified at least on Windows XP SP1 Japanese version. I have never used
- // it since then, and I'm not sure whether it has been fixed now, but I don't think
- // it is worth trying. The good old WM_CHAR works just fine even for supplementary
- // characters. We just need to take care of surrogate pairs sent as two WM_CHAR's
- // by ourselves. It is not that tough. -- Alissa Sabre @ SL
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_CHAR");
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "Debug WindowProc WM_CHAR "
- << " key " << S32(w_param)
- << LL_ENDL;
- }
- // Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE,
- // we *did* processed the event, so I believe we should not pass it to DefWindowProc...
- window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE));
- return 0;
+ case WM_PAINT:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - 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;
+
+ WINDOW_IMP_POST(window_imp->mCallbacks->handlePaint(window_imp, update_rect.left, update_rect.top,
+ update_width, update_height));
+ break;
+ }
+ case WM_PARENTNOTIFY:
+ {
+ break;
+ }
- case WM_NCLBUTTONDOWN:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_NCLBUTTONDOWN");
- // A click in a non-client area, e.g. title bar or window border.
- sHandleLeftMouseUp = false;
- sHandleDoubleClick = true;
- }
- break;
+ case WM_SETCURSOR:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_SETCURSOR");
+ // This message is sent whenever the cursor is moved in a window.
+ // You need to set the appropriate cursor appearance.
- case WM_LBUTTONDOWN:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDOWN");
- LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
- sHandleLeftMouseUp = true;
+ // Only take control of cursor over client region of window
+ // This allows Windows(tm) to handle resize cursors, etc.
+ if (LOWORD(l_param) == HTCLIENT)
+ {
+ SetCursor(window_imp->mCursor[window_imp->mCurrentCursor]);
+ return 0;
+ }
+ break;
+ }
+ case WM_ENTERMENULOOP:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_ENTERMENULOOP");
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleWindowBlock(window_imp));
+ break;
+ }
- if (LLWinImm::isAvailable() && window_imp->mPreeditor)
- {
- window_imp->interruptLanguageTextInput();
- }
+ case WM_EXITMENULOOP:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_EXITMENULOOP");
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleWindowUnblock(window_imp));
+ break;
+ }
- // Because we move the cursor position in the app, we need to query
- // to find out where the cursor at the time the event is handled.
- // If we don't do this, many clicks could get buffered up, and if the
- // first click changes the cursor position, all subsequent clicks
- // will occur at the wrong location. JC
- if (window_imp->mMousePositionModified)
- {
- LLCoordWindow cursor_coord_window;
- window_imp->getCursorPosition(&cursor_coord_window);
- gl_coord = cursor_coord_window.convert();
- }
- else
- {
- gl_coord = window_coord.convert();
- }
- MASK mask = gKeyboard->currentMask(TRUE);
- // generate move event to update mouse coordinates
- window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
- if (window_imp->mCallbacks->handleMouseDown(window_imp, gl_coord, mask))
- {
- return 0;
- }
- }
- break;
+ case WM_ACTIVATEAPP:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_ACTIVATEAPP");
+ window_imp->post([=]()
+ {
+ // This message should be sent whenever the app gains or loses focus.
+ BOOL activating = (BOOL)w_param;
+ BOOL minimized = window_imp->getMinimized();
+
+ if (debug_window_proc)
+ {
+ LL_INFOS("Window") << "WINDOWPROC ActivateApp "
+ << " activating " << S32(activating)
+ << " minimized " << S32(minimized)
+ << " fullscreen " << S32(window_imp->mFullscreen)
+ << LL_ENDL;
+ }
+
+ if (window_imp->mFullscreen)
+ {
+ // When we run fullscreen, restoring or minimizing the app needs
+ // to switch the screen resolution
+ if (activating)
+ {
+ window_imp->setFullscreenResolution();
+ window_imp->restore();
+ }
+ else
+ {
+ window_imp->minimize();
+ window_imp->resetDisplayResolution();
+ }
+ }
+
+ if (!activating)
+ {
+ sHandleDoubleClick = false;
+ }
+
+ window_imp->mCallbacks->handleActivateApp(window_imp, activating);
+ });
+ break;
+ }
+ case WM_ACTIVATE:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_ACTIVATE");
+ window_imp->post([=]()
+ {
+ // Can be one of WA_ACTIVE, WA_CLICKACTIVE, or WA_INACTIVE
+ BOOL activating = (LOWORD(w_param) != WA_INACTIVE);
+
+ BOOL minimized = BOOL(HIWORD(w_param));
+
+ if (!activating && LLWinImm::isAvailable() && window_imp->mPreeditor)
+ {
+ window_imp->interruptLanguageTextInput();
+ }
+
+ // JC - I'm not sure why, but if we don't report that we handled the
+ // WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work
+ // properly when we run fullscreen.
+ if (debug_window_proc)
+ {
+ LL_INFOS("Window") << "WINDOWPROC Activate "
+ << " activating " << S32(activating)
+ << " minimized " << S32(minimized)
+ << LL_ENDL;
+ }
+ });
+
+ break;
+ }
- case WM_LBUTTONDBLCLK:
- //RN: ignore right button double clicks for now
- //case WM_RBUTTONDBLCLK:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDBLCLK");
+ case WM_QUERYOPEN:
+ // TODO: use this to return a nice icon
+ break;
- if (!sHandleDoubleClick)
- {
- sHandleDoubleClick = true;
- break;
- }
+ case WM_SYSCOMMAND:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_SYSCOMMAND");
+ switch (w_param)
+ {
+ case SC_KEYMENU:
+ // Disallow the ALT key from triggering the default system menu.
+ return 0;
+
+ case SC_SCREENSAVE:
+ case SC_MONITORPOWER:
+ // eat screen save messages and prevent them!
+ return 0;
+ }
+ break;
+ }
+ case WM_CLOSE:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_CLOSE");
+ window_imp->post([=]()
+ {
+ // Will the app allow the window to close?
+ if (window_imp->mCallbacks->handleCloseRequest(window_imp))
+ {
+ // Get the app to initiate cleanup.
+ window_imp->mCallbacks->handleQuit(window_imp);
+ // The app is responsible for calling destroyWindow when done with GL
+ }
+ });
+ return 0;
+ }
+ case WM_DESTROY:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_DESTROY");
+ if (window_imp->shouldPostQuit())
+ {
+ PostQuitMessage(0); // Posts WM_QUIT with an exit code of 0
+ }
+ return 0;
+ }
+ case WM_COMMAND:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_COMMAND");
+ if (!HIWORD(w_param)) // this message is from a menu
+ {
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleMenuSelect(window_imp, LOWORD(w_param)));
+ }
+ break;
+ }
+ case WM_SYSKEYDOWN:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_SYSKEYDOWN");
+ // allow system keys, such as ALT-F4 to be processed by Windows
+ eat_keystroke = FALSE;
+ }
+ case WM_KEYDOWN:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_KEYDOWN");
+ window_imp->post([=]()
+ {
+ window_imp->mKeyCharCode = 0; // don't know until wm_char comes in next
+ window_imp->mKeyScanCode = (l_param >> 16) & 0xff;
+ window_imp->mKeyVirtualKey = w_param;
+ window_imp->mRawMsg = u_msg;
+ window_imp->mRawWParam = w_param;
+ window_imp->mRawLParam = l_param;
+
+ {
+ if (debug_window_proc)
+ {
+ LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN "
+ << " key " << S32(w_param)
+ << LL_ENDL;
+ }
+
+ gKeyboard->handleKeyDown(w_param, mask);
+ }
+ });
+ return eat_keystroke;
+ }
+ case WM_SYSKEYUP:
+ eat_keystroke = FALSE;
+ case WM_KEYUP:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_KEYUP");
+ window_imp->post([=]()
+ {
+ window_imp->mKeyScanCode = (l_param >> 16) & 0xff;
+ window_imp->mKeyVirtualKey = w_param;
+ window_imp->mRawMsg = u_msg;
+ window_imp->mRawWParam = w_param;
+ window_imp->mRawLParam = l_param;
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER);
+
+ if (debug_window_proc)
+ {
+ LL_INFOS("Window") << "Debug WindowProc WM_KEYUP "
+ << " key " << S32(w_param)
+ << LL_ENDL;
+ }
+ gKeyboard->handleKeyUp(w_param, mask);
+ }
+ });
+ return eat_keystroke;
+ }
+ case WM_IME_SETCONTEXT:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_IME_SETCONTEXT");
+ if (debug_window_proc)
+ {
+ LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL;
+ }
+ if (LLWinImm::isAvailable() && window_imp->mPreeditor)
+ {
+ l_param &= ~ISC_SHOWUICOMPOSITIONWINDOW;
+ // Invoke DefWinProc with the modified LPARAM.
+ }
+ break;
+ }
+ case WM_IME_STARTCOMPOSITION:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_IME_STARTCOMPOSITION");
+ if (debug_window_proc)
+ {
+ LL_INFOS() << "WM_IME_STARTCOMPOSITION" << LL_ENDL;
+ }
+ if (LLWinImm::isAvailable() && window_imp->mPreeditor)
+ {
+ WINDOW_IMP_POST(window_imp->handleStartCompositionMessage());
+ return 0;
+ }
+ break;
+ }
+ case WM_IME_ENDCOMPOSITION:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_IME_ENDCOMPOSITION");
+ if (debug_window_proc)
+ {
+ LL_INFOS() << "WM_IME_ENDCOMPOSITION" << LL_ENDL;
+ }
+ if (LLWinImm::isAvailable() && window_imp->mPreeditor)
+ {
+ return 0;
+ }
+ break;
+ }
+ case WM_IME_COMPOSITION:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_IME_COMPOSITION");
+ if (debug_window_proc)
+ {
+ LL_INFOS() << "WM_IME_COMPOSITION" << LL_ENDL;
+ }
+ if (LLWinImm::isAvailable() && window_imp->mPreeditor)
+ {
+ WINDOW_IMP_POST(window_imp->handleCompositionMessage(l_param));
+ return 0;
+ }
+ break;
+ }
+ case WM_IME_REQUEST:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_IME_REQUEST");
+ if (debug_window_proc)
+ {
+ LL_INFOS() << "WM_IME_REQUEST" << LL_ENDL;
+ }
+ if (LLWinImm::isAvailable() && window_imp->mPreeditor)
+ {
+ LRESULT result;
+ window_imp->handleImeRequests(w_param, l_param, &result);
+ return result;
+ }
+ break;
+ }
+ case WM_CHAR:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_CHAR");
+ window_imp->post([=]()
+ {
+ window_imp->mKeyCharCode = w_param;
+ window_imp->mRawMsg = u_msg;
+ window_imp->mRawWParam = w_param;
+ window_imp->mRawLParam = l_param;
+
+ // Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need
+ // to figure out how that works. - Doug
+ //
+ // ... Well, I don't think so.
+ // How it works is explained in Win32 API document, but WM_UNICHAR didn't work
+ // as specified at least on Windows XP SP1 Japanese version. I have never used
+ // it since then, and I'm not sure whether it has been fixed now, but I don't think
+ // it is worth trying. The good old WM_CHAR works just fine even for supplementary
+ // characters. We just need to take care of surrogate pairs sent as two WM_CHAR's
+ // by ourselves. It is not that tough. -- Alissa Sabre @ SL
+ if (debug_window_proc)
+ {
+ LL_INFOS("Window") << "Debug WindowProc WM_CHAR "
+ << " key " << S32(w_param)
+ << LL_ENDL;
+ }
+ // Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE,
+ // we *did* processed the event, so I believe we should not pass it to DefWindowProc...
+ window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE));
+ });
+ return 0;
+ }
+ case WM_NCLBUTTONDOWN:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_NCLBUTTONDOWN");
+ {
+ // A click in a non-client area, e.g. title bar or window border.
+ window_imp->post([=]()
+ {
+ sHandleLeftMouseUp = false;
+ sHandleDoubleClick = true;
+ });
+ }
+ break;
+ }
+ case WM_LBUTTONDOWN:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONDOWN");
+ {
+ LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
+ window_imp->postMouseButtonEvent([=]()
+ {
+ sHandleLeftMouseUp = true;
+
+ if (LLWinImm::isAvailable() && window_imp->mPreeditor)
+ {
+ window_imp->interruptLanguageTextInput();
+ }
+
+ MASK mask = gKeyboard->currentMask(TRUE);
+ auto gl_coord = window_imp->mCursorPosition.convert();
+ window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
+ window_imp->mCallbacks->handleMouseDown(window_imp, gl_coord, mask);
+ });
+
+ return 0;
+ }
+ break;
+ }
- // Because we move the cursor position in the app, we need to query
- // to find out where the cursor at the time the event is handled.
- // If we don't do this, many clicks could get buffered up, and if the
- // first click changes the cursor position, all subsequent clicks
- // will occur at the wrong location. JC
- if (window_imp->mMousePositionModified)
- {
- LLCoordWindow cursor_coord_window;
- window_imp->getCursorPosition(&cursor_coord_window);
- gl_coord = cursor_coord_window.convert();
- }
- else
- {
- gl_coord = window_coord.convert();
- }
- MASK mask = gKeyboard->currentMask(TRUE);
- // generate move event to update mouse coordinates
- window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
- if (window_imp->mCallbacks->handleDoubleClick(window_imp, gl_coord, mask) )
- {
- return 0;
- }
- }
- break;
+ case WM_LBUTTONDBLCLK:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONDBLCLK");
+ window_imp->postMouseButtonEvent([=]()
+ {
+ //RN: ignore right button double clicks for now
+ //case WM_RBUTTONDBLCLK:
+ if (!sHandleDoubleClick)
+ {
+ sHandleDoubleClick = true;
+ return;
+ }
+ MASK mask = gKeyboard->currentMask(TRUE);
+
+ // generate move event to update mouse coordinates
+ window_imp->mCursorPosition = window_coord;
+ window_imp->mCallbacks->handleDoubleClick(window_imp, window_imp->mCursorPosition.convert(), mask);
+ });
+
+ return 0;
+ }
+ case WM_LBUTTONUP:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONUP");
+ {
+ window_imp->postMouseButtonEvent([=]()
+ {
+ LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
+ if (!sHandleLeftMouseUp)
+ {
+ sHandleLeftMouseUp = true;
+ return;
+ }
+ sHandleDoubleClick = true;
+
+
+ MASK mask = gKeyboard->currentMask(TRUE);
+ // generate move event to update mouse coordinates
+ window_imp->mCursorPosition = window_coord;
+ window_imp->mCallbacks->handleMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask);
+ });
+ }
+ return 0;
+ }
+ case WM_RBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_RBUTTONDOWN");
+ {
+ LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
+ window_imp->post([=]()
+ {
+ if (LLWinImm::isAvailable() && window_imp->mPreeditor)
+ {
+ WINDOW_IMP_POST(window_imp->interruptLanguageTextInput());
+ }
+
+ MASK mask = gKeyboard->currentMask(TRUE);
+ // generate move event to update mouse coordinates
+ auto gl_coord = window_imp->mCursorPosition.convert();
+ window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
+ window_imp->mCallbacks->handleRightMouseDown(window_imp, gl_coord, mask);
+ });
+ }
+ return 0;
+ }
+ break;
- case WM_LBUTTONUP:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONUP");
- LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
+ case WM_RBUTTONUP:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_RBUTTONUP");
+ {
+ LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
+ window_imp->postMouseButtonEvent([=]()
+ {
+ MASK mask = gKeyboard->currentMask(TRUE);
+ window_imp->mCallbacks->handleRightMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask);
+ });
+ }
+ }
+ break;
- if (!sHandleLeftMouseUp)
- {
- sHandleLeftMouseUp = true;
- break;
- }
- sHandleDoubleClick = true;
-
- //if (gDebugClicks)
- //{
- // LL_INFOS("Window") << "WndProc left button up" << LL_ENDL;
- //}
- // Because we move the cursor position in the app, we need to query
- // to find out where the cursor at the time the event is handled.
- // If we don't do this, many clicks could get buffered up, and if the
- // first click changes the cursor position, all subsequent clicks
- // will occur at the wrong location. JC
- if (window_imp->mMousePositionModified)
- {
- LLCoordWindow cursor_coord_window;
- window_imp->getCursorPosition(&cursor_coord_window);
- gl_coord = cursor_coord_window.convert();
- }
- else
- {
- gl_coord = window_coord.convert();
- }
- MASK mask = gKeyboard->currentMask(TRUE);
- // generate move event to update mouse coordinates
- window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
- if (window_imp->mCallbacks->handleMouseUp(window_imp, gl_coord, mask))
- {
- return 0;
- }
- }
- break;
+ case WM_MBUTTONDOWN:
+ // case WM_MBUTTONDBLCLK:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_MBUTTONDOWN");
+ {
+ LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
+ window_imp->postMouseButtonEvent([=]()
+ {
+ if (LLWinImm::isAvailable() && window_imp->mPreeditor)
+ {
+ window_imp->interruptLanguageTextInput();
+ }
+
+ MASK mask = gKeyboard->currentMask(TRUE);
+ window_imp->mCallbacks->handleMiddleMouseDown(window_imp, window_imp->mCursorPosition.convert(), mask);
+ });
+ }
+ }
+ break;
- case WM_RBUTTONDBLCLK:
- case WM_RBUTTONDOWN:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONDOWN");
- LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
- if (LLWinImm::isAvailable() && window_imp->mPreeditor)
- {
- window_imp->interruptLanguageTextInput();
- }
+ case WM_MBUTTONUP:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_MBUTTONUP");
+ {
+ LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
+ window_imp->postMouseButtonEvent([=]()
+ {
+ MASK mask = gKeyboard->currentMask(TRUE);
+ window_imp->mCallbacks->handleMiddleMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask);
+ });
+ }
+ }
+ break;
+ case WM_XBUTTONDOWN:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_XBUTTONDOWN");
+ window_imp->postMouseButtonEvent([=]()
+ {
+ LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
+ S32 button = GET_XBUTTON_WPARAM(w_param);
+ if (LLWinImm::isAvailable() && window_imp->mPreeditor)
+ {
+ window_imp->interruptLanguageTextInput();
+ }
+
+ MASK mask = gKeyboard->currentMask(TRUE);
+ // Windows uses numbers 1 and 2 for buttons, remap to 4, 5
+ window_imp->mCallbacks->handleOtherMouseDown(window_imp, window_imp->mCursorPosition.convert(), mask, button + 3);
+ });
+
+ }
+ break;
- // Because we move the cursor position in the llviewerapp, we need to query
- // to find out where the cursor at the time the event is handled.
- // If we don't do this, many clicks could get buffered up, and if the
- // first click changes the cursor position, all subsequent clicks
- // will occur at the wrong location. JC
- if (window_imp->mMousePositionModified)
- {
- LLCoordWindow cursor_coord_window;
- window_imp->getCursorPosition(&cursor_coord_window);
- gl_coord = cursor_coord_window.convert();
- }
- else
- {
- gl_coord = window_coord.convert();
- }
- MASK mask = gKeyboard->currentMask(TRUE);
- // generate move event to update mouse coordinates
- window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
- if (window_imp->mCallbacks->handleRightMouseDown(window_imp, gl_coord, mask))
- {
- return 0;
- }
- }
- break;
+ case WM_XBUTTONUP:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_XBUTTONUP");
+ window_imp->postMouseButtonEvent([=]()
+ {
- case WM_RBUTTONUP:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONUP");
- LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
- // Because we move the cursor position in the app, we need to query
- // to find out where the cursor at the time the event is handled.
- // If we don't do this, many clicks could get buffered up, and if the
- // first click changes the cursor position, all subsequent clicks
- // will occur at the wrong location. JC
- if (window_imp->mMousePositionModified)
- {
- LLCoordWindow cursor_coord_window;
- window_imp->getCursorPosition(&cursor_coord_window);
- gl_coord = cursor_coord_window.convert();
- }
- else
- {
- gl_coord = window_coord.convert();
- }
- MASK mask = gKeyboard->currentMask(TRUE);
- // generate move event to update mouse coordinates
- window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
- if (window_imp->mCallbacks->handleRightMouseUp(window_imp, gl_coord, mask))
- {
- return 0;
- }
- }
- break;
+ LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
- case WM_MBUTTONDOWN:
-// case WM_MBUTTONDBLCLK:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONDOWN");
- LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
- if (LLWinImm::isAvailable() && window_imp->mPreeditor)
- {
- window_imp->interruptLanguageTextInput();
- }
+ S32 button = GET_XBUTTON_WPARAM(w_param);
+ MASK mask = gKeyboard->currentMask(TRUE);
+ // Windows uses numbers 1 and 2 for buttons, remap to 4, 5
+ window_imp->mCallbacks->handleOtherMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask, button + 3);
+ });
+ }
+ break;
- // Because we move the cursor position in tllviewerhe app, we need to query
- // to find out where the cursor at the time the event is handled.
- // If we don't do this, many clicks could get buffered up, and if the
- // first click changes the cursor position, all subsequent clicks
- // will occur at the wrong location. JC
- if (window_imp->mMousePositionModified)
- {
- LLCoordWindow cursor_coord_window;
- window_imp->getCursorPosition(&cursor_coord_window);
- gl_coord = cursor_coord_window.convert();
- }
- else
- {
- gl_coord = window_coord.convert();
- }
- MASK mask = gKeyboard->currentMask(TRUE);
- // generate move event to update mouse coordinates
- window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
- if (window_imp->mCallbacks->handleMiddleMouseDown(window_imp, gl_coord, mask))
- {
- return 0;
- }
- }
- break;
+ case WM_MOUSEWHEEL:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEWHEEL");
+ static short z_delta = 0;
- case WM_MBUTTONUP:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONUP");
- LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
- // Because we move the cursor position in the llviewer app, we need to query
- // to find out where the cursor at the time the event is handled.
- // If we don't do this, many clicks could get buffered up, and if the
- // first click changes the cursor position, all subsequent clicks
- // will occur at the wrong location. JC
- if (window_imp->mMousePositionModified)
- {
- LLCoordWindow cursor_coord_window;
- window_imp->getCursorPosition(&cursor_coord_window);
- gl_coord = cursor_coord_window.convert();
- }
- else
- {
- gl_coord = window_coord.convert();
- }
- MASK mask = gKeyboard->currentMask(TRUE);
- // generate move event to update mouse coordinates
- window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
- if (window_imp->mCallbacks->handleMiddleMouseUp(window_imp, gl_coord, mask))
- {
- return 0;
- }
- }
- break;
- case WM_XBUTTONDOWN:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONDOWN");
- LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
- S32 button = GET_XBUTTON_WPARAM(w_param);
- if (LLWinImm::isAvailable() && window_imp->mPreeditor)
- {
- window_imp->interruptLanguageTextInput();
- }
+ RECT client_rect;
- // Because we move the cursor position in tllviewerhe app, we need to query
- // to find out where the cursor at the time the event is handled.
- // If we don't do this, many clicks could get buffered up, and if the
- // first click changes the cursor position, all subsequent clicks
- // will occur at the wrong location. JC
- if (window_imp->mMousePositionModified)
- {
- LLCoordWindow cursor_coord_window;
- window_imp->getCursorPosition(&cursor_coord_window);
- gl_coord = cursor_coord_window.convert();
- }
- else
- {
- gl_coord = window_coord.convert();
- }
- MASK mask = gKeyboard->currentMask(TRUE);
- // generate move event to update mouse coordinates
- window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
- // Windows uses numbers 1 and 2 for buttons, remap to 4, 5
- if (window_imp->mCallbacks->handleOtherMouseDown(window_imp, gl_coord, mask, button + 3))
- {
- return 0;
- }
- }
- break;
+ // eat scroll events that occur outside our window, since we use mouse position to direct scroll
+ // instead of keyboard focus
+ // NOTE: mouse_coord is in *window* coordinates for scroll events
+ POINT mouse_coord = { (S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param) };
- case WM_XBUTTONUP:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONUP");
- LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER);
- S32 button = GET_XBUTTON_WPARAM(w_param);
- // Because we move the cursor position in the llviewer app, we need to query
- // to find out where the cursor at the time the event is handled.
- // If we don't do this, many clicks could get buffered up, and if the
- // first click changes the cursor position, all subsequent clicks
- // will occur at the wrong location. JC
- if (window_imp->mMousePositionModified)
- {
- LLCoordWindow cursor_coord_window;
- window_imp->getCursorPosition(&cursor_coord_window);
- gl_coord = cursor_coord_window.convert();
- }
- else
- {
- gl_coord = window_coord.convert();
- }
- MASK mask = gKeyboard->currentMask(TRUE);
- // generate move event to update mouse coordinates
- window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask);
- // Windows uses numbers 1 and 2 for buttons, remap to 4, 5
- if (window_imp->mCallbacks->handleOtherMouseUp(window_imp, gl_coord, mask, button + 3))
- {
- return 0;
- }
- }
- break;
+ if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord)
+ && GetClientRect(window_imp->mWindowHandle, &client_rect))
+ {
+ // we have a valid mouse point and client rect
+ if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x
+ || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y)
+ {
+ // mouse is outside of client rect, so don't do anything
+ return 0;
+ }
+ }
- case WM_MOUSEWHEEL:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEWHEEL");
- static short z_delta = 0;
+ S16 incoming_z_delta = HIWORD(w_param);
+ z_delta += incoming_z_delta;
+ // cout << "z_delta " << z_delta << endl;
+
+ // current mouse wheels report changes in increments of zDelta (+120, -120)
+ // Future, higher resolution mouse wheels may report smaller deltas.
+ // So we sum the deltas and only act when we've exceeded WHEEL_DELTA
+ //
+ // If the user rapidly spins the wheel, we can get messages with
+ // large deltas, like 480 or so. Thus we need to scroll more quickly.
+ if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta)
+ {
+ short clicks = -z_delta / WHEEL_DELTA;
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleScrollWheel(window_imp, clicks));
+ z_delta = 0;
+ }
+ return 0;
+ }
+ /*
+ // TODO: add this after resolving _WIN32_WINNT issue
+ case WM_MOUSELEAVE:
+ {
+ window_imp->mCallbacks->handleMouseLeave(window_imp);
+
+ // TRACKMOUSEEVENT track_mouse_event;
+ // track_mouse_event.cbSize = sizeof( TRACKMOUSEEVENT );
+ // track_mouse_event.dwFlags = TME_LEAVE;
+ // track_mouse_event.hwndTrack = h_wnd;
+ // track_mouse_event.dwHoverTime = HOVER_DEFAULT;
+ // TrackMouseEvent( &track_mouse_event );
+ return 0;
+ }
+ */
+ case WM_MOUSEHWHEEL:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEHWHEEL");
+ static short h_delta = 0;
- RECT client_rect;
+ RECT client_rect;
- // eat scroll events that occur outside our window, since we use mouse position to direct scroll
- // instead of keyboard focus
- // NOTE: mouse_coord is in *window* coordinates for scroll events
- POINT mouse_coord = {(S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)};
+ // eat scroll events that occur outside our window, since we use mouse position to direct scroll
+ // instead of keyboard focus
+ // NOTE: mouse_coord is in *window* coordinates for scroll events
+ POINT mouse_coord = { (S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param) };
- if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord)
- && GetClientRect(window_imp->mWindowHandle, &client_rect))
- {
- // we have a valid mouse point and client rect
- if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x
- || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y)
- {
- // mouse is outside of client rect, so don't do anything
- return 0;
- }
- }
+ if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord)
+ && GetClientRect(window_imp->mWindowHandle, &client_rect))
+ {
+ // we have a valid mouse point and client rect
+ if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x
+ || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y)
+ {
+ // mouse is outside of client rect, so don't do anything
+ return 0;
+ }
+ }
- S16 incoming_z_delta = HIWORD(w_param);
- z_delta += incoming_z_delta;
- // cout << "z_delta " << z_delta << endl;
-
- // current mouse wheels report changes in increments of zDelta (+120, -120)
- // Future, higher resolution mouse wheels may report smaller deltas.
- // So we sum the deltas and only act when we've exceeded WHEEL_DELTA
- //
- // If the user rapidly spins the wheel, we can get messages with
- // large deltas, like 480 or so. Thus we need to scroll more quickly.
- if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta)
- {
- window_imp->mCallbacks->handleScrollWheel(window_imp, -z_delta / WHEEL_DELTA);
- z_delta = 0;
- }
- return 0;
- }
- /*
- // TODO: add this after resolving _WIN32_WINNT issue
- case WM_MOUSELEAVE:
- {
- window_imp->mCallbacks->handleMouseLeave(window_imp);
-
- // TRACKMOUSEEVENT track_mouse_event;
- // track_mouse_event.cbSize = sizeof( TRACKMOUSEEVENT );
- // track_mouse_event.dwFlags = TME_LEAVE;
- // track_mouse_event.hwndTrack = h_wnd;
- // track_mouse_event.dwHoverTime = HOVER_DEFAULT;
- // TrackMouseEvent( &track_mouse_event );
- return 0;
- }
- */
- case WM_MOUSEHWHEEL:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEHWHEEL");
- static short h_delta = 0;
+ S16 incoming_h_delta = HIWORD(w_param);
+ h_delta += incoming_h_delta;
- RECT client_rect;
+ // If the user rapidly spins the wheel, we can get messages with
+ // large deltas, like 480 or so. Thus we need to scroll more quickly.
+ if (h_delta <= -WHEEL_DELTA || WHEEL_DELTA <= h_delta)
+ {
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleScrollHWheel(window_imp, h_delta / WHEEL_DELTA));
+ h_delta = 0;
+ }
+ return 0;
+ }
+ // Handle mouse movement within the window
+ case WM_MOUSEMOVE:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEMOVE");
+ // DO NOT use mouse event queue for move events to ensure cursor position is updated
+ // when button events are handled
+ WINDOW_IMP_POST(
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEMOVE lambda");
+
+ MASK mask = gKeyboard->currentMask(TRUE);
+ window_imp->mMouseMask = mask;
+ window_imp->mCursorPosition = window_coord;
+ });
+ return 0;
+ }
- // eat scroll events that occur outside our window, since we use mouse position to direct scroll
- // instead of keyboard focus
- // NOTE: mouse_coord is in *window* coordinates for scroll events
- POINT mouse_coord = {(S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)};
+ case WM_GETMINMAXINFO:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_GETMINMAXINFO");
+ LPMINMAXINFO min_max = (LPMINMAXINFO)l_param;
+ min_max->ptMinTrackSize.x = window_imp->mMinWindowWidth;
+ min_max->ptMinTrackSize.y = window_imp->mMinWindowHeight;
+ return 0;
+ }
- if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord)
- && GetClientRect(window_imp->mWindowHandle, &client_rect))
- {
- // we have a valid mouse point and client rect
- if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x
- || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y)
- {
- // mouse is outside of client rect, so don't do anything
- return 0;
- }
- }
+ case WM_SIZE:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_SIZE");
+ S32 width = S32(LOWORD(l_param));
+ S32 height = S32(HIWORD(l_param));
- S16 incoming_h_delta = HIWORD(w_param);
- h_delta += incoming_h_delta;
+ if (debug_window_proc)
+ {
+ BOOL maximized = (w_param == SIZE_MAXIMIZED);
+ BOOL restored = (w_param == SIZE_RESTORED);
+ BOOL minimized = (w_param == SIZE_MINIMIZED);
+
+ LL_INFOS("Window") << "WINDOWPROC Size "
+ << width << "x" << height
+ << " max " << S32(maximized)
+ << " min " << S32(minimized)
+ << " rest " << S32(restored)
+ << LL_ENDL;
+ }
- // If the user rapidly spins the wheel, we can get messages with
- // large deltas, like 480 or so. Thus we need to scroll more quickly.
- if (h_delta <= -WHEEL_DELTA || WHEEL_DELTA <= h_delta)
- {
- window_imp->mCallbacks->handleScrollHWheel(window_imp, h_delta / WHEEL_DELTA);
- h_delta = 0;
- }
- return 0;
- }
- // Handle mouse movement within the window
- case WM_MOUSEMOVE:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEMOVE");
- MASK mask = gKeyboard->currentMask(TRUE);
- window_imp->mCallbacks->handleMouseMove(window_imp, window_coord.convert(), mask);
- return 0;
- }
+ // There's an odd behavior with WM_SIZE that I would call a bug. If
+ // the window is maximized, and you call MoveWindow() with a size smaller
+ // than a maximized window, it ends up sending WM_SIZE with w_param set
+ // to SIZE_MAXIMIZED -- which isn't true. So the logic below doesn't work.
+ // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see
+ // LLWindowWin32::moveWindow in this file).
- case WM_GETMINMAXINFO:
- {
- LPMINMAXINFO min_max = (LPMINMAXINFO)l_param;
- min_max->ptMinTrackSize.x = window_imp->mMinWindowWidth;
- min_max->ptMinTrackSize.y = window_imp->mMinWindowHeight;
- return 0;
- }
+ // If we are now restored, but we weren't before, this
+ // means that the window was un-minimized.
+ if (w_param == SIZE_RESTORED && window_imp->mLastSizeWParam != SIZE_RESTORED)
+ {
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleActivate(window_imp, TRUE));
+ }
- case WM_SIZE:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SIZE");
- S32 width = S32( LOWORD(l_param) );
- S32 height = S32( HIWORD(l_param) );
+ // handle case of window being maximized from fully minimized state
+ if (w_param == SIZE_MAXIMIZED && window_imp->mLastSizeWParam != SIZE_MAXIMIZED)
+ {
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleActivate(window_imp, TRUE));
+ }
- if (debug_window_proc)
- {
- BOOL maximized = ( w_param == SIZE_MAXIMIZED );
- BOOL restored = ( w_param == SIZE_RESTORED );
- BOOL minimized = ( w_param == SIZE_MINIMIZED );
-
- LL_INFOS("Window") << "WINDOWPROC Size "
- << width << "x" << height
- << " max " << S32(maximized)
- << " min " << S32(minimized)
- << " rest " << S32(restored)
- << LL_ENDL;
- }
+ // Also handle the minimization case
+ if (w_param == SIZE_MINIMIZED && window_imp->mLastSizeWParam != SIZE_MINIMIZED)
+ {
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleActivate(window_imp, FALSE));
+ }
- // There's an odd behavior with WM_SIZE that I would call a bug. If
- // the window is maximized, and you call MoveWindow() with a size smaller
- // than a maximized window, it ends up sending WM_SIZE with w_param set
- // to SIZE_MAXIMIZED -- which isn't true. So the logic below doesn't work.
- // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see
- // LLWindowWin32::moveWindow in this file).
+ // Actually resize all of our views
+ if (w_param != SIZE_MINIMIZED)
+ {
+ // Ignore updates for minimizing and minimized "windows"
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleResize(window_imp,
+ LOWORD(l_param),
+ HIWORD(l_param)));
+ }
- // If we are now restored, but we weren't before, this
- // means that the window was un-minimized.
- if (w_param == SIZE_RESTORED && window_imp->mLastSizeWParam != SIZE_RESTORED)
- {
- window_imp->mCallbacks->handleActivate(window_imp, TRUE);
- }
+ window_imp->mLastSizeWParam = w_param;
- // handle case of window being maximized from fully minimized state
- if (w_param == SIZE_MAXIMIZED && window_imp->mLastSizeWParam != SIZE_MAXIMIZED)
- {
- window_imp->mCallbacks->handleActivate(window_imp, TRUE);
- }
+ return 0;
+ }
- // Also handle the minimization case
- if (w_param == SIZE_MINIMIZED && window_imp->mLastSizeWParam != SIZE_MINIMIZED)
- {
- window_imp->mCallbacks->handleActivate(window_imp, FALSE);
- }
+ case WM_DPICHANGED:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_DPICHANGED");
+ LPRECT lprc_new_scale;
+ F32 new_scale = F32(LOWORD(w_param)) / F32(USER_DEFAULT_SCREEN_DPI);
+ lprc_new_scale = (LPRECT)l_param;
+ S32 new_width = lprc_new_scale->right - lprc_new_scale->left;
+ S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top;
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height));
+
+ SetWindowPos(h_wnd,
+ HWND_TOP,
+ lprc_new_scale->left,
+ lprc_new_scale->top,
+ new_width,
+ new_height,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+
+ return 0;
+ }
- // Actually resize all of our views
- if (w_param != SIZE_MINIMIZED)
- {
- // Ignore updates for minimizing and minimized "windows"
- window_imp->mCallbacks->handleResize( window_imp,
- LOWORD(l_param),
- HIWORD(l_param) );
- }
+ case WM_SETFOCUS:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_SETFOCUS");
+ if (debug_window_proc)
+ {
+ LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL;
+ }
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleFocus(window_imp));
+ return 0;
+ }
- window_imp->mLastSizeWParam = w_param;
+ case WM_KILLFOCUS:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_KILLFOCUS");
+ if (debug_window_proc)
+ {
+ LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL;
+ }
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleFocusLost(window_imp));
+ return 0;
+ }
- return 0;
- }
+ case WM_COPYDATA:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_COPYDATA");
+ {
+ // received a URL
+ PCOPYDATASTRUCT myCDS = (PCOPYDATASTRUCT)l_param;
+ void* data = new U8[myCDS->cbData];
+ memcpy(data, myCDS->lpData, myCDS->cbData);
+ auto myType = myCDS->dwData;
+
+ window_imp->post([=]()
+ {
+ window_imp->mCallbacks->handleDataCopy(window_imp, myType, data);
+ delete[] data;
+ });
+ };
+ return 0;
+
+ break;
+ }
+ case WM_SETTINGCHANGE:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_SETTINGCHANGE");
+ if (w_param == SPI_SETMOUSEVANISH)
+ {
+ if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &window_imp->mMouseVanish, 0))
+ {
+ WINDOW_IMP_POST(window_imp->mMouseVanish = TRUE);
+ }
+ }
+ }
+ break;
- case WM_DPICHANGED:
- {
- LPRECT lprc_new_scale;
- F32 new_scale = F32(LOWORD(w_param)) / F32(USER_DEFAULT_SCREEN_DPI);
- lprc_new_scale = (LPRECT)l_param;
- S32 new_width = lprc_new_scale->right - lprc_new_scale->left;
- S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top;
- if (window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height))
- {
- SetWindowPos(h_wnd,
- HWND_TOP,
- lprc_new_scale->left,
- lprc_new_scale->top,
- new_width,
- new_height,
- SWP_NOZORDER | SWP_NOACTIVATE);
- }
- return 0;
- }
-
- case WM_SETFOCUS:
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL;
- }
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS");
- window_imp->mCallbacks->handleFocus(window_imp);
- return 0;
-
- case WM_KILLFOCUS:
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL;
- }
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KILLFOCUS");
- window_imp->mCallbacks->handleFocusLost(window_imp);
- return 0;
-
- case WM_COPYDATA:
- {
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_COPYDATA");
- // received a URL
- PCOPYDATASTRUCT myCDS = (PCOPYDATASTRUCT) l_param;
- window_imp->mCallbacks->handleDataCopy(window_imp, myCDS->dwData, myCDS->lpData);
- };
- return 0;
-
- break;
-
- case WM_SETTINGCHANGE:
- {
- if (w_param == SPI_SETMOUSEVANISH)
- {
- if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &window_imp->mMouseVanish, 0))
- {
- window_imp->mMouseVanish = TRUE;
- }
- }
- }
- break;
- default:
- {
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "Unhandled windows message code: " << U32(u_msg) << LL_ENDL;
- }
- }
- break;
- }
-
- window_imp->mCallbacks->handlePauseWatchdog(window_imp);
- }
+ case WM_INPUT:
+ {
+ LL_PROFILE_ZONE_NAMED("MWP - WM_INPUT");
+
+ UINT dwSize = 0;
+ GetRawInputData((HRAWINPUT)l_param, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
+ llassert(dwSize < 1024);
+
+ U8 lpb[1024];
+
+ if (GetRawInputData((HRAWINPUT)l_param, RID_INPUT, (void*)lpb, &dwSize, sizeof(RAWINPUTHEADER)) == dwSize)
+ {
+ RAWINPUT* raw = (RAWINPUT*)lpb;
+
+ if (raw->header.dwType == RIM_TYPEMOUSE)
+ {
+ LLMutexLock lock(&window_imp->mRawMouseMutex);
+ window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
+ window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
+ }
+ }
+ }
+ //list of messages we get often that we don't care to log about
+ case WM_NCHITTEST:
+ case WM_NCMOUSEMOVE:
+ case WM_NCMOUSELEAVE:
+ case WM_MOVING:
+ case WM_MOVE:
+ case WM_WINDOWPOSCHANGING:
+ case WM_WINDOWPOSCHANGED:
+ break;
+
+ default:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - default");
+ if (debug_window_proc)
+ {
+ LL_INFOS("Window") << "Unhandled windows message code: 0x" << std::hex << U32(u_msg) << LL_ENDL;
+ }
+ }
+ break;
+ }
+ }
else
{
// (NULL == window_imp)
LL_DEBUGS("Window") << "No window implementation to handle message with, message code: " << U32(u_msg) << LL_ENDL;
}
- // pass unhandled messages down to Windows
- return DefWindowProc(h_wnd, u_msg, w_param, l_param);
+ // pass unhandled messages down to Windows
+ LRESULT ret;
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - DefWindowProc");
+ ret = DefWindowProc(h_wnd, u_msg, w_param, l_param);
+ }
+ return ret;
}
BOOL LLWindowWin32::convertCoords(LLCoordGL from, LLCoordWindow *to)
@@ -3184,6 +3334,8 @@ BOOL LLWindowWin32::copyTextToClipboard(const LLWString& wstr)
// Constrains the mouse to the window.
void LLWindowWin32::setMouseClipping( BOOL b )
{
+ LL_PROFILE_ZONE_SCOPED;
+ ASSERT_MAIN_THREAD();
if( b != mIsMouseClipping )
{
BOOL success = FALSE;
@@ -3260,6 +3412,7 @@ F32 LLWindowWin32::getGamma()
BOOL LLWindowWin32::restoreGamma()
{
+ ASSERT_MAIN_THREAD();
if (mCustomGammaSet != FALSE)
{
LL_DEBUGS("Window") << "Restoring gamma" << LL_ENDL;
@@ -3271,6 +3424,7 @@ BOOL LLWindowWin32::restoreGamma()
BOOL LLWindowWin32::setGamma(const F32 gamma)
{
+ ASSERT_MAIN_THREAD();
mCurrentGamma = gamma;
//Get the previous gamma ramp to restore later.
@@ -3309,6 +3463,7 @@ BOOL LLWindowWin32::setGamma(const F32 gamma)
void LLWindowWin32::setFSAASamples(const U32 fsaa_samples)
{
+ ASSERT_MAIN_THREAD();
mFSAASamples = fsaa_samples;
}
@@ -3319,6 +3474,7 @@ U32 LLWindowWin32::getFSAASamples()
LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions)
{
+ ASSERT_MAIN_THREAD();
if (!mSupportedResolutions)
{
mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS];
@@ -3473,7 +3629,11 @@ BOOL LLWindowWin32::resetDisplayResolution()
void LLWindowWin32::swapBuffers()
{
+ LL_PROFILE_ZONE_SCOPED;
+ ASSERT_MAIN_THREAD();
SwapBuffers(mhDC);
+
+ LL_PROFILER_GPU_COLLECT
}
@@ -3946,6 +4106,7 @@ void LLWindowWin32::updateLanguageTextInputArea()
void LLWindowWin32::interruptLanguageTextInput()
{
+ ASSERT_MAIN_THREAD();
if (mPreeditor && LLWinImm::isAvailable())
{
HIMC himc = LLWinImm::getContext(mWindowHandle);
@@ -4148,6 +4309,7 @@ static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_leng
// for files and via IDropTarget interface requests.
LLWindowCallbacks::DragNDropResult LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url )
{
+ ASSERT_MAIN_THREAD();
return mCallbacks->handleDragNDrop( this, gl_coord, mask, action, url );
}
@@ -4196,6 +4358,7 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res
LL_WARNS("Window") << "*** IMR_QUERYCHARPOSITON called but getPreeditLocation failed." << LL_ENDL;
return FALSE;
}
+
fillCharPosition(caret_coord, preedit_bounds, text_control, char_position);
*result = 1;
@@ -4403,3 +4566,77 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
#endif // LL_WINDOWS
+
+inline LLWindowWin32Thread::LLWindowWin32Thread(LLWindowWin32* window)
+ : LLThread("Window Thread"),
+ mWindow(window),
+ mFunctionQueue(MAX_QUEUE_SIZE)
+{
+
+}
+
+inline void LLWindowWin32Thread::run()
+{
+ sWindowThreadId = getID();
+ while (!mFinished)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+
+
+ if (mWindow && mWindow->mWindowHandle != 0)
+ {
+ MSG msg;
+ BOOL status;
+ if (mWindow->mhDC == 0)
+ {
+ LL_PROFILE_ZONE_NAMED("w32t - PeekMessage");
+ status = PeekMessage(&msg, mWindow->mWindowHandle, 0, 0, PM_REMOVE);
+ }
+ else
+ {
+ LL_PROFILE_ZONE_NAMED("w32t - GetMessage");
+ status = GetMessage(&msg, mWindow->mWindowHandle, 0, 0);
+ }
+ if (status > 0)
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+
+ mMessageQueue.pushFront(msg);
+ }
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED("w32t - Function Queue");
+ //process any pending functions
+ std::function<void()> curFunc;
+ while (mFunctionQueue.tryPopBack(curFunc))
+ {
+ curFunc();
+ }
+ }
+
+#if 0
+ {
+ LL_PROFILE_ZONE_NAMED("w32t - Sleep");
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ }
+#endif
+ }
+}
+
+void LLWindowWin32Thread::post(const std::function<void()>& func)
+{
+ mFunctionQueue.pushFront(func);
+}
+
+void LLWindowWin32::post(const std::function<void()>& func)
+{
+ mFunctionQueue.pushFront(func);
+}
+
+void LLWindowWin32::postMouseButtonEvent(const std::function<void()>& func)
+{
+ mMouseQueue.pushFront(func);
+}
+
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 0b3d14fb16..d082080807 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -33,11 +33,47 @@
#include "llwindow.h"
#include "llwindowcallbacks.h"
#include "lldragdropwin32.h"
+#include "llthread.h"
+#include "llthreadsafequeue.h"
+#include "llmutex.h"
// Hack for async host by name
#define LL_WM_HOST_RESOLVED (WM_APP + 1)
typedef void (*LLW32MsgCallback)(const MSG &msg);
+class LLWindowWin32;
+
+// Thread that owns the Window Handle
+class LLWindowWin32Thread : public LLThread
+{
+public:
+ class Message
+ {
+ public:
+ LRESULT mMsg;
+ };
+
+ static const int MAX_QUEUE_SIZE = 2048;
+
+ LLThreadSafeQueue<MSG> mMessageQueue;
+ LLThreadSafeQueue<std::function<void()>> mFunctionQueue;
+
+ bool mFinished = false;
+
+ LLWindowWin32Thread(LLWindowWin32* window);
+
+ void run() override;
+
+ void post(const std::function<void()>& func);
+
+private:
+
+ // call PeekMessage and pull enqueue messages for later processing
+ void gatherInput();
+ LLWindowWin32* mWindow = nullptr;
+
+};
+
class LLWindowWin32 : public LLWindow
{
public:
@@ -57,9 +93,15 @@ public:
/*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 switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL);
+ /*virtual*/ void setTitle(const std::string title);
+ void* createSharedContext() override;
+ void makeContextCurrent(void* context) override;
+ void destroySharedContext(void* context) override;
+ /*virtual*/ void toggleVSync(bool enable_vsync);
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position);
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position);
+ /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta);
/*virtual*/ void showCursor();
/*virtual*/ void hideCursor();
/*virtual*/ void showCursorFromMouseMove();
@@ -123,7 +165,7 @@ public:
protected:
LLWindowWin32(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 disable_vsync, BOOL use_gl,
+ BOOL fullscreen, BOOL clearBg, BOOL enable_vsync, BOOL use_gl,
BOOL ignore_pixel_depth, U32 fsaa_samples);
~LLWindowWin32();
@@ -172,9 +214,9 @@ protected:
WCHAR *mWindowTitle;
WCHAR *mWindowClassName;
- HWND mWindowHandle; // window handle
- HGLRC mhRC; // OpenGL rendering context
- HDC mhDC; // Windows Device context handle
+ HWND mWindowHandle = 0; // window handle
+ HGLRC mhRC = 0; // OpenGL rendering context
+ HDC mhDC = 0; // Windows Device context handle
HINSTANCE mhInstance; // handle to application instance
WNDPROC mWndProc; // user-installable window proc
RECT mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
@@ -183,6 +225,14 @@ protected:
F32 mNativeAspectRatio;
HCURSOR mCursor[ UI_CURSOR_COUNT ]; // Array of all mouse cursors
+ LLCoordWindow mCursorPosition; // mouse cursor position, should only be mutated on main thread
+ LLMutex mRawMouseMutex;
+ RAWINPUTDEVICE mRawMouse;
+ LLCoordWindow mLastCursorPosition; // mouse cursor position from previous frame
+ LLCoordCommon mRawMouseDelta; // raw mouse delta according to window thread
+ LLCoordCommon mMouseFrameDelta; // how much the mouse moved between the last two calls to gatherInput
+
+ MASK mMouseMask;
static BOOL sIsClassRegistered; // has the window class been registered?
@@ -193,7 +243,6 @@ protected:
BOOL mCustomGammaSet;
LPWSTR mIconResource;
- BOOL mMousePositionModified;
BOOL mInputProcessingPaused;
// The following variables are for Language Text Input control.
@@ -221,7 +270,14 @@ protected:
BOOL mMouseVanish;
+ LLWindowWin32Thread* mWindowThread = nullptr;
+ LLThreadSafeQueue<std::function<void()>> mFunctionQueue;
+ LLThreadSafeQueue<std::function<void()>> mMouseQueue;
+ void post(const std::function<void()>& func);
+ void postMouseButtonEvent(const std::function<void()>& func);
+
friend class LLWindowManager;
+ friend class LLWindowWin32Thread;
};
class LLSplashScreenWin32 : public LLSplashScreen
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 19508becc3..5da13f5010 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -405,8 +405,8 @@ public:
const T& default_value,
const std::string& comment = "Declared In Code")
{
- mCachedControlPtr = LLControlCache<T>::getInstance(name);
- if (mCachedControlPtr.isNull())
+ mCachedControlPtr = LLControlCache<T>::getInstance(name).get();
+ if (! mCachedControlPtr)
{
mCachedControlPtr = new LLControlCache<T>(group, name, default_value, comment);
}
@@ -415,8 +415,8 @@ public:
LLCachedControl(LLControlGroup& group,
const std::string& name)
{
- mCachedControlPtr = LLControlCache<T>::getInstance(name);
- if (mCachedControlPtr.isNull())
+ mCachedControlPtr = LLControlCache<T>::getInstance(name).get();
+ if (! mCachedControlPtr)
{
mCachedControlPtr = new LLControlCache<T>(group, name);
}
diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index 854ba55731..2acce03d08 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -108,9 +108,6 @@ if (DARWIN)
LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp"
)
- ## turns on C++11 using Cmake
- target_compile_features(media_plugin_cef PRIVATE cxx_range_for)
-
add_custom_command(TARGET media_plugin_cef
POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change "@executable_path/Chromium Embedded Framework"
"@executable_path/../../../../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework"
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 1969c498f0..9b636e5e5d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -47,6 +47,7 @@ include(OpenGL)
include(OpenSSL)
include(PNG)
include(TemplateCheck)
+include(Tracy)
include(UI)
include(UnixInstall)
include(ViewerMiscLibs)
@@ -92,6 +93,7 @@ include_directories(
${LIBS_PREBUILT_DIR}/include/collada/1.4
${LLAPPEARANCE_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
+ ${TRACY_INCLUDE_DIR}
)
include_directories(SYSTEM
@@ -587,7 +589,6 @@ set(viewer_SOURCE_FILES
llsyntaxid.cpp
llsyswellitem.cpp
llsyswellwindow.cpp
- lltelemetry.cpp
llteleporthistory.cpp
llteleporthistorystorage.cpp
lltextureatlas.cpp
@@ -2065,6 +2066,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLPHYSICS_LIBRARIES}
${LLPHYSICSEXTENSIONS_LIBRARIES}
${LLAPPEARANCE_LIBRARIES}
+ ${TRACY_LIBRARY}
)
if (USE_BUGSPLAT)
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index 4e186292f7..7514913d13 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -217,6 +217,14 @@
<string>NoInventoryLibrary</string>
</map>
+ <key>noninteractive</key>
+ <map>
+ <key>desc</key>
+ <string>Run in semi-headless mode where only login and logout need to work.</string>
+ <key>map-to</key>
+ <string>NonInteractive</string>
+ </map>
+
<key>nonotifications</key>
<map>
<key>desc</key>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index eeb7e6f0aa..144323bb11 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -812,17 +812,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>FramePerSecondLimit</key>
- <map>
- <key>Comment</key>
- <string>Controls upper limit of frames per second</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>120</integer>
- </map>
<key>BackgroundYieldTime</key>
<map>
<key>Comment</key>
@@ -3365,10 +3354,10 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>DisableVerticalSync</key>
+ <key>RenderVSyncEnable</key>
<map>
<key>Comment</key>
- <string>Update frames as fast as possible (FALSE = update frames between display scans)</string>
+ <string>Update frames between display scans (FALSE = Update frames as fast as possible).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -7041,6 +7030,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>NonInteractive</key>
+ <map>
+ <key>Comment</key>
+ <string>Run in a semi-headless mode where only logging in and logging out needs to work.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>NonvisibleObjectsInMemoryTime</key>
<map>
<key>Comment</key>
@@ -9840,7 +9840,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>RenderGlow</key>
<map>
@@ -14131,18 +14131,7 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>RenderSynchronousOcclusion</key>
- <map>
- <key>Comment</key>
- <string>Don't let occlusion queries get more than one frame behind (block until they complete).</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>RenderDelayVBUpdate</key>
+ <key>RenderDelayVBUpdate</key>
<map>
<key>Comment</key>
<string>Delay vertex buffer updates until just before rendering</string>
@@ -16683,6 +16672,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>UpdateAppWindowTitleBar</key>
+ <map>
+ <key>Comment</key>
+ <string>Updates the application window title bar with brief information about user/location</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index dc484317e9..d3a05c34c0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -86,6 +86,14 @@ float getAmbientClamp();
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
{
+ // SL-14895 inverted attenuation work-around
+ // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
+ // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
+ // to recover the `adjusted_radius` value previously being sent as la.
+ float falloff_factor = (12.0 * fa) - 9.0;
+ float inverted_la = falloff_factor / la;
+ // Yes, it makes me want to cry as well. DJH
+
vec3 col = vec3(0);
//get light vector
@@ -95,7 +103,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
float dist = length(lv);
float da = 1.0;
- /*if (dist > la)
+ /*if (dist > inverted_la)
{
return col;
}
@@ -113,9 +121,9 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
return col;
}*/
- if (dist > 0.0 && la > 0.0)
+ if (dist > 0.0 && inverted_la > 0.0)
{
- dist /= la;
+ dist /= inverted_la;
//normalize light vector
lv = normalize(lv);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index e1f7031af6..02d83925ea 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -91,6 +91,14 @@ float getAmbientClamp();
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
{
+ // SL-14895 inverted attenuation work-around
+ // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
+ // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
+ // to recover the `adjusted_radius` value previously being sent as la.
+ float falloff_factor = (12.0 * fa) - 9.0;
+ float inverted_la = falloff_factor / la;
+ // Yes, it makes me want to cry as well. DJH
+
vec3 col = vec3(0);
//get light vector
@@ -100,9 +108,9 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
float dist = length(lv);
float da = 1.0;
- dist /= la;
+ dist /= inverted_la;
- if (dist > 0.0 && la > 0.0)
+ if (dist > 0.0 && inverted_la > 0.0)
{
//normalize light vector
lv = normalize(lv);
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 389448654a..b35eef20f7 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1481,7 +1481,7 @@ void LLAgent::resetControlFlags()
//-----------------------------------------------------------------------------
void LLAgent::setAFK()
{
- if (!gAgent.getRegion())
+ if (gNonInteractive || !gAgent.getRegion())
{
// Don't set AFK if we're not talking to a region yet.
return;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f668dc754d..52ef2966ce 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -91,7 +91,6 @@
#include "llsdutil_math.h"
#include "lllocationhistory.h"
#include "llfasttimerview.h"
-#include "lltelemetry.h"
#include "llvector4a.h"
#include "llviewermenufile.h"
#include "llvoicechannel.h"
@@ -611,7 +610,7 @@ static void settings_modify()
LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
- LLPipeline::sRenderDeferred = LLPipeline::sRenderTransparentWater && LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
+ LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
@@ -695,8 +694,7 @@ LLAppViewer::LLAppViewer()
mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
mFastTimerLogThread(NULL),
mSettingsLocationList(NULL),
- mIsFirstRun(false),
- mMinMicroSecPerFrame(0.f)
+ mIsFirstRun(false)
{
if(NULL != sInstance)
{
@@ -865,8 +863,6 @@ bool LLAppViewer::init()
LLNotifications::instance();
LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
- writeSystemInfo();
-
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -980,6 +976,9 @@ bool LLAppViewer::init()
// Initialize the repeater service.
LLMainLoopRepeater::instance().start();
+ // Initialize event recorder
+ LLViewerEventRecorder::createInstance();
+
//
// Initialize the window
//
@@ -987,6 +986,9 @@ bool LLAppViewer::init()
initWindow();
LL_INFOS("InitInfo") << "Window is initialized." << LL_ENDL ;
+ // writeSystemInfo can be called after window is initialized (gViewerWindow non-null)
+ writeSystemInfo();
+
// initWindow also initializes the Feature List, so now we can initialize this global.
LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");
@@ -1011,19 +1013,6 @@ bool LLAppViewer::init()
return 0;
}
- // If we don't have the right shader requirements.
- if (!gGLManager.mHasShaderObjects
- || !gGLManager.mHasVertexShader
- || !gGLManager.mHasFragmentShader)
- {
- LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedShaderRequirements");
- OSMessageBox(
- details.getString(),
- LLStringUtil::null,
- OSMB_OK);
- return 0;
- }
-
// Without SSE2 support we will crash almost immediately, warn here.
if (!gSysCPU.hasSSE2())
{
@@ -1114,26 +1103,26 @@ bool LLAppViewer::init()
|| mNumSessions % 20 == 0 //periodically remind user to update driver
)
{
- LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedIntelDriver");
- std::string gpu_name = ll_safe_string((const char *)glGetString(GL_RENDERER));
+ LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedIntelDriver");
+ std::string gpu_name = ll_safe_string((const char *)glGetString(GL_RENDERER));
LL_INFOS("AppInit") << "Notifying user about obsolete intel driver for " << gpu_name << LL_ENDL;
- details.setArg("[VERSION]", driver);
- details.setArg("[GPUNAME]", gpu_name);
- S32 button = OSMessageBox(details.getString(),
- LLStringUtil::null,
- OSMB_YESNO);
- if (OSBTN_YES == button && gViewerWindow)
+ details.setArg("[VERSION]", driver);
+ details.setArg("[GPUNAME]", gpu_name);
+ S32 button = OSMessageBox(details.getString(),
+ LLStringUtil::null,
+ OSMB_YESNO);
+ if (OSBTN_YES == button && gViewerWindow)
+ {
+ std::string url = LLWeb::escapeURL(LLTrans::getString("IntelDriverPage"));
+ if (gViewerWindow->getWindow())
{
- std::string url = LLWeb::escapeURL(LLTrans::getString("IntelDriverPage"));
- if (gViewerWindow->getWindow())
- {
- gViewerWindow->getWindow()->spawnWebBrowser(url, false);
- }
+ gViewerWindow->getWindow()->spawnWebBrowser(url, false);
}
}
}
}
}
+ }
#endif
// Obsolete? mExpectedGLVersion is always zero
@@ -1334,13 +1323,16 @@ bool LLAppViewer::init()
joystick = LLViewerJoystick::getInstance();
joystick->setNeedsReset(true);
/*----------------------------------------------------------------------*/
-
- gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2));
- onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit"));
-
// Load User's bindings
loadKeyBindings();
+ //LLSimpleton creations
+ LLEnvironment::createInstance();
+ LLEnvironment::getInstance()->initSingleton();
+ LLWorld::createInstance();
+ LLSelectMgr::createInstance();
+ LLViewerCamera::createInstance();
+
#if LL_WINDOWS
if (!mSecondInstance)
{
@@ -1373,7 +1365,8 @@ void LLAppViewer::initMaxHeapSize()
}
static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages");
-static LLTrace::BlockTimerStatHandle FTM_SLEEP("Sleep");
+static LLTrace::BlockTimerStatHandle FTM_SLEEP1("Sleep1");
+static LLTrace::BlockTimerStatHandle FTM_SLEEP2("Sleep2");
static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield");
static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache");
@@ -1435,13 +1428,21 @@ bool LLAppViewer::frame()
bool LLAppViewer::doFrame()
{
+ LL_RECORD_BLOCK_TIME(FTM_FRAME);
+
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD newFrame;
- LL_RECORD_BLOCK_TIME(FTM_FRAME);
+ {
+ LL_PROFILE_ZONE_NAMED("df LLTrace");
+ if (LLFloaterReg::instanceVisible("block_timers"))
+ {
LLTrace::BlockTimer::processTimes();
+ }
+
LLTrace::get_frame_recording().nextPeriod();
LLTrace::BlockTimer::logStats();
+ }
LLTrace::get_thread_recorder()->pullFromChildren();
@@ -1449,6 +1450,7 @@ bool LLAppViewer::doFrame()
LL_CLEAR_CALLSTACKS();
{
+ LL_PROFILE_ZONE_NAMED( "df processMiscNativeEvents" )
pingMainloopTimeout("Main:MiscNativeWindowEvents");
if (gViewerWindow)
@@ -1457,7 +1459,10 @@ bool LLAppViewer::doFrame()
gViewerWindow->getWindow()->processMiscNativeEvents();
}
+ {
+ LL_PROFILE_ZONE_NAMED( "df gatherInput" )
pingMainloopTimeout("Main:GatherInput");
+ }
if (gViewerWindow)
{
@@ -1481,13 +1486,21 @@ bool LLAppViewer::doFrame()
}
}
+ {
+ LL_PROFILE_ZONE_NAMED( "df mainloop" )
// canonical per-frame event
mainloop.post(newFrame);
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED( "df suspend" )
// give listeners a chance to run
llcoro::suspend();
+ }
if (!LLApp::isExiting())
{
+ LL_PROFILE_ZONE_NAMED( "df JoystickKeyboard" )
pingMainloopTimeout("Main:JoystickKeyboard");
// Scan keyboard for movement keys. Command keys and typing
@@ -1508,13 +1521,19 @@ bool LLAppViewer::doFrame()
// Update state based on messages, user input, object idle.
{
+ {
+ LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout" )
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
+ }
LL_RECORD_BLOCK_TIME(FTM_IDLE);
idle();
+ {
+ LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" )
resumeMainloopTimeout();
}
+ }
if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))
{
@@ -1534,49 +1553,51 @@ bool LLAppViewer::doFrame()
// *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18
if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
{
+ LL_PROFILE_ZONE_NAMED( "df Display" )
pingMainloopTimeout("Main:Display");
gGLActive = TRUE;
display();
- static U64 last_call = 0;
- if (!gTeleportDisplay)
{
- // Frame/draw throttling, controlled by FramePerSecondLimit
- U64 elapsed_time = LLTimer::getTotalTime() - last_call;
- if (elapsed_time < mMinMicroSecPerFrame)
- {
- LL_RECORD_BLOCK_TIME(FTM_SLEEP);
- // llclamp for when time function gets funky
- U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6);
- micro_sleep(sleep_time, 0);
- }
- }
- last_call = LLTimer::getTotalTime();
-
+ LL_PROFILE_ZONE_NAMED( "df Snapshot" )
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update();
gGLActive = FALSE;
}
}
+ }
+ {
+ LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout" )
pingMainloopTimeout("Main:Sleep");
pauseMainloopTimeout();
+ }
// Sleep and run background threads
{
- LL_RECORD_BLOCK_TIME(FTM_SLEEP);
+ //LL_RECORD_BLOCK_TIME(SLEEP2);
+ LL_PROFILE_ZONE_WARN( "Sleep2" )
// yield some time to the os based on command line option
static LLCachedControl<S32> yield_time(gSavedSettings, "YieldTime", -1);
if(yield_time >= 0)
{
LL_RECORD_BLOCK_TIME(FTM_YIELD);
+ LL_PROFILE_ZONE_NUM( yield_time )
ms_sleep(yield_time);
}
+ if (gNonInteractive)
+ {
+ S32 non_interactive_ms_sleep_time = 100;
+ LLAppViewer::getTextureCache()->pause();
+ LLAppViewer::getImageDecodeThread()->pause();
+ ms_sleep(non_interactive_ms_sleep_time);
+ }
+
// yield cooperatively when not running as foreground window
// and when not quiting (causes trouble at mac's cleanup stage)
if (!LLApp::isExiting()
@@ -1584,8 +1605,8 @@ bool LLAppViewer::doFrame()
|| !gFocusMgr.getAppHasFocus()))
{
// Sleep if we're not rendering, or the window is minimized.
- static LLCachedControl<S32> s_bacground_yeild_time(gSavedSettings, "BackgroundYieldTime", 40);
- S32 milliseconds_to_sleep = llclamp((S32)s_bacground_yeild_time, 0, 1000);
+ static LLCachedControl<S32> s_background_yield_time(gSavedSettings, "BackgroundYieldTime", 40);
+ S32 milliseconds_to_sleep = llclamp((S32)s_background_yield_time, 0, 1000);
// don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads
// of equal priority on Windows
if (milliseconds_to_sleep > 0)
@@ -1636,16 +1657,22 @@ bool LLAppViewer::doFrame()
total_io_pending += io_pending ;
}
+
+ {
+ LL_PROFILE_ZONE_NAMED( "df gMeshRepo" )
gMeshRepo.update() ;
+ }
if(!total_work_pending) //pause texture fetching threads if nothing to process.
{
+ LL_PROFILE_ZONE_NAMED( "df getTextureCache" )
LLAppViewer::getTextureCache()->pause();
LLAppViewer::getImageDecodeThread()->pause();
LLAppViewer::getTextureFetch()->pause();
}
if(!total_io_pending) //pause file threads if nothing to process.
{
+ LL_PROFILE_ZONE_NAMED( "df LLVFSThread" )
LLVFSThread::sLocal->pause();
LLLFSThread::sLocal->pause();
}
@@ -1653,6 +1680,7 @@ bool LLAppViewer::doFrame()
//texture fetching debugger
if(LLTextureFetchDebugger::isEnabled())
{
+ LL_PROFILE_ZONE_NAMED( "df tex_fetch_debugger_instance" )
LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance =
LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger");
if(tex_fetch_debugger_instance)
@@ -1661,8 +1689,10 @@ bool LLAppViewer::doFrame()
}
}
+ {
+ LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" )
resumeMainloopTimeout();
-
+ }
pingMainloopTimeout("Main:End");
}
}
@@ -1688,7 +1718,7 @@ bool LLAppViewer::doFrame()
LL_INFOS() << "Exiting main_loop" << LL_ENDL;
}
- LLPROFILE_UPDATE();
+ LL_PROFILER_FRAME_END
return ! LLApp::isRunning();
}
@@ -2188,6 +2218,10 @@ bool LLAppViewer::cleanup()
LLError::LLCallStacks::cleanup();
+ LLEnvironment::deleteSingleton();
+ LLSelectMgr::deleteSingleton();
+ LLViewerEventRecorder::deleteSingleton();
+
// It's not at first obvious where, in this long sequence, a generic cleanup
// call OUGHT to go. So let's say this: as we migrate cleanup from
// explicit hand-placed calls into the generic mechanism, eventually
@@ -2199,6 +2233,7 @@ bool LLAppViewer::cleanup()
// deleteSingleton() methods.
LLSingletonBase::deleteAll();
+
LL_INFOS() << "Goodbye!" << LL_ENDL;
removeDumpDir();
@@ -2262,14 +2297,14 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)
void LLAppViewer::initLoggingAndGetLastDuration()
{
- //
- // Set up logging defaults for the viewer
- //
- LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "")
+ //
+ // Set up logging defaults for the viewer
+ //
+ LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "")
,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")
);
- LLError::addGenericRecorder(&errorCallback);
- //LLError::setTimeFunction(getRuntime);
+ LLError::addGenericRecorder(&errorCallback);
+ //LLError::setTimeFunction(getRuntime);
if (mSecondInstance)
@@ -2282,66 +2317,66 @@ void LLAppViewer::initLoggingAndGetLastDuration()
}
else
{
- // Remove the last ".old" log file.
- std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- "SecondLife.old");
- LLFile::remove(old_log_file);
-
- // Get name of the log file
- std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- "SecondLife.log");
- /*
- * Before touching any log files, compute the duration of the last run
- * by comparing the ctime of the previous start marker file with the ctime
- * of the last log file.
- */
- std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME);
- llstat start_marker_stat;
- llstat log_file_stat;
- std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below
- int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat);
- int log_stat_result = LLFile::stat(log_file, &log_file_stat);
+ // Remove the last ".old" log file.
+ std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+ "SecondLife.old");
+ LLFile::remove(old_log_file);
+
+ // Get name of the log file
+ std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+ "SecondLife.log");
+ /*
+ * Before touching any log files, compute the duration of the last run
+ * by comparing the ctime of the previous start marker file with the ctime
+ * of the last log file.
+ */
+ std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME);
+ llstat start_marker_stat;
+ llstat log_file_stat;
+ std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below
+ int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat);
+ int log_stat_result = LLFile::stat(log_file, &log_file_stat);
if (0 == start_stat_result && 0 == log_stat_result)
- {
- int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime;
- // only report a last run time if the last viewer was the same version
- // because this stat will be counted against this version
+ {
+ int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime;
+ // only report a last run time if the last viewer was the same version
+ // because this stat will be counted against this version
if (markerIsSameVersion(start_marker_file_name))
- {
- gLastExecDuration = elapsed_seconds;
- }
- else
- {
- duration_log_stream << "start marker from some other version; duration is not reported";
- gLastExecDuration = -1;
- }
- }
- else
- {
- // at least one of the LLFile::stat calls failed, so we can't compute the run time
+ {
+ gLastExecDuration = elapsed_seconds;
+ }
+ else
+ {
+ duration_log_stream << "start marker from some other version; duration is not reported";
+ gLastExecDuration = -1;
+ }
+ }
+ else
+ {
+ // at least one of the LLFile::stat calls failed, so we can't compute the run time
duration_log_stream << "duration stat failure; start: " << start_stat_result << " log: " << log_stat_result;
- gLastExecDuration = -1; // unknown
- }
- std::string duration_log_msg(duration_log_stream.str());
+ gLastExecDuration = -1; // unknown
+ }
+ std::string duration_log_msg(duration_log_stream.str());
- // Create a new start marker file for comparison with log file time for the next run
+ // Create a new start marker file for comparison with log file time for the next run
LLAPRFile start_marker_file;
- start_marker_file.open(start_marker_file_name, LL_APR_WB);
- if (start_marker_file.getFileHandle())
- {
- recordMarkerVersion(start_marker_file);
- start_marker_file.close();
- }
+ start_marker_file.open(start_marker_file_name, LL_APR_WB);
+ if (start_marker_file.getFileHandle())
+ {
+ recordMarkerVersion(start_marker_file);
+ start_marker_file.close();
+ }
- // Rename current log file to ".old"
- LLFile::rename(log_file, old_log_file);
+ // Rename current log file to ".old"
+ LLFile::rename(log_file, old_log_file);
- // Set the log file to SecondLife.log
- LLError::logToFile(log_file);
- if (!duration_log_msg.empty())
- {
- LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
- }
+ // Set the log file to SecondLife.log
+ LLError::logToFile(log_file);
+ if (!duration_log_msg.empty())
+ {
+ LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
+ }
}
}
@@ -2370,7 +2405,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name()
<< " - from location " << location_key << LL_ENDL;
- LLControlGroup* settings_group = LLControlGroup::getInstance(file.name);
+ auto settings_group = LLControlGroup::getInstance(file.name);
if(!settings_group)
{
LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL;
@@ -2465,6 +2500,38 @@ namespace
}
} // anonymous namespace
+// Set a named control temporarily for this session, as when set via the command line --set option.
+// Name can be specified as "<control_group>.<control_name>", with default group being Global.
+bool tempSetControl(const std::string& name, const std::string& value)
+{
+ std::string name_part;
+ std::string group_part;
+ LLControlVariable* control = NULL;
+
+ // Name can be further split into ControlGroup.Name, with the default control group being Global
+ size_t pos = name.find('.');
+ if (pos != std::string::npos)
+ {
+ group_part = name.substr(0, pos);
+ name_part = name.substr(pos+1);
+ LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL;
+ auto g = LLControlGroup::getInstance(group_part);
+ if (g) control = g->getControl(name_part);
+ }
+ else
+ {
+ LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL;
+ control = gSavedSettings.getControl(name);
+ }
+
+ if (control)
+ {
+ control->setValue(value, false);
+ return true;
+ }
+ return false;
+}
+
bool LLAppViewer::initConfiguration()
{
//Load settings files list
@@ -2515,12 +2582,7 @@ bool LLAppViewer::initConfiguration()
#ifndef LL_RELEASE_FOR_DOWNLOAD
// provide developer build only overrides for these control variables that are not
// persisted to settings.xml
- LLControlVariable* c = gSavedSettings.getControl("ShowConsoleWindow");
- if (c)
- {
- c->setValue(true, false);
- }
- c = gSavedSettings.getControl("AllowMultipleViewers");
+ LLControlVariable* c = gSavedSettings.getControl("AllowMultipleViewers");
if (c)
{
c->setValue(true, false);
@@ -2626,9 +2688,10 @@ bool LLAppViewer::initConfiguration()
disableCrashlogger();
}
+ gNonInteractive = gSavedSettings.getBOOL("NonInteractive");
// Handle initialization from settings.
// Start up the debugging console before handling other options.
- if (gSavedSettings.getBOOL("ShowConsoleWindow"))
+ if (gSavedSettings.getBOOL("ShowConsoleWindow") && !gNonInteractive)
{
initConsole();
}
@@ -2661,31 +2724,7 @@ bool LLAppViewer::initConfiguration()
{
const std::string& name = *itr;
const std::string& value = *(++itr);
- std::string name_part;
- std::string group_part;
- LLControlVariable* control = NULL;
-
- // Name can be further split into ControlGroup.Name, with the default control group being Global
- size_t pos = name.find('.');
- if (pos != std::string::npos)
- {
- group_part = name.substr(0, pos);
- name_part = name.substr(pos+1);
- LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL;
- LLControlGroup* g = LLControlGroup::getInstance(group_part);
- if (g) control = g->getControl(name_part);
- }
- else
- {
- LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL;
- control = gSavedSettings.getControl(name);
- }
-
- if (control)
- {
- control->setValue(value, false);
- }
- else
+ if (!tempSetControl(name,value))
{
LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL;
}
@@ -2773,6 +2812,19 @@ bool LLAppViewer::initConfiguration()
}
}
+ if (gNonInteractive)
+ {
+ tempSetControl("AllowMultipleViewers", "TRUE");
+ tempSetControl("SLURLPassToOtherInstance", "FALSE");
+ tempSetControl("RenderWater", "FALSE");
+ tempSetControl("FlyingAtExit", "FALSE");
+ tempSetControl("WindowWidth", "1024");
+ tempSetControl("WindowHeight", "200");
+ LLError::setEnabledLogTypesMask(0);
+ llassert_always(!gSavedSettings.getBOOL("SLURLPassToOtherInstance"));
+ }
+
+
// Handle slurl use. NOTE: Don't let SL-55321 reappear.
// This initial-SLURL logic, up through the call to
// sendURLToOtherInstance(), must precede LLSplashScreen::show() --
@@ -3550,11 +3602,14 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
+ if (gViewerWindow)
+ {
std::vector<std::string> resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList();
for (auto res_iter : resolutions)
{
gDebugInfo["DisplayInfo"].append(res_iter);
}
+ }
writeDebugInfo(); // Save out debug_info.log early, in case of crash.
}
@@ -3992,8 +4047,8 @@ void LLAppViewer::removeDumpDir()
//its locking table for us.
if (gDirUtilp->dumpDirExists()) // Check if dump dir was created this run
{
- std::string dump_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
- gDirUtilp->deleteDirAndContents(dump_dir);
+ std::string dump_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+ gDirUtilp->deleteDirAndContents(dump_dir);
}
if (mSecondInstance && !isError())
@@ -4888,6 +4943,7 @@ void LLAppViewer::idle()
LLNotificationsUI::LLToast::updateClass();
LLSmoothInterpolation::updateInterpolants();
LLMortician::updateClass();
+ LLImageGL::updateClass();
LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify()
LLDirPickerThread::clearDead();
F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
@@ -5661,6 +5717,7 @@ void LLAppViewer::disconnectViewer()
LLWorld::getInstance()->destroyClass();
}
LLVOCache::deleteSingleton();
+ LLViewerCamera::deleteSingleton();
// call all self-registered classes
LLDestroyClassList::instance().fireCallbacks();
@@ -5673,19 +5730,6 @@ void LLAppViewer::disconnectViewer()
LLUrlEntryParcel::setDisconnected(gDisconnected);
}
-bool LLAppViewer::onChangeFrameLimit(LLSD const & evt)
-{
- if (evt.asInteger() > 0)
- {
- mMinMicroSecPerFrame = (U64)(1000000.0f / F32(evt.asInteger()));
- }
- else
- {
- mMinMicroSecPerFrame = 0;
- }
- return false;
-}
-
void LLAppViewer::forceErrorLLError()
{
LL_ERRS() << "This is a deliberate llerror" << LL_ENDL;
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 95f6efa29a..37119aeef9 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -261,8 +261,6 @@ private:
void sendLogoutRequest();
void disconnectViewer();
- bool onChangeFrameLimit(LLSD const & evt);
-
// *FIX: the app viewer class should be some sort of singleton, no?
// Perhaps its child class is the singleton and this should be an abstract base.
static LLAppViewer* sInstance;
@@ -318,10 +316,7 @@ private:
// llcorehttp library init/shutdown helper
LLAppCoreHttp mAppCoreHttp;
- bool mIsFirstRun;
- U64 mMinMicroSecPerFrame; // frame throttling
-
-
+ bool mIsFirstRun;
};
// consts from viewer.h
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 5556ec8f76..8b14ed3ccf 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -329,6 +329,11 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
PWSTR pCmdLine,
int nCmdShow)
{
+ // 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");
+
const S32 MAX_HEAPS = 255;
DWORD heap_enable_lfh_error[MAX_HEAPS];
S32 num_heaps = 0;
diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp
index 0460bff1b4..30ac35fff7 100644
--- a/indra/newview/llbrowsernotification.cpp
+++ b/indra/newview/llbrowsernotification.cpp
@@ -43,14 +43,14 @@ LLBrowserNotification::LLBrowserNotification()
bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification)
{
LLUUID media_id = notification->getPayload()["media_id"].asUUID();
- LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id);
+ auto media_instance = LLMediaCtrl::getInstance(media_id);
if (media_instance)
{
media_instance->showNotification(notification);
}
else if (LLViewerMediaFocus::instance().getControlsMediaID() == media_id)
{
- LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(media_id);
+ auto impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(media_id);
if (impl)
{
impl->showNotification(notification);
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 6d20b23e9f..9ee9900eba 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -257,7 +257,6 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
LLAvatarName av_name;
LLAvatarNameCache::get(agent_id, &av_name);
- addChangedMask(LLFriendObserver::ADD, agent_id);
LL_DEBUGS() << "Added buddy " << agent_id
<< ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline")
<< ", TO: " << mBuddyInfo[agent_id]->getRightsGrantedTo()
@@ -493,6 +492,7 @@ void LLAvatarTracker::notifyObservers()
// new masks and ids will be processed later from idle.
return;
}
+ LL_PROFILE_ZONE_SCOPED
mIsNotifyObservers = TRUE;
observer_list_t observers(mObservers);
@@ -678,6 +678,7 @@ void LLAvatarTracker::processChangeUserRights(LLMessageSystem* msg, void**)
void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
{
+ LL_PROFILE_ZONE_SCOPED
S32 count = msg->getNumberOfBlocksFast(_PREHASH_AgentBlock);
BOOL chat_notify = gSavedSettings.getBOOL("ChatOnlineNotification");
@@ -712,8 +713,6 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
// we were tracking someone who went offline
deleteTrackingData();
}
- // *TODO: get actual inventory id
- gInventory.addChangedMask(LLInventoryObserver::CALLING_CARD, LLUUID::null);
}
if(chat_notify)
{
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index fab249f988..606e670805 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -241,7 +241,7 @@ void LLControlAvatar::matchVolumeTransform()
if (skin_info)
{
LL_DEBUGS("BindShape") << getFullname() << " bind shape " << skin_info->mBindShapeMatrix << LL_ENDL;
- bind_rot = LLSkinningUtil::getUnscaledQuaternion(skin_info->mBindShapeMatrix);
+ bind_rot = LLSkinningUtil::getUnscaledQuaternion(LLMatrix4(skin_info->mBindShapeMatrix));
}
#endif
setRotation(bind_rot*obj_rot);
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index cb5f9c8a2c..7d4961c598 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -96,11 +96,9 @@ void LLDoNotDisturbNotificationStorage::resetDirty()
mDirty = false;
}
-static LLTrace::BlockTimerStatHandle FTM_SAVE_DND_NOTIFICATIONS("Save DND Notifications");
-
void LLDoNotDisturbNotificationStorage::saveNotifications()
{
- LL_RECORD_BLOCK_TIME(FTM_SAVE_DND_NOTIFICATIONS);
+ LL_PROFILE_ZONE_SCOPED;
LLNotificationChannelPtr channelPtr = getCommunicationChannel();
const LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 507af56cb0..502ebbd4b1 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -58,8 +58,6 @@ const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;
const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
const F32 OBJECT_DAMPING_TIME_CONSTANT = 0.06f;
-static LLTrace::BlockTimerStatHandle FTM_CULL_REBOUND("Cull Rebound");
-
extern bool gShiftFrame;
@@ -93,7 +91,6 @@ void LLDrawable::incrementVisible()
LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry)
: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE),
- LLTrace::MemTrackable<LLDrawable, 16>("LLDrawable"),
mVObjp(vobj)
{
init(new_entry);
@@ -101,6 +98,8 @@ LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry)
void LLDrawable::init(bool new_entry)
{
+ LL_PROFILE_ZONE_SCOPED
+
// mXform
mParent = NULL;
mRenderType = 0;
@@ -261,19 +260,13 @@ BOOL LLDrawable::isLight() const
}
}
-static LLTrace::BlockTimerStatHandle FTM_CLEANUP_DRAWABLE("Cleanup Drawable");
-static LLTrace::BlockTimerStatHandle FTM_DEREF_DRAWABLE("Deref");
-static LLTrace::BlockTimerStatHandle FTM_DELETE_FACES("Faces");
-
void LLDrawable::cleanupReferences()
{
- LL_RECORD_BLOCK_TIME(FTM_CLEANUP_DRAWABLE);
+ LL_PROFILE_ZONE_SCOPED;
- {
- LL_RECORD_BLOCK_TIME(FTM_DELETE_FACES);
- std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
- mFaces.clear();
- }
+
+ std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
+ mFaces.clear();
gObjectList.removeDrawable(this);
@@ -281,12 +274,9 @@ void LLDrawable::cleanupReferences()
removeFromOctree();
- {
- LL_RECORD_BLOCK_TIME(FTM_DEREF_DRAWABLE);
- // Cleanup references to other objects
- mVObjp = NULL;
- mParent = NULL;
- }
+ // Cleanup references to other objects
+ mVObjp = NULL;
+ mParent = NULL;
}
void LLDrawable::removeFromOctree()
@@ -331,14 +321,12 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep)
return count;
}
-static LLTrace::BlockTimerStatHandle FTM_ALLOCATE_FACE("Allocate Face");
-
LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
{
+ LL_PROFILE_ZONE_SCOPED
LLFace *face;
{
- LL_RECORD_BLOCK_TIME(FTM_ALLOCATE_FACE);
face = new LLFace(this, mVObjp);
}
@@ -363,13 +351,12 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
{
- LLFace *face;
+ LL_PROFILE_ZONE_SCOPED
- {
- LL_RECORD_BLOCK_TIME(FTM_ALLOCATE_FACE);
- face = new LLFace(this, mVObjp);
- }
+ LLFace *face;
+ face = new LLFace(this, mVObjp);
+
face->setTEOffset(mFaces.size());
face->setTexture(texturep);
face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
@@ -387,6 +374,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp)
{
+ LL_PROFILE_ZONE_SCOPED
+
LLFace *face;
face = new LLFace(this, mVObjp);
@@ -408,6 +397,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep,
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp)
{
+ LL_PROFILE_ZONE_SCOPED
+
LLFace *face;
face = new LLFace(this, mVObjp);
@@ -430,6 +421,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep,
void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (newFaces == (S32)mFaces.size())
{
return;
@@ -453,6 +446,8 @@ void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerText
void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2)
{
return;
@@ -476,6 +471,8 @@ void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewer
void LLDrawable::mergeFaces(LLDrawable* src)
{
+ LL_PROFILE_ZONE_SCOPED
+
U32 face_count = mFaces.size() + src->mFaces.size();
mFaces.reserve(face_count);
@@ -509,6 +506,8 @@ void LLDrawable::updateMaterial()
void LLDrawable::makeActive()
{
+ LL_PROFILE_ZONE_SCOPED
+
#if !LL_RELEASE_FOR_DOWNLOAD
if (mVObjp.notNull())
{
@@ -572,6 +571,8 @@ void LLDrawable::makeActive()
void LLDrawable::makeStatic(BOOL warning_enabled)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (isState(ACTIVE) &&
!isState(ACTIVE_CHILD) &&
!mVObjp->isAttachment() &&
@@ -618,6 +619,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
// Returns "distance" between target destination and resulting xfrom
F32 LLDrawable::updateXform(BOOL undamped)
{
+ LL_PROFILE_ZONE_SCOPED
+
BOOL damped = !undamped;
// Position
@@ -769,6 +772,8 @@ void LLDrawable::moveUpdatePipeline(BOOL moved)
void LLDrawable::movePartition()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLSpatialPartition* part = getSpatialPartition();
if (part)
{
@@ -813,6 +818,8 @@ BOOL LLDrawable::updateMoveUndamped()
void LLDrawable::updatePartition()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!getVOVolume())
{
movePartition();
@@ -830,6 +837,8 @@ void LLDrawable::updatePartition()
BOOL LLDrawable::updateMoveDamped()
{
+ LL_PROFILE_ZONE_SCOPED
+
F32 dist_squared = updateXform(FALSE);
mGeneration++;
@@ -853,6 +862,8 @@ BOOL LLDrawable::updateMoveDamped()
void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
{
LL_WARNS() << "Attempted to update distance for non-world camera." << LL_ENDL;
@@ -957,6 +968,8 @@ void LLDrawable::updateTexture()
BOOL LLDrawable::updateGeometry(BOOL priority)
{
+ LL_PROFILE_ZONE_SCOPED
+
llassert(mVObjp.notNull());
BOOL res = mVObjp->updateGeometry(this);
return res;
@@ -1034,6 +1047,8 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const
void LLDrawable::updateSpatialExtents()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (mVObjp)
{
const LLVector4a* exts = getSpatialExtents();
@@ -1164,6 +1179,8 @@ void LLDrawable::setGroup(LLViewerOctreeGroup *groupp)
LLSpatialPartition* LLDrawable::getSpatialPartition()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLSpatialPartition* retval = NULL;
if (!mVObjp ||
@@ -1247,6 +1264,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
LLDrawable(root->getVObj(), true),
LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp)
{
+ LL_PROFILE_ZONE_SCOPED
+
mBridge = this;
mDrawable = root;
root->setSpatialBridge(this);
@@ -1292,12 +1311,11 @@ void LLSpatialBridge::destroyTree()
void LLSpatialBridge::updateSpatialExtents()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0);
- {
- LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND);
- root->rebound();
- }
+ root->rebound();
const LLVector4a* root_bounds = root->getBounds();
LLVector4a offset;
@@ -1455,6 +1473,8 @@ public:
void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results, BOOL for_select)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!gPipeline.hasRenderType(mDrawableType))
{
return;
@@ -1552,6 +1572,8 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (mDrawable == NULL)
{
markDead();
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 14d782d6f2..6002e3e0dd 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -59,14 +59,13 @@ const U32 SILHOUETTE_HIGHLIGHT = 0;
// All data for new renderer goes into this class.
LL_ALIGN_PREFIX(16)
-class LLDrawable
-: public LLViewerOctreeEntryData,
- public LLTrace::MemTrackable<LLDrawable, 16>
+class LLDrawable
+ : public LLViewerOctreeEntryData
{
+ LL_ALIGN_NEW;
public:
LLDrawable(const LLDrawable& rhs)
- : LLTrace::MemTrackable<LLDrawable, 16>("LLDrawable"),
- LLViewerOctreeEntryData(rhs)
+ : LLViewerOctreeEntryData(rhs)
{
*this = rhs;
}
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index d583a692f9..3e4f97e494 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -404,6 +404,7 @@ void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures)
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{
+ LL_PROFILE_ZONE_SCOPED;
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LLDrawInfo* pparams = *i;
@@ -452,6 +453,7 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!params.mCount)
{
return;
@@ -469,7 +471,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
{
if (params.mTextureList[i].notNull())
{
- gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
+ gGL.getTexUnit(i)->bindFast(params.mTextureList[i]);
}
}
}
@@ -477,8 +479,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
{ //not batching textures or batch has only 1 texture -- might need a texture matrix
if (params.mTexture.notNull())
{
- params.mTexture->addTextureStats(params.mVSize);
- gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
+ gGL.getTexUnit(0)->bindFast(params.mTexture);
if (params.mTextureMatrix)
{
tex_setup = true;
@@ -490,24 +491,20 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
}
else
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
}
}
}
- if (params.mVertexBuffer.notNull())
- {
- if (params.mGroup)
- {
- params.mGroup->rebuildMesh();
- }
+ if (params.mGroup)
+ {
+ params.mGroup->rebuildMesh();
+ }
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
-
- params.mVertexBuffer->setBuffer(mask);
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
- }
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+
+ params.mVertexBuffer->setBufferFast(mask);
+ params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
if (tex_setup)
{
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 4ee08e869a..34f9bfe35d 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -53,22 +53,6 @@ BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
static BOOL deferred_render = FALSE;
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETUP("Alpha Setup");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED("Alpha Deferred");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETBUFFER("Alpha SetBuffer");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DRAW("Alpha Draw");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_TEX_BINDS("Alpha Tex Binds");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MATS("Alpha Mat Tex Binds");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GLOW("Alpha Glow Binds");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SHADER_BINDS("Alpha Shader Binds");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS("Alpha Def Binds");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS("Alpha Def Tex Binds");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MESH_REBUILD("Alpha Mesh Rebuild");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_EMISSIVE("Alpha Emissive");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_LIGHT_SETUP("Alpha Light Setup");
-
LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
LLRenderPass(type), current_shader(NULL), target_shader(NULL),
simple_shader(NULL), fullbright_shader(NULL), emissive_shader(NULL),
@@ -86,6 +70,10 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha()
void LLDrawPoolAlpha::prerender()
{
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+
+ // TODO: is this even necessay? These are probably set to never discard
+ LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(1024.f*1024.f);
+ LLViewerFetchedTexture::sWhiteImagep->addTextureStats(1024.f * 1024.f);
}
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
@@ -106,7 +94,7 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
+ LL_PROFILE_ZONE_SCOPED;
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
@@ -161,7 +149,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
+ LL_PROFILE_ZONE_SCOPED;
if (pass == 1 && !LLPipeline::sImpostorRender)
{
@@ -176,13 +164,13 @@ void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
+ LL_PROFILE_ZONE_SCOPED;
render(pass);
}
void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP);
+ LL_PROFILE_ZONE_SCOPED;
simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram :
(LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram;
@@ -233,7 +221,7 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
void LLDrawPoolAlpha::endRenderPass( S32 pass )
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP);
+ LL_PROFILE_ZONE_SCOPED;
LLRenderPass::endRenderPass(pass);
if(gPipeline.canUseWindLightShaders())
@@ -309,7 +297,7 @@ void LLDrawPoolAlpha::render(S32 pass)
gGL.diffuseColor4f(1,0,0,1);
LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f);
- gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ;
+ gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sSmokeImagep);
renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0);
@@ -358,9 +346,8 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
params.mGroup->rebuildMesh();
}
- params.mVertexBuffer->setBuffer(mask);
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ params.mVertexBuffer->setBufferFast(mask);
+ params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
}
}
}
@@ -383,27 +370,23 @@ inline bool IsEmissive(LLDrawInfo& params)
inline void Draw(LLDrawInfo* draw, U32 mask)
{
- draw->mVertexBuffer->setBuffer(mask);
+ draw->mVertexBuffer->setBufferFast(mask);
LLRenderPass::applyModelMatrix(*draw);
- draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
- gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode);
+ draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
}
-bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader)
+bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader* current_shader)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_TEX_BINDS);
-
bool tex_setup = false;
if (deferred_render && use_material && current_shader)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS);
if (draw->mNormalMap)
- {
+ {
draw->mNormalMap->addTextureStats(draw->mVSize);
current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
}
-
+
if (draw->mSpecularMap)
{
draw->mSpecularMap->addTextureStats(draw->mVSize);
@@ -412,18 +395,16 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate
}
else if (current_shader == simple_shader)
{
- LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(draw->mVSize);
- LLViewerFetchedTexture::sWhiteImagep->addTextureStats(draw->mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
}
- if (use_shaders && draw->mTextureList.size() > 1)
+ if (draw->mTextureList.size() > 1)
{
for (U32 i = 0; i < draw->mTextureList.size(); ++i)
{
if (draw->mTextureList[i].notNull())
{
- gGL.getTexUnit(i)->bind(draw->mTextureList[i], TRUE);
+ gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);
}
}
}
@@ -431,16 +412,15 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate
{ //not batching textures or batch has only 1 texture -- might need a texture matrix
if (draw->mTexture.notNull())
{
- draw->mTexture->addTextureStats(draw->mVSize);
- if (use_shaders && use_material)
+ if (use_material)
{
current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
}
else
{
- gGL.getTexUnit(0)->bind(draw->mTexture, TRUE) ;
+ gGL.getTexUnit(0)->bindFast(draw->mTexture);
}
-
+
if (draw->mTextureMatrix)
{
tex_setup = true;
@@ -452,7 +432,7 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate
}
else
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
}
}
@@ -470,37 +450,15 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)
}
}
-void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples)
-{
- gPipeline.enableLightsDynamic();
- simple_shader->bind();
- simple_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
- simple_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
- simple_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
- simple_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
- simple_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 0.0f);
- bool use_shaders = gPipeline.canUseVertexShaders();
- for (LLDrawInfo* draw : simples)
- {
- bool tex_setup = TexSetup(draw, use_shaders, false, simple_shader);
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
- gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
-
- Draw(draw, mask);
- RestoreTexSetup(tex_setup);
- }
- simple_shader->unbind();
-}
-
void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights)
{
gPipeline.enableLightsFullbright();
fullbright_shader->bind();
fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f);
- bool use_shaders = gPipeline.canUseVertexShaders();
+
for (LLDrawInfo* draw : fullbrights)
{
- bool tex_setup = TexSetup(draw, use_shaders, false, fullbright_shader);
+ bool tex_setup = TexSetup(draw, false, fullbright_shader);
LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
@@ -511,65 +469,10 @@ void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& full
fullbright_shader->unbind();
}
-void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector<LLDrawInfo*>& materials)
-{
- LLGLSLShader::bindNoShader();
- current_shader = NULL;
-
- gPipeline.enableLightsDynamic();
- bool use_shaders = gPipeline.canUseVertexShaders();
- for (LLDrawInfo* draw : materials)
- {
- U32 mask = draw->mShaderMask;
-
- llassert(mask < LLMaterial::SHADER_COUNT);
- target_shader = (LLPipeline::sUnderWaterRender) ? &(gDeferredMaterialWaterProgram[mask]) : &(gDeferredMaterialProgram[mask]);
-
- if (current_shader != target_shader)
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS);
- if (current_shader)
- {
- gPipeline.unbindDeferredShader(*current_shader);
- }
- gPipeline.bindDeferredShader(*target_shader);
- current_shader = target_shader;
- }
-
- bool tex_setup = TexSetup(draw, use_shaders, true, current_shader);
-
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, draw->mSpecColor.mV[0], draw->mSpecColor.mV[1], draw->mSpecColor.mV[2], draw->mSpecColor.mV[3]);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, draw->mEnvIntensity);
- current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, draw->mFullbright ? 1.f : 0.f);
-
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS);
- if (draw->mNormalMap)
- {
- draw->mNormalMap->addTextureStats(draw->mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
- }
-
- if (draw->mSpecularMap)
- {
- draw->mSpecularMap->addTextureStats(draw->mVSize);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
- }
- }
-
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
- gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
-
- Draw(draw, mask);
- RestoreTexSetup(tex_setup);
- }
-}
-
void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)
{
- draw->mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
- draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
- gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode);
+ draw->mVertexBuffer->setBufferFast((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
+ draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
}
void LLDrawPoolAlpha::drawEmissiveInline(U32 mask, LLDrawInfo* draw)
@@ -599,10 +502,10 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi
// install glow-accumulating blend mode
// don't touch color, add to alpha (glow)
gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);
- bool use_shaders = gPipeline.canUseVertexShaders();
+
for (LLDrawInfo* draw : emissives)
{
- bool tex_setup = TexSetup(draw, use_shaders, false, emissive_shader);
+ bool tex_setup = TexSetup(draw, false, emissive_shader);
drawEmissive(mask, draw);
RestoreTexSetup(tex_setup);
}
@@ -615,15 +518,15 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi
void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED;
BOOL batch_fullbrights = gSavedSettings.getBOOL("RenderAlphaBatchFullbrights");
BOOL batch_emissives = gSavedSettings.getBOOL("RenderAlphaBatchEmissives");
BOOL initialized_lighting = FALSE;
BOOL light_enabled = TRUE;
- BOOL use_shaders = gPipeline.canUseVertexShaders();
-
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
+ LL_PROFILE_ZONE_NAMED("renderAlpha - group");
LLSpatialGroup* group = *i;
llassert(group);
llassert(group->getSpatialPartition());
@@ -631,17 +534,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
- std::vector<LLDrawInfo*> emissives;
- std::vector<LLDrawInfo*> fullbrights;
+ static std::vector<LLDrawInfo*> emissives;
+ static std::vector<LLDrawInfo*> fullbrights;
+ emissives.resize(0);
+ fullbrights.resize(0);
bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
|| group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
bool draw_glow_for_this_partition = mShaderLevel > 0; // no shaders = no glow.
-
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP);
-
bool disable_cull = is_particle_or_hud_particle;
LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
@@ -649,6 +551,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
+ LL_PROFILE_ZONE_NAMED("ra - push batch")
LLDrawInfo& params = **k;
U32 have_mask = params.mVertexBuffer->getTypeMask() & mask;
if (have_mask != mask)
@@ -696,34 +599,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
// Turn off lighting if it hasn't already been so.
if (light_enabled || !initialized_lighting)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP);
-
initialized_lighting = TRUE;
- if (use_shaders)
- {
- target_shader = fullbright_shader;
- }
- else
- {
- gPipeline.enableLightsFullbright();
- }
+ target_shader = fullbright_shader;
+
light_enabled = FALSE;
}
}
// Turn on lighting if it isn't already.
else if (!light_enabled || !initialized_lighting)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP);
-
initialized_lighting = TRUE;
- if (use_shaders)
- {
- target_shader = simple_shader;
- }
- else
- {
- gPipeline.enableLightsDynamic();
- }
+ target_shader = simple_shader;
light_enabled = TRUE;
}
@@ -741,7 +627,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
if (current_shader != target_shader)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS);
gPipeline.bindDeferredShader(*target_shader);
current_shader = target_shader;
}
@@ -755,25 +640,19 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
target_shader = fullbright_shader;
}
- if(use_shaders && (current_shader != target_shader))
+ if(current_shader != target_shader)
{// If we need shaders, and we're not ALREADY using the proper shader, then bind it
// (this way we won't rebind shaders unnecessarily).
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SHADER_BINDS);
current_shader = target_shader;
current_shader->bind();
}
- else if (!use_shaders && current_shader != NULL)
- {
- LLGLSLShader::bindNoShader();
- current_shader = NULL;
- }
LLVector4 spec_color(1, 1, 1, 1);
F32 env_intensity = 0.0f;
F32 brightness = 1.0f;
// We have a material. Supply the appropriate data here.
- if (use_shaders && mat && deferred_render)
+ if (mat && deferred_render)
{
spec_color = params.mSpecColor;
env_intensity = params.mEnvIntensity;
@@ -792,20 +671,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
params.mGroup->rebuildMesh();
}
- bool tex_setup = TexSetup(&params, use_shaders, use_shaders && (mat != nullptr), current_shader);
+ bool tex_setup = TexSetup(&params, (mat != nullptr), current_shader);
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH);
-
LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
- params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
+ params.mVertexBuffer->setBufferFast(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DRAW);
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
}
}
@@ -814,8 +689,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
draw_glow_for_this_partition &&
params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_EMISSIVE);
-
if (batch_emissives)
{
emissives.push_back(&params);
@@ -835,19 +708,29 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
}
}
+
+ bool rebind = false;
if (batch_fullbrights)
{
- light_enabled = false;
- renderFullbrights(mask, fullbrights);
+ if (!fullbrights.empty())
+ {
+ light_enabled = false;
+ renderFullbrights(mask, fullbrights);
+ rebind = true;
+ }
}
if (batch_emissives)
{
- light_enabled = true;
- renderEmissives(mask, emissives);
+ if (!emissives.empty())
+ {
+ light_enabled = true;
+ renderEmissives(mask, emissives);
+ rebind = true;
+ }
}
- if (current_shader)
+ if (current_shader && rebind)
{
current_shader->bind();
}
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index a069f805e8..a50b1d929e 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -75,15 +75,13 @@ private:
LLGLSLShader* fullbright_shader;
LLGLSLShader* emissive_shader;
- void renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples);
void renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights);
- void renderMaterials(U32 mask, std::vector<LLDrawInfo*>& fullbrights);
void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);
void drawEmissive(U32 mask, LLDrawInfo* draw);
void drawEmissiveInline(U32 mask, LLDrawInfo* draw);
- bool TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader);
+ bool TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader* current_shader);
void RestoreTexSetup(bool tex_setup);
// our 'normal' alpha blend function for this pass
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 687b13d2c8..5b51e9db24 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -103,8 +103,6 @@ S32 normal_channel = -1;
S32 specular_channel = -1;
S32 cube_channel = -1;
-static LLTrace::BlockTimerStatHandle FTM_SHADOW_AVATAR("Avatar Shadow");
-
LLDrawPoolAvatar::LLDrawPoolAvatar(U32 type) :
LLFacePool(type)
{
@@ -121,6 +119,8 @@ LLDrawPoolAvatar::~LLDrawPoolAvatar()
// virtual
BOOL LLDrawPoolAvatar::isDead()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!LLFacePool::isDead())
{
return FALSE;
@@ -138,11 +138,15 @@ BOOL LLDrawPoolAvatar::isDead()
S32 LLDrawPoolAvatar::getShaderLevel() const
{
+ LL_PROFILE_ZONE_SCOPED
+
return (S32) LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
}
void LLDrawPoolAvatar::prerender()
{
+ LL_PROFILE_ZONE_SCOPED
+
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
sShaderLevel = mShaderLevel;
@@ -163,12 +167,15 @@ void LLDrawPoolAvatar::prerender()
{
LLVOAvatar* avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get();
updateRiggedVertexBuffers(avatarp);
+ updateSkinInfoMatrixPalettes(avatarp);
}
}
}
LLMatrix4& LLDrawPoolAvatar::getModelView()
{
+ LL_PROFILE_ZONE_SCOPED
+
static LLMatrix4 ret;
ret.initRows(LLVector4(gGLModelView+0),
@@ -187,7 +194,7 @@ LLMatrix4& LLDrawPoolAvatar::getModelView()
void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS);
+ LL_PROFILE_ZONE_SCOPED;
sSkipTransparent = TRUE;
is_deferred_render = true;
@@ -222,7 +229,7 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
void LLDrawPoolAvatar::endDeferredPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS);
+ LL_PROFILE_ZONE_SCOPED;
sSkipTransparent = FALSE;
is_deferred_render = false;
@@ -257,6 +264,8 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)
void LLDrawPoolAvatar::renderDeferred(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED
+
render(pass);
}
@@ -267,6 +276,8 @@ S32 LLDrawPoolAvatar::getNumPostDeferredPasses()
void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED
+
switch (pass)
{
case 0:
@@ -295,6 +306,8 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
void LLDrawPoolAvatar::beginPostDeferredAlpha()
{
+ LL_PROFILE_ZONE_SCOPED
+
sSkipOpaque = TRUE;
sShaderLevel = mShaderLevel;
sVertexProgram = &gDeferredAvatarAlphaProgram;
@@ -309,6 +322,8 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()
void LLDrawPoolAvatar::beginDeferredRiggedAlpha()
{
+ LL_PROFILE_ZONE_SCOPED
+
sVertexProgram = &gDeferredSkinnedAlphaProgram;
gPipeline.bindDeferredShader(*sVertexProgram);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -317,6 +332,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha()
void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED
+
switch (pass)
{
case 0: pass = 1; break;
@@ -343,6 +360,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)
void LLDrawPoolAvatar::endDeferredRiggedAlpha()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLVertexBuffer::unbind();
gPipeline.unbindDeferredShader(*sVertexProgram);
sDiffuseChannel = 0;
@@ -353,6 +372,8 @@ void LLDrawPoolAvatar::endDeferredRiggedAlpha()
void LLDrawPoolAvatar::endPostDeferredPass(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED
+
switch (pass)
{
case 0:
@@ -381,6 +402,8 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass)
void LLDrawPoolAvatar::endPostDeferredAlpha()
{
+ LL_PROFILE_ZONE_SCOPED
+
// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done
sRenderingSkinned = FALSE;
sSkipOpaque = FALSE;
@@ -392,6 +415,8 @@ void LLDrawPoolAvatar::endPostDeferredAlpha()
void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED
+
static const S32 actual_pass[] =
{ //map post deferred pass numbers to what render() expects
2, //skinned
@@ -427,23 +452,23 @@ S32 LLDrawPoolAvatar::getNumShadowPasses()
void LLDrawPoolAvatar::beginShadowPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR);
+ LL_PROFILE_ZONE_SCOPED;
- if (pass == SHADOW_PASS_AVATAR_OPAQUE)
- {
- sVertexProgram = &gDeferredAvatarShadowProgram;
-
- if ((sShaderLevel > 0)) // for hardware blending
- {
- sRenderingSkinned = TRUE;
- sVertexProgram->bind();
- }
+ if (pass == SHADOW_PASS_AVATAR_OPAQUE)
+ {
+ sVertexProgram = &gDeferredAvatarShadowProgram;
- gGL.diffuseColor4f(1,1,1,1);
- }
+ if ((sShaderLevel > 0)) // for hardware blending
+ {
+ sRenderingSkinned = TRUE;
+ sVertexProgram->bind();
+ }
+
+ gGL.diffuseColor4f(1, 1, 1, 1);
+ }
else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND)
- {
- sVertexProgram = &gDeferredAvatarAlphaShadowProgram;
+ {
+ sVertexProgram = &gDeferredAvatarAlphaShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -451,19 +476,19 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
if (loc != -1)
{
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
+ }
- if ((sShaderLevel > 0)) // for hardware blending
- {
- sRenderingSkinned = TRUE;
- sVertexProgram->bind();
- }
+ if ((sShaderLevel > 0)) // for hardware blending
+ {
+ sRenderingSkinned = TRUE;
+ sVertexProgram->bind();
+ }
- gGL.diffuseColor4f(1,1,1,1);
- }
+ gGL.diffuseColor4f(1, 1, 1, 1);
+ }
else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK)
- {
- sVertexProgram = &gDeferredAvatarAlphaMaskShadowProgram;
+ {
+ sVertexProgram = &gDeferredAvatarAlphaMaskShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -471,19 +496,19 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
if (loc != -1)
{
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
+ }
- if ((sShaderLevel > 0)) // for hardware blending
- {
- sRenderingSkinned = TRUE;
- sVertexProgram->bind();
- }
+ if ((sShaderLevel > 0)) // for hardware blending
+ {
+ sRenderingSkinned = TRUE;
+ sVertexProgram->bind();
+ }
- gGL.diffuseColor4f(1,1,1,1);
- }
+ gGL.diffuseColor4f(1, 1, 1, 1);
+ }
else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND)
- {
- sVertexProgram = &gDeferredAttachmentAlphaShadowProgram;
+ {
+ sVertexProgram = &gDeferredAttachmentAlphaShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -491,62 +516,62 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
if (loc != -1)
{
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
-
- if ((sShaderLevel > 0)) // for hardware blending
- {
- sRenderingSkinned = TRUE;
- sVertexProgram->bind();
- }
+ }
- gGL.diffuseColor4f(1,1,1,1);
- }
+ if ((sShaderLevel > 0)) // for hardware blending
+ {
+ sRenderingSkinned = TRUE;
+ sVertexProgram->bind();
+ }
+
+ gGL.diffuseColor4f(1, 1, 1, 1);
+ }
else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK)
- {
- sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram;
+ {
+ sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
sDiffuseChannel = 0;
if (loc != -1)
{
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
+ }
- if ((sShaderLevel > 0)) // for hardware blending
- {
- sRenderingSkinned = TRUE;
- sVertexProgram->bind();
- }
+ if ((sShaderLevel > 0)) // for hardware blending
+ {
+ sRenderingSkinned = TRUE;
+ sVertexProgram->bind();
+ }
- gGL.diffuseColor4f(1,1,1,1);
- }
- else // SHADOW_PASS_ATTACHMENT_OPAQUE
- {
- sVertexProgram = &gDeferredAttachmentShadowProgram;
- S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ gGL.diffuseColor4f(1, 1, 1, 1);
+ }
+ else // SHADOW_PASS_ATTACHMENT_OPAQUE
+ {
+ sVertexProgram = &gDeferredAttachmentShadowProgram;
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
sDiffuseChannel = 0;
if (loc != -1)
{
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
- sVertexProgram->bind();
- }
+ }
+ sVertexProgram->bind();
+ }
}
void LLDrawPoolAvatar::endShadowPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR);
+ LL_PROFILE_ZONE_SCOPED;
- if (pass == SHADOW_PASS_ATTACHMENT_OPAQUE)
- {
- LLVertexBuffer::unbind();
- }
+ if (pass == SHADOW_PASS_ATTACHMENT_OPAQUE)
+ {
+ LLVertexBuffer::unbind();
+ }
if (sShaderLevel > 0)
- {
- sVertexProgram->unbind();
- }
+ {
+ sVertexProgram->unbind();
+ }
sVertexProgram = NULL;
sRenderingSkinned = FALSE;
LLDrawPoolAvatar::sShadowPass = -1;
@@ -554,55 +579,54 @@ void LLDrawPoolAvatar::endShadowPass(S32 pass)
void LLDrawPoolAvatar::renderShadow(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR);
+ LL_PROFILE_ZONE_SCOPED;
- if (mDrawFace.empty())
- {
- return;
- }
+ if (mDrawFace.empty())
+ {
+ return;
+ }
- const LLFace *facep = mDrawFace[0];
- if (!facep->getDrawable())
- {
- return;
- }
- LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get();
+ const LLFace *facep = mDrawFace[0];
+ if (!facep->getDrawable())
+ {
+ return;
+ }
+ LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get();
+
+ if (avatarp->isDead() || avatarp->isUIAvatar() || avatarp->mDrawable.isNull())
+ {
+ return;
+ }
+ LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
+ BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
+ if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
+ {
+ // No shadows for impostored (including jellydolled) or invisible avs.
+ return;
+ }
- if (avatarp->isDead() || avatarp->isUIAvatar() || avatarp->mDrawable.isNull())
- {
- return;
- }
- LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
- BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
- if (oa == LLVOAvatar::AOA_INVISIBLE ||
- (impostor && oa == LLVOAvatar::AOA_JELLYDOLL))
- {
- // No shadows for jellydolled or invisible avs.
- return;
- }
-
LLDrawPoolAvatar::sShadowPass = pass;
- if (pass == SHADOW_PASS_AVATAR_OPAQUE)
- {
+ if (pass == SHADOW_PASS_AVATAR_OPAQUE)
+ {
LLDrawPoolAvatar::sSkipTransparent = true;
- avatarp->renderSkinned();
+ avatarp->renderSkinned();
LLDrawPoolAvatar::sSkipTransparent = false;
- }
+ }
else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND)
- {
+ {
LLDrawPoolAvatar::sSkipOpaque = true;
- avatarp->renderSkinned();
+ avatarp->renderSkinned();
LLDrawPoolAvatar::sSkipOpaque = false;
- }
+ }
else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK)
- {
+ {
LLDrawPoolAvatar::sSkipOpaque = true;
- avatarp->renderSkinned();
+ avatarp->renderSkinned();
LLDrawPoolAvatar::sSkipOpaque = false;
- }
+ }
else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) // rigged alpha
- {
+ {
LLDrawPoolAvatar::sSkipOpaque = true;
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA);
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);
@@ -613,40 +637,42 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
renderRigged(avatarp, RIGGED_NORMMAP_BLEND);
renderRigged(avatarp, RIGGED_NORMSPEC_BLEND);
LLDrawPoolAvatar::sSkipOpaque = false;
- }
+ }
else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) // rigged alpha mask
- {
+ {
LLDrawPoolAvatar::sSkipOpaque = true;
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK);
renderRigged(avatarp, RIGGED_NORMMAP_MASK);
renderRigged(avatarp, RIGGED_SPECMAP_MASK);
- renderRigged(avatarp, RIGGED_NORMSPEC_MASK);
+ renderRigged(avatarp, RIGGED_NORMSPEC_MASK);
renderRigged(avatarp, RIGGED_GLOW);
LLDrawPoolAvatar::sSkipOpaque = false;
- }
- else // rigged opaque (SHADOW_PASS_ATTACHMENT_OPAQUE
- {
+ }
+ else // rigged opaque (SHADOW_PASS_ATTACHMENT_OPAQUE
+ {
LLDrawPoolAvatar::sSkipTransparent = true;
- renderRigged(avatarp, RIGGED_MATERIAL);
+ renderRigged(avatarp, RIGGED_MATERIAL);
renderRigged(avatarp, RIGGED_SPECMAP);
- renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
- renderRigged(avatarp, RIGGED_NORMMAP);
- renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
- renderRigged(avatarp, RIGGED_NORMSPEC);
- renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE);
- renderRigged(avatarp, RIGGED_SIMPLE);
- renderRigged(avatarp, RIGGED_FULLBRIGHT);
- renderRigged(avatarp, RIGGED_SHINY);
- renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY);
- renderRigged(avatarp, RIGGED_GLOW);
- renderRigged(avatarp, RIGGED_DEFERRED_BUMP);
- renderRigged(avatarp, RIGGED_DEFERRED_SIMPLE);
+ renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
+ renderRigged(avatarp, RIGGED_NORMMAP);
+ renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
+ renderRigged(avatarp, RIGGED_NORMSPEC);
+ renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE);
+ renderRigged(avatarp, RIGGED_SIMPLE);
+ renderRigged(avatarp, RIGGED_FULLBRIGHT);
+ renderRigged(avatarp, RIGGED_SHINY);
+ renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY);
+ renderRigged(avatarp, RIGGED_GLOW);
+ renderRigged(avatarp, RIGGED_DEFERRED_BUMP);
+ renderRigged(avatarp, RIGGED_DEFERRED_SIMPLE);
LLDrawPoolAvatar::sSkipTransparent = false;
- }
+ }
}
S32 LLDrawPoolAvatar::getNumPasses()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (LLPipeline::sImpostorRender)
{
return 8;
@@ -660,6 +686,8 @@ S32 LLDrawPoolAvatar::getNumPasses()
S32 LLDrawPoolAvatar::getNumDeferredPasses()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (LLPipeline::sImpostorRender)
{
return 19;
@@ -673,7 +701,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()
void LLDrawPoolAvatar::render(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS);
+ LL_PROFILE_ZONE_SCOPED;
if (LLPipeline::sImpostorRender)
{
renderAvatars(NULL, pass+2);
@@ -685,7 +713,7 @@ void LLDrawPoolAvatar::render(S32 pass)
void LLDrawPoolAvatar::beginRenderPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS);
+ LL_PROFILE_ZONE_SCOPED;
//reset vertex buffer mappings
LLVertexBuffer::unbind();
@@ -736,7 +764,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
void LLDrawPoolAvatar::endRenderPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS);
+ LL_PROFILE_ZONE_SCOPED;
if (LLPipeline::sImpostorRender)
{
@@ -780,6 +808,8 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
void LLDrawPoolAvatar::beginImpostor()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!LLPipeline::sReflectionRender)
{
LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f);
@@ -798,6 +828,8 @@ void LLDrawPoolAvatar::beginImpostor()
void LLDrawPoolAvatar::endImpostor()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (LLGLSLShader::sNoFixedFunction)
{
gImpostorProgram.unbind();
@@ -807,6 +839,8 @@ void LLDrawPoolAvatar::endImpostor()
void LLDrawPoolAvatar::beginRigid()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (gPipeline.canUseVertexShaders())
{
if (LLPipeline::sUnderWaterRender)
@@ -840,6 +874,8 @@ void LLDrawPoolAvatar::beginRigid()
void LLDrawPoolAvatar::endRigid()
{
+ LL_PROFILE_ZONE_SCOPED
+
sShaderLevel = mShaderLevel;
if (sVertexProgram != NULL)
{
@@ -849,6 +885,8 @@ void LLDrawPoolAvatar::endRigid()
void LLDrawPoolAvatar::beginDeferredImpostor()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!LLPipeline::sReflectionRender)
{
LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f);
@@ -865,6 +903,8 @@ void LLDrawPoolAvatar::beginDeferredImpostor()
void LLDrawPoolAvatar::endDeferredImpostor()
{
+ LL_PROFILE_ZONE_SCOPED
+
sShaderLevel = mShaderLevel;
sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
@@ -876,6 +916,8 @@ void LLDrawPoolAvatar::endDeferredImpostor()
void LLDrawPoolAvatar::beginDeferredRigid()
{
+ LL_PROFILE_ZONE_SCOPED
+
sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->bind();
@@ -892,6 +934,8 @@ void LLDrawPoolAvatar::beginDeferredRigid()
void LLDrawPoolAvatar::endDeferredRigid()
{
+ LL_PROFILE_ZONE_SCOPED
+
sShaderLevel = mShaderLevel;
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->unbind();
@@ -901,6 +945,8 @@ void LLDrawPoolAvatar::endDeferredRigid()
void LLDrawPoolAvatar::beginSkinned()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (sShaderLevel > 0)
{
if (LLPipeline::sUnderWaterRender)
@@ -967,6 +1013,8 @@ void LLDrawPoolAvatar::beginSkinned()
void LLDrawPoolAvatar::endSkinned()
{
+ LL_PROFILE_ZONE_SCOPED
+
// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done
if (sShaderLevel > 0)
{
@@ -991,6 +1039,8 @@ void LLDrawPoolAvatar::endSkinned()
void LLDrawPoolAvatar::beginRiggedSimple()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (sShaderLevel > 0)
{
if (LLPipeline::sUnderWaterRender)
@@ -1031,6 +1081,8 @@ void LLDrawPoolAvatar::beginRiggedSimple()
void LLDrawPoolAvatar::endRiggedSimple()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLVertexBuffer::unbind();
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
@@ -1041,27 +1093,37 @@ void LLDrawPoolAvatar::endRiggedSimple()
void LLDrawPoolAvatar::beginRiggedAlpha()
{
+ LL_PROFILE_ZONE_SCOPED
+
beginRiggedSimple();
}
void LLDrawPoolAvatar::endRiggedAlpha()
{
+ LL_PROFILE_ZONE_SCOPED
+
endRiggedSimple();
}
void LLDrawPoolAvatar::beginRiggedFullbrightAlpha()
{
+ LL_PROFILE_ZONE_SCOPED
+
beginRiggedFullbright();
}
void LLDrawPoolAvatar::endRiggedFullbrightAlpha()
{
+ LL_PROFILE_ZONE_SCOPED
+
endRiggedFullbright();
}
void LLDrawPoolAvatar::beginRiggedGlow()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (sShaderLevel > 0)
{
if (LLPipeline::sUnderWaterRender)
@@ -1108,11 +1170,15 @@ void LLDrawPoolAvatar::beginRiggedGlow()
void LLDrawPoolAvatar::endRiggedGlow()
{
+ LL_PROFILE_ZONE_SCOPED
+
endRiggedFullbright();
}
void LLDrawPoolAvatar::beginRiggedFullbright()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (sShaderLevel > 0)
{
if (LLPipeline::sUnderWaterRender)
@@ -1170,6 +1236,8 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
void LLDrawPoolAvatar::endRiggedFullbright()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLVertexBuffer::unbind();
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
@@ -1180,6 +1248,8 @@ void LLDrawPoolAvatar::endRiggedFullbright()
void LLDrawPoolAvatar::beginRiggedShinySimple()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (sShaderLevel > 0)
{
if (LLPipeline::sUnderWaterRender)
@@ -1220,6 +1290,8 @@ void LLDrawPoolAvatar::beginRiggedShinySimple()
void LLDrawPoolAvatar::endRiggedShinySimple()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLVertexBuffer::unbind();
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
@@ -1231,6 +1303,8 @@ void LLDrawPoolAvatar::endRiggedShinySimple()
void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (sShaderLevel > 0)
{
if (LLPipeline::sUnderWaterRender)
@@ -1296,6 +1370,8 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
void LLDrawPoolAvatar::endRiggedFullbrightShiny()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLVertexBuffer::unbind();
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
@@ -1308,6 +1384,8 @@ void LLDrawPoolAvatar::endRiggedFullbrightShiny()
void LLDrawPoolAvatar::beginDeferredRiggedSimple()
{
+ LL_PROFILE_ZONE_SCOPED
+
sVertexProgram = &gDeferredSkinnedDiffuseProgram;
sDiffuseChannel = 0;
sVertexProgram->bind();
@@ -1323,6 +1401,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedSimple()
void LLDrawPoolAvatar::endDeferredRiggedSimple()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLVertexBuffer::unbind();
sVertexProgram->unbind();
sVertexProgram = NULL;
@@ -1330,6 +1410,8 @@ void LLDrawPoolAvatar::endDeferredRiggedSimple()
void LLDrawPoolAvatar::beginDeferredRiggedBump()
{
+ LL_PROFILE_ZONE_SCOPED
+
sVertexProgram = &gDeferredSkinnedBumpProgram;
sVertexProgram->bind();
if (LLPipeline::sRenderingHUDs)
@@ -1346,6 +1428,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedBump()
void LLDrawPoolAvatar::endDeferredRiggedBump()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLVertexBuffer::unbind();
sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -1357,6 +1441,8 @@ void LLDrawPoolAvatar::endDeferredRiggedBump()
void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (pass == 1 ||
pass == 5 ||
pass == 9 ||
@@ -1387,6 +1473,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (pass == 1 ||
pass == 5 ||
pass == 9 ||
@@ -1407,6 +1495,8 @@ void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)
void LLDrawPoolAvatar::beginDeferredSkinned()
{
+ LL_PROFILE_ZONE_SCOPED
+
sShaderLevel = mShaderLevel;
sVertexProgram = &gDeferredAvatarProgram;
sRenderingSkinned = TRUE;
@@ -1428,6 +1518,8 @@ void LLDrawPoolAvatar::beginDeferredSkinned()
void LLDrawPoolAvatar::endDeferredSkinned()
{
+ LL_PROFILE_ZONE_SCOPED
+
// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done
sRenderingSkinned = FALSE;
sVertexProgram->unbind();
@@ -1439,13 +1531,8 @@ void LLDrawPoolAvatar::endDeferredSkinned()
gGL.getTexUnit(0)->activate();
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_AVATARS("renderAvatars");
-
-
void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_AVATARS);
-
if (pass == -1)
{
for (S32 i = 1; i < getNumPasses(); i++)
@@ -1485,6 +1572,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS);
+
if (!single_avatar && !avatarp->isFullyLoaded() )
{
if (pass==0 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0))
@@ -1582,7 +1671,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);
renderRigged(avatarp, RIGGED_NORMMAP);
renderRigged(avatarp, RIGGED_NORMMAP_MASK);
- renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
+ renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
renderRigged(avatarp, RIGGED_SPECMAP);
renderRigged(avatarp, RIGGED_SPECMAP_MASK);
renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
@@ -1740,6 +1829,8 @@ void LLDrawPoolAvatar::getRiggedGeometry(
LLVolume* volume,
const LLVolumeFace& vol_face)
{
+ LL_PROFILE_ZONE_SCOPED
+
face->setGeomIndex(0);
face->setIndicesIndex(0);
@@ -1794,7 +1885,7 @@ void LLDrawPoolAvatar::getRiggedGeometry(
U16 offset = 0;
- LLMatrix4 mat_vert = skin->mBindShapeMatrix;
+ LLMatrix4 mat_vert = LLMatrix4(skin->mBindShapeMatrix);
glh::matrix4f m((F32*) mat_vert.mMatrix);
m = m.inverse().transpose();
@@ -1836,24 +1927,26 @@ void LLDrawPoolAvatar::getRiggedGeometry(
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLVOAvatar* avatar,
LLFace* face,
- const LLMeshSkinInfo* skin,
+ const LLVOVolume* vobj,
LLVolume* volume,
LLVolumeFace& vol_face)
{
+ LL_PROFILE_ZONE_SCOPED;
+
LLVector4a* weights = vol_face.mWeights;
if (!weights)
{
return;
}
+ if (!vobj || vobj->isNoLOD())
+ {
+ return;
+ }
+
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
- if (drawable->getVOVolume() && drawable->getVOVolume()->isNoLOD())
- {
- return;
- }
-
const U32 max_joints = LLSkinningUtil::getMaxJointCount();
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
@@ -1893,23 +1986,26 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
}
#endif
- // FIXME ugly const cast
- LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
-
- U32 data_mask = face->getRiggedVertexBufferDataMask();
+ U32 data_mask = face->getRiggedVertexBufferDataMask();
+ const LLMeshSkinInfo* skin = nullptr;
- if (!vol_face.mWeightsScrubbed)
- {
- LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin);
- vol_face.mWeightsScrubbed = TRUE;
- }
-
if (buffer.isNull() ||
buffer->getTypeMask() != data_mask ||
buffer->getNumVerts() != vol_face.mNumVertices ||
buffer->getNumIndices() != vol_face.mNumIndices ||
(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
{
+ LL_PROFILE_ZONE_NAMED("Rigged VBO Rebuild");
+ skin = vobj->getSkinInfo();
+ // FIXME ugly const cast
+ LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
+
+ if (!vol_face.mWeightsScrubbed)
+ {
+ LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin);
+ vol_face.mWeightsScrubbed = TRUE;
+ }
+
if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
{
//rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
@@ -1935,18 +2031,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
}
}
- if (buffer.isNull() ||
- buffer->getNumVerts() != vol_face.mNumVertices ||
- buffer->getNumIndices() != vol_face.mNumIndices)
- {
- // Allocation failed
- return;
- }
-
- if (!buffer.isNull() &&
- sShaderLevel <= 0 &&
- face->mLastSkinTime < avatar->getLastSkinTime())
+ if (sShaderLevel <= 0 &&
+ face->mLastSkinTime < avatar->getLastSkinTime() &&
+ !buffer.isNull() &&
+ buffer->getNumVerts() == vol_face.mNumVertices &&
+ buffer->getNumIndices() == vol_face.mNumIndices)
{
+ LL_PROFILE_ZONE_NAMED("Software Skinning");
//perform software vertex skinning for this face
LLStrider<LLVector3> position;
LLStrider<LLVector3> normal;
@@ -1962,54 +2053,12 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLVector4a* pos = (LLVector4a*) position.get();
LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL;
-
- //build matrix palette
- LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
- U32 count = LLSkinningUtil::getMeshJointCount(skin);
- LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);
- LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin);
-
- LLMatrix4a bind_shape_matrix;
- bind_shape_matrix.loadu(skin->mBindShapeMatrix);
-
-#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
- U8* joint_indices_cursor = vol_face.mJointIndices;
- // fast path with joint indices separate from weights
- if (joint_indices_cursor)
- {
- LLMatrix4a src[4];
- for (U32 j = 0; j < buffer->getNumVerts(); ++j)
- {
- LLMatrix4a final_mat;
- //LLMatrix4a final_mat_correct;
-
- F32* jw = just_weights[j].getF32ptr();
-
- LLSkinningUtil::getPerVertexSkinMatrixWithIndices(jw, joint_indices_cursor, mat, final_mat, src);
- joint_indices_cursor += 4;
+ const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, vobj->getMeshID());
+ const LLMatrix4a* mat = &(mpc.mMatrixPalette[0]);
+ const LLMatrix4a& bind_shape_matrix = mpc.mBindShapeMatrix;
- LLVector4a& v = vol_face.mPositions[j];
-
- LLVector4a t;
- LLVector4a dst;
- bind_shape_matrix.affineTransform(v, t);
- final_mat.affineTransform(t, dst);
- pos[j] = dst;
-
- if (norm)
- {
- LLVector4a& n = vol_face.mNormals[j];
- bind_shape_matrix.rotate(n, t);
- final_mat.rotate(t, dst);
- dst.normalize3fast();
- norm[j] = dst;
- }
- }
- }
- // slow path with joint indices calculated from weights
- else
-#endif
+ if (!mpc.mMatrixPalette.empty())
{
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
{
@@ -2038,22 +2087,25 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!avatar->shouldRenderRigged())
{
return;
}
- stop_glerror();
+ LLUUID lastMeshId;
for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
{
+ LL_PROFILE_ZONE_NAMED("Render Rigged Face");
LLFace* face = mRiggedFace[type][i];
S32 offset = face->getIndicesStart();
U32 count = face->getIndicesCount();
U16 start = face->getGeomStart();
- U16 end = start + face->getGeomCount()-1;
+ U16 end = start + face->getGeomCount()-1;
LLDrawable* drawable = face->getDrawable();
if (!drawable)
@@ -2076,19 +2128,6 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
continue;
}
- const LLMeshSkinInfo* skin = vobj->getSkinInfo();
- if (!skin)
- {
- continue;
- }
-
- //stop_glerror();
-
- //const LLVolumeFace& vol_face = volume->getVolumeFace(te);
- //updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
-
- //stop_glerror();
-
U32 data_mask = LLFace::getRiggedDataMask(type);
LLVertexBuffer* buff = face->getVertexBuffer();
@@ -2175,57 +2214,36 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
}
if (buff)
- {
+ {
if (sShaderLevel > 0)
{
- // upload matrix palette to shader
- LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
- U32 count = LLSkinningUtil::getMeshJointCount(skin);
- LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);
-
- stop_glerror();
-
- F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12];
-
- for (U32 i = 0; i < count; ++i)
- {
- F32* m = (F32*) mat[i].mMatrix[0].getF32ptr();
-
- U32 idx = i*12;
-
- mp[idx+0] = m[0];
- mp[idx+1] = m[1];
- mp[idx+2] = m[2];
- mp[idx+3] = m[12];
-
- mp[idx+4] = m[4];
- mp[idx+5] = m[5];
- mp[idx+6] = m[6];
- mp[idx+7] = m[13];
+ auto& meshId = vobj->getMeshID();
+
+ if (lastMeshId != meshId) // <== only upload matrix palette to GL if the skininfo changed
+ {
+ // upload matrix palette to shader
+ const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, meshId);
+ U32 count = mpc.mMatrixPalette.size();
- mp[idx+8] = m[8];
- mp[idx+9] = m[9];
- mp[idx+10] = m[10];
- mp[idx+11] = m[14];
- }
+ if (count == 0)
+ {
+ //skin info not loaded yet, don't render
+ continue;
+ }
- LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
- count,
- FALSE,
- (GLfloat*) mp);
+ LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
+ count,
+ FALSE,
+ (GLfloat*) &(mpc.mGLMp[0]));
+ }
- stop_glerror();
+ lastMeshId = meshId;
}
else
{
data_mask &= ~LLVertexBuffer::MAP_WEIGHT4;
}
- /*if (glow)
- {
- gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
- }*/
-
if (mat)
{
//order is important here LLRender::DIFFUSE_MAP should be last, becouse it change
@@ -2240,13 +2258,25 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
specular = face->getTexture(LLRender::SPECULAR_MAP);
}
- if (specular)
+ if (specular && specular_channel >= 0)
{
- gGL.getTexUnit(specular_channel)->bind(specular);
+ gGL.getTexUnit(specular_channel)->bindFast(specular);
}
- gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP));
- gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP), false, true);
+ if (normal_channel >= 0)
+ {
+ auto* texture = face->getTexture(LLRender::NORMAL_MAP);
+ if (texture)
+ {
+ gGL.getTexUnit(normal_channel)->bindFast(texture);
+ }
+ //else
+ //{
+ // TODO handle missing normal map
+ //}
+ }
+
+ gGL.getTexUnit(sDiffuseChannel)->bindFast(face->getTexture(LLRender::DIFFUSE_MAP));
LLColor4 col = mat->getSpecularLightColor();
@@ -2277,23 +2307,28 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
sVertexProgram->setMinimumAlpha(0.f);
}
- for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
- {
- LLViewerTexture* tex = face->getTexture(i);
- if (tex)
- {
- tex->addTextureStats(avatar->getPixelArea());
- }
- }
+ if (!LLPipeline::sShadowRender && !LLPipeline::sReflectionRender)
+ {
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ LLViewerTexture* tex = face->getTexture(i);
+ if (tex)
+ {
+ tex->addTextureStats(avatar->getPixelArea());
+ }
+ }
+ }
}
else
{
- gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
sVertexProgram->setMinimumAlpha(0.f);
if (normal_channel > -1)
{
LLDrawPoolBump::bindBumpMap(face, normal_channel);
}
+
+ gGL.getTexUnit(sDiffuseChannel)->bindFast(face->getTexture());
+
}
if (face->mTextureMatrix && vobj->mTexAnimMode)
@@ -2307,8 +2342,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
}
- buff->setBuffer(data_mask);
- buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+ buff->setBufferFast(data_mask);
+ buff->drawRangeFast(LLRender::TRIANGLES, start, end, count, offset);
if (tex_index <= 1)
{
@@ -2319,27 +2354,31 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
}
else
{
- buff->setBuffer(data_mask);
- buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+ buff->setBufferFast(data_mask);
+ buff->drawRangeFast(LLRender::TRIANGLES, start, end, count, offset);
}
-
- gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);
}
}
}
void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar)
{
+ LL_PROFILE_ZONE_SCOPED
+
renderRigged(avatar, RIGGED_DEFERRED_SIMPLE);
}
void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)
{
+ LL_PROFILE_ZONE_SCOPED
+
renderRigged(avatar, RIGGED_DEFERRED_BUMP);
}
void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED
+
renderRigged(avatar, pass);
}
@@ -2352,8 +2391,10 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
//update rigged vertex buffers
for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type)
{
+ LL_PROFILE_ZONE_NAMED("Pass");
for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
{
+ LL_PROFILE_ZONE_NAMED("Face");
LLFace* face = mRiggedFace[type][i];
LLDrawable* drawable = face->getDrawable();
if (!drawable)
@@ -2376,43 +2417,120 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
continue;
}
- const LLMeshSkinInfo* skin = vobj->getSkinInfo();
- if (!skin)
- {
- continue;
- }
-
- stop_glerror();
-
LLVolumeFace& vol_face = volume->getVolumeFace(te);
- updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
+ updateRiggedFaceVertexBuffer(avatar, face, vobj, volume, vol_face);
}
}
}
+void LLDrawPoolAvatar::updateSkinInfoMatrixPalettes(LLVOAvatar* avatarp)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ //evict matrix palettes from the cache that haven't been updated in 10 frames
+ for (matrix_palette_cache_t::iterator iter = mMatrixPaletteCache.begin(); iter != mMatrixPaletteCache.end(); )
+ {
+ if (gFrameCount - iter->second.mFrame > 10)
+ {
+ iter = mMatrixPaletteCache.erase(iter);
+ }
+ else
+ {
+ ++iter;
+ }
+ }
+}
+
+const LLDrawPoolAvatar::MatrixPaletteCache& LLDrawPoolAvatar::updateSkinInfoMatrixPalette(LLVOAvatar * avatarp, const LLUUID& meshId)
+{
+ MatrixPaletteCache& entry = mMatrixPaletteCache[meshId];
+
+ if (entry.mFrame != gFrameCount)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+
+ const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(meshId);
+ entry.mFrame = gFrameCount;
+
+ if (skin != nullptr)
+ {
+ entry.mBindShapeMatrix = skin->mBindShapeMatrix;
+
+ //build matrix palette
+ U32 count = LLSkinningUtil::getMeshJointCount(skin);
+ entry.mMatrixPalette.resize(count);
+ LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, avatarp);
+
+ const LLMatrix4a* mat = &(entry.mMatrixPalette[0]);
+
+ entry.mGLMp.resize(count * 12);
+
+ F32* mp = &(entry.mGLMp[0]);
+
+ for (U32 i = 0; i < count; ++i)
+ {
+ F32* m = (F32*)mat[i].mMatrix[0].getF32ptr();
+
+ U32 idx = i * 12;
+
+ mp[idx + 0] = m[0];
+ mp[idx + 1] = m[1];
+ mp[idx + 2] = m[2];
+ mp[idx + 3] = m[12];
+
+ mp[idx + 4] = m[4];
+ mp[idx + 5] = m[5];
+ mp[idx + 6] = m[6];
+ mp[idx + 7] = m[13];
+
+ mp[idx + 8] = m[8];
+ mp[idx + 9] = m[9];
+ mp[idx + 10] = m[10];
+ mp[idx + 11] = m[14];
+ }
+ }
+ else
+ {
+ entry.mMatrixPalette.resize(0);
+ entry.mGLMp.resize(0);
+ }
+ }
+
+ return entry;
+}
+
void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar)
{
+ LL_PROFILE_ZONE_SCOPED
+
renderRigged(avatar, RIGGED_SIMPLE);
}
void LLDrawPoolAvatar::renderRiggedFullbright(LLVOAvatar* avatar)
{
+ LL_PROFILE_ZONE_SCOPED
+
renderRigged(avatar, RIGGED_FULLBRIGHT);
}
void LLDrawPoolAvatar::renderRiggedShinySimple(LLVOAvatar* avatar)
{
+ LL_PROFILE_ZONE_SCOPED
+
renderRigged(avatar, RIGGED_SHINY);
}
void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar)
{
+ LL_PROFILE_ZONE_SCOPED
+
renderRigged(avatar, RIGGED_FULLBRIGHT_SHINY);
}
void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!mRiggedFace[RIGGED_ALPHA].empty())
{
LLGLEnable blend(GL_BLEND);
@@ -2430,6 +2548,8 @@ void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar)
void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty())
{
LLGLEnable blend(GL_BLEND);
@@ -2447,6 +2567,8 @@ void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar)
void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!mRiggedFace[RIGGED_GLOW].empty())
{
LLGLEnable blend(GL_BLEND);
@@ -2474,6 +2596,8 @@ void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar)
//-----------------------------------------------------------------------------
LLViewerTexture *LLDrawPoolAvatar::getDebugTexture()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (mReferences.empty())
{
return NULL;
@@ -2497,6 +2621,8 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
{
+ LL_PROFILE_ZONE_SCOPED
+
llassert (facep->isState(LLFace::RIGGED));
llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);
if (facep->getPool() && facep->getPool() != this)
@@ -2519,6 +2645,8 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep)
{
+ LL_PROFILE_ZONE_SCOPED
+
llassert (facep->isState(LLFace::RIGGED));
llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);
if (facep->getPool() != this)
@@ -2556,7 +2684,7 @@ LLVertexBufferAvatar::LLVertexBufferAvatar()
: LLVertexBuffer(sDataMask,
GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets
{
-
+ LL_PROFILE_ZONE_SCOPED
}
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 92a8538958..800bbc5f62 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -28,14 +28,18 @@
#define LL_LLDRAWPOOLAVATAR_H
#include "lldrawpool.h"
+#include "llmodel.h"
+
+#include <unordered_map>
class LLVOAvatar;
+class LLVOVolume;
class LLGLSLShader;
class LLFace;
-class LLMeshSkinInfo;
class LLVolume;
class LLVolumeFace;
+extern U32 gFrameCount;
class LLDrawPoolAvatar : public LLFacePool
{
@@ -253,11 +257,13 @@ typedef enum
void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
LLFace* facep,
- const LLMeshSkinInfo* skin,
+ const LLVOVolume* vobj,
LLVolume* volume,
LLVolumeFace& vol_face);
void updateRiggedVertexBuffers(LLVOAvatar* avatar);
+ void updateSkinInfoMatrixPalettes(LLVOAvatar* avatarp);
+
void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false);
void renderRiggedSimple(LLVOAvatar* avatar);
void renderRiggedAlpha(LLVOAvatar* avatar);
@@ -277,6 +283,27 @@ typedef enum
std::vector<LLFace*> mRiggedFace[NUM_RIGGED_PASSES];
+ LL_ALIGN_PREFIX(16)
+ class MatrixPaletteCache
+ {
+ public:
+ U32 mFrame;
+ LLMeshSkinInfo::matrix_list_t mMatrixPalette;
+ LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);
+ // Float array ready to be sent to GL
+ std::vector<F32> mGLMp;
+
+ MatrixPaletteCache() :
+ mFrame(gFrameCount-1)
+ {
+ }
+ } LL_ALIGN_POSTFIX(16);
+
+ const MatrixPaletteCache& updateSkinInfoMatrixPalette(LLVOAvatar* avatarp, const LLUUID& meshId);
+
+ typedef std::unordered_map<LLUUID, MatrixPaletteCache> matrix_palette_cache_t;
+ matrix_palette_cache_t mMatrixPaletteCache;
+
/*virtual*/ LLViewerTexture *getDebugTexture();
/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 14069fa6c2..8f3b0c99b4 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -677,6 +677,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel)
//static
BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsize, S32 channel)
{
+ LL_PROFILE_ZONE_SCOPED;
//Note: texture atlas does not support bump texture now.
LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ;
if(!tex)
@@ -693,7 +694,7 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi
break;
case BE_BRIGHTNESS:
case BE_DARKNESS:
- bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );
+ bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );
break;
default:
@@ -709,12 +710,13 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi
{
if (channel == -2)
{
- gGL.getTexUnit(1)->bind(bump);
- gGL.getTexUnit(0)->bind(bump);
+ gGL.getTexUnit(1)->bindFast(bump);
+ gGL.getTexUnit(0)->bindFast(bump);
}
else
{
- gGL.getTexUnit(channel)->bind(bump);
+ // NOTE: do not use bindFast here (see SL-16222)
+ gGL.getTexUnit(channel)->bind(bump);
}
return TRUE;
@@ -1061,6 +1063,7 @@ void LLBumpImageList::updateImages()
// Note: the caller SHOULD NOT keep the pointer that this function returns. It may be updated as more data arrives.
LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code )
{
+ LL_PROFILE_ZONE_SCOPED;
llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) );
LLViewerTexture* bump = NULL;
@@ -1113,11 +1116,10 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
}
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_STANDARD_LOADED("Bump Standard Callback");
-
// static
void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
+ LL_PROFILE_ZONE_SCOPED;
LLUUID* source_asset_id = (LLUUID*)userdata;
LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS );
if( final )
@@ -1137,22 +1139,17 @@ void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTextu
}
}
-static LLTrace::BlockTimerStatHandle FTM_BUMP_GEN_NORMAL("Generate Normal Map");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_CREATE_TEXTURE("Create GL Normal Map");
-
void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
{
if (success && LLPipeline::sRenderDeferred)
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_STANDARD_LOADED);
+ LL_PROFILE_ZONE_SCOPED;
LLPointer<LLImageRaw> nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4);
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_GEN_NORMAL);
generateNormalMapFromAlpha(src, nrm_image);
}
src_vi->setExplicitFormat(GL_RGBA, GL_RGBA);
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_CREATE_TEXTURE);
src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image);
}
}
@@ -1213,28 +1210,18 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr
}
}
-
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_LOADED("Bump Source Loaded");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_ENTRIES_UPDATE("Entries Update");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_MIN_MAX("Min/Max");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_RGB2LUM("RGB to Luminance");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_RESCALE("Rescale");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_GEN_NORMAL("Generate Normal");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_CREATE("Bump Source Create");
-
// static
void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code )
{
if( success )
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_LOADED);
+ LL_PROFILE_ZONE_SCOPED;
bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries );
bump_image_map_t::iterator iter = entries_list.find(source_asset_id);
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_ENTRIES_UPDATE);
if (iter == entries_list.end() ||
iter->second.isNull() ||
iter->second->getWidth() != src->getWidth() ||
@@ -1277,7 +1264,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
case 1:
case 2:
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_MIN_MAX);
if( src_data_size == dst_data_size * src_components )
{
for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
@@ -1303,7 +1289,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
case 3:
case 4:
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_RGB2LUM);
if( src_data_size == dst_data_size * src_components )
{
for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
@@ -1336,7 +1321,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
if( maximum > minimum )
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_RESCALE);
U8 bias_and_scale_lut[256];
F32 twice_one_over_range = 2.f / (maximum - minimum);
S32 i;
@@ -1372,7 +1356,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
if (!LLPipeline::sRenderDeferred)
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_CREATE);
bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
bump->createGLTexture(0, dst_image);
}
@@ -1383,13 +1366,11 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
bump->getGLTexture()->setAllowCompression(false);
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_CREATE);
bump->setExplicitFormat(GL_RGBA8, GL_ALPHA);
bump->createGLTexture(0, dst_image);
}
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_GEN_NORMAL);
gPipeline.mScreen.bindTarget();
LLGLDepthTest depth(GL_FALSE);
@@ -1497,6 +1478,7 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
{
+ LL_PROFILE_ZONE_SCOPED;
applyModelMatrix(params);
bool tex_setup = false;
@@ -1507,7 +1489,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
{
if (params.mTextureList[i].notNull())
{
- gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
+ gGL.getTexUnit(i)->bindFast(params.mTextureList[i]);
}
}
}
@@ -1522,13 +1504,6 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
}
else
{
- if (!LLGLSLShader::sNoFixedFunction)
- {
- gGL.getTexUnit(1)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
- }
-
gGL.getTexUnit(0)->activate();
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
@@ -1545,8 +1520,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
{
if (params.mTexture.notNull())
{
- gGL.getTexUnit(diffuse_channel)->bind(params.mTexture);
- params.mTexture->addTextureStats(params.mVSize);
+ gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture);
}
else
{
@@ -1559,10 +1533,10 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
{
params.mGroup->rebuildMesh();
}
- params.mVertexBuffer->setBuffer(mask);
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
- if (tex_setup)
+ params.mVertexBuffer->setBufferFast(mask);
+ params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+
+ if (tex_setup)
{
if (mShiny)
{
@@ -1570,12 +1544,6 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
}
else
{
- if (!LLGLSLShader::sNoFixedFunction)
- {
- gGL.getTexUnit(1)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- }
gGL.getTexUnit(0)->activate();
gGL.matrixMode(LLRender::MM_TEXTURE);
}
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index 476b1d41b7..bab160c34d 100644
--- a/indra/newview/lldrawpoolbump.h
+++ b/indra/newview/lldrawpoolbump.h
@@ -32,6 +32,8 @@
#include "lltextureentry.h"
#include "lluuid.h"
+#include <unordered_map>
+
class LLImageRaw;
class LLSpatialGroup;
class LLDrawInfo;
@@ -161,7 +163,7 @@ private:
static void onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump );
private:
- typedef std::map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t;
+ typedef std::unordered_map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t;
bump_image_map_t mBrightnessEntries;
bump_image_map_t mDarknessEntries;
};
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 05b0c1f1a9..d2a8757379 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -106,6 +106,7 @@ void LLDrawPoolMaterials::endDeferredPass(S32 pass)
void LLDrawPoolMaterials::renderDeferred(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED;
static const U32 type_list[] =
{
LLRenderPass::PASS_MATERIAL,
@@ -157,7 +158,10 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
mShader->setMinimumAlpha(params.mAlphaMaskCutoff);
mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
- pushBatch(params, mask, TRUE);
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ pushMaterialsBatch(params, mask);
+ }
}
}
@@ -171,49 +175,37 @@ void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex)
mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex);
}
-void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
+void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask)
{
+ LL_PROFILE_ZONE_SCOPED;
applyModelMatrix(params);
bool tex_setup = false;
- if (batch_textures && params.mTextureList.size() > 1)
+ //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (params.mTextureMatrix)
{
- for (U32 i = 0; i < params.mTextureList.size(); ++i)
+ //if (mShiny)
{
- if (params.mTextureList[i].notNull())
- {
- gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
- }
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
}
- }
- else
- { //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (params.mTextureMatrix)
- {
- //if (mShiny)
- {
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- }
- gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
+ gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
- tex_setup = true;
- }
+ tex_setup = true;
+ }
- if (mShaderLevel > 1 && texture)
+ if (mShaderLevel > 1)
+ {
+ if (params.mTexture.notNull())
+ {
+ gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture);
+ }
+ else
{
- if (params.mTexture.notNull())
- {
- gGL.getTexUnit(diffuse_channel)->bind(params.mTexture);
- params.mTexture->addTextureStats(params.mVSize);
- }
- else
- {
- gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE);
}
}
@@ -224,9 +216,9 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,
LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
- params.mVertexBuffer->setBuffer(mask);
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ params.mVertexBuffer->setBufferFast(mask);
+ params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+
if (tex_setup)
{
gGL.getTexUnit(0)->activate();
diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h
index eae1aba87c..6e39821b07 100644
--- a/indra/newview/lldrawpoolmaterials.h
+++ b/indra/newview/lldrawpoolmaterials.h
@@ -69,7 +69,7 @@ public:
void bindSpecularMap(LLViewerTexture* tex);
void bindNormalMap(LLViewerTexture* tex);
- /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
+ /*virtual*/ void pushMaterialsBatch(LLDrawInfo& params, U32 mask);
};
#endif //LL_LLDRAWPOOLMATERIALS_H
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index f211cf6e27..320160d10d 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -57,8 +57,6 @@ void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)
}
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW_PUSH("Glow Push");
-
void LLDrawPoolGlow::renderPostDeferred(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
@@ -73,10 +71,7 @@ void LLDrawPoolGlow::renderPostDeferred(S32 pass)
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
gGL.setColorMask(false, true);
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW_PUSH);
- pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- }
+ pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
gGL.setColorMask(true, false);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -150,13 +145,6 @@ void LLDrawPoolGlow::render(S32 pass)
}
}
-void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
-{
- //gGL.diffuseColor4ubv(params.mGlowColor.mV);
- LLRenderPass::pushBatch(params, mask, texture, batch_textures);
-}
-
-
LLDrawPoolSimple::LLDrawPoolSimple() :
LLRenderPass(POOL_SIMPLE)
{
@@ -199,11 +187,7 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)
}
else
{
- // don't use shaders!
- if (gGLManager.mHasShaderObjects)
- {
- LLGLSLShader::bindNoShader();
- }
+ LLGLSLShader::bindNoShader();
}
}
@@ -301,11 +285,7 @@ void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
}
else
{
- // don't use shaders!
- if (gGLManager.mHasShaderObjects)
- {
- LLGLSLShader::bindNoShader();
- }
+ LLGLSLShader::bindNoShader();
}
}
@@ -324,7 +304,7 @@ void LLDrawPoolAlphaMask::endRenderPass(S32 pass)
void LLDrawPoolAlphaMask::render(S32 pass)
{
LLGLDisable blend(GL_BLEND);
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
+ LL_PROFILE_ZONE_SCOPED;
if (mShaderLevel > 0)
{
@@ -392,11 +372,7 @@ void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
}
else
{
- // don't use shaders!
- if (gGLManager.mHasShaderObjects)
- {
- LLGLSLShader::bindNoShader();
- }
+ LLGLSLShader::bindNoShader();
}
}
@@ -483,6 +459,7 @@ void LLDrawPoolSimple::endDeferredPass(S32 pass)
void LLDrawPoolSimple::renderDeferred(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED;
LLGLDisable blend(GL_BLEND);
LLGLDisable alpha_test(GL_ALPHA_TEST);
@@ -567,11 +544,7 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass)
else
{
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
- // don't use shaders!
- if (gGLManager.mHasShaderObjects)
- {
- LLGLSLShader::bindNoShader();
- }
+ LLGLSLShader::bindNoShader();
}
}
diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h
index 608ad9e1eb..b27cc4babc 100644
--- a/indra/newview/lldrawpoolsimple.h
+++ b/indra/newview/lldrawpoolsimple.h
@@ -187,7 +187,6 @@ public:
/*virtual*/ S32 getNumPasses();
void render(S32 pass = 0);
- void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
};
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index b6f55e800a..b1eefaab81 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -82,13 +82,7 @@ void LLDrawPoolSky::render(S32 pass)
}
else
{
- // don't use shaders!
- if (gGLManager.mHasShaderObjects)
- {
- // Ironically, we must support shader objects to be
- // able to use this call.
- LLGLSLShader::bindNoShader();
- }
+ LLGLSLShader::bindNoShader();
mShader = NULL;
}
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 37dc80e2b7..9cea8f5460 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -343,8 +343,6 @@ void LLDrawPoolTerrain::renderFullShader()
LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
- ((LLSettingsVOWater*)pwater.get())->updateShader(shader);
-
//
// detail texture 1
//
@@ -922,6 +920,7 @@ void LLDrawPoolTerrain::renderOwnership()
void LLDrawPoolTerrain::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures)
{
+ LL_PROFILE_ZONE_SCOPED;
LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ;
if (tex && textures.find(tex) != textures.end())
{
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index 0d5195bdbf..202f648e3f 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -42,7 +42,6 @@
S32 LLDrawPoolTree::sDiffTex = 0;
static LLGLSLShader* shader = NULL;
-static LLTrace::BlockTimerStatHandle FTM_SHADOW_TREE("Tree Shadow");
LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) :
LLFacePool(POOL_TREE),
@@ -84,7 +83,7 @@ void LLDrawPoolTree::beginRenderPass(S32 pass)
void LLDrawPoolTree::render(S32 pass)
{
- LL_RECORD_BLOCK_TIME(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES);
+ LL_PROFILE_ZONE_SCOPED;
if (mDrawFace.empty())
{
@@ -153,6 +152,7 @@ void LLDrawPoolTree::beginDeferredPass(S32 pass)
void LLDrawPoolTree::renderDeferred(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED;
render(pass);
}
@@ -168,7 +168,7 @@ void LLDrawPoolTree::endDeferredPass(S32 pass)
//============================================
void LLDrawPoolTree::beginShadowPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_TREE);
+ LL_PROFILE_ZONE_SCOPED;
glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"),
gSavedSettings.getF32("RenderDeferredTreeShadowBias"));
@@ -187,7 +187,7 @@ void LLDrawPoolTree::renderShadow(S32 pass)
void LLDrawPoolTree::endShadowPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_TREE);
+ LL_PROFILE_ZONE_SCOPED;
glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"),
gSavedSettings.getF32("RenderDeferredSpotShadowBias"));
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index aa426cd785..2f3c52ecd2 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -137,6 +137,14 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass)
void LLDrawPoolWater::renderDeferred(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
+
+ if (!LLPipeline::sRenderTransparentWater)
+ {
+ // Will render opaque water without use of ALM
+ render(pass);
+ return;
+ }
+
deferred_render = TRUE;
shade();
deferred_render = FALSE;
@@ -337,7 +345,13 @@ void LLDrawPoolWater::render(S32 pass)
// for low end hardware
void LLDrawPoolWater::renderOpaqueLegacyWater()
{
- LLVOSky *voskyp = gSky.mVOSkyp;
+ LL_PROFILE_ZONE_SCOPED;
+ LLVOSky *voskyp = gSky.mVOSkyp;
+
+ if (voskyp == NULL)
+ {
+ return;
+ }
LLGLSLShader* shader = NULL;
if (LLGLSLShader::sNoFixedFunction)
@@ -444,6 +458,7 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
void LLDrawPoolWater::renderReflection(LLFace* face)
{
+ LL_PROFILE_ZONE_SCOPED;
LLVOSky *voskyp = gSky.mVOSkyp;
if (!voskyp)
@@ -472,6 +487,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp)
{
+ LL_PROFILE_ZONE_SCOPED;
F32 water_height = LLEnvironment::instance().getWaterHeight();
F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
F32 eyedepth = camera_height - water_height;
@@ -680,7 +696,8 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li
void LLDrawPoolWater::shade()
{
- if (!deferred_render)
+ LL_PROFILE_ZONE_SCOPED;
+ if (!deferred_render)
{
gGL.setColorMask(true, true);
}
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 0c3d8f3098..8c8dc3f3d2 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -182,8 +182,6 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
sky_shader->bindTexture(LLShaderMgr::RAINBOW_MAP, rainbow_tex);
sky_shader->bindTexture(LLShaderMgr::HALO_MAP, halo_tex);
- ((LLSettingsVOSky*)psky.get())->updateShader(sky_shader);
-
F32 moisture_level = (float)psky->getSkyMoistureLevel();
F32 droplet_radius = (float)psky->getSkyDropletRadius();
F32 ice_level = (float)psky->getSkyIceLevel();
@@ -406,8 +404,6 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32
cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
- ((LLSettingsVOSky*)psky.get())->updateShader(cloudshader);
-
/// Render the skydome
renderDome(camPosLocal, camHeightLocal, cloudshader);
@@ -462,8 +458,6 @@ void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeigh
cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
- ((LLSettingsVOSky*)psky.get())->updateShader(cloudshader);
-
/// Render the skydome
renderDome(camPosLocal, camHeightLocal, cloudshader);
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 8b8273d183..31ca2531ba 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -119,8 +119,11 @@ BOOL LLViewerDynamicTexture::render()
void LLViewerDynamicTexture::preRender(BOOL clear_depth)
{
gPipeline.allocatePhysicsBuffer();
- llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth()));
- llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
+ if (!gNonInteractive)
+ {
+ llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth()));
+ llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
+ }
if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI)
{ //using offscreen render target, just use the bottom left corner
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index 4bd74a8425..caedf928c3 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -35,16 +35,8 @@
class LLViewerDynamicTexture : public LLViewerTexture
{
+ LL_ALIGN_NEW
public:
- void* operator new(size_t size)
- {
- return LLTrace::MemTrackable<LLTexture>::aligned_new<16>(size);
- }
-
- void operator delete(void* ptr, size_t size)
- {
- LLTrace::MemTrackable<LLTexture>::aligned_delete<16>(ptr, size);
- }
enum
{
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index cc2b1cc42c..0b914f07ab 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -105,7 +105,6 @@ namespace
//---------------------------------------------------------------------
LLTrace::BlockTimerStatHandle FTM_ENVIRONMENT_UPDATE("Update Environment Tick");
- LLTrace::BlockTimerStatHandle FTM_SHADER_PARAM_UPDATE("Update Shader Parameters");
LLSettingsBase::Seconds DEFAULT_UPDATE_THRESHOLD(10.0);
const LLSettingsBase::Seconds MINIMUM_SPANLENGTH(0.01f);
@@ -825,7 +824,7 @@ std::string env_selection_to_string(LLEnvironment::EnvSelection_t sel)
#undef RTNENUM
}
-
+LLEnvironment* LLSimpleton<LLEnvironment>::sInstance = nullptr;
//-------------------------------------------------------------------------
LLEnvironment::LLEnvironment():
mCloudScrollDelta(),
@@ -879,6 +878,7 @@ void LLEnvironment::cleanupSingleton()
LLEnvironment::~LLEnvironment()
{
+ cleanupSingleton();
}
bool LLEnvironment::canEdit() const
@@ -1471,6 +1471,7 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::getSharedEnvironmentInstance()
void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool forced)
{
+ LL_PROFILE_ZONE_SCOPED;
DayInstance::ptr_t pinstance = getSelectedEnvironmentInstance();
if ((mCurrentEnvironment != pinstance) || forced)
@@ -1488,6 +1489,8 @@ void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool f
{
mCurrentEnvironment = pinstance;
}
+
+ updateSettingsUniforms();
}
}
@@ -1614,6 +1617,8 @@ void LLEnvironment::update(const LLViewerCamera * cam)
stop_glerror();
+ updateSettingsUniforms();
+
// *TODO: potential optimization - this block may only need to be
// executed some of the time. For example for water shaders only.
{
@@ -1648,10 +1653,16 @@ void LLEnvironment::updateCloudScroll()
}
// static
-void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting)
+void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, const LLSettingsBase::ptr_t &psetting)
{
- LL_RECORD_BLOCK_TIME(FTM_SHADER_PARAM_UPDATE);
+ LL_PROFILE_ZONE_SCOPED;
+
+ for (int i = 0; i < LLGLSLShader::SG_COUNT; ++i)
+ {
+ uniforms[i].clear();
+ }
+ LLShaderUniforms* shader = &uniforms[LLGLSLShader::SG_ANY];
//_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL;
LLSettingsBase::parammapping_t params = psetting->getParameterMap();
for (auto &it: params)
@@ -1694,7 +1705,7 @@ void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLS
{
LLVector4 vect4(value);
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL;
- shader->uniform4fv(it.second.getShaderKey(), 1, vect4.mV);
+ shader->uniform4fv(it.second.getShaderKey(), vect4 );
break;
}
@@ -1707,17 +1718,30 @@ void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLS
default:
break;
}
- stop_glerror();
}
//_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL;
- psetting->applySpecial(shader);
+ psetting->applySpecial(uniforms);
+}
+
+void LLEnvironment::updateShaderUniforms(LLGLSLShader* shader)
+{
+ LL_PROFILE_ZONE_SCOPED;
+
+ // apply uniforms that should be applied to all shaders
+ mSkyUniforms[LLGLSLShader::SG_ANY].apply(shader);
+ mWaterUniforms[LLGLSLShader::SG_ANY].apply(shader);
+
+ // apply uniforms specific to the given shader's shader group
+ auto group = shader->mShaderGroup;
+ mSkyUniforms[group].apply(shader);
+ mWaterUniforms[group].apply(shader);
}
-void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader)
+void LLEnvironment::updateSettingsUniforms()
{
- updateGLVariablesForSettings(shader, mCurrentEnvironment->getWater());
- updateGLVariablesForSettings(shader, mCurrentEnvironment->getSky());
+ updateGLVariablesForSettings(mWaterUniforms, mCurrentEnvironment->getWater());
+ updateGLVariablesForSettings(mSkyUniforms, mCurrentEnvironment->getSky());
}
void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envinfo, LLSettingsBase::Seconds transition)
@@ -2634,6 +2658,7 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::DayInstance::clone() const
bool LLEnvironment::DayInstance::applyTimeDelta(const LLSettingsBase::Seconds& delta)
{
+ LL_PROFILE_ZONE_SCOPED;
ptr_t keeper(shared_from_this()); // makes sure that this does not go away while it is being worked on.
bool changed(false);
diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h
index 7cbf2d25bb..0ec06402f8 100644
--- a/indra/newview/llenvironment.h
+++ b/indra/newview/llenvironment.h
@@ -38,20 +38,21 @@
#include "llatmosphere.h"
+#include "llglslshader.h"
+
#include <boost/signals2.hpp>
//-------------------------------------------------------------------------
class LLViewerCamera;
-class LLGLSLShader;
class LLParcel;
//-------------------------------------------------------------------------
-class LLEnvironment : public LLSingleton<LLEnvironment>
+class LLEnvironment : public LLSimpleton<LLEnvironment>
{
- LLSINGLETON_C11(LLEnvironment);
LOG_CLASS(LLEnvironment);
-
public:
+ LLEnvironment();
+
static const F64Seconds TRANSITION_INSTANT;
static const F64Seconds TRANSITION_FAST;
static const F64Seconds TRANSITION_DEFAULT;
@@ -114,7 +115,7 @@ public:
typedef std::array<F32, 4> altitude_list_t;
typedef std::vector<F32> altitudes_vect_t;
- virtual ~LLEnvironment();
+ ~LLEnvironment();
bool canEdit() const;
bool isExtendedEnvironmentEnabled() const;
@@ -131,9 +132,14 @@ public:
void update(const LLViewerCamera * cam);
- static void updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting);
+ static void updateGLVariablesForSettings(LLShaderUniforms* uniforms, const LLSettingsBase::ptr_t &psetting);
+
+ // apply current sky settings to given shader
void updateShaderUniforms(LLGLSLShader *shader);
+ // prepare settings to be applied to shaders (call whenever settings are updated)
+ void updateSettingsUniforms();
+
void setSelectedEnvironment(EnvSelection_t env, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, bool forced = false);
EnvSelection_t getSelectedEnvironment() const { return mSelectedEnvironment; }
@@ -234,6 +240,11 @@ public:
void handleEnvironmentPush(LLSD &message);
+ //cached uniform values from LLSD values
+ LLShaderUniforms mWaterUniforms[LLGLSLShader::SG_COUNT];
+ LLShaderUniforms mSkyUniforms[LLGLSLShader::SG_COUNT];
+ // =======================================================================================
+
class DayInstance: public std::enable_shared_from_this<DayInstance>
{
public:
@@ -288,6 +299,7 @@ public:
LLSettingsDay::ptr_t mDayCycle;
LLSettingsSky::ptr_t mSky;
LLSettingsWater::ptr_t mWater;
+
S32 mSkyTrack;
bool mInitialized;
@@ -325,9 +337,10 @@ public:
DayInstance::ptr_t getSelectedEnvironmentInstance();
DayInstance::ptr_t getSharedEnvironmentInstance();
+ void initSingleton();
+
protected:
- virtual void initSingleton() override;
- virtual void cleanupSingleton() override;
+ void cleanupSingleton();
private:
diff --git a/indra/newview/llexperiencelog.cpp b/indra/newview/llexperiencelog.cpp
index ee5d561927..c441fbc09f 100644
--- a/indra/newview/llexperiencelog.cpp
+++ b/indra/newview/llexperiencelog.cpp
@@ -149,10 +149,6 @@ std::string LLExperienceLog::getPermissionString( const LLSD& message, const std
{
buf.str(entry);
}
- else
- {
- buf.str();
- }
}
if(buf.str().empty())
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 4a802ad9aa..88b958d24a 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -127,6 +127,7 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal,
void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
{
+ LL_PROFILE_ZONE_SCOPED;
mLastUpdateTime = gFrameTimeSeconds;
mLastMoveTime = 0.f;
mLastSkinTime = gFrameTimeSeconds;
@@ -241,6 +242,8 @@ void LLFace::setPool(LLFacePool* pool)
void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!new_pool)
{
LL_ERRS() << "Setting pool to null!" << LL_ENDL;
@@ -320,6 +323,8 @@ void LLFace::setSpecularMap(LLViewerTexture* tex)
void LLFace::dirtyTexture()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLDrawable* drawablep = getDrawable();
if (mVObjp.notNull() && mVObjp->getVolume())
@@ -535,6 +540,8 @@ void LLFace::updateCenterAgent()
void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL)
{
return;
@@ -585,6 +592,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords);
}
gGL.syncMatrices();
+ LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x00FF00 );
glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
@@ -605,6 +613,8 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
void renderFace(LLDrawable* drawable, LLFace *face)
{
+ LL_PROFILE_ZONE_SCOPED
+
LLVOVolume* vobj = drawable->getVOVolume();
if (vobj)
{
@@ -891,6 +901,8 @@ bool less_than_max_mag(const LLVector4a& vec)
BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
const LLMatrix4& mat_vert_in, BOOL global_volume)
{
+ LL_PROFILE_ZONE_SCOPED
+
//get bounding box
if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))
{
@@ -1195,12 +1207,10 @@ bool LLFace::canRenderAsMask()
}
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_VOLUME("Volume VB Cache");
-
//static
void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_VOLUME);
+ LL_PROFILE_ZONE_SCOPED;
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL;
@@ -1262,41 +1272,13 @@ void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count)
}
}
-static LLTrace::BlockTimerStatHandle FTM_FACE_GET_GEOM("Face Geom");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_POSITION("Position");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_NORMAL("Normal");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_TEXTURE("Texture");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_COLOR("Color");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_EMISSIVE("Emissive");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_WEIGHTS("Weights");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_TANGENT("Binormal");
-
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_FEEDBACK("Face Feedback");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_FEEDBACK_POSITION("Feedback Position");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_FEEDBACK_NORMAL("Feedback Normal");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_FEEDBACK_TEXTURE("Feedback Texture");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_FEEDBACK_COLOR("Feedback Color");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_FEEDBACK_EMISSIVE("Feedback Emissive");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_FEEDBACK_BINORMAL("Feedback Binormal");
-
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_INDEX("Index");
-static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_INDEX_TAIL("Tail");
-static LLTrace::BlockTimerStatHandle FTM_FACE_POSITION_STORE("Pos");
-static LLTrace::BlockTimerStatHandle FTM_FACE_TEXTURE_INDEX_STORE("TexIdx");
-static LLTrace::BlockTimerStatHandle FTM_FACE_POSITION_PAD("Pad");
-static LLTrace::BlockTimerStatHandle FTM_FACE_TEX_DEFAULT("Default");
-static LLTrace::BlockTimerStatHandle FTM_FACE_TEX_QUICK("Quick");
-static LLTrace::BlockTimerStatHandle FTM_FACE_TEX_QUICK_NO_XFORM("No Xform");
-static LLTrace::BlockTimerStatHandle FTM_FACE_TEX_QUICK_XFORM("Xform");
-static LLTrace::BlockTimerStatHandle FTM_FACE_TEX_QUICK_PLANAR("Quick Planar");
-
BOOL LLFace::getGeometryVolume(const LLVolume& volume,
const S32 &f,
const LLMatrix4& mat_vert_in, const LLMatrix3& mat_norm_in,
const U16 &index_offset,
bool force_rebuild)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GET_GEOM);
+ LL_PROFILE_ZONE_SCOPED;
llassert(verify());
if (volume.getNumVolumeFaces() <= f) {
@@ -1437,7 +1419,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
// INDICES
if (full_rebuild)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_INDEX);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - indices");
mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range);
volatile __m128i* dst = (__m128i*) indicesp.get();
@@ -1453,7 +1435,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_INDEX_TAIL);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - indices tail");
U16* idx = (U16*) dst;
for (S32 i = end*8; i < num_indices; ++i)
@@ -1516,7 +1498,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
!volume.isUnique()) //source volume is NOT flexi
{ //use transform feedback to pack vertex buffer
//gGLDebugLoggingEnabled = TRUE;
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK);
+
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - transform feedback");
LLGLEnable discard(GL_RASTERIZER_DISCARD);
LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
@@ -1534,7 +1517,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_pos)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK_POSITION);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - tf position");
gTransformPositionProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
@@ -1559,7 +1542,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_color)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK_COLOR);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - tf color");
gTransformColorProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
@@ -1575,7 +1558,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_emissive)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK_EMISSIVE);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - tf emissive");
gTransformColorProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount);
@@ -1596,7 +1579,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_normal)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK_NORMAL);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - tf normal");
gTransformNormalProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount);
@@ -1609,7 +1592,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_tangent)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_TANGENT);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - tf tangent");
gTransformTangentProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);
@@ -1622,7 +1605,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_tcoord)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK_TEXTURE);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - tf tcoord");
gTransformTexCoordProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount);
@@ -1661,7 +1644,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_tcoord)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_TEXTURE);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - tcoord");
//bump setup
LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f );
@@ -1784,18 +1767,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_TEX_QUICK);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - texgen");
if (!do_tex_mat)
{
if (!do_xform)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_TEX_QUICK_NO_XFORM);
+ LL_PROFILE_ZONE_NAMED("ggv - texgen 1");
S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size);
}
else
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_TEX_QUICK_XFORM);
+ LL_PROFILE_ZONE_NAMED("ggv - texgen 2");
F32* dst = (F32*) tex_coords0.get();
LLVector4a* src = (LLVector4a*) vf.mTexCoords;
@@ -1835,9 +1818,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
- //LLVector4a& norm = vf.mNormals[i];
- //LLVector4a& center = *(vf.mCenter);
-
+
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
tmp = tmp * *mTextureMatrix;
tc.mV[0] = tmp.mV[0];
@@ -1848,7 +1829,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
else
{ //no bump, tex gen planar
- LL_RECORD_BLOCK_TIME(FTM_FACE_TEX_QUICK_PLANAR);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - texgen planar");
if (do_tex_mat)
{
for (S32 i = 0; i < num_vertices; i++)
@@ -1893,7 +1874,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
else
{ //bump mapped or has material, just do the whole expensive loop
- LL_RECORD_BLOCK_TIME(FTM_FACE_TEX_DEFAULT);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - texgen default");
std::vector<LLVector2> bump_tc;
@@ -2051,7 +2032,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a* end = src+num_vertices;
//LLVector4a* end_64 = end-4;
- //LL_RECORD_TIME_BLOCK(FTM_FACE_GEOM_POSITION);
llassert(num_vertices > 0);
mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
@@ -2088,53 +2068,19 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a tmp;
- {
- //LL_RECORD_TIME_BLOCK(FTM_FACE_POSITION_STORE);
-
- /*if (num_vertices > 4)
- { //more than 64 bytes
- while (src < end_64)
- {
- _mm_prefetch((char*)src + 64, _MM_HINT_T0);
- _mm_prefetch((char*)dst + 64, _MM_HINT_T0);
-
- mat_vert.affineTransform(*src, res0);
- tmp.setSelectWithMask(mask, texIdx, res0);
- tmp.store4a((F32*) dst);
-
- mat_vert.affineTransform(*(src+1), res1);
- tmp.setSelectWithMask(mask, texIdx, res1);
- tmp.store4a((F32*) dst+4);
-
- mat_vert.affineTransform(*(src+2), res2);
- tmp.setSelectWithMask(mask, texIdx, res2);
- tmp.store4a((F32*) dst+8);
-
- mat_vert.affineTransform(*(src+3), res3);
- tmp.setSelectWithMask(mask, texIdx, res3);
- tmp.store4a((F32*) dst+12);
-
- dst += 16;
- src += 4;
- }
- }*/
-
- while (src < end)
- {
- mat_vert.affineTransform(*src++, res0);
- tmp.setSelectWithMask(mask, texIdx, res0);
- tmp.store4a((F32*) dst);
- dst += 4;
- }
+
+ while (src < end)
+ {
+ mat_vert.affineTransform(*src++, res0);
+ tmp.setSelectWithMask(mask, texIdx, res0);
+ tmp.store4a((F32*) dst);
+ dst += 4;
}
-
+
+ while (dst < end_f32)
{
- //LL_RECORD_TIME_BLOCK(FTM_FACE_POSITION_PAD);
- while (dst < end_f32)
- {
- res0.store4a((F32*) dst);
- dst += 4;
- }
+ res0.store4a((F32*) dst);
+ dst += 4;
}
if (map_range)
@@ -2168,7 +2114,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_tangent)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_TANGENT);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - tangent");
mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range);
F32* tangents = (F32*) tangent.get();
@@ -2201,7 +2147,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_weights && vf.mWeights)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_WEIGHTS);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - weight");
mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);
F32* weights = (F32*) wght.get();
LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
@@ -2213,7 +2159,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) )
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_COLOR);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - color");
mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range);
LLVector4a src;
@@ -2244,7 +2190,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_emissive)
{
- LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_EMISSIVE);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - emissive");
LLStrider<LLColor4U> emissive;
mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range);
@@ -2375,6 +2321,8 @@ F32 LLFace::getTextureVirtualSize()
BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
{
+ LL_PROFILE_ZONE_SCOPED
+
//VECTORIZE THIS
//get area of circle around face
LLVector4a center;
@@ -2654,6 +2602,8 @@ const LLMatrix4& LLFace::getRenderMatrix() const
S32 LLFace::renderElements(const U16 *index_array) const
{
+ LL_PROFILE_ZONE_SCOPED
+
S32 ret = 0;
if (isState(GLOBAL))
@@ -2673,6 +2623,8 @@ S32 LLFace::renderElements(const U16 *index_array) const
S32 LLFace::renderIndexed()
{
+ LL_PROFILE_ZONE_SCOPED
+
if(mDrawablep == NULL || mDrawPoolp == NULL)
{
return 0;
@@ -2683,6 +2635,8 @@ S32 LLFace::renderIndexed()
S32 LLFace::renderIndexed(U32 mask)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (mVertexBuffer.isNull())
{
return 0;
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 3611539ff8..2e76c974fa 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -54,11 +54,11 @@ const F32 MIN_ALPHA_SIZE = 1024.f;
const F32 MIN_TEX_ANIM_SIZE = 512.f;
const U8 FACE_DO_NOT_BATCH_TEXTURES = 255;
-class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16>
+class alignas(16) LLFace
{
+ LL_ALIGN_NEW
public:
LLFace(const LLFace& rhs)
- : LLTrace::MemTrackableNonVirtual<LLFace, 16>("LLFace")
{
*this = rhs;
}
@@ -85,8 +85,8 @@ public:
public:
LLFace(LLDrawable* drawablep, LLViewerObject* objp)
- : LLTrace::MemTrackableNonVirtual<LLFace, 16>("LLFace")
{
+ LL_PROFILE_ZONE_SCOPED;
init(drawablep, objp);
}
~LLFace() { destroy(); }
@@ -271,10 +271,10 @@ private:
LLColor4 mFaceColor; // overrides material color if state |= USE_FACE_COLOR
U16 mGeomCount; // vertex count for this face
- U16 mGeomIndex; // index into draw pool
+ U16 mGeomIndex; // starting index into mVertexBuffer's vertex array
U8 mTextureIndex; // index of texture channel to use for pseudo-atlasing
U32 mIndicesCount;
- U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!)
+ U32 mIndicesIndex; // index into mVertexBuffer's index array
S32 mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS];
LLXformMatrix* mXform;
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 239d162101..1605e4133d 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -716,7 +716,6 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
//======================================
buffer.clear();
-
gGL.color3fv(base_col.mV);
U32 count = 0;
U32 total_count = base_execution.size();
@@ -1019,11 +1018,9 @@ void LLFastTimerView::printLineStats()
}
}
-static LLTrace::BlockTimerStatHandle FTM_DRAW_LINE_GRAPH("Draw line graph");
-
void LLFastTimerView::drawLineGraph()
{
- LL_RECORD_BLOCK_TIME(FTM_DRAW_LINE_GRAPH);
+ LL_PROFILE_ZONE_SCOPED;
//draw line graph history
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLLocalClipRect clip(mGraphRect);
@@ -1062,6 +1059,7 @@ void LLFastTimerView::drawLineGraph()
F32Seconds cur_max(0);
U32 cur_max_calls = 0;
+
for(block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
it != LLTrace::end_block_timer_tree_df();
++it)
@@ -1096,6 +1094,7 @@ void LLFastTimerView::drawLineGraph()
F32 call_scale_factor = (F32)mGraphRect.getHeight() / (F32)max_calls;
F32 time_scale_factor = (F32)mGraphRect.getHeight() / max_time.value();
F32 hz_scale_factor = (F32) mGraphRect.getHeight() / (1.f / max_time.value());
+
for (U32 j = mRecording.getNumRecordedPeriods();
j > 0;
j--)
@@ -1103,7 +1102,7 @@ void LLFastTimerView::drawLineGraph()
LLTrace::Recording& recording = mRecording.getPrevRecording(j);
F32Seconds time = llmax(recording.getSum(*idp), F64Seconds(0.000001));
U32 calls = recording.getSum(idp->callCount());
-
+
if (is_hover_timer)
{
//normalize to highlighted timer
@@ -1450,6 +1449,7 @@ void LLFastTimerView::updateTotalTime()
void LLFastTimerView::drawBars()
{
+ LL_PROFILE_ZONE_SCOPED;
LLLocalClipRect clip(mBarRect);
S32 bar_height = mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2);
@@ -1527,11 +1527,9 @@ void LLFastTimerView::drawBars()
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_TIMER_BAR_WIDTHS("Update timer bar widths");
-
F32Seconds LLFastTimerView::updateTimerBarWidths(LLTrace::BlockTimerStatHandle* time_block, TimerBarRow& row, S32 history_index, U32& bar_index)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_TIMER_BAR_WIDTHS);
+ LL_PROFILE_ZONE_SCOPED;
const F32Seconds self_time = history_index == -1
? mRecording.getPeriodMean(time_block->selfTime(), RUNNING_AVERAGE_WIDTH)
: mRecording.getPrevRecording(history_index).getSum(time_block->selfTime());
@@ -1555,11 +1553,9 @@ F32Seconds LLFastTimerView::updateTimerBarWidths(LLTrace::BlockTimerStatHandle*
return full_time;
}
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_TIMER_BAR_FRACTIONS("Update timer bar fractions");
-
S32 LLFastTimerView::updateTimerBarOffsets(LLTrace::BlockTimerStatHandle* time_block, TimerBarRow& row, S32 timer_bar_index)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_TIMER_BAR_FRACTIONS);
+ LL_PROFILE_ZONE_SCOPED;
TimerBar& timer_bar = row.mBars[timer_bar_index];
const F32Seconds bar_time = timer_bar.mTotalTime - timer_bar.mSelfTime;
@@ -1620,6 +1616,7 @@ S32 LLFastTimerView::updateTimerBarOffsets(LLTrace::BlockTimerStatHandle* time_b
S32 LLFastTimerView::drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered, bool visible, S32 bar_index)
{
+ LL_PROFILE_ZONE_SCOPED;
TimerBar& timer_bar = row.mBars[bar_index];
LLTrace::BlockTimerStatHandle* time_block = timer_bar.mTimeBlock;
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index e6bbe234b3..98c8531cd6 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -670,11 +670,7 @@ void LLFeatureManager::applyBaseMasks()
}
// now all those wacky ones
- if (!gGLManager.mHasFragmentShader)
- {
- maskFeatures("NoPixelShaders");
- }
- if (!gGLManager.mHasVertexShader || !mGPUSupported)
+ if (!mGPUSupported)
{
maskFeatures("NoVertexShaders");
}
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index e075a311c2..0b0567b687 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -47,9 +47,6 @@ static const F32 SEC_PER_FLEXI_FRAME = 1.f / 60.f; // 60 flexi updates per secon
/*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f;
std::vector<LLVolumeImplFlexible*> LLVolumeImplFlexible::sInstanceList;
-static LLTrace::BlockTimerStatHandle FTM_FLEXIBLE_REBUILD("Rebuild");
-static LLTrace::BlockTimerStatHandle FTM_DO_FLEXIBLE_UPDATE("Flexible Update");
-
// LLFlexibleObjectData::pack/unpack now in llprimitive.cpp
//-----------------------------------------------
@@ -95,7 +92,7 @@ LLVolumeImplFlexible::~LLVolumeImplFlexible()
//static
void LLVolumeImplFlexible::updateClass()
{
- LL_RECORD_BLOCK_TIME(FTM_DO_FLEXIBLE_UPDATE);
+ LL_PROFILE_ZONE_SCOPED;
U64 virtual_frame_num = LLTimer::getElapsedSeconds() / SEC_PER_FLEXI_FRAME;
for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin();
@@ -429,7 +426,7 @@ inline S32 log2(S32 x)
void LLVolumeImplFlexible::doFlexibleUpdate()
{
- LL_RECORD_BLOCK_TIME(FTM_DO_FLEXIBLE_UPDATE);
+ LL_PROFILE_ZONE_SCOPED;
LLVolume* volume = mVO->getVolume();
LLPath *path = &volume->getPath();
if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible())
@@ -720,13 +717,12 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
mLastSegmentRotation = parentSegmentRotation;
}
-static LLTrace::BlockTimerStatHandle FTM_FLEXI_PREBUILD("Flexi Prebuild");
void LLVolumeImplFlexible::preRebuild()
{
if (!mUpdated)
{
- LL_RECORD_BLOCK_TIME(FTM_FLEXI_PREBUILD);
+ LL_PROFILE_ZONE_SCOPED;
doFlexibleRebuild(false);
}
}
@@ -752,6 +748,7 @@ void LLVolumeImplFlexible::onSetScale(const LLVector3& scale, BOOL damped)
BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
{
+ LL_PROFILE_ZONE_SCOPED;
LLVOVolume *volume = (LLVOVolume*)mVO;
if (mVO->isAttachment())
@@ -789,7 +786,6 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
if (mRenderRes > -1)
{
- LL_RECORD_BLOCK_TIME(FTM_DO_FLEXIBLE_UPDATE);
doFlexibleUpdate();
}
@@ -809,7 +805,6 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
volume->mDrawable->setState(LLDrawable::REBUILD_VOLUME);
volume->dirtySpatialGroup();
{
- LL_RECORD_BLOCK_TIME(FTM_FLEXIBLE_REBUILD);
doFlexibleRebuild(volume->mVolumeChanged);
}
volume->genBBoxes(isVolumeGlobal());
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 9c84fa1991..112ece0fbf 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -723,7 +723,8 @@ void LLFloaterIMContainer::setMinimized(BOOL b)
}
void LLFloaterIMContainer::setVisible(BOOL visible)
-{ LLFloaterIMNearbyChat* nearby_chat;
+{
+ LLFloaterIMNearbyChat* nearby_chat;
if (visible)
{
// Make sure we have the Nearby Chat present when showing the conversation container
@@ -758,22 +759,25 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
LLFloaterIMSessionTab::addToHost(LLUUID());
}
- // We need to show/hide all the associated conversations that have been torn off
- // (and therefore, are not longer managed by the multifloater),
- // so that they show/hide with the conversations manager.
- conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
- for (;widget_it != mConversationsWidgets.end(); ++widget_it)
- {
- LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
- if (widget)
- {
- LLFloater* session_floater = widget->getSessionFloater();
- if (session_floater != nearby_chat)
- {
- widget->setVisibleIfDetached(visible);
- }
- }
- }
+ if (!LLFloater::isQuitRequested())
+ {
+ // We need to show/hide all the associated conversations that have been torn off
+ // (and therefore, are not longer managed by the multifloater),
+ // so that they show/hide with the conversations manager.
+ conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+ for (; widget_it != mConversationsWidgets.end(); ++widget_it)
+ {
+ LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+ if (widget)
+ {
+ LLFloater* session_floater = widget->getSessionFloater();
+ if (session_floater != nearby_chat)
+ {
+ widget->setVisibleIfDetached(visible);
+ }
+ }
+ }
+ }
// Now, do the normal multifloater show/hide
LLMultiFloater::setVisible(visible);
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index d9edd4dc30..0e54b66ea9 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1357,31 +1357,31 @@ void LLFloaterModelPreview::clearAvatarTab()
}
void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
- {
+{
S32 display_lod = mModelPreview->mPreviewLOD;
if (mModelPreview->mModel[display_lod].empty())
- {
+ {
mSelectedJointName.clear();
return;
- }
+ }
// Joints will be listed as long as they are listed in mAlternateBindMatrix
// even if they are for some reason identical to defaults.
// Todo: Are overrides always identical for all lods? They normally are, but there might be situations where they aren't.
if (mJointOverrides[display_lod].empty())
- {
+ {
// populate map
for (LLModelLoader::scene::iterator iter = mModelPreview->mScene[display_lod].begin(); iter != mModelPreview->mScene[display_lod].end(); ++iter)
- {
+ {
for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
- {
+ {
LLModelInstance& instance = *model_iter;
LLModel* model = instance.mModel;
const LLMeshSkinInfo *skin = &model->mSkinInfo;
U32 joint_count = LLSkinningUtil::getMeshJointCount(skin);
U32 bind_count = highlight_overrides ? skin->mAlternateBindMatrix.size() : 0; // simply do not include overrides if data is not needed
if (bind_count > 0 && bind_count != joint_count)
- {
+ {
std::ostringstream out;
out << "Invalid joint overrides for model " << model->getName();
out << ". Amount of joints " << joint_count;
@@ -1390,68 +1390,68 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
addStringToLog(out.str(), true);
// Disable overrides for this model
bind_count = 0;
- }
+ }
if (bind_count > 0)
- {
+ {
for (U32 j = 0; j < joint_count; ++j)
- {
- const LLVector3& joint_pos = skin->mAlternateBindMatrix[j].getTranslation();
+ {
+ const LLVector3& joint_pos = LLVector3(skin->mAlternateBindMatrix[j].getTranslation());
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j], mModelPreview);
if (pJoint)
- {
+ {
// see how voavatar uses aboveJointPosThreshold
if (pJoint->aboveJointPosThreshold(joint_pos))
- {
+ {
// valid override
if (data.mPosOverrides.size() > 0
&& (data.mPosOverrides.begin()->second - joint_pos).lengthSquared() > (LL_JOINT_TRESHOLD_POS_OFFSET * LL_JOINT_TRESHOLD_POS_OFFSET))
- {
+ {
// File contains multiple meshes with conflicting joint offsets
// preview may be incorrect, upload result might wary (depends onto
// mesh_id that hasn't been generated yet).
data.mHasConflicts = true;
- }
+ }
data.mPosOverrides[model->getName()] = joint_pos;
- }
- else
- {
+ }
+ else
+ {
// default value, it won't be accounted for by avatar
data.mModelsNoOverrides.insert(model->getName());
- }
- }
- }
- }
- else
- {
+ }
+ }
+ }
+ }
+ else
+ {
for (U32 j = 0; j < joint_count; ++j)
- {
+ {
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
data.mModelsNoOverrides.insert(model->getName());
}
}
- }
- }
- }
+ }
+ }
+ }
LLPanel *panel = mTabContainer->getPanelByName("rigging_panel");
LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
if (joints_list->isEmpty())
- {
+ {
// Populate table
- std::map<std::string, std::string> joint_alias_map;
+ std::map<std::string, std::string> joint_alias_map;
mModelPreview->getJointAliases(joint_alias_map);
-
+
S32 conflicts = 0;
joint_override_data_map_t::iterator joint_iter = mJointOverrides[display_lod].begin();
joint_override_data_map_t::iterator joint_end = mJointOverrides[display_lod].end();
while (joint_iter != joint_end)
- {
+ {
const std::string& listName = joint_iter->first;
-
+
LLScrollListItem::Params item_params;
item_params.value(listName);
@@ -1459,38 +1459,38 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
cell_params.font = LLFontGL::getFontSansSerif();
cell_params.value = listName;
if (joint_alias_map.find(listName) == joint_alias_map.end())
- {
+ {
// Missing names
cell_params.color = LLColor4::red;
- }
+ }
if (joint_iter->second.mHasConflicts)
- {
+ {
// Conflicts
cell_params.color = LLColor4::orange;
conflicts++;
- }
+ }
if (highlight_overrides && joint_iter->second.mPosOverrides.size() > 0)
- {
+ {
cell_params.font.style = "BOLD";
- }
+ }
item_params.columns.add(cell_params);
joints_list->addRow(item_params, ADD_BOTTOM);
joint_iter++;
- }
+ }
joints_list->selectFirstItem();
LLScrollListItem *selected = joints_list->getFirstSelected();
if (selected)
-{
+ {
mSelectedJointName = selected->getValue().asString();
- }
+ }
LLTextBox *joint_conf_descr = panel->getChild<LLTextBox>("conflicts_description");
joint_conf_descr->setTextArg("[CONFLICTS]", llformat("%d", conflicts));
joint_conf_descr->setTextArg("[JOINTS_COUNT]", llformat("%d", mJointOverrides[display_lod].size()));
- }
- }
+ }
+}
//-----------------------------------------------------------------------------
// addStringToLogTab()
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 82f01fb747..12b4d6a1cd 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1199,11 +1199,9 @@ void LLFloaterPreference::refreshEnabledState()
//Deferred/SSAO/Shadows
BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
- BOOL transparent_water = LLFeatureManager::getInstance()->isFeatureAvailable("RenderTransparentWater") && gSavedSettings.getBOOL("RenderTransparentWater");
BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
bumpshiny &&
- transparent_water &&
shaders &&
gGLManager.mHasFramebufferObject &&
gSavedSettings.getBOOL("RenderAvatarVP") &&
@@ -1227,9 +1225,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
ctrl_reflections->setEnabled(reflections);
reflections_text->setEnabled(reflections);
- // Transparent Water
- LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
-
// Bump & Shiny
LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
@@ -1280,7 +1275,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
- ((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
gGLManager.mHasFramebufferObject &&
gSavedSettings.getBOOL("RenderAvatarVP") &&
(ctrl_wind_light->get()) ? TRUE : FALSE;
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index 23fd6d9c8e..ceab472c55 100644
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -159,7 +159,7 @@ LLFloater* LLFloaterWebContent::create( Params p)
//static
void LLFloaterWebContent::closeRequest(const std::string &uuid)
{
- LLFloaterWebContent* floaterp = instance_tracker_t::getInstance(uuid);
+ auto floaterp = instance_tracker_t::getInstance(uuid);
if (floaterp)
{
floaterp->closeFloater(false);
@@ -169,7 +169,7 @@ void LLFloaterWebContent::closeRequest(const std::string &uuid)
//static
void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height)
{
- LLFloaterWebContent* floaterp = instance_tracker_t::getInstance(uuid);
+ auto floaterp = instance_tracker_t::getInstance(uuid);
if (floaterp)
{
floaterp->geometryChanged(x, y, width, height);
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 698c15bd2d..91f314c115 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -993,9 +993,8 @@ private:
//-----------------------------------------------------------------------------
F32 gpu_benchmark()
{
- if (!gGLManager.mHasShaderObjects || !gGLManager.mHasTimerQuery)
- { // don't bother benchmarking the fixed function
- // or venerable drivers which don't support accurate timing anyway
+ if (!gGLManager.mHasTimerQuery)
+ { // don't bother benchmarking venerable drivers which don't support accurate timing anyway
// and are likely to be correctly identified by the GPU table already.
return -1.f;
}
@@ -1091,7 +1090,7 @@ F32 gpu_benchmark()
delete [] pixels;
//make a dummy triangle to draw with
- LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STREAM_DRAW_ARB);
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STREAM_DRAW_ARB);
if (!buff->allocateBuffer(3, 0, true))
{
@@ -1101,7 +1100,6 @@ F32 gpu_benchmark()
}
LLStrider<LLVector3> v;
- LLStrider<LLVector2> tc;
if (! buff->getVertexStrider(v))
{
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 32f88b49ac..7f65153879 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -944,12 +944,10 @@ static void formatDateString(std::string &date_string)
}
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_MEMBERS_REPLY("Process Group Members");
-
// static
void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_MEMBERS_REPLY);
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupMembersReply" << LL_ENDL;
LLUUID agent_id;
@@ -1054,12 +1052,10 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_PROPERTIES_REPLY("Process Group Properties");
-
//static
void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_PROPERTIES_REPLY);
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL;
if (!msg)
@@ -1139,11 +1135,10 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES);
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_DATA_REPLY("Process Group Role Data");
// static
void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_DATA_REPLY);
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL;
LLUUID agent_id;
@@ -1227,11 +1222,10 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_DATA);
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY("Process Group Role Members");
// static
void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY);
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL;
LLUUID agent_id;
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 9d49c30a49..55a4b5a457 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -224,6 +224,7 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4
void LLHUDNameTag::render()
{
+ LL_PROFILE_ZONE_SCOPED;
if (sDisplayText)
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
@@ -731,6 +732,7 @@ void LLHUDNameTag::updateSize()
void LLHUDNameTag::updateAll()
{
+ LL_PROFILE_ZONE_SCOPED;
// iterate over all text objects, calculate their restoration forces,
// and add them to the visible set if they are on screen and close enough
sVisibleTextObjects.clear();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 1059324a16..f5358ba5f2 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1229,7 +1229,6 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id,
if (!session)
{
- LL_WARNS() << "session " << session_id << "does not exist " << LL_ENDL;
return NULL;
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 81b55c1073..3609c5e457 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -5740,14 +5740,14 @@ class LLCallingCardObserver : public LLFriendObserver
public:
LLCallingCardObserver(LLCallingCardBridge* bridge) : mBridgep(bridge) {}
virtual ~LLCallingCardObserver() { mBridgep = NULL; }
- virtual void changed(U32 mask)
- {
- mBridgep->refreshFolderViewItem();
- if (mask & LLFriendObserver::ONLINE)
- {
- mBridgep->checkSearchBySuffixChanges();
- }
- }
+ virtual void changed(U32 mask)
+ {
+ if (mask & LLFriendObserver::ONLINE)
+ {
+ mBridgep->refreshFolderViewItem();
+ mBridgep->checkSearchBySuffixChanges();
+ }
+ }
protected:
LLCallingCardBridge* mBridgep;
};
@@ -5761,14 +5761,15 @@ LLCallingCardBridge::LLCallingCardBridge(LLInventoryPanel* inventory,
const LLUUID& uuid ) :
LLItemBridge(inventory, root, uuid)
{
- mObserver = new LLCallingCardObserver(this);
- LLAvatarTracker::instance().addObserver(mObserver);
+ mObserver = new LLCallingCardObserver(this);
+ LLAvatarTracker::instance().addParticularFriendObserver(getItem()->getCreatorUUID(), mObserver);
}
LLCallingCardBridge::~LLCallingCardBridge()
{
- LLAvatarTracker::instance().removeObserver(mObserver);
- delete mObserver;
+ LLAvatarTracker::instance().removeParticularFriendObserver(getItem()->getCreatorUUID(), mObserver);
+
+ delete mObserver;
}
void LLCallingCardBridge::refreshFolderViewItem()
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 3b5ba24b9f..707ff2b7b6 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -48,8 +48,6 @@
#include "llclipboard.h"
#include "lltrans.h"
-LLTrace::BlockTimerStatHandle FT_FILTER_CLIPBOARD("Filter Clipboard");
-
LLInventoryFilter::FilterOps::FilterOps(const Params& p)
: mFilterObjectTypes(p.object_types),
mFilterCategoryTypes(p.category_types),
@@ -506,7 +504,7 @@ bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const
{
if (LLClipboard::instance().isCutMode())
{
- LL_RECORD_BLOCK_TIME(FT_FILTER_CLIPBOARD);
+ LL_PROFILE_ZONE_SCOPED;
LLUUID current_id = object_id;
LLInventoryObject *current_object = gInventory.getObject(object_id);
while (current_id.notNull() && current_object)
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index 1dc1aa395e..23129f7d44 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -133,11 +133,9 @@ void LLInventoryItemsList::idle(void* user_data)
}
}
-LLTrace::BlockTimerStatHandle FTM_INVENTORY_ITEMS_REFRESH("Inventory List Refresh");
-
void LLInventoryItemsList::refresh()
{
- LL_RECORD_BLOCK_TIME(FTM_INVENTORY_ITEMS_REFRESH);
+ LL_PROFILE_ZONE_SCOPED;
switch (mRefreshState)
{
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 05d9fec701..7c241c3283 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -674,10 +674,9 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
}
// Called when something changed in the global model (new item, item coming through the wire, rename, move, etc...) (CHUI-849)
-static LLTrace::BlockTimerStatHandle FTM_REFRESH("Inventory Refresh");
void LLInventoryPanel::modelChanged(U32 mask)
{
- LL_RECORD_BLOCK_TIME(FTM_REFRESH);
+ LL_PROFILE_ZONE_SCOPED;
if (mViewsInitialized != VIEWS_INITIALIZED) return;
@@ -1692,10 +1691,9 @@ void LLInventoryPanel::removeItemID(const LLUUID& id)
}
}
-LLTrace::BlockTimerStatHandle FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id)
{
- LL_RECORD_BLOCK_TIME(FTM_GET_ITEM_BY_ID);
+ LL_PROFILE_ZONE_SCOPED;
std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
map_it = mItemMap.find(id);
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp
index a2acb3efe2..238e9fe0e1 100644
--- a/indra/newview/lllegacyatmospherics.cpp
+++ b/indra/newview/lllegacyatmospherics.cpp
@@ -202,17 +202,11 @@ void LLAtmospherics::init()
mInitialized = true;
}
-LLColor4 LLAtmospherics::calcSkyColorInDir(AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny)
-{
- LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- return calcSkyColorInDir(psky, vars, dir, isShiny);
-}
-
// This cubemap is used as "environmentMap" in indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
-LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny)
+LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny, bool low_end)
{
- F32 sky_saturation = 0.25f;
- F32 land_saturation = 0.1f;
+ const F32 sky_saturation = 0.25f;
+ const F32 land_saturation = 0.1f;
if (isShiny && dir.mV[VZ] < -0.02f)
{
@@ -227,7 +221,7 @@ LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, Atm
}
F32 greyscale_sat = brightness * (1.0f - land_saturation);
desat_fog = desat_fog * land_saturation + smear(greyscale_sat);
- if (!gPipeline.canUseWindLightShaders())
+ if (low_end)
{
col = LLColor4(desat_fog, 0.f);
}
@@ -258,8 +252,7 @@ LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, Atm
return LLColor4(sky_color, 0.0f);
}
- bool low_end = !gPipeline.canUseWindLightShaders();
- LLColor3 sky_color = low_end ? vars.hazeColor * 2.0f : psky->gammaCorrect(vars.hazeColor * 2.0f);
+ LLColor3 sky_color = low_end ? vars.hazeColor * 2.0f : psky->gammaCorrect(vars.hazeColor * 2.0f, vars.gamma);
return LLColor4(sky_color, 0.0f);
}
@@ -270,11 +263,12 @@ LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, Atm
// indra\newview\lllegacyatmospherics.cpp
void LLAtmospherics::calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVector3 & Pn, AtmosphericsVars& vars)
{
- LLColor3 blue_density = vars.blue_density;
- LLColor3 blue_horizon = vars.blue_horizon;
- F32 haze_horizon = vars.haze_horizon;
- F32 haze_density = vars.haze_density;
- F32 density_multiplier = vars.density_multiplier;
+ const LLColor3 blue_density = vars.blue_density;
+ const LLColor3 blue_horizon = vars.blue_horizon;
+ const F32 haze_horizon = vars.haze_horizon;
+ const F32 haze_density = vars.haze_density;
+ const F32 density_multiplier = vars.density_multiplier;
+
F32 max_y = vars.max_y;
LLVector4 sun_norm = vars.sun_norm;
@@ -313,7 +307,7 @@ void LLAtmospherics::calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVect
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
LLColor3 light_atten = vars.light_atten;
- LLColor3 light_transmittance = psky->getLightTransmittance(Plen);
+ LLColor3 light_transmittance = psky->getLightTransmittanceFast(vars.total_density, vars.density_multiplier, Plen);
(void)light_transmittance; // silence Clang warn-error
// Calculate relative weights
@@ -436,12 +430,16 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ // NOTE: This is very similar to LLVOSky::cacheEnvironment()
+ // Differences:
+ // vars.sun_norm
+ // vars.sunlight
// invariants across whole sky tex process...
- vars.blue_density = psky->getBlueDensity();
+ vars.blue_density = psky->getBlueDensity();
vars.blue_horizon = psky->getBlueHorizon();
vars.haze_density = psky->getHazeDensity();
vars.haze_horizon = psky->getHazeHorizon();
- vars.density_multiplier = psky->getDensityMultiplier();
+ vars.density_multiplier = psky->getDensityMultiplier();
vars.distance_multiplier = psky->getDistanceMultiplier();
vars.max_y = psky->getMaxY();
vars.sun_norm = LLEnvironment::instance().getSunDirectionCFR();
@@ -456,9 +454,9 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
vars.total_density = psky->getTotalDensity();
vars.gamma = psky->getGamma();
- res_color[0] = calcSkyColorInDir(vars, tosun);
- res_color[1] = calcSkyColorInDir(vars, perp_tosun);
- res_color[2] = calcSkyColorInDir(vars, tosun_45);
+ res_color[0] = calcSkyColorInDir(psky, vars, tosun);
+ res_color[1] = calcSkyColorInDir(psky, vars, perp_tosun);
+ res_color[2] = calcSkyColorInDir(psky, vars, tosun_45);
sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]);
diff --git a/indra/newview/lllegacyatmospherics.h b/indra/newview/lllegacyatmospherics.h
index 03c8efb91a..d48f3040c3 100644
--- a/indra/newview/lllegacyatmospherics.h
+++ b/indra/newview/lllegacyatmospherics.h
@@ -257,13 +257,11 @@ public:
void setCloudDensity(F32 cloud_density) { mCloudDensity = cloud_density; }
void setWind ( const LLVector3& wind ) { mWind = wind.length(); }
- LLColor4 calcSkyColorInDir(AtmosphericsVars& vars, const LLVector3& dir, bool isShiny = false);
- LLColor4 calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3& dir, bool isShiny = false);
+ LLColor4 calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3& dir, bool isShiny = false, const bool low_end = false);
-protected:
+protected:
void calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVector3 & Pn, AtmosphericsVars& vars);
- LLColor3 getHazeColor(LLSettingsSky::ptr_t psky, AtmosphericsVars& vars, F32 costheta, F32 cloud_shadow);
LLHaze mHaze;
F32 mHazeConcentration;
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index 52b9fb40ae..11aa607393 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -580,11 +580,9 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
}
}
-static LLTrace::BlockTimerStatHandle FTM_MATERIALS_IDLE("Idle Materials");
-
void LLMaterialMgr::onIdle(void*)
{
- LL_RECORD_BLOCK_TIME(FTM_MATERIALS_IDLE);
+ LL_PROFILE_ZONE_SCOPED;
LLMaterialMgr* instancep = LLMaterialMgr::getInstance();
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 2c1c1191da..a19d6d0b19 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -4045,29 +4045,28 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj)
{
- LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
-
- if (mesh_id.notNull())
- {
- skin_map::iterator iter = mSkinMap.find(mesh_id);
- if (iter != mSkinMap.end())
- {
- return &(iter->second);
- }
-
- //no skin info known about given mesh, try to fetch it
- {
- LLMutexLock lock(mMeshMutex);
- //add volume to list of loading meshes
- skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);
- if (iter == mLoadingSkins.end())
- { //no request pending for this skin info
- mPendingSkinRequests.push(mesh_id);
- }
- mLoadingSkins[mesh_id].insert(requesting_obj->getID());
- }
- }
+ LL_PROFILE_ZONE_SCOPED;
+ if (mesh_id.notNull())
+ {
+ skin_map::iterator iter = mSkinMap.find(mesh_id);
+ if (iter != mSkinMap.end())
+ {
+ return &(iter->second);
+ }
+ //no skin info known about given mesh, try to fetch it
+ if (requesting_obj != nullptr)
+ {
+ LLMutexLock lock(mMeshMutex);
+ //add volume to list of loading meshes
+ skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);
+ if (iter == mLoadingSkins.end())
+ { //no request pending for this skin info
+ mPendingSkinRequests.push(mesh_id);
+ }
+ mLoadingSkins[mesh_id].insert(requesting_obj->getID());
+ }
+ }
return NULL;
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 81e49cb1d8..c0e894fda4 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -27,6 +27,7 @@
#ifndef LL_MESH_REPOSITORY_H
#define LL_MESH_REPOSITORY_H
+#include <unordered_map>
#include "llassettype.h"
#include "llmodel.h"
#include "lluuid.h"
@@ -585,7 +586,7 @@ public:
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
static S32 getActualMeshLOD(LLSD& header, S32 lod);
- const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj);
+ const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj = nullptr);
LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
void fetchPhysicsShape(const LLUUID& mesh_id);
bool hasPhysicsShape(const LLUUID& mesh_id);
@@ -613,7 +614,7 @@ public:
typedef std::map<LLVolumeParams, std::set<LLUUID> > mesh_load_map;
mesh_load_map mLoadingMeshes[4];
- typedef std::map<LLUUID, LLMeshSkinInfo> skin_map;
+ typedef std::unordered_map<LLUUID, LLMeshSkinInfo> skin_map;
skin_map mSkinMap;
typedef std::map<LLUUID, LLModel::Decomposition*> decomposition_map;
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index a9e80ab5da..4fce6735e0 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -591,7 +591,7 @@ void LLModelPreview::rebuildUploadData()
bool upload_skinweights = fmp && fmp->childGetValue("upload_skin").asBoolean();
if (upload_skinweights && high_lod_model->mSkinInfo.mJointNames.size() > 0)
{
- LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(high_lod_model->mSkinInfo.mBindShapeMatrix);
+ LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(LLMatrix4(high_lod_model->mSkinInfo.mBindShapeMatrix));
LLQuaternion identity;
if (!bind_rot.isEqualEps(identity, 0.01))
{
@@ -3126,7 +3126,7 @@ BOOL LLModelPreview::render()
}
gGL.diffuseColor4ubv(hull_colors[i].mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions);
if (explode > 0.f)
{
@@ -3298,7 +3298,7 @@ BOOL LLModelPreview::render()
LLJoint *joint = getPreviewAvatar()->getJoint(skin->mJointNums[j]);
if (joint)
{
- const LLVector3& jointPos = skin->mAlternateBindMatrix[j].getTranslation();
+ const LLVector3& jointPos = LLVector3(skin->mAlternateBindMatrix[j].getTranslation());
if (joint->aboveJointPosThreshold(jointPos))
{
bool override_changed;
@@ -3340,11 +3340,10 @@ BOOL LLModelPreview::render()
//build matrix palette
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
- LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, joint_count,
+ LLSkinningUtil::initSkinningMatrixPalette(mat, joint_count,
skin, getPreviewAvatar());
- LLMatrix4a bind_shape_matrix;
- bind_shape_matrix.loadu(skin->mBindShapeMatrix);
+ const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix;
U32 max_joints = LLSkinningUtil::getMaxJointCount();
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
{
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 112da55682..111b45612e 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -147,6 +147,7 @@ void LLNetMap::setScale( F32 scale )
void LLNetMap::draw()
{
+ LL_PROFILE_ZONE_SCOPED;
static LLFrameTimer map_timer;
static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white);
static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white);
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index a9678b1e93..d9359d20cf 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -166,14 +166,14 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
/*virtual*/ void LLOfferHandler::onChange(LLNotificationPtr p)
{
- LLToastNotifyPanel* panelp = LLToastNotifyPanel::getInstance(p->getID());
+ auto panelp = LLToastNotifyPanel::getInstance(p->getID());
if (panelp)
{
//
// HACK: if we're dealing with a notification embedded in IM, update it
// otherwise remove its toast
//
- if (dynamic_cast<LLIMToastNotifyPanel*>(panelp))
+ if (dynamic_cast<LLIMToastNotifyPanel*>(panelp.get()))
{
panelp->updateNotification();
}
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index ba831ab2ed..d896c409d7 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -69,7 +69,8 @@ void LLScriptHandler::initChannel()
//--------------------------------------------------------------------------
void LLScriptHandler::addToastWithNotification(const LLNotificationPtr& notification)
{
- LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
+ LL_PROFILE_ZONE_SCOPED
+ LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
LLToast::Params p;
p.notif_id = notification->getID();
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index f95ab9928d..20cf4df56b 100644
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -47,11 +47,9 @@ LLPersistentNotificationStorage::~LLPersistentNotificationStorage()
{
}
-static LLTrace::BlockTimerStatHandle FTM_SAVE_NOTIFICATIONS("Save Notifications");
-
void LLPersistentNotificationStorage::saveNotifications()
{
- LL_RECORD_BLOCK_TIME(FTM_SAVE_NOTIFICATIONS);
+ LL_PROFILE_ZONE_SCOPED;
boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent"));
if (!history_channel)
@@ -90,11 +88,9 @@ void LLPersistentNotificationStorage::saveNotifications()
writeNotifications(output);
}
-static LLTrace::BlockTimerStatHandle FTM_LOAD_NOTIFICATIONS("Load Notifications");
-
void LLPersistentNotificationStorage::loadNotifications()
{
- LL_RECORD_BLOCK_TIME(FTM_LOAD_NOTIFICATIONS);
+ LL_PROFILE_ZONE_SCOPED;
LL_INFOS("LLPersistentNotificationStorage") << "start loading notifications" << LL_ENDL;
diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp
index f48ce680fd..30ca7ae539 100644
--- a/indra/newview/llphysicsmotion.cpp
+++ b/indra/newview/llphysicsmotion.cpp
@@ -453,6 +453,7 @@ F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, const
BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
// Skip if disabled globally.
if (!gSavedSettings.getBOOL("AvatarPhysics"))
{
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index f9baf5fbd3..177bc84cee 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -332,9 +332,6 @@ bool LLSceneMonitor::needsUpdate() const
return mDiffState == NEED_DIFF;
}
-static LLTrace::BlockTimerStatHandle FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE("Generate Scene Load Dither Texture");
-static LLTrace::BlockTimerStatHandle FTM_SCENE_LOAD_IMAGE_DIFF("Scene Load Image Diff");
-
static LLStaticHashedString sDitherScale("dither_scale");
static LLStaticHashedString sDitherScaleS("dither_scale_s");
static LLStaticHashedString sDitherScaleT("dither_scale_t");
@@ -356,14 +353,12 @@ void LLSceneMonitor::compare()
return;
}
- LL_RECORD_BLOCK_TIME(FTM_SCENE_LOAD_IMAGE_DIFF);
mDiffState = EXECUTE_DIFF;
S32 width = gViewerWindow->getWindowWidthRaw();
S32 height = gViewerWindow->getWindowHeightRaw();
if(!mDiff)
{
- LL_RECORD_BLOCK_TIME(FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE);
mDiff = new LLRenderTarget();
mDiff->allocate(width, height, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true);
@@ -371,7 +366,6 @@ void LLSceneMonitor::compare()
}
else if(mDiff->getWidth() != width || mDiff->getHeight() != height)
{
- LL_RECORD_BLOCK_TIME(FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE);
mDiff->resize(width, height);
generateDitheringTexture(width, height);
}
@@ -427,8 +421,6 @@ void LLSceneMonitor::calcDiffAggregate()
{
#ifdef LL_WINDOWS
- LL_RECORD_BLOCK_TIME(FTM_SCENE_LOAD_IMAGE_DIFF);
-
if(mDiffState != EXECUTE_DIFF && !mDebugViewerVisible)
{
return;
@@ -481,8 +473,6 @@ void LLSceneMonitor::calcDiffAggregate()
static LLTrace::EventStatHandle<> sFramePixelDiff("FramePixelDifference");
void LLSceneMonitor::fetchQueryResult()
{
- LL_RECORD_BLOCK_TIME(FTM_SCENE_LOAD_IMAGE_DIFF);
-
// also throttle timing here, to avoid going below sample time due to phasing with frame capture
static LLCachedControl<F32> scene_load_sample_time_control(gSavedSettings, "SceneLoadingMonitorSampleTime");
F32Seconds scene_load_sample_time = (F32Seconds)scene_load_sample_time_control();
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 681787bcbe..17f2970f99 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -49,10 +49,9 @@ using namespace LLNotificationsUI;
bool LLScreenChannel::mWasStartUpToastShown = false;
-LLTrace::BlockTimerStatHandle FTM_GET_CHANNEL_RECT("Calculate Notification Channel Region");
LLRect LLScreenChannelBase::getChannelRect()
{
- LL_RECORD_BLOCK_TIME(FTM_GET_CHANNEL_RECT);
+ LL_PROFILE_ZONE_SCOPED;
if (mFloaterSnapRegion == NULL)
{
@@ -259,7 +258,8 @@ void LLScreenChannel::updatePositionAndSize(LLRect new_world_rect)
//--------------------------------------------------------------------------
void LLScreenChannel::addToast(const LLToast::Params& p)
{
- bool store_toast = false, show_toast = false;
+ LL_PROFILE_ZONE_SCOPED
+ bool store_toast = false, show_toast = false;
if (mDisplayToastsAlways)
{
diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp
index cd3a4dfd11..c6bb2f19dd 100644
--- a/indra/newview/llscripteditor.cpp
+++ b/indra/newview/llscripteditor.cpp
@@ -138,11 +138,9 @@ void LLScriptEditor::initKeywords()
mKeywords.initialize(LLSyntaxIdLSL::getInstance()->getKeywordsXML());
}
-LLTrace::BlockTimerStatHandle FTM_SYNTAX_HIGHLIGHTING("Syntax Highlighting");
-
void LLScriptEditor::loadKeywords()
{
- LL_RECORD_BLOCK_TIME(FTM_SYNTAX_HIGHLIGHTING);
+ LL_PROFILE_ZONE_SCOPED;
mKeywords.processTokens();
segment_vec_t segment_list;
@@ -160,7 +158,7 @@ void LLScriptEditor::updateSegments()
{
if (mReflowIndex < S32_MAX && mKeywords.isLoaded() && mParseOnTheFly)
{
- LL_RECORD_BLOCK_TIME(FTM_SYNTAX_HIGHLIGHTING);
+ LL_PROFILE_ZONE_SCOPED;
// HACK: No non-ascii keywords for now
segment_vec_t segment_list;
mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index b0a566755f..e7670b5a73 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -97,6 +97,8 @@
#include "llglheaders.h"
#include "llinventoryobserver.h"
+LLSelectMgr* LLSimpleton<LLSelectMgr>::sInstance = nullptr;
+
LLViewerObject* getSelectedParentObject(LLViewerObject *object) ;
//
// Consts
@@ -209,8 +211,6 @@ void LLSelectMgr::cleanupGlobals()
LLSelectMgr::getInstance()->clearSelections();
}
-// Build time optimization, generate this function once here
-template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance();
//-----------------------------------------------------------------------------
// LLSelectMgr()
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 2b00fa1595..ce0316e610 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -407,11 +407,8 @@ private:
LLObjectSelectionHandle mSelectedObjects;
};
-class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
+class LLSelectMgr : public LLEditMenuHandler, public LLSimpleton<LLSelectMgr>
{
- LLSINGLETON(LLSelectMgr);
- ~LLSelectMgr();
-
public:
static BOOL sRectSelectInclusive; // do we need to surround an object to pick it?
static BOOL sRenderHiddenSelections; // do we show selection silhouettes that are occluded?
@@ -437,6 +434,9 @@ public:
LLCachedControl<bool> mDebugSelectMgr;
public:
+ LLSelectMgr();
+ ~LLSelectMgr();
+
static void cleanupGlobals();
// LLEditMenuHandler interface
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 1e5b893cbc..0c59de5ea0 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -637,6 +637,7 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA
//-------------------------------------------------------------------------
void LLSettingsVOSky::updateSettings()
{
+ LL_PROFILE_ZONE_SCOPED;
LLSettingsSky::updateSettings();
LLVector3 sun_direction = getSunDirection();
LLVector3 moon_direction = getMoonDirection();
@@ -665,55 +666,56 @@ void LLSettingsVOSky::updateSettings()
void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
{
- LLGLSLShader *shader = (LLGLSLShader *)ptarget;
-
+ LL_PROFILE_ZONE_SCOPED
LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm();
- if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)
+ LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_DEFAULT];
{
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV);
- shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
+ shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, LLViewerCamera::getInstance()->getOrigin());
}
- else if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
+
+ shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_SKY];
{
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV);
+ shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
- // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate")
- LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
- LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() );
+ // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate")
+ LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
+ LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() );
- // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
- // Keep in Sync!
- // * indra\newview\llsettingsvo.cpp
- // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl
- // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
- cloud_scroll[0] = -cloud_scroll[0];
- vect_c_p_d1 += cloud_scroll;
- shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV);
+ // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
+ // Keep in Sync!
+ // * indra\newview\llsettingsvo.cpp
+ // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl
+ // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
+ cloud_scroll[0] = -cloud_scroll[0];
+ vect_c_p_d1 += cloud_scroll;
+ shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, vect_c_p_d1);
- LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- LLColor4 sunDiffuse = psky->getSunlightColor();
- LLColor4 moonDiffuse = psky->getMoonlightColor();
+ LLVector4 sunDiffuse = LLVector4(psky->getSunlightColor().mV);
+ LLVector4 moonDiffuse = LLVector4(psky->getMoonlightColor().mV);
- shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, sunDiffuse.mV);
- shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, moonDiffuse.mV);
+ shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse);
+ shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse);
- LLColor4 cloud_color(psky->getCloudColor(), 1.0);
- shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, 1, cloud_color.mV);
+ LLVector4 cloud_color(LLVector3(psky->getCloudColor().mV), 1.0);
+ shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, cloud_color);
}
+ shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_ANY];
shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
LLColor4 ambient(getTotalAmbient());
- shader->uniform4fv(LLShaderMgr::AMBIENT, 1, ambient.mV);
+ shader->uniform4fv(LLShaderMgr::AMBIENT, LLVector4(ambient.mV));
shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, getIsSunUp() ? 1 : 0);
shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, getSunMoonGlowFactor());
shader->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, getDensityMultiplier());
shader->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER, getDistanceMultiplier());
- F32 g = getGamma();
+ F32 g = getGamma();
F32 display_gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
shader->uniform1f(LLShaderMgr::GAMMA, g);
@@ -907,11 +909,13 @@ LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater)
//-------------------------------------------------------------------------
void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
{
- LLGLSLShader *shader = (LLGLSLShader *)ptarget;
+ LL_PROFILE_ZONE_SCOPED
LLEnvironment& env = LLEnvironment::instance();
- if (force || (shader->mShaderGroup == LLGLSLShader::SG_WATER))
+ auto group = LLGLSLShader::SG_WATER;
+ LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[group];
+
{
F32 water_height = env.getWaterHeight();
@@ -935,7 +939,7 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
- shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, waterPlane.mV);
+ shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, waterPlane.mV);
LLVector4 light_direction = env.getClampedLightNorm();
@@ -950,18 +954,19 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, waterFogDensity);
LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor(), 0.0f);
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV);
F32 blend_factor = env.getCurrentWater()->getBlendFactor();
shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
// update to normal lightnorm, water shader itself will use rotated lightnorm as necessary
- shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, light_direction.mV);
+ shader->uniform4fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
}
}
void LLSettingsVOWater::updateSettings()
{
+ LL_PROFILE_ZONE_SCOPED;
// base class clears dirty flag so as to not trigger recursive update
LLSettingsBase::updateSettings();
diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h
index 65136ad2f5..caa3ac18d3 100644
--- a/indra/newview/llsettingsvo.h
+++ b/indra/newview/llsettingsvo.h
@@ -102,8 +102,6 @@ public:
bool isAdvanced() const { return m_isAdvanced; }
- virtual void updateShader(LLGLSLShader* shader) { applySpecial(shader, true); }
-
protected:
LLSettingsVOSky();
@@ -136,8 +134,6 @@ public:
static LLSD convertToLegacy(const ptr_t &);
- virtual void updateShader(LLGLSLShader* shader) { applySpecial(shader, true); }
-
protected:
LLSettingsVOWater();
diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp
index e02b21f036..dc12de29fb 100644
--- a/indra/newview/llskinningutil.cpp
+++ b/indra/newview/llskinningutil.cpp
@@ -35,7 +35,6 @@
#include "llrigginginfo.h"
#define DEBUG_SKINNING LL_DEBUG
-#define MAT_USE_SSE 1
void dump_avatar_and_skin_state(const std::string& reason, LLVOAvatar *avatar, const LLMeshSkinInfo *skin)
{
@@ -120,36 +119,26 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin
skin->mInvalidJointsScrubbed = true;
}
-#define MAT_USE_SSE 1
-
void LLSkinningUtil::initSkinningMatrixPalette(
- LLMatrix4* mat,
+ LLMatrix4a* mat,
S32 count,
const LLMeshSkinInfo* skin,
LLVOAvatar *avatar)
{
+ LL_PROFILE_ZONE_SCOPED;
+
initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);
+
+ LLMatrix4a world[LL_CHARACTER_MAX_ANIMATED_JOINTS];
+
for (U32 j = 0; j < count; ++j)
{
S32 joint_num = skin->mJointNums[j];
- LLJoint *joint = NULL;
- if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS)
- {
- joint = avatar->getJoint(joint_num);
- }
- llassert(joint);
+ LLJoint *joint = avatar->getJoint(joint_num);
+
if (joint)
{
-#ifdef MAT_USE_SSE
- LLMatrix4a bind, world, res;
- bind.loadu(skin->mInvBindMatrix[j]);
- world.loadu(joint->getWorldMatrix());
- matMul(bind,world,res);
- memcpy(mat[j].mMatrix,res.mMatrix,16*sizeof(float));
-#else
- mat[j] = skin->mInvBindMatrix[j];
- mat[j] *= joint->getWorldMatrix();
-#endif
+ world[j] = joint->getWorldMatrix4a();
}
else
{
@@ -159,16 +148,27 @@ void LLSkinningUtil::initSkinningMatrixPalette(
// rendering should be disabled unless all joints are
// valid. In other cases of skinned rendering, invalid
// joints should already have been removed during scrubInvalidJoints().
- LL_WARNS_ONCE("Avatar") << avatar->getFullname()
- << " rigged to invalid joint name " << skin->mJointNames[j]
- << " num " << skin->mJointNums[j] << LL_ENDL;
- LL_WARNS_ONCE("Avatar") << avatar->getFullname()
- << " avatar build state: isBuilt() " << avatar->isBuilt()
- << " mInitFlags " << avatar->mInitFlags << LL_ENDL;
+ LL_WARNS_ONCE("Avatar") << avatar->getFullname()
+ << " rigged to invalid joint name " << skin->mJointNames[j]
+ << " num " << skin->mJointNums[j] << LL_ENDL;
+ LL_WARNS_ONCE("Avatar") << avatar->getFullname()
+ << " avatar build state: isBuilt() " << avatar->isBuilt()
+ << " mInitFlags " << avatar->mInitFlags << LL_ENDL;
#endif
dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin);
}
}
+
+ //NOTE: pointer striders used here as a micro-optimization over vector/array lookups
+ const LLMatrix4a* invBind = &(skin->mInvBindMatrix[0]);
+ const LLMatrix4a* w = world;
+ LLMatrix4a* m = mat;
+ LLMatrix4a* end = m + count;
+
+ while (m < end)
+ {
+ matMulUnsafe(*(invBind++), *(w++), *(m++));
+ }
}
void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin)
@@ -212,7 +212,7 @@ void LLSkinningUtil::scrubSkinWeights(LLVector4a* weights, U32 num_vertices, con
void LLSkinningUtil::getPerVertexSkinMatrix(
F32* weights,
- LLMatrix4a* mat,
+ const LLMatrix4a* mat,
bool handle_bad_scale,
LLMatrix4a& final_mat,
U32 max_joints)
@@ -270,6 +270,7 @@ void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar)
{
if (!skin->mJointNumsInitialized)
{
+ LL_PROFILE_ZONE_SCOPED;
for (U32 j = 0; j < skin->mJointNames.size(); ++j)
{
#if DEBUG_SKINNING
@@ -357,13 +358,11 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
rig_info_tab[joint_num].setIsRiggedTo(true);
// FIXME could precompute these matMuls.
- LLMatrix4a bind_shape;
- LLMatrix4a inv_bind;
+ const LLMatrix4a& bind_shape = skin->mBindShapeMatrix;
+ const LLMatrix4a& inv_bind = skin->mInvBindMatrix[joint_index];
LLMatrix4a mat;
LLVector4a pos_joint_space;
- bind_shape.loadu(skin->mBindShapeMatrix);
- inv_bind.loadu(skin->mInvBindMatrix[joint_index]);
matMul(bind_shape, inv_bind, mat);
mat.affineTransform(pos, pos_joint_space);
@@ -426,3 +425,4 @@ LLQuaternion LLSkinningUtil::getUnscaledQuaternion(const LLMatrix4& mat4)
bind_rot.normalize();
return bind_rot;
}
+
diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h
index efe7c85997..807418f983 100644
--- a/indra/newview/llskinningutil.h
+++ b/indra/newview/llskinningutil.h
@@ -42,10 +42,10 @@ namespace LLSkinningUtil
S32 getMaxJointCount();
U32 getMeshJointCount(const LLMeshSkinInfo *skin);
void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin);
- void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar);
+ void initSkinningMatrixPalette(LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar);
void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
- void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints);
+ void getPerVertexSkinMatrix(F32* weights, const LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints);
LL_FORCE_INLINE void getPerVertexSkinMatrixWithIndices(
F32* weights,
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index efa4a7fd66..30b7124550 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -55,9 +55,6 @@
#include "llviewershadermgr.h"
#include "llcontrolavatar.h"
-static LLTrace::BlockTimerStatHandle FTM_FRUSTUM_CULL("Frustum Culling");
-static LLTrace::BlockTimerStatHandle FTM_CULL_REBOUND("Cull Rebound Partition");
-
extern bool gShiftFrame;
static U32 sZombieGroups = 0;
@@ -409,11 +406,6 @@ void LLSpatialGroup::rebuildMesh()
}
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_VBO("VBO Rebuilt");
-static LLTrace::BlockTimerStatHandle FTM_ADD_GEOMETRY_COUNT("Add Geometry");
-static LLTrace::BlockTimerStatHandle FTM_CREATE_VB("Create VB");
-static LLTrace::BlockTimerStatHandle FTM_GET_GEOMETRY("Get Geometry");
-
void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
{
if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
@@ -427,7 +419,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
group->mLastUpdateViewAngle = group->mViewAngle;
}
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_VBO);
+ LL_PROFILE_ZONE_SCOPED;
group->clearDrawMap();
@@ -435,15 +427,12 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
U32 index_count = 0;
U32 vertex_count = 0;
- {
- LL_RECORD_BLOCK_TIME(FTM_ADD_GEOMETRY_COUNT);
- addGeometryCount(group, vertex_count, index_count);
- }
-
+ addGeometryCount(group, vertex_count, index_count);
+
if (vertex_count > 0 && index_count > 0)
{ //create vertex buffer containing volume geometry for this node
{
- LL_RECORD_BLOCK_TIME(FTM_CREATE_VB);
+
group->mBuilt = 1.f;
if (group->mVertexBuffer.isNull() ||
!group->mVertexBuffer->isWriteable() ||
@@ -458,7 +447,6 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
group->mVertexBuffer = NULL;
group->mBufferMap.clear();
}
- stop_glerror();
}
else
{
@@ -471,13 +459,11 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
group->mVertexBuffer = NULL;
group->mBufferMap.clear();
}
- stop_glerror();
}
}
if (group->mVertexBuffer)
{
- LL_RECORD_BLOCK_TIME(FTM_GET_GEOMETRY);
getGeometry(group);
}
}
@@ -503,7 +489,9 @@ LLSpatialGroup* LLSpatialGroup::getParent()
}
BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
- {
+{
+ LL_PROFILE_ZONE_SCOPED
+
if(!drawablep)
{
return FALSE;
@@ -591,6 +579,8 @@ public:
void LLSpatialGroup::setState(U32 state, S32 mode)
{
+ LL_PROFILE_ZONE_SCOPED
+
llassert(state <= LLSpatialGroup::STATE_MASK);
if (mode > STATE_MODE_SINGLE)
@@ -638,6 +628,8 @@ public:
void LLSpatialGroup::clearState(U32 state, S32 mode)
{
+ LL_PROFILE_ZONE_SCOPED
+
llassert(state <= LLSpatialGroup::STATE_MASK);
if (mode > STATE_MODE_SINGLE)
@@ -724,6 +716,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)
F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)
{
+ LL_PROFILE_ZONE_SCOPED
+
LLVector4a eye;
LLVector4a origin;
origin.load3(camera.getOrigin().mV);
@@ -815,6 +809,8 @@ F32 LLSpatialGroup::getUpdateUrgency() const
BOOL LLSpatialGroup::changeLOD()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (hasState(ALPHA_DIRTY | OBJECT_DIRTY))
{
//a rebuild is going to happen, update distance and LoD
@@ -907,6 +903,8 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)
void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (child->getListenerCount() == 0)
{
new LLSpatialGroup(child, getSpatialPartition());
@@ -1477,12 +1475,12 @@ void LLSpatialPartition::resetVertexBuffers()
BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax)
{
+ LL_PROFILE_ZONE_SCOPED;
LLVector4a visMina, visMaxa;
visMina.load3(visMin.mV);
visMaxa.load3(visMax.mV);
{
- LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND);
LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
group->rebound();
}
@@ -1504,11 +1502,11 @@ BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera)
S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select)
{
+ LL_PROFILE_ZONE_SCOPED;
#if LL_OCTREE_PARANOIA_CHECK
((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
#endif
{
- LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND);
LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
group->rebound();
}
@@ -1525,37 +1523,32 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
{
+ LL_PROFILE_ZONE_SCOPED;
#if LL_OCTREE_PARANOIA_CHECK
((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
#endif
- {
- LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND);
- LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
- group->rebound();
- }
+ LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
+ group->rebound();
#if LL_OCTREE_PARANOIA_CHECK
((LLSpatialGroup*)mOctree->getListener(0))->validate();
#endif
- if (LLPipeline::sShadowRender)
- {
- LL_RECORD_BLOCK_TIME(FTM_FRUSTUM_CULL);
- LLOctreeCullShadow culler(&camera);
- culler.traverse(mOctree);
- }
- else if (mInfiniteFarClip || !LLPipeline::sUseFarClip)
- {
- LL_RECORD_BLOCK_TIME(FTM_FRUSTUM_CULL);
- LLOctreeCullNoFarClip culler(&camera);
- culler.traverse(mOctree);
- }
- else
- {
- LL_RECORD_BLOCK_TIME(FTM_FRUSTUM_CULL);
- LLOctreeCull culler(&camera);
- culler.traverse(mOctree);
- }
+ if (LLPipeline::sShadowRender)
+ {
+ LLOctreeCullShadow culler(&camera);
+ culler.traverse(mOctree);
+ }
+ else if (mInfiniteFarClip || !LLPipeline::sUseFarClip)
+ {
+ LLOctreeCullNoFarClip culler(&camera);
+ culler.traverse(mOctree);
+ }
+ else
+ {
+ LLOctreeCull culler(&camera);
+ culler.traverse(mOctree);
+ }
return 0;
}
@@ -2374,7 +2367,12 @@ void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLCo
if (!decomp->mBaseHullMesh.empty())
{
gGL.diffuseColor4fv(color.mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions, decomp->mBaseHullMesh.mNormals);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ gGL.diffuseColor4fv(line_color.mV);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
else
{
@@ -2394,13 +2392,11 @@ void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLCo
void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color, const LLColor4& line_color)
{
gGL.diffuseColor4fv(color.mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals);
- LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- glPolygonOffset(3.f, 3.f);
glLineWidth(3.f);
gGL.diffuseColor4fv(line_color.mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions);
glLineWidth(1.f);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
@@ -2455,6 +2451,9 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
gGL.pushMatrix();
gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix);
+ LLGLEnable(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(3.f, 3.f);
+
if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH)
{
LLUUID mesh_id = volume->getVolume()->getParams().getSculptID();
@@ -2482,12 +2481,12 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
{
//decomp has physics mesh, render that mesh
gGL.diffuseColor4fv(color.mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions, decomp->mPhysicsShapeMesh.mNormals);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
gGL.diffuseColor4fv(line_color.mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions, decomp->mPhysicsShapeMesh.mNormals);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
else
{ //no mesh or decomposition, render base hull
@@ -2614,8 +2613,8 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
LLVertexBuffer::unbind();
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShader != 0);
-
- LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
+
+ LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
gGL.diffuseColor4fv(color.mV);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -2700,11 +2699,17 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints);
gGL.diffuseColor4fv(line_color.mV);
gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
+ {
+ LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x20FF20 )
+ glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
+ }
gGL.diffuseColor4fv(color.mV);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
+ {
+ LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x40FF40 )
+ glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
+ }
}
else
{
@@ -3222,6 +3227,7 @@ void renderRaycast(LLDrawable* drawablep)
gGL.diffuseColor4f(0,1,1,0.5f);
glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions);
gGL.syncMatrices();
+ LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x60FF60 );
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
}
@@ -4023,8 +4029,7 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
LLViewerTexture* texture, LLVertexBuffer* buffer,
bool selected,
BOOL fullbright, U8 bump, BOOL particle, F32 part_size)
-: LLTrace::MemTrackableNonVirtual<LLDrawInfo, 16>("LLDrawInfo"),
- mVertexBuffer(buffer),
+: mVertexBuffer(buffer),
mTexture(texture),
mTextureMatrix(NULL),
mModelMatrix(NULL),
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 919f386d29..8cc50e71b1 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -41,6 +41,7 @@
#include "llviewercamera.h"
#include "llvector4a.h"
#include <queue>
+#include <unordered_map>
#define SG_STATE_INHERIT_MASK (OCCLUDED)
#define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY)
@@ -55,14 +56,14 @@ class LLViewerRegion;
void pushVerts(LLFace* face, U32 mask);
-class LLDrawInfo : public LLRefCount, public LLTrace::MemTrackableNonVirtual<LLDrawInfo, 16>
+class LLDrawInfo : public LLRefCount
{
+ LL_ALIGN_NEW;
protected:
~LLDrawInfo();
public:
LLDrawInfo(const LLDrawInfo& rhs)
- : LLTrace::MemTrackableNonVirtual<LLDrawInfo, 16>("LLDrawInfo")
{
*this = rhs;
}
@@ -216,10 +217,10 @@ public:
typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t;
typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t;
typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t;
- typedef std::map<U32, drawmap_elem_t > draw_map_t;
+ typedef std::unordered_map<U32, drawmap_elem_t > draw_map_t;
typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t;
- typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t;
- typedef std::map<U32, buffer_texture_map_t> buffer_map_t;
+ typedef std::unordered_map<LLFace*, buffer_list_t> buffer_texture_map_t;
+ typedef std::unordered_map<U32, buffer_texture_map_t> buffer_map_t;
struct CompareDistanceGreater
{
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index f22be6481a..c178f27db7 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -179,7 +179,6 @@
#include "pipeline.h"
#include "llappviewer.h"
#include "llfasttimerview.h"
-#include "lltelemetry.h"
#include "llfloatermap.h"
#include "llweb.h"
#include "llvoiceclient.h"
@@ -530,8 +529,6 @@ bool idle_startup()
}
#if LL_WINDOWS
- LLPROFILE_STARTUP();
-
// On the windows dev builds, unpackaged, the message.xml file will
// be located in indra/build-vc**/newview/<config>/app_settings.
std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml");
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index cb356726e6..ea36e1d7be 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -1214,6 +1214,7 @@ F32 LLSurface::getWaterHeight() const
BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y,
const F32 width, const F32 height)
{
+ LL_PROFILE_ZONE_SCOPED
if (!getWaterTexture())
{
return FALSE;
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index 5e056944e9..aeefcd6fb8 100644
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -728,6 +728,7 @@ BOOL LLSurfacePatch::updateTexture()
void LLSurfacePatch::updateGL()
{
+ LL_PROFILE_ZONE_SCOPED
F32 meters_per_grid = getSurface()->getMetersPerGrid();
F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge();
diff --git a/indra/newview/lltelemetry.cpp b/indra/newview/lltelemetry.cpp
deleted file mode 100644
index 0c63e2fede..0000000000
--- a/indra/newview/lltelemetry.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
- /**
- * @file lltelemetry.cpp
- * @brief Wrapper for Rad Game Tools Telemetry
- *
- * $LicenseInfo:firstyear=2020&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2020, 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 "lltelemetry.h"
-
-#if LLPROFILE_USE_RAD_TELEMETRY_PROFILER
- #if LL_WINDOWS
- #include "llwin32headers.h"
-
- // build-vc120-64\packages\lib\release
- // build-vc150-64\packages\lib\release
- #ifdef _MSC_VER
- #pragma comment(lib,"rad_tm_win64.lib")
- #else
- #pragma message "NOTE: Rad GameTools Telemetry requested but non-MSVC compiler not yet supported on Windows"
- #endif
- #endif // LL_WINDOWS
-
- #if LL_DARWIN
- #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Darwin"
- #endif
-
- #if LL_LINUX
- #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Linux"
- #endif
-
-//
-// local consts
-//
-static const tm_int32 TELEMETRY_BUFFER_SIZE = 8 * 1024 * 1024;
-
-//
-// local globals
-//
-static char *gTelemetryBufferPtr = NULL; // Telemetry
-
-static const char *tm_status[ TMERR_INIT_NETWORKING_FAILED + 1 ] =
-{
- "Telemetry pass: connected" // TM_OK
- , "Telemetry FAIL: disabled via #define NTELEMETRY" // TMERR_DISABLED
- , "Telemetry FAIL: invalid paramater" // TMERR_INVALID_PARAM
- , "Telemetry FAIL: DLL not found" // TMERR_NULL_API
- , "Telemetry FAIL: out of resources" // TMERR_OUT_OF_RESOURCES
- , "Telemetry FAIL: tmInitialize() not called" // TMERR_UNINITIALIZED
- , "Telemetry FAIL: bad hostname" // TMERR_BAD_HOSTNAME
- , "Telemetry FAIL: couldn't connect to server" // TMERR_COULD_NOT_CONNECT
- , "Telemetry FAIL: unknown network error" // TMERR_UNKNOWN_NETWORK
- , "Telemetry FAIL: tmShutdown() already called" // TMERR_ALREADY_SHUTDOWN
- , "Telemetry FAIL: memory buffer too small" // TMERR_ARENA_TOO_SMALL
- , "Telemetry FAIL: server handshake error" // TMERR_BAD_HANDSHAKE
- , "Telemetry FAIL: unaligned parameters" // TMERR_UNALIGNED
- , "Telemetry FAIL: network not initialized" // TMERR_NETWORK_NOT_INITIALIZED -- WSAStartup not called before tmOpen()
- , "Telemetry FAIL: bad version" // TMERR_BAD_VERSION
- , "Telemetry FAIL: timer too large" // TMERR_BAD_TIMER
- , "Telemetry FAIL: tmOpen() already called" // TMERR_ALREADY_OPENED
- , "Telemetry FAIL: tmInitialize() already called" // TMERR_ALREADY_INITIALIZED
- , "Telemetry FAIL: could't open file" // TMERR_FILE_OPEN_FAILED
- , "Telemetry FAIL: tmOpen() failed networking" // TMERR_INIT_NETWORKING_FAILED
-};
-
-//
-// exported functionality
-//
-
-void telemetry_shutdown()
-{
- #if LL_WINDOWS
- if (gTelemetryBufferPtr)
- {
- tmClose(0);
- tmShutdown();
-
- delete[] gTelemetryBufferPtr;
- gTelemetryBufferPtr = NULL;
- }
- #endif
-}
-
-void telemetry_startup()
-{
- #if LL_WINDOWS
- tmLoadLibrary(TM_RELEASE); // Loads .dll
-
- gTelemetryBufferPtr = new char[ TELEMETRY_BUFFER_SIZE ];
- tmInitialize(TELEMETRY_BUFFER_SIZE, gTelemetryBufferPtr);
-
- tm_error telemetry_status = tmOpen(
- 0, // unused
- "SecondLife", // app name
- __DATE__ " " __TIME__, // build identifier
- "localhost", // server name (or filename)
- TMCT_TCP, // connection type (or TMCT_FILE)
- 4719, // port
- TMOF_INIT_NETWORKING, // open flags
- 250 ); // timeout ms
-
- if (telemetry_status == TMERR_UNKNOWN)
- {
- LL_ERRS() << "Telemetry FAIL: unknown error" << LL_ENDL;
- }
- else if (telemetry_status && (telemetry_status <= TMERR_INIT_NETWORKING_FAILED))
- {
- LL_INFOS() << tm_status[ telemetry_status ] << LL_ENDL;
- free(gTelemetryBufferPtr);
- gTelemetryBufferPtr = NULL;
- }
- #endif // LL_WINDOWS
-}
-
-// Called after we render a frame
-void telemetry_update()
-{
- #if LL_WINDOWS
- if (gTelemetryBufferPtr)
- {
- tmTick(0);
- }
- #endif
-}
-#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER
diff --git a/indra/newview/lltelemetry.h b/indra/newview/lltelemetry.h
deleted file mode 100644
index a73e5fcfa2..0000000000
--- a/indra/newview/lltelemetry.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file lltelemetry.h
- * @brief Wrapper for Rad Game Tools Telemetry
- *
- * $LicenseInfo:firstyear=2020&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2020, 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$
- */
-
-/*
-To use:
-
-1. Uncomment #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER below
-
-2. Include this header file
- #include "lltelemetry.h"
-
-3. Add zones to the functions you wish to profile
- void onFoo()
- {
- LLPROFILE_ZONE("Foo");
- }
-*/
-//#define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 1
-
-// Default NO local telemetry profiling
-#ifndef LLPROFILE_USE_RAD_TELEMETRY_PROFILER
- #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 0
- #define LLPROFILE_SHUTDOWN( ...) {}
- #define LLPROFILE_STARTUP( ...) {}
- #define LLPROFILE_UPDATE( ...) {}
-
- #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b)
- #define LLPROFILE_ENTER(name)
- #define LLPROFILE_ENTER_FORMAT(format, ...)
- #define LLPROFILE_FUNCTION
- #define LLPROFILE_LEAVE()
- #define LLPROFILE_THREAD_NAME(name)
- #define LLPROFILE_ZONE(name)
- #define LLPROFILE_ZONE_FORMAT(format, ...)
-#else
- #include <rad_tm.h>
-
- #define LLPROFILE_SHUTDOWN telemetry_shutdown
- #define LLPROFILE_STARTUP telemetry_startup
- #define LLPROFILE_UPDATE telemetry_update
-
- #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) tmZoneColor(r, g, b)
- #define LLPROFILE_ENTER(name) tmEnter(0, 0, name)
- #define LLPROFILE_ENTER_FORMAT(format, ...) tmEnter(0, 0, format, __VA_ARGS__)
- #define LLPROFILE_FUNCTION tmFunction(0, 0)
- #define LLPROFILE_LEAVE() tmLeave(0)
- #define LLPROFILE_THREAD_NAME(name) tmThreadName(0, 0, name)
- #define LLPROFILE_ZONE(name) tmZone(0, 0, name)
- #define LLPROFILE_ZONE_FORMAT(format, ...) tmZone(0, 0, format, __VA_ARGS__)
-#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER
-
-//
-// exported functionality
-//
-
-extern void telemetry_startup();
-extern void telemetry_shutdown();
-extern void telemetry_update(); // called after every frame update
diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp
index 3c3c1c96ef..3ece12931c 100644
--- a/indra/newview/llteleporthistory.cpp
+++ b/indra/newview/llteleporthistory.cpp
@@ -39,6 +39,11 @@
#include "llviewerregion.h"
#include "llworldmap.h"
#include "llagentui.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
+
//////////////////////////////////////////////////////////////////////////////
// LLTeleportHistoryItem
@@ -113,6 +118,20 @@ void LLTeleportHistory::handleLoginComplete()
updateCurrentLocation(gAgent.getPositionGlobal());
}
+static void on_avatar_name_update_title(const LLAvatarName& av_name)
+{
+ if (gAgent.getRegion() && gViewerWindow && gViewerWindow->getWindow())
+ {
+ std::string region = gAgent.getRegion()->getName();
+ std::string username = av_name.getUserName();
+
+ // this first pass simply displays username and region name
+ // but could easily be extended to include other details like
+ // X/Y/Z location within a region etc.
+ std::string new_title = STRINGIZE(username << " @ " << region);
+ gViewerWindow->getWindow()->setTitle(new_title);
+ }
+}
void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)
{
@@ -174,6 +193,14 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)
if (!mGotInitialUpdate)
mGotInitialUpdate = true;
+ // update Viewer window title with username and region name
+ // if we are in "non-interactive mode" (SL-15999) or the debug
+ // setting to allow it is enabled (may be useful in other situations)
+ if (gNonInteractive || gSavedSettings.getBOOL("UpdateAppWindowTitleBar"))
+ {
+ LLAvatarNameCache::get(gAgent.getID(), boost::bind(&on_avatar_name_update_title, _2));
+ }
+
// Signal the interesting party that we've changed.
onHistoryChanged();
}
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index f64db7beb5..73a25397fd 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -314,6 +314,7 @@ private:
// Threads: Ttc
virtual void completed(bool success)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
if (worker)
{
@@ -338,6 +339,7 @@ private:
// Threads: Ttc
virtual void completed(bool success)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
if (worker)
{
@@ -362,6 +364,7 @@ private:
// Threads: Tid
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
if (worker)
{
@@ -1139,6 +1142,11 @@ void LLTextureFetchWorker::startWork(S32 param)
// Threads: Ttf
bool LLTextureFetchWorker::doWork(S32 param)
{
+ LL_PROFILE_ZONE_SCOPED;
+ if (gNonInteractive)
+ {
+ return true;
+ }
static const LLCore::HttpStatus http_not_found(HTTP_NOT_FOUND); // 404
static const LLCore::HttpStatus http_service_unavail(HTTP_SERVICE_UNAVAILABLE); // 503
static const LLCore::HttpStatus http_not_sat(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE); // 416;
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index 100d5ee713..d43da93c61 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -114,7 +114,8 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
LLToastPanel* LLToastPanel::buidPanelFromNotification(
const LLNotificationPtr& notification)
{
- LLToastPanel* res = NULL;
+ LL_PROFILE_ZONE_SCOPED
+ LLToastPanel* res = NULL;
//process tip toast panels
if ("notifytip" == notification->getType())
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 27a87ee1a0..5ebce115f6 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -54,6 +54,8 @@
// System includes
#include <iomanip> // for setprecision
+LLViewerCamera* LLSimpleton<LLViewerCamera>::sInstance = nullptr;
+
LLTrace::CountStatHandle<> LLViewerCamera::sVelocityStat("camera_velocity");
LLTrace::CountStatHandle<> LLViewerCamera::sAngularVelocityStat("camera_angular_velocity");
@@ -81,9 +83,6 @@ glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height
return glh::matrix4f(m);
}
-// Build time optimization, generate this once in .cpp file
-template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInstance();
-
LLViewerCamera::LLViewerCamera() : LLCamera()
{
calcProjection(getFar());
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index fb07a3fb2d..549778a841 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -38,25 +38,11 @@ class LLViewerObject;
const BOOL FOR_SELECTION = TRUE;
const BOOL NOT_FOR_SELECTION = FALSE;
-// Build time optimization, generate this once in .cpp file
-#ifndef LLVIEWERCAMERA_CPP
-extern template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInstance();
-#endif
-
-LL_ALIGN_PREFIX(16)
-class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera>
+class alignas(16) LLViewerCamera : public LLCamera, public LLSimpleton<LLViewerCamera>
{
- LLSINGLETON(LLViewerCamera);
+ LL_ALIGN_NEW
public:
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
+ LLViewerCamera();
typedef enum
{
@@ -141,7 +127,7 @@ protected:
S16 mZoomSubregion;
public:
-} LL_ALIGN_POSTFIX(16);
+};
#endif // LL_LLVIEWERCAMERA_H
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 89c600fc2c..9f76543647 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -107,10 +107,14 @@ static bool handleRenderAvatarMouselookChanged(const LLSD& newvalue)
static bool handleRenderFarClipChanged(const LLSD& newvalue)
{
- F32 draw_distance = (F32) newvalue.asReal();
- gAgentCamera.mDrawDistance = draw_distance;
- LLWorld::getInstance()->setLandFarClip(draw_distance);
- return true;
+ if (LLStartUp::getStartupState() >= STATE_STARTED)
+ {
+ F32 draw_distance = (F32)newvalue.asReal();
+ gAgentCamera.mDrawDistance = draw_distance;
+ LLWorld::getInstance()->setLandFarClip(draw_distance);
+ return true;
+ }
+ return false;
}
static bool handleTerrainDetailChanged(const LLSD& newvalue)
@@ -201,7 +205,6 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue)
bool handleRenderTransparentWaterChanged(const LLSD& newvalue)
{
- LLRenderTarget::sUseFBO = newvalue.asBoolean();
if (gPipeline.isInit())
{
gPipeline.updateRenderTransparentWater();
@@ -255,6 +258,14 @@ static bool handleAnisotropicChanged(const LLSD& newvalue)
return true;
}
+static bool handleVSyncChanged(const LLSD& newvalue)
+{
+#if LL_WINDOWS
+ gViewerWindow->getWindow()->toggleVSync(newvalue.asBoolean());
+#endif
+ return true;
+}
+
static bool handleVolumeLODChanged(const LLSD& newvalue)
{
LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR);
@@ -679,6 +690,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2));
gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+ gSavedSettings.getControl("RenderVSyncEnable")->getSignal()->connect(boost::bind(&handleVSyncChanged, _2));
gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
gSavedSettings.getControl("RenderDebugGL")->getSignal()->connect(boost::bind(&handleRenderDebugGLChanged, _2));
gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));
diff --git a/indra/newview/llviewercontrollistener.cpp b/indra/newview/llviewercontrollistener.cpp
index 3443bb644a..8820f9ec56 100644
--- a/indra/newview/llviewercontrollistener.cpp
+++ b/indra/newview/llviewercontrollistener.cpp
@@ -127,7 +127,7 @@ struct Info
LLEventAPI::Response response;
std::string groupname;
- LLControlGroup* group;
+ LLControlGroup::ptr_t group;
std::string key;
LLControlVariable* control;
};
@@ -187,7 +187,7 @@ void LLViewerControlListener::groups(LLSD const & request)
struct CollectVars: public LLControlGroup::ApplyFunctor
{
- CollectVars(LLControlGroup* g):
+ CollectVars(LLControlGroup::ptr_t g):
mGroup(g)
{}
@@ -200,7 +200,7 @@ struct CollectVars: public LLControlGroup::ApplyFunctor
("comment", control->getComment()));
}
- LLControlGroup* mGroup;
+ LLControlGroup::ptr_t mGroup;
LLSD vars;
};
@@ -210,7 +210,7 @@ void LLViewerControlListener::vars(LLSD const & request)
// control name.
Response response(LLSD(), request);
std::string groupname(request["group"]);
- LLControlGroup* group(LLControlGroup::getInstance(groupname));
+ auto group(LLControlGroup::getInstance(groupname));
if (! group)
{
return response.error(STRINGIZE("Unrecognized group '" << groupname << "'"));
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 109dc93261..6368286f6e 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -124,7 +124,8 @@ void display_startup()
if ( !gViewerWindow
|| !gViewerWindow->getActive()
|| !gViewerWindow->getWindow()->getVisible()
- || gViewerWindow->getWindow()->getMinimized() )
+ || gViewerWindow->getWindow()->getMinimized()
+ || gNonInteractive)
{
return;
}
@@ -208,9 +209,11 @@ void display_update_camera()
// Write some stats to LL_INFOS()
void display_stats()
{
+ LL_PROFILE_ZONE_SCOPED
F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency");
if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq)
{
+ LL_PROFILE_ZONE_NAMED("DS - FPS");
F32 fps = gRecentFrameCount / fps_log_freq;
LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL;
gRecentFrameCount = 0;
@@ -219,6 +222,7 @@ void display_stats()
F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency");
if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq)
{
+ LL_PROFILE_ZONE_NAMED("DS - Memory");
gMemoryAllocated = U64Bytes(LLMemory::getCurrentRSS());
U32Megabytes memory = gMemoryAllocated;
LL_INFOS() << "MEMORY: " << memory << LL_ENDL;
@@ -228,6 +232,7 @@ void display_stats()
F32 asset_storage_log_freq = gSavedSettings.getF32("AssetStorageLogFrequency");
if (asset_storage_log_freq > 0.f && gAssetStorageLogTime.getElapsedTimeF32() >= asset_storage_log_freq)
{
+ LL_PROFILE_ZONE_NAMED("DS - Asset Storage");
gAssetStorageLogTime.reset();
gAssetStorage->logAssetStorageInfo();
}
@@ -309,7 +314,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
// Attempting to draw into a minimized window causes a GL error. JC
if ( !gViewerWindow->getActive()
|| !gViewerWindow->getWindow()->getVisible()
- || gViewerWindow->getWindow()->getMinimized() )
+ || gViewerWindow->getWindow()->getMinimized()
+ || gNonInteractive)
{
// Clean up memory the pools may have allocated
if (rebuild)
@@ -630,6 +636,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (!gDisconnected)
{
+ LL_PROFILE_ZONE_NAMED("display - 1");
LLAppViewer::instance()->pingMainloopTimeout("Display:Update");
if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
{ //don't draw hud objects in this frame
@@ -722,6 +729,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
{
+ LL_PROFILE_ZONE_NAMED("display - 2")
if (gResizeScreenTexture)
{
gResizeScreenTexture = FALSE;
@@ -777,6 +785,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
//if (!for_snapshot)
{
+ LL_PROFILE_ZONE_NAMED("display - 3")
LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
gPipeline.generateHighlight(*LLViewerCamera::getInstance());
@@ -800,13 +809,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_CLASS);
- LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
- LLTrace::CountStatHandle<>* angular_velocity_stat = LLViewerCamera::getAngularVelocityStat();
- LLViewerTexture::updateClass(LLTrace::get_frame_recording().getPeriodMeanPerSec(*velocity_stat),
- LLTrace::get_frame_recording().getPeriodMeanPerSec(*angular_velocity_stat));
+ LLViewerTexture::updateClass();
}
-
{
LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_BUMP);
gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first.
@@ -825,7 +830,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLImageGL::deleteDeadTextures();
stop_glerror();
}*/
- }
+ }
LLGLState::checkStates();
LLGLState::checkClientArrays();
@@ -840,6 +845,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
//
LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort");
{
+ LL_PROFILE_ZONE_NAMED("display - 3")
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
stop_glerror();
@@ -948,6 +954,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
&& !gRestoreGL)
{
+ LL_PROFILE_ZONE_NAMED("display - 4")
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
if (gSavedSettings.getBOOL("RenderDepthPrePass") && LLGLSLShader::sNoFixedFunction)
@@ -1259,7 +1266,7 @@ bool setup_hud_matrices(const LLRect& screen_region)
void render_ui(F32 zoom_factor, int subfield)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
LLGLState::checkStates();
@@ -1274,7 +1281,6 @@ void render_ui(F32 zoom_factor, int subfield)
if(LLSceneMonitor::getInstance()->needsUpdate())
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_SCENE_MON);
gGL.pushMatrix();
gViewerWindow->setup2DRender();
LLSceneMonitor::getInstance()->compare();
@@ -1282,55 +1288,61 @@ void render_ui(F32 zoom_factor, int subfield)
gGL.popMatrix();
}
- // Finalize scene
- gPipeline.renderFinalize();
+ // Finalize scene
+ gPipeline.renderFinalize();
- LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
- render_hud_elements();
- render_hud_attachments();
-
- LLGLSDefault gls_default;
- LLGLSUIDefault gls_ui;
{
- gPipeline.disableLights();
- }
+ // SL-15709
+ // NOTE: Tracy only allows one ZoneScoped per function.
+ // Solutions are:
+ // 1. Use a new scope
+ // 2. Use named zones
+ // 3. Use transient zones
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
+ render_hud_elements();
+ render_hud_attachments();
+
+ LLGLSDefault gls_default;
+ LLGLSUIDefault gls_ui;
+ {
+ gPipeline.disableLights();
+ }
- {
- gGL.color4f(1,1,1,1);
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
{
- if (!gDisconnected)
+ gGL.color4f(1,1,1,1);
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
- render_ui_3d();
+ if (!gDisconnected)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
+ render_ui_3d();
+ LLGLState::checkStates();
+ }
+ else
+ {
+ render_disconnected_background();
+ }
+
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
+ render_ui_2d();
LLGLState::checkStates();
}
- else
- {
- render_disconnected_background();
- }
+ gGL.flush();
- LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
- render_ui_2d();
- LLGLState::checkStates();
- }
- gGL.flush();
-
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_DEBUG_TEXT);
gViewerWindow->setup2DRender();
gViewerWindow->updateDebugText();
gViewerWindow->drawDebugText();
+
+ LLVertexBuffer::unbind();
}
- LLVertexBuffer::unbind();
- }
+ if (!gSnapshot)
+ {
+ set_current_modelview(saved_view);
+ gGL.popMatrix();
+ }
- if (!gSnapshot)
- {
- set_current_modelview(saved_view);
- gGL.popMatrix();
- }
+ } // Tracy integration
}
static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 5a05f89758..98b76328de 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -192,6 +192,10 @@ LLFloaterOpenHandler gFloaterOpenHandler;
void LLViewerFloaterReg::registerFloaters()
{
+ if (gNonInteractive)
+ {
+ return;
+ }
// *NOTE: Please keep these alphabetized for easier merges
LLFloaterAboutUtil::registerFloater();
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 63ad708e59..3e385a46e4 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -362,7 +362,6 @@ void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32
//-----------------------------------------------------------------------------
// updateFaceData()
//-----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_AVATAR_FACE("Avatar Face");
void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
{
@@ -383,9 +382,8 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
// since mMesh is being copied into mVertexBuffer every frame
return;
}
-
-
- LL_RECORD_BLOCK_TIME(FTM_AVATAR_FACE);
+
+ LL_PROFILE_ZONE_SCOPED;
LLStrider<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index d0cf8ea407..af8db76add 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1216,7 +1216,7 @@ LLCore::HttpHeaders::ptr_t LLViewerMedia::getHttpHeaders()
/////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMedia::setOpenIDCookie(const std::string& url)
{
- if(!mOpenIDCookie.empty())
+ if(!gNonInteractive && !mOpenIDCookie.empty())
{
std::string profileUrl = getProfileURL("");
@@ -1693,6 +1693,11 @@ void LLViewerMediaImpl::setMediaType(const std::string& media_type)
/*static*/
LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, F64 zoom_factor, const std::string target, bool clean_browser)
{
+ if (gNonInteractive)
+ {
+ return NULL;
+ }
+
std::string plugin_basename = LLMIMETypes::implType(media_type);
LLPluginClassMedia* media_source = NULL;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 635b731193..3f8398d93a 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -8328,6 +8328,7 @@ class LLViewHighlightTransparent : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha;
+ gPipeline.resetVertexBuffers();
return true;
}
};
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 9d85586dae..e5d81032c5 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2220,11 +2220,9 @@ protected:
}
};
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMPROVED_IM("Process IM");
-
void process_improved_im(LLMessageSystem *msg, void **user_data)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMPROVED_IM);
+ LL_PROFILE_ZONE_SCOPED;
LLUUID from_id;
BOOL from_group;
@@ -2424,6 +2422,10 @@ void translateFailure(LLChat chat, LLSD toastArgs, int status, const std::string
void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
{
+ if (gNonInteractive)
+ {
+ return;
+ }
LLChat chat;
std::string mesg;
std::string from_name;
@@ -3264,10 +3266,9 @@ const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f; // ~= 2.5 degrees -- if its less th
const F32 MAX_HEAD_ROT_QDOT = 0.99999f; // ~= 0.5 degrees -- if its greater than this then no need to update head_rot
// between these values we delay the updates (but no more than one second)
-static LLTrace::BlockTimerStatHandle FTM_AGENT_UPDATE_SEND("Send Message");
-
void send_agent_update(BOOL force_send, BOOL send_reliable)
{
+ LL_PROFILE_ZONE_SCOPED;
if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
{
// We don't care if they want to send an agent update, they're not allowed to until the simulator
@@ -3448,7 +3449,6 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
}
*/
- LL_RECORD_BLOCK_TIME(FTM_AGENT_UPDATE_SEND);
// Build the message
msg->newMessageFast(_PREHASH_AgentUpdate);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -3698,11 +3698,9 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_
}
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Kill Objects");
-
void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_OBJECTS);
+ LL_PROFILE_ZONE_SCOPED;
LLUUID id;
@@ -3984,8 +3982,8 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)
F32 stat_value;
msg->getU32("Stat", "StatID", stat_id, i);
msg->getF32("Stat", "StatValue", stat_value, i);
- LLStatViewer::SimMeasurementSampler* measurementp = LLStatViewer::SimMeasurementSampler::getInstance((ESimStatID)stat_id);
-
+ auto measurementp = LLStatViewer::SimMeasurementSampler::getInstance((ESimStatID)stat_id);
+
if (measurementp )
{
measurementp->sample(stat_value);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index b88baf6aa7..c671aec224 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -107,6 +107,7 @@
#include "llcleanup.h"
#include "llcallstack.h"
#include "llmeshrepository.h"
+#include "llgl.h"
//#define DEBUG_UPDATE_TYPE
@@ -145,21 +146,35 @@ const S32 MAX_OBJECT_BINARY_DATA_SIZE = 60 + 16;
const F64 INVENTORY_UPDATE_WAIT_TIME_DESYNC = 5; // seconds
const F64 INVENTORY_UPDATE_WAIT_TIME_OUTDATED = 1;
-static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
-
// static
LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, S32 flags)
{
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS("ObjectUpdate") << "creating " << id << LL_ENDL;
dumpStack("ObjectUpdateStack");
LLViewerObject *res = NULL;
- LL_RECORD_BLOCK_TIME(FTM_CREATE_OBJECT);
-
+
+ if (gNonInteractive
+ && pcode != LL_PCODE_LEGACY_AVATAR
+ && pcode != LL_VO_SURFACE_PATCH
+ && pcode != LL_VO_WATER
+ && pcode != LL_VO_VOID_WATER
+ && pcode != LL_VO_WL_SKY
+ && pcode != LL_VO_SKY
+ && pcode != LL_VO_GROUND
+ && pcode != LL_VO_PART_GROUP
+ )
+ {
+ return res;
+ }
switch (pcode)
{
case LL_PCODE_VOLUME:
- res = new LLVOVolume(id, pcode, regionp); break;
+ {
+ res = new LLVOVolume(id, pcode, regionp); break;
+ break;
+ }
case LL_PCODE_LEGACY_AVATAR:
{
if (id == gAgentID)
@@ -235,8 +250,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
}
LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global)
-: LLTrace::MemTrackable<LLViewerObject>("LLViewerObject"),
- LLPrimitive(),
+: LLPrimitive(),
mChildList(),
mID(id),
mLocalID(0),
@@ -2500,9 +2514,6 @@ void LLViewerObject::loadFlags(U32 flags)
void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &frame_time)
{
- //static LLTrace::BlockTimerStatHandle ftm("Viewer Object");
- //LL_RECORD_BLOCK_TIME(ftm);
-
if (!mDead)
{
if (!mStatic && sVelocityInterpolate && !isSelected())
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 250c4ac328..bef8e3e7e3 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -110,8 +110,7 @@ struct PotentialReturnableObject
class LLViewerObject
: public LLPrimitive,
public LLRefCount,
- public LLGLUpdate,
- public LLTrace::MemTrackable<LLViewerObject>
+ public LLGLUpdate
{
protected:
virtual ~LLViewerObject(); // use unref()
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 63e48d1dd0..971a355a65 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -80,6 +80,7 @@
#include "llfloaterperms.h"
#include "llvocache.h"
#include "llcorehttputil.h"
+#include "llstartup.h"
#include <algorithm>
#include <iterator>
@@ -168,6 +169,8 @@ U64 LLViewerObjectList::getIndex(const U32 local_id,
BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)
{
+ LL_PROFILE_ZONE_SCOPED
+
if(objectp && objectp->getRegion())
{
U32 local_id = objectp->mLocalID;
@@ -303,9 +306,11 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Objects");
LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp)
{
+ LL_PROFILE_ZONE_SCOPED
+
LLDataPacker *cached_dpp = entry->getDP();
- if (!cached_dpp)
+ if (!cached_dpp || gNonInteractive)
{
return NULL; //nothing cached.
}
@@ -844,10 +849,10 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
LLVOAvatar::cullAvatarsByPixelArea();
}
-static LLTrace::BlockTimerStatHandle FTM_IDLE_COPY("Idle Copy");
-
void LLViewerObjectList::update(LLAgent &agent)
{
+ LL_PROFILE_ZONE_SCOPED
+
// Update globals
LLViewerObject::setVelocityInterpolate( gSavedSettings.getBOOL("VelocityInterpolate") );
LLViewerObject::setPingInterpolate( gSavedSettings.getBOOL("PingInterpolate") );
@@ -899,8 +904,6 @@ void LLViewerObjectList::update(LLAgent &agent)
U32 idle_count = 0;
{
- LL_RECORD_BLOCK_TIME(FTM_IDLE_COPY);
-
for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
active_iter != mActiveObjects.end(); active_iter++)
{
@@ -1293,6 +1296,8 @@ void LLViewerObjectList::clearDebugText()
void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
{
+ LL_PROFILE_ZONE_SCOPED
+
bool new_dead_object = true;
if (mDeadObjects.find(objectp->mID) != mDeadObjects.end())
{
@@ -1343,11 +1348,9 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
}
}
-static LLTrace::BlockTimerStatHandle FTM_REMOVE_DRAWABLE("Remove Drawable");
-
void LLViewerObjectList::removeDrawable(LLDrawable* drawablep)
{
- LL_RECORD_BLOCK_TIME(FTM_REMOVE_DRAWABLE);
+ LL_PROFILE_ZONE_SCOPED;
if (!drawablep)
{
@@ -1523,6 +1526,8 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp)
void LLViewerObjectList::updateActive(LLViewerObject *objectp)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (objectp->isDead())
{
return; // We don't update dead objects!
@@ -1634,12 +1639,9 @@ void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id)
mPendingPhysicsFlags.erase(object_id);
}
-static LLTrace::BlockTimerStatHandle FTM_SHIFT_OBJECTS("Shift Objects");
-static LLTrace::BlockTimerStatHandle FTM_PIPELINE_SHIFT("Pipeline Shift");
-static LLTrace::BlockTimerStatHandle FTM_REGION_SHIFT("Region Shift");
-
void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
{
+ LL_PROFILE_ZONE_SCOPED;
// This is called when we shift our origin when we cross region boundaries...
// We need to update many object caches, I'll document this more as I dig through the code
// cleaning things out...
@@ -1649,7 +1651,6 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
return;
}
- LL_RECORD_BLOCK_TIME(FTM_SHIFT_OBJECTS);
LLViewerObject *objectp;
for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
@@ -1667,16 +1668,10 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
}
}
- {
- LL_RECORD_BLOCK_TIME(FTM_PIPELINE_SHIFT);
gPipeline.shiftObjects(offset);
- }
-
- {
- LL_RECORD_BLOCK_TIME(FTM_REGION_SHIFT);
+
LLWorld::getInstance()->shiftRegions(offset);
}
-}
void LLViewerObjectList::repartitionObjects()
{
@@ -1843,6 +1838,8 @@ void LLViewerObjectList::renderObjectBounds(const LLVector3 &center)
void LLViewerObjectList::generatePickList(LLCamera &camera)
{
+ LL_PROFILE_ZONE_SCOPED
+
LLViewerObject *objectp;
S32 i;
// Reset all of the GL names to zero.
@@ -2051,7 +2048,6 @@ LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, L
LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp,
const LLUUID &uuid, const U32 local_id, const LLHost &sender)
{
-
LLUUID fullid;
if (uuid == LLUUID::null)
{
@@ -2104,6 +2100,8 @@ LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCod
S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const
{
+ LL_PROFILE_ZONE_SCOPED
+
LLViewerObject *objectp;
S32 num_refs = 0;
@@ -2167,6 +2165,8 @@ void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip
void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (objectp->isDead())
{
LL_WARNS() << "Trying to find orphans for dead obj " << objectp->mID
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 6365df09e1..868cf75d11 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -231,8 +231,7 @@ S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LL
//class LLViewerOctreeEntry definitions
//-----------------------------------------------------------------------------------
LLViewerOctreeEntry::LLViewerOctreeEntry()
-: LLTrace::MemTrackable<LLViewerOctreeEntry, 16>("LLViewerOctreeEntry"),
- mGroup(NULL),
+: mGroup(NULL),
mBinRadius(0.f),
mBinIndex(-1),
mVisible(0)
@@ -458,8 +457,7 @@ LLViewerOctreeGroup::~LLViewerOctreeGroup()
}
LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node)
-: LLTrace::MemTrackable<LLViewerOctreeGroup, 16>("LLViewerOctreeGroup"),
- mOctreeNode(node),
+: mOctreeNode(node),
mAnyVisible(0),
mState(CLEAN)
{
@@ -545,6 +543,7 @@ void LLViewerOctreeGroup::unbound()
//virtual
void LLViewerOctreeGroup::rebound()
{
+ LL_PROFILE_ZONE_SCOPED;
if (!isDirty())
{
return;
@@ -1039,11 +1038,9 @@ void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode)
}
}
-static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_READBACK("Readback Occlusion");
-static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_WAIT("Occlusion Wait");
-
BOOL LLOcclusionCullingGroup::earlyFail(LLCamera* camera, const LLVector4a* bounds)
{
+ LL_PROFILE_ZONE_SCOPED;
if (camera->getOrigin().isExactlyZero())
{
return FALSE;
@@ -1094,7 +1091,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
{
if (LLPipeline::sUseOcclusion > 1)
{
- LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_READBACK);
+ LL_PROFILE_ZONE_SCOPED;
LLOcclusionCullingGroup* parent = (LLOcclusionCullingGroup*)getParent();
if (parent && parent->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
{ //if the parent has been marked as occluded, the child is implicitly occluded
@@ -1106,19 +1103,8 @@ void LLOcclusionCullingGroup::checkOcclusion()
GLuint available = 0;
if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
+ LL_PROFILE_ZONE_NAMED("co - query available")
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
-
- static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion", true);
-
- if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
- { //query was issued last frame, wait until it's available
- S32 max_loop = 1024;
- LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_WAIT);
- while (!available && max_loop-- > 0)
- {
- glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
- }
- }
}
else
{
@@ -1130,6 +1116,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
GLuint res = 1;
if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
+ LL_PROFILE_ZONE_NAMED("co - query result")
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res);
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
@@ -1173,19 +1160,9 @@ void LLOcclusionCullingGroup::checkOcclusion()
}
}
-static LLTrace::BlockTimerStatHandle FTM_PUSH_OCCLUSION_VERTS("Push Occlusion");
-static LLTrace::BlockTimerStatHandle FTM_SET_OCCLUSION_STATE("Occlusion State");
-static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail");
-static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_ALLOCATE("Allocate");
-static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_BUILD("Build");
-static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_BEGIN_QUERY("Begin Query");
-static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_END_QUERY("End Query");
-static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_SET_BUFFER("Set Buffer");
-static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_DRAW_WATER("Draw Water");
-static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_DRAW("Draw");
-
void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* shift)
{
+ LL_PROFILE_ZONE_SCOPED;
if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1)
{
//move mBounds to the agent space if necessary
@@ -1206,7 +1183,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
// Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension
if (earlyFail(camera, bounds))
{
- LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_EARLY_FAIL);
+ LL_PROFILE_ZONE_NAMED("doOcclusion - early fail");
setOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY);
assert_states_valid(this);
clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
@@ -1217,11 +1194,10 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY))
{
{ //no query pending, or previous query to be discarded
- LL_RECORD_BLOCK_TIME(FTM_RENDER_OCCLUSION);
+ LL_PROFILE_ZONE_NAMED("doOcclusion - render");
if (!mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
- LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_ALLOCATE);
mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName();
}
@@ -1246,15 +1222,12 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
add(sOcclusionQueries, 1);
{
- LL_RECORD_BLOCK_TIME(FTM_PUSH_OCCLUSION_VERTS);
+ LL_PROFILE_ZONE_NAMED("doOcclusion - push");
//store which frame this query was issued on
mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount;
- {
- LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_BEGIN_QUERY);
- glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
- }
+ glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
llassert(shader);
@@ -1266,7 +1239,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
{
- LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_DRAW_WATER);
+ LL_PROFILE_ZONE_NAMED("doOcclusion - draw water");
LLGLSquashToFarClip squash;
if (camera->getOrigin().isExactlyZero())
@@ -1281,7 +1254,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
}
else
{
- LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_DRAW);
+ LL_PROFILE_ZONE_NAMED("doOcclusion - draw");
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
@@ -1292,17 +1265,13 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, bounds[0]));
}
}
-
-
- {
- LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_END_QUERY);
- glEndQueryARB(mode);
- }
+
+ glEndQueryARB(mode);
}
}
{
- LL_RECORD_BLOCK_TIME(FTM_SET_OCCLUSION_STATE);
+ LL_PROFILE_ZONE_NAMED("doOcclusion - set state");
setOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING);
clearOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY);
}
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index 219ec7e8da..11ba7e4f1e 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -71,8 +71,9 @@ S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVe
//defines data needed for octree of an entry
//LL_ALIGN_PREFIX(16)
-class LLViewerOctreeEntry : public LLRefCount, public LLTrace::MemTrackable<LLViewerOctreeEntry, 16>
+class LLViewerOctreeEntry : public LLRefCount
{
+ LL_ALIGN_NEW
friend class LLViewerOctreeEntryData;
public:
@@ -178,8 +179,9 @@ protected:
//defines an octree group for an octree node, which contains multiple entries.
//LL_ALIGN_PREFIX(16)
class LLViewerOctreeGroup
-: public LLOctreeListener<LLViewerOctreeEntry>, public LLTrace::MemTrackable<LLViewerOctreeGroup, 16>
+: public LLOctreeListener<LLViewerOctreeEntry>
{
+ LL_ALIGN_NEW
friend class LLViewerOctreeCull;
protected:
virtual ~LLViewerOctreeGroup();
@@ -201,7 +203,6 @@ public:
LLViewerOctreeGroup(OctreeNode* node);
LLViewerOctreeGroup(const LLViewerOctreeGroup& rhs)
- : LLTrace::MemTrackable<LLViewerOctreeGroup, 16>("LLViewerOctreeGroup")
{
*this = rhs;
}
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 7c3dd00e1a..02f7bbeed8 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -847,6 +847,7 @@ void LLViewerParcelOverlay::setDirty()
void LLViewerParcelOverlay::updateGL()
{
+ LL_PROFILE_ZONE_SCOPED
updateOverlayTexture();
}
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 945b51d819..b34c5b1188 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -384,7 +384,7 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)
S32 LLViewerShaderMgr::getShaderLevel(S32 type)
{
- return LLPipeline::sDisableShaders ? 0 : mShaderLevel[type];
+ return mShaderLevel[type];
}
//============================================================================
@@ -400,15 +400,6 @@ void LLViewerShaderMgr::setShaders()
return;
}
- if (!gGLManager.mHasShaderObjects
- || !gGLManager.mHasVertexShader
- || !gGLManager.mHasFragmentShader)
- {
- // Viewer will show 'hardware requirements' warning later
- LL_INFOS("ShaderLoading") << "Shaders not supported" << LL_ENDL;
- return;
- }
-
static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) max_texture_index), 1);
@@ -433,7 +424,7 @@ void LLViewerShaderMgr::setShaders()
initAttribsAndUniforms();
gPipeline.releaseGLBuffers();
- LLPipeline::sWaterReflections = gGLManager.mHasCubeMap;
+ LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && LLPipeline::sRenderTransparentWater;
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
LLPipeline::updateRenderDeferred();
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 314c1a1f1e..1fda2fb20e 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -183,8 +183,9 @@ SimMeasurement<F64Kilobytes > SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_S
SimMeasurement<F64Megabytes > SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY);
LLTrace::SampleStatHandle<F64Milliseconds > FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"),
- FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"),
- SIM_PING("simpingstat");
+ FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"),
+ FRAMETIME("frametime", "Measured frame time"),
+ SIM_PING("simpingstat");
LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Meters> > AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections");
@@ -261,8 +262,11 @@ void LLViewerStats::updateFrameStats(const F64Seconds time_diff)
// new "stutter" meter
add(LLStatViewer::FRAMETIME_DOUBLED, time_diff >= 2.0 * mLastTimeDiff ? 1 : 0);
+ sample(LLStatViewer::FRAMETIME, time_diff);
+
// old stats that were never really used
- sample(LLStatViewer::FRAMETIME_JITTER, F64Milliseconds (mLastTimeDiff - time_diff));
+ F64Seconds jit = (F64Seconds) std::fabs((mLastTimeDiff - time_diff));
+ sample(LLStatViewer::FRAMETIME_JITTER, jit);
F32Seconds average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
sample(LLStatViewer::FRAMETIME_SLEW, F64Milliseconds (average_frametime - time_diff));
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 04870e0c26..ac8eccc0ca 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -218,8 +218,8 @@ extern SimMeasurement<F64Megabytes > SIM_PHYSICS_MEM;
extern LLTrace::SampleStatHandle<F64Milliseconds > FRAMETIME_JITTER,
- FRAMETIME_SLEW,
- SIM_PING;
+ FRAMETIME_SLEW,
+ SIM_PING;
extern LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Meters> > AGENT_POSITION_SNAP;
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 7fbc4d789b..e6ac701644 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -184,6 +184,7 @@ void LLViewerTextureManager::findFetchedTextures(const LLUUID& id, std::vector<L
void LLViewerTextureManager::findTextures(const LLUUID& id, std::vector<LLViewerTexture*> &output)
{
+ LL_PROFILE_ZONE_SCOPED;
std::vector<LLViewerFetchedTexture*> fetched_output;
gTextureList.findTexturesByID(id, fetched_output);
std::vector<LLViewerFetchedTexture*>::iterator iter = fetched_output.begin();
@@ -208,6 +209,7 @@ void LLViewerTextureManager::findTextures(const LLUUID& id, std::vector<LLViewe
LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID& id, S32 tex_type)
{
+ LL_PROFILE_ZONE_SCOPED;
return gTextureList.findImage(id, (ETexListType)tex_type);
}
@@ -479,11 +481,10 @@ const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f;
F32 texmem_lower_bound_scale = 0.85f;
F32 texmem_middle_bound_scale = 0.925f;
-static LLTrace::BlockTimerStatHandle FTM_TEXTURE_MEMORY_CHECK("Memory Check");
-
//static
bool LLViewerTexture::isMemoryForTextureLow()
{
+ LL_PROFILE_ZONE_SCOPED;
// Note: we need to figure out a better source for 'min' values,
// what is free for low end at minimal settings is 'nothing left'
// for higher end gpus at high settings.
@@ -500,6 +501,7 @@ bool LLViewerTexture::isMemoryForTextureLow()
//static
bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
{
+ LL_PROFILE_ZONE_SCOPED;
const S32Megabytes DESIRED_FREE_TEXTURE_MEMORY(50);
const S32Megabytes DESIRED_FREE_MAIN_MEMORY(200);
@@ -513,6 +515,7 @@ bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
//static
void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical)
{
+ LL_PROFILE_ZONE_SCOPED;
static LLFrameTimer timer;
static S32Megabytes gpu_res = S32Megabytes(S32_MAX);
static S32Megabytes physical_res = S32Megabytes(S32_MAX);
@@ -525,48 +528,42 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p
}
timer.reset();
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK);
-
- if (gGLManager.mHasATIMemInfo)
{
- S32 meminfo[4];
- glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
- gpu_res = (S32Megabytes)meminfo[0];
+ if (gGLManager.mHasATIMemInfo)
+ {
+ S32 meminfo[4];
+ glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
+ gpu_res = (S32Megabytes)meminfo[0];
- //check main memory, only works for windows.
- LLMemory::updateMemoryInfo();
- physical_res = LLMemory::getAvailableMemKB();
- }
- else if (gGLManager.mHasNVXMemInfo)
- {
- S32 free_memory;
- glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
- gpu_res = (S32Megabytes)(free_memory / 1024);
- }
+ //check main memory, only works for windows.
+ LLMemory::updateMemoryInfo();
+ physical_res = LLMemory::getAvailableMemKB();
+ }
+ else if (gGLManager.mHasNVXMemInfo)
+ {
+ S32 free_memory;
+ glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
+ gpu_res = (S32Megabytes)(free_memory / 1024);
+ }
- gpu = gpu_res;
- physical = physical_res;
+ gpu = gpu_res;
+ physical = physical_res;
+ }
}
-static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_MEDIA("Media");
-static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_TEST("Test");
-
//static
-void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity)
+void LLViewerTexture::updateClass()
{
+ LL_PROFILE_ZONE_SCOPED;
sCurrentTime = gFrameTimeSeconds;
LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
if (tester)
{
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_UPDATE_TEST);
tester->update();
}
- {
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_UPDATE_MEDIA);
- LLViewerMediaTexture::updateClass();
- }
+ LLViewerMediaTexture::updateClass();
sBoundTextureMemory = LLImageGL::sBoundTextureMemory;
sTotalTextureMemory = LLImageGL::sGlobalTextureMemory;
@@ -703,6 +700,7 @@ void LLViewerTexture::cleanup()
void LLViewerTexture::notifyAboutCreatingTexture()
{
+ LL_PROFILE_ZONE_SCOPED;
for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
for(U32 f = 0; f < mNumFaces[ch]; f++)
@@ -714,6 +712,7 @@ void LLViewerTexture::notifyAboutCreatingTexture()
void LLViewerTexture::notifyAboutMissingAsset()
{
+ LL_PROFILE_ZONE_SCOPED;
for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
for(U32 f = 0; f < mNumFaces[ch]; f++)
@@ -726,6 +725,7 @@ void LLViewerTexture::notifyAboutMissingAsset()
// virtual
void LLViewerTexture::dump()
{
+ LL_PROFILE_ZONE_SCOPED;
LLGLTexture::dump();
LL_INFOS() << "LLViewerTexture"
@@ -761,6 +761,7 @@ bool LLViewerTexture::isActiveFetching()
bool LLViewerTexture::bindDebugImage(const S32 stage)
{
+ LL_PROFILE_ZONE_SCOPED;
if (stage < 0) return false;
bool res = true;
@@ -779,6 +780,7 @@ bool LLViewerTexture::bindDebugImage(const S32 stage)
bool LLViewerTexture::bindDefaultImage(S32 stage)
{
+ LL_PROFILE_ZONE_SCOPED;
if (stage < 0) return false;
bool res = true;
@@ -821,6 +823,7 @@ void LLViewerTexture::forceImmediateUpdate()
void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const
{
+ LL_PROFILE_ZONE_SCOPED;
if(needs_gltexture)
{
mNeedsGLTexture = TRUE;
@@ -831,14 +834,14 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
{
//flag to reset the values because the old values are used.
resetMaxVirtualSizeResetCounter();
- mMaxVirtualSize = virtual_size;
- mAdditionalDecodePriority = 0.f;
+ mMaxVirtualSize = virtual_size;
+ mAdditionalDecodePriority = 0.f;
mNeedsGLTexture = needs_gltexture;
}
else if (virtual_size > mMaxVirtualSize)
{
mMaxVirtualSize = virtual_size;
- }
+ }
}
void LLViewerTexture::resetTextureStats()
@@ -863,6 +866,7 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
//virtual
void LLViewerTexture::addFace(U32 ch, LLFace* facep)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
if(mNumFaces[ch] >= mFaceList[ch].size())
@@ -878,6 +882,7 @@ void LLViewerTexture::addFace(U32 ch, LLFace* facep)
//virtual
void LLViewerTexture::removeFace(U32 ch, LLFace* facep)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
if(mNumFaces[ch] > 1)
@@ -918,6 +923,7 @@ S32 LLViewerTexture::getNumFaces(U32 ch) const
//virtual
void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep)
{
+ LL_PROFILE_ZONE_SCOPED;
if (mNumVolumes[ch] >= mVolumeList[ch].size())
{
mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1);
@@ -931,6 +937,7 @@ void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep)
//virtual
void LLViewerTexture::removeVolume(U32 ch, LLVOVolume* volumep)
{
+ LL_PROFILE_ZONE_SCOPED;
if (mNumVolumes[ch] > 1)
{
S32 index = volumep->getIndexInTex(ch);
@@ -954,6 +961,7 @@ S32 LLViewerTexture::getNumVolumes(U32 ch) const
void LLViewerTexture::reorganizeFaceList()
{
+ LL_PROFILE_ZONE_SCOPED;
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
@@ -977,6 +985,7 @@ void LLViewerTexture::reorganizeFaceList()
void LLViewerTexture::reorganizeVolumeList()
{
+ LL_PROFILE_ZONE_SCOPED;
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
@@ -1179,6 +1188,7 @@ FTType LLViewerFetchedTexture::getFTType() const
void LLViewerFetchedTexture::cleanup()
{
+ LL_PROFILE_ZONE_SCOPED;
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
iter != mLoadedCallbackList.end(); )
{
@@ -1204,6 +1214,7 @@ void LLViewerFetchedTexture::cleanup()
//access the fast cache
void LLViewerFetchedTexture::loadFromFastCache()
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInFastCacheList)
{
return; //no need to access the fast cache.
@@ -1349,6 +1360,7 @@ void LLViewerFetchedTexture::dump()
// ONLY called from LLViewerFetchedTextureList
void LLViewerFetchedTexture::destroyTexture()
{
+ LL_PROFILE_ZONE_SCOPED;
if(LLImageGL::sGlobalTextureMemory < sMaxDesiredTextureMem * 0.95f)//not ready to release unused memory.
{
return ;
@@ -1365,6 +1377,7 @@ void LLViewerFetchedTexture::destroyTexture()
void LLViewerFetchedTexture::addToCreateTexture()
{
+ LL_PROFILE_ZONE_SCOPED;
bool force_update = false;
if (getComponents() != mRawImage->getComponents())
{
@@ -1406,6 +1419,7 @@ void LLViewerFetchedTexture::addToCreateTexture()
}
else
{
+ LL_PROFILE_ZONE_SCOPED;
#if 1
//
//if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up,
@@ -1450,99 +1464,100 @@ void LLViewerFetchedTexture::addToCreateTexture()
}
}
#endif
- mNeedsCreateTexture = TRUE;
- gTextureList.mCreateTextureList.insert(this);
- }
+ scheduleCreateTexture();
+ }
return;
}
// ONLY called from LLViewerTextureList
-BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
+BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/)
{
- if (!mNeedsCreateTexture)
- {
- destroyRawImage();
- return FALSE;
- }
- mNeedsCreateTexture = FALSE;
- if (mRawImage.isNull())
- {
- LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL;
- }
- if (mRawImage->isBufferInvalid())
- {
- LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL;
- destroyRawImage();
- return FALSE;
- }
-// LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
-// mRawDiscardLevel,
-// mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
-// << mID.getString() << LL_ENDL;
- BOOL res = TRUE;
+ LL_PROFILE_ZONE_SCOPED;
+ if (!mNeedsCreateTexture)
+ {
+ destroyRawImage();
+ return FALSE;
+ }
+ mNeedsCreateTexture = FALSE;
- // store original size only for locally-sourced images
- if (mUrl.compare(0, 7, "file://") == 0)
- {
- mOrigWidth = mRawImage->getWidth();
- mOrigHeight = mRawImage->getHeight();
+ if (mRawImage.isNull())
+ {
+ LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL;
+ }
+ if (mRawImage->isBufferInvalid())
+ {
+ LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL;
+ destroyRawImage();
+ return FALSE;
+ }
+ // LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
+ // mRawDiscardLevel,
+ // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
+ // << mID.getString() << LL_ENDL;
+ BOOL res = TRUE;
+
+ // store original size only for locally-sourced images
+ if (mUrl.compare(0, 7, "file://") == 0)
+ {
+ mOrigWidth = mRawImage->getWidth();
+ mOrigHeight = mRawImage->getHeight();
// This is only safe because it's a local image and fetcher doesn't use raw data
// from local images, but this might become unsafe in case of changes to fetcher
- if (mBoostLevel == BOOST_PREVIEW)
- {
- mRawImage->biasedScaleToPowerOfTwo(1024);
- }
- else
- { // leave black border, do not scale image content
- mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
- }
-
- mFullWidth = mRawImage->getWidth();
- mFullHeight = mRawImage->getHeight();
- setTexelsPerImage();
- }
- else
- {
- mOrigWidth = mFullWidth;
- mOrigHeight = mFullHeight;
- }
+ if (mBoostLevel == BOOST_PREVIEW)
+ {
+ mRawImage->biasedScaleToPowerOfTwo(1024);
+ }
+ else
+ { // leave black border, do not scale image content
+ mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
+ }
+
+ mFullWidth = mRawImage->getWidth();
+ mFullHeight = mRawImage->getHeight();
+ setTexelsPerImage();
+ }
+ else
+ {
+ mOrigWidth = mFullWidth;
+ mOrigHeight = mFullHeight;
+ }
- bool size_okay = true;
+ bool size_okay = true;
- S32 discard_level = mRawDiscardLevel;
- if (mRawDiscardLevel < 0)
- {
- LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL;
- discard_level = 0;
- }
+ S32 discard_level = mRawDiscardLevel;
+ if (mRawDiscardLevel < 0)
+ {
+ LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL;
+ discard_level = 0;
+ }
- U32 raw_width = mRawImage->getWidth() << discard_level;
- U32 raw_height = mRawImage->getHeight() << discard_level;
+ U32 raw_width = mRawImage->getWidth() << discard_level;
+ U32 raw_height = mRawImage->getHeight() << discard_level;
- if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE )
- {
- LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL;
- size_okay = false;
- }
-
- if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
- {
- // A non power-of-two image was uploaded (through a non standard client)
- LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL;
- size_okay = false;
- }
-
- if( !size_okay )
- {
- // An inappropriately-sized image was uploaded (through a non standard client)
- // We treat these images as missing assets which causes them to
- // be renderd as 'missing image' and to stop requesting data
- LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL;
- setIsMissingAsset();
- destroyRawImage();
- return FALSE;
- }
+ if (raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE)
+ {
+ LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL;
+ size_okay = false;
+ }
+
+ if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
+ {
+ // A non power-of-two image was uploaded (through a non standard client)
+ LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL;
+ size_okay = false;
+ }
+
+ if (!size_okay)
+ {
+ // An inappropriately-sized image was uploaded (through a non standard client)
+ // We treat these images as missing assets which causes them to
+ // be renderd as 'missing image' and to stop requesting data
+ LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL;
+ setIsMissingAsset();
+ destroyRawImage();
+ return FALSE;
+ }
if (mGLTexturep->getHasExplicitFormat())
{
@@ -1564,19 +1579,66 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
}
}
- res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+ return res;
+}
- notifyAboutCreatingTexture();
+BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
+{
+ if (!mNeedsCreateTexture)
+ {
+ return FALSE;
+ }
- setActive();
+ BOOL res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+
+ return res;
+}
- if (!needsToSaveRawImage())
- {
- mNeedsAux = FALSE;
- destroyRawImage();
- }
+void LLViewerFetchedTexture::postCreateTexture()
+{
+ if (!mNeedsCreateTexture)
+ {
+ return;
+ }
- return res;
+ notifyAboutCreatingTexture();
+
+ setActive();
+
+ if (!needsToSaveRawImage())
+ {
+ mNeedsAux = FALSE;
+ destroyRawImage();
+ }
+
+ mNeedsCreateTexture = FALSE;
+}
+
+void LLViewerFetchedTexture::scheduleCreateTexture()
+{
+ ref();
+ mNeedsCreateTexture = TRUE;
+ if (preCreateTexture())
+ {
+ mNeedsCreateTexture = TRUE;
+#if LL_WINDOWS //flip to 0 to revert to single-threaded OpenGL texture uploads
+ if (!LLImageGLThread::sInstance->post([this]()
+ {
+ //actually create the texture on a background thread
+ createTexture();
+ LLImageGLThread::sInstance->postCallback([this]()
+ {
+ //finalize on main thread
+ postCreateTexture();
+ unref();
+ });
+ }))
+#endif
+ {
+ gTextureList.mCreateTextureList.insert(this);
+ unref();
+ }
+ }
}
// Call with 0,0 to turn this feature off.
@@ -1868,6 +1930,7 @@ void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
void LLViewerFetchedTexture::updateVirtualSize()
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mMaxVirtualSizeResetCounter)
{
addTextureStats(0.f, FALSE);//reset
@@ -1959,6 +2022,7 @@ bool LLViewerFetchedTexture::isActiveFetching()
bool LLViewerFetchedTexture::updateFetch()
{
+ LL_PROFILE_ZONE_SCOPED;
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2);
static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3);
@@ -2061,7 +2125,7 @@ bool LLViewerFetchedTexture::updateFetch()
}
else
{
- mIsRawImageValid = TRUE;
+ mIsRawImageValid = TRUE;
addToCreateTexture();
}
@@ -2539,6 +2603,7 @@ void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::s
bool LLViewerFetchedTexture::doLoadedCallbacks()
{
+ LL_PROFILE_ZONE_SCOPED;
static const F32 MAX_INACTIVE_TIME = 900.f ; //seconds
static const F32 MAX_IDLE_WAIT_TIME = 5.f ; //seconds
@@ -2889,6 +2954,7 @@ void LLViewerFetchedTexture::destroyRawImage()
//virtual
void LLViewerFetchedTexture::switchToCachedImage()
{
+ LL_PROFILE_ZONE_SCOPED;
if(mCachedRawImage.notNull())
{
mRawImage = mCachedRawImage;
@@ -2900,12 +2966,12 @@ void LLViewerFetchedTexture::switchToCachedImage()
mComponents = mRawImage->getComponents();
mGLTexturep->setComponents(mComponents);
gTextureList.dirtyImage(this);
- }
+ }
mIsRawImageValid = TRUE;
mRawDiscardLevel = mCachedRawDiscardLevel;
- gTextureList.mCreateTextureList.insert(this);
- mNeedsCreateTexture = TRUE;
+
+ scheduleCreateTexture();
}
}
@@ -3179,6 +3245,7 @@ bool LLViewerLODTexture::isUpdateFrozen()
//virtual
void LLViewerLODTexture::processTextureStats()
{
+ LL_PROFILE_ZONE_SCOPED;
updateVirtualSize();
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
@@ -3342,6 +3409,7 @@ bool LLViewerLODTexture::scaleDown()
//static
void LLViewerMediaTexture::updateClass()
{
+ LL_PROFILE_ZONE_SCOPED;
static const F32 MAX_INACTIVE_TIME = 30.f;
#if 0
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 69568cc825..f9f1bfef44 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -114,7 +114,7 @@ protected:
public:
static void initClass();
- static void updateClass(const F32 velocity, const F32 angular_velocity) ;
+ static void updateClass();
LLViewerTexture(BOOL usemipmaps = TRUE);
LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ;
@@ -321,9 +321,13 @@ public:
void addToCreateTexture();
-
- // ONLY call from LLViewerTextureList
+ //call to determine if createTexture is necessary
+ BOOL preCreateTexture(S32 usename = 0);
+ // ONLY call from LLViewerTextureList or ImageGL background thread
BOOL createTexture(S32 usename = 0);
+ void postCreateTexture();
+ void scheduleCreateTexture();
+
void destroyTexture() ;
virtual void processTextureStats() ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 561319ca5d..fe26cd67a4 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -68,7 +68,6 @@ void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL;
S32 LLViewerTextureList::sNumImages = 0;
LLViewerTextureList gTextureList;
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMAGES("Process Images");
ETexListType get_element_type(S32 priority)
{
@@ -114,6 +113,7 @@ void LLViewerTextureList::init()
void LLViewerTextureList::doPreloadImages()
{
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL;
llassert_always(mInitialized) ;
@@ -205,6 +205,7 @@ static std::string get_texture_list_name()
void LLViewerTextureList::doPrefetchImages()
{
+ LL_PROFILE_ZONE_SCOPED;
if (LLAppViewer::instance()->getPurgeCache())
{
// cache was purged, no point
@@ -258,6 +259,7 @@ LLViewerTextureList::~LLViewerTextureList()
void LLViewerTextureList::shutdown()
{
+ LL_PROFILE_ZONE_SCOPED;
// clear out preloads
mImagePreloads.clear();
@@ -333,6 +335,7 @@ void LLViewerTextureList::shutdown()
void LLViewerTextureList::dump()
{
+ LL_PROFILE_ZONE_SCOPED;
LL_INFOS() << "LLViewerTextureList::dump()" << LL_ENDL;
for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it)
{
@@ -377,6 +380,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
LLGLenum primary_format,
const LLUUID& force_id)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInitialized)
{
return NULL ;
@@ -404,6 +408,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
LLGLenum primary_format,
const LLUUID& force_id)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInitialized)
{
return NULL ;
@@ -492,6 +497,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
LLGLenum primary_format,
LLHost request_from_host)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInitialized)
{
return NULL ;
@@ -554,6 +560,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
LLGLenum primary_format,
LLHost request_from_host)
{
+ LL_PROFILE_ZONE_SCOPED;
static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled", true);
LLPointer<LLViewerFetchedTexture> imagep ;
@@ -609,6 +616,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector<LLViewerFetchedTexture*> &output)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTextureKey search_key(image_id, TEX_LIST_STANDARD);
uuid_map_t::iterator iter = mUUIDMap.lower_bound(search_key);
while (iter != mUUIDMap.end() && iter->first.textureId == image_id)
@@ -620,6 +628,7 @@ void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector<L
LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLTextureKey &search_key)
{
+ LL_PROFILE_ZONE_SCOPED;
uuid_map_t::iterator iter = mUUIDMap.find(search_key);
if (iter == mUUIDMap.end())
return NULL;
@@ -633,6 +642,7 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id, E
void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
{
+ LL_PROFILE_ZONE_SCOPED;
assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
@@ -652,6 +662,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
{
+ LL_PROFILE_ZONE_SCOPED;
assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
@@ -700,6 +711,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListType tex_type)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!new_image)
{
return;
@@ -723,6 +735,7 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListTy
void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image)
{
+ LL_PROFILE_ZONE_SCOPED;
if( image)
{
if (image->hasCallbacks())
@@ -747,18 +760,10 @@ void LLViewerTextureList::dirtyImage(LLViewerFetchedTexture *image)
}
////////////////////////////////////////////////////////////////////////////
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_MARK_DIRTY("Dirty Images");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_PRIORITIES("Prioritize");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_CALLBACKS("Callbacks");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_FETCH("Fetch");
-static LLTrace::BlockTimerStatHandle FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_CREATE("Create");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_STATS("Stats");
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_TEXTURES("Update Textures");
void LLViewerTextureList::updateImages(F32 max_time)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_TEXTURES);
+ LL_PROFILE_ZONE_SCOPED;
static BOOL cleared = FALSE;
if(gTeleportDisplay)
{
@@ -784,66 +789,49 @@ void LLViewerTextureList::updateImages(F32 max_time)
sample(FORMATTED_MEM, F64Bytes(LLImageFormatted::sGlobalFormattedMemory));
}
- {
- //loading from fast cache
- LL_RECORD_BLOCK_TIME(FTM_FAST_CACHE_IMAGE_FETCH);
- max_time -= updateImagesLoadingFastCache(max_time);
- }
-
- {
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_PRIORITIES);
- updateImagesDecodePriorities();
- }
-
- F32 total_max_time = max_time;
-
- {
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_FETCH);
- max_time -= updateImagesFetchTextures(max_time);
- }
+ //loading from fast cache
+ max_time -= updateImagesLoadingFastCache(max_time);
- {
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_CREATE);
- max_time = llmax(max_time, total_max_time*.50f); // at least 50% of max_time
- max_time -= updateImagesCreateTextures(max_time);
- }
+ updateImagesDecodePriorities();
+
+ F32 total_max_time = max_time;
+
+ max_time -= updateImagesFetchTextures(max_time);
+
+ max_time = llmax(max_time, total_max_time*.50f); // at least 50% of max_time
+ max_time -= updateImagesCreateTextures(max_time);
if (!mDirtyTextureList.empty())
{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_MARK_DIRTY);
gPipeline.dirtyPoolObjectTextures(mDirtyTextureList);
mDirtyTextureList.clear();
}
+ bool didone = false;
+ for (image_list_t::iterator iter = mCallbackList.begin();
+ iter != mCallbackList.end(); )
{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_CALLBACKS);
- bool didone = false;
- for (image_list_t::iterator iter = mCallbackList.begin();
- iter != mCallbackList.end(); )
+ //trigger loaded callbacks on local textures immediately
+ LLViewerFetchedTexture* image = *iter++;
+ if (!image->getUrl().empty())
{
- //trigger loaded callbacks on local textures immediately
- LLViewerFetchedTexture* image = *iter++;
- if (!image->getUrl().empty())
- {
- // Do stuff to handle callbacks, update priorities, etc.
- didone = image->doLoadedCallbacks();
- }
- else if (!didone)
- {
- // Do stuff to handle callbacks, update priorities, etc.
- didone = image->doLoadedCallbacks();
- }
+ // Do stuff to handle callbacks, update priorities, etc.
+ didone = image->doLoadedCallbacks();
+ }
+ else if (!didone)
+ {
+ // Do stuff to handle callbacks, update priorities, etc.
+ didone = image->doLoadedCallbacks();
}
}
+
- {
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_STATS);
- updateImagesUpdateStats();
- }
+ updateImagesUpdateStats();
}
void LLViewerTextureList::clearFetchingRequests()
{
+ LL_PROFILE_ZONE_SCOPED;
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
{
return;
@@ -861,6 +849,7 @@ void LLViewerTextureList::clearFetchingRequests()
void LLViewerTextureList::updateImagesDecodePriorities()
{
+ LL_PROFILE_ZONE_SCOPED;
// Update the decode priority for N images each frame
{
F32 lazy_flush_timeout = 30.f; // stop decoding
@@ -976,6 +965,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()
void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!tex->setDebugFetching(debug_level))
{
return;
@@ -1024,6 +1014,7 @@ void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debu
F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
{
+ LL_PROFILE_ZONE_SCOPED;
if (gGLManager.mIsDisabled) return 0.0f;
//
@@ -1040,6 +1031,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
enditer = iter;
LLViewerFetchedTexture *imagep = *curiter;
imagep->createTexture();
+ imagep->postCreateTexture();
if (create_timer.getElapsedTimeF32() > max_time)
{
break;
@@ -1051,6 +1043,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
{
+ LL_PROFILE_ZONE_SCOPED;
if (gGLManager.mIsDisabled) return 0.0f;
if(mFastCacheList.empty())
{
@@ -1081,6 +1074,7 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!imagep)
{
return ;
@@ -1100,6 +1094,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTimer image_op_timer;
// Update fetch for N images each frame
@@ -1175,6 +1170,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
void LLViewerTextureList::updateImagesUpdateStats()
{
+ LL_PROFILE_ZONE_SCOPED;
if (mForceResetTextureStats)
{
for (image_priority_list_t::iterator iter = mImageList.begin();
@@ -1189,6 +1185,7 @@ void LLViewerTextureList::updateImagesUpdateStats()
void LLViewerTextureList::decodeAllImages(F32 max_time)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTimer timer;
//loading from fast cache
@@ -1258,6 +1255,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
const std::string& out_filename,
const U8 codec)
{
+ LL_PROFILE_ZONE_SCOPED;
// Load the image
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
if (image.isNull())
@@ -1311,6 +1309,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
// note: modifies the argument raw_image!!!!
LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image)
{
+ LL_PROFILE_ZONE_SCOPED;
raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
@@ -1344,6 +1343,7 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
// Returns min setting for TextureMemory (in MB)
S32Megabytes LLViewerTextureList::getMinVideoRamSetting()
{
+ LL_PROFILE_ZONE_SCOPED;
U32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
//min texture mem sets to 64M if total physical mem is more than 1.5GB
return (system_ram > U32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ;
@@ -1353,6 +1353,7 @@ S32Megabytes LLViewerTextureList::getMinVideoRamSetting()
// Returns max setting for TextureMemory (in MB)
S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier)
{
+ LL_PROFILE_ZONE_SCOPED;
S32Megabytes max_texmem;
if (gGLManager.mVRAM != 0)
{
@@ -1406,6 +1407,7 @@ const S32Megabytes VIDEO_CARD_FRAMEBUFFER_MEM(12);
const S32Megabytes MIN_MEM_FOR_NON_TEXTURE(512);
void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
{
+ LL_PROFILE_ZONE_SCOPED;
// Initialize the image pipeline VRAM settings
S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory"));
F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
@@ -1468,8 +1470,8 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d
{
static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMAGES);
-
+ LL_PROFILE_ZONE_SCOPED;
+
// Receive image header, copy into image object and decompresses
// if this is a one-packet image.
@@ -1540,7 +1542,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d
{
static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMAGES);
+ LL_PROFILE_ZONE_SCOPED;
// Receives image packet, copy into image object,
// checks if all packets received, decompresses if so.
@@ -1613,7 +1615,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d
// static
void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data)
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMAGES);
+ LL_PROFILE_ZONE_SCOPED;
LLUUID image_id;
msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, image_id);
@@ -1646,6 +1648,7 @@ void LLUIImageList::cleanUp()
LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id, S32 priority)
{
+ LL_PROFILE_ZONE_SCOPED;
// use id as image name
std::string image_name = image_id.asString();
@@ -1664,6 +1667,7 @@ LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id, S32 priority)
LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priority)
{
+ LL_PROFILE_ZONE_SCOPED;
// look for existing image
uuid_ui_image_map_t::iterator found_it = mUIImages.find(image_name);
if (found_it != mUIImages.end())
@@ -1681,6 +1685,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std
BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority,
LLUIImage::EScaleStyle scale_style)
{
+ LL_PROFILE_ZONE_SCOPED;
if (boost_priority == LLGLTexture::BOOST_NONE)
{
boost_priority = LLGLTexture::BOOST_UI;
@@ -1693,6 +1698,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id,
BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority,
LLUIImage::EScaleStyle scale_style)
{
+ LL_PROFILE_ZONE_SCOPED;
if (boost_priority == LLGLTexture::BOOST_NONE)
{
boost_priority = LLGLTexture::BOOST_UI;
@@ -1704,6 +1710,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id,
LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect,
LLUIImage::EScaleStyle scale_style)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!imagep) return NULL;
imagep->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -1741,6 +1748,7 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLUIImage::EScaleStyle scale_style)
{
+ LL_PROFILE_ZONE_SCOPED;
// look for existing image
uuid_ui_image_map_t::iterator found_it = mUIImages.find(name);
if (found_it != mUIImages.end())
@@ -1755,6 +1763,7 @@ LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::s
//static
void LLUIImageList::onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* user_data )
{
+ LL_PROFILE_ZONE_SCOPED;
if(!success || !user_data)
{
return;
@@ -1856,6 +1865,7 @@ struct UIImageDeclarations : public LLInitParam::Block<UIImageDeclarations>
bool LLUIImageList::initFromFile()
{
+ LL_PROFILE_ZONE_SCOPED;
// Look for textures.xml in all the right places. Pass
// constraint=LLDir::ALL_SKINS because we want to overlay textures.xml
// from all the skins directories.
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index c20021d4c7..198007aaa1 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1518,8 +1518,15 @@ BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)
void LLViewerWindow::handleQuit(LLWindow *window)
{
- LL_INFOS() << "Window forced quit" << LL_ENDL;
- LLAppViewer::instance()->forceQuit();
+ if (gNonInteractive)
+ {
+ LLAppViewer::instance()->requestQuit();
+ }
+ else
+ {
+ LL_INFOS() << "Window forced quit" << LL_ENDL;
+ LLAppViewer::instance()->forceQuit();
+ }
}
void LLViewerWindow::handleResize(LLWindow *window, S32 width, S32 height)
@@ -1906,7 +1913,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
p.title, p.name, p.x, p.y, p.width, p.height, 0,
p.fullscreen,
gHeadlessClient,
- gSavedSettings.getBOOL("DisableVerticalSync"),
+ gSavedSettings.getBOOL("RenderVSyncEnable"),
!gHeadlessClient,
p.ignore_pixel_depth,
gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled
@@ -1973,6 +1980,13 @@ LLViewerWindow::LLViewerWindow(const Params& p)
}
LLFontManager::initClass();
+ // Init font system, load default fonts and generate basic glyphs
+ // currently it takes aprox. 0.5 sec and we would load these fonts anyway
+ // before login screen.
+ LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
+ mDisplayScale.mV[VX],
+ mDisplayScale.mV[VY],
+ gDirUtilp->getAppRODataDir());
//
// We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off
@@ -2014,19 +2028,11 @@ LLViewerWindow::LLViewerWindow(const Params& p)
// Init the image list. Must happen after GL is initialized and before the images that
// LLViewerWindow needs are requested.
- LLImageGL::initClass(LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ;
+ LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ;
gTextureList.init();
LLViewerTextureManager::init() ;
gBumpImageList.init();
- // Init font system, but don't actually load the fonts yet
- // because our window isn't onscreen and they take several
- // seconds to parse.
- LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
- mDisplayScale.mV[VX],
- mDisplayScale.mV[VY],
- gDirUtilp->getAppRODataDir());
-
// Create container for all sub-views
LLView::Params rvp;
rvp.name("root");
@@ -2112,6 +2118,8 @@ void LLViewerWindow::initBase()
LL_DEBUGS("AppInit") << "initializing edit menu" << LL_ENDL;
initialize_edit_menu();
+ LLFontGL::loadCommonFonts();
+
// Create the floater view at the start so that other views can add children to it.
// (But wait to add it as a child of the root view so that it will be in front of the
// other views.)
@@ -2198,6 +2206,14 @@ void LLViewerWindow::initBase()
void LLViewerWindow::initWorldUI()
{
+ if (gNonInteractive)
+ {
+ gIMMgr = LLIMMgr::getInstance();
+ LLNavigationBar::getInstance();
+ gFloaterView->pushVisibleAll(FALSE);
+ return;
+ }
+
S32 height = mRootView->getRect().getHeight();
S32 width = mRootView->getRect().getWidth();
LLRect full_window(0, height, width, 0);
@@ -2208,12 +2224,15 @@ void LLViewerWindow::initWorldUI()
//getRootView()->sendChildToFront(gFloaterView);
//getRootView()->sendChildToFront(gSnapshotFloaterView);
- LLPanel* chiclet_container = getRootView()->getChild<LLPanel>("chiclet_container");
- LLChicletBar* chiclet_bar = LLChicletBar::getInstance();
- chiclet_bar->setShape(chiclet_container->getLocalRect());
- chiclet_bar->setFollowsAll();
- chiclet_container->addChild(chiclet_bar);
- chiclet_container->setVisible(TRUE);
+ if (!gNonInteractive)
+ {
+ LLPanel* chiclet_container = getRootView()->getChild<LLPanel>("chiclet_container");
+ LLChicletBar* chiclet_bar = LLChicletBar::getInstance();
+ chiclet_bar->setShape(chiclet_container->getLocalRect());
+ chiclet_bar->setFollowsAll();
+ chiclet_container->addChild(chiclet_bar);
+ chiclet_container->setVisible(TRUE);
+ }
LLRect morph_view_rect = full_window;
morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
@@ -2302,21 +2321,24 @@ void LLViewerWindow::initWorldUI()
gToolBarView->setVisible(TRUE);
}
- LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
- if (destinations)
+ if (!gNonInteractive)
{
- destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
- std::string url = gSavedSettings.getString("DestinationGuideURL");
- url = LLWeb::expandURLSubstitutions(url, LLSD());
- destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
- }
- LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents");
- if (avatar_picker)
- {
- avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
- std::string url = gSavedSettings.getString("AvatarPickerURL");
- url = LLWeb::expandURLSubstitutions(url, LLSD());
- avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+ LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
+ if (destinations)
+ {
+ destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
+ std::string url = gSavedSettings.getString("DestinationGuideURL");
+ url = LLWeb::expandURLSubstitutions(url, LLSD());
+ destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+ }
+ LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents");
+ if (avatar_picker)
+ {
+ avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
+ std::string url = gSavedSettings.getString("AvatarPickerURL");
+ url = LLWeb::expandURLSubstitutions(url, LLSD());
+ avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+ }
}
}
@@ -2560,7 +2582,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
mWindow->setMinSize(min_window_width, min_window_height);
LLCoordScreen window_rect;
- if (mWindow->getSize(&window_rect))
+ if (!gNonInteractive && mWindow->getSize(&window_rect))
{
// Only save size if not maximized
gSavedSettings.setU32("WindowWidth", window_rect.mX);
@@ -3790,8 +3812,15 @@ void LLViewerWindow::updateLayout()
void LLViewerWindow::updateMouseDelta()
{
+#if LL_WINDOWS
+ LLCoordCommon delta;
+ mWindow->getCursorDelta(&delta);
+ S32 dx = delta.mX;
+ S32 dy = delta.mY;
+#else
S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]);
S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]);
+#endif
//RN: fix for asynchronous notification of mouse leaving window not working
LLCoordWindow mouse_pos;
@@ -5290,6 +5319,7 @@ void LLViewerWindow::setup3DRender()
void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset)
{
+ LL_PROFILE_ZONE_SCOPED
gGLViewport[0] = mWorldViewRectRaw.mLeft + x_offset;
gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset;
gGLViewport[2] = mWorldViewRectRaw.getWidth();
@@ -5508,8 +5538,6 @@ void LLViewerWindow::initFonts(F32 zoom_factor)
mDisplayScale.mV[VX] * zoom_factor,
mDisplayScale.mV[VY] * zoom_factor,
gDirUtilp->getAppRODataDir());
- // Force font reloads, which can be very slow
- LLFontGL::loadDefaultFonts();
}
void LLViewerWindow::requestResolutionUpdate()
@@ -5551,7 +5579,7 @@ void LLViewerWindow::restartDisplay(BOOL show_progress_bar)
}
}
-BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar)
+BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar)
{
//BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized");
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 8a6df613dc..93194b1884 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -424,7 +424,7 @@ public:
void requestResolutionUpdate();
void checkSettings();
void restartDisplay(BOOL show_progress_bar);
- BOOL changeDisplaySettings(LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar);
+ BOOL changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar);
BOOL getIgnoreDestroyWindow() { return mIgnoreActivate; }
F32 getWorldViewAspectRatio() const;
const LLVector2& getDisplayScale() const { return mDisplayScale; }
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index c63c5f6b23..46beac8255 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -254,6 +254,7 @@ BOOL LLVLComposition::generateComposition()
BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
const F32 width, const F32 height)
{
+ LL_PROFILE_ZONE_SCOPED
llassert(mSurfacep);
llassert(x >= 0.f);
llassert(y >= 0.f);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 0e0ebce949..310a6a2adb 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -126,6 +126,9 @@ const F32 MIN_HOVER_Z = -2.0;
const F32 MIN_ATTACHMENT_COMPLEXITY = 0.f;
const F32 DEFAULT_MAX_ATTACHMENT_COMPLEXITY = 1.0e6f;
+const F32 FIRST_APPEARANCE_CLOUD_MIN_DELAY = 3.f; // seconds
+const F32 FIRST_APPEARANCE_CLOUD_MAX_DELAY = 45.f;
+
using namespace LLAvatarAppearanceDefines;
//-----------------------------------------------------------------------------
@@ -328,6 +331,7 @@ public:
// must return FALSE when the motion is completed.
virtual BOOL onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
F32 nx[2];
nx[0]=time*TORSO_NOISE_SPEED;
nx[1]=0.0f;
@@ -448,6 +452,7 @@ public:
// must return FALSE when the motion is completed.
virtual BOOL onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
mBreatheRate = 1.f;
F32 breathe_amt = (sinf(mBreatheRate * time) * BREATHE_ROT_MOTION_STRENGTH);
@@ -549,6 +554,7 @@ public:
// must return FALSE when the motion is completed.
virtual BOOL onUpdate(F32 time, U8* joint_mask)
{
+ LL_PROFILE_ZONE_SCOPED;
mPelvisState->setPosition(LLVector3::zero);
return TRUE;
@@ -664,6 +670,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mVisuallyMuteSetting(AV_RENDER_NORMALLY),
mMutedAVColor(LLColor4::white /* used for "uninitialize" */),
mFirstFullyVisible(TRUE),
+ mFirstUseDelaySeconds(FIRST_APPEARANCE_CLOUD_MIN_DELAY),
mFullyLoaded(FALSE),
mPreviousFullyLoaded(FALSE),
mFullyLoadedInitialized(FALSE),
@@ -738,7 +745,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mCurrentGesticulationLevel = 0;
-
+ mFirstSeenTimer.reset();
mRuthTimer.reset();
mRuthDebugTimer.reset();
mDebugExistenceTimer.reset();
@@ -1318,11 +1325,9 @@ void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
}
-static LLTrace::BlockTimerStatHandle FTM_AVATAR_EXTENT_UPDATE("Av Upd Extent");
-
void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
{
- LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE);
+ LL_PROFILE_ZONE_SCOPED;
S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity");
if (getOverallAppearance() != AOA_NORMAL)
@@ -2491,10 +2496,6 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
return setTETextureCore(te, image);
}
-static LLTrace::BlockTimerStatHandle FTM_AVATAR_UPDATE("Avatar Update");
-static LLTrace::BlockTimerStatHandle FTM_AVATAR_UPDATE_COMPLEXITY("Avatar Update Complexity");
-static LLTrace::BlockTimerStatHandle FTM_JOINT_UPDATE("Update Joints");
-
//------------------------------------------------------------------------
// LLVOAvatar::dumpAnimationState()
//------------------------------------------------------------------------
@@ -2527,7 +2528,7 @@ void LLVOAvatar::dumpAnimationState()
//------------------------------------------------------------------------
void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
{
- LL_RECORD_BLOCK_TIME(FTM_AVATAR_UPDATE);
+ LL_PROFILE_ZONE_SCOPED;
if (isDead())
{
@@ -2563,8 +2564,6 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
// force asynchronous drawable update
if(mDrawable.notNull())
{
- LL_RECORD_BLOCK_TIME(FTM_JOINT_UPDATE);
-
if (isSitting() && getParent())
{
LLViewerObject *root_object = (LLViewerObject*)getRoot();
@@ -2664,9 +2663,8 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
if ((LLFrameTimer::getFrameCount() + mID.mData[0]) % compl_upd_freq == 0)
{
- LL_RECORD_BLOCK_TIME(FTM_AVATAR_UPDATE_COMPLEXITY);
- idleUpdateRenderComplexity();
-}
+ idleUpdateRenderComplexity();
+ }
idleUpdateDebugInfo();
}
@@ -2779,10 +2777,9 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
}//if ( voiceEnabled )
}
-static LLTrace::BlockTimerStatHandle FTM_ATTACHMENT_UPDATE("Update Attachments");
-
void LLVOAvatar::idleUpdateMisc(bool detailed_update)
{
+ LL_PROFILE_ZONE_SCOPED;
if (LLVOAvatar::sJointDebug)
{
LL_INFOS() << getFullname() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << LL_ENDL;
@@ -2796,7 +2793,6 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
// update attachments positions
if (detailed_update)
{
- LL_RECORD_BLOCK_TIME(FTM_ATTACHMENT_UPDATE);
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -3136,6 +3132,8 @@ void LLVOAvatar::idleUpdateWindEffect()
void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
{
+ LL_PROFILE_ZONE_SCOPED;
+
// update chat bubble
//--------------------------------------------------------------------
// draw text label over character's head
@@ -4884,6 +4882,8 @@ bool LLVOAvatar::shouldAlphaMask()
//-----------------------------------------------------------------------------
U32 LLVOAvatar::renderSkinned()
{
+ LL_PROFILE_ZONE_SCOPED;
+
U32 num_indices = 0;
if (!mIsBuilt)
@@ -6158,27 +6158,29 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
LLJoint *LLVOAvatar::getJoint( S32 joint_num )
{
LLJoint *pJoint = NULL;
- S32 collision_start = mNumBones;
- S32 attachment_start = mNumBones + mNumCollisionVolumes;
- if (joint_num>=attachment_start)
+ if (joint_num >= 0)
{
- // Attachment IDs start at 1
- S32 attachment_id = joint_num - attachment_start + 1;
- attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id);
- if (iter != mAttachmentPoints.end())
+ if (joint_num < mNumBones)
{
- pJoint = iter->second;
+ pJoint = mSkeleton[joint_num];
+ }
+ else if (joint_num < mNumBones + mNumCollisionVolumes)
+ {
+ S32 collision_id = joint_num - mNumBones;
+ pJoint = &mCollisionVolumes[collision_id];
+ }
+ else
+ {
+ // Attachment IDs start at 1
+ S32 attachment_id = joint_num - (mNumBones + mNumCollisionVolumes) + 1;
+ attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id);
+ if (iter != mAttachmentPoints.end())
+ {
+ pJoint = iter->second;
+ }
}
}
- else if (joint_num>=collision_start)
- {
- S32 collision_id = joint_num-collision_start;
- pJoint = &mCollisionVolumes[collision_id];
- }
- else if (joint_num>=0)
- {
- pJoint = mSkeleton[joint_num];
- }
+
llassert(!pJoint || pJoint->getJointNum() == joint_num);
return pJoint;
}
@@ -6513,7 +6515,7 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL
LLJoint* pJoint = getJoint( lookingForJoint );
if (pJoint)
{
- const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
+ const LLVector3& jointPos = LLVector3(pSkinData->mAlternateBindMatrix[i].getTranslation());
if (pJoint->aboveJointPosThreshold(jointPos))
{
bool override_changed;
@@ -7117,6 +7119,7 @@ void LLVOAvatar::updateGL()
{
if (mMeshTexturesDirty)
{
+ LL_PROFILE_ZONE_SCOPED
updateMeshTextures();
mMeshTexturesDirty = FALSE;
}
@@ -7125,10 +7128,9 @@ void LLVOAvatar::updateGL()
//-----------------------------------------------------------------------------
// updateGeometry()
//-----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_AVATAR("Update Avatar");
BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_AVATAR);
+ LL_PROFILE_ZONE_SCOPED;
if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)))
{
return TRUE;
@@ -7862,6 +7864,8 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color)
// Do rigged mesh attachments display with this av?
bool LLVOAvatar::shouldRenderRigged() const
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (getOverallAppearance() == AOA_NORMAL)
{
return true;
@@ -8126,16 +8130,35 @@ void LLVOAvatar::updateRuthTimer(bool loading)
BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
{
// We wait a little bit before giving the 'all clear', to let things to
- // settle down (models to snap into place, textures to get first packets)
+ // settle down (models to snap into place, textures to get first packets).
+ // And if viewer isn't aware of some parts yet, this gives them a chance
+ // to arrive.
const F32 LOADED_DELAY = 1.f;
- const F32 FIRST_USE_DELAY = 3.f;
- if (loading)
- mFullyLoadedTimer.reset();
+ if (loading)
+ {
+ mFullyLoadedTimer.reset();
+ }
if (mFirstFullyVisible)
{
- mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > FIRST_USE_DELAY);
+ if (!isSelf() && loading)
+ {
+ // Note that textures can causes 60s delay on thier own
+ // so this delay might end up on top of textures' delay
+ mFirstUseDelaySeconds = llclamp(
+ mFirstSeenTimer.getElapsedTimeF32(),
+ FIRST_APPEARANCE_CLOUD_MIN_DELAY,
+ FIRST_APPEARANCE_CLOUD_MAX_DELAY);
+
+ if (shouldImpostor())
+ {
+ // Impostors are less of a priority,
+ // let them stay cloud longer
+ mFirstUseDelaySeconds *= 1.25;
+ }
+ }
+ mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > mFirstUseDelaySeconds);
}
else
{
@@ -8353,6 +8376,7 @@ void LLVOAvatar::updateMeshVisibility()
// virtual
void LLVOAvatar::updateMeshTextures()
{
+ LL_PROFILE_ZONE_SCOPED
static S32 update_counter = 0;
mBakedTextureDebugText.clear();
@@ -10184,6 +10208,7 @@ void showRigInfoTabExtents(LLVOAvatar *avatar, LLJointRiggingInfoTab& tab, S32&
void LLVOAvatar::getAssociatedVolumes(std::vector<LLVOVolume*>& volumes)
{
+ LL_PROFILE_ZONE_SCOPED;
for ( LLVOAvatar::attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter )
{
LLViewerJointAttachment* attachment = iter->second;
@@ -10241,27 +10266,19 @@ void LLVOAvatar::getAssociatedVolumes(std::vector<LLVOVolume*>& volumes)
}
}
-static LLTrace::BlockTimerStatHandle FTM_AVATAR_RIGGING_INFO_UPDATE("Av Upd Rig Info");
-static LLTrace::BlockTimerStatHandle FTM_AVATAR_RIGGING_KEY_UPDATE("Av Upd Rig Key");
-static LLTrace::BlockTimerStatHandle FTM_AVATAR_RIGGING_AVOL_UPDATE("Av Upd Avol");
-
// virtual
void LLVOAvatar::updateRiggingInfo()
{
- LL_RECORD_BLOCK_TIME(FTM_AVATAR_RIGGING_INFO_UPDATE);
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS("RigSpammish") << getFullname() << " updating rig tab" << LL_ENDL;
std::vector<LLVOVolume*> volumes;
- {
- LL_RECORD_BLOCK_TIME(FTM_AVATAR_RIGGING_AVOL_UPDATE);
- getAssociatedVolumes(volumes);
- }
+ getAssociatedVolumes(volumes);
std::map<LLUUID,S32> curr_rigging_info_key;
{
- LL_RECORD_BLOCK_TIME(FTM_AVATAR_RIGGING_KEY_UPDATE);
// Get current rigging info key
for (std::vector<LLVOVolume*>::iterator it = volumes.begin(); it != volumes.end(); ++it)
{
@@ -10423,6 +10440,7 @@ void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue)
void LLVOAvatar::idleUpdateRenderComplexity()
{
+ LL_PROFILE_ZONE_SCOPED;
if (isControlAvatar())
{
LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
@@ -10950,6 +10968,7 @@ void LLVOAvatar::updateOverallAppearanceAnimations()
// Based on isVisuallyMuted(), but has 3 possible results.
LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const
{
+ LL_PROFILE_ZONE_SCOPED;
AvatarOverallAppearance result = AOA_NORMAL;
// Priority order (highest priority first)
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 74ef589ca4..aeac23ad92 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -87,6 +87,7 @@ class LLVOAvatar :
public LLViewerObject,
public boost::signals2::trackable
{
+ LL_ALIGN_NEW;
LOG_CLASS(LLVOAvatar);
public:
@@ -99,16 +100,6 @@ public:
**/
public:
- void* operator new(size_t size)
- {
- return LLTrace::MemTrackable<LLViewerObject>::aligned_new<16>(size);
- }
-
- void operator delete(void* ptr, size_t size)
- {
- LLTrace::MemTrackable<LLViewerObject>::aligned_delete<16>(ptr, size);
- }
-
LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
virtual void markDead();
static void initClass(); // Initialize data that's only init'd once per class.
@@ -209,6 +200,11 @@ public:
virtual LLJoint* getJoint(const std::string &name);
LLJoint* getJoint(S32 num);
+ //if you KNOW joint_num is a valid animated joint index, use getSkeletonJoint for efficiency
+ inline LLJoint* getSkeletonJoint(S32 joint_num) { return mSkeleton[joint_num]; }
+ inline size_t getSkeletonJointCount() const { return mSkeleton.size(); }
+
+
void addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LLUUID>* meshes_seen = NULL, bool recursive = true);
void removeAttachmentOverridesForObject(const LLUUID& mesh_id);
void removeAttachmentOverridesForObject(LLViewerObject *vo);
@@ -380,6 +376,9 @@ protected:
private:
BOOL mFirstFullyVisible;
+ F32 mFirstUseDelaySeconds;
+ LLFrameTimer mFirstSeenTimer;
+
BOOL mFullyLoaded;
BOOL mPreviousFullyLoaded;
BOOL mFullyLoadedInitialized;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 5ebc65405f..e10a9f9bcb 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -63,8 +63,7 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)
//---------------------------------------------------------------------------
LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp)
-: LLTrace::MemTrackable<LLVOCacheEntry, 16>("LLVOCacheEntry"),
- LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
+: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
mLocalID(local_id),
mCRC(crc),
mUpdateFlags(-1),
@@ -83,8 +82,7 @@ LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &
}
LLVOCacheEntry::LLVOCacheEntry()
-: LLTrace::MemTrackable<LLVOCacheEntry, 16>("LLVOCacheEntry"),
- LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
+: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
mLocalID(0),
mCRC(0),
mUpdateFlags(-1),
@@ -102,8 +100,7 @@ LLVOCacheEntry::LLVOCacheEntry()
}
LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
-: LLTrace::MemTrackable<LLVOCacheEntry, 16>("LLVOCacheEntry"),
- LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
+: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
mBuffer(NULL),
mUpdateFlags(-1),
mState(INACTIVE),
@@ -619,7 +616,6 @@ void LLVOCacheGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c
}
LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp)
-: LLTrace::MemTrackable<LLVOCachePartition>("LLVOCachePartition")
{
mLODPeriod = 16;
mRegionp = regionp;
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index dd6afd6b85..c510ff77fc 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -38,9 +38,9 @@
class LLCamera;
class LLVOCacheEntry
-: public LLViewerOctreeEntryData,
- public LLTrace::MemTrackable<LLVOCacheEntry, 16>
+: public LLViewerOctreeEntryData
{
+ LL_ALIGN_NEW
public:
enum
{
@@ -185,7 +185,7 @@ protected:
virtual ~LLVOCacheGroup();
};
-class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTrackable<LLVOCachePartition>
+class LLVOCachePartition : public LLViewerOctreePartition
{
public:
LLVOCachePartition(LLViewerRegion* regionp);
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 345e87eea8..9a41eedb54 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -661,11 +661,9 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count
}
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_GRASS_VB("Grass VB");
-
void LLGrassPartition::getGeometry(LLSpatialGroup* group)
{
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_GRASS_VB);
+ LL_PROFILE_ZONE_SCOPED;
std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index c7a544f8eb..3d503638e0 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -5560,7 +5560,9 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
bool LLVivoxVoiceClient::voiceEnabled()
{
- return gSavedSettings.getBOOL("EnableVoiceChat") && !gSavedSettings.getBOOL("CmdLineDisableVoice");
+ return gSavedSettings.getBOOL("EnableVoiceChat") &&
+ !gSavedSettings.getBOOL("CmdLineDisableVoice") &&
+ !gNonInteractive;
}
void LLVivoxVoiceClient::setLipSyncEnabled(BOOL enabled)
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index b31afca61d..068e8a131d 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -306,10 +306,9 @@ LLVector3 LLVOPartGroup::getCameraPosition() const
return gAgentCamera.getCameraPositionAgent();
}
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_PARTICLES("Update Particles");
BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_PARTICLES);
+ LL_PROFILE_ZONE_SCOPED;
dirtySpatialGroup();
@@ -754,10 +753,9 @@ LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) :
mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE;
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_PARTICLE_VBO("Particle VBO");
-
void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
{
+ LL_PROFILE_ZONE_SCOPED;
if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
{
return;
@@ -769,8 +767,6 @@ void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
group->mLastUpdateViewAngle = group->mViewAngle;
}
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_PARTICLE_VBO);
-
group->clearDrawMap();
//get geometry count
@@ -843,11 +839,9 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_PARTICLE_GEOM("Particle Geom");
-
void LLParticlePartition::getGeometry(LLSpatialGroup* group)
{
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_PARTICLE_GEOM);
+ LL_PROFILE_ZONE_SCOPED;
std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 878d7287ed..72ec8390a4 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvosky.cpp
* @brief LLVOSky class implementation
*
* $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$
*/
@@ -64,7 +64,9 @@ namespace
const S32 NUM_TILES_X = 8;
const S32 NUM_TILES_Y = 4;
const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y;
- const S32 NUM_CUBEMAP_FACES = 6;
+ const S32 NUM_CUBEMAP_FACES = 6; // See SKYTEX_RESOLUTION for face dimensions
+ const S32 TOTAL_TILES = NUM_CUBEMAP_FACES * NUM_TILES;
+ const S32 MAX_TILES = TOTAL_TILES + 1;
// Heavenly body constants
const F32 SUN_DISK_RADIUS = 0.5f;
@@ -77,11 +79,6 @@ namespace
const LLVector2 TEX10 = LLVector2(1.f, 0.f);
const LLVector2 TEX11 = LLVector2(1.f, 1.f);
- LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATETIMER("VOSky Update Timer Tick");
- LLTrace::BlockTimerStatHandle FTM_VOSKY_CALC("VOSky Update Calculations");
- LLTrace::BlockTimerStatHandle FTM_VOSKY_CREATETEXTURES("VOSky Update Textures");
- LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATEFORCED("VOSky Update Forced");
-
F32Seconds UPDATE_EXPRY(0.25f);
const F32 UPDATE_MIN_DELTA_THRESHOLD = 0.0005f;
@@ -90,8 +87,6 @@ namespace
SkyTex
***************************************/
-S32 LLSkyTex::sComponents = 4;
-S32 LLSkyTex::sResolution = 64;
S32 LLSkyTex::sCurrent = 0;
@@ -105,15 +100,15 @@ LLSkyTex::LLSkyTex() :
void LLSkyTex::init(bool isShiny)
{
mIsShiny = isShiny;
- mSkyData = new LLColor4[sResolution * sResolution];
- mSkyDirs = new LLVector3[sResolution * sResolution];
+ mSkyData = new LLColor4[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION];
+ mSkyDirs = new LLVector3[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION];
for (S32 i = 0; i < 2; ++i)
{
mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE);
mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
- mImageRaw[i] = new LLImageRaw(sResolution, sResolution, sComponents);
-
+ mImageRaw[i] = new LLImageRaw(SKYTEX_RESOLUTION, SKYTEX_RESOLUTION, SKYTEX_COMPONENTS);
+
initEmpty(i);
}
}
@@ -144,7 +139,7 @@ LLSkyTex::~LLSkyTex()
S32 LLSkyTex::getResolution()
{
- return sResolution;
+ return SKYTEX_RESOLUTION;
}
S32 LLSkyTex::getCurrent()
@@ -172,12 +167,12 @@ S32 LLSkyTex::getWhich(const BOOL curr)
void LLSkyTex::initEmpty(const S32 tex)
{
U8* data = mImageRaw[tex]->getData();
- for (S32 i = 0; i < sResolution; ++i)
+ for (S32 i = 0; i < SKYTEX_RESOLUTION; ++i)
{
- for (S32 j = 0; j < sResolution; ++j)
+ for (S32 j = 0; j < SKYTEX_RESOLUTION; ++j)
{
- const S32 basic_offset = (i * sResolution + j);
- S32 offset = basic_offset * sComponents;
+ const S32 basic_offset = (i * SKYTEX_RESOLUTION + j);
+ S32 offset = basic_offset * SKYTEX_COMPONENTS;
data[offset] = 0;
data[offset+1] = 0;
data[offset+2] = 0;
@@ -193,12 +188,12 @@ void LLSkyTex::initEmpty(const S32 tex)
void LLSkyTex::create()
{
U8* data = mImageRaw[sCurrent]->getData();
- for (S32 i = 0; i < sResolution; ++i)
+ for (S32 i = 0; i < SKYTEX_RESOLUTION; ++i)
{
- for (S32 j = 0; j < sResolution; ++j)
+ for (S32 j = 0; j < SKYTEX_RESOLUTION; ++j)
{
- const S32 basic_offset = (i * sResolution + j);
- S32 offset = basic_offset * sComponents;
+ const S32 basic_offset = (i * SKYTEX_RESOLUTION + j);
+ S32 offset = basic_offset * SKYTEX_COMPONENTS;
U32* pix = (U32*)(data + offset);
LLColor4U temp = LLColor4U(mSkyData[basic_offset]);
*pix = temp.asRGBA();
@@ -208,7 +203,7 @@ void LLSkyTex::create()
}
void LLSkyTex::createGLImage(S32 which)
-{
+{
mTexture[which]->setExplicitFormat(GL_RGBA8, GL_RGBA);
mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);
mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -395,10 +390,8 @@ const LLVector3* LLHeavenBody::corners() const
Sky
***************************************/
-
-S32 LLVOSky::sResolution = LLSkyTex::getResolution();
-S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X;
-S32 LLVOSky::sTileResY = sResolution/NUM_TILES_Y;
+const S32 SKYTEX_TILE_RES_X = SKYTEX_RESOLUTION / NUM_TILES_X;
+const S32 SKYTEX_TILE_RES_Y = SKYTEX_RESOLUTION / NUM_TILES_Y;
LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
: LLStaticViewerObject(id, pcode, regionp, TRUE),
@@ -433,7 +426,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
{
mFace[i] = NULL;
}
-
+
mCameraPosAgent = gAgentCamera.getCameraPositionAgent();
mAtmHeight = ATM_HEIGHT;
mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS);
@@ -461,30 +454,12 @@ void LLVOSky::init()
llassert(!mInitialized);
// Update sky at least once to get correct initial sun/moon directions and lighting calcs performed
- LLEnvironment::instance().getCurrentSky()->update();
-
- updateDirections();
-
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ psky->update();
- // invariants across whole sky tex process...
- m_atmosphericsVars.blue_density = psky->getBlueDensity();
- m_atmosphericsVars.blue_horizon = psky->getBlueHorizon();
- m_atmosphericsVars.haze_density = psky->getHazeDensity();
- m_atmosphericsVars.haze_horizon = psky->getHazeHorizon();
- m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier();
- m_atmosphericsVars.max_y = psky->getMaxY();
- m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
- m_atmosphericsVars.sunlight = psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor();
- m_atmosphericsVars.ambient = psky->getAmbientColor();
- m_atmosphericsVars.glow = psky->getGlow();
- m_atmosphericsVars.cloud_shadow = psky->getCloudShadow();
- m_atmosphericsVars.dome_radius = psky->getDomeRadius();
- m_atmosphericsVars.dome_offset = psky->getDomeOffset();
- m_atmosphericsVars.light_atten = psky->getLightAttenuation(m_atmosphericsVars.max_y);
- m_atmosphericsVars.light_transmittance = psky->getLightTransmittance(m_atmosphericsVars.max_y);
- m_atmosphericsVars.total_density = psky->getTotalDensity();
- m_atmosphericsVars.gamma = psky->getGamma();
+ updateDirections(psky);
+
+ cacheEnvironment(psky,m_atmosphericsVars);
// Initialize the cached normalized direction vectors
for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
@@ -492,7 +467,7 @@ void LLVOSky::init()
for (S32 tile = 0; tile < NUM_TILES; ++tile)
{
initSkyTextureDirs(side, tile);
- createSkyTexture(m_atmosphericsVars, side, tile);
+ createSkyTexture(psky, m_atmosphericsVars, side, tile);
}
mSkyTex[side].create();
mShinyTex[side].create();
@@ -509,28 +484,35 @@ void LLVOSky::init()
}
+void LLVOSky::cacheEnvironment(LLSettingsSky::ptr_t psky,AtmosphericsVars& atmosphericsVars)
+{
+ // NOTE: Also see: LLAtmospherics::updateFog()
+ // invariants across whole sky tex process...
+ atmosphericsVars.blue_density = psky->getBlueDensity();
+ atmosphericsVars.blue_horizon = psky->getBlueHorizon();
+ atmosphericsVars.haze_density = psky->getHazeDensity();
+ atmosphericsVars.haze_horizon = psky->getHazeHorizon();
+ atmosphericsVars.density_multiplier = psky->getDensityMultiplier();
+ atmosphericsVars.distance_multiplier = psky->getDistanceMultiplier();
+ atmosphericsVars.max_y = psky->getMaxY();
+ atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
+ atmosphericsVars.sunlight = psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor();
+ atmosphericsVars.ambient = psky->getAmbientColor();
+ atmosphericsVars.glow = psky->getGlow();
+ atmosphericsVars.cloud_shadow = psky->getCloudShadow();
+ atmosphericsVars.dome_radius = psky->getDomeRadius();
+ atmosphericsVars.dome_offset = psky->getDomeOffset();
+ atmosphericsVars.light_atten = psky->getLightAttenuation(atmosphericsVars.max_y);
+ atmosphericsVars.light_transmittance = psky->getLightTransmittance(atmosphericsVars.max_y);
+ atmosphericsVars.total_density = psky->getTotalDensity();
+ atmosphericsVars.gamma = psky->getGamma();
+}
+
void LLVOSky::calc()
{
+ LL_PROFILE_ZONE_SCOPED;
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
-
- // invariants across whole sky tex process...
- m_atmosphericsVars.blue_density = psky->getBlueDensity();
- m_atmosphericsVars.blue_horizon = psky->getBlueHorizon();
- m_atmosphericsVars.haze_density = psky->getHazeDensity();
- m_atmosphericsVars.haze_horizon = psky->getHazeHorizon();
- m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier();
- m_atmosphericsVars.distance_multiplier = psky->getDistanceMultiplier();
- m_atmosphericsVars.max_y = psky->getMaxY();
- m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
- m_atmosphericsVars.sunlight = psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor();
- m_atmosphericsVars.ambient = psky->getAmbientColor();
- m_atmosphericsVars.glow = psky->getGlow();
- m_atmosphericsVars.cloud_shadow = psky->getCloudShadow();
- m_atmosphericsVars.dome_radius = psky->getDomeRadius();
- m_atmosphericsVars.dome_offset = psky->getDomeOffset();
- m_atmosphericsVars.light_atten = psky->getLightAttenuation(m_atmosphericsVars.max_y);
- m_atmosphericsVars.light_transmittance = psky->getLightTransmittance(m_atmosphericsVars.max_y);
- m_atmosphericsVars.gamma = psky->getGamma();
+ cacheEnvironment(psky,m_atmosphericsVars);
mSun.setColor(psky->getSunDiffuse());
mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));
@@ -541,14 +523,14 @@ void LLVOSky::calc()
mMoon.renewColor();
}
-void LLVOSky::initCubeMap()
+void LLVOSky::initCubeMap()
{
std::vector<LLPointer<LLImageRaw> > images;
for (S32 side = 0; side < NUM_CUBEMAP_FACES; side++)
{
images.push_back(mShinyTex[side].getImageRaw());
}
-
+
if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
{
mCubeMap = new LLCubeMap(false);
@@ -592,12 +574,12 @@ void LLVOSky::restoreGL()
setMoonTextures(psky->getMoonTextureId(), psky->getNextMoonTextureId());
}
- updateDirections();
+ updateDirections(psky);
if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
- {
+ {
initCubeMap();
- }
+ }
forceSkyUpdate();
@@ -613,8 +595,8 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile)
S32 tile_x = tile % NUM_TILES_X;
S32 tile_y = tile / NUM_TILES_X;
- S32 tile_x_pos = tile_x * sTileResX;
- S32 tile_y_pos = tile_y * sTileResY;
+ S32 tile_x_pos = tile_x * SKYTEX_TILE_RES_X;
+ S32 tile_y_pos = tile_y * SKYTEX_TILE_RES_Y;
F32 coeff[3] = {0, 0, 0};
const S32 curr_coef = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X
@@ -624,11 +606,11 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile)
coeff[curr_coef] = (F32)side_dir;
- F32 inv_res = 1.f/sResolution;
+ F32 inv_res = 1.f/SKYTEX_RESOLUTION;
S32 x, y;
- for (y = tile_y_pos; y < (tile_y_pos + sTileResY); ++y)
+ for (y = tile_y_pos; y < (tile_y_pos + SKYTEX_TILE_RES_Y); ++y)
{
- for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x)
+ for (x = tile_x_pos; x < (tile_x_pos + SKYTEX_TILE_RES_X); ++x)
{
coeff[x_coef] = F32((x<<1) + 1) * inv_res - 1.f;
coeff[y_coef] = F32((y<<1) + 1) * inv_res - 1.f;
@@ -640,37 +622,35 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile)
}
}
-void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile)
+void LLVOSky::createSkyTexture(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const S32 side, const S32 tile)
{
- LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ const bool low_end = !gPipeline.canUseWindLightShaders();
S32 tile_x = tile % NUM_TILES_X;
S32 tile_y = tile / NUM_TILES_X;
- S32 tile_x_pos = tile_x * sTileResX;
- S32 tile_y_pos = tile_y * sTileResY;
+ S32 tile_x_pos = tile_x * SKYTEX_TILE_RES_X;
+ S32 tile_y_pos = tile_y * SKYTEX_TILE_RES_Y;
S32 x, y;
- for (y = tile_y_pos; y < (tile_y_pos + sTileResY); ++y)
+ for (y = tile_y_pos; y < (tile_y_pos + SKYTEX_TILE_RES_Y); ++y)
{
- for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x)
+ for (x = tile_x_pos; x < (tile_x_pos + SKYTEX_TILE_RES_X); ++x)
{
- mSkyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mSkyTex[side].getDir(x, y), false), x, y);
- mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mShinyTex[side].getDir(x, y), true), x, y);
+ mSkyTex [side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mSkyTex [side].getDir(x, y), false, low_end), x, y);
+ mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mShinyTex[side].getDir(x, y), true , low_end), x, y);
}
}
}
-void LLVOSky::updateDirections(void)
+void LLVOSky::updateDirections(LLSettingsSky::ptr_t psky)
{
- LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
-
mSun.setDirection(psky->getSunDirection());
- mMoon.setDirection(psky->getMoonDirection());
+ mMoon.setDirection(psky->getMoonDirection());
mSun.setRotation(psky->getSunRotation());
- mMoon.setRotation(psky->getMoonRotation());
- mSun.renewDirection();
- mMoon.renewDirection();
+ mMoon.setRotation(psky->getMoonRotation());
+ mSun.renewDirection();
+ mMoon.renewDirection();
}
void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time)
@@ -692,11 +672,6 @@ bool LLVOSky::updateSky()
if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)))
{
- return TRUE;
- }
-
- if (mDead)
- {
// It's dead. Don't update it.
return TRUE;
}
@@ -706,18 +681,18 @@ bool LLVOSky::updateSky()
return TRUE;
}
+ LL_PROFILE_ZONE_SCOPED;
+
static S32 next_frame = 0;
- const S32 total_no_tiles = NUM_CUBEMAP_FACES * NUM_TILES;
- const S32 cycle_frame_no = total_no_tiles + 1;
-
+
mNeedUpdate = mForceUpdate;
++next_frame;
- next_frame = next_frame % cycle_frame_no;
+ next_frame = next_frame % MAX_TILES;
- mInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no;
+ mInterpVal = (!mInitialized) ? 1 : (F32)next_frame / MAX_TILES;
LLHeavenBody::setInterpVal( mInterpVal );
- updateDirections();
+ updateDirections(psky);
if (!mCubeMap)
{
@@ -725,10 +700,9 @@ bool LLVOSky::updateSky()
mForceUpdate = FALSE;
return TRUE;
}
-
+
if (mCubeMapUpdateStage < 0)
{
- LL_RECORD_BLOCK_TIME(FTM_VOSKY_CALC);
calc();
bool same_atmospherics = approximatelyEqual(m_lastAtmosphericsVars, m_atmosphericsVars, UPDATE_MIN_DELTA_THRESHOLD);
@@ -745,7 +719,7 @@ bool LLVOSky::updateSky()
}
else if (mCubeMapUpdateStage == NUM_CUBEMAP_FACES)
{
- LL_RECORD_BLOCK_TIME(FTM_VOSKY_UPDATEFORCED);
+ LL_PROFILE_ZONE_NAMED("updateSky - forced");
LLSkyTex::stepCurrent();
bool is_alm_wl_sky = gPipeline.canUseWindLightShaders();
@@ -805,8 +779,8 @@ bool LLVOSky::updateSky()
}
// run 0 to 5 faces, each face in own frame
else if (mCubeMapUpdateStage >= 0 && mCubeMapUpdateStage < NUM_CUBEMAP_FACES)
- {
- LL_RECORD_BLOCK_TIME(FTM_VOSKY_CREATETEXTURES);
+ {
+ LL_PROFILE_ZONE_NAMED("updateSky - create");
S32 side = mCubeMapUpdateStage;
// CPU hungry part, createSkyTexture() is math heavy
// Prior to EEP it was mostly per tile, but since EPP it is per face.
@@ -815,7 +789,7 @@ bool LLVOSky::updateSky()
// instead of executing per face, or may be can be moved to shaders)
for (S32 tile = 0; tile < NUM_TILES; tile++)
{
- createSkyTexture(m_atmosphericsVars, side, tile);
+ createSkyTexture(psky, m_atmosphericsVars, side, tile);
}
mCubeMapUpdateStage++;
}
@@ -889,10 +863,10 @@ void LLVOSky::setSunScale(F32 sun_scale)
void LLVOSky::setMoonScale(F32 moon_scale)
{
mMoonScale = moon_scale;
- }
-
+}
+
void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next)
- {
+{
// We test the UUIDs here because we explicitly do not want the default image returned by getFetchedTexture in that case...
mSunTexturep[0] = sun_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
mSunTexturep[1] = sun_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
@@ -910,32 +884,32 @@ void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_textur
LLViewerTexture* current_tex1 = mFace[FACE_SUN]->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
if (current_tex0 && (mSunTexturep[0] != current_tex0) && current_tex0->isViewerMediaTexture())
- {
+ {
static_cast<LLViewerMediaTexture*>(current_tex0)->removeMediaFromFace(mFace[FACE_SUN]);
}
if (current_tex1 && (mSunTexturep[1] != current_tex1) && current_tex1->isViewerMediaTexture())
- {
+ {
static_cast<LLViewerMediaTexture*>(current_tex1)->removeMediaFromFace(mFace[FACE_SUN]);
- }
+ }
mFace[FACE_SUN]->setTexture(LLRender::DIFFUSE_MAP, mSunTexturep[0]);
if (can_use_wl)
{
if (mSunTexturep[1])
- {
- mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
+ {
+ mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
mFace[FACE_SUN]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mSunTexturep[1]);
- }
- }
- }
+ }
+ }
+}
void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next)
- {
+{
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
-
+
bool can_use_wl = gPipeline.canUseWindLightShaders();
mMoonTexturep[0] = moon_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
@@ -944,17 +918,17 @@ void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_tex
if (mFace[FACE_MOON])
{
if (mMoonTexturep[0])
- {
- mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
+ {
+ mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
mFace[FACE_MOON]->setTexture(LLRender::DIFFUSE_MAP, mMoonTexturep[0]);
if (mMoonTexturep[1] && can_use_wl)
- {
- mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ {
+ mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
mFace[FACE_MOON]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mMoonTexturep[1]);
- }
- }
+ }
+ }
}
void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next)
@@ -963,7 +937,7 @@ void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLU
mCloudNoiseTexturep[0] = cloud_noise_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
mCloudNoiseTexturep[1] = cloud_noise_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
-
+
if (mCloudNoiseTexturep[0])
{
mCloudNoiseTexturep[0]->setAddressMode(LLTexUnit::TAM_WRAP);
@@ -986,21 +960,19 @@ void LLVOSky::setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_
mBloomTexturep[1] = bloom_tex_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(bloom_tex_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
if (mBloomTexturep[0])
-{
- mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ {
+ mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
}
if (mBloomTexturep[1])
- {
- mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ {
+ mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
}
- }
-
-static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Sky Geometry");
+}
BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
{
- LL_RECORD_BLOCK_TIME(FTM_GEO_SKY);
+ LL_PROFILE_ZONE_SCOPED;
if (mFace[FACE_REFLECTION] == NULL)
{
LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
@@ -1029,11 +1001,11 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
LLStrider<LLVector2> texCoordsp;
LLStrider<U16> indicesp;
U16 index_offset;
- LLFace *face;
+ LLFace *face;
for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
{
- face = mFace[FACE_SIDE0 + side];
+ face = mFace[FACE_SIDE0 + side];
if (!face->getVertexBuffer())
{
@@ -1045,7 +1017,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
face->setVertexBuffer(buff);
index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
-
+
S32 vtx = 0;
S32 curr_bit = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X
S32 side_dir = side & 1; // even - 0, odd - 1
@@ -1164,11 +1136,11 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const
hb.setVisible(TRUE);
- facep = mFace[f];
+ facep = mFace[f];
if (!facep->getVertexBuffer())
{
- facep->setSize(4, 6);
+ facep->setSize(4, 6);
LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE))
{
@@ -1402,7 +1374,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
dt_clip = -0.1f;
}
- LLFace *face = mFace[FACE_REFLECTION];
+ LLFace *face = mFace[FACE_REFLECTION];
if (face)
{
@@ -1420,13 +1392,13 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
face->setGeomIndex(0);
face->setVertexBuffer(buff);
}
-
+
LLStrider<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> texCoordsp;
LLStrider<U16> indicesp;
S32 index_offset;
-
+
index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
if (-1 == index_offset)
{
@@ -1444,7 +1416,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
LLColor4 hb_refl_col = (1 - attenuation) * hb_col + attenuation * getSkyFogColor();
face->setFaceColor(hb_refl_col);
-
+
LLVector3 v_far[2];
v_far[0] = v_refl_corner[1];
v_far[1] = v_refl_corner[3];
@@ -1568,52 +1540,53 @@ void LLVOSky::updateFog(const F32 distance)
}
void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir_cfr, const LLVector3 &moon_dir_cfr)
- {
- mSun.setDirection(sun_dir_cfr);
- mMoon.setDirection(moon_dir_cfr);
+{
+ mSun.setDirection(sun_dir_cfr);
+ mMoon.setDirection(moon_dir_cfr);
- // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
- // on the upward facing faces of cubes.
- {
- // Same as dot product with the up direction + clamp.
- F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
- sunDot *= sunDot;
-
- // Create normalized vector that has the sunDir pushed south about an hour and change.
- LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
-
- // Blend between normal sun dir and adjusted sun dir based on how close we are
- // to having the sun overhead.
- mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot);
- mBumpSunDir.normalize();
- }
- updateDirections();
- }
+ // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
+ // on the upward facing faces of cubes.
+ // Same as dot product with the up direction + clamp.
+ F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
+ sunDot *= sunDot;
+
+ // Create normalized vector that has the sunDir pushed south about an hour and change.
+ LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
+
+ // Blend between normal sun dir and adjusted sun dir based on how close we are
+ // to having the sun overhead.
+ mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot);
+ mBumpSunDir.normalize();
+
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ updateDirections(psky);
+}
void LLVOSky::setSunDirectionCFR(const LLVector3 &sun_dir_cfr)
- {
- mSun.setDirection(sun_dir_cfr);
+{
+ mSun.setDirection(sun_dir_cfr);
- // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
- // on the upward facing faces of cubes.
- {
- // Same as dot product with the up direction + clamp.
- F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
- sunDot *= sunDot;
+ // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
+ // on the upward facing faces of cubes.
+ // Same as dot product with the up direction + clamp.
+ F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
+ sunDot *= sunDot;
- // Create normalized vector that has the sunDir pushed south about an hour and change.
- LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
+ // Create normalized vector that has the sunDir pushed south about an hour and change.
+ LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
- // Blend between normal sun dir and adjusted sun dir based on how close we are
- // to having the sun overhead.
- mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot);
- mBumpSunDir.normalize();
- }
- updateDirections();
+ // Blend between normal sun dir and adjusted sun dir based on how close we are
+ // to having the sun overhead.
+ mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot);
+ mBumpSunDir.normalize();
+
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ updateDirections(psky);
}
void LLVOSky::setMoonDirectionCFR(const LLVector3 &moon_dir_cfr)
{
- mMoon.setDirection(moon_dir_cfr);
- updateDirections();
+ mMoon.setDirection(moon_dir_cfr);
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ updateDirections(psky);
}
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 39e42bbb24..5941ab6e3b 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -43,6 +43,9 @@ const F32 HEAVENLY_BODY_DIST = HORIZON_DIST - 20.f;
const F32 HEAVENLY_BODY_FACTOR = 0.1f;
const F32 HEAVENLY_BODY_SCALE = HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR;
+const F32 SKYTEX_COMPONENTS = 4;
+const F32 SKYTEX_RESOLUTION = 64;
+
class LLFace;
class LLHaze;
@@ -50,8 +53,6 @@ class LLSkyTex
{
friend class LLVOSky;
private:
- static S32 sResolution;
- static S32 sComponents;
LLPointer<LLViewerTexture> mTexture[2];
LLPointer<LLImageRaw> mImageRaw[2];
LLColor4 *mSkyData;
@@ -82,25 +83,25 @@ protected:
void setDir(const LLVector3 &dir, const S32 i, const S32 j)
{
- S32 offset = i * sResolution + j;
+ S32 offset = i * SKYTEX_RESOLUTION + j;
mSkyDirs[offset] = dir;
}
const LLVector3 &getDir(const S32 i, const S32 j) const
{
- S32 offset = i * sResolution + j;
+ S32 offset = i * SKYTEX_RESOLUTION + j;
return mSkyDirs[offset];
}
void setPixel(const LLColor4 &col, const S32 i, const S32 j)
{
- S32 offset = i * sResolution + j;
+ S32 offset = i * SKYTEX_RESOLUTION + j;
mSkyData[offset] = col;
}
void setPixel(const LLColor4U &col, const S32 i, const S32 j)
{
- S32 offset = (i * sResolution + j) * sComponents;
+ S32 offset = (i * SKYTEX_RESOLUTION + j) * SKYTEX_COMPONENTS;
U32* pix = (U32*) &(mImageRaw[sCurrent]->getData()[offset]);
*pix = col.asRGBA();
}
@@ -108,7 +109,7 @@ protected:
LLColor4U getPixel(const S32 i, const S32 j)
{
LLColor4U col;
- S32 offset = (i * sResolution + j) * sComponents;
+ S32 offset = (i * SKYTEX_RESOLUTION + j) * SKYTEX_COMPONENTS;
U32* pix = (U32*) &(mImageRaw[sCurrent]->getData()[offset]);
col.fromRGBA( *pix );
return col;
@@ -214,12 +215,12 @@ public:
// Initialize/delete data that's only inited once per class.
void init();
void initCubeMap();
- void initEmpty();
void cleanupGL();
void restoreGL();
void calc();
+ void cacheEnvironment(LLSettingsSky::ptr_t psky, AtmosphericsVars& atmosphericsVars);
/*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
bool updateSky();
@@ -253,8 +254,6 @@ public:
LLColor4 getSkyFogColor() const { return m_legacyAtmospherics.getFogColor(); }
LLColor4 getGLFogColor() const { return m_legacyAtmospherics.getGLFogColor(); }
- LLColor4U getFadeColor() const;
-
void setCloudDensity(F32 cloud_density) { mCloudDensity = cloud_density; }
void setWind ( const LLVector3& wind ) { mWind = wind.length(); }
@@ -299,10 +298,10 @@ public:
protected:
~LLVOSky();
- void updateDirections(void);
+ void updateDirections(LLSettingsSky::ptr_t psky);
void initSkyTextureDirs(const S32 side, const S32 tile);
- void createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile);
+ void createSkyTexture(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const S32 side, const S32 tile);
LLPointer<LLViewerFetchedTexture> mSunTexturep[2];
LLPointer<LLViewerFetchedTexture> mMoonTexturep[2];
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index 897bace4e1..4d25e8c7bd 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -212,19 +212,19 @@ LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_TERRAIN("Update Terrain");
void LLVOSurfacePatch::updateGL()
{
if (mPatchp)
{
+ LL_PROFILE_ZONE_SCOPED
mPatchp->updateGL();
}
}
BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_TERRAIN);
+ LL_PROFILE_ZONE_SCOPED;
dirtySpatialGroup(TRUE);
@@ -1070,10 +1070,9 @@ LLVertexBuffer* LLTerrainPartition::createVertexBuffer(U32 type_mask, U32 usage)
return new LLVertexBufferTerrain();
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_TERRAIN_VB("Terrain VB");
void LLTerrainPartition::getGeometry(LLSpatialGroup* group)
{
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_TERRAIN_VB);
+ LL_PROFILE_ZONE_SCOPED;
LLVertexBuffer* buffer = group->mVertexBuffer;
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 41099cb570..493162b47b 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -493,11 +493,9 @@ LLDrawable* LLVOTree::createDrawable(LLPipeline *pipeline)
const S32 LEAF_INDICES = 24;
const S32 LEAF_VERTICES = 16;
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_TREE("Update Tree");
-
BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_TREE);
+ LL_PROFILE_ZONE_SCOPED;
if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree.
{
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index ca5305b169..755a70599a 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -103,10 +103,6 @@ S32 LLVOVolume::mRenderComplexity_current = 0;
LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL;
LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL;
-static LLTrace::BlockTimerStatHandle FTM_GEN_TRIANGLES("Generate Triangles");
-static LLTrace::BlockTimerStatHandle FTM_GEN_VOLUME("Generate Volumes");
-static LLTrace::BlockTimerStatHandle FTM_VOLUME_TEXTURES("Volume Textures");
-
extern BOOL gGLDebugLoggingEnabled;
// Implementation class of LLMediaDataClientObject. See llmediadataclient.h
@@ -716,7 +712,7 @@ BOOL LLVOVolume::isVisible() const
void LLVOVolume::updateTextureVirtualSize(bool forced)
{
- LL_RECORD_BLOCK_TIME(FTM_VOLUME_TEXTURES);
+ LL_PROFILE_ZONE_SCOPED;
// Update the pixel area of all faces
if (mDrawable.isNull())
@@ -995,6 +991,7 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bool unique_volume)
{
+ LL_PROFILE_ZONE_SCOPED;
LLVolumeParams volume_params = params_in;
S32 last_lod = mVolumep.notNull() ? LLVolumeLODGroup::getVolumeDetailFromScale(mVolumep->getDetail()) : -1;
@@ -1622,6 +1619,7 @@ BOOL LLVOVolume::setParent(LLViewerObject* parent)
// NOTE: regenFaces() MUST be followed by genTriangles()!
void LLVOVolume::regenFaces()
{
+ LL_PROFILE_ZONE_SCOPED;
// remove existing faces
BOOL count_changed = mNumFaces != getNumTEs();
@@ -1669,6 +1667,7 @@ void LLVOVolume::regenFaces()
BOOL LLVOVolume::genBBoxes(BOOL force_global)
{
+ LL_PROFILE_ZONE_SCOPED;
BOOL res = TRUE;
LLVector4a min,max;
@@ -1879,12 +1878,9 @@ void LLVOVolume::updateRelativeXform(bool force_identity)
}
}
-static LLTrace::BlockTimerStatHandle FTM_GEN_FLEX("Generate Flexies");
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_PRIMITIVES("Update Primitives");
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_RIGGED_VOLUME("Update Rigged");
-
bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
{
+ LL_PROFILE_ZONE_SCOPED;
bool regen_faces = false;
LLVolume *old_volumep, *new_volumep;
@@ -1897,7 +1893,6 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
old_volumep = NULL;
{
- LL_RECORD_BLOCK_TIME(FTM_GEN_VOLUME);
const LLVolumeParams &volume_params = getVolume()->getParams();
setVolume(volume_params, 0);
}
@@ -1925,7 +1920,6 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles()
{
- LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES);
regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs();
if (regen_faces)
{
@@ -1950,14 +1944,11 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_PRIMITIVES);
+ LL_PROFILE_ZONE_SCOPED;
if (mDrawable->isState(LLDrawable::REBUILD_RIGGED))
{
- {
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_RIGGED_VOLUME);
- updateRiggedVolume();
- }
+ updateRiggedVolume();
genBBoxes(FALSE);
mDrawable->clearState(LLDrawable::REBUILD_RIGGED);
}
@@ -1966,7 +1957,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
{
BOOL res;
{
- LL_RECORD_BLOCK_TIME(FTM_GEN_FLEX);
res = mVolumeImpl->doUpdateGeometry(drawable);
}
updateFaceFlags();
@@ -2006,7 +1996,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
}
if (!was_regen_faces) {
- LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES);
regenFaces();
}
@@ -2029,7 +2018,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
{
compiled = TRUE;
// All it did was move or we changed the texture coordinate offset
- LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES);
genBBoxes(FALSE);
}
@@ -3579,7 +3567,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const
{
if (getVolume())
{
- return gMeshRepo.getSkinInfo(getVolume()->getParams().getSculptID(), this);
+ return gMeshRepo.getSkinInfo(getMeshID(), this);
}
else
{
@@ -3741,11 +3729,9 @@ void LLVOVolume::afterReparent()
}
//----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_VOVOL_RIGGING_INFO("VOVol Rigging Info");
-
void LLVOVolume::updateRiggingInfo()
{
- LL_RECORD_BLOCK_TIME(FTM_VOVOL_RIGGING_INFO);
+ LL_PROFILE_ZONE_SCOPED;
if (isRiggedMesh())
{
const LLMeshSkinInfo* skin = getSkinInfo();
@@ -4750,6 +4736,7 @@ void LLVOVolume::clearRiggedVolume()
void LLVOVolume::updateRiggedVolume(bool force_update)
{
+ LL_PROFILE_ZONE_SCOPED;
//Update mRiggedVolume to match current animation frame of avatar.
//Also update position/size in octree.
@@ -4785,11 +4772,9 @@ void LLVOVolume::updateRiggedVolume(bool force_update)
mRiggedVolume->update(skin, avatar, volume);
}
-static LLTrace::BlockTimerStatHandle FTM_SKIN_RIGGED("Skin");
-static LLTrace::BlockTimerStatHandle FTM_RIGGED_OCTREE("Octree");
-
void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume)
{
+ LL_PROFILE_ZONE_SCOPED;
bool copy = false;
if (volume->getNumVolumeFaces() != getNumVolumeFaces())
{
@@ -4831,7 +4816,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
LLMatrix4a mat[kMaxJoints];
U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin);
- LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar);
+ LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar);
S32 rigged_vert_count = 0;
S32 rigged_face_count = 0;
@@ -4847,15 +4832,12 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
if ( weight )
{
LLSkinningUtil::checkSkinWeights(weight, dst_face.mNumVertices, skin);
- LLMatrix4a bind_shape_matrix;
- bind_shape_matrix.loadu(skin->mBindShapeMatrix);
+ const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix;
LLVector4a* pos = dst_face.mPositions;
if (pos && dst_face.mExtents)
{
- LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED);
-
U32 max_joints = LLSkinningUtil::getMaxJointCount();
rigged_vert_count += dst_face.mNumVertices;
rigged_face_count++;
@@ -4926,8 +4908,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
}
{
- LL_RECORD_BLOCK_TIME(FTM_RIGGED_OCTREE);
- delete dst_face.mOctree;
+ delete dst_face.mOctree;
dst_face.mOctree = NULL;
LLVector4a size;
@@ -5091,11 +5072,9 @@ void LLVolumeGeometryManager::freeFaces()
sAlphaFaces = NULL;
}
-static LLTrace::BlockTimerStatHandle FTM_REGISTER_FACE("Register Face");
-
void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
{
- LL_RECORD_BLOCK_TIME(FTM_REGISTER_FACE);
+ LL_PROFILE_ZONE_SCOPED;
if ( type == LLRenderPass::PASS_ALPHA
&& facep->getTextureEntry()->getMaterialParams().notNull()
&& !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)
@@ -5327,10 +5306,6 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_VOLUME_VB("Volume VB");
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_VOLUME_FACE_LIST("Build Face List");
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_VOLUME_GEN_DRAW_INFO("Gen Draw Info");
-
static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
{
LLVOAvatar* avatar = vobj->getAvatar();
@@ -5434,8 +5409,19 @@ void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value)
}
}
+// add a face pointer to a list of face pointers without going over MAX_COUNT faces
+template<typename T>
+static inline void add_face(T** list, U32& count, T* face)
+{
+ if (count < MAX_FACE_COUNT)
+ {
+ list[count++] = face;
+ }
+}
+
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
+ LL_PROFILE_ZONE_SCOPED;
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -5452,8 +5438,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
return;
}
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);
-
group->mBuilt = 1.f;
LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
@@ -5510,7 +5494,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
#endif
{
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_FACE_LIST);
+ LL_PROFILE_ZONE_NAMED("rebuildGeom - face list");
//get all the faces into a list
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin();
@@ -5851,21 +5835,19 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
if (facep->canRenderAsMask())
{ //can be treated as alpha mask
- if (simple_count < MAX_FACE_COUNT)
- {
- sSimpleFaces[simple_count++] = facep;
- }
+ add_face(sSimpleFaces, simple_count, facep);
}
else
{
- if (te->getColor().mV[3] > 0.f)
- { //only treat as alpha in the pipeline if < 100% transparent
- drawablep->setState(LLDrawable::HAS_ALPHA);
- }
- if (alpha_count < MAX_FACE_COUNT)
- {
- sAlphaFaces[alpha_count++] = facep;
- }
+ if (te->getColor().mV[3] > 0.f)
+ { //only treat as alpha in the pipeline if < 100% transparent
+ drawablep->setState(LLDrawable::HAS_ALPHA);
+ add_face(sAlphaFaces, alpha_count, facep);
+ }
+ else if (LLDrawPoolAlpha::sShowDebugAlpha)
+ {
+ add_face(sAlphaFaces, alpha_count, facep);
+ }
}
}
else
@@ -5885,81 +5867,51 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
if (mat->getSpecularID().notNull())
{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
- if (normspec_count < MAX_FACE_COUNT)
- {
- sNormSpecFaces[normspec_count++] = facep;
- }
+ add_face(sNormSpecFaces, normspec_count, facep);
}
else
{ //has normal map (needs texcoord1 and tangent)
- if (norm_count < MAX_FACE_COUNT)
- {
- sNormFaces[norm_count++] = facep;
- }
+ add_face(sNormFaces, norm_count, facep);
}
}
else if (mat->getSpecularID().notNull())
{ //has specular map but no normal map, needs texcoord2
- if (spec_count < MAX_FACE_COUNT)
- {
- sSpecFaces[spec_count++] = facep;
- }
+ add_face(sSpecFaces, spec_count, facep);
}
else
{ //has neither specular map nor normal map, only needs texcoord0
- if (simple_count < MAX_FACE_COUNT)
- {
- sSimpleFaces[simple_count++] = facep;
- }
+ add_face(sSimpleFaces, simple_count, facep);
}
}
else if (te->getBumpmap())
{ //needs normal + tangent
- if (bump_count < MAX_FACE_COUNT)
- {
- sBumpFaces[bump_count++] = facep;
- }
+ add_face(sBumpFaces, bump_count, facep);
}
else if (te->getShiny() || !te->getFullbright())
{ //needs normal
- if (simple_count < MAX_FACE_COUNT)
- {
- sSimpleFaces[simple_count++] = facep;
- }
+ add_face(sSimpleFaces, simple_count, facep);
}
else
{ //doesn't need normal
facep->setState(LLFace::FULLBRIGHT);
- if (fullbright_count < MAX_FACE_COUNT)
- {
- sFullbrightFaces[fullbright_count++] = facep;
- }
+ add_face(sFullbrightFaces, fullbright_count, facep);
}
}
else
{
if (te->getBumpmap() && LLPipeline::sRenderBump)
{ //needs normal + tangent
- if (bump_count < MAX_FACE_COUNT)
- {
- sBumpFaces[bump_count++] = facep;
- }
+ add_face(sBumpFaces, bump_count, facep);
}
else if ((te->getShiny() && LLPipeline::sRenderBump) ||
!(te->getFullbright() || bake_sunlight))
{ //needs normal
- if (simple_count < MAX_FACE_COUNT)
- {
- sSimpleFaces[simple_count++] = facep;
- }
+ add_face(sSimpleFaces, simple_count, facep);
}
else
{ //doesn't need normal
facep->setState(LLFace::FULLBRIGHT);
- if (fullbright_count < MAX_FACE_COUNT)
- {
- sFullbrightFaces[fullbright_count++] = facep;
- }
+ add_face(sFullbrightFaces, fullbright_count, facep);
}
}
}
@@ -6061,133 +6013,130 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
mFaceList.clear();
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_MESH_FLUSH("Flush Mesh");
-
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(group);
if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY))
{
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers
+ {
+ LL_PROFILE_ZONE_NAMED("rebuildMesh - gen draw info");
- group->mBuilt = 1.f;
+ group->mBuilt = 1.f;
- S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ;
+ S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ;
- const U32 MAX_BUFFER_COUNT = 4096;
- LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT];
-
- U32 buffer_count = 0;
+ const U32 MAX_BUFFER_COUNT = 4096;
+ LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT];
- for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
- {
- LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
+ U32 buffer_count = 0;
- if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- LLVOVolume* vobj = drawablep->getVOVolume();
- if (debugLoggingEnabled("AnimatedObjectsLinkset"))
- {
- if (vobj->isAnimatedObject() && vobj->isRiggedMesh())
- {
- std::string vobj_name = llformat("Vol%p", vobj);
- F32 est_tris = vobj->getEstTrianglesMax();
- LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL;
- }
- }
- if (vobj->isNoLOD()) continue;
-
- vobj->preRebuild();
-
- if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
- {
- vobj->updateRelativeXform(true);
- }
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- LLVolume* volume = vobj->getVolume();
- for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
+ if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
{
- LLFace* face = drawablep->getFace(i);
- if (face)
+ LLVOVolume* vobj = drawablep->getVOVolume();
+ if (debugLoggingEnabled("AnimatedObjectsLinkset"))
{
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (buff)
+ if (vobj->isAnimatedObject() && vobj->isRiggedMesh())
{
- llassert(!face->isState(LLFace::RIGGED));
+ std::string vobj_name = llformat("Vol%p", vobj);
+ F32 est_tris = vobj->getEstTrianglesMax();
+ LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL;
+ }
+ }
+ if (vobj->isNoLOD()) continue;
- if (!face->getGeometryVolume(*volume, face->getTEOffset(),
- vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
- { //something's gone wrong with the vertex buffer accounting, rebuild this group
- group->dirtyGeom();
- gPipeline.markRebuild(group, TRUE);
- }
+ vobj->preRebuild();
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(true);
+ }
- if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT)
+ LLVolume* volume = vobj->getVolume();
+ for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
+ {
+ LLFace* face = drawablep->getFace(i);
+ if (face)
+ {
+ LLVertexBuffer* buff = face->getVertexBuffer();
+ if (buff)
{
- locked_buffer[buffer_count++] = buff;
+ llassert(!face->isState(LLFace::RIGGED));
+
+ if (!face->getGeometryVolume(*volume, face->getTEOffset(),
+ vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
+ { //something's gone wrong with the vertex buffer accounting, rebuild this group
+ group->dirtyGeom();
+ gPipeline.markRebuild(group, TRUE);
+ }
+
+
+ if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT)
+ {
+ locked_buffer[buffer_count++] = buff;
+ }
}
}
}
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform();
+ }
+
+ drawablep->clearState(LLDrawable::REBUILD_ALL);
}
+ }
- if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ LL_PROFILE_ZONE_NAMED("rebuildMesh - flush");
+ for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter)
{
- vobj->updateRelativeXform();
+ (*iter)->flush();
}
-
- drawablep->clearState(LLDrawable::REBUILD_ALL);
+ // don't forget alpha
+ if(group != NULL &&
+ !group->mVertexBuffer.isNull() &&
+ group->mVertexBuffer->isLocked())
+ {
+ group->mVertexBuffer->flush();
+ }
}
- }
-
- {
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_MESH_FLUSH);
- for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter)
- {
- (*iter)->flush();
- }
-
- // don't forget alpha
- if(group != NULL &&
- !group->mVertexBuffer.isNull() &&
- group->mVertexBuffer->isLocked())
- {
- group->mVertexBuffer->flush();
- }
- }
- //if not all buffers are unmapped
- if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount)
- {
- LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ;
- for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
+ //if not all buffers are unmapped
+ if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount)
{
- LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- if(!drawablep)
- {
- continue;
- }
- for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
+ LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ;
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- LLFace* face = drawablep->getFace(i);
- if (face)
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
+ if(!drawablep)
{
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (buff && buff->isLocked())
+ continue;
+ }
+ for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
+ {
+ LLFace* face = drawablep->getFace(i);
+ if (face)
{
- buff->flush();
+ LLVertexBuffer* buff = face->getVertexBuffer();
+ if (buff && buff->isLocked())
+ {
+ buff->flush();
+ }
}
}
}
- }
- }
-
- group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
- }
+ }
-// llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
+ group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
+ }
+ }
}
struct CompareBatchBreakerModified
@@ -6220,19 +6169,10 @@ struct CompareBatchBreakerModified
}
};
-static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_SORT("Draw Info Face Sort");
-static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_FACE_SIZE("Face Sizing");
-static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_ALLOCATE("Allocate VB");
-static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_FIND_VB("Find VB");
-static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
-
-
-
-
U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
{
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
+ LL_PROFILE_ZONE_SCOPED;
U32 geometryBytes = 0;
U32 buffer_usage = group->mBufferUsage;
@@ -6264,7 +6204,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
max_vertices = llmin(max_vertices, (U32) 65535);
{
- LL_RECORD_BLOCK_TIME(FTM_GEN_DRAW_INFO_SORT);
+ LL_PROFILE_ZONE_NAMED("genDrawInfo - sort");
if (!distance_sort)
{
//sort faces by things that break batches
@@ -6350,7 +6290,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
U32 texture_count = 0;
{
- LL_RECORD_BLOCK_TIME(FTM_GEN_DRAW_INFO_FACE_SIZE);
+ LL_PROFILE_ZONE_NAMED("genDrawInfo - face size");
if (batch_textures)
{
U8 cur_tex = 0;
@@ -6473,7 +6413,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
LLPointer<LLVertexBuffer> buffer;
{
- LL_RECORD_BLOCK_TIME(FTM_GEN_DRAW_INFO_ALLOCATE);
+ LL_PROFILE_ZONE_NAMED("genDrawInfo - allocate");
buffer = createVertexBuffer(mask, buffer_usage);
if(!buffer->allocateBuffer(geom_count, index_count, TRUE))
{
@@ -6861,6 +6801,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count)
{
+ LL_PROFILE_ZONE_SCOPED;
+
//initialize to default usage for this partition
U32 usage = group->getSpatialPartition()->mBufferUsage;
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index ce400a3498..b8c6f47bbd 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -296,6 +296,9 @@ public:
BOOL setIsFlexible(BOOL is_flexible);
const LLMeshSkinInfo* getSkinInfo() const;
+
+ //convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons)
+ const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); }
// Extended Mesh Properties
U32 getExtendedMeshFlags() const;
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 12def24a0d..efe6aa158e 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -114,11 +114,9 @@ LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_WATER("Update Water");
-
BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_WATER);
+ LL_PROFILE_ZONE_SCOPED;
LLFace *face;
if (drawable->getNumFaces() < 1)
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index d428cb1568..d1f584cbca 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -36,8 +36,8 @@
#include "llenvironment.h"
#include "llsettingssky.h"
-static const U32 MIN_SKY_DETAIL = 8;
-static const U32 MAX_SKY_DETAIL = 180;
+constexpr U32 MIN_SKY_DETAIL = 8;
+constexpr U32 MAX_SKY_DETAIL = 180;
inline U32 LLVOWLSky::getNumStacks(void)
{
@@ -97,13 +97,14 @@ LLDrawable * LLVOWLSky::createDrawable(LLPipeline * pipeline)
return mDrawable;
}
-inline F32 LLVOWLSky::calcPhi(U32 i)
+// a tiny helper function for controlling the sky dome tesselation.
+inline F32 calcPhi(const U32 &i, const F32 &reciprocal_num_stacks)
{
// Calc: PI/8 * 1-((1-t^4)*(1-t^4)) { 0<t<1 }
// Demos: \pi/8*\left(1-((1-x^{4})*(1-x^{4}))\right)\ \left\{0<x\le1\right\}
// i should range from [0..SKY_STACKS] so t will range from [0.f .. 1.f]
- F32 t = float(i) / float(getNumStacks());
+ F32 t = float(i) * reciprocal_num_stacks; //SL-16127: remove: / float(getNumStacks());
// ^4 the parameter of the tesselation to bias things toward 0 (the dome's apex)
t *= t;
@@ -141,11 +142,9 @@ void LLVOWLSky::restoreGL()
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
}
-static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Windlight Sky Geometry");
-
BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
{
- LL_RECORD_BLOCK_TIME(FTM_GEO_SKY);
+ LL_PROFILE_ZONE_SCOPED;
LLStrider<LLVector3> vertices;
LLStrider<LLVector2> texCoords;
LLStrider<U16> indices;
@@ -189,6 +188,8 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
}
{
+ const F32 dome_radius = LLEnvironment::instance().getCurrentSky()->getDomeRadius();
+
const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024;
const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask);
@@ -204,12 +205,14 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
// round up to a whole number of segments
const U32 strips_segments = (total_stacks+stacks_per_seg-1) / stacks_per_seg;
- LL_INFOS() << "WL Skydome strips in " << strips_segments << " batches." << LL_ENDL;
-
mStripsVerts.resize(strips_segments, NULL);
+#if RELEASE_SHOW_DEBUG
+ LL_INFOS() << "WL Skydome strips in " << strips_segments << " batches." << LL_ENDL;
+
LLTimer timer;
timer.start();
+#endif
for (U32 i = 0; i < strips_segments ;++i)
{
@@ -234,34 +237,42 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
const U32 num_indices_this_seg = 1+num_stacks_this_seg*(2+2*verts_per_stack);
llassert(num_indices_this_seg * sizeof(U16) <= max_buffer_bytes);
- if (!segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE))
+ bool allocated = segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE);
+#if RELEASE_SHOW_WARNS
+ if( !allocated )
{
LL_WARNS() << "Failed to allocate Vertex Buffer on update to "
<< num_verts_this_seg << " vertices and "
<< num_indices_this_seg << " indices" << LL_ENDL;
}
+#else
+ (void) allocated;
+#endif
// lock the buffer
BOOL success = segment->getVertexStrider(vertices)
&& segment->getTexCoord0Strider(texCoords)
&& segment->getIndexStrider(indices);
- if(!success)
+#if RELEASE_SHOW_DEBUG
+ if(!success)
{
LL_ERRS() << "Failed updating WindLight sky geometry." << LL_ENDL;
}
-
- U32 vertex_count = 0;
- U32 index_count = 0;
+#else
+ (void) success;
+#endif
// fill it
- buildStripsBuffer(begin_stack, end_stack, vertex_count, index_count, vertices, texCoords, indices);
+ buildStripsBuffer(begin_stack, end_stack, vertices, texCoords, indices, dome_radius, verts_per_stack, total_stacks);
// and unlock the buffer
segment->flush();
}
+#if RELEASE_SHOW_DEBUG
LL_INFOS() << "completed in " << llformat("%.2f", timer.getElapsedTimeF32().value()) << "seconds" << LL_ENDL;
+#endif
}
updateStarColors();
@@ -366,23 +377,16 @@ void LLVOWLSky::initStars()
void LLVOWLSky::buildStripsBuffer(U32 begin_stack,
U32 end_stack,
- U32& vertex_count,
- U32& index_count,
- LLStrider<LLVector3> & vertices,
- LLStrider<LLVector2> & texCoords,
- LLStrider<U16> & indices)
+ LLStrider<LLVector3> & vertices,
+ LLStrider<LLVector2> & texCoords,
+ LLStrider<U16> & indices,
+ const F32 dome_radius,
+ const U32& num_slices,
+ const U32& num_stacks)
{
- const F32 RADIUS = LLEnvironment::instance().getCurrentSky()->getDomeRadius();
-
- U32 i, j, num_slices, num_stacks;
+ U32 i, j;
F32 phi0, theta, x0, y0, z0;
-
- // paranoia checking for SL-55986/SL-55833
- U32 count_verts = 0;
- U32 count_indices = 0;
-
- num_slices = getNumSlices();
- num_stacks = getNumStacks();
+ const F32 reciprocal_num_stacks = 1.f / num_stacks;
llassert(end_stack <= num_stacks);
@@ -393,7 +397,7 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack,
for(i = begin_stack + 1; i <= end_stack+1; ++i)
#endif
{
- phi0 = calcPhi(i);
+ phi0 = calcPhi(i, reciprocal_num_stacks);
for(j = 0; j < num_slices; ++j)
{
@@ -406,24 +410,22 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack,
z0 = sin(phi0) * sin(theta);
#if NEW_TESS
- *vertices++ = LLVector3(x0 * RADIUS, y0 * RADIUS, z0 * RADIUS);
+ *vertices++ = LLVector3(x0 * dome_radius, y0 * dome_radius, z0 * dome_radius);
#else
if (i == num_stacks-2)
{
- *vertices++ = LLVector3(x0*RADIUS, y0*RADIUS-1024.f*2.f, z0*RADIUS);
+ *vertices++ = LLVector3(x0*dome_radius, y0*dome_radius-1024.f*2.f, z0*dome_radius);
}
else if (i == num_stacks-1)
{
- *vertices++ = LLVector3(0, y0*RADIUS-1024.f*2.f, 0);
+ *vertices++ = LLVector3(0, y0*dome_radius-1024.f*2.f, 0);
}
else
{
- *vertices++ = LLVector3(x0 * RADIUS, y0 * RADIUS, z0 * RADIUS);
+ *vertices++ = LLVector3(x0 * dome_radius, y0 * dome_radius, z0 * dome_radius);
}
#endif
- ++count_verts;
-
// generate planar uv coordinates
// note: x and z are transposed in order for things to animate
// correctly in the global coordinate system where +x is east and
@@ -434,12 +436,11 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack,
//build triangle strip...
*indices++ = 0 ;
- count_indices++ ;
+
S32 k = 0 ;
for(i = 1; i <= end_stack - begin_stack; ++i)
{
*indices++ = i * num_slices + k ;
- count_indices++ ;
k = (k+1) % num_slices ;
for(j = 0; j < num_slices ; ++j)
@@ -447,8 +448,6 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack,
*indices++ = (i-1) * num_slices + k ;
*indices++ = i * num_slices + k ;
- count_indices += 2 ;
-
k = (k+1) % num_slices ;
}
@@ -458,11 +457,7 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack,
}
*indices++ = i * num_slices + k ;
- count_indices++ ;
}
-
- vertex_count = count_verts;
- index_count = count_indices;
}
void LLVOWLSky::updateStarColors()
diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h
index 2b7ebe75dd..3853dd2c70 100644
--- a/indra/newview/llvowlsky.h
+++ b/indra/newview/llvowlsky.h
@@ -55,8 +55,6 @@ public:
void restoreGL();
private:
- // a tiny helper function for controlling the sky dome tesselation.
- static F32 calcPhi(U32 i);
// helper function for initializing the stars.
void initStars();
@@ -66,11 +64,12 @@ private:
// begin_stack is the first stack to be included, end_stack is the first
// stack not to be included.
static void buildStripsBuffer(U32 begin_stack, U32 end_stack,
- U32& vertex_count,
- U32& index_count,
- LLStrider<LLVector3> & vertices,
- LLStrider<LLVector2> & texCoords,
- LLStrider<U16> & indices);
+ LLStrider<LLVector3> & vertices,
+ LLStrider<LLVector2> & texCoords,
+ LLStrider<U16> & indices,
+ const F32 RADIUS,
+ const U32& num_slices,
+ const U32& num_stacks);
// helper function for updating the stars colors.
void updateStarColors();
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index fb3fc55a94..4cb63d0ab8 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -62,6 +62,8 @@
#include <cstring>
+LLWorld* LLSimpleton<LLWorld>::sInstance = nullptr;
+
//
// Globals
//
@@ -135,6 +137,7 @@ void LLWorld::destroyClass()
LLDrawable::incrementVisible();
LLSceneMonitor::deleteSingleton();
+ LLWorld::deleteSingleton();
}
@@ -1077,6 +1080,7 @@ void LLWorld::updateWaterObjects()
void LLWorld::shiftRegions(const LLVector3& offset)
{
+ LL_PROFILE_ZONE_SCOPED;
for (region_list_t::const_iterator i = getRegionList().begin(); i != getRegionList().end(); ++i)
{
LLViewerRegion* region = *i;
@@ -1147,11 +1151,9 @@ void LLWorld::disconnectRegions()
}
}
-static LLTrace::BlockTimerStatHandle FTM_ENABLE_SIMULATOR("Enable Sim");
-
void process_enable_simulator(LLMessageSystem *msg, void **user_data)
{
- LL_RECORD_BLOCK_TIME(FTM_ENABLE_SIMULATOR);
+ LL_PROFILE_ZONE_SCOPED;
// enable the appropriate circuit for this simulator and
// add its values into the gSimulator structure
U64 handle;
@@ -1222,12 +1224,11 @@ public:
}
};
-static LLTrace::BlockTimerStatHandle FTM_DISABLE_REGION("Disable Region");
// disable the circuit to this simulator
// Called in response to "DisableSimulator" message.
void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data)
{
- LL_RECORD_BLOCK_TIME(FTM_DISABLE_REGION);
+ LL_PROFILE_ZONE_SCOPED;
LLHost host = mesgsys->getSender();
@@ -1289,6 +1290,7 @@ void send_agent_pause()
void send_agent_resume()
{
+ LL_PROFILE_ZONE_SCOPED
// Note: used to check for LLWorld initialization before it became a singleton.
// Rather than just remove this check I'm changing it to assure that the message
// system has been initialized. -MG
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index 98552bc4d1..69f2df4203 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -59,11 +59,12 @@ class LLVOAvatar;
// as simulators are connected to, viewer_regions are popped off the stack and connected as required
// as simulators are removed, they are pushed back onto the stack
-class LLWorld : public LLSingleton<LLWorld>
+class LLWorld : public LLSimpleton<LLWorld>
{
- LLSINGLETON(LLWorld);
public:
- void destroyClass();
+ LLWorld();
+
+ void destroyClass();
LLViewerRegion* addRegion(const U64 &region_handle, const LLHost &host);
// safe to call if already present, does the "right thing" if
diff --git a/indra/newview/llworldmapmessage.cpp b/indra/newview/llworldmapmessage.cpp
index 8be340de4c..e4a9f9afdb 100644
--- a/indra/newview/llworldmapmessage.cpp
+++ b/indra/newview/llworldmapmessage.cpp
@@ -150,6 +150,10 @@ void LLWorldMapMessage::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16
// public static
void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**)
{
+ if (gNonInteractive)
+ {
+ return;
+ }
U32 agent_flags;
msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index cd1b9c7c69..cb54b1eaed 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -238,7 +238,6 @@ const LLMatrix4* gGLLastMatrix = NULL;
LLTrace::BlockTimerStatHandle FTM_RENDER_GEOMETRY("Render Geometry");
LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS("Grass");
LLTrace::BlockTimerStatHandle FTM_RENDER_INVISIBLE("Invisible");
-LLTrace::BlockTimerStatHandle FTM_RENDER_OCCLUSION("Occlusion");
LLTrace::BlockTimerStatHandle FTM_RENDER_SHINY("Shiny");
LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE("Simple");
LLTrace::BlockTimerStatHandle FTM_RENDER_TERRAIN("Terrain");
@@ -253,14 +252,12 @@ LLTrace::BlockTimerStatHandle FTM_RENDER_MATERIALS("Render Materials");
LLTrace::BlockTimerStatHandle FTM_RENDER_FULLBRIGHT("Fullbright");
LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW("Glow");
LLTrace::BlockTimerStatHandle FTM_GEO_UPDATE("Geo Update");
-LLTrace::BlockTimerStatHandle FTM_PIPELINE_CREATE("Pipeline Create");
LLTrace::BlockTimerStatHandle FTM_POOLRENDER("RenderPool");
LLTrace::BlockTimerStatHandle FTM_POOLS("Pools");
LLTrace::BlockTimerStatHandle FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)");
LLTrace::BlockTimerStatHandle FTM_DEFERRED_POOLS("Pools (Deferred)");
LLTrace::BlockTimerStatHandle FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)");
LLTrace::BlockTimerStatHandle FTM_POST_DEFERRED_POOLS("Pools (Post)");
-LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM_FBO("First FBO");
LLTrace::BlockTimerStatHandle FTM_STATESORT("Sort Draw State");
LLTrace::BlockTimerStatHandle FTM_PIPELINE("Pipeline");
LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY("Client Copy");
@@ -269,11 +266,8 @@ LLTrace::BlockTimerStatHandle FTM_RENDER_DEFERRED("Deferred Shading");
LLTrace::BlockTimerStatHandle FTM_RENDER_UI_HUD("HUD");
LLTrace::BlockTimerStatHandle FTM_RENDER_UI_3D("3D");
LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D("2D");
-LLTrace::BlockTimerStatHandle FTM_RENDER_UI_DEBUG_TEXT("Debug Text");
-LLTrace::BlockTimerStatHandle FTM_RENDER_UI_SCENE_MON("Scene Mon");
static LLTrace::BlockTimerStatHandle FTM_STATESORT_DRAWABLE("Sort Drawables");
-static LLTrace::BlockTimerStatHandle FTM_STATESORT_POSTSORT("Post Sort");
static LLStaticHashedString sTint("tint");
static LLStaticHashedString sAmbiance("ambiance");
@@ -338,7 +332,6 @@ S32 LLPipeline::sUseOcclusion = 0;
bool LLPipeline::sDelayVBUpdate = true;
bool LLPipeline::sAutoMaskAlphaDeferred = true;
bool LLPipeline::sAutoMaskAlphaNonDeferred = false;
-bool LLPipeline::sDisableShaders = false;
bool LLPipeline::sRenderTransparentWater = true;
bool LLPipeline::sRenderBump = true;
bool LLPipeline::sBakeSunlight = false;
@@ -359,7 +352,6 @@ bool LLPipeline::sRenderAttachedLights = true;
bool LLPipeline::sRenderAttachedParticles = true;
bool LLPipeline::sRenderDeferred = false;
S32 LLPipeline::sVisibleLightCount = 0;
-F32 LLPipeline::sMinRenderSize = 0.f;
bool LLPipeline::sRenderingHUDs;
F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f;
@@ -487,6 +479,10 @@ void LLPipeline::init()
{
clearAllRenderTypes();
}
+ else if (gNonInteractive)
+ {
+ clearAllRenderTypes();
+ }
else
{
setAllRenderTypes(); // By default, all rendering types start enabled
@@ -725,8 +721,6 @@ void LLPipeline::destroyGL()
}
}
-static LLTrace::BlockTimerStatHandle FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
-
void LLPipeline::requestResizeScreenTexture()
{
gResizeScreenTexture = TRUE;
@@ -746,7 +740,6 @@ void LLPipeline::resizeShadowTexture()
void LLPipeline::resizeScreenTexture()
{
- LL_RECORD_BLOCK_TIME(FTM_RESIZE_SCREEN_TEXTURE);
if (gPipeline.canUseVertexShaders() && assertInitialized())
{
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
@@ -1054,7 +1047,6 @@ void LLPipeline::updateRenderDeferred()
RenderDeferred &&
LLRenderTarget::sUseFBO &&
LLPipeline::sRenderBump &&
- LLPipeline::sRenderTransparentWater &&
RenderAvatarVP &&
WindLightUseAtmosShaders &&
(bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
@@ -1153,6 +1145,12 @@ void LLPipeline::refreshCachedSettings()
RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit");
RenderSpotLight = nullptr;
updateRenderDeferred();
+
+ if (gNonInteractive)
+ {
+ LLVOAvatar::sMaxNonImpostors = 1;
+ LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors);
+ }
}
void LLPipeline::releaseGLBuffers()
@@ -1232,7 +1230,8 @@ void LLPipeline::releaseShadowTargets()
void LLPipeline::createGLBuffers()
{
- stop_glerror();
+ LL_PROFILE_ZONE_SCOPED;
+ stop_glerror();
assertInitialized();
updateRenderDeferred();
@@ -1385,7 +1384,7 @@ void LLPipeline::restoreGL()
if (part)
{
part->restoreGL();
- }
+ }
}
}
}
@@ -1393,10 +1392,7 @@ void LLPipeline::restoreGL()
bool LLPipeline::canUseVertexShaders()
{
- if (sDisableShaders ||
- !gGLManager.mHasVertexShader ||
- !gGLManager.mHasFragmentShader ||
- (assertInitialized() && mVertexShadersLoaded != 1) )
+ if ((assertInitialized() && mVertexShadersLoaded != 1) )
{
return false;
}
@@ -1408,8 +1404,7 @@ bool LLPipeline::canUseVertexShaders()
bool LLPipeline::canUseWindLightShaders() const
{
- return (!LLPipeline::sDisableShaders &&
- gWLSkyProgram.mProgramObject != 0 &&
+ return (gWLSkyProgram.mProgramObject != 0 &&
LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1);
}
@@ -1514,6 +1509,7 @@ public:
// Called when a texture changes # of channels (causes faces to move to alpha pool)
void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerFetchedTexture*>& textures)
{
+ LL_PROFILE_ZONE_SCOPED;
assertInitialized();
// *TODO: This is inefficient and causes frame spikes; need a better way to do this
@@ -1725,15 +1721,9 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj)
}
-static LLTrace::BlockTimerStatHandle FTM_UNLINK("Unlink");
-static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_MOVE_LIST("Movelist");
-static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_SPATIAL_PARTITION("Spatial Partition");
-static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_LIGHT_SET("Light Set");
-static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Set");
-
void LLPipeline::unlinkDrawable(LLDrawable *drawable)
{
- LL_RECORD_BLOCK_TIME(FTM_UNLINK);
+ LL_PROFILE_ZONE_SCOPED;
assertInitialized();
@@ -1742,7 +1732,6 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
// Based on flags, remove the drawable from the queues that it's on.
if (drawablep->isState(LLDrawable::ON_MOVE_LIST))
{
- LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_MOVE_LIST);
LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep);
if (iter != mMovedList.end())
{
@@ -1752,7 +1741,6 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
if (drawablep->getSpatialGroup())
{
- LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_SPATIAL_PARTITION);
if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup()))
{
#ifdef LL_RELEASE_FOR_DOWNLOAD
@@ -1763,30 +1751,24 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
}
}
- {
- LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_LIGHT_SET);
- mLights.erase(drawablep);
+ mLights.erase(drawablep);
- for (light_set_t::iterator iter = mNearbyLights.begin();
- iter != mNearbyLights.end(); iter++)
+ for (light_set_t::iterator iter = mNearbyLights.begin();
+ iter != mNearbyLights.end(); iter++)
+ {
+ if (iter->drawable == drawablep)
{
- if (iter->drawable == drawablep)
- {
- mNearbyLights.erase(iter);
- break;
- }
+ mNearbyLights.erase(iter);
+ break;
}
}
- {
- LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_HIGHLIGHT_SET);
- HighlightItem item(drawablep);
- mHighlightSet.erase(item);
+ HighlightItem item(drawablep);
+ mHighlightSet.erase(item);
- if (mHighlightObject == drawablep)
- {
- mHighlightObject = NULL;
- }
+ if (mHighlightObject == drawablep)
+ {
+ mHighlightObject = NULL;
}
for (U32 i = 0; i < 2; ++i)
@@ -1801,14 +1783,12 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
mTargetShadowSpotLight[i] = NULL;
}
}
-
-
}
//static
void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar)
{
- LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_LIGHT_SET);
+ LL_PROFILE_ZONE_SCOPED;
for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
iter != gPipeline.mNearbyLights.end(); iter++)
{
@@ -1836,7 +1816,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj)
void LLPipeline::createObjects(F32 max_dtime)
{
- LL_RECORD_BLOCK_TIME(FTM_PIPELINE_CREATE);
+ LL_PROFILE_ZONE_SCOPED;
LLTimer update_timer;
@@ -1860,6 +1840,7 @@ void LLPipeline::createObjects(F32 max_dtime)
void LLPipeline::createObject(LLViewerObject* vobj)
{
+ LL_PROFILE_ZONE_SCOPED;
LLDrawable* drawablep = vobj->mDrawable;
if (!drawablep)
@@ -1897,6 +1878,7 @@ void LLPipeline::createObject(LLViewerObject* vobj)
void LLPipeline::resetFrameStats()
{
+ LL_PROFILE_ZONE_SCOPED
assertInitialized();
sCompiles = 0;
@@ -2005,14 +1987,9 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
}
}
-static LLTrace::BlockTimerStatHandle FTM_OCTREE_BALANCE("Balance Octree");
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_MOVE("Update Move");
-static LLTrace::BlockTimerStatHandle FTM_RETEXTURE("Retexture");
-static LLTrace::BlockTimerStatHandle FTM_MOVED_LIST("Moved List");
-
void LLPipeline::updateMove()
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_MOVE);
+ LL_PROFILE_ZONE_SCOPED;
if (FreezeTime)
{
@@ -2021,49 +1998,38 @@ void LLPipeline::updateMove()
assertInitialized();
+ for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin();
+ iter != mRetexturedList.end(); ++iter)
{
- LL_RECORD_BLOCK_TIME(FTM_RETEXTURE);
-
- for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin();
- iter != mRetexturedList.end(); ++iter)
+ LLDrawable* drawablep = *iter;
+ if (drawablep && !drawablep->isDead())
{
- LLDrawable* drawablep = *iter;
- if (drawablep && !drawablep->isDead())
- {
- drawablep->updateTexture();
- }
+ drawablep->updateTexture();
}
- mRetexturedList.clear();
}
+ mRetexturedList.clear();
- {
- LL_RECORD_BLOCK_TIME(FTM_MOVED_LIST);
- updateMovedList(mMovedList);
- }
+ updateMovedList(mMovedList);
//balance octrees
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
- LL_RECORD_BLOCK_TIME(FTM_OCTREE_BALANCE);
-
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
{
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
{
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- part->mOctree->balance();
- }
+ part->mOctree->balance();
}
+ }
- //balance the VO Cache tree
- LLVOCachePartition* vo_part = region->getVOCachePartition();
- if(vo_part)
- {
- vo_part->mOctree->balance();
- }
+ //balance the VO Cache tree
+ LLVOCachePartition* vo_part = region->getVOCachePartition();
+ if(vo_part)
+ {
+ vo_part->mOctree->balance();
}
}
}
@@ -2125,6 +2091,7 @@ void LLPipeline::grabReferences(LLCullResult& result)
void LLPipeline::clearReferences()
{
+ LL_PROFILE_ZONE_SCOPED
sCull = NULL;
mGroupSaveQ1.clear();
}
@@ -2461,8 +2428,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
LLVOCachePartition* vo_part = region->getVOCachePartition();
if(vo_part)
{
- bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe && 0 > water_clip /* && !gViewerWindow->getProgressView()->getVisible()*/;
- do_occlusion_cull &= !sReflectionRender;
+ bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe; // && 0 > water_clip
vo_part->cull(camera, do_occlusion_cull);
}
}
@@ -2553,13 +2519,6 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
return;
}
- const LLVector4a* bounds = group->getBounds();
- if (sMinRenderSize > 0.f &&
- llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize)
- {
- return;
- }
-
assertInitialized();
if (!group->getSpatialPartition()->mRenderByGroup)
@@ -2669,7 +2628,8 @@ void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderT
void LLPipeline::doOcclusion(LLCamera& camera)
{
- if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&
+ LL_PROFILE_ZONE_SCOPED;
+ if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&
(sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
{
LLVertexBuffer::unbind();
@@ -2753,14 +2713,10 @@ bool LLPipeline::updateDrawableGeom(LLDrawable* drawablep, bool priority)
return update_complete;
}
-static LLTrace::BlockTimerStatHandle FTM_SEED_VBO_POOLS("Seed VBO Pool");
-
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_GL("Update GL");
-
void LLPipeline::updateGL()
{
+ LL_PROFILE_ZONE_SCOPED;
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_GL);
while (!LLGLUpdate::sGLQ.empty())
{
LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
@@ -2771,15 +2727,13 @@ void LLPipeline::updateGL()
}
{ //seed VBO Pools
- LL_RECORD_BLOCK_TIME(FTM_SEED_VBO_POOLS);
LLVertexBuffer::seedPools();
}
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups");
-
void LLPipeline::clearRebuildGroups()
{
+ LL_PROFILE_ZONE_SCOPED;
LLSpatialGroup::sg_vector_t hudGroups;
mGroupQ1Locked = true;
@@ -2884,7 +2838,7 @@ void LLPipeline::clearRebuildDrawables()
void LLPipeline::rebuildPriorityGroups()
{
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_PRIORITY_GROUPS);
+ LL_PROFILE_ZONE_SCOPED;
LLTimer update_timer;
assertInitialized();
@@ -2906,8 +2860,6 @@ void LLPipeline::rebuildPriorityGroups()
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_GROUPS("Rebuild Groups");
-
void LLPipeline::rebuildGroups()
{
if (mGroupQ2.empty())
@@ -2915,7 +2867,7 @@ void LLPipeline::rebuildGroups()
return;
}
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_GROUPS);
+ LL_PROFILE_ZONE_SCOPED;
mGroupQ2Locked = true;
// Iterate through some drawables on the non-priority build queue
S32 size = (S32) mGroupQ2.size();
@@ -3161,12 +3113,9 @@ void LLPipeline::markShift(LLDrawable *drawablep)
}
}
-static LLTrace::BlockTimerStatHandle FTM_SHIFT_DRAWABLE("Shift Drawable");
-static LLTrace::BlockTimerStatHandle FTM_SHIFT_OCTREE("Shift Octree");
-static LLTrace::BlockTimerStatHandle FTM_SHIFT_HUD("Shift HUD");
-
void LLPipeline::shiftObjects(const LLVector3 &offset)
{
+ LL_PROFILE_ZONE_SCOPED;
assertInitialized();
glClear(GL_DEPTH_BUFFER_BIT);
@@ -3175,46 +3124,36 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
LLVector4a offseta;
offseta.load3(offset.mV);
+ for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
+ iter != mShiftList.end(); iter++)
{
- LL_RECORD_BLOCK_TIME(FTM_SHIFT_DRAWABLE);
-
- for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
- iter != mShiftList.end(); iter++)
+ LLDrawable *drawablep = *iter;
+ if (drawablep->isDead())
{
- LLDrawable *drawablep = *iter;
- if (drawablep->isDead())
- {
- continue;
- }
- drawablep->shiftPos(offseta);
- drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
- }
- mShiftList.resize(0);
+ continue;
+ }
+ drawablep->shiftPos(offseta);
+ drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
}
-
+ mShiftList.resize(0);
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
- LL_RECORD_BLOCK_TIME(FTM_SHIFT_OCTREE);
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
{
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
{
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- part->shift(offseta);
- }
+ part->shift(offseta);
}
}
}
- {
- LL_RECORD_BLOCK_TIME(FTM_SHIFT_HUD);
- LLHUDText::shiftAll(offset);
- LLHUDNameTag::shiftAll(offset);
- }
+ LLHUDText::shiftAll(offset);
+ LLHUDNameTag::shiftAll(offset);
+
display_update_camera();
}
@@ -3245,10 +3184,9 @@ void LLPipeline::markPartitionMove(LLDrawable* drawable)
}
}
-static LLTrace::BlockTimerStatHandle FTM_PROCESS_PARTITIONQ("PartitionQ");
void LLPipeline::processPartitionQ()
{
- LL_RECORD_BLOCK_TIME(FTM_PROCESS_PARTITIONQ);
+ LL_PROFILE_ZONE_SCOPED;
for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter)
{
LLDrawable* drawable = *iter;
@@ -3348,8 +3286,6 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f
}
}
-static LLTrace::BlockTimerStatHandle FTM_RESET_DRAWORDER("Reset Draw Order");
-
void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
{
if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR,
@@ -3363,7 +3299,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
LLPipeline::END_RENDER_TYPES))
{
//clear faces from face pools
- LL_RECORD_BLOCK_TIME(FTM_RESET_DRAWORDER);
gPipeline.resetDrawOrders();
}
@@ -3483,12 +3418,12 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
group->mLastUpdateDistance = group->mDistance;
}
}
-
}
void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed)
{
- if (bridge->getSpatialGroup()->changeLOD() || fov_changed)
+ LL_PROFILE_ZONE_SCOPED;
+ if (bridge->getSpatialGroup()->changeLOD() || fov_changed)
{
bool force_update = false;
bridge->updateDistance(camera, force_update);
@@ -3497,7 +3432,8 @@ void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_c
void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
{
- if (!drawablep
+ LL_PROFILE_ZONE_SCOPED;
+ if (!drawablep
|| drawablep->isDead()
|| !hasRenderType(drawablep->getRenderType()))
{
@@ -3790,9 +3726,30 @@ void renderSoundHighlights(LLDrawable* drawablep)
}
}
+void LLPipeline::touchTextures(LLDrawInfo* info)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ for (auto& tex : info->mTextureList)
+ {
+ if (tex.notNull())
+ {
+ LLImageGL* gl_tex = tex->getGLTexture();
+ if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory))
+ {
+ tex->setActive();
+ }
+ }
+ }
+
+ if (info->mTexture.notNull())
+ {
+ info->mTexture->addTextureStats(info->mVSize);
+ }
+}
+
void LLPipeline::postSort(LLCamera& camera)
{
- LL_RECORD_BLOCK_TIME(FTM_STATESORT_POSTSORT);
+ LL_PROFILE_ZONE_SCOPED;
assertInitialized();
@@ -3842,20 +3799,14 @@ void LLPipeline::postSort(LLCamera& camera)
for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k)
{
- if (sMinRenderSize > 0.f)
- {
- LLVector4a bounds;
- bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]);
-
- if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize)
- {
- sCull->pushDrawInfo(j->first, *k);
- }
- }
- else
- {
- sCull->pushDrawInfo(j->first, *k);
- }
+ LLDrawInfo* info = *k;
+
+ sCull->pushDrawInfo(j->first, info);
+ if (!sShadowRender && !sReflectionRender)
+ {
+ touchTextures(info);
+ addTrianglesDrawn(info->mCount, info->mDrawMode);
+ }
}
}
@@ -3994,7 +3945,10 @@ void LLPipeline::postSort(LLCamera& camera)
{
mSelectedFaces.clear();
- LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
+ if (!gNonInteractive)
+ {
+ LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
+ }
// Draw face highlights for selected faces.
if (LLSelectMgr::getInstance()->getTEMode())
@@ -4564,92 +4518,99 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
+ {
+ // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function.
+ // Solutions are:
+ // 1. Use a new scope
+ // 2. Use named zones
+ // 3. Use transient zones
+ LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS);
- LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS);
-
- LLGLEnable cull(GL_CULL_FACE);
+ LLGLEnable cull(GL_CULL_FACE);
- for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
- {
- LLDrawPool *poolp = *iter;
- if (hasRenderType(poolp->getType()))
+ for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
{
- poolp->prerender();
+ LLDrawPool *poolp = *iter;
+ if (hasRenderType(poolp->getType()))
+ {
+ poolp->prerender();
+ }
}
- }
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
- LLVertexBuffer::unbind();
+ LLVertexBuffer::unbind();
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
+ LLGLState::checkStates();
+ LLGLState::checkTextureChannels();
+ LLGLState::checkClientArrays();
- U32 cur_type = 0;
+ U32 cur_type = 0;
- gGL.setColorMask(true, true);
+ gGL.setColorMask(true, true);
- pool_set_t::iterator iter1 = mPools.begin();
+ pool_set_t::iterator iter1 = mPools.begin();
- while ( iter1 != mPools.end() )
- {
- LLDrawPool *poolp = *iter1;
+ while ( iter1 != mPools.end() )
+ {
+ LLDrawPool *poolp = *iter1;
- cur_type = poolp->getType();
+ cur_type = poolp->getType();
- pool_set_t::iterator iter2 = iter1;
- if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
- {
- LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER);
+ pool_set_t::iterator iter2 = iter1;
+ if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER);
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
- for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ )
- {
- LLVertexBuffer::unbind();
- poolp->beginDeferredPass(i);
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
+ for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ )
{
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
+ LLVertexBuffer::unbind();
+ poolp->beginDeferredPass(i);
+ for (iter2 = iter1; iter2 != mPools.end(); iter2++)
{
- break;
+ LLDrawPool *p = *iter2;
+ if (p->getType() != cur_type)
+ {
+ break;
+ }
+
+ if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); }
}
-
- if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); }
- }
- poolp->endDeferredPass(i);
- LLVertexBuffer::unbind();
+ poolp->endDeferredPass(i);
+ LLVertexBuffer::unbind();
- if (gDebugGL || gDebugPipeline)
- {
- LLGLState::checkStates();
+ if (gDebugGL || gDebugPipeline)
+ {
+ LLGLState::checkStates();
+ }
}
}
- }
- else
- {
- // Skip all pools of this type
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
+ else
{
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
+ // Skip all pools of this type
+ for (iter2 = iter1; iter2 != mPools.end(); iter2++)
{
- break;
+ LLDrawPool *p = *iter2;
+ if (p->getType() != cur_type)
+ {
+ break;
+ }
}
}
+ iter1 = iter2;
+ stop_glerror();
}
- iter1 = iter2;
- stop_glerror();
- }
- gGLLastMatrix = NULL;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.loadMatrix(gGLModelView);
- gGL.setColorMask(true, false);
+ gGL.setColorMask(true, false);
+
+ } // Tracy ZoneScoped
}
void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
@@ -4749,7 +4710,8 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
void LLPipeline::renderGeomShadow(LLCamera& camera)
{
- U32 cur_type = 0;
+ LL_PROFILE_ZONE_SCOPED;
+ U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
@@ -4814,6 +4776,7 @@ void LLPipeline::renderGeomShadow(LLCamera& camera)
void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type)
{
+ LL_PROFILE_ZONE_SCOPED;
assertInitialized();
S32 count = 0;
if (render_type == LLRender::TRIANGLE_STRIP)
@@ -5594,11 +5557,9 @@ void LLPipeline::renderDebug()
}
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_POOLS("Rebuild Pools");
-
void LLPipeline::rebuildPools()
{
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_POOLS);
+ LL_PROFILE_ZONE_SCOPED;
assertInitialized();
@@ -5942,6 +5903,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
void LLPipeline::resetDrawOrders()
{
+ LL_PROFILE_ZONE_SCOPED;
assertInitialized();
// Iterate through all of the draw pools and rebuild them.
for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
@@ -6387,21 +6349,19 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
continue;
}
- LLVector3 light_pos(light->getRenderPosition());
- LLVector4 light_pos_gl(light_pos, 1.0f);
-
- F32 light_radius = llmax(light->getLightRadius(), 0.001f);
- F32 size = light_radius * (sRenderDeferred ? 1.5f : 1.0f);
+ LLVector3 light_pos(light->getRenderPosition());
+ LLVector4 light_pos_gl(light_pos, 1.0f);
- if (size <= 0.001f)
+ F32 adjusted_radius = light->getLightRadius() * (sRenderDeferred ? 1.5f : 1.0f);
+ if (adjusted_radius <= 0.001f)
{
continue;
}
- F32 x = (3.f * (1.f + (light->getLightFalloff() * 2.0f))); // why this magic? probably trying to match a historic behavior.
- F32 linatten = x / (light_radius); // % of brightness at radius
+ F32 x = (3.f * (1.f + (light->getLightFalloff() * 2.0f))); // why this magic? probably trying to match a historic behavior.
+ F32 linatten = x / adjusted_radius; // % of brightness at radius
- mHWLightColors[cur_light] = light_color;
+ mHWLightColors[cur_light] = light_color;
LLLightState* light_state = gGL.getLight(cur_light);
light_state->setPosition(light_pos_gl);
@@ -6410,7 +6370,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_state->setConstantAttenuation(0.f);
if (sRenderDeferred)
{
- light_state->setLinearAttenuation(size);
+ light_state->setLinearAttenuation(linatten);
light_state->setQuadraticAttenuation(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF) + 1.f); // get falloff to match for forward deferred rendering lights
}
else
@@ -7357,8 +7317,6 @@ void LLPipeline::resetVertexBuffers()
mResetVertexBuffers = true;
}
-static LLTrace::BlockTimerStatHandle FTM_RESET_VB("Reset VB");
-
void LLPipeline::doResetVertexBuffers(bool forced)
{
if (!mResetVertexBuffers)
@@ -7380,7 +7338,7 @@ void LLPipeline::doResetVertexBuffers(bool forced)
}
}
- LL_RECORD_BLOCK_TIME(FTM_RESET_VB);
+ LL_PROFILE_ZONE_SCOPED;
mResetVertexBuffers = false;
mCubeVB = NULL;
@@ -7580,11 +7538,8 @@ void LLPipeline::renderFinalize()
if (sRenderGlow)
{
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
- mGlow[2].bindTarget();
- mGlow[2].clear();
- }
+ mGlow[2].bindTarget();
+ mGlow[2].clear();
gGlowExtractProgram.bind();
F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f);
@@ -7650,11 +7605,8 @@ void LLPipeline::renderFinalize()
for (S32 i = 0; i < kernel; i++)
{
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
- mGlow[i % 2].bindTarget();
- mGlow[i % 2].clear();
- }
+ mGlow[i % 2].bindTarget();
+ mGlow[i % 2].clear();
if (i == 0)
{
@@ -8171,11 +8123,9 @@ void LLPipeline::renderFinalize()
LLGLState::checkTextureChannels();
}
-static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred");
-
void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
{
- LL_RECORD_BLOCK_TIME(FTM_BIND_DEFERRED);
+ LL_PROFILE_ZONE_SCOPED;
LLRenderTarget* deferred_target = &mDeferredScreen;
LLRenderTarget* deferred_depth_target = &mDeferredDepth;
@@ -8417,8 +8367,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
LLEnvironment& environment = LLEnvironment::instance();
LLSettingsSky::ptr_t sky = environment.getCurrentSky();
-
- static_cast<LLSettingsVOSky*>(sky.get())->updateShader(&shader);
}
LLColor3 pow3f(LLColor3 v, F32 f)
@@ -8437,19 +8385,9 @@ LLVector4 pow4fsrgb(LLVector4 v, F32 f)
return v;
}
-static LLTrace::BlockTimerStatHandle FTM_GI_TRACE("Trace");
-static LLTrace::BlockTimerStatHandle FTM_GI_GATHER("Gather");
-static LLTrace::BlockTimerStatHandle FTM_SUN_SHADOW("Shadow Map");
-static LLTrace::BlockTimerStatHandle FTM_SOFTEN_SHADOW("Shadow Soften");
-static LLTrace::BlockTimerStatHandle FTM_EDGE_DETECTION("Find Edges");
-static LLTrace::BlockTimerStatHandle FTM_LOCAL_LIGHTS("Local Lights");
-static LLTrace::BlockTimerStatHandle FTM_ATMOSPHERICS("Atmospherics");
-static LLTrace::BlockTimerStatHandle FTM_FULLSCREEN_LIGHTS("Fullscreen Lights");
-static LLTrace::BlockTimerStatHandle FTM_PROJECTORS("Projectors");
-static LLTrace::BlockTimerStatHandle FTM_POST("Post");
-
void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!sCull)
{
return;
@@ -8526,7 +8464,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
deferred_light_target->bindTarget();
{ // paint shadow/SSAO light map (direct lighting lightmap)
- LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);
+ LL_PROFILE_ZONE_NAMED("renderDeferredLighting - sun shadow");
bindDeferredShader(gDeferredSunProgram, deferred_light_target);
mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
glClearColor(1, 1, 1, 1);
@@ -8572,7 +8510,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
if (RenderDeferredSSAO)
{ // soften direct lighting lightmap
- LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW);
+ LL_PROFILE_ZONE_NAMED("renderDeferredLighting - soften shadow");
// blur lightmap
screen_target->bindTarget();
glClearColor(1, 1, 1, 1);
@@ -8650,7 +8588,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{ // apply sunlight contribution
LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;
- LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS);
+ LL_PROFILE_ZONE_NAMED("renderDeferredLighting - atmospherics");
bindDeferredShader(soften_shader);
LLEnvironment &environment = LLEnvironment::instance();
@@ -8716,6 +8654,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLVertexBuffer::unbind();
{
+ LL_PROFILE_ZONE_NAMED("renderDeferredLighting - local lights");
bindDeferredShader(gDeferredLightProgram);
if (mCubeVB.isNull())
@@ -8786,7 +8725,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
continue;
}
- LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS);
gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
@@ -8822,6 +8760,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
if (!spot_lights.empty())
{
+ LL_PROFILE_ZONE_NAMED("renderDeferredLighting - projectors");
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
bindDeferredShader(gDeferredSpotLightProgram);
@@ -8831,7 +8770,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
{
- LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
LLDrawable *drawablep = *iter;
LLVOVolume *volume = drawablep->getVOVolume();
@@ -8867,6 +8805,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
vert[2].set(3, 1, 0);
{
+ LL_PROFILE_ZONE_NAMED("renderDeferredLighting - fullscreen lights");
LLGLDepthTest depth(GL_FALSE);
// full screen blit
@@ -8886,7 +8825,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
while (!fullscreen_lights.empty())
{
- LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS);
light[count] = fullscreen_lights.front();
fullscreen_lights.pop_front();
col[count] = light_colors.front();
@@ -8918,7 +8856,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
{
- LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
LLDrawable *drawablep = *iter;
LLVOVolume *volume = drawablep->getVOVolume();
LLVector3 center = drawablep->getPositionAgent();
@@ -9262,7 +9199,14 @@ inline float sgn(float a)
void LLPipeline::generateWaterReflection(LLCamera& camera_in)
{
- if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
+ LL_PROFILE_ZONE_SCOPED;
+
+ if (!assertInitialized())
+ {
+ return;
+ }
+
+ if (LLPipeline::sWaterReflections && LLDrawPoolWater::sNeedsReflectionUpdate)
{
bool skip_avatar_update = false;
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
@@ -9316,11 +9260,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
water_clip = -1;
}
- S32 occlusion = LLPipeline::sUseOcclusion;
-
- //disable occlusion culling for reflection map for now
- LLPipeline::sUseOcclusion = 0;
-
if (!camera_is_underwater)
{
//generate planar reflection map
@@ -9436,8 +9375,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
set_current_modelview(saved_modelview);
}
- //LLPipeline::sUseOcclusion = occlusion;
-
camera.setOrigin(camera_in.getOrigin());
//render distortion map
static bool last_update = true;
@@ -9489,19 +9426,13 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
//clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself,
// but not so much as to clip out parts of avatars that should be seen under the water in the distortion map
- LLPlane plane(-pnorm, water_dist);
+ LLPlane plane(-pnorm, camera_is_underwater ? -water_height : water_dist);
LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection);
gGL.setColorMask(true, true);
mWaterDis.clear();
gGL.setColorMask(true, false);
- // ignore clip plane if we're underwater and viewing distortion map of objects above waterline
- if (camera_is_underwater)
- {
- clip_plane.disable();
- }
-
if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
{
updateCull(camera, mRefractedObjects, water_clip, &plane);
@@ -9532,7 +9463,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.popRenderTypeMask();
- LLPipeline::sUseOcclusion = occlusion;
LLPipeline::sUnderWaterRender = false;
LLPipeline::sReflectionRender = false;
@@ -9555,6 +9485,29 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
}
+ else
+ {
+ // Initial sky pass is still needed even if water reflection is not rendering
+ bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
+ if (!camera_is_underwater)
+ {
+ gPipeline.pushRenderTypeMask();
+ {
+ gPipeline.andRenderTypeMask(
+ LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
+
+ LLCamera camera = camera_in;
+ camera.setFar(camera_in.getFar() * 0.75f);
+
+ updateCull(camera, mSky);
+ stateSort(camera, mSky);
+ renderGeom(camera, TRUE);
+ }
+ gPipeline.popRenderTypeMask();
+ }
+ }
}
glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
@@ -9828,10 +9781,9 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLPipeline::sShadowRender = false;
}
-static LLTrace::BlockTimerStatHandle FTM_VISIBLE_CLOUD("Visible Cloud");
bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir)
{
- LL_RECORD_BLOCK_TIME(FTM_VISIBLE_CLOUD);
+ LL_PROFILE_ZONE_SCOPED;
//get point cloud of intersection of frust and min, max
if (getVisibleExtents(camera, min, max))
@@ -10088,9 +10040,6 @@ LLRenderTarget* LLPipeline::getShadowTarget(U32 i)
}
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
-static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SETUP("Sun Shadow Setup");
-static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_RENDER_DIRECTIONAL("Render Dir");
-static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_SETUP("Spot Shadow Setup");
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow Render");
void LLPipeline::generateSunShadow(LLCamera& camera)
@@ -10886,14 +10835,11 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool textu
}
}
-static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible");
-static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_SETUP("Impostor Setup");
-static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_BACKGROUND("Impostor Background");
-static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_ALLOCATE("Impostor Allocate");
-static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_RESIZE("Impostor Resize");
+static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor");
void LLPipeline::generateImpostor(LLVOAvatar* avatar)
{
+ LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR);
LLGLState::checkStates();
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
@@ -10968,7 +10914,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLViewerCamera* viewer_camera = LLViewerCamera::getInstance();
{
- LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE);
markVisible(avatar->mDrawable, *viewer_camera);
LLVOAvatar::attachment_map_t::iterator iter;
@@ -10997,7 +10942,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
U32 resX = 0;
{
- LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_SETUP);
const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
@@ -11054,9 +10998,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
if (!avatar->mImpostor.isComplete())
{
- LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_ALLOCATE);
-
-
if (LLPipeline::sRenderDeferred)
{
avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE);
@@ -11073,7 +11014,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
}
else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())
{
- LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_RESIZE);
avatar->mImpostor.resize(resX,resY);
}
@@ -11135,10 +11075,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
{ //create alpha mask based on depth buffer (grey out if muted)
- LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_BACKGROUND);
if (LLPipeline::sRenderDeferred)
{
GLuint buff = GL_COLOR_ATTACHMENT0;
+ LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x8000FF );
glDrawBuffersARB(1, &buff);
}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 0eaa6b141d..b87a726647 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -66,7 +66,6 @@ bool setup_hud_matrices(const LLRect& screen_region); // specify portion of scre
extern LLTrace::BlockTimerStatHandle FTM_RENDER_GEOMETRY;
extern LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS;
extern LLTrace::BlockTimerStatHandle FTM_RENDER_INVISIBLE;
-extern LLTrace::BlockTimerStatHandle FTM_RENDER_OCCLUSION;
extern LLTrace::BlockTimerStatHandle FTM_RENDER_SHINY;
extern LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE;
extern LLTrace::BlockTimerStatHandle FTM_RENDER_TERRAIN;
@@ -87,8 +86,6 @@ extern LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY;
extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_HUD;
extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_3D;
extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D;
-extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_DEBUG_TEXT;
-extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_SCENE_MON;
class LLPipeline
{
@@ -265,6 +262,8 @@ public:
void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE);
void stateSort(LLDrawable* drawablep, LLCamera& camera);
void postSort(LLCamera& camera);
+ //update stats for textures in given DrawInfo
+ void touchTextures(LLDrawInfo* info);
void forAllVisibleDrawables(void (*func)(LLDrawable*));
void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false);
@@ -574,7 +573,6 @@ public:
static bool sDelayVBUpdate;
static bool sAutoMaskAlphaDeferred;
static bool sAutoMaskAlphaNonDeferred;
- static bool sDisableShaders; // if true, rendering will be done without shaders
static bool sRenderTransparentWater;
static bool sRenderBump;
static bool sBakeSunlight;
@@ -597,7 +595,6 @@ public:
static bool sRenderAttachedParticles;
static bool sRenderDeferred;
static S32 sVisibleLightCount;
- static F32 sMinRenderSize;
static bool sRenderingHUDs;
static F32 sDistortionWaterClipPlaneMargin;
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 7786ba8a1c..4f355cce00 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
@@ -102,6 +102,18 @@
Low
</text>
+ <check_box
+ control_name="RenderVSyncEnable"
+ height="16"
+ initial_value="true"
+ label="Enable VSync"
+ layout="topleft"
+ left="30"
+ top_delta="16"
+ name="vsync"
+ tool_tip="Synchronizes the frame rate to the refresh rate of the monitor, which results in smooth performance."
+ width="315" />
+
<text
type="string"
length="1"
@@ -334,18 +346,6 @@
width="256" />
<check_box
- control_name="RenderVBOEnable"
- height="16"
- initial_value="true"
- label="Enable OpenGL Vertex Buffer Objects"
- layout="topleft"
- left="30"
- top_delta="16"
- name="vbo"
- tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled."
- width="315" />
-
- <check_box
control_name="RenderCompressTextures"
height="16"
initial_value="true"
diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml
index e4f735740b..6f84930c75 100644
--- a/indra/newview/skins/default/xui/en/floater_stats.xml
+++ b/indra/newview/skins/default/xui/en/floater_stats.xml
@@ -35,6 +35,25 @@
decimal_digits="1"
show_bar="true"
show_history="true"/>
+ <stat_bar name="frame_mean"
+ label="frame (mean)"
+ unit_label="ms"
+ stat="frametime"
+ decimal_digits="1"
+ show_bar="false"
+ show_history="false"/>
+ <stat_bar name="frame_median"
+ label="frame (median)"
+ unit_label="ms"
+ stat="frametime"
+ show_median="true"
+ decimal_digits="1"
+ show_bar="false"
+ show_history="false"/>
+ <stat_bar name="framet_jitter"
+ label="jitter"
+ decimal_digits="1"
+ stat="frametimejitter"/>
<stat_bar name="bandwidth"
label="UDP Data Received"
stat="activemessagedatareceived"
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index 87c4a8d8a3..bb48216b2b 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -112,6 +112,7 @@ public:
virtual void recordMessage(LLError::ELevel level, const std::string& message)
{
+ LL_PROFILE_ZONE_SCOPED
mFile << message << std::endl;
}
diff --git a/scripts/perf/perfbot_run.py b/scripts/perf/perfbot_run.py
new file mode 100644
index 0000000000..55ea2fae66
--- /dev/null
+++ b/scripts/perf/perfbot_run.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python3
+"""\
+@file perfbot_run.py
+@brief Run a number of non interactive Viewers (PerfBots) with
+ a variety of options and settings. Pass --help for details.
+
+$LicenseInfo:firstyear=2007&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2021, 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 argparse
+import subprocess
+import os
+import math
+import time
+
+# Required parameters that are always passed in
+# Specify noninteractive mode (SL-15999 for details)
+PARAM_NON_INTERACTIVE = "--noninteractive"
+# Run multiple Viewers at once
+PARAM_MULTI = "--multiple"
+# Specify username (first and last) and password
+PARAM_LOGIN = "--login"
+# SLURL to teleport to after login
+PARAM_SLURL = "--slurl"
+
+
+def gen_niv_script(args):
+ print(f"Reading creds from {(args.creds)} folder")
+ print(f"Using the non interactive Viewer from {(args.viewer)}")
+ print(f"Sleeping for {args.sleep}ms between Viewer launches")
+
+ # Read the lines from the creds file. Typically this will be
+ # stored in the build-secrets-git private repository but you
+ # can point to any location with the --creds parameter
+ creds_lines = []
+ with open(args.creds) as file:
+ creds_lines = file.readlines()
+ creds_lines = [line.rstrip() for line in creds_lines]
+ creds_lines = [line for line in creds_lines if not line.startswith("#") and len(line)]
+ # We cannot log in more users than we have credentials for
+ if args.num==0:
+ args.num = len(creds_lines)
+ if args.num > len(creds_lines):
+ print(
+ f"The number of agents specified ({(args.num)}) exceeds "
+ f"the number of valid entries ({(len(creds_lines))}) in "
+ f"the creds file "
+ )
+ return
+
+ print(f"Launching {(args.num)} instances of the Viewer")
+
+ # The Viewer (in dev environments at least) needs a well specified
+ # working directory to function properly. We try to guess what it
+ # might be based on the full path to the Viewer executable but
+ # you can also specify it explicitly with the --cwd parameter
+ # (required for dev builds)
+ args.viewer = os.path.abspath(args.viewer)
+ if len(args.cwd) == 0:
+ working_dir = os.path.dirname(os.path.abspath(args.viewer))
+ else:
+ working_dir = os.path.abspath(args.cwd)
+ print(f"Working directory is {working_dir}, cwd {args.cwd}")
+ os.chdir(working_dir)
+
+ if args.dryrun:
+ print("Running in dry-run mode - no Viewers will be started")
+ print("")
+
+ for inst in range(args.num):
+
+ # Format of each cred line is username_first username_last password
+ # A space is used to separate each and a # at the start of a line
+ # removes it from the pool (useful if someone else is using a subset
+ # of the available ones)
+ creds = creds_lines[inst].split(" ")
+ username_first = creds[0]
+ username_last = creds[1]
+ password = creds[2]
+
+ # The default layout is an evenly spaced circle in the
+ # center of the region. We may extend this to allow other
+ # patterns like a square/rectangle or a spiral. (Hint: it
+ # likely won't be needed :))
+ center_x = 128
+ center_y = 128
+ if args.layout == "circle":
+ radius = 6
+ angle = (2 * math.pi / args.num) * inst
+ region_x = int(math.sin(angle) * radius + center_x)
+ region_y = int(math.cos(angle) * radius + center_y)
+ region_z = 0
+ elif args.layout == "square":
+ region_x = center_x
+ region_y = center_y
+ elif args.layout == "spiral":
+ region_x = center_x
+ region_y = center_y
+ slurl = f"secondlife://{args.region}/{region_x}/{region_y}/{region_z}"
+
+ # Build the script line
+ script_cmd = [args.viewer]
+ script_cmd.append(PARAM_NON_INTERACTIVE)
+ script_cmd.append(PARAM_MULTI)
+ script_cmd.append(PARAM_LOGIN)
+ script_cmd.append(username_first)
+ script_cmd.append(username_last)
+ script_cmd.append(password)
+ script_cmd.append(PARAM_SLURL)
+ script_cmd.append(slurl)
+
+ # Display the script we will execute.
+ cmd = ""
+ for p in script_cmd:
+ cmd = cmd + " " + p
+ print(cmd)
+
+ # If --dry-run is specified, we do everything (including, most
+ # usefully, display the script lines) but do not start the Viewer
+ if args.dryrun == False:
+ print("opening viewer session with",script_cmd)
+ viewer_session = subprocess.Popen(script_cmd)
+
+ # Sleeping a bit between launches seems to help avoid a CPU
+ # surge when N Viewers are started simulatanously. The default
+ # value can be changed with the --sleep parameter
+ time.sleep(args.sleep / 1000)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(allow_abbrev=False)
+ parser.add_argument(
+ "--num",
+ type=int,
+ default=0,
+ dest="num",
+ help="How many avatars to add to the script",
+ )
+ parser.add_argument(
+ "--creds",
+ default="../../../build-secrets-git/perf/perfbot_creds.txt",
+ dest="creds",
+ help="Location of the text file containing user credentials",
+ )
+ parser.add_argument(
+ "--viewer",
+ default="C:/Program Files/SecondLife/SecondLifeViewer.exe",
+ dest="viewer",
+ help="Location of the non interactive Viewer build",
+ )
+ parser.add_argument(
+ "--cwd",
+ default="",
+ dest="cwd",
+ help="Location of the current working directory to use",
+ )
+ parser.add_argument(
+ "--region",
+ default="Lag Me 5",
+ dest="region",
+ help="The SLURL for the Second Life region to visit",
+ )
+ parser.add_argument(
+ "--layout",
+ default="circle",
+ dest="layout",
+ choices={"circle", "square", "spiral"},
+ help="The geometric layout of the avatar destination locations",
+ )
+ parser.add_argument(
+ "--sleep",
+ type=int,
+ default=1000,
+ dest="sleep",
+ help="Time to sleep between launches in milliseconds",
+ )
+ parser.add_argument(
+ "--dry-run",
+ action="store_true",
+ dest="dryrun",
+ help="Dryrun mode - display parameters and script lines but do not start any Viewers",
+ )
+ args = parser.parse_args()
+
+ gen_niv_script(args)